Merge remote-tracking branch 'upstream/develop' into reshare-delivery

This commit is contained in:
Michael 2019-12-08 08:49:47 +00:00
commit ca0a961ad2
12 changed files with 66 additions and 46 deletions

View file

@ -50,7 +50,7 @@ case "$MODE" in
# skip addon folder # skip addon folder
FINDOPTS="( -wholename */addon -or -wholename */addons -or -wholename */addons-extra -or -wholename */smarty3 ) -prune -o" FINDOPTS="( -wholename */addon -or -wholename */addons -or -wholename */addons-extra -or -wholename */smarty3 ) -prune -o"
F9KVERSION=$(sed -n "s/.*'FRIENDICA_VERSION'.*'\([0-9.]*\)'.*/\1/p" ./boot.php); F9KVERSION=$(cat ./VERSION);
echo "Friendica version $F9KVERSION" echo "Friendica version $F9KVERSION"
;; ;;
esac esac

View file

@ -80,7 +80,7 @@ Field parameter:
### field_input.tpl ### field_input.tpl
A single line input field for textual input. A single line input field for any type of input.
Field parameter: Field parameter:
0. Name of the field, 0. Name of the field,
@ -89,7 +89,7 @@ Field parameter:
3. Help text for the input box, 3. Help text for the input box,
4. if set to "required" modern browser will check that this input box is filled when submitting the form, 4. if set to "required" modern browser will check that this input box is filled when submitting the form,
5. if set to "autofocus" modern browser will put the cursur into this box once the page is loaded, 5. if set to "autofocus" modern browser will put the cursur into this box once the page is loaded,
6. if set to "email" or "url" modern browser will check that the filled in value corresponds to an email address or URL. 6. if set, it will be used for the input type, default is `text` (possible types: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#%3Cinput%3E_types).
### field_intcheckbox.tpl ### field_intcheckbox.tpl

View file

@ -652,6 +652,9 @@ function item_post(App $a) {
if ($orig_post) { if ($orig_post) {
$datarray['edit'] = true; $datarray['edit'] = true;
} else { } else {
// If this was a share, add missing data here
$datarray = Item::addShareDataFromOriginal($datarray);
$datarray['edit'] = false; $datarray['edit'] = false;
} }
@ -730,9 +733,6 @@ function item_post(App $a) {
} }
} }
// If this was a share, add missing data here
$datarray = Item::addShareDataFromOriginal($datarray);
$post_id = Item::insert($datarray); $post_id = Item::insert($datarray);
if (!$post_id) { if (!$post_id) {

View file

@ -953,12 +953,11 @@ class BBCode extends BaseObject
public static function convertShare($text, callable $callback) public static function convertShare($text, callable $callback)
{ {
$return = preg_replace_callback( $return = preg_replace_callback(
"/(.*?)\[share(.*?)\](.*?)\[\/share\]/ism", "/(.*?)\[share(.*?)\](.*)\[\/share\]/ism",
function ($match) use ($callback) { function ($match) use ($callback) {
$attribute_string = $match[2]; $attribute_string = $match[2];
$attributes = []; $attributes = [];
foreach(['author', 'profile', 'avatar', 'link', 'posted'] as $field) { foreach (['author', 'profile', 'avatar', 'link', 'posted'] as $field) {
preg_match("/$field=(['\"])(.+?)\\1/ism", $attribute_string, $matches); preg_match("/$field=(['\"])(.+?)\\1/ism", $attribute_string, $matches);
$attributes[$field] = html_entity_decode($matches[2] ?? '', ENT_QUOTES, 'UTF-8'); $attributes[$field] = html_entity_decode($matches[2] ?? '', ENT_QUOTES, 'UTF-8');
} }

View file

@ -258,10 +258,20 @@ class ACL extends BaseObject
*/ */
public static function getContactListByUserId(int $user_id) public static function getContactListByUserId(int $user_id)
{ {
$acl_contacts = Contact::selectToArray( $fields = ['id', 'name', 'addr', 'micro'];
['id', 'name', 'addr', 'micro'], $params = ['order' => ['name']];
['uid' => $user_id, 'pending' => false, 'rel' => [Contact::FOLLOWER, Contact::FRIEND]] $acl_contacts = Contact::selectToArray($fields,
['uid' => $user_id, 'self' => false, 'blocked' => false, 'archive' => false, 'deleted' => false,
'pending' => false, 'rel' => [Contact::FOLLOWER, Contact::FRIEND]], $params
); );
$acl_forums = Contact::selectToArray($fields,
['uid' => $user_id, 'self' => false, 'blocked' => false, 'archive' => false, 'deleted' => false,
'pending' => false, 'contact-type' => Contact::TYPE_COMMUNITY], $params
);
$acl_contacts = array_merge($acl_forums, $acl_contacts);
array_walk($acl_contacts, function (&$value) { array_walk($acl_contacts, function (&$value) {
$value['type'] = 'contact'; $value['type'] = 'contact';
}); });
@ -367,7 +377,7 @@ class ACL extends BaseObject
} }
} }
if ($default_permissions['hidewall']) { if (!$default_permissions['hidewall']) {
if ($mail_enabled) { if ($mail_enabled) {
$jotnets_fields[] = [ $jotnets_fields[] = [
'type' => 'checkbox', 'type' => 'checkbox',

View file

@ -1458,15 +1458,26 @@ class Contact extends BaseObject
if (DBA::isResult($contact)) { if (DBA::isResult($contact)) {
$contact_id = $contact["id"]; $contact_id = $contact["id"];
// Update the contact every 7 days // Update the contact every 7 days (Don't update mail or feed contacts)
if (in_array($contact['network'], Protocol::NATIVE_SUPPORT)) { if (in_array($contact['network'], Protocol::FEDERATED)) {
$update_contact = ($contact['updated'] < DateTimeFormat::utc('now -7 days')); $update_contact = ($contact['updated'] < DateTimeFormat::utc('now -7 days'));
// We force the update if the avatar is empty // We force the update if the avatar is empty
if (empty($contact['avatar'])) { if (empty($contact['avatar'])) {
$update_contact = true; $update_contact = true;
} }
} else { } elseif (empty($default) && in_array($contact['network'], [Protocol::MAIL, Protocol::PHANTOM]) && ($uid == 0)) {
// Update public mail accounts via their user's accounts
$fields = ['network', 'addr', 'name', 'nick', 'avatar', 'photo', 'thumb', 'micro'];
$mailcontact = DBA::selectFirst('contact', $fields, ["`addr` = ? AND `network` = ? AND `uid` != 0", $url, Protocol::MAIL]);
if (!DBA::isResult($mailcontact)) {
$mailcontact = DBA::selectFirst('contact', $fields, ["`nurl` = ? AND `network` = ? AND `uid` != 0", $url, Protocol::MAIL]);
}
if (DBA::isResult($mailcontact)) {
DBA::update('contact', $mailcontact, ['id' => $contact_id]);
}
$update_contact = false; $update_contact = false;
} }
@ -1743,7 +1754,7 @@ class Contact extends BaseObject
$sql = "`item`.`uid` = ?"; $sql = "`item`.`uid` = ?";
} }
$contact_field = ($contact["contact-type"] == self::TYPE_COMMUNITY ? 'owner-id' : 'author-id'); $contact_field = ((($contact["contact-type"] == self::TYPE_COMMUNITY) || ($contact['network'] == Protocol::MAIL)) ? 'owner-id' : 'author-id');
if ($thread_mode) { if ($thread_mode) {
$condition = ["`$contact_field` = ? AND `gravity` = ? AND " . $sql, $condition = ["`$contact_field` = ? AND `gravity` = ? AND " . $sql,

View file

@ -3833,7 +3833,7 @@ class Item extends BaseObject
$body = $shared_item['body']; $body = $shared_item['body'];
} }
$item['body'] = preg_replace("/(.*?\[share.*?\]\s?).*?(\s?\[\/share\]\s?)/ism", '$1' . $body . '$2', $item['body']); $item['body'] = preg_replace("/\[share ([^\[\]]*)\].*\[\/share\]/ism", '[share $1]' . $body . '[/share]', $item['body']);
unset($shared_item['body']); unset($shared_item['body']);
return array_merge($item, $shared_item); return array_merge($item, $shared_item);

View file

@ -64,7 +64,7 @@ class Verify extends BaseModule
'$errors_label' => L10n::tt('Error', 'Errors', count(self::$errors)), '$errors_label' => L10n::tt('Error', 'Errors', count(self::$errors)),
'$errors' => self::$errors, '$errors' => self::$errors,
'$recovery_message' => L10n::t('Dont have your phone? <a href="%s">Enter a two-factor recovery code</a>', '2fa/recovery'), '$recovery_message' => L10n::t('Dont have your phone? <a href="%s">Enter a two-factor recovery code</a>', '2fa/recovery'),
'$verify_code' => ['verify_code', L10n::t('Please enter a code from your authentication app'), '', '', 'required', 'autofocus placeholder="000000"'], '$verify_code' => ['verify_code', L10n::t('Please enter a code from your authentication app'), '', '', 'required', 'autofocus placeholder="000000"', 'number'],
'$verify_label' => L10n::t('Verify code and complete login'), '$verify_label' => L10n::t('Verify code and complete login'),
]); ]);
} }

View file

@ -381,16 +381,16 @@ class Transmitter
$terms = Term::tagArrayFromItemId($item['id'], [Term::MENTION, Term::IMPLICIT_MENTION]); $terms = Term::tagArrayFromItemId($item['id'], [Term::MENTION, Term::IMPLICIT_MENTION]);
// Directly mention the original author upon a quoted reshare.
// Else just ensure that the original author receives the reshare.
$announce = self::getAnnounceArray($item);
if (!empty($announce['comment'])) {
$data['to'][] = $announce['actor']['url'];
} elseif (!empty($announce)) {
$data['cc'][] = $announce['actor']['url'];
}
if (!$item['private']) { if (!$item['private']) {
// Directly mention the original author upon a quoted reshare.
// Else just ensure that the original author receives the reshare.
$announce = self::getAnnounceArray($item);
if (!empty($announce['comment'])) {
$data['to'][] = $announce['actor']['url'];
} elseif (!empty($announce)) {
$data['cc'][] = $announce['actor']['url'];
}
$data = array_merge($data, self::fetchPermissionBlockFromConversation($item)); $data = array_merge($data, self::fetchPermissionBlockFromConversation($item));
$data['to'][] = ActivityPub::PUBLIC_COLLECTION; $data['to'][] = ActivityPub::PUBLIC_COLLECTION;

View file

@ -130,19 +130,19 @@
// Custom visibility tags inputs // Custom visibility tags inputs
let acl_groups = new Bloodhound({ let acl_groups = new Bloodhound({
local: {{$acl_groups|@json_encode nofilter}}, local: {{$acl_groups|@json_encode nofilter}},
identify: function(obj) { return obj.id; }, identify: function(obj) { return obj.type + '-' + obj.id.toString(); },
datumTokenizer: Bloodhound.tokenizers.obj.whitespace(['name']), datumTokenizer: Bloodhound.tokenizers.obj.whitespace(['name']),
queryTokenizer: Bloodhound.tokenizers.whitespace, queryTokenizer: Bloodhound.tokenizers.whitespace,
}); });
let acl_contacts = new Bloodhound({ let acl_contacts = new Bloodhound({
local: {{$acl_contacts|@json_encode nofilter}}, local: {{$acl_contacts|@json_encode nofilter}},
identify: function(obj) { return obj.id; }, identify: function(obj) { return obj.type + '-' + obj.id.toString(); },
datumTokenizer: Bloodhound.tokenizers.obj.whitespace(['name', 'addr']), datumTokenizer: Bloodhound.tokenizers.obj.whitespace(['name', 'addr']),
queryTokenizer: Bloodhound.tokenizers.whitespace, queryTokenizer: Bloodhound.tokenizers.whitespace,
}); });
let acl = new Bloodhound({ let acl = new Bloodhound({
local: {{$acl_list|@json_encode nofilter}}, local: {{$acl_list|@json_encode nofilter}},
identify: function(obj) { return obj.id; }, identify: function(obj) { return obj.type + '-' + obj.id.toString(); },
datumTokenizer: Bloodhound.tokenizers.obj.whitespace(['name', 'addr']), datumTokenizer: Bloodhound.tokenizers.obj.whitespace(['name', 'addr']),
queryTokenizer: Bloodhound.tokenizers.whitespace, queryTokenizer: Bloodhound.tokenizers.whitespace,
}); });
@ -163,7 +163,7 @@
return 'label label-info'; return 'label label-info';
} }
}, },
itemValue: 'id', itemValue: function (item) { return item.type + '-' + item.id.toString(); },
itemText: 'name', itemText: 'name',
itemThumb: 'micro', itemThumb: 'micro',
itemTitle: function(item) { itemTitle: function(item) {
@ -191,7 +191,7 @@
return 'label label-info'; return 'label label-info';
} }
}, },
itemValue: 'id', itemValue: function (item) { return item.type + '-' + item.id.toString(); },
itemText: 'name', itemText: 'name',
itemThumb: 'micro', itemThumb: 'micro',
itemTitle: function(item) { itemTitle: function(item) {
@ -209,17 +209,17 @@
// Import existing ACL into the tags input fields. // Import existing ACL into the tags input fields.
$group_allow_input.val().split(',').forEach(function (val) { $group_allow_input.val().split(',').forEach(function (group_id) {
$acl_allow_input.tagsinput('add', acl_groups.get(val)[0]); $acl_allow_input.tagsinput('add', acl_groups.get('group-' + group_id)[0]);
}); });
$contact_allow_input.val().split(',').forEach(function (val) { $contact_allow_input.val().split(',').forEach(function (contact_id) {
$acl_allow_input.tagsinput('add', acl_contacts.get(val)[0]); $acl_allow_input.tagsinput('add', acl_contacts.get('contact-' + contact_id)[0]);
}); });
$group_deny_input.val().split(',').forEach(function (val) { $group_deny_input.val().split(',').forEach(function (group_id) {
$acl_deny_input.tagsinput('add', acl_groups.get(val)[0]); $acl_deny_input.tagsinput('add', acl_groups.get('group-' + group_id)[0]);
}); });
$contact_deny_input.val().split(',').forEach(function (val) { $contact_deny_input.val().split(',').forEach(function (contact_id) {
$acl_deny_input.tagsinput('add', acl_contacts.get(val)[0]); $acl_deny_input.tagsinput('add', acl_contacts.get('contact-' + contact_id)[0]);
}); });
// Anti-duplicate callback + acl fields value generation // Anti-duplicate callback + acl fields value generation

View file

@ -1,8 +1,8 @@
<div class='field input' id='wrapper_{{$field.0}}'> <div class="field input" id="wrapper_{{$field.0}}">
<label for='id_{{$field.0}}'>{{$field.1}}</label> <label for="id_{{$field.0}}">{{$field.1}}</label>
<input{{if $field.6 eq 'email'}} type='email'{{elseif $field.6 eq 'url'}} type='url'{{else}} type="text"{{/if}} name='{{$field.0}}' id='id_{{$field.0}}' value="{{$field.2 nofilter}}"{{if $field.4 eq 'required'}} required{{/if}}{{if $field.5 eq "autofocus"}} autofocus{{elseif $field.5}} {{$field.5 nofilter}}{{/if}} aria-describedby='{{$field.0}}_tip'> <input{{if $field.6}} type="{{$field.6}}"{{else}} type="text"{{/if}} name="{{$field.0}}" id="id_{{$field.0}}" value="{{$field.2 nofilter}}"{{if $field.4 eq 'required'}} required{{/if}}{{if $field.5 eq "autofocus"}} autofocus{{elseif $field.5}} {{$field.5 nofilter}}{{/if}} aria-describedby="{{$field.0}}_tip">
{{if $field.3}} {{if $field.3}}
<span class='field_help' role='tooltip' id='{{$field.0}}_tip'>{{$field.3 nofilter}}</span> <span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3 nofilter}}</span>
{{/if}} {{/if}}
</div> </div>

View file

@ -3,7 +3,7 @@
{{if !isset($label) || $label != false }} {{if !isset($label) || $label != false }}
<label for="id_{{$field.0}}" id="label_{{$field.0}}">{{$field.1 nofilter}}{{if $field.4}}<span class="required"> {{$field.4}}</span>{{/if}}</label> <label for="id_{{$field.0}}" id="label_{{$field.0}}">{{$field.1 nofilter}}{{if $field.4}}<span class="required"> {{$field.4}}</span>{{/if}}</label>
{{/if}} {{/if}}
<input class="form-control" name="{{$field.0}}" id="id_{{$field.0}}"{{if $field.6 eq "email"}} type="email"{{elseif $field.6 eq "url"}} type="url"{{else}} type="text"{{/if}} value="{{$field.2 nofilter}}"{{if $field.4 eq "required"}} required{{/if}}{{if $field.5 eq "autofocus"}} autofocus{{elseif $field.5}} {{$field.5 nofilter}}{{/if}} aria-describedby="{{$field.0}}_tip"> <input class="form-control" name="{{$field.0}}" id="id_{{$field.0}}"{{if $field.6}} type="{{$field.6}}"{{else}} type="text"{{/if}} value="{{$field.2 nofilter}}"{{if $field.4 eq "required"}} required{{/if}}{{if $field.5 eq "autofocus"}} autofocus{{elseif $field.5}} {{$field.5 nofilter}}{{/if}} aria-describedby="{{$field.0}}_tip">
{{if $field.3}} {{if $field.3}}
<span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.3 nofilter}}</span> <span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.3 nofilter}}</span>
{{/if}} {{/if}}