From 1f1d3b25788b8897b0ae9ea0db218178a9ed9c7d Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 2 Mar 2022 05:05:49 +0000 Subject: [PATCH 1/3] API: Only display active incoming contact requests --- .../Api/Twitter/Friendships/Incoming.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Module/Api/Twitter/Friendships/Incoming.php b/src/Module/Api/Twitter/Friendships/Incoming.php index 378159c3c2..d34d79fae0 100644 --- a/src/Module/Api/Twitter/Friendships/Incoming.php +++ b/src/Module/Api/Twitter/Friendships/Incoming.php @@ -46,32 +46,32 @@ class Incoming extends ContactEndpoint $max_id = $this->getRequestValue($request, 'max_id', 0, 0); $min_id = $this->getRequestValue($request, 'min_id', 0, 0); - $params = ['order' => ['cid' => true], 'limit' => $count]; + $params = ['order' => ['contact-id' => true], 'limit' => $count]; - $condition = ['uid' => $uid, 'pending' => true]; + $condition = ["`uid` = ? AND NOT `blocked` AND NOT `ignore` AND `contact-id` != 0 AND (`suggest-cid` = 0 OR `suggest-cid` IS NULL)", $uid]; - $total_count = (int)DBA::count('user-contact', $condition); + $total_count = (int)DBA::count('intro', $condition); if (!empty($max_id)) { - $condition = DBA::mergeConditions($condition, ["`cid` < ?", $max_id]); + $condition = DBA::mergeConditions($condition, ["`contact-id` < ?", $max_id]); } if (!empty($since_id)) { - $condition = DBA::mergeConditions($condition, ["`cid` > ?", $since_id]); + $condition = DBA::mergeConditions($condition, ["`contact-id` > ?", $since_id]); } if (!empty($min_id)) { - $condition = DBA::mergeConditions($condition, ["`cid` > ?", $min_id]); + $condition = DBA::mergeConditions($condition, ["`contact-id` > ?", $min_id]); - $params['order'] = ['cid']; + $params['order'] = ['contact-id']; } $ids = []; - $contacts = DBA::select('user-contact', ['cid'], $condition, $params); + $contacts = DBA::select('intro', ['contact-id'], $condition, $params); while ($contact = DBA::fetch($contacts)) { - self::setBoundaries($contact['cid']); - $ids[] = $contact['cid']; + self::setBoundaries($contact['contact-id']); + $ids[] = $contact['contact-id']; } DBA::close($contacts); From f853d58198b3ebee1af85bc76982e7552c2701e8 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 2 Mar 2022 06:59:07 +0000 Subject: [PATCH 2/3] API: Forum mentions are now working --- mod/item.php | 93 ++++++---------------- src/Content/Item.php | 73 ++++++++++++++++- src/Module/Api/Twitter/Statuses/Update.php | 7 +- 3 files changed, 98 insertions(+), 75 deletions(-) diff --git a/mod/item.php b/mod/item.php index bc35282e33..855e7de3f2 100644 --- a/mod/item.php +++ b/mod/item.php @@ -383,69 +383,34 @@ function item_post(App $a) { $contact_record = DBA::selectFirst('contact', [], ['uid' => $profile_uid, 'self' => true]) ?: []; } - // Look for any tags and linkify them - $inform = ''; - $private_forum = false; - $private_id = null; - $only_to_forum = false; - $forum_contact = []; - // Personal notes must never be altered to a forum post. if ($posttype != Item::PT_PERSONAL_NOTE) { - // Convert mentions in the body to a unified format - $body = BBCode::setMentions($body, local_user() ? local_user() : $profile_uid, $network); + // Look for any tags and linkify them + $item = [ + 'uid' => local_user() ? local_user() : $profile_uid, + 'gravity' => $toplevel_item_id ? GRAVITY_COMMENT : GRAVITY_PARENT, + 'network' => $network, + 'body' => $body, + 'postopts' => $postopts, + 'private' => $private, + 'allow_cid' => $str_contact_allow, + 'allow_gid' => $str_group_allow, + 'deny_cid' => $str_contact_deny, + 'deny_gid' => $str_group_deny, + ]; - // Search for forum mentions - foreach (Tag::getFromBody($body, Tag::TAG_CHARACTER[Tag::MENTION] . Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]) as $tag) { - $contact = Contact::getByURLForUser($tag[2], $profile_uid); - if (!empty($inform)) { - $inform .= ','; - } - $inform .= 'cid:' . $contact['id']; + $item = DI::contentItem()->expandTags($item); - if ($toplevel_item_id || empty($contact['cid']) || ($contact['contact-type'] != Contact::TYPE_COMMUNITY)) { - continue; - } - - if (!empty($contact['prv']) || ($tag[1] == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION])) { - $private_forum = $contact['prv']; - $only_to_forum = ($tag[1] == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]); - $private_id = $contact['id']; - $forum_contact = $contact; - Logger::info('Private forum or exclusive mention', ['url' => $tag[2], 'mention' => $tag[1]]); - } elseif ($str_contact_allow == '<' . $contact['id'] . '>') { - $private_forum = false; - $only_to_forum = true; - $private_id = $contact['id']; - $forum_contact = $contact; - Logger::info('Public forum', ['url' => $tag[2], 'mention' => $tag[1]]); - } else { - Logger::info('Post with forum mention will not be converted to a forum post', ['url' => $tag[2], 'mention' => $tag[1]]); - } - } - Logger::info('Got inform', ['inform' => $inform]); - } - - $original_contact_id = $contact_id; - - if (!$toplevel_item_id && !empty($forum_contact) && ($private_forum || $only_to_forum)) { - // we tagged a forum in a top level post. Now we change the post - $private = $private_forum ? Item::PRIVATE : Item::UNLISTED; - - if ($only_to_forum) { - $postopts = ''; - } - - $str_contact_deny = ''; - $str_group_deny = ''; - - if ($private_forum) { - $str_contact_allow = '<' . $private_id . '>'; - $str_group_allow = '<' . Group::getIdForForum($forum_contact['id']) . '>'; - } else { - $str_contact_allow = ''; - $str_group_allow = ''; - } + $body = $item['body']; + $inform = $item['inform']; + $postopts = $item['postopts']; + $private = $item['private']; + $str_contact_allow = $item['allow_cid']; + $str_group_allow = $item['allow_gid']; + $str_contact_deny = $item['deny_cid']; + $str_group_deny = $item['deny_gid']; + } else { + $inform = ''; } /* @@ -460,7 +425,7 @@ function item_post(App $a) { $match = null; - if (!$preview && Photo::setPermissionFromBody($body, $uid, $original_contact_id, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny)) { + if (!$preview && Photo::setPermissionFromBody($body, $uid, $contact_id, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny)) { $objecttype = Activity\ObjectType::IMAGE; } @@ -475,7 +440,7 @@ function item_post(App $a) { if (count($attaches)) { foreach ($attaches as $attach) { // Ensure to only modify attachments that you own - $srch = '<' . intval($original_contact_id) . '>'; + $srch = '<' . intval($contact_id) . '>'; $condition = ['allow_cid' => $srch, 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '', 'id' => $attach]; @@ -797,12 +762,6 @@ function item_post(App $a) { } } - // When we are doing some forum posting via ! we have to start the notifier manually. - // These kind of posts don't initiate the notifier call in the item class. - if ($only_to_forum) { - Worker::add(['priority' => PRIORITY_HIGH, 'dont_fork' => false], "Notifier", Delivery::POST, (int)$datarray['uri-id'], (int)$datarray['uid']); - } - Logger::info('post_complete'); if ($api_source) { diff --git a/src/Content/Item.php b/src/Content/Item.php index 5037be80e2..334507861b 100644 --- a/src/Content/Item.php +++ b/src/Content/Item.php @@ -21,12 +21,15 @@ namespace Friendica\Content; +use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\L10n; +use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Session; use Friendica\Database\DBA; use Friendica\Model\Contact; +use Friendica\Model\Group; use Friendica\Model\Item as ModelItem; use Friendica\Model\Tag; use Friendica\Model\Post; @@ -53,7 +56,7 @@ class Item $this->activity = $activity; $this->l10n = $l10n; } - + /** * Return array with details for categories and folders for an item * @@ -479,7 +482,7 @@ class Item if (empty($item['verb']) || $this->activity->isHidden($item['verb'])) { return false; } - + // @TODO below if() block can be rewritten to a single line: $isVisible = allConditionsHere; if ($this->activity->match($item['verb'], Activity::FOLLOW) && $item['object-type'] === Activity\ObjectType::NOTE && @@ -487,7 +490,71 @@ class Item $item['uid'] == local_user()) { return false; } - + return true; } + + public function expandTags(array $item) + { + // Look for any tags and linkify them + $item['inform'] = ''; + $private_forum = false; + $private_id = null; + $only_to_forum = false; + $forum_contact = []; + + // Convert mentions in the body to a unified format + $item['body'] = BBCode::setMentions($item['body'], $item['uid'], $item['network']); + + // Search for forum mentions + foreach (Tag::getFromBody($item['body'], Tag::TAG_CHARACTER[Tag::MENTION] . Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]) as $tag) { + $contact = Contact::getByURLForUser($tag[2], $item['uid']); + if (!empty($item['inform'])) { + $item['inform'] .= ','; + } + $item['inform'] .= 'cid:' . $contact['id']; + + if (($item['gravity'] == GRAVITY_COMMENT) || empty($contact['cid']) || ($contact['contact-type'] != Contact::TYPE_COMMUNITY)) { + continue; + } + + if (!empty($contact['prv']) || ($tag[1] == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION])) { + $private_forum = $contact['prv']; + $only_to_forum = ($tag[1] == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]); + $private_id = $contact['id']; + $forum_contact = $contact; + Logger::info('Private forum or exclusive mention', ['url' => $tag[2], 'mention' => $tag[1]]); + } elseif ($item['allow_cid'] == '<' . $contact['id'] . '>') { + $private_forum = false; + $only_to_forum = true; + $private_id = $contact['id']; + $forum_contact = $contact; + Logger::info('Public forum', ['url' => $tag[2], 'mention' => $tag[1]]); + } else { + Logger::info('Post with forum mention will not be converted to a forum post', ['url' => $tag[2], 'mention' => $tag[1]]); + } + } + Logger::info('Got inform', ['inform' => $item['inform']]); + + if (($item['gravity'] == GRAVITY_PARENT) && !empty($forum_contact) && ($private_forum || $only_to_forum)) { + // we tagged a forum in a top level post. Now we change the post + $item['private'] = $private_forum ? ModelItem::PRIVATE : ModelItem::UNLISTED; + + if ($only_to_forum) { + $item['postopts'] = ''; + } + + $item['deny_cid'] = ''; + $item['deny_gid'] = ''; + + if ($private_forum) { + $item['allow_cid'] = '<' . $private_id . '>'; + $item['allow_gid'] = '<' . Group::getIdForForum($forum_contact['id']) . '>'; + } else { + $item['allow_cid'] = ''; + $item['allow_gid'] = ''; + } + } + return $item; + } } diff --git a/src/Module/Api/Twitter/Statuses/Update.php b/src/Module/Api/Twitter/Statuses/Update.php index 45e56cea85..6ee305d19d 100644 --- a/src/Module/Api/Twitter/Statuses/Update.php +++ b/src/Module/Api/Twitter/Statuses/Update.php @@ -78,11 +78,6 @@ class Update extends BaseApi $body = Markdown::toBBCode($request['status']); } - // Avoids potential double expansion of existing links - $body = BBCode::performWithEscapedTags($body, ['url'], function ($body) { - return BBCode::expandTags($body); - }); - $item = []; $item['uid'] = $uid; $item['verb'] = Activity::POST; @@ -127,6 +122,8 @@ class Update extends BaseApi $item['object-type'] = Activity\ObjectType::NOTE; } + $item = DI::contentItem()->expandTags($item); + if (!empty($request['media_ids'])) { $ids = explode(',', $request['media_ids']); } elseif (!empty($_FILES['media'])) { From f059e56e0f82e64024da7dcbb1ecac20ad84c1b5 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 2 Mar 2022 17:17:07 +0000 Subject: [PATCH 3/3] Fix test / Use new expandTags function --- src/Module/Api/Mastodon/Statuses.php | 12 +++++------- src/Module/Api/Twitter/Statuses/Update.php | 6 +++--- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/Module/Api/Mastodon/Statuses.php b/src/Module/Api/Mastodon/Statuses.php index 7bf40c837e..1dd36f16b3 100644 --- a/src/Module/Api/Mastodon/Statuses.php +++ b/src/Module/Api/Mastodon/Statuses.php @@ -21,8 +21,8 @@ namespace Friendica\Module\Api\Mastodon; -use Friendica\Content\Text\BBCode; use Friendica\Content\Text\Markdown; +use Friendica\Core\Protocol; use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\DI; @@ -63,12 +63,8 @@ class Statuses extends BaseApi // The imput is defined as text. So we can use Markdown for some enhancements $body = Markdown::toBBCode($request['status']); - // Avoids potential double expansion of existing links - $body = BBCode::performWithEscapedTags($body, ['url'], function ($body) { - return BBCode::expandTags($body); - }); - - $item = []; + $item = []; + $item['network'] = Protocol::DFRN; $item['uid'] = $uid; $item['verb'] = Activity::POST; $item['contact-id'] = $owner['id']; @@ -149,6 +145,8 @@ class Statuses extends BaseApi $item['object-type'] = Activity\ObjectType::NOTE; } + $item = DI::contentItem()->expandTags($item); + if (!empty($request['media_ids'])) { $item['object-type'] = Activity\ObjectType::IMAGE; $item['post-type'] = Item::PT_IMAGE; diff --git a/src/Module/Api/Twitter/Statuses/Update.php b/src/Module/Api/Twitter/Statuses/Update.php index 6ee305d19d..c2b830b661 100644 --- a/src/Module/Api/Twitter/Statuses/Update.php +++ b/src/Module/Api/Twitter/Statuses/Update.php @@ -21,9 +21,9 @@ namespace Friendica\Module\Api\Twitter\Statuses; -use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Content\Text\Markdown; +use Friendica\Core\Protocol; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; @@ -79,11 +79,11 @@ class Update extends BaseApi } $item = []; + $item['network'] = Protocol::DFRN; $item['uid'] = $uid; $item['verb'] = Activity::POST; $item['contact-id'] = $owner['id']; - $item['author-id'] = Contact::getPublicIdByUserId($uid); - $item['owner-id'] = $item['author-id']; + $item['author-id'] = $item['owner-id'] = Contact::getPublicIdByUserId($uid); $item['title'] = $request['title']; $item['body'] = $body; $item['app'] = $request['source'];