From ca8a89ed1ca776469a8007a7aaddb13bf204fba9 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 13 Dec 2022 23:19:19 +0000 Subject: [PATCH 0001/1145] Use reshare with Diaspora like with ActivityPub --- database.sql | 4 +- doc/database/db_post-user.md | 2 +- src/Content/Conversation.php | 29 ++++++++- src/Factory/Api/Mastodon/Status.php | 13 +++- src/Model/Post/UserNotification.php | 29 ++++++++- src/Module/Api/Mastodon/Statuses/Reblog.php | 9 ++- src/Module/Api/Mastodon/Statuses/Unreblog.php | 15 ++++- src/Module/Item/Activity.php | 17 +++-- .../Notifications/Factory/Notification.php | 6 +- src/Protocol/Diaspora.php | 64 ------------------- static/dbstructure.config.php | 4 +- 11 files changed, 108 insertions(+), 84 deletions(-) diff --git a/database.sql b/database.sql index 49f282db0a..7285d7fa1e 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2022.12-rc (Giant Rhubarb) --- DB_UPDATE_VERSION 1501 +-- DB_UPDATE_VERSION 1502 -- ------------------------------------------ @@ -1439,7 +1439,7 @@ CREATE TABLE IF NOT EXISTS `post-user` ( `event-id` int unsigned COMMENT 'Used to link to the event.id', `unseen` boolean NOT NULL DEFAULT '1' COMMENT 'post has not been seen', `hidden` boolean NOT NULL DEFAULT '0' COMMENT 'Marker to hide the post from the user', - `notification-type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '', + `notification-type` smallint unsigned NOT NULL DEFAULT 0 COMMENT '', `wall` boolean NOT NULL DEFAULT '0' COMMENT 'This item was posted to the wall of uid', `origin` boolean NOT NULL DEFAULT '0' COMMENT 'item originated at this site', `psid` int unsigned COMMENT 'ID of the permission set of this post', diff --git a/doc/database/db_post-user.md b/doc/database/db_post-user.md index ce213941da..2fe91d144b 100644 --- a/doc/database/db_post-user.md +++ b/doc/database/db_post-user.md @@ -34,7 +34,7 @@ Fields | event-id | Used to link to the event.id | int unsigned | YES | | NULL | | | unseen | post has not been seen | boolean | NO | | 1 | | | hidden | Marker to hide the post from the user | boolean | NO | | 0 | | -| notification-type | | tinyint unsigned | NO | | 0 | | +| notification-type | | smallint unsigned | NO | | 0 | | | wall | This item was posted to the wall of uid | boolean | NO | | 0 | | | origin | item originated at this site | boolean | NO | | 0 | | | psid | ID of the permission set of this post | int unsigned | YES | | NULL | | diff --git a/src/Content/Conversation.php b/src/Content/Conversation.php index 6d19eb1635..f8885b5b07 100644 --- a/src/Content/Conversation.php +++ b/src/Content/Conversation.php @@ -985,7 +985,8 @@ class Conversation $thread_items = Post::selectForUser($uid, array_merge(ItemModel::DISPLAY_FIELDLIST, ['featured', 'contact-uid', 'gravity', 'post-type', 'post-reason']), $condition, $params); - $items = []; + $items = []; + $quoteuriids = []; while ($row = Post::fetch($thread_items)) { if (!empty($items[$row['uri-id']]) && ($row['uid'] == 0)) { @@ -1005,11 +1006,37 @@ class Conversation } } + if (in_array($row['gravity'], [ItemModel::GRAVITY_PARENT, ItemModel::GRAVITY_COMMENT])) { + $quoteuriids[$row['uri-id']] = [ + 'uri-id' => $row['uri-id'], + 'uri' => $row['uri'], + 'parent-uri-id' => $row['parent-uri-id'], + 'parent-uri' => $row['parent-uri'], + ]; + } + $items[$row['uri-id']] = $this->addRowInformation($row, $activities[$row['uri-id']] ?? [], $thr_parent[$row['thr-parent-id']] ?? []); } DBA::close($thread_items); + $quotes = Post::select(array_merge(ItemModel::DISPLAY_FIELDLIST, ['featured', 'contact-uid', 'gravity', 'post-type', 'post-reason']), ['quote-uri-id' => array_column($quoteuriids, 'uri-id'), 'uid' => 0]); + while ($quote = Post::fetch($quotes)) { + $row = $quote; + + $row['uid'] = $uid; + $row['verb'] = $row['body'] = $row['raw-body'] = Activity::ANNOUNCE; + $row['gravity'] = ItemModel::GRAVITY_ACTIVITY; + $row['object-type'] = Activity\ObjectType::NOTE; + $row['parent-uri'] = $quoteuriids[$quote['quote-uri-id']]['parent-uri']; + $row['parent-uri-id'] = $quoteuriids[$quote['quote-uri-id']]['parent-uri-id']; + $row['thr-parent'] = $quoteuriids[$quote['quote-uri-id']]['uri']; + $row['thr-parent-id'] = $quoteuriids[$quote['quote-uri-id']]['uri-id']; + + $items[$row['uri-id']] = $this->addRowInformation($row, [], []); + } + DBA::close($quotes); + $items = $this->convSort($items, $order); $this->profiler->stopRecording(); diff --git a/src/Factory/Api/Mastodon/Status.php b/src/Factory/Api/Mastodon/Status.php index 18701bb661..698c127f72 100644 --- a/src/Factory/Api/Mastodon/Status.php +++ b/src/Factory/Api/Mastodon/Status.php @@ -115,13 +115,17 @@ class Status extends BaseFactory 'gravity' => Item::GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::ANNOUNCE), 'deleted' => false - ], []); + ]) + Post::countPosts([ + 'quote-uri-id' => $uriId, + 'deleted' => false + ]); + $count_like = Post::countPosts([ 'thr-parent-id' => $uriId, 'gravity' => Item::GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::LIKE), 'deleted' => false - ], []); + ]); $counts = new \Friendica\Object\Api\Mastodon\Status\Counts( Post::countPosts(['thr-parent-id' => $uriId, 'gravity' => Item::GRAVITY_COMMENT, 'deleted' => false], []), @@ -144,6 +148,11 @@ class Status extends BaseFactory 'gravity' => Item::GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::ANNOUNCE), 'deleted' => false + ]) || Post::exists([ + 'quote-uri-id' => $uriId, + 'uid' => $uid, + 'origin' => true, + 'deleted' => false ]); $userAttributes = new \Friendica\Object\Api\Mastodon\Status\UserAttributes( $origin_like, diff --git a/src/Model/Post/UserNotification.php b/src/Model/Post/UserNotification.php index d872d5c41c..44a7dd9000 100644 --- a/src/Model/Post/UserNotification.php +++ b/src/Model/Post/UserNotification.php @@ -27,7 +27,6 @@ use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Database\Database; use Friendica\Database\DBA; -use Friendica\Database\DBStructure; use Friendica\DI; use Friendica\Model\Contact; use Friendica\Model\Item; @@ -52,6 +51,7 @@ class UserNotification const TYPE_DIRECT_THREAD_COMMENT = 64; const TYPE_SHARED = 128; const TYPE_FOLLOW = 256; + const TYPE_QUOTED = 512; /** * Insert a new user notification entry @@ -273,6 +273,14 @@ class UserNotification } } + if (($item['verb'] != Activity::ANNOUNCE) && self::checkQuoted($item, $contacts)) { + $notification_type = $notification_type | self::TYPE_QUOTED; + if (!$notified) { + self::insertNotificationByItem(self::TYPE_QUOTED, $uid, $item); + $notified = true; + } + } + if (($item['verb'] != Activity::ANNOUNCE) && self::checkFollowParticipation($item, $contacts)) { $notification_type = $notification_type | self::TYPE_FOLLOW; if (!$notified) { @@ -581,4 +589,23 @@ class UserNotification $condition = ['parent' => $item['parent'], 'author-id' => $contacts, 'deleted' => false, 'gravity' => Item::GRAVITY_ACTIVITY]; return Post::exists($condition); } + + /** + * Check for a quoted post of a post of the given user + * + * @param array $item + * @param array $contacts Array of contact IDs + * @return bool The item is a quoted post of a user's post or comment + * @throws Exception + */ + private static function checkQuoted(array $item, array $contacts): bool + { + if (empty($item['quote-uri-id'])) { + return false; + } + $condition = ['uri-id' => $item['quote-uri-id'], 'uid' => $item['uid'], 'author-id' => $contacts, 'deleted' => false, 'gravity' => [item::GRAVITY_PARENT, Item::GRAVITY_COMMENT]]; + return Post::exists($condition); + } + + } diff --git a/src/Module/Api/Mastodon/Statuses/Reblog.php b/src/Module/Api/Mastodon/Statuses/Reblog.php index 65b641ab89..bf4a739466 100644 --- a/src/Module/Api/Mastodon/Statuses/Reblog.php +++ b/src/Module/Api/Mastodon/Statuses/Reblog.php @@ -29,6 +29,7 @@ use Friendica\DI; use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Module\BaseApi; +use Friendica\Protocol\Diaspora; /** * @see https://docs.joinmastodon.org/methods/statuses/ @@ -49,12 +50,14 @@ class Reblog extends BaseApi DI::mstdnError()->RecordNotFound(); } - if (!in_array($item['network'], [Protocol::DFRN, Protocol::ACTIVITYPUB, Protocol::TWITTER])) { + if ($item['network'] == Protocol::DIASPORA) { + Diaspora::performReshare($this->parameters['id'], $uid); + } elseif (!in_array($item['network'], [Protocol::DFRN, Protocol::ACTIVITYPUB, Protocol::TWITTER])) { DI::mstdnError()->UnprocessableEntity(DI::l10n()->t("Posts from %s can't be shared", ContactSelector::networkToName($item['network']))); + } else { + Item::performActivity($item['id'], 'announce', $uid); } - Item::performActivity($item['id'], 'announce', $uid); - System::jsonExit(DI::mstdnStatus()->createFromUriId($this->parameters['id'], $uid)->toArray()); } } diff --git a/src/Module/Api/Mastodon/Statuses/Unreblog.php b/src/Module/Api/Mastodon/Statuses/Unreblog.php index a6741c6de2..faacefe38d 100644 --- a/src/Module/Api/Mastodon/Statuses/Unreblog.php +++ b/src/Module/Api/Mastodon/Statuses/Unreblog.php @@ -49,12 +49,21 @@ class Unreblog extends BaseApi DI::mstdnError()->RecordNotFound(); } - if (!in_array($item['network'], [Protocol::DFRN, Protocol::ACTIVITYPUB, Protocol::TWITTER])) { + if ($item['network'] == Protocol::DIASPORA) { + $item = Post::selectFirstForUser($uid, ['id'], ['quote-uri-id' => $this->parameters['id'], 'origin' => true, 'uid' => $uid]); + if (empty($item['id'])) { + DI::mstdnError()->RecordNotFound(); + } + + if (!Item::markForDeletionById($item['id'])) { + DI::mstdnError()->RecordNotFound(); + } + } elseif (!in_array($item['network'], [Protocol::DFRN, Protocol::ACTIVITYPUB, Protocol::TWITTER])) { DI::mstdnError()->UnprocessableEntity(DI::l10n()->t("Posts from %s can't be unshared", ContactSelector::networkToName($item['network']))); + } else { + Item::performActivity($item['id'], 'unannounce', $uid); } - Item::performActivity($item['id'], 'unannounce', $uid); - System::jsonExit(DI::mstdnStatus()->createFromUriId($this->parameters['id'], $uid)->toArray()); } } diff --git a/src/Module/Item/Activity.php b/src/Module/Item/Activity.php index 3fa6d38fc9..c52882efb8 100644 --- a/src/Module/Item/Activity.php +++ b/src/Module/Item/Activity.php @@ -46,17 +46,26 @@ class Activity extends BaseModule throw new HTTPException\BadRequestException(); } - $verb = $this->parameters['verb']; - $itemId = $this->parameters['id']; + $verb = $this->parameters['verb']; + $itemId = $this->parameters['id']; + $handled = false; if (in_array($verb, ['announce', 'unannounce'])) { $item = Post::selectFirst(['network', 'uri-id'], ['id' => $itemId, 'uid' => [DI::userSession()->getLocalUserId(), 0]]); if ($item['network'] == Protocol::DIASPORA) { - Diaspora::performReshare($item['uri-id'], DI::userSession()->getLocalUserId()); + $quote = Post::selectFirst(['id'], ['quote-uri-id' => $item['uri-id'], 'origin' => true, 'uid' => DI::userSession()->getLocalUserId()]); + if (!empty($quote['id'])) { + if (!Item::markForDeletionById($quote['id'])) { + throw new HTTPException\BadRequestException(); + } + } else { + Diaspora::performReshare($item['uri-id'], DI::userSession()->getLocalUserId()); + } + $handled = true; } } - if (!Item::performActivity($itemId, $verb, DI::userSession()->getLocalUserId())) { + if (!$handled && !Item::performActivity($itemId, $verb, DI::userSession()->getLocalUserId())) { throw new HTTPException\BadRequestException(); } diff --git a/src/Navigation/Notifications/Factory/Notification.php b/src/Navigation/Notifications/Factory/Notification.php index 7f6988b3bf..86d462e0b2 100644 --- a/src/Navigation/Notifications/Factory/Notification.php +++ b/src/Navigation/Notifications/Factory/Notification.php @@ -311,7 +311,11 @@ class Notification extends BaseFactory implements ICanCreateFromTableRow $msg = $l10n->t('%1$s shared a post'); } break; - } + + case Post\UserNotification::TYPE_QUOTED: + $msg = $l10n->t('%1$s shared your post %2$s'); + break; + } break; } } diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index fe5b27d334..8e2dc56d9e 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -2285,65 +2285,6 @@ class Diaspora return true; } - /** - * Stores a reshare activity - * - * @param array $item Array of reshare post - * @param integer $parent_message_id Id of the parent post - * @param string $guid GUID string of reshare action - * @param WebFingerUri $author Author handle - * @return false|void - * @throws InternalServerErrorException - * @throws \ImagickException - */ - private static function addReshareActivity(array $item, int $parent_message_id, string $guid, WebFingerUri $author) - { - $parent = Post::selectFirst(['uri', 'guid'], ['id' => $parent_message_id]); - - $datarray = []; - - $datarray['uid'] = $item['uid']; - $datarray['contact-id'] = $item['contact-id']; - $datarray['network'] = $item['network']; - - $datarray['author-link'] = $item['author-link']; - $datarray['author-id'] = $item['author-id']; - - $datarray['owner-link'] = $datarray['author-link']; - $datarray['owner-id'] = $datarray['author-id']; - - $datarray['guid'] = $parent['guid'] . '-' . $guid; - $datarray['uri'] = self::getUriFromGuid($datarray['guid'], $author); - $datarray['thr-parent'] = $parent['uri']; - - $datarray['verb'] = $datarray['body'] = Activity::ANNOUNCE; - $datarray['gravity'] = Item::GRAVITY_ACTIVITY; - $datarray['object-type'] = Activity\ObjectType::NOTE; - - $datarray['protocol'] = $item['protocol']; - $datarray['source'] = $item['source']; - $datarray['direction'] = $item['direction']; - $datarray['post-reason'] = $item['post-reason']; - - $datarray['plink'] = self::plink($author, $datarray['guid']); - $datarray['private'] = $item['private']; - $datarray['changed'] = $datarray['created'] = $datarray['edited'] = $item['created']; - - if (Item::isTooOld($datarray)) { - Logger::info('Reshare activity is too old', ['created' => $datarray['created'], 'uid' => $datarray['uid'], 'guid' => $datarray['guid']]); - return false; - } - - $message_id = Item::insert($datarray); - - if ($message_id) { - Logger::info('Stored reshare activity.', ['guid' => $guid, 'id' => $message_id]); - if ($datarray['uid'] == 0) { - Item::distribute($message_id); - } - } - } - /** * Processes a reshare message * @@ -2436,11 +2377,6 @@ class Diaspora self::sendParticipation($contact, $datarray); - $root_message_id = self::messageExists($importer['uid'], $root_guid); - if ($root_message_id) { - self::addReshareActivity($datarray, $root_message_id, $guid, $author); - } - if ($message_id) { Logger::info('Stored reshare ' . $datarray['guid'] . ' with message id ' . $message_id); if ($datarray['uid'] == 0) { diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index d9ff07178b..4a340d1f7b 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -55,7 +55,7 @@ use Friendica\Database\DBA; if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1501); + define('DB_UPDATE_VERSION', 1502); } return [ @@ -1458,7 +1458,7 @@ return [ "event-id" => ["type" => "int unsigned", "foreign" => ["event" => "id"], "comment" => "Used to link to the event.id"], "unseen" => ["type" => "boolean", "not null" => "1", "default" => "1", "comment" => "post has not been seen"], "hidden" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Marker to hide the post from the user"], - "notification-type" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => ""], + "notification-type" => ["type" => "smallint unsigned", "not null" => "1", "default" => "0", "comment" => ""], "wall" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "This item was posted to the wall of uid"], "origin" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "item originated at this site"], "psid" => ["type" => "int unsigned", "foreign" => ["permissionset" => "id", "on delete" => "restrict"], "comment" => "ID of the permission set of this post"], From f013c92487b5590b226e864ab9eb4c807dfe8faf Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 13 Dec 2022 23:26:58 +0000 Subject: [PATCH 0002/1145] Only search for empty quoted reshares (Diaspora type) --- src/Content/Conversation.php | 2 +- src/Factory/Api/Mastodon/Status.php | 4 +++- src/Module/Api/Mastodon/Statuses/Unreblog.php | 2 +- src/Module/Item/Activity.php | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Content/Conversation.php b/src/Content/Conversation.php index f8885b5b07..aa7c016180 100644 --- a/src/Content/Conversation.php +++ b/src/Content/Conversation.php @@ -1020,7 +1020,7 @@ class Conversation DBA::close($thread_items); - $quotes = Post::select(array_merge(ItemModel::DISPLAY_FIELDLIST, ['featured', 'contact-uid', 'gravity', 'post-type', 'post-reason']), ['quote-uri-id' => array_column($quoteuriids, 'uri-id'), 'uid' => 0]); + $quotes = Post::select(array_merge(ItemModel::DISPLAY_FIELDLIST, ['featured', 'contact-uid', 'gravity', 'post-type', 'post-reason']), ['quote-uri-id' => array_column($quoteuriids, 'uri-id'), 'body' => '', 'uid' => 0]); while ($quote = Post::fetch($quotes)) { $row = $quote; diff --git a/src/Factory/Api/Mastodon/Status.php b/src/Factory/Api/Mastodon/Status.php index 698c127f72..df5970d298 100644 --- a/src/Factory/Api/Mastodon/Status.php +++ b/src/Factory/Api/Mastodon/Status.php @@ -117,7 +117,8 @@ class Status extends BaseFactory 'deleted' => false ]) + Post::countPosts([ 'quote-uri-id' => $uriId, - 'deleted' => false + 'body' => '', + 'deleted' => false ]); $count_like = Post::countPosts([ @@ -152,6 +153,7 @@ class Status extends BaseFactory 'quote-uri-id' => $uriId, 'uid' => $uid, 'origin' => true, + 'body' => '', 'deleted' => false ]); $userAttributes = new \Friendica\Object\Api\Mastodon\Status\UserAttributes( diff --git a/src/Module/Api/Mastodon/Statuses/Unreblog.php b/src/Module/Api/Mastodon/Statuses/Unreblog.php index faacefe38d..afb84e2630 100644 --- a/src/Module/Api/Mastodon/Statuses/Unreblog.php +++ b/src/Module/Api/Mastodon/Statuses/Unreblog.php @@ -50,7 +50,7 @@ class Unreblog extends BaseApi } if ($item['network'] == Protocol::DIASPORA) { - $item = Post::selectFirstForUser($uid, ['id'], ['quote-uri-id' => $this->parameters['id'], 'origin' => true, 'uid' => $uid]); + $item = Post::selectFirstForUser($uid, ['id'], ['quote-uri-id' => $this->parameters['id'], 'body' => '', 'origin' => true, 'uid' => $uid]); if (empty($item['id'])) { DI::mstdnError()->RecordNotFound(); } diff --git a/src/Module/Item/Activity.php b/src/Module/Item/Activity.php index c52882efb8..bcfb83513b 100644 --- a/src/Module/Item/Activity.php +++ b/src/Module/Item/Activity.php @@ -53,7 +53,7 @@ class Activity extends BaseModule if (in_array($verb, ['announce', 'unannounce'])) { $item = Post::selectFirst(['network', 'uri-id'], ['id' => $itemId, 'uid' => [DI::userSession()->getLocalUserId(), 0]]); if ($item['network'] == Protocol::DIASPORA) { - $quote = Post::selectFirst(['id'], ['quote-uri-id' => $item['uri-id'], 'origin' => true, 'uid' => DI::userSession()->getLocalUserId()]); + $quote = Post::selectFirst(['id'], ['quote-uri-id' => $item['uri-id'], 'body' => '', 'origin' => true, 'uid' => DI::userSession()->getLocalUserId()]); if (!empty($quote['id'])) { if (!Item::markForDeletionById($quote['id'])) { throw new HTTPException\BadRequestException(); From 6e6c9314afdb270841e1e67065fe9a35c10551f0 Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Tue, 20 Dec 2022 06:50:37 +0100 Subject: [PATCH 0003/1145] prepare the CHANGELOG for 2023.03 --- CHANGELOG | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 3cddea4763..472c5af189 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +Version 2023.03 (unreleased) + Friendica Core + + Friendica Addons + + Closed Issues + Version 2022.12 (2022-12-20) Friendica Core Updates to the translations DE, FR, HU, PL, RU From c84f18ef669b4d2713cd8da8d66d4c8d39a14b8f Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Tue, 20 Dec 2022 06:52:15 +0100 Subject: [PATCH 0004/1145] bump VERSION to 2023.03-dev --- VERSION | 2 +- database.sql | 2 +- src/App.php | 2 +- view/lang/C/messages.po | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index b66c15a015..f0bc8ce38a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2022.12 +2023.03-dev diff --git a/database.sql b/database.sql index 6667b697fd..3e9fba679a 100644 --- a/database.sql +++ b/database.sql @@ -1,5 +1,5 @@ -- ------------------------------------------ --- Friendica 2022.12 (Giant Rhubarb) +-- Friendica 2023.03-dev (Giant Rhubarb) -- DB_UPDATE_VERSION 1502 -- ------------------------------------------ diff --git a/src/App.php b/src/App.php index db3ebbd67c..eb0d1cc217 100644 --- a/src/App.php +++ b/src/App.php @@ -64,7 +64,7 @@ class App { const PLATFORM = 'Friendica'; const CODENAME = 'Giant Rhubarb'; - const VERSION = '2022.12'; + const VERSION = '2023.03-dev'; // Allow themes to control internal parameters // by changing App values in theme.php diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index c660dac5c1..28951eb314 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -6,7 +6,7 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: 2022.12\n" +"Project-Id-Version: 2023.03-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-17 23:06-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" From 1ed5fb349964893c74b778e7c8d25b172dca3f32 Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Tue, 20 Dec 2022 06:53:14 +0100 Subject: [PATCH 0005/1145] renewed the expiration date for the security.txt file --- security.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security.txt b/security.txt index 6a20672fa9..1624a69cfe 100644 --- a/security.txt +++ b/security.txt @@ -1,6 +1,6 @@ Contact: mailto:info@friendi.ca -Expires: Sat, 30 Sept 2023 23:59 +0000 +Expires: Sun, 31 Dec 2023 23:59 +0000 Preferred-Languages: en From bdc865afaeb891a38445353fe824b558fb4f35e5 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 20 Dec 2022 06:22:11 +0000 Subject: [PATCH 0006/1145] Measures against several warnings and errors in the log --- src/Model/Contact.php | 16 ++++++++++++---- src/Network/Probe.php | 13 +++++++++++-- src/Object/Image.php | 24 +++++++++++------------- src/Protocol/Diaspora.php | 2 +- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index b703f82a00..392f777615 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1386,14 +1386,18 @@ class Contact if ($data['network'] == Protocol::DIASPORA) { try { DI::dsprContact()->updateFromProbeArray($data); + } catch (HTTPException\NotFoundException $e) { + Logger::notice($e->getMessage(), ['url' => $url, 'data' => $data]); } catch (\InvalidArgumentException $e) { - Logger::error($e->getMessage(), ['url' => $url, 'data' => $data]); + Logger::notice($e->getMessage(), ['url' => $url, 'data' => $data]); } } elseif (!empty($data['networks'][Protocol::DIASPORA])) { try { DI::dsprContact()->updateFromProbeArray($data['networks'][Protocol::DIASPORA]); + } catch (HTTPException\NotFoundException $e) { + Logger::notice($e->getMessage(), ['url' => $url, 'data' => $data['networks'][Protocol::DIASPORA]]); } catch (\InvalidArgumentException $e) { - Logger::error($e->getMessage(), ['url' => $url, 'data' => $data['networks'][Protocol::DIASPORA]]); + Logger::notice($e->getMessage(), ['url' => $url, 'data' => $data['networks'][Protocol::DIASPORA]]); } } @@ -2498,14 +2502,18 @@ class Contact if ($data['network'] == Protocol::DIASPORA) { try { DI::dsprContact()->updateFromProbeArray($data); + } catch (HTTPException\NotFoundException $e) { + Logger::notice($e->getMessage(), ['id' => $id, 'network' => $network, 'contact' => $contact, 'data' => $data]); } catch (\InvalidArgumentException $e) { - Logger::error($e->getMessage(), ['id' => $id, 'network' => $network, 'contact' => $contact, 'data' => $data]); + Logger::notice($e->getMessage(), ['id' => $id, 'network' => $network, 'contact' => $contact, 'data' => $data]); } } elseif (!empty($data['networks'][Protocol::DIASPORA])) { try { DI::dsprContact()->updateFromProbeArray($data['networks'][Protocol::DIASPORA]); + } catch (HTTPException\NotFoundException $e) { + Logger::notice($e->getMessage(), ['id' => $id, 'network' => $network, 'contact' => $contact, 'data' => $data]); } catch (\InvalidArgumentException $e) { - Logger::error($e->getMessage(), ['id' => $id, 'network' => $network, 'contact' => $contact, 'data' => $data]); + Logger::notice($e->getMessage(), ['id' => $id, 'network' => $network, 'contact' => $contact, 'data' => $data]); } } diff --git a/src/Network/Probe.php b/src/Network/Probe.php index 5a8f75e2d8..44348dcd74 100644 --- a/src/Network/Probe.php +++ b/src/Network/Probe.php @@ -139,8 +139,17 @@ class Probe foreach ([Protocol::DIASPORA, Protocol::OSTATUS] as $network) { if (!empty($data['networks'][$network])) { $data['networks'][$network]['subscribe'] = $newdata['subscribe'] ?? ''; - $data['networks'][$network]['baseurl'] = $newdata['baseurl'] ?? ''; - $data['networks'][$network]['gsid'] = $newdata['gsid'] ?? 0; + if (empty($data['networks'][$network]['baseurl'])) { + $data['networks'][$network]['baseurl'] = $newdata['baseurl'] ?? ''; + } else { + $newdata['baseurl'] = $data['networks'][$network]['baseurl']; + } + if (!empty($newdata['baseurl'])) { + $newdata['gsid'] = $data['networks'][$network]['gsid'] = GServer::getID($newdata['baseurl']); + } else { + $newdata['gsid'] = $data['networks'][$network]['gsid'] = null; + } + $newdata['networks'][$network] = self::rearrangeData($data['networks'][$network]); unset($newdata['networks'][$network]['networks']); } diff --git a/src/Object/Image.php b/src/Object/Image.php index 06498f963f..7069f7a47f 100644 --- a/src/Object/Image.php +++ b/src/Object/Image.php @@ -66,6 +66,7 @@ class Image $this->type = $type; if ($this->isImagick() && (empty($data) || $this->loadData($data))) { + $this->valid = !empty($data); return; } else { // Failed to load with Imagick, fallback @@ -158,12 +159,11 @@ class Image $this->image->setCompressionQuality($quality); } - // The 'width' and 'height' properties are only used by non-Imagick routines. $this->width = $this->image->getImageWidth(); $this->height = $this->image->getImageHeight(); - $this->valid = true; + $this->valid = !empty($this->image); - return true; + return $this->valid; } $this->valid = false; @@ -210,9 +210,6 @@ class Image return false; } - if ($this->isImagick()) { - return $this->image->getImageWidth(); - } return $this->width; } @@ -225,9 +222,6 @@ class Image return false; } - if ($this->isImagick()) { - return $this->image->getImageHeight(); - } return $this->height; } @@ -353,6 +347,9 @@ class Image do { $this->image->rotateImage(new ImagickPixel(), -$degrees); // ImageMagick rotates in the opposite direction of imagerotate() } while ($this->image->nextImage()); + + $this->width = $this->image->getImageWidth(); + $this->height = $this->image->getImageHeight(); return; } @@ -576,7 +573,6 @@ class Image } } while ($this->image->nextImage()); - // These may not be necessary anymore $this->width = $this->image->getImageWidth(); $this->height = $this->image->getImageHeight(); } else { @@ -659,7 +655,7 @@ class Image if ($this->image) { imagedestroy($this->image); } - $this->image = $dest; + $this->image = $dest; $this->width = imagesx($this->image); $this->height = imagesy($this->image); @@ -734,7 +730,7 @@ class Image public function getBlurHash(): string { $image = New Image($this->asString()); - if (empty($image)) { + if (empty($image) || !$this->isValid()) { return ''; } @@ -809,12 +805,14 @@ class Image if ($this->isImagick()) { $this->image->drawImage($draw); + $this->width = $this->image->getImageWidth(); + $this->height = $this->image->getImageHeight(); } else { $this->width = imagesx($this->image); $this->height = imagesy($this->image); } - $this->valid = true; + $this->valid = !empty($this->image); $this->scaleUp(min($width, $height)); } diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index fe5b27d334..16b0c918e1 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -499,7 +499,7 @@ class Diaspora } if (!($fields = self::validPosting($msg))) { - Logger::warning('Invalid posting', ['msg' => $msg]); + Logger::notice('Invalid posting', ['msg' => $msg]); return false; } From a0faca9eaf86814d23ee9bb76fe22254ba29a388 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 20 Dec 2022 07:00:10 +0000 Subject: [PATCH 0007/1145] Updated database version --- database.sql | 2 +- static/dbstructure.config.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/database.sql b/database.sql index 78559f78f3..d93c979f05 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2023.03-dev (Giant Rhubarb) --- DB_UPDATE_VERSION 1502 +-- DB_UPDATE_VERSION 1503 -- ------------------------------------------ diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 4a340d1f7b..ac2bb0e1ea 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -55,7 +55,7 @@ use Friendica\Database\DBA; if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1502); + define('DB_UPDATE_VERSION', 1503); } return [ From d95fe1c41f6830f53becbf6aac721848214da657 Mon Sep 17 00:00:00 2001 From: MarekBenjamin <117765478+MarekBenjamin@users.noreply.github.com> Date: Tue, 20 Dec 2022 12:47:05 +0100 Subject: [PATCH 0008/1145] Update CHANGELOG Typo --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 472c5af189..5cccb7d0a4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -26,7 +26,7 @@ Version 2022.12 (2022-12-20) Added a moderation section to the admin panel [annando] Added an option to make the calendar public [matthiasmoritz] Fixed a bug in the federation with Diaspora* [annando] - Fixec a problem in the federation with GoTo Social and Owncast [annando] + Fixed a problem in the federation with GoTo Social and Owncast [annando] Deprecated old themes (duepuntozero, quattro, smoothy) NOTE: The Apache2 rewrite rule in the .htaccess-dist has been changed. From de1c0f4c139fcbb5341a3176e12bf5dad53c802b Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 20 Dec 2022 19:25:57 +0000 Subject: [PATCH 0009/1145] Don't display Diaspora reshares --- src/Content/Conversation.php | 16 ++++++++-------- src/Model/Contact.php | 4 ++-- src/Module/Api/Mastodon/Accounts/Statuses.php | 9 +++++---- .../Notifications/Factory/Notification.php | 2 +- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/Content/Conversation.php b/src/Content/Conversation.php index aa7c016180..d9036c7839 100644 --- a/src/Content/Conversation.php +++ b/src/Content/Conversation.php @@ -985,8 +985,8 @@ class Conversation $thread_items = Post::selectForUser($uid, array_merge(ItemModel::DISPLAY_FIELDLIST, ['featured', 'contact-uid', 'gravity', 'post-type', 'post-reason']), $condition, $params); - $items = []; - $quoteuriids = []; + $items = []; + $quote_uri_ids = []; while ($row = Post::fetch($thread_items)) { if (!empty($items[$row['uri-id']]) && ($row['uid'] == 0)) { @@ -1007,7 +1007,7 @@ class Conversation } if (in_array($row['gravity'], [ItemModel::GRAVITY_PARENT, ItemModel::GRAVITY_COMMENT])) { - $quoteuriids[$row['uri-id']] = [ + $quote_uri_ids[$row['uri-id']] = [ 'uri-id' => $row['uri-id'], 'uri' => $row['uri'], 'parent-uri-id' => $row['parent-uri-id'], @@ -1020,7 +1020,7 @@ class Conversation DBA::close($thread_items); - $quotes = Post::select(array_merge(ItemModel::DISPLAY_FIELDLIST, ['featured', 'contact-uid', 'gravity', 'post-type', 'post-reason']), ['quote-uri-id' => array_column($quoteuriids, 'uri-id'), 'body' => '', 'uid' => 0]); + $quotes = Post::select(array_merge(ItemModel::DISPLAY_FIELDLIST, ['featured', 'contact-uid', 'gravity', 'post-type', 'post-reason']), ['quote-uri-id' => array_column($quote_uri_ids, 'uri-id'), 'body' => '', 'uid' => 0]); while ($quote = Post::fetch($quotes)) { $row = $quote; @@ -1028,10 +1028,10 @@ class Conversation $row['verb'] = $row['body'] = $row['raw-body'] = Activity::ANNOUNCE; $row['gravity'] = ItemModel::GRAVITY_ACTIVITY; $row['object-type'] = Activity\ObjectType::NOTE; - $row['parent-uri'] = $quoteuriids[$quote['quote-uri-id']]['parent-uri']; - $row['parent-uri-id'] = $quoteuriids[$quote['quote-uri-id']]['parent-uri-id']; - $row['thr-parent'] = $quoteuriids[$quote['quote-uri-id']]['uri']; - $row['thr-parent-id'] = $quoteuriids[$quote['quote-uri-id']]['uri-id']; + $row['parent-uri'] = $quote_uri_ids[$quote['quote-uri-id']]['parent-uri']; + $row['parent-uri-id'] = $quote_uri_ids[$quote['quote-uri-id']]['parent-uri-id']; + $row['thr-parent'] = $quote_uri_ids[$quote['quote-uri-id']]['uri']; + $row['thr-parent-id'] = $quote_uri_ids[$quote['quote-uri-id']]['uri-id']; $items[$row['uri-id']] = $this->addRowInformation($row, [], []); } diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 392f777615..2003b4608e 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1544,8 +1544,8 @@ class Contact $contact_field = ((($contact["contact-type"] == self::TYPE_COMMUNITY) || ($contact['network'] == Protocol::MAIL)) ? 'owner-id' : 'author-id'); if ($thread_mode) { - $condition = ["((`$contact_field` = ? AND `gravity` = ?) OR (`author-id` = ? AND `gravity` = ? AND `vid` = ? AND `thr-parent-id` = `parent-uri-id`)) AND " . $sql, - $cid, Item::GRAVITY_PARENT, $cid, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), DI::userSession()->getLocalUserId()]; + $condition = ["((`$contact_field` = ? AND `gravity` = ?) OR (`author-id` = ? AND `gravity` = ? AND `vid` = ? AND `protocol` != ? AND `thr-parent-id` = `parent-uri-id`)) AND " . $sql, + $cid, Item::GRAVITY_PARENT, $cid, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), Conversation::PARCEL_DIASPORA, DI::userSession()->getLocalUserId()]; } else { $condition = ["`$contact_field` = ? AND `gravity` IN (?, ?) AND " . $sql, $cid, Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT, DI::userSession()->getLocalUserId()]; diff --git a/src/Module/Api/Mastodon/Accounts/Statuses.php b/src/Module/Api/Mastodon/Accounts/Statuses.php index b9bb63ae78..36f730404a 100644 --- a/src/Module/Api/Mastodon/Accounts/Statuses.php +++ b/src/Module/Api/Mastodon/Accounts/Statuses.php @@ -26,6 +26,7 @@ use Friendica\Core\Protocol; use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\DI; +use Friendica\Model\Conversation; use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Model\Verb; @@ -81,11 +82,11 @@ class Statuses extends BaseApi if (!$request['pinned'] && !$request['only_media']) { if ($request['exclude_replies']) { - $condition = DBA::mergeConditions($condition, ["(`gravity` = ? OR (`gravity` = ? AND `vid` = ?))", - Item::GRAVITY_PARENT, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE)]); + $condition = DBA::mergeConditions($condition, ["(`gravity` = ? OR (`gravity` = ? AND `vid` = ? AND `protocol` != ?))", + Item::GRAVITY_PARENT, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), Conversation::PARCEL_DIASPORA]); } else { - $condition = DBA::mergeConditions($condition, ["(`gravity` IN (?, ?) OR (`gravity` = ? AND `vid` = ?))", - Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE)]); + $condition = DBA::mergeConditions($condition, ["(`gravity` IN (?, ?) OR (`gravity` = ? AND `vid` = ? AND `protocol` != ?))", + Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), Conversation::PARCEL_DIASPORA]); } } elseif ($request['exclude_replies']) { $condition = DBA::mergeConditions($condition, ['gravity' => Item::GRAVITY_PARENT]); diff --git a/src/Navigation/Notifications/Factory/Notification.php b/src/Navigation/Notifications/Factory/Notification.php index 86d462e0b2..6368820f6a 100644 --- a/src/Navigation/Notifications/Factory/Notification.php +++ b/src/Navigation/Notifications/Factory/Notification.php @@ -315,7 +315,7 @@ class Notification extends BaseFactory implements ICanCreateFromTableRow case Post\UserNotification::TYPE_QUOTED: $msg = $l10n->t('%1$s shared your post %2$s'); break; - } + } break; } } From 69a9f9033d19950ce11938945c8d9361d57d5825 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 20 Dec 2022 22:29:53 +0000 Subject: [PATCH 0010/1145] Three systems added to the federation statistics --- src/Module/Admin/Federation.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Module/Admin/Federation.php b/src/Module/Admin/Federation.php index 0fae254ddc..e591650999 100644 --- a/src/Module/Admin/Federation.php +++ b/src/Module/Admin/Federation.php @@ -42,9 +42,12 @@ class Federation extends BaseAdmin 'akkoma' => ['name' => 'Akkoma', 'color' => '#9574cd'], // Color from the page 'birdsitelive' => ['name' => 'BirdsiteLIVE', 'color' => '#1b6ec2'], // Color from the page 'bookwyrm' => ['name' => 'BookWyrm', 'color' => '#00d1b2'], // Color from the page + 'calckey' => ['name' => 'Calckey', 'color' => '#286983'], // Color from the page 'castopod' => ['name' => 'Castopod', 'color' => '#00564a'], // Background color from the page 'diaspora' => ['name' => 'Diaspora', 'color' => '#a1a1a1'], // logo is black and white, makes a gray + 'foundkey' => ['name' => 'Foundkey', 'color' => '#609926'], // Some random color from the repository 'funkwhale' => ['name' => 'Funkwhale', 'color' => '#4082B4'], // From the homepage + 'gancio' => ['name' => 'Gancio', 'color' => '#7253ed'], // Fontcolor from the page 'gnusocial' => ['name' => 'GNU Social/Statusnet', 'color' => '#a22430'], // dark red from the logo 'gotosocial' => ['name' => 'GoToSocial', 'color' => '#df8958'], // Some color from their mascot 'hometown' => ['name' => 'Hometown', 'color' => '#1f70c1'], // Color from the Patreon page @@ -128,6 +131,8 @@ class Federation extends BaseAdmin $platform = 'pleroma'; } elseif(stristr($platform, 'statusnet')) { $platform = 'gnusocial'; + } elseif(stristr($platform, 'nextcloud')) { + $platform = 'nextcloud'; } elseif(stristr($platform, 'wordpress')) { $platform = 'wordpress'; } elseif (in_array($platform, ['activityrelay', 'pub-relay', 'selective-relay', 'aoderelay'])) { From e6f0e3c23eb29a878242fadc38a648a16b70261e Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 20 Dec 2022 22:32:24 +0000 Subject: [PATCH 0011/1145] Don't calculate the blurhash on images without a size --- src/Object/Image.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Object/Image.php b/src/Object/Image.php index 7069f7a47f..1d2832f20a 100644 --- a/src/Object/Image.php +++ b/src/Object/Image.php @@ -734,15 +734,19 @@ class Image return ''; } - $width = $image->getWidth(); + $width = $image->getWidth(); $height = $image->getHeight(); if (max($width, $height) > 90) { $image->scaleDown(90); - $width = $image->getWidth(); + $width = $image->getWidth(); $height = $image->getHeight(); } + if (empty($width) || empty($height)) { + return ''; + } + $pixels = []; for ($y = 0; $y < $height; ++$y) { $row = []; From 90d99bc3e86a3e6eeea9ee889db2ba184614b1a1 Mon Sep 17 00:00:00 2001 From: Marek Bachmann Date: Wed, 21 Dec 2022 20:05:35 +0100 Subject: [PATCH 0012/1145] Changed registration text input to text area since BBcode is allowed there (was single line input) --- view/templates/admin/site.tpl | 2 +- view/theme/frio/templates/admin/site.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/view/templates/admin/site.tpl b/view/templates/admin/site.tpl index 3861b9b7f4..abdabbcc82 100644 --- a/view/templates/admin/site.tpl +++ b/view/templates/admin/site.tpl @@ -31,7 +31,7 @@

{{$registration}}

- {{include file="field_input.tpl" field=$register_text}} + {{include file="field_textarea.tpl" field=$register_text}} {{include file="field_select.tpl" field=$register_policy}} {{include file="field_input.tpl" field=$daily_registrations}} {{include file="field_checkbox.tpl" field=$enable_multi_reg}} diff --git a/view/theme/frio/templates/admin/site.tpl b/view/theme/frio/templates/admin/site.tpl index fea32ccc89..05a25f6cb7 100644 --- a/view/theme/frio/templates/admin/site.tpl +++ b/view/theme/frio/templates/admin/site.tpl @@ -70,7 +70,7 @@
- {{include file="field_input.tpl" field=$register_text}} + {{include file="field_textarea.tpl" field=$register_text}} {{include file="field_select.tpl" field=$register_policy}} {{include file="field_input.tpl" field=$daily_registrations}} {{include file="field_checkbox.tpl" field=$enable_multi_reg}} From d75cd8a00a88a52e6d7bf67c91ba464c81c644c1 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 21 Dec 2022 22:21:22 +0000 Subject: [PATCH 0013/1145] The GNU-Social import is removed --- src/Module/Contact/Follow.php | 5 ++--- src/Module/Search/Acl.php | 4 ++-- src/Module/User/PortableContacts.php | 4 ---- src/Protocol/DFRN.php | 4 ++-- src/Protocol/OStatus.php | 10 ++++------ 5 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/Module/Contact/Follow.php b/src/Module/Contact/Follow.php index f8b88c05fc..0b4363b4c1 100644 --- a/src/Module/Contact/Follow.php +++ b/src/Module/Contact/Follow.php @@ -105,11 +105,10 @@ class Follow extends BaseModule // Don't try to add a pending contact $userContact = Contact::selectFirst(['pending'], [ - "`uid` = ? AND ((`rel` != ?) OR (`network` = ?)) AND (`nurl` = ? OR `alias` = ? OR `alias` = ?) AND `network` != ?", + "`uid` = ? AND ((`rel` != ?) OR (`network` = ?)) AND (`nurl` = ? OR `alias` = ? OR `alias` = ?)", $uid, Contact::FOLLOWER, Protocol::DFRN, Strings::normaliseLink($url), - Strings::normaliseLink($url), $url, - Protocol::STATUSNET]); + Strings::normaliseLink($url), $url]); if (!empty($userContact['pending'])) { $this->sysMessages->addNotice($this->t('You already added this contact.')); diff --git a/src/Module/Search/Acl.php b/src/Module/Search/Acl.php index ddf45303b3..9f072b91c9 100644 --- a/src/Module/Search/Acl.php +++ b/src/Module/Search/Acl.php @@ -135,13 +135,13 @@ class Acl extends BaseModule switch ($type) { case self::TYPE_MENTION_CONTACT_GROUP: $condition = DBA::mergeConditions($condition, - ["NOT `self` AND NOT `blocked` AND `notify` != ? AND NOT `network` IN (?, ?)", '', Protocol::OSTATUS, Protocol::STATUSNET + ["NOT `self` AND NOT `blocked` AND `notify` != ? AND `network` != ?", '', Protocol::OSTATUS ]); break; case self::TYPE_MENTION_CONTACT: $condition = DBA::mergeConditions($condition, - ["NOT `self` AND NOT `blocked` AND `notify` != ? AND `network` != ?", '', Protocol::STATUSNET + ["NOT `self` AND NOT `blocked` AND `notify` != ?", '' ]); break; diff --git a/src/Module/User/PortableContacts.php b/src/Module/User/PortableContacts.php index 6a3c1201d9..9f98ca7ebe 100644 --- a/src/Module/User/PortableContacts.php +++ b/src/Module/User/PortableContacts.php @@ -223,10 +223,6 @@ class PortableContacts extends BaseModule if ($selectedFields['network']) { $entry['network'] = $contact['network']; - if ($entry['network'] == Protocol::STATUSNET) { - $entry['network'] = Protocol::OSTATUS; - } - if (($entry['network'] == '') && ($contact['self'])) { $entry['network'] = Protocol::DFRN; } diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index 9900708ed0..e29cfcc5ab 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -1066,8 +1066,8 @@ class DFRN $fields = ['id', 'uid', 'url', 'network', 'avatar-date', 'avatar', 'name-date', 'uri-date', 'addr', 'name', 'nick', 'about', 'location', 'keywords', 'xmpp', 'bdyear', 'bd', 'hidden', 'contact-type']; - $condition = ["`uid` = ? AND `nurl` = ? AND `network` != ? AND NOT `pending` AND NOT `blocked`", - $importer["importer_uid"], Strings::normaliseLink($author["link"]), Protocol::STATUSNET]; + $condition = ["`uid` = ? AND `nurl` = ? AND NOT `pending` AND NOT `blocked`", + $importer["importer_uid"], Strings::normaliseLink($author["link"])]; if ($importer['account-type'] != User::ACCOUNT_TYPE_COMMUNITY) { $condition = DBA::mergeConditions($condition, ['rel' => [Contact::SHARING, Contact::FRIEND]]); diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index ee9c015a9c..81a0c38842 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -103,9 +103,9 @@ class OStatus */ if ($aliaslink != '') { $contact = DBA::selectFirst('contact', [], [ - "`uid` = ? AND `alias` = ? AND `network` != ? AND `rel` IN (?, ?)", + "`uid` = ? AND `alias` = ? AND `rel` IN (?, ?)", $importer['uid'], - $aliaslink, Protocol::STATUSNET, + $aliaslink, Contact::SHARING, Contact::FRIEND, ]); } @@ -116,11 +116,10 @@ class OStatus } $contact = DBA::selectFirst('contact', [], [ - "`uid` = ? AND `nurl` IN (?, ?) AND `network` != ? AND `rel` IN (?, ?)", + "`uid` = ? AND `nurl` IN (?, ?) AND `rel` IN (?, ?)", $importer['uid'], Strings::normaliseLink($author['author-link']), Strings::normaliseLink($aliaslink), - Protocol::STATUSNET, Contact::SHARING, Contact::FRIEND, ]); @@ -128,10 +127,9 @@ class OStatus if (!DBA::isResult($contact) && ($addr != '')) { $contact = DBA::selectFirst('contact', [], [ - "`uid` = ? AND `addr` = ? AND `network` != ? AND `rel` IN (?, ?)", + "`uid` = ? AND `addr` = ? AND `rel` IN (?, ?)", $importer['uid'], $addr, - Protocol::STATUSNET, Contact::SHARING, Contact::FRIEND, ]); From 9fe70af85a9bc6ca69e6e708009420042e665d3f Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 22 Dec 2022 21:58:51 +0000 Subject: [PATCH 0014/1145] AP: Support for "move" and "accept" from gup.pe --- src/Protocol/ActivityPub/Processor.php | 57 +++++++++++++++++++++++++- src/Protocol/ActivityPub/Receiver.php | 31 ++++++++++---- 2 files changed, 77 insertions(+), 11 deletions(-) diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index d098ddb691..a18d6be774 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -1733,6 +1733,38 @@ class Processor Queue::remove($activity); } + /** + * Add moved contacts as followers for all subscribers of the old contact + * + * @param array $activity + * @return void + * @throws \Friendica\Network\HTTPException\InternalServerErrorException + */ + public static function movePerson(array $activity) + { + if (empty($activity['target_id']) || empty($activity['object_id'])) { + return; + } + + if ($activity['object_id'] != $activity['actor']) { + Logger::notice('Object is not the actor', ['activity' => $activity]); + return; + } + + $from = Contact::getByURL($activity['object_id'], false, ['uri-id']); + if (empty($from['uri-id'])) { + Logger::info('Object not found', ['activity' => $activity]); + return; + } + + $contacts = DBA::select('contact', ['uid', 'url'], ["`uri-id` = ? AND `uid` != ? AND `rel` IN (?, ?)", $from['uri-id'], 0, Contact::FRIEND, Contact::SHARING]); + while ($from_contact = DBA::fetch($contacts)) { + $result = Contact::createFromProbeForUser($from_contact['uid'], $activity['target_id']); + Logger::debug('Follower added', ['from' => $from_contact, 'result' => $result]); + } + DBA::close($contacts); + } + /** * Blocks the user by the contact * @@ -1792,17 +1824,38 @@ class Processor */ public static function acceptFollowUser(array $activity) { - $uid = User::getIdForURL($activity['object_actor']); + if (!empty($activity['object_actor'])) { + $uid = User::getIdForURL($activity['object_actor']); + $check_id = false; + } elseif (!empty($activity['receiver']) && (count($activity['receiver']) == 1)) { + $uid = array_shift($activity['receiver']); + $check_id = true; + } + if (empty($uid)) { + Logger::notice('User could not be detected', ['activity' => $activity]); + Queue::remove($activity); return; } $cid = Contact::getIdForURL($activity['actor'], $uid); if (empty($cid)) { - Logger::info('No contact found', ['actor' => $activity['actor']]); + Logger::notice('No contact found', ['actor' => $activity['actor']]); + Queue::remove($activity); return; } + $id = Transmitter::activityIDFromContact($cid); + if ($id == $activity['object_id']) { + Logger::info('Successful id check', ['uid' => $uid, 'cid' => $cid]); + } else { + Logger::info('Unsuccessful id check', ['uid' => $uid, 'cid' => $cid, 'id' => $id, 'object_id' => $activity['object_id']]); + if ($check_id) { + Queue::remove($activity); + return; + } + } + self::switchContact($cid); $fields = ['pending' => false]; diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index 8939822742..cb76ca7e18 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -451,7 +451,7 @@ class Receiver $object_data['object_id'] = $object_id; $object_data['object_type'] = ''; // Since we don't fetch the object, we don't know the type $object_data['push'] = $push; - } elseif (in_array($type, ['as:Add', 'as:Remove'])) { + } elseif (in_array($type, ['as:Add', 'as:Remove', 'as:Move'])) { $object_data = []; $object_data['id'] = JsonLD::fetchElement($activity, '@id'); $object_data['target_id'] = JsonLD::fetchElement($activity, 'as:target', '@id'); @@ -669,10 +669,6 @@ class Receiver $object_data['recursion-depth'] = $activity['recursion-depth']; } - if (in_array('as:Question', [$object_data['object_type'] ?? '', $object_data['object_object_type'] ?? ''])) { - self::storeUnhandledActivity(false, $type, $object_data, $activity, $body, $uid, $trust_source, $push, $signer); - } - if (!self::routeActivities($object_data, $type, $push)) { self::storeUnhandledActivity(true, $type, $object_data, $activity, $body, $uid, $trust_source, $push, $signer); Queue::remove($object_data); @@ -702,6 +698,8 @@ class Receiver } elseif (in_array($object_data['object_type'], ['pt:CacheFile'])) { // Unhandled Peertube activity Queue::remove($object_data); + } elseif (in_array($object_data['object_type'], self::ACCOUNT_TYPES)) { + ActivityPub\Processor::updatePerson($object_data); } else { return false; } @@ -739,7 +737,8 @@ class Receiver $item = ActivityPub\Processor::createItem($object_data, $fetch_parents); if (empty($item)) { Logger::debug('announced id was not created', ['id' => $object_data['id']]); - return false; + Queue::remove($object_data); + return true; } $item['post-reason'] = Item::PR_ANNOUNCEMENT; @@ -775,7 +774,7 @@ class Receiver case 'as:Like': if (in_array($object_data['object_type'], self::CONTENT_TYPES)) { ActivityPub\Processor::createActivity($object_data, Activity::LIKE); - } elseif ($object_data['object_type'] == '') { + } elseif (in_array($object_data['object_type'], ['', 'as:Tombstone'])) { // The object type couldn't be determined. We don't have it and we can't fetch it. We ignore this activity. Queue::remove($object_data); } else { @@ -786,7 +785,7 @@ class Receiver case 'as:Dislike': if (in_array($object_data['object_type'], self::CONTENT_TYPES)) { ActivityPub\Processor::createActivity($object_data, Activity::DISLIKE); - } elseif ($object_data['object_type'] == '') { + } elseif (in_array($object_data['object_type'], ['', 'as:Tombstone'])) { // The object type couldn't be determined. We don't have it and we can't fetch it. We ignore this activity. Queue::remove($object_data); } else { @@ -828,6 +827,14 @@ class Receiver } break; + case 'as:Move': + if (in_array($object_data['object_type'], self::ACCOUNT_TYPES)) { + ActivityPub\Processor::movePerson($object_data); + } else { + return false; + } + break; + case 'as:Block': if (in_array($object_data['object_type'], self::ACCOUNT_TYPES)) { ActivityPub\Processor::blockAccount($object_data); @@ -867,6 +874,9 @@ class Receiver } } elseif (in_array($object_data['object_type'], self::CONTENT_TYPES)) { ActivityPub\Processor::createActivity($object_data, Activity::ATTEND); + } elseif (!empty($object_data['object_id']) && empty($object_data['object_actor']) && empty($object_data['object_type'])) { + // Follow acceptances from gup.pe only contain the object id + ActivityPub\Processor::acceptFollowUser($object_data); } else { return false; } @@ -906,6 +916,9 @@ class Receiver in_array($object_data['object_object_type'], ['pt:CacheFile'])) { // Unhandled Peertube activity Queue::remove($object_data); + } elseif (in_array($object_data['object_type'], ['as:Delete'])) { + // We cannot undo deletions, so we just ignore this + Queue::remove($object_data); } else { return false; } @@ -972,7 +985,7 @@ class Receiver $tempfile = tempnam(System::getTempPath(), $file); file_put_contents($tempfile, json_encode(['activity' => $activity, 'body' => $body, 'uid' => $uid, 'trust_source' => $trust_source, 'push' => $push, 'signer' => $signer, 'object_data' => $object_data], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); - Logger::notice('Unknown activity stored', ['type' => $type, 'object_type' => $object_data['object_type'], $object_data['object_object_type'] ?? '', 'file' => $tempfile]); + Logger::notice('Unknown activity stored', ['type' => $type, 'object_type' => $object_data['object_type'], 'object_object_type' => $object_data['object_object_type'] ?? '', 'file' => $tempfile]); } /** From 99284222c1d7fb4adca9077e3057faf3b36f7180 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 22 Dec 2022 22:08:42 +0000 Subject: [PATCH 0015/1145] Remove the activity --- src/Protocol/ActivityPub/Processor.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index a18d6be774..d689ba72a5 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -1715,11 +1715,13 @@ class Processor { if (empty($activity['object_id']) || empty($activity['actor'])) { Logger::info('Empty object id or actor.'); + Queue::remove($activity); return; } if ($activity['object_id'] != $activity['actor']) { Logger::info('Object id does not match actor.'); + Queue::remove($activity); return; } @@ -1743,17 +1745,20 @@ class Processor public static function movePerson(array $activity) { if (empty($activity['target_id']) || empty($activity['object_id'])) { + Queue::remove($activity); return; } if ($activity['object_id'] != $activity['actor']) { Logger::notice('Object is not the actor', ['activity' => $activity]); + Queue::remove($activity); return; } $from = Contact::getByURL($activity['object_id'], false, ['uri-id']); if (empty($from['uri-id'])) { Logger::info('Object not found', ['activity' => $activity]); + Queue::remove($activity); return; } @@ -1763,6 +1768,7 @@ class Processor Logger::debug('Follower added', ['from' => $from_contact, 'result' => $result]); } DBA::close($contacts); + Queue::remove($activity); } /** From 82eec270faab5cb2b830d9b7e81eb3517897194a Mon Sep 17 00:00:00 2001 From: Marek Bachmann Date: Fri, 23 Dec 2022 00:56:26 +0100 Subject: [PATCH 0016/1145] Change email subject to "(...)like in conversation(...)" for likes instead of "(...)new comment(...)" --- src/Navigation/Notifications/Repository/Notify.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Navigation/Notifications/Repository/Notify.php b/src/Navigation/Notifications/Repository/Notify.php index 75aff6b870..a0a1d5b513 100644 --- a/src/Navigation/Notifications/Repository/Notify.php +++ b/src/Navigation/Notifications/Repository/Notify.php @@ -783,9 +783,15 @@ class Notify extends BaseRepository $subject = $l10n->t('%s %s shared a new post', $subjectPrefix, $contact['name']); } else { $params['type'] = Model\Notification\Type::COMMENT; - $subject = $l10n->t('%1$s Comment to conversation #%2$d by %3$s', $subjectPrefix, $item['parent'], $contact['name']); + if ($params['verb'] = Activity::LIKE) { + $subject = $l10n->t('%1$s Like in conversation #%2$d by %3$s', $subjectPrefix, $item['parent'], $contact['name']); + } else { + $subject = $l10n->t('%1$s Comment to conversation #%2$d by %3$s', $subjectPrefix, $item['parent'], $contact['name']); + } } + + $msg = $this->notification->getMessageFromNotification($Notification); if (empty($msg)) { $this->logger->info('No notification message, quitting', ['uid' => $Notification->uid, 'id' => $Notification->id, 'type' => $Notification->type]); From ef4f508f9b574f649164ca86f51ef5ca7c4ecb51 Mon Sep 17 00:00:00 2001 From: Marek Bachmann Date: Fri, 23 Dec 2022 01:06:21 +0100 Subject: [PATCH 0017/1145] messages.po and and corrected typo in comment --- .../Notifications/Repository/Notify.php | 2 +- view/lang/C/messages.po | 742 +++++++++--------- 2 files changed, 375 insertions(+), 369 deletions(-) diff --git a/src/Navigation/Notifications/Repository/Notify.php b/src/Navigation/Notifications/Repository/Notify.php index a0a1d5b513..7af61d0b68 100644 --- a/src/Navigation/Notifications/Repository/Notify.php +++ b/src/Navigation/Notifications/Repository/Notify.php @@ -771,7 +771,7 @@ class Notify extends BaseRepository $title = '"' . trim(str_replace("\n", " ", $title)) . '"'; } - // Some mail software relies on subject field for threading. + // Some mail software rely on subject field for threading. // So, we cannot have different subjects for notifications of the same thread. // Before this we have the name of the replier on the subject rendering // different subjects for messages on the same thread. diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index 28951eb314..e4d20b57e5 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2023.03-dev\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-12-17 23:06-0500\n" +"POT-Creation-Date: 2022-12-23 01:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -29,7 +29,7 @@ msgstr "" #: src/Module/Calendar/Event/API.php:88 src/Module/Calendar/Event/Form.php:84 #: src/Module/Calendar/Export.php:62 src/Module/Calendar/Show.php:82 #: src/Module/Contact/Advanced.php:60 src/Module/Contact/Follow.php:86 -#: src/Module/Contact/Follow.php:160 src/Module/Contact/MatchInterests.php:86 +#: src/Module/Contact/Follow.php:159 src/Module/Contact/MatchInterests.php:86 #: src/Module/Contact/Suggestions.php:54 src/Module/Contact/Unfollow.php:66 #: src/Module/Contact/Unfollow.php:80 src/Module/Contact/Unfollow.php:112 #: src/Module/Delegation.php:118 src/Module/FollowConfirm.php:38 @@ -38,8 +38,8 @@ msgstr "" #: src/Module/Notifications/Notification.php:76 #: src/Module/Notifications/Notification.php:107 #: src/Module/OStatus/Repair.php:60 src/Module/OStatus/Subscribe.php:66 -#: src/Module/Post/Edit.php:76 src/Module/Profile/Common.php:55 -#: src/Module/Profile/Contacts.php:55 src/Module/Profile/Photos.php:92 +#: src/Module/Post/Edit.php:76 src/Module/Profile/Common.php:75 +#: src/Module/Profile/Contacts.php:78 src/Module/Profile/Photos.php:92 #: src/Module/Profile/Schedule.php:39 src/Module/Profile/Schedule.php:56 #: src/Module/Profile/UnkMail.php:69 src/Module/Profile/UnkMail.php:121 #: src/Module/Profile/UnkMail.php:132 src/Module/Register.php:77 @@ -310,7 +310,7 @@ msgstr "" #: src/Module/Install.php:252 src/Module/Install.php:294 #: src/Module/Install.php:331 src/Module/Invite.php:178 #: src/Module/Item/Compose.php:189 src/Module/Moderation/Item/Source.php:79 -#: src/Module/Profile/Profile.php:239 src/Module/Profile/UnkMail.php:156 +#: src/Module/Profile/Profile.php:274 src/Module/Profile/UnkMail.php:156 #: src/Module/Settings/Profile/Index.php:231 src/Object/Post.php:986 #: view/theme/duepuntozero/config.php:85 view/theme/frio/config.php:171 #: view/theme/quattro/config.php:87 view/theme/vier/config.php:135 @@ -387,31 +387,31 @@ msgstr "" #: src/Model/Event.php:514 src/Model/Profile.php:234 #: src/Module/Calendar/Export.php:67 src/Module/Calendar/Show.php:74 #: src/Module/DFRN/Poll.php:43 src/Module/Feed.php:65 src/Module/HCard.php:51 -#: src/Module/Profile/Common.php:40 src/Module/Profile/Common.php:51 -#: src/Module/Profile/Contacts.php:39 src/Module/Profile/Contacts.php:49 +#: src/Module/Profile/Common.php:62 src/Module/Profile/Common.php:71 +#: src/Module/Profile/Contacts.php:64 src/Module/Profile/Contacts.php:72 #: src/Module/Profile/Media.php:38 src/Module/Profile/Photos.php:83 -#: src/Module/Profile/RemoteFollow.php:71 src/Module/Profile/Status.php:58 +#: src/Module/Profile/RemoteFollow.php:71 src/Module/Profile/Status.php:91 #: src/Module/Register.php:267 msgid "User not found." msgstr "" #: mod/photos.php:105 src/Module/BaseProfile.php:68 -#: src/Module/Profile/Photos.php:407 +#: src/Module/Profile/Photos.php:399 msgid "Photo Albums" msgstr "" -#: mod/photos.php:106 src/Module/Profile/Photos.php:408 -#: src/Module/Profile/Photos.php:423 +#: mod/photos.php:106 src/Module/Profile/Photos.php:400 +#: src/Module/Profile/Photos.php:420 msgid "Recent Photos" msgstr "" -#: mod/photos.php:108 mod/photos.php:872 src/Module/Profile/Photos.php:410 -#: src/Module/Profile/Photos.php:425 +#: mod/photos.php:108 mod/photos.php:872 src/Module/Profile/Photos.php:402 +#: src/Module/Profile/Photos.php:422 msgid "Upload New Photos" msgstr "" #: mod/photos.php:126 src/Module/BaseSettings.php:74 -#: src/Module/Profile/Photos.php:391 +#: src/Module/Profile/Photos.php:383 msgid "everybody" msgstr "" @@ -489,7 +489,7 @@ msgid "Delete Album" msgstr "" #: mod/photos.php:803 mod/photos.php:904 src/Content/Conversation.php:389 -#: src/Module/Contact/Follow.php:173 src/Module/Contact/Revoke.php:109 +#: src/Module/Contact/Follow.php:172 src/Module/Contact/Revoke.php:109 #: src/Module/Contact/Unfollow.php:126 #: src/Module/Media/Attachment/Browser.php:77 #: src/Module/Media/Photo/Browser.php:88 src/Module/Post/Edit.php:164 @@ -514,7 +514,7 @@ msgstr "" msgid "Show Oldest First" msgstr "" -#: mod/photos.php:857 src/Module/Profile/Photos.php:378 +#: mod/photos.php:857 src/Module/Profile/Photos.php:370 msgid "View Photo" msgstr "" @@ -595,7 +595,7 @@ msgid "Rotate CCW (left)" msgstr "" #: mod/photos.php:1134 mod/photos.php:1190 mod/photos.php:1264 -#: src/Module/Contact.php:547 src/Module/Item/Compose.php:188 +#: src/Module/Contact.php:550 src/Module/Item/Compose.php:188 #: src/Object/Post.php:983 msgid "This is you" msgstr "" @@ -695,16 +695,16 @@ msgid "All contacts" msgstr "" #: src/BaseModule.php:424 src/Content/Widget.php:235 src/Core/ACL.php:194 -#: src/Module/Contact.php:370 src/Module/PermissionTooltip.php:122 +#: src/Module/Contact.php:371 src/Module/PermissionTooltip.php:122 #: src/Module/PermissionTooltip.php:144 msgid "Followers" msgstr "" -#: src/BaseModule.php:429 src/Content/Widget.php:236 src/Module/Contact.php:371 +#: src/BaseModule.php:429 src/Content/Widget.php:236 src/Module/Contact.php:372 msgid "Following" msgstr "" -#: src/BaseModule.php:434 src/Content/Widget.php:237 src/Module/Contact.php:372 +#: src/BaseModule.php:434 src/Content/Widget.php:237 src/Module/Contact.php:373 msgid "Mutual friends" msgstr "" @@ -1539,35 +1539,35 @@ msgstr "" msgid "Follow Thread" msgstr "" -#: src/Content/Item.php:387 src/Model/Contact.php:1213 +#: src/Content/Item.php:387 src/Model/Contact.php:1198 msgid "View Status" msgstr "" -#: src/Content/Item.php:388 src/Content/Item.php:406 src/Model/Contact.php:1151 -#: src/Model/Contact.php:1205 src/Model/Contact.php:1214 +#: src/Content/Item.php:388 src/Content/Item.php:406 src/Model/Contact.php:1142 +#: src/Model/Contact.php:1190 src/Model/Contact.php:1199 #: src/Module/Directory.php:157 src/Module/Settings/Profile/Index.php:234 msgid "View Profile" msgstr "" -#: src/Content/Item.php:389 src/Model/Contact.php:1215 +#: src/Content/Item.php:389 src/Model/Contact.php:1200 msgid "View Photos" msgstr "" -#: src/Content/Item.php:390 src/Model/Contact.php:1206 -#: src/Model/Contact.php:1216 +#: src/Content/Item.php:390 src/Model/Contact.php:1191 +#: src/Model/Contact.php:1201 msgid "Network Posts" msgstr "" -#: src/Content/Item.php:391 src/Model/Contact.php:1207 -#: src/Model/Contact.php:1217 +#: src/Content/Item.php:391 src/Model/Contact.php:1192 +#: src/Model/Contact.php:1202 msgid "View Contact" msgstr "" -#: src/Content/Item.php:392 src/Model/Contact.php:1218 +#: src/Content/Item.php:392 src/Model/Contact.php:1203 msgid "Send PM" msgstr "" -#: src/Content/Item.php:393 src/Module/Contact.php:401 +#: src/Content/Item.php:393 src/Module/Contact.php:402 #: src/Module/Contact/Profile.php:348 src/Module/Contact/Profile.php:467 #: src/Module/Moderation/Blocklist/Contact.php:116 #: src/Module/Moderation/Users/Active.php:137 @@ -1575,7 +1575,7 @@ msgstr "" msgid "Block" msgstr "" -#: src/Content/Item.php:394 src/Module/Contact.php:402 +#: src/Content/Item.php:394 src/Module/Contact.php:403 #: src/Module/Contact/Profile.php:349 src/Module/Contact/Profile.php:475 #: src/Module/Notifications/Introductions.php:134 #: src/Module/Notifications/Introductions.php:206 @@ -1588,8 +1588,8 @@ msgid "Languages" msgstr "" #: src/Content/Item.php:403 src/Content/Widget.php:80 -#: src/Model/Contact.php:1208 src/Model/Contact.php:1219 -#: src/Module/Contact/Follow.php:167 view/theme/vier/theme.php:196 +#: src/Model/Contact.php:1193 src/Model/Contact.php:1204 +#: src/Module/Contact/Follow.php:166 view/theme/vier/theme.php:196 msgid "Connect/Follow" msgstr "" @@ -1627,7 +1627,7 @@ msgid "Sign in" msgstr "" #: src/Content/Nav.php:193 src/Module/BaseProfile.php:57 -#: src/Module/Contact.php:436 src/Module/Contact/Profile.php:380 +#: src/Module/Contact.php:437 src/Module/Contact/Profile.php:380 #: src/Module/Settings/TwoFactor/Index.php:119 view/theme/frio/theme.php:236 msgid "Status" msgstr "" @@ -1638,8 +1638,8 @@ msgid "Your posts and conversations" msgstr "" #: src/Content/Nav.php:194 src/Module/BaseProfile.php:49 -#: src/Module/BaseSettings.php:100 src/Module/Contact.php:460 -#: src/Module/Contact/Profile.php:382 src/Module/Profile/Profile.php:233 +#: src/Module/BaseSettings.php:100 src/Module/Contact.php:461 +#: src/Module/Contact/Profile.php:382 src/Module/Profile/Profile.php:268 #: src/Module/Welcome.php:57 view/theme/frio/theme.php:237 msgid "Profile" msgstr "" @@ -1658,7 +1658,7 @@ msgid "Your photos" msgstr "" #: src/Content/Nav.php:196 src/Module/BaseProfile.php:73 -#: src/Module/BaseProfile.php:76 src/Module/Contact.php:452 +#: src/Module/BaseProfile.php:76 src/Module/Contact.php:453 #: view/theme/frio/theme.php:242 msgid "Media" msgstr "" @@ -1744,8 +1744,8 @@ msgstr "" #: src/Content/Nav.php:238 src/Content/Nav.php:293 #: src/Content/Text/HTML.php:899 src/Module/BaseProfile.php:127 -#: src/Module/BaseProfile.php:130 src/Module/Contact.php:373 -#: src/Module/Contact.php:467 view/theme/frio/theme.php:250 +#: src/Module/BaseProfile.php:130 src/Module/Contact.php:374 +#: src/Module/Contact.php:468 view/theme/frio/theme.php:250 msgid "Contacts" msgstr "" @@ -1776,7 +1776,7 @@ msgstr "" #: src/Content/Nav.php:265 src/Module/Admin/Tos.php:78 #: src/Module/BaseAdmin.php:95 src/Module/Register.php:176 -#: src/Module/Tos.php:98 +#: src/Module/Tos.php:100 msgid "Terms of Service" msgstr "" @@ -1925,7 +1925,7 @@ msgstr "" msgid "Link to source" msgstr "" -#: src/Content/Text/BBCode.php:1795 src/Content/Text/HTML.php:940 +#: src/Content/Text/BBCode.php:1795 src/Content/Text/HTML.php:927 msgid "Click to open/close" msgstr "" @@ -1993,7 +1993,7 @@ msgstr "" msgid "Examples: Robert Morgenstein, Fishing" msgstr "" -#: src/Content/Widget.php:82 src/Module/Contact.php:394 +#: src/Content/Widget.php:82 src/Module/Contact.php:395 #: src/Module/Directory.php:96 view/theme/vier/theme.php:198 msgid "Find" msgstr "" @@ -2025,7 +2025,7 @@ msgid "Local Directory" msgstr "" #: src/Content/Widget.php:211 src/Model/Group.php:587 -#: src/Module/Contact.php:357 src/Module/Welcome.php:76 +#: src/Module/Contact.php:358 src/Module/Welcome.php:76 msgid "Groups" msgstr "" @@ -2037,7 +2037,7 @@ msgstr "" msgid "Relationships" msgstr "" -#: src/Content/Widget.php:244 src/Module/Contact.php:309 +#: src/Content/Widget.php:244 src/Module/Contact.php:310 #: src/Module/Group.php:291 msgid "All Contacts" msgstr "" @@ -2081,7 +2081,7 @@ msgstr "" msgid "Organisations" msgstr "" -#: src/Content/Widget.php:523 src/Model/Contact.php:1655 +#: src/Content/Widget.php:523 src/Model/Contact.php:1644 msgid "News" msgstr "" @@ -2140,12 +2140,12 @@ msgid "More Trending Tags" msgstr "" #: src/Content/Widget/VCard.php:102 src/Model/Profile.php:378 -#: src/Module/Contact/Profile.php:371 src/Module/Profile/Profile.php:168 +#: src/Module/Contact/Profile.php:371 src/Module/Profile/Profile.php:199 msgid "XMPP:" msgstr "" #: src/Content/Widget/VCard.php:103 src/Model/Profile.php:379 -#: src/Module/Contact/Profile.php:373 src/Module/Profile/Profile.php:172 +#: src/Module/Contact/Profile.php:373 src/Module/Profile/Profile.php:203 msgid "Matrix:" msgstr "" @@ -2153,7 +2153,7 @@ msgstr "" #: src/Model/Event.php:109 src/Model/Event.php:473 src/Model/Event.php:958 #: src/Model/Profile.php:373 src/Module/Contact/Profile.php:369 #: src/Module/Directory.php:147 src/Module/Notifications/Introductions.php:187 -#: src/Module/Profile/Profile.php:186 +#: src/Module/Profile/Profile.php:221 msgid "Location:" msgstr "" @@ -2162,13 +2162,13 @@ msgstr "" msgid "Network:" msgstr "" -#: src/Content/Widget/VCard.php:111 src/Model/Contact.php:1209 -#: src/Model/Contact.php:1220 src/Model/Profile.php:465 +#: src/Content/Widget/VCard.php:111 src/Model/Contact.php:1194 +#: src/Model/Contact.php:1205 src/Model/Profile.php:465 #: src/Module/Contact/Profile.php:419 msgid "Unfollow" msgstr "" -#: src/Core/ACL.php:165 src/Module/Profile/Profile.php:234 +#: src/Core/ACL.php:165 src/Module/Profile/Profile.php:269 msgid "Yourself" msgstr "" @@ -2866,77 +2866,77 @@ msgstr "" msgid "Legacy module file not found: %s" msgstr "" -#: src/Model/Contact.php:1226 src/Module/Moderation/Users/Pending.php:102 +#: src/Model/Contact.php:1211 src/Module/Moderation/Users/Pending.php:102 #: src/Module/Notifications/Introductions.php:132 #: src/Module/Notifications/Introductions.php:204 msgid "Approve" msgstr "" -#: src/Model/Contact.php:1651 +#: src/Model/Contact.php:1640 msgid "Organisation" msgstr "" -#: src/Model/Contact.php:1659 +#: src/Model/Contact.php:1648 msgid "Forum" msgstr "" -#: src/Model/Contact.php:2884 +#: src/Model/Contact.php:2877 msgid "Disallowed profile URL." msgstr "" -#: src/Model/Contact.php:2889 src/Module/Friendica.php:82 +#: src/Model/Contact.php:2882 src/Module/Friendica.php:82 msgid "Blocked domain" msgstr "" -#: src/Model/Contact.php:2894 +#: src/Model/Contact.php:2887 msgid "Connect URL missing." msgstr "" -#: src/Model/Contact.php:2903 +#: src/Model/Contact.php:2896 msgid "" "The contact could not be added. Please check the relevant network " "credentials in your Settings -> Social Networks page." msgstr "" -#: src/Model/Contact.php:2945 +#: src/Model/Contact.php:2931 msgid "The profile address specified does not provide adequate information." msgstr "" -#: src/Model/Contact.php:2947 +#: src/Model/Contact.php:2933 msgid "No compatible communication protocols or feeds were discovered." msgstr "" -#: src/Model/Contact.php:2950 +#: src/Model/Contact.php:2936 msgid "An author or name was not found." msgstr "" -#: src/Model/Contact.php:2953 +#: src/Model/Contact.php:2939 msgid "No browser URL could be matched to this address." msgstr "" -#: src/Model/Contact.php:2956 +#: src/Model/Contact.php:2942 msgid "" "Unable to match @-style Identity Address with a known protocol or email " "contact." msgstr "" -#: src/Model/Contact.php:2957 +#: src/Model/Contact.php:2943 msgid "Use mailto: in front of address to force email check." msgstr "" -#: src/Model/Contact.php:2963 +#: src/Model/Contact.php:2949 msgid "" "The profile address specified belongs to a network which has been disabled " "on this site." msgstr "" -#: src/Model/Contact.php:2968 +#: src/Model/Contact.php:2954 msgid "" "Limited profile. This person will be unable to receive direct/personal " "notifications from you." msgstr "" -#: src/Model/Contact.php:3027 +#: src/Model/Contact.php:3019 msgid "Unable to retrieve contact information." msgstr "" @@ -3156,8 +3156,8 @@ msgstr "" msgid "Wall Photos" msgstr "" -#: src/Model/Profile.php:361 src/Module/Profile/Profile.php:248 -#: src/Module/Profile/Profile.php:250 +#: src/Model/Profile.php:361 src/Module/Profile/Profile.php:283 +#: src/Module/Profile/Profile.php:285 msgid "Edit profile" msgstr "" @@ -3166,7 +3166,7 @@ msgid "Change profile photo" msgstr "" #: src/Model/Profile.php:376 src/Module/Directory.php:152 -#: src/Module/Profile/Profile.php:176 +#: src/Module/Profile/Profile.php:209 msgid "Homepage:" msgstr "" @@ -3585,9 +3585,9 @@ msgid "Enable" msgstr "" #: src/Module/Admin/Addons/Details.php:111 src/Module/Admin/Addons/Index.php:67 -#: src/Module/Admin/Federation.php:202 src/Module/Admin/Logs/Settings.php:79 +#: src/Module/Admin/Federation.php:207 src/Module/Admin/Logs/Settings.php:79 #: src/Module/Admin/Logs/View.php:84 src/Module/Admin/Queue.php:72 -#: src/Module/Admin/Site.php:437 src/Module/Admin/Storage.php:138 +#: src/Module/Admin/Site.php:433 src/Module/Admin/Storage.php:138 #: src/Module/Admin/Summary.php:216 src/Module/Admin/Themes/Details.php:90 #: src/Module/Admin/Themes/Index.php:111 src/Module/Admin/Tos.php:77 #: src/Module/Moderation/Users/Create.php:61 @@ -3625,7 +3625,7 @@ msgid "Addon %s failed to install." msgstr "" #: src/Module/Admin/Addons/Index.php:69 src/Module/Admin/Features.php:87 -#: src/Module/Admin/Logs/Settings.php:81 src/Module/Admin/Site.php:440 +#: src/Module/Admin/Logs/Settings.php:81 src/Module/Admin/Site.php:436 #: src/Module/Admin/Themes/Index.php:113 src/Module/Admin/Tos.php:86 #: src/Module/Settings/Account.php:560 src/Module/Settings/Addons.php:81 #: src/Module/Settings/Connectors.php:159 @@ -3715,75 +3715,75 @@ msgstr "" msgid "Manage Additional Features" msgstr "" -#: src/Module/Admin/Federation.php:70 +#: src/Module/Admin/Federation.php:73 msgid "Other" msgstr "" -#: src/Module/Admin/Federation.php:142 src/Module/Admin/Federation.php:391 +#: src/Module/Admin/Federation.php:147 src/Module/Admin/Federation.php:396 msgid "unknown" msgstr "" -#: src/Module/Admin/Federation.php:175 +#: src/Module/Admin/Federation.php:180 #, php-format msgid "%2$s total system" msgid_plural "%2$s total systems" msgstr[0] "" msgstr[1] "" -#: src/Module/Admin/Federation.php:176 +#: src/Module/Admin/Federation.php:181 #, php-format msgid "%2$s active user last month" msgid_plural "%2$s active users last month" msgstr[0] "" msgstr[1] "" -#: src/Module/Admin/Federation.php:177 +#: src/Module/Admin/Federation.php:182 #, php-format msgid "%2$s active user last six months" msgid_plural "%2$s active users last six months" msgstr[0] "" msgstr[1] "" -#: src/Module/Admin/Federation.php:178 +#: src/Module/Admin/Federation.php:183 #, php-format msgid "%2$s registered user" msgid_plural "%2$s registered users" msgstr[0] "" msgstr[1] "" -#: src/Module/Admin/Federation.php:179 +#: src/Module/Admin/Federation.php:184 #, php-format msgid "%2$s locally created post or comment" msgid_plural "%2$s locally created posts and comments" msgstr[0] "" msgstr[1] "" -#: src/Module/Admin/Federation.php:182 +#: src/Module/Admin/Federation.php:187 #, php-format msgid "%2$s post per user" msgid_plural "%2$s posts per user" msgstr[0] "" msgstr[1] "" -#: src/Module/Admin/Federation.php:187 +#: src/Module/Admin/Federation.php:192 #, php-format msgid "%2$s user per system" msgid_plural "%2$s users per system" msgstr[0] "" msgstr[1] "" -#: src/Module/Admin/Federation.php:197 +#: src/Module/Admin/Federation.php:202 msgid "" "This page offers you some numbers to the known part of the federated social " "network your Friendica node is part of. These numbers are not complete but " "only reflect the part of the network your node is aware of." msgstr "" -#: src/Module/Admin/Federation.php:203 src/Module/BaseAdmin.php:87 +#: src/Module/Admin/Federation.php:208 src/Module/BaseAdmin.php:87 msgid "Federation Statistics" msgstr "" -#: src/Module/Admin/Federation.php:207 +#: src/Module/Admin/Federation.php:212 #, php-format msgid "" "Currently this node is aware of %2$s node (%3$s active users last month, " @@ -4015,251 +4015,251 @@ msgstr "" msgid "Multi user instance" msgstr "" -#: src/Module/Admin/Site.php:408 +#: src/Module/Admin/Site.php:404 msgid "Closed" msgstr "" -#: src/Module/Admin/Site.php:409 +#: src/Module/Admin/Site.php:405 msgid "Requires approval" msgstr "" -#: src/Module/Admin/Site.php:410 +#: src/Module/Admin/Site.php:406 msgid "Open" msgstr "" -#: src/Module/Admin/Site.php:414 src/Module/Install.php:222 +#: src/Module/Admin/Site.php:410 src/Module/Install.php:222 msgid "No SSL policy, links will track page SSL state" msgstr "" -#: src/Module/Admin/Site.php:415 src/Module/Install.php:223 +#: src/Module/Admin/Site.php:411 src/Module/Install.php:223 msgid "Force all links to use SSL" msgstr "" -#: src/Module/Admin/Site.php:416 src/Module/Install.php:224 +#: src/Module/Admin/Site.php:412 src/Module/Install.php:224 msgid "Self-signed certificate, use SSL for local links only (discouraged)" msgstr "" -#: src/Module/Admin/Site.php:420 +#: src/Module/Admin/Site.php:416 msgid "Don't check" msgstr "" -#: src/Module/Admin/Site.php:421 +#: src/Module/Admin/Site.php:417 msgid "check the stable version" msgstr "" -#: src/Module/Admin/Site.php:422 +#: src/Module/Admin/Site.php:418 msgid "check the development version" msgstr "" -#: src/Module/Admin/Site.php:426 +#: src/Module/Admin/Site.php:422 msgid "none" msgstr "" -#: src/Module/Admin/Site.php:427 +#: src/Module/Admin/Site.php:423 msgid "Local contacts" msgstr "" -#: src/Module/Admin/Site.php:428 +#: src/Module/Admin/Site.php:424 msgid "Interactors" msgstr "" -#: src/Module/Admin/Site.php:438 src/Module/BaseAdmin.php:90 +#: src/Module/Admin/Site.php:434 src/Module/BaseAdmin.php:90 msgid "Site" msgstr "" -#: src/Module/Admin/Site.php:439 +#: src/Module/Admin/Site.php:435 msgid "General Information" msgstr "" -#: src/Module/Admin/Site.php:441 +#: src/Module/Admin/Site.php:437 msgid "Republish users to directory" msgstr "" -#: src/Module/Admin/Site.php:442 src/Module/Register.php:152 +#: src/Module/Admin/Site.php:438 src/Module/Register.php:152 msgid "Registration" msgstr "" -#: src/Module/Admin/Site.php:443 +#: src/Module/Admin/Site.php:439 msgid "File upload" msgstr "" -#: src/Module/Admin/Site.php:444 +#: src/Module/Admin/Site.php:440 msgid "Policies" msgstr "" -#: src/Module/Admin/Site.php:445 src/Module/Calendar/Event/Form.php:252 -#: src/Module/Contact.php:477 src/Module/Profile/Profile.php:241 +#: src/Module/Admin/Site.php:441 src/Module/Calendar/Event/Form.php:252 +#: src/Module/Contact.php:478 src/Module/Profile/Profile.php:276 msgid "Advanced" msgstr "" -#: src/Module/Admin/Site.php:446 +#: src/Module/Admin/Site.php:442 msgid "Auto Discovered Contact Directory" msgstr "" -#: src/Module/Admin/Site.php:447 +#: src/Module/Admin/Site.php:443 msgid "Performance" msgstr "" -#: src/Module/Admin/Site.php:448 +#: src/Module/Admin/Site.php:444 msgid "Worker" msgstr "" -#: src/Module/Admin/Site.php:449 +#: src/Module/Admin/Site.php:445 msgid "Message Relay" msgstr "" -#: src/Module/Admin/Site.php:450 +#: src/Module/Admin/Site.php:446 msgid "" "Use the command \"console relay\" in the command line to add or remove " "relays." msgstr "" -#: src/Module/Admin/Site.php:451 +#: src/Module/Admin/Site.php:447 msgid "The system is not subscribed to any relays at the moment." msgstr "" -#: src/Module/Admin/Site.php:452 +#: src/Module/Admin/Site.php:448 msgid "The system is currently subscribed to the following relays:" msgstr "" -#: src/Module/Admin/Site.php:454 +#: src/Module/Admin/Site.php:450 msgid "Relocate Node" msgstr "" -#: src/Module/Admin/Site.php:455 +#: src/Module/Admin/Site.php:451 msgid "" "Relocating your node enables you to change the DNS domain of this node and " "keep all the existing users and posts. This process takes a while and can " "only be started from the relocate console command like this:" msgstr "" -#: src/Module/Admin/Site.php:456 +#: src/Module/Admin/Site.php:452 msgid "(Friendica directory)# bin/console relocate https://newdomain.com" msgstr "" -#: src/Module/Admin/Site.php:460 +#: src/Module/Admin/Site.php:456 msgid "Site name" msgstr "" -#: src/Module/Admin/Site.php:461 +#: src/Module/Admin/Site.php:457 msgid "Sender Email" msgstr "" -#: src/Module/Admin/Site.php:461 +#: src/Module/Admin/Site.php:457 msgid "" "The email address your server shall use to send notification emails from." msgstr "" -#: src/Module/Admin/Site.php:462 +#: src/Module/Admin/Site.php:458 msgid "Name of the system actor" msgstr "" -#: src/Module/Admin/Site.php:462 +#: src/Module/Admin/Site.php:458 msgid "" "Name of the internal system account that is used to perform ActivityPub " "requests. This must be an unused username. If set, this can't be changed " "again." msgstr "" -#: src/Module/Admin/Site.php:463 +#: src/Module/Admin/Site.php:459 msgid "Banner/Logo" msgstr "" -#: src/Module/Admin/Site.php:464 +#: src/Module/Admin/Site.php:460 msgid "Email Banner/Logo" msgstr "" -#: src/Module/Admin/Site.php:465 +#: src/Module/Admin/Site.php:461 msgid "Shortcut icon" msgstr "" -#: src/Module/Admin/Site.php:465 +#: src/Module/Admin/Site.php:461 msgid "Link to an icon that will be used for browsers." msgstr "" -#: src/Module/Admin/Site.php:466 +#: src/Module/Admin/Site.php:462 msgid "Touch icon" msgstr "" -#: src/Module/Admin/Site.php:466 +#: src/Module/Admin/Site.php:462 msgid "Link to an icon that will be used for tablets and mobiles." msgstr "" -#: src/Module/Admin/Site.php:467 +#: src/Module/Admin/Site.php:463 msgid "Additional Info" msgstr "" -#: src/Module/Admin/Site.php:467 +#: src/Module/Admin/Site.php:463 #, php-format msgid "" "For public servers: you can add additional information here that will be " "listed at %s/servers." msgstr "" -#: src/Module/Admin/Site.php:468 +#: src/Module/Admin/Site.php:464 msgid "System language" msgstr "" -#: src/Module/Admin/Site.php:469 +#: src/Module/Admin/Site.php:465 msgid "System theme" msgstr "" -#: src/Module/Admin/Site.php:469 +#: src/Module/Admin/Site.php:465 #, php-format msgid "" "Default system theme - may be over-ridden by user profiles - Change default theme settings" msgstr "" -#: src/Module/Admin/Site.php:470 +#: src/Module/Admin/Site.php:466 msgid "Mobile system theme" msgstr "" -#: src/Module/Admin/Site.php:470 +#: src/Module/Admin/Site.php:466 msgid "Theme for mobile devices" msgstr "" -#: src/Module/Admin/Site.php:471 src/Module/Install.php:232 +#: src/Module/Admin/Site.php:467 src/Module/Install.php:232 msgid "SSL link policy" msgstr "" -#: src/Module/Admin/Site.php:471 src/Module/Install.php:234 +#: src/Module/Admin/Site.php:467 src/Module/Install.php:234 msgid "Determines whether generated links should be forced to use SSL" msgstr "" -#: src/Module/Admin/Site.php:472 +#: src/Module/Admin/Site.php:468 msgid "Force SSL" msgstr "" -#: src/Module/Admin/Site.php:472 +#: src/Module/Admin/Site.php:468 msgid "" "Force all Non-SSL requests to SSL - Attention: on some systems it could lead " "to endless loops." msgstr "" -#: src/Module/Admin/Site.php:473 +#: src/Module/Admin/Site.php:469 msgid "Show help entry from navigation menu" msgstr "" -#: src/Module/Admin/Site.php:473 +#: src/Module/Admin/Site.php:469 msgid "" "Displays the menu entry for the Help pages from the navigation menu. It is " "always accessible by calling /help directly." msgstr "" -#: src/Module/Admin/Site.php:474 +#: src/Module/Admin/Site.php:470 msgid "Single user instance" msgstr "" -#: src/Module/Admin/Site.php:474 +#: src/Module/Admin/Site.php:470 msgid "Make this instance multi-user or single-user for the named user" msgstr "" -#: src/Module/Admin/Site.php:476 +#: src/Module/Admin/Site.php:472 msgid "Maximum image size" msgstr "" -#: src/Module/Admin/Site.php:476 +#: src/Module/Admin/Site.php:472 #, php-format msgid "" "Maximum size in bytes of uploaded images. Default is 0, which means no " @@ -4271,192 +4271,192 @@ msgid "" "to %s (%s byte)" msgstr "" -#: src/Module/Admin/Site.php:480 +#: src/Module/Admin/Site.php:476 msgid "Maximum image length" msgstr "" -#: src/Module/Admin/Site.php:480 +#: src/Module/Admin/Site.php:476 msgid "" "Maximum length in pixels of the longest side of uploaded images. Default is " "-1, which means no limits." msgstr "" -#: src/Module/Admin/Site.php:481 +#: src/Module/Admin/Site.php:477 msgid "JPEG image quality" msgstr "" -#: src/Module/Admin/Site.php:481 +#: src/Module/Admin/Site.php:477 msgid "" "Uploaded JPEGS will be saved at this quality setting [0-100]. Default is " "100, which is full quality." msgstr "" -#: src/Module/Admin/Site.php:483 +#: src/Module/Admin/Site.php:479 msgid "Register policy" msgstr "" -#: src/Module/Admin/Site.php:484 +#: src/Module/Admin/Site.php:480 msgid "Maximum Daily Registrations" msgstr "" -#: src/Module/Admin/Site.php:484 +#: src/Module/Admin/Site.php:480 msgid "" "If registration is permitted above, this sets the maximum number of new user " "registrations to accept per day. If register is set to closed, this setting " "has no effect." msgstr "" -#: src/Module/Admin/Site.php:485 +#: src/Module/Admin/Site.php:481 msgid "Register text" msgstr "" -#: src/Module/Admin/Site.php:485 +#: src/Module/Admin/Site.php:481 msgid "" "Will be displayed prominently on the registration page. You can use BBCode " "here." msgstr "" -#: src/Module/Admin/Site.php:486 +#: src/Module/Admin/Site.php:482 msgid "Forbidden Nicknames" msgstr "" -#: src/Module/Admin/Site.php:486 +#: src/Module/Admin/Site.php:482 msgid "" "Comma separated list of nicknames that are forbidden from registration. " "Preset is a list of role names according RFC 2142." msgstr "" -#: src/Module/Admin/Site.php:487 +#: src/Module/Admin/Site.php:483 msgid "Accounts abandoned after x days" msgstr "" -#: src/Module/Admin/Site.php:487 +#: src/Module/Admin/Site.php:483 msgid "" "Will not waste system resources polling external sites for abandonded " "accounts. Enter 0 for no time limit." msgstr "" -#: src/Module/Admin/Site.php:488 +#: src/Module/Admin/Site.php:484 msgid "Allowed friend domains" msgstr "" -#: src/Module/Admin/Site.php:488 +#: src/Module/Admin/Site.php:484 msgid "" "Comma separated list of domains which are allowed to establish friendships " "with this site. Wildcards are accepted. Empty to allow any domains" msgstr "" -#: src/Module/Admin/Site.php:489 +#: src/Module/Admin/Site.php:485 msgid "Allowed email domains" msgstr "" -#: src/Module/Admin/Site.php:489 +#: src/Module/Admin/Site.php:485 msgid "" "Comma separated list of domains which are allowed in email addresses for " "registrations to this site. Wildcards are accepted. Empty to allow any " "domains" msgstr "" -#: src/Module/Admin/Site.php:490 +#: src/Module/Admin/Site.php:486 msgid "No OEmbed rich content" msgstr "" -#: src/Module/Admin/Site.php:490 +#: src/Module/Admin/Site.php:486 msgid "" "Don't show the rich content (e.g. embedded PDF), except from the domains " "listed below." msgstr "" -#: src/Module/Admin/Site.php:491 +#: src/Module/Admin/Site.php:487 msgid "Trusted third-party domains" msgstr "" -#: src/Module/Admin/Site.php:491 +#: src/Module/Admin/Site.php:487 msgid "" "Comma separated list of domains from which content is allowed to be embedded " "in posts like with OEmbed. All sub-domains of the listed domains are allowed " "as well." msgstr "" -#: src/Module/Admin/Site.php:492 +#: src/Module/Admin/Site.php:488 msgid "Block public" msgstr "" -#: src/Module/Admin/Site.php:492 +#: src/Module/Admin/Site.php:488 msgid "" "Check to block public access to all otherwise public personal pages on this " "site unless you are currently logged in." msgstr "" -#: src/Module/Admin/Site.php:493 +#: src/Module/Admin/Site.php:489 msgid "Force publish" msgstr "" -#: src/Module/Admin/Site.php:493 +#: src/Module/Admin/Site.php:489 msgid "" "Check to force all profiles on this site to be listed in the site directory." msgstr "" -#: src/Module/Admin/Site.php:493 +#: src/Module/Admin/Site.php:489 msgid "Enabling this may violate privacy laws like the GDPR" msgstr "" -#: src/Module/Admin/Site.php:494 +#: src/Module/Admin/Site.php:490 msgid "Global directory URL" msgstr "" -#: src/Module/Admin/Site.php:494 +#: src/Module/Admin/Site.php:490 msgid "" "URL to the global directory. If this is not set, the global directory is " "completely unavailable to the application." msgstr "" -#: src/Module/Admin/Site.php:495 +#: src/Module/Admin/Site.php:491 msgid "Private posts by default for new users" msgstr "" -#: src/Module/Admin/Site.php:495 +#: src/Module/Admin/Site.php:491 msgid "" "Set default post permissions for all new members to the default privacy " "group rather than public." msgstr "" -#: src/Module/Admin/Site.php:496 +#: src/Module/Admin/Site.php:492 msgid "Don't include post content in email notifications" msgstr "" -#: src/Module/Admin/Site.php:496 +#: src/Module/Admin/Site.php:492 msgid "" "Don't include the content of a post/comment/private message/etc. in the " "email notifications that are sent out from this site, as a privacy measure." msgstr "" -#: src/Module/Admin/Site.php:497 +#: src/Module/Admin/Site.php:493 msgid "Disallow public access to addons listed in the apps menu." msgstr "" -#: src/Module/Admin/Site.php:497 +#: src/Module/Admin/Site.php:493 msgid "" "Checking this box will restrict addons listed in the apps menu to members " "only." msgstr "" -#: src/Module/Admin/Site.php:498 +#: src/Module/Admin/Site.php:494 msgid "Don't embed private images in posts" msgstr "" -#: src/Module/Admin/Site.php:498 +#: src/Module/Admin/Site.php:494 msgid "" "Don't replace locally-hosted private photos in posts with an embedded copy " "of the image. This means that contacts who receive posts containing private " "photos will have to authenticate and load each image, which may take a while." msgstr "" -#: src/Module/Admin/Site.php:499 +#: src/Module/Admin/Site.php:495 msgid "Explicit Content" msgstr "" -#: src/Module/Admin/Site.php:499 +#: src/Module/Admin/Site.php:495 msgid "" "Set this to announce that your node is used mostly for explicit content that " "might not be suited for minors. This information will be published in the " @@ -4465,267 +4465,267 @@ msgid "" "will be shown at the user registration page." msgstr "" -#: src/Module/Admin/Site.php:500 +#: src/Module/Admin/Site.php:496 msgid "Proxify external content" msgstr "" -#: src/Module/Admin/Site.php:500 +#: src/Module/Admin/Site.php:496 msgid "" "Route external content via the proxy functionality. This is used for example " "for some OEmbed accesses and in some other rare cases." msgstr "" -#: src/Module/Admin/Site.php:501 +#: src/Module/Admin/Site.php:497 msgid "Cache contact avatars" msgstr "" -#: src/Module/Admin/Site.php:501 +#: src/Module/Admin/Site.php:497 msgid "" "Locally store the avatar pictures of the contacts. This uses a lot of " "storage space but it increases the performance." msgstr "" -#: src/Module/Admin/Site.php:502 +#: src/Module/Admin/Site.php:498 msgid "Allow Users to set remote_self" msgstr "" -#: src/Module/Admin/Site.php:502 +#: src/Module/Admin/Site.php:498 msgid "" "With checking this, every user is allowed to mark every contact as a " "remote_self in the repair contact dialog. Setting this flag on a contact " "causes mirroring every posting of that contact in the users stream." msgstr "" -#: src/Module/Admin/Site.php:503 +#: src/Module/Admin/Site.php:499 msgid "Enable multiple registrations" msgstr "" -#: src/Module/Admin/Site.php:503 +#: src/Module/Admin/Site.php:499 msgid "Enable users to register additional accounts for use as pages." msgstr "" -#: src/Module/Admin/Site.php:504 +#: src/Module/Admin/Site.php:500 msgid "Enable OpenID" msgstr "" -#: src/Module/Admin/Site.php:504 +#: src/Module/Admin/Site.php:500 msgid "Enable OpenID support for registration and logins." msgstr "" -#: src/Module/Admin/Site.php:505 +#: src/Module/Admin/Site.php:501 msgid "Enable Fullname check" msgstr "" -#: src/Module/Admin/Site.php:505 +#: src/Module/Admin/Site.php:501 msgid "" "Enable check to only allow users to register with a space between the first " "name and the last name in their full name." msgstr "" -#: src/Module/Admin/Site.php:506 +#: src/Module/Admin/Site.php:502 msgid "Email administrators on new registration" msgstr "" -#: src/Module/Admin/Site.php:506 +#: src/Module/Admin/Site.php:502 msgid "" "If enabled and the system is set to an open registration, an email for each " "new registration is sent to the administrators." msgstr "" -#: src/Module/Admin/Site.php:507 +#: src/Module/Admin/Site.php:503 msgid "Community pages for visitors" msgstr "" -#: src/Module/Admin/Site.php:507 +#: src/Module/Admin/Site.php:503 msgid "" "Which community pages should be available for visitors. Local users always " "see both pages." msgstr "" -#: src/Module/Admin/Site.php:508 +#: src/Module/Admin/Site.php:504 msgid "Posts per user on community page" msgstr "" -#: src/Module/Admin/Site.php:508 +#: src/Module/Admin/Site.php:504 msgid "" "The maximum number of posts per user on the community page. (Not valid for " "\"Global Community\")" msgstr "" -#: src/Module/Admin/Site.php:510 +#: src/Module/Admin/Site.php:506 msgid "Enable Mail support" msgstr "" -#: src/Module/Admin/Site.php:510 +#: src/Module/Admin/Site.php:506 msgid "" "Enable built-in mail support to poll IMAP folders and to reply via mail." msgstr "" -#: src/Module/Admin/Site.php:511 +#: src/Module/Admin/Site.php:507 msgid "" "Mail support can't be enabled because the PHP IMAP module is not installed." msgstr "" -#: src/Module/Admin/Site.php:512 +#: src/Module/Admin/Site.php:508 msgid "Enable OStatus support" msgstr "" -#: src/Module/Admin/Site.php:512 +#: src/Module/Admin/Site.php:508 msgid "" "Enable built-in OStatus (StatusNet, GNU Social etc.) compatibility. All " "communications in OStatus are public." msgstr "" -#: src/Module/Admin/Site.php:514 +#: src/Module/Admin/Site.php:510 msgid "" "Diaspora support can't be enabled because Friendica was installed into a sub " "directory." msgstr "" -#: src/Module/Admin/Site.php:515 +#: src/Module/Admin/Site.php:511 msgid "Enable Diaspora support" msgstr "" -#: src/Module/Admin/Site.php:515 +#: src/Module/Admin/Site.php:511 msgid "" "Enable built-in Diaspora network compatibility for communicating with " "diaspora servers." msgstr "" -#: src/Module/Admin/Site.php:516 +#: src/Module/Admin/Site.php:512 msgid "Verify SSL" msgstr "" -#: src/Module/Admin/Site.php:516 +#: src/Module/Admin/Site.php:512 msgid "" "If you wish, you can turn on strict certificate checking. This will mean you " "cannot connect (at all) to self-signed SSL sites." msgstr "" -#: src/Module/Admin/Site.php:517 +#: src/Module/Admin/Site.php:513 msgid "Proxy user" msgstr "" -#: src/Module/Admin/Site.php:517 +#: src/Module/Admin/Site.php:513 msgid "User name for the proxy server." msgstr "" -#: src/Module/Admin/Site.php:518 +#: src/Module/Admin/Site.php:514 msgid "Proxy URL" msgstr "" -#: src/Module/Admin/Site.php:518 +#: src/Module/Admin/Site.php:514 msgid "" "If you want to use a proxy server that Friendica should use to connect to " "the network, put the URL of the proxy here." msgstr "" -#: src/Module/Admin/Site.php:519 +#: src/Module/Admin/Site.php:515 msgid "Network timeout" msgstr "" -#: src/Module/Admin/Site.php:519 +#: src/Module/Admin/Site.php:515 msgid "Value is in seconds. Set to 0 for unlimited (not recommended)." msgstr "" -#: src/Module/Admin/Site.php:520 +#: src/Module/Admin/Site.php:516 msgid "Maximum Load Average" msgstr "" -#: src/Module/Admin/Site.php:520 +#: src/Module/Admin/Site.php:516 #, php-format msgid "" "Maximum system load before delivery and poll processes are deferred - " "default %d." msgstr "" -#: src/Module/Admin/Site.php:521 +#: src/Module/Admin/Site.php:517 msgid "Minimal Memory" msgstr "" -#: src/Module/Admin/Site.php:521 +#: src/Module/Admin/Site.php:517 msgid "" "Minimal free memory in MB for the worker. Needs access to /proc/meminfo - " "default 0 (deactivated)." msgstr "" -#: src/Module/Admin/Site.php:522 +#: src/Module/Admin/Site.php:518 msgid "Periodically optimize tables" msgstr "" -#: src/Module/Admin/Site.php:522 +#: src/Module/Admin/Site.php:518 msgid "Periodically optimize tables like the cache and the workerqueue" msgstr "" -#: src/Module/Admin/Site.php:524 +#: src/Module/Admin/Site.php:520 msgid "Discover followers/followings from contacts" msgstr "" -#: src/Module/Admin/Site.php:524 +#: src/Module/Admin/Site.php:520 msgid "" "If enabled, contacts are checked for their followers and following contacts." msgstr "" -#: src/Module/Admin/Site.php:525 +#: src/Module/Admin/Site.php:521 msgid "None - deactivated" msgstr "" -#: src/Module/Admin/Site.php:526 +#: src/Module/Admin/Site.php:522 msgid "" "Local contacts - contacts of our local contacts are discovered for their " "followers/followings." msgstr "" -#: src/Module/Admin/Site.php:527 +#: src/Module/Admin/Site.php:523 msgid "" "Interactors - contacts of our local contacts and contacts who interacted on " "locally visible postings are discovered for their followers/followings." msgstr "" -#: src/Module/Admin/Site.php:529 +#: src/Module/Admin/Site.php:525 msgid "Synchronize the contacts with the directory server" msgstr "" -#: src/Module/Admin/Site.php:529 +#: src/Module/Admin/Site.php:525 msgid "" "if enabled, the system will check periodically for new contacts on the " "defined directory server." msgstr "" -#: src/Module/Admin/Site.php:531 +#: src/Module/Admin/Site.php:527 msgid "Days between requery" msgstr "" -#: src/Module/Admin/Site.php:531 +#: src/Module/Admin/Site.php:527 msgid "Number of days after which a server is requeried for his contacts." msgstr "" -#: src/Module/Admin/Site.php:532 +#: src/Module/Admin/Site.php:528 msgid "Discover contacts from other servers" msgstr "" -#: src/Module/Admin/Site.php:532 +#: src/Module/Admin/Site.php:528 msgid "" "Periodically query other servers for contacts. The system queries Friendica, " "Mastodon and Hubzilla servers." msgstr "" -#: src/Module/Admin/Site.php:533 +#: src/Module/Admin/Site.php:529 msgid "Search the local directory" msgstr "" -#: src/Module/Admin/Site.php:533 +#: src/Module/Admin/Site.php:529 msgid "" "Search the local directory instead of the global directory. When searching " "locally, every search will be executed on the global directory in the " "background. This improves the search results when the search is repeated." msgstr "" -#: src/Module/Admin/Site.php:535 +#: src/Module/Admin/Site.php:531 msgid "Publish server information" msgstr "" -#: src/Module/Admin/Site.php:535 +#: src/Module/Admin/Site.php:531 msgid "" "If enabled, general server and usage data will be published. The data " "contains the name and version of the server, number of users with public " @@ -4733,50 +4733,50 @@ msgid "" "href=\"http://the-federation.info/\">the-federation.info for details." msgstr "" -#: src/Module/Admin/Site.php:537 +#: src/Module/Admin/Site.php:533 msgid "Check upstream version" msgstr "" -#: src/Module/Admin/Site.php:537 +#: src/Module/Admin/Site.php:533 msgid "" "Enables checking for new Friendica versions at github. If there is a new " "version, you will be informed in the admin panel overview." msgstr "" -#: src/Module/Admin/Site.php:538 +#: src/Module/Admin/Site.php:534 msgid "Suppress Tags" msgstr "" -#: src/Module/Admin/Site.php:538 +#: src/Module/Admin/Site.php:534 msgid "Suppress showing a list of hashtags at the end of the posting." msgstr "" -#: src/Module/Admin/Site.php:539 +#: src/Module/Admin/Site.php:535 msgid "Clean database" msgstr "" -#: src/Module/Admin/Site.php:539 +#: src/Module/Admin/Site.php:535 msgid "" "Remove old remote items, orphaned database records and old content from some " "other helper tables." msgstr "" -#: src/Module/Admin/Site.php:540 +#: src/Module/Admin/Site.php:536 msgid "Lifespan of remote items" msgstr "" -#: src/Module/Admin/Site.php:540 +#: src/Module/Admin/Site.php:536 msgid "" "When the database cleanup is enabled, this defines the days after which " "remote items will be deleted. Own items, and marked or filed items are " "always kept. 0 disables this behaviour." msgstr "" -#: src/Module/Admin/Site.php:541 +#: src/Module/Admin/Site.php:537 msgid "Lifespan of unclaimed items" msgstr "" -#: src/Module/Admin/Site.php:541 +#: src/Module/Admin/Site.php:537 msgid "" "When the database cleanup is enabled, this defines the days after which " "unclaimed remote items (mostly content from the relay) will be deleted. " @@ -4784,144 +4784,144 @@ msgid "" "items if set to 0." msgstr "" -#: src/Module/Admin/Site.php:542 +#: src/Module/Admin/Site.php:538 msgid "Lifespan of raw conversation data" msgstr "" -#: src/Module/Admin/Site.php:542 +#: src/Module/Admin/Site.php:538 msgid "" "The conversation data is used for ActivityPub and OStatus, as well as for " "debug purposes. It should be safe to remove it after 14 days, default is 90 " "days." msgstr "" -#: src/Module/Admin/Site.php:543 +#: src/Module/Admin/Site.php:539 msgid "Maximum numbers of comments per post" msgstr "" -#: src/Module/Admin/Site.php:543 +#: src/Module/Admin/Site.php:539 msgid "How much comments should be shown for each post? Default value is 100." msgstr "" -#: src/Module/Admin/Site.php:544 +#: src/Module/Admin/Site.php:540 msgid "Maximum numbers of comments per post on the display page" msgstr "" -#: src/Module/Admin/Site.php:544 +#: src/Module/Admin/Site.php:540 msgid "" "How many comments should be shown on the single view for each post? Default " "value is 1000." msgstr "" -#: src/Module/Admin/Site.php:545 +#: src/Module/Admin/Site.php:541 msgid "Temp path" msgstr "" -#: src/Module/Admin/Site.php:545 +#: src/Module/Admin/Site.php:541 msgid "" "If you have a restricted system where the webserver can't access the system " "temp path, enter another path here." msgstr "" -#: src/Module/Admin/Site.php:546 +#: src/Module/Admin/Site.php:542 msgid "Only search in tags" msgstr "" -#: src/Module/Admin/Site.php:546 +#: src/Module/Admin/Site.php:542 msgid "On large systems the text search can slow down the system extremely." msgstr "" -#: src/Module/Admin/Site.php:547 +#: src/Module/Admin/Site.php:543 msgid "Generate counts per contact group when calculating network count" msgstr "" -#: src/Module/Admin/Site.php:547 +#: src/Module/Admin/Site.php:543 msgid "" "On systems with users that heavily use contact groups the query can be very " "expensive." msgstr "" -#: src/Module/Admin/Site.php:549 +#: src/Module/Admin/Site.php:545 msgid "Maximum number of parallel workers" msgstr "" -#: src/Module/Admin/Site.php:549 +#: src/Module/Admin/Site.php:545 #, php-format msgid "" "On shared hosters set this to %d. On larger systems, values of %d are great. " "Default value is %d." msgstr "" -#: src/Module/Admin/Site.php:550 +#: src/Module/Admin/Site.php:546 msgid "Enable fastlane" msgstr "" -#: src/Module/Admin/Site.php:550 +#: src/Module/Admin/Site.php:546 msgid "" "When enabed, the fastlane mechanism starts an additional worker if processes " "with higher priority are blocked by processes of lower priority." msgstr "" -#: src/Module/Admin/Site.php:552 +#: src/Module/Admin/Site.php:548 msgid "Direct relay transfer" msgstr "" -#: src/Module/Admin/Site.php:552 +#: src/Module/Admin/Site.php:548 msgid "" "Enables the direct transfer to other servers without using the relay servers" msgstr "" -#: src/Module/Admin/Site.php:553 +#: src/Module/Admin/Site.php:549 msgid "Relay scope" msgstr "" -#: src/Module/Admin/Site.php:553 +#: src/Module/Admin/Site.php:549 msgid "" "Can be \"all\" or \"tags\". \"all\" means that every public post should be " "received. \"tags\" means that only posts with selected tags should be " "received." msgstr "" -#: src/Module/Admin/Site.php:553 src/Module/Contact/Profile.php:274 +#: src/Module/Admin/Site.php:549 src/Module/Contact/Profile.php:274 #: src/Module/Settings/TwoFactor/Index.php:125 msgid "Disabled" msgstr "" -#: src/Module/Admin/Site.php:553 +#: src/Module/Admin/Site.php:549 msgid "all" msgstr "" -#: src/Module/Admin/Site.php:553 +#: src/Module/Admin/Site.php:549 msgid "tags" msgstr "" -#: src/Module/Admin/Site.php:554 +#: src/Module/Admin/Site.php:550 msgid "Server tags" msgstr "" -#: src/Module/Admin/Site.php:554 +#: src/Module/Admin/Site.php:550 msgid "Comma separated list of tags for the \"tags\" subscription." msgstr "" -#: src/Module/Admin/Site.php:555 +#: src/Module/Admin/Site.php:551 msgid "Deny Server tags" msgstr "" -#: src/Module/Admin/Site.php:555 +#: src/Module/Admin/Site.php:551 msgid "Comma separated list of tags that are rejected." msgstr "" -#: src/Module/Admin/Site.php:556 +#: src/Module/Admin/Site.php:552 msgid "Allow user tags" msgstr "" -#: src/Module/Admin/Site.php:556 +#: src/Module/Admin/Site.php:552 msgid "" "If enabled, the tags from the saved searches will used for the \"tags\" " "subscription in addition to the \"relay_server_tags\"." msgstr "" -#: src/Module/Admin/Site.php:559 +#: src/Module/Admin/Site.php:555 msgid "Start Relocation" msgstr "" @@ -5226,7 +5226,7 @@ msgstr "" msgid "Only starting posts can be muted" msgstr "" -#: src/Module/Api/Mastodon/Statuses/Reblog.php:53 +#: src/Module/Api/Mastodon/Statuses/Reblog.php:56 #, php-format msgid "Posts from %s can't be shared" msgstr "" @@ -5239,7 +5239,7 @@ msgstr "" msgid "Only starting posts can be unmuted" msgstr "" -#: src/Module/Api/Mastodon/Statuses/Unreblog.php:53 +#: src/Module/Api/Mastodon/Statuses/Unreblog.php:62 #, php-format msgid "Posts from %s can't be unshared" msgstr "" @@ -5387,12 +5387,12 @@ msgstr "" msgid "Item Source" msgstr "" -#: src/Module/BaseProfile.php:52 src/Module/Contact.php:463 +#: src/Module/BaseProfile.php:52 src/Module/Contact.php:464 msgid "Profile Details" msgstr "" -#: src/Module/BaseProfile.php:60 src/Module/Contact.php:447 -#: src/Module/Contact/Follow.php:192 src/Module/Contact/Unfollow.php:138 +#: src/Module/BaseProfile.php:60 src/Module/Contact.php:448 +#: src/Module/Contact/Follow.php:191 src/Module/Contact/Unfollow.php:138 msgid "Status Messages and Posts" msgstr "" @@ -5547,7 +5547,7 @@ msgstr "" msgid "Share this event" msgstr "" -#: src/Module/Calendar/Event/Form.php:251 src/Module/Profile/Profile.php:240 +#: src/Module/Calendar/Event/Form.php:251 src/Module/Profile/Profile.php:275 msgid "Basic" msgstr "" @@ -5579,78 +5579,78 @@ msgstr "" msgid "list" msgstr "" -#: src/Module/Contact.php:88 +#: src/Module/Contact.php:89 #, php-format msgid "%d contact edited." msgid_plural "%d contacts edited." msgstr[0] "" msgstr[1] "" -#: src/Module/Contact.php:312 +#: src/Module/Contact.php:313 msgid "Show all contacts" msgstr "" -#: src/Module/Contact.php:317 src/Module/Contact.php:377 +#: src/Module/Contact.php:318 src/Module/Contact.php:378 #: src/Module/Moderation/BaseUsers.php:85 msgid "Pending" msgstr "" -#: src/Module/Contact.php:320 +#: src/Module/Contact.php:321 msgid "Only show pending contacts" msgstr "" -#: src/Module/Contact.php:325 src/Module/Contact.php:378 +#: src/Module/Contact.php:326 src/Module/Contact.php:379 #: src/Module/Moderation/BaseUsers.php:93 msgid "Blocked" msgstr "" -#: src/Module/Contact.php:328 +#: src/Module/Contact.php:329 msgid "Only show blocked contacts" msgstr "" -#: src/Module/Contact.php:333 src/Module/Contact.php:380 +#: src/Module/Contact.php:334 src/Module/Contact.php:381 #: src/Object/Post.php:338 msgid "Ignored" msgstr "" -#: src/Module/Contact.php:336 +#: src/Module/Contact.php:337 msgid "Only show ignored contacts" msgstr "" -#: src/Module/Contact.php:341 src/Module/Contact.php:381 +#: src/Module/Contact.php:342 src/Module/Contact.php:382 msgid "Archived" msgstr "" -#: src/Module/Contact.php:344 +#: src/Module/Contact.php:345 msgid "Only show archived contacts" msgstr "" -#: src/Module/Contact.php:349 src/Module/Contact.php:379 +#: src/Module/Contact.php:350 src/Module/Contact.php:380 msgid "Hidden" msgstr "" -#: src/Module/Contact.php:352 +#: src/Module/Contact.php:353 msgid "Only show hidden contacts" msgstr "" -#: src/Module/Contact.php:360 +#: src/Module/Contact.php:361 msgid "Organize your contact groups" msgstr "" -#: src/Module/Contact.php:392 +#: src/Module/Contact.php:393 msgid "Search your contacts" msgstr "" -#: src/Module/Contact.php:393 src/Module/Search/Index.php:206 +#: src/Module/Contact.php:394 src/Module/Search/Index.php:206 #, php-format msgid "Results for: %s" msgstr "" -#: src/Module/Contact.php:400 +#: src/Module/Contact.php:401 msgid "Update" msgstr "" -#: src/Module/Contact.php:401 src/Module/Contact/Profile.php:348 +#: src/Module/Contact.php:402 src/Module/Contact/Profile.php:348 #: src/Module/Contact/Profile.php:467 #: src/Module/Moderation/Blocklist/Contact.php:117 #: src/Module/Moderation/Users/Blocked.php:138 @@ -5658,62 +5658,62 @@ msgstr "" msgid "Unblock" msgstr "" -#: src/Module/Contact.php:402 src/Module/Contact/Profile.php:349 +#: src/Module/Contact.php:403 src/Module/Contact/Profile.php:349 #: src/Module/Contact/Profile.php:475 msgid "Unignore" msgstr "" -#: src/Module/Contact.php:404 +#: src/Module/Contact.php:405 msgid "Batch Actions" msgstr "" -#: src/Module/Contact.php:439 +#: src/Module/Contact.php:440 msgid "Conversations started by this contact" msgstr "" -#: src/Module/Contact.php:444 +#: src/Module/Contact.php:445 msgid "Posts and Comments" msgstr "" -#: src/Module/Contact.php:455 +#: src/Module/Contact.php:456 msgid "Posts containing media objects" msgstr "" -#: src/Module/Contact.php:470 +#: src/Module/Contact.php:471 msgid "View all known contacts" msgstr "" -#: src/Module/Contact.php:480 +#: src/Module/Contact.php:481 msgid "Advanced Contact Settings" msgstr "" -#: src/Module/Contact.php:514 +#: src/Module/Contact.php:517 msgid "Mutual Friendship" msgstr "" -#: src/Module/Contact.php:518 +#: src/Module/Contact.php:521 msgid "is a fan of yours" msgstr "" -#: src/Module/Contact.php:522 +#: src/Module/Contact.php:525 msgid "you are a fan of" msgstr "" -#: src/Module/Contact.php:540 +#: src/Module/Contact.php:543 msgid "Pending outgoing contact request" msgstr "" -#: src/Module/Contact.php:542 +#: src/Module/Contact.php:545 msgid "Pending incoming contact request" msgstr "" -#: src/Module/Contact.php:555 src/Module/Contact/Profile.php:334 +#: src/Module/Contact.php:558 src/Module/Contact/Profile.php:334 #, php-format msgid "Visit %s's profile [%s]" msgstr "" #: src/Module/Contact/Advanced.php:70 src/Module/Contact/Advanced.php:109 -#: src/Module/Contact/Contacts.php:53 src/Module/Contact/Conversations.php:84 +#: src/Module/Contact/Contacts.php:71 src/Module/Contact/Conversations.php:84 #: src/Module/Contact/Conversations.php:89 #: src/Module/Contact/Conversations.php:94 src/Module/Contact/Media.php:43 #: src/Module/Contact/Posts.php:78 src/Module/Contact/Posts.php:83 @@ -5761,60 +5761,60 @@ msgstr "" msgid "New photo from this URL" msgstr "" -#: src/Module/Contact/Contacts.php:48 src/Module/Conversation/Network.php:188 +#: src/Module/Contact/Contacts.php:66 src/Module/Conversation/Network.php:188 #: src/Module/Group.php:101 msgid "Invalid contact." msgstr "" -#: src/Module/Contact/Contacts.php:71 +#: src/Module/Contact/Contacts.php:89 msgid "No known contacts." msgstr "" -#: src/Module/Contact/Contacts.php:85 src/Module/Profile/Common.php:97 +#: src/Module/Contact/Contacts.php:103 src/Module/Profile/Common.php:128 msgid "No common contacts." msgstr "" -#: src/Module/Contact/Contacts.php:97 src/Module/Profile/Contacts.php:95 +#: src/Module/Contact/Contacts.php:115 src/Module/Profile/Contacts.php:132 #, php-format msgid "Follower (%s)" msgid_plural "Followers (%s)" msgstr[0] "" msgstr[1] "" -#: src/Module/Contact/Contacts.php:101 src/Module/Profile/Contacts.php:98 +#: src/Module/Contact/Contacts.php:119 src/Module/Profile/Contacts.php:135 #, php-format msgid "Following (%s)" msgid_plural "Following (%s)" msgstr[0] "" msgstr[1] "" -#: src/Module/Contact/Contacts.php:105 src/Module/Profile/Contacts.php:101 +#: src/Module/Contact/Contacts.php:123 src/Module/Profile/Contacts.php:138 #, php-format msgid "Mutual friend (%s)" msgid_plural "Mutual friends (%s)" msgstr[0] "" msgstr[1] "" -#: src/Module/Contact/Contacts.php:107 src/Module/Profile/Contacts.php:103 +#: src/Module/Contact/Contacts.php:125 src/Module/Profile/Contacts.php:140 #, php-format msgid "These contacts both follow and are followed by %s." msgstr "" -#: src/Module/Contact/Contacts.php:113 src/Module/Profile/Common.php:85 +#: src/Module/Contact/Contacts.php:131 src/Module/Profile/Common.php:116 #, php-format msgid "Common contact (%s)" msgid_plural "Common contacts (%s)" msgstr[0] "" msgstr[1] "" -#: src/Module/Contact/Contacts.php:115 src/Module/Profile/Common.php:87 +#: src/Module/Contact/Contacts.php:133 src/Module/Profile/Common.php:118 #, php-format msgid "" "Both %s and yourself have publicly interacted with these " "contacts (follow, comment or likes on public posts)." msgstr "" -#: src/Module/Contact/Contacts.php:121 src/Module/Profile/Contacts.php:109 +#: src/Module/Contact/Contacts.php:139 src/Module/Profile/Contacts.php:146 #, php-format msgid "Contact (%s)" msgid_plural "Contacts (%s)" @@ -5836,31 +5836,31 @@ msgstr "" msgid "Submit Request" msgstr "" -#: src/Module/Contact/Follow.php:115 +#: src/Module/Contact/Follow.php:114 msgid "You already added this contact." msgstr "" -#: src/Module/Contact/Follow.php:130 +#: src/Module/Contact/Follow.php:129 msgid "The network type couldn't be detected. Contact can't be added." msgstr "" -#: src/Module/Contact/Follow.php:138 +#: src/Module/Contact/Follow.php:137 msgid "Diaspora support isn't enabled. Contact can't be added." msgstr "" -#: src/Module/Contact/Follow.php:143 +#: src/Module/Contact/Follow.php:142 msgid "OStatus support is disabled. Contact can't be added." msgstr "" -#: src/Module/Contact/Follow.php:168 src/Module/Profile/RemoteFollow.php:132 +#: src/Module/Contact/Follow.php:167 src/Module/Profile/RemoteFollow.php:132 msgid "Please answer the following:" msgstr "" -#: src/Module/Contact/Follow.php:169 src/Module/Contact/Unfollow.php:123 +#: src/Module/Contact/Follow.php:168 src/Module/Contact/Unfollow.php:123 msgid "Your Identity Address:" msgstr "" -#: src/Module/Contact/Follow.php:170 src/Module/Contact/Profile.php:365 +#: src/Module/Contact/Follow.php:169 src/Module/Contact/Profile.php:365 #: src/Module/Contact/Unfollow.php:129 #: src/Module/Moderation/Blocklist/Contact.php:133 #: src/Module/Notifications/Introductions.php:129 @@ -5868,22 +5868,22 @@ msgstr "" msgid "Profile URL" msgstr "" -#: src/Module/Contact/Follow.php:171 src/Module/Contact/Profile.php:377 +#: src/Module/Contact/Follow.php:170 src/Module/Contact/Profile.php:377 #: src/Module/Notifications/Introductions.php:191 -#: src/Module/Profile/Profile.php:199 +#: src/Module/Profile/Profile.php:234 msgid "Tags:" msgstr "" -#: src/Module/Contact/Follow.php:182 +#: src/Module/Contact/Follow.php:181 #, php-format msgid "%s knows you" msgstr "" -#: src/Module/Contact/Follow.php:183 +#: src/Module/Contact/Follow.php:182 msgid "Add a personal note:" msgstr "" -#: src/Module/Contact/Follow.php:221 +#: src/Module/Contact/Follow.php:220 msgid "The contact could not be added." msgstr "" @@ -8178,7 +8178,7 @@ msgstr "" msgid "Remove" msgstr "" -#: src/Module/Profile/Contacts.php:119 +#: src/Module/Profile/Contacts.php:156 msgid "No contacts." msgstr "" @@ -8200,47 +8200,47 @@ msgstr "" msgid "Image file is empty." msgstr "" -#: src/Module/Profile/Photos.php:384 +#: src/Module/Profile/Photos.php:376 msgid "View Album" msgstr "" -#: src/Module/Profile/Profile.php:81 src/Module/Profile/Restricted.php:50 +#: src/Module/Profile/Profile.php:112 src/Module/Profile/Restricted.php:50 msgid "Profile not found." msgstr "" -#: src/Module/Profile/Profile.php:127 +#: src/Module/Profile/Profile.php:158 #, php-format msgid "" "You're currently viewing your profile as %s Cancel" msgstr "" -#: src/Module/Profile/Profile.php:136 src/Module/Settings/Account.php:576 +#: src/Module/Profile/Profile.php:167 src/Module/Settings/Account.php:576 msgid "Full Name:" msgstr "" -#: src/Module/Profile/Profile.php:141 +#: src/Module/Profile/Profile.php:172 msgid "Member since:" msgstr "" -#: src/Module/Profile/Profile.php:147 +#: src/Module/Profile/Profile.php:178 msgid "j F, Y" msgstr "" -#: src/Module/Profile/Profile.php:148 +#: src/Module/Profile/Profile.php:179 msgid "j F" msgstr "" -#: src/Module/Profile/Profile.php:156 src/Util/Temporal.php:166 +#: src/Module/Profile/Profile.php:187 src/Util/Temporal.php:166 msgid "Birthday:" msgstr "" -#: src/Module/Profile/Profile.php:159 src/Module/Settings/Profile/Index.php:254 +#: src/Module/Profile/Profile.php:190 src/Module/Settings/Profile/Index.php:254 #: src/Util/Temporal.php:168 msgid "Age: " msgstr "" -#: src/Module/Profile/Profile.php:159 src/Module/Settings/Profile/Index.php:254 +#: src/Module/Profile/Profile.php:190 src/Module/Settings/Profile/Index.php:254 #: src/Util/Temporal.php:168 #, php-format msgid "%d year old" @@ -8248,37 +8248,37 @@ msgid_plural "%d years old" msgstr[0] "" msgstr[1] "" -#: src/Module/Profile/Profile.php:164 src/Module/Settings/Profile/Index.php:247 +#: src/Module/Profile/Profile.php:195 src/Module/Settings/Profile/Index.php:247 msgid "Description:" msgstr "" -#: src/Module/Profile/Profile.php:226 +#: src/Module/Profile/Profile.php:261 msgid "Forums:" msgstr "" -#: src/Module/Profile/Profile.php:238 +#: src/Module/Profile/Profile.php:273 msgid "View profile as:" msgstr "" -#: src/Module/Profile/Profile.php:255 +#: src/Module/Profile/Profile.php:290 msgid "View as" msgstr "" -#: src/Module/Profile/Profile.php:318 src/Module/Profile/Profile.php:321 -#: src/Module/Profile/Status.php:65 src/Module/Profile/Status.php:68 -#: src/Protocol/Feed.php:1024 src/Protocol/OStatus.php:1047 +#: src/Module/Profile/Profile.php:351 src/Module/Profile/Profile.php:354 +#: src/Module/Profile/Status.php:106 src/Module/Profile/Status.php:109 +#: src/Protocol/Feed.php:1024 src/Protocol/OStatus.php:1045 #, php-format msgid "%s's timeline" msgstr "" -#: src/Module/Profile/Profile.php:319 src/Module/Profile/Status.php:66 -#: src/Protocol/Feed.php:1028 src/Protocol/OStatus.php:1052 +#: src/Module/Profile/Profile.php:352 src/Module/Profile/Status.php:107 +#: src/Protocol/Feed.php:1028 src/Protocol/OStatus.php:1050 #, php-format msgid "%s's posts" msgstr "" -#: src/Module/Profile/Profile.php:320 src/Module/Profile/Status.php:67 -#: src/Protocol/Feed.php:1031 src/Protocol/OStatus.php:1056 +#: src/Module/Profile/Profile.php:353 src/Module/Profile/Status.php:108 +#: src/Protocol/Feed.php:1031 src/Protocol/OStatus.php:1054 #, php-format msgid "%s's comments" msgstr "" @@ -10287,7 +10287,7 @@ msgstr "" msgid "Exception thrown in %s:%d" msgstr "" -#: src/Module/Tos.php:57 src/Module/Tos.php:104 +#: src/Module/Tos.php:57 src/Module/Tos.php:106 msgid "" "At the time of registration, and for providing communications between the " "user account and their contacts, the user has to provide a display name (pen " @@ -10300,14 +10300,14 @@ msgid "" "settings, it is not necessary for communication." msgstr "" -#: src/Module/Tos.php:58 src/Module/Tos.php:105 +#: src/Module/Tos.php:58 src/Module/Tos.php:107 msgid "" "This data is required for communication and is passed on to the nodes of the " "communication partners and is stored there. Users can enter additional " "private data that may be transmitted to the communication partners accounts." msgstr "" -#: src/Module/Tos.php:59 src/Module/Tos.php:106 +#: src/Module/Tos.php:59 src/Module/Tos.php:108 #, php-format msgid "" "At any point in time a logged in user can export their account data from the " @@ -10318,11 +10318,11 @@ msgid "" "communication partners." msgstr "" -#: src/Module/Tos.php:62 src/Module/Tos.php:103 +#: src/Module/Tos.php:62 src/Module/Tos.php:105 msgid "Privacy Statement" msgstr "" -#: src/Module/Tos.php:100 +#: src/Module/Tos.php:102 msgid "Rules" msgstr "" @@ -10659,6 +10659,7 @@ msgid "%1$s shared your comment %2$s" msgstr "" #: src/Navigation/Notifications/Factory/Notification.php:231 +#: src/Navigation/Notifications/Factory/Notification.php:316 #, php-format msgid "%1$s shared your post %2$s" msgstr "" @@ -10792,7 +10793,7 @@ msgid "%1$s commented on their %2$s %3$s" msgstr "" #: src/Navigation/Notifications/Repository/Notify.php:341 -#: src/Navigation/Notifications/Repository/Notify.php:786 +#: src/Navigation/Notifications/Repository/Notify.php:789 #, php-format msgid "%1$s Comment to conversation #%2$d by %3$s" msgstr "" @@ -10804,7 +10805,7 @@ msgstr "" #: src/Navigation/Notifications/Repository/Notify.php:347 #: src/Navigation/Notifications/Repository/Notify.php:362 -#: src/Navigation/Notifications/Repository/Notify.php:801 +#: src/Navigation/Notifications/Repository/Notify.php:807 #, php-format msgid "Please visit %s to view and/or reply to the conversation." msgstr "" @@ -11007,6 +11008,11 @@ msgstr "" msgid "%s %s shared a new post" msgstr "" +#: src/Navigation/Notifications/Repository/Notify.php:787 +#, php-format +msgid "%1$s Like in conversation #%2$d by %3$s" +msgstr "" + #: src/Object/EMail/ItemCCEMail.php:42 #, php-format msgid "" @@ -11231,21 +11237,21 @@ msgstr "" msgid "Show fewer" msgstr "" -#: src/Protocol/OStatus.php:1472 +#: src/Protocol/OStatus.php:1470 #, php-format msgid "%s is now following %s." msgstr "" -#: src/Protocol/OStatus.php:1473 +#: src/Protocol/OStatus.php:1471 msgid "following" msgstr "" -#: src/Protocol/OStatus.php:1476 +#: src/Protocol/OStatus.php:1474 #, php-format msgid "%s stopped following %s." msgstr "" -#: src/Protocol/OStatus.php:1477 +#: src/Protocol/OStatus.php:1475 msgid "stopped following" msgstr "" From d52c988ebc8cd6a26f499c8ad625e4c4e1202cc9 Mon Sep 17 00:00:00 2001 From: MarekBenjamin <117765478+MarekBenjamin@users.noreply.github.com> Date: Fri, 23 Dec 2022 01:22:21 +0100 Subject: [PATCH 0018/1145] Update src/Navigation/Notifications/Repository/Notify.php Co-authored-by: Hypolite Petovan --- src/Navigation/Notifications/Repository/Notify.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Navigation/Notifications/Repository/Notify.php b/src/Navigation/Notifications/Repository/Notify.php index 7af61d0b68..c15500ad66 100644 --- a/src/Navigation/Notifications/Repository/Notify.php +++ b/src/Navigation/Notifications/Repository/Notify.php @@ -771,7 +771,7 @@ class Notify extends BaseRepository $title = '"' . trim(str_replace("\n", " ", $title)) . '"'; } - // Some mail software rely on subject field for threading. + // Some mail software relies on the subject field for threading. // So, we cannot have different subjects for notifications of the same thread. // Before this we have the name of the replier on the subject rendering // different subjects for messages on the same thread. From b876a9efcd5580fe9c8800b7fdf165c6f6c4345a Mon Sep 17 00:00:00 2001 From: Marek Bachmann Date: Fri, 23 Dec 2022 02:38:00 +0100 Subject: [PATCH 0019/1145] Distinguish between comment likes and post likes. --- .../Notifications/Repository/Notify.php | 11 ++++++++--- view/lang/C/messages.po | 15 ++++++++++----- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/Navigation/Notifications/Repository/Notify.php b/src/Navigation/Notifications/Repository/Notify.php index 7af61d0b68..e2eb6cbf69 100644 --- a/src/Navigation/Notifications/Repository/Notify.php +++ b/src/Navigation/Notifications/Repository/Notify.php @@ -784,14 +784,19 @@ class Notify extends BaseRepository } else { $params['type'] = Model\Notification\Type::COMMENT; if ($params['verb'] = Activity::LIKE) { - $subject = $l10n->t('%1$s Like in conversation #%2$d by %3$s', $subjectPrefix, $item['parent'], $contact['name']); + switch ($Notification->type) { + case Model\Post\UserNotification::TYPE_DIRECT_COMMENT: + $subject = $l10n->t('%1$s %2$s liked your post #%3$d', $subjectPrefix, $contact['name'], $item['parent']); + break; + case Model\Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT: + $subject = $l10n->t('%1$s %2$s liked your comment on #%3$d', $subjectPrefix, $contact['name'], $item['parent']); + break; + } } else { $subject = $l10n->t('%1$s Comment to conversation #%2$d by %3$s', $subjectPrefix, $item['parent'], $contact['name']); } } - - $msg = $this->notification->getMessageFromNotification($Notification); if (empty($msg)) { $this->logger->info('No notification message, quitting', ['uid' => $Notification->uid, 'id' => $Notification->id, 'type' => $Notification->type]); diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index e4d20b57e5..a086ec4c13 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2023.03-dev\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-12-23 01:05+0100\n" +"POT-Creation-Date: 2022-12-23 02:32+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -10793,7 +10793,7 @@ msgid "%1$s commented on their %2$s %3$s" msgstr "" #: src/Navigation/Notifications/Repository/Notify.php:341 -#: src/Navigation/Notifications/Repository/Notify.php:789 +#: src/Navigation/Notifications/Repository/Notify.php:796 #, php-format msgid "%1$s Comment to conversation #%2$d by %3$s" msgstr "" @@ -10805,7 +10805,7 @@ msgstr "" #: src/Navigation/Notifications/Repository/Notify.php:347 #: src/Navigation/Notifications/Repository/Notify.php:362 -#: src/Navigation/Notifications/Repository/Notify.php:807 +#: src/Navigation/Notifications/Repository/Notify.php:812 #, php-format msgid "Please visit %s to view and/or reply to the conversation." msgstr "" @@ -11008,9 +11008,14 @@ msgstr "" msgid "%s %s shared a new post" msgstr "" -#: src/Navigation/Notifications/Repository/Notify.php:787 +#: src/Navigation/Notifications/Repository/Notify.php:789 #, php-format -msgid "%1$s Like in conversation #%2$d by %3$s" +msgid "%1$s %2$s liked your post #%3$d" +msgstr "" + +#: src/Navigation/Notifications/Repository/Notify.php:792 +#, php-format +msgid "%1$s %2$s liked your comment on #%3$d" msgstr "" #: src/Object/EMail/ItemCCEMail.php:42 From 179d776d0ada7bc12ac1f6963c395c99cdf3ab64 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 23 Dec 2022 06:22:12 +0000 Subject: [PATCH 0020/1145] Only check the homepage for active users with a homepage --- src/Worker/Cron.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Worker/Cron.php b/src/Worker/Cron.php index d450f4cd5b..ecf8ad9f40 100644 --- a/src/Worker/Cron.php +++ b/src/Worker/Cron.php @@ -27,9 +27,9 @@ use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Tag; -use Friendica\Model\User; use Friendica\Protocol\ActivityPub\Queue; use Friendica\Protocol\Relay; +use Friendica\Util\DateTimeFormat; class Cron { @@ -136,10 +136,12 @@ class Cron Worker::add(Worker::PRIORITY_LOW, 'OptimizeTables'); } - foreach (User::getList(1, PHP_INT_MAX, 'active') as $user) { + $users = DBA::select('owner-view', ['uid'], ["`last-activity` > ? AND (`homepage_verified` OR `homepage` != ?)", DateTimeFormat::utc('now - 30 days', 'Y-m-d'), '']); + while ($user = DBA::fetch($users)) { Worker::add(Worker::PRIORITY_LOW, 'CheckRelMeProfileLink', $user['uid']); } - + DBA::close($users); + // Resubscribe to relay servers Relay::reSubscribe(); From 1e888ad6a4b86744832ab7b10d1eba85ca789f50 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 23 Dec 2022 06:26:58 +0000 Subject: [PATCH 0021/1145] Always check whe verified --- src/Worker/Cron.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Worker/Cron.php b/src/Worker/Cron.php index ecf8ad9f40..94f002805b 100644 --- a/src/Worker/Cron.php +++ b/src/Worker/Cron.php @@ -136,7 +136,7 @@ class Cron Worker::add(Worker::PRIORITY_LOW, 'OptimizeTables'); } - $users = DBA::select('owner-view', ['uid'], ["`last-activity` > ? AND (`homepage_verified` OR `homepage` != ?)", DateTimeFormat::utc('now - 30 days', 'Y-m-d'), '']); + $users = DBA::select('owner-view', ['uid'], ["`homepage_verified` OR (`last-activity` > ? AND `homepage` != ?)", DateTimeFormat::utc('now - 7 days', 'Y-m-d'), '']); while ($user = DBA::fetch($users)) { Worker::add(Worker::PRIORITY_LOW, 'CheckRelMeProfileLink', $user['uid']); } From 998b05095b81c00f7c7d7be4bb0cf271954f0b70 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 23 Dec 2022 06:48:53 +0000 Subject: [PATCH 0022/1145] A server is only reachable when the network can be detected --- src/Model/GServer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Model/GServer.php b/src/Model/GServer.php index 2fc37f35c3..b0a9dd5c9a 100644 --- a/src/Model/GServer.php +++ b/src/Model/GServer.php @@ -191,11 +191,11 @@ class GServer $condition = ['nurl' => Strings::normaliseLink($server)]; } - $gserver = DBA::selectFirst('gserver', ['url', 'next_contact', 'failed'], $condition); + $gserver = DBA::selectFirst('gserver', ['url', 'next_contact', 'failed', 'network'], $condition); if (empty($gserver)) { $reachable = true; } else { - $reachable = !$gserver['failed']; + $reachable = !$gserver['failed'] && in_array($gserver['network'], Protocol::FEDERATED); $server = $gserver['url']; } From 91c4ab23593f141e3d441ebe70dce8883244b27e Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 23 Dec 2022 02:41:22 -0500 Subject: [PATCH 0023/1145] Add new xpathQuote and checkRelMeLink methods to Content\Text\HTML class - Add tests for both methods --- src/Content/Text/HTML.php | 48 ++++++ .../dom/relme/a-multiple-rel-value-end.html | 10 ++ .../relme/a-multiple-rel-value-middle.html | 10 ++ .../dom/relme/a-multiple-rel-value-start.html | 10 ++ .../dom/relme/a-single-rel-value-fail.html | 10 ++ .../dom/relme/a-single-rel-value.html | 10 ++ .../dom/relme/link-single-rel-value-fail.html | 11 ++ .../dom/relme/link-single-rel-value.html | 11 ++ tests/src/Content/Text/HTMLTest.php | 150 ++++++++++++++++++ 9 files changed, 270 insertions(+) create mode 100644 tests/datasets/dom/relme/a-multiple-rel-value-end.html create mode 100644 tests/datasets/dom/relme/a-multiple-rel-value-middle.html create mode 100644 tests/datasets/dom/relme/a-multiple-rel-value-start.html create mode 100644 tests/datasets/dom/relme/a-single-rel-value-fail.html create mode 100644 tests/datasets/dom/relme/a-single-rel-value.html create mode 100644 tests/datasets/dom/relme/link-single-rel-value-fail.html create mode 100644 tests/datasets/dom/relme/link-single-rel-value.html diff --git a/src/Content/Text/HTML.php b/src/Content/Text/HTML.php index fa5a0a5905..00d609cb60 100644 --- a/src/Content/Text/HTML.php +++ b/src/Content/Text/HTML.php @@ -33,6 +33,7 @@ use Friendica\Util\Network; use Friendica\Util\Strings; use Friendica\Util\XML; use League\HTMLToMarkdown\HtmlConverter; +use Psr\Http\Message\UriInterface; class HTML { @@ -1007,4 +1008,51 @@ class HTML return $text; } + + /** + * XPath arbitrary string quoting + * + * @see https://stackoverflow.com/a/45228168 + * @param string $value + * @return string + */ + public static function xpathQuote(string $value): string + { + if (false === strpos($value, '"')) { + return '"' . $value . '"'; + } + + if (false === strpos($value, "'")) { + return "'" . $value . "'"; + } + + // if the value contains both single and double quotes, construct an + // expression that concatenates all non-double-quote substrings with + // the quotes, e.g.: + // + // concat("'foo'", '"', "bar") + return 'concat(' . implode(', \'"\', ', array_map(['self', 'xpathQuote'], explode('"', $value))) . ')'; + } + + /** + * Checks if the provided URL is present in the DOM document in an element with the rel="me" attribute + * + * XHTML Friends Network http://gmpg.org/xfn/ + * + * @param DOMDocument $doc + * @param UriInterface $meUrl + * @return bool + */ + public static function checkRelMeLink(DOMDocument $doc, UriInterface $meUrl): bool + { + $xpath = new \DOMXpath($doc); + + // This expression checks that "me" is among the space-delimited values of the "rel" attribute. + // And that the href attribute contains exactly the provided URL + $expression = "//*[contains(concat(' ', normalize-space(@rel), ' '), ' me ')][@href = " . self::xpathQuote($meUrl) . "]"; + + $result = $xpath->query($expression); + + return $result !== false && $result->length > 0; + } } diff --git a/tests/datasets/dom/relme/a-multiple-rel-value-end.html b/tests/datasets/dom/relme/a-multiple-rel-value-end.html new file mode 100644 index 0000000000..5fa4cbdf4a --- /dev/null +++ b/tests/datasets/dom/relme/a-multiple-rel-value-end.html @@ -0,0 +1,10 @@ + + + + + Remote page + + + My Profile + + diff --git a/tests/datasets/dom/relme/a-multiple-rel-value-middle.html b/tests/datasets/dom/relme/a-multiple-rel-value-middle.html new file mode 100644 index 0000000000..08d33f051b --- /dev/null +++ b/tests/datasets/dom/relme/a-multiple-rel-value-middle.html @@ -0,0 +1,10 @@ + + + + + Remote page + + + My Profile + + diff --git a/tests/datasets/dom/relme/a-multiple-rel-value-start.html b/tests/datasets/dom/relme/a-multiple-rel-value-start.html new file mode 100644 index 0000000000..c71d8288ca --- /dev/null +++ b/tests/datasets/dom/relme/a-multiple-rel-value-start.html @@ -0,0 +1,10 @@ + + + + + Remote page + + + My Profile + + diff --git a/tests/datasets/dom/relme/a-single-rel-value-fail.html b/tests/datasets/dom/relme/a-single-rel-value-fail.html new file mode 100644 index 0000000000..2735aa4aa7 --- /dev/null +++ b/tests/datasets/dom/relme/a-single-rel-value-fail.html @@ -0,0 +1,10 @@ + + + + + Remote page + + + My Profile + + diff --git a/tests/datasets/dom/relme/a-single-rel-value.html b/tests/datasets/dom/relme/a-single-rel-value.html new file mode 100644 index 0000000000..26d61204e7 --- /dev/null +++ b/tests/datasets/dom/relme/a-single-rel-value.html @@ -0,0 +1,10 @@ + + + + + Remote page + + + My Profile + + diff --git a/tests/datasets/dom/relme/link-single-rel-value-fail.html b/tests/datasets/dom/relme/link-single-rel-value-fail.html new file mode 100644 index 0000000000..2b7df5cb22 --- /dev/null +++ b/tests/datasets/dom/relme/link-single-rel-value-fail.html @@ -0,0 +1,11 @@ + + + + + Remote page + + + + + + diff --git a/tests/datasets/dom/relme/link-single-rel-value.html b/tests/datasets/dom/relme/link-single-rel-value.html new file mode 100644 index 0000000000..f18d000f3d --- /dev/null +++ b/tests/datasets/dom/relme/link-single-rel-value.html @@ -0,0 +1,11 @@ + + + + + Remote page + + + + + + diff --git a/tests/src/Content/Text/HTMLTest.php b/tests/src/Content/Text/HTMLTest.php index bc352e5427..e4a8603595 100644 --- a/tests/src/Content/Text/HTMLTest.php +++ b/tests/src/Content/Text/HTMLTest.php @@ -25,6 +25,8 @@ use Exception; use Friendica\Content\Text\HTML; use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Test\FixtureTest; +use GuzzleHttp\Psr7\Uri; +use Psr\Http\Message\UriInterface; class HTMLTest extends FixtureTest { @@ -105,4 +107,152 @@ its surprisingly good", self::assertEquals($expectedBBCode, $actual); } + + public function dataXpathQuote(): array + { + return [ + 'no quotes' => [ + 'value' => "foo", + ], + 'double quotes only' => [ + 'value' => "\"foo", + ], + 'single quotes only' => [ + 'value' => "'foo", + ], + 'both; double quotes in mid-string' => [ + 'value' => "'foo\"bar", + ], + 'multiple double quotes in mid-string' => [ + 'value' => "'foo\"bar\"baz", + ], + 'string ends with double quotes' => [ + 'value' => "'foo\"", + ], + 'string ends with run of double quotes' => [ + 'value' => "'foo\"\"", + ], + 'string begins with double quotes' => [ + 'value' => "\"'foo", + ], + 'string begins with run of double quotes' => [ + 'value' => "\"\"'foo", + ], + 'run of double quotes in mid-string' => [ + 'value' => "'foo\"\"bar", + ], + ]; + } + + /** + * @dataProvider dataXpathQuote + * @param string $value + * @return void + * @throws \DOMException + */ + public function testXpathQuote(string $value) + { + $dom = new \DOMDocument(); + $element = $dom->createElement('test'); + $attribute = $dom->createAttribute('value'); + $attribute->value = $value; + $element->appendChild($attribute); + $dom->appendChild($element); + + $xpath = new \DOMXPath($dom); + + $result = $xpath->query('//test[@value = ' . HTML::xpathQuote($value) . ']'); + + $this->assertInstanceOf(\DOMNodeList::class, $result); + $this->assertEquals(1, $result->length); + } + + public function dataCheckRelMeLink(): array + { + $aSingleRelValue = new \DOMDocument(); + $aSingleRelValue->load(__DIR__ . '/../../../datasets/dom/relme/a-single-rel-value.html'); + + $aMultipleRelValueStart = new \DOMDocument(); + $aMultipleRelValueStart->load(__DIR__ . '/../../../datasets/dom/relme/a-multiple-rel-value-start.html'); + + $aMultipleRelValueMiddle = new \DOMDocument(); + $aMultipleRelValueMiddle->load(__DIR__ . '/../../../datasets/dom/relme/a-multiple-rel-value-middle.html'); + + $aMultipleRelValueEnd = new \DOMDocument(); + $aMultipleRelValueEnd->load(__DIR__ . '/../../../datasets/dom/relme/a-multiple-rel-value-end.html'); + + $linkSingleRelValue = new \DOMDocument(); + $linkSingleRelValue->load(__DIR__ . '/../../../datasets/dom/relme/link-single-rel-value.html'); + + $meUrl = new Uri('https://example.com/profile/me'); + + return [ + 'a-single-rel-value' => [ + 'doc' => $aSingleRelValue, + 'meUrl' => $meUrl + ], + 'a-multiple-rel-value-start' => [ + 'doc' => $aMultipleRelValueStart, + 'meUrl' => $meUrl + ], + 'a-multiple-rel-value-middle' => [ + 'doc' => $aMultipleRelValueMiddle, + 'meUrl' => $meUrl + ], + 'a-multiple-rel-value-end' => [ + 'doc' => $aMultipleRelValueEnd, + 'meUrl' => $meUrl + ], + 'link-single-rel-value' => [ + 'doc' => $linkSingleRelValue, + 'meUrl' => $meUrl + ], + ]; + } + + + /** + * @dataProvider dataCheckRelMeLink + * @param \DOMDocument $doc + * @param UriInterface $meUrl + * @return void + */ + public function testCheckRelMeLink(\DOMDocument $doc, UriInterface $meUrl) + { + $this->assertTrue(HTML::checkRelMeLink($doc, $meUrl)); + } + + public function dataCheckRelMeLinkFail(): array + { + $aSingleRelValueFail = new \DOMDocument(); + $aSingleRelValueFail->load(__DIR__ . '/../../../datasets/dom/relme/a-single-rel-value-fail.html'); + + $linkSingleRelValueFail = new \DOMDocument(); + $linkSingleRelValueFail->load(__DIR__ . '/../../../datasets/dom/relme/link-single-rel-value-fail.html'); + + $meUrl = new Uri('https://example.com/profile/me'); + + return [ + 'a-single-rel-value-fail' => [ + 'doc' => $aSingleRelValueFail, + 'meUrl' => $meUrl + ], + 'link-single-rel-value-fail' => [ + 'doc' => $linkSingleRelValueFail, + 'meUrl' => $meUrl + ], + ]; + } + + + /** + * @dataProvider dataCheckRelMeLinkFail + * @param \DOMDocument $doc + * @param UriInterface $meUrl + * @return void + */ + public function testCheckRelMeLinkFail(\DOMDocument $doc, UriInterface $meUrl) + { + $this->assertFalse(HTML::checkRelMeLink($doc, $meUrl)); + } } From b2f2fbc4d42b92451dd93c56ecb2983693b2c313 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 23 Dec 2022 02:42:58 -0500 Subject: [PATCH 0024/1145] Flatten conditions and add call to HTML::checkRelMeLink in Worker\CheckRelMeProfileLink --- src/Worker/CheckRelMeProfileLink.php | 72 +++++++++++++--------------- 1 file changed, 33 insertions(+), 39 deletions(-) diff --git a/src/Worker/CheckRelMeProfileLink.php b/src/Worker/CheckRelMeProfileLink.php index 987619e19a..ebd0254889 100644 --- a/src/Worker/CheckRelMeProfileLink.php +++ b/src/Worker/CheckRelMeProfileLink.php @@ -22,14 +22,14 @@ namespace Friendica\Worker; use DOMDocument; -use Friendica\DI; +use Friendica\Content\Text\HTML; use Friendica\Core\Logger; +use Friendica\DI; use Friendica\Model\Profile; use Friendica\Model\User; use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPClient\Client\HttpClientOptions; -use Friendica\Util\Network; -use Friendica\Util\Strings; +use GuzzleHttp\Psr7\Uri; /* This class is used to verify the homepage link of a user profile. * To do so, we look for rel="me" links in the given homepage, if one @@ -56,43 +56,37 @@ class CheckRelMeProfileLink { Logger::notice('Verifying the homepage', ['uid' => $uid]); Profile::update(['homepage_verified' => false], $uid); - $homepageUrlVerified = false; - $owner = User::getOwnerDataById($uid); - if (!empty($owner['homepage'])) { - $xrd_timeout = DI::config()->get('system', 'xrd_timeout'); - $curlResult = DI::httpClient()->get($owner['homepage'], $accept_content = HttpClientAccept::HTML, [HttpClientOptions::TIMEOUT => $xrd_timeout]); - if ($curlResult->isSuccess()) { - $content = $curlResult->getBody(); - if (!$content) { - Logger::notice('Empty body of the fetched homepage link). Cannot verify the relation to profile of UID %s.', ['uid' => $uid, 'owner homepage' => $owner['homepage']]); - } else { - $doc = new DOMDocument(); - @$doc->loadHTML($content); - if (!$doc) { - Logger::notice('Could not parse the content'); - } else { - foreach ($doc->getElementsByTagName('a') as $link) { - $rel = $link->getAttribute('rel'); - if ($rel == 'me') { - $href = $link->getAttribute('href'); - if (!$homepageUrlVerified && Network::isValidHttpUrl($href)) { - $homepageUrlVerified = Strings::compareLink($owner['url'], $href); - } - } - } - } - if ($homepageUrlVerified) { - Profile::update(['homepage_verified' => true], $uid); - Logger::notice('Homepage URL verified', ['uid' => $uid, 'owner homepage' => $owner['homepage']]); - } else { - Logger::notice('Homepage URL could not be verified', ['uid' => $uid, 'owner homepage' => $owner['homepage']]); - } - } - } else { - Logger::notice('Could not cURL the homepage URL', ['owner homepage' => $owner['homepage']]); - } - } else { + + $owner = User::getOwnerDataById($uid); + if (empty($owner['homepage'])) { Logger::notice('The user has no homepage link.', ['uid' => $uid]); + return; + } + + $xrd_timeout = DI::config()->get('system', 'xrd_timeout'); + $curlResult = DI::httpClient()->get($owner['homepage'], HttpClientAccept::HTML, [HttpClientOptions::TIMEOUT => $xrd_timeout]); + if (!$curlResult->isSuccess()) { + Logger::notice('Could not cURL the homepage URL', ['owner homepage' => $owner['homepage']]); + return; + } + + $content = $curlResult->getBody(); + if (!$content) { + Logger::notice('Empty body of the fetched homepage link). Cannot verify the relation to profile of UID %s.', ['uid' => $uid, 'owner homepage' => $owner['homepage']]); + return; + } + + $doc = new DOMDocument(); + if (!@$doc->loadHTML($content)) { + Logger::notice('Could not parse the content'); + return; + } + + if (HTML::checkRelMeLink($doc, new Uri($owner['url']))) { + Profile::update(['homepage_verified' => true], $uid); + Logger::notice('Homepage URL verified', ['uid' => $uid, 'owner homepage' => $owner['homepage']]); + } else { + Logger::notice('Homepage URL could not be verified', ['uid' => $uid, 'owner homepage' => $owner['homepage']]); } } } From 3061cee083ebbd531b6e44e96b4ab44aca4ac0fa Mon Sep 17 00:00:00 2001 From: MarekBenjamin <117765478+MarekBenjamin@users.noreply.github.com> Date: Fri, 23 Dec 2022 11:14:38 +0100 Subject: [PATCH 0025/1145] Update src/Navigation/Notifications/Repository/Notify.php Co-authored-by: Hypolite Petovan --- src/Navigation/Notifications/Repository/Notify.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Navigation/Notifications/Repository/Notify.php b/src/Navigation/Notifications/Repository/Notify.php index ff69637c31..278451936d 100644 --- a/src/Navigation/Notifications/Repository/Notify.php +++ b/src/Navigation/Notifications/Repository/Notify.php @@ -786,14 +786,14 @@ class Notify extends BaseRepository if ($params['verb'] = Activity::LIKE) { switch ($Notification->type) { case Model\Post\UserNotification::TYPE_DIRECT_COMMENT: - $subject = $l10n->t('%1$s %2$s liked your post #%3$d', $subjectPrefix, $contact['name'], $item['parent']); + $subject = $l10n->t('%1$s %2$s liked your post #%3$d', $subjectPrefix, $contact['name'], $item['parent']); break; case Model\Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT: - $subject = $l10n->t('%1$s %2$s liked your comment on #%3$d', $subjectPrefix, $contact['name'], $item['parent']); + $subject = $l10n->t('%1$s %2$s liked your comment on #%3$d', $subjectPrefix, $contact['name'], $item['parent']); break; } } else { - $subject = $l10n->t('%1$s Comment to conversation #%2$d by %3$s', $subjectPrefix, $item['parent'], $contact['name']); + $subject = $l10n->t('%1$s Comment to conversation #%2$d by %3$s', $subjectPrefix, $item['parent'], $contact['name']); } } From ca12d1549b3269234186dac6b7c4f87a4fc1987f Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 23 Dec 2022 22:11:50 +0000 Subject: [PATCH 0026/1145] AP: We can now store received reports --- src/DI.php | 10 ++++++++ src/Protocol/ActivityPub/Processor.php | 33 ++++++++++++++++++++++++++ src/Protocol/ActivityPub/Receiver.php | 17 ++++++++++++- 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/DI.php b/src/DI.php index 59f48fcb5f..bf2b5a2371 100644 --- a/src/DI.php +++ b/src/DI.php @@ -532,6 +532,16 @@ abstract class DI return self::$dice->create(Contact\Introduction\Factory\Introduction::class); } + public static function report(): Moderation\Repository\Report + { + return self::$dice->create(Moderation\Repository\Report::class); + } + + public static function reportFactory(): Moderation\Factory\Report + { + return self::$dice->create(Moderation\Factory\Report::class); + } + public static function localRelationship(): Contact\LocalRelationship\Repository\LocalRelationship { return self::$dice->create(Contact\LocalRelationship\Repository\LocalRelationship::class); diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index d689ba72a5..a4333217de 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -1821,6 +1821,39 @@ class Processor Queue::remove($activity); } + /** + * Report a user + * + * @param array $activity + * @return void + * @throws \Exception + */ + public static function ReportAccount(array $activity) + { + $account_id = Contact::getIdForURL($activity['object_id']); + if (empty($account_id)) { + Logger::info('Unknown account', ['activity' => $activity]); + Queue::remove($activity); + return; + } + + $status_ids = $activity['object_ids']; + array_shift($status_ids); + + $uri_ids = []; + foreach ($status_ids as $status_id) { + $post = Post::selectFirst(['uri-id'], ['uri' => $status_id]); + if (!empty($post['uri-id'])) { + $uri_ids[] = $post['uri-id']; + } + } + + $report = DI::reportFactory()->createFromReportsRequest(0, $account_id, $activity['content'], false, $uri_ids); + DI::report()->save($report); + + Logger::info('Stored report', ['account_id' => $account_id, 'comment' => $activity['content'], 'status_ids' => $status_ids]); + } + /** * Accept a follow request * diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index cb76ca7e18..85965d7129 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -406,7 +406,14 @@ class Receiver } // Any activities on account types must not be altered - if (in_array($object_type, self::ACCOUNT_TYPES)) { + if (in_array($type, ['as:Flag'])) { + $object_data = []; + $object_data['id'] = JsonLD::fetchElement($activity, '@id'); + $object_data['object_id'] = JsonLD::fetchElement($activity, 'as:object', '@id'); + $object_data['object_ids'] = JsonLD::fetchElementArray($activity, 'as:object', '@id'); + $object_data['content'] = JsonLD::fetchElement($activity, 'as:content', '@type'); + $object_data['push'] = $push; + } elseif (in_array($object_type, self::ACCOUNT_TYPES)) { $object_data = []; $object_data['id'] = JsonLD::fetchElement($activity, '@id'); $object_data['object_id'] = JsonLD::fetchElement($activity, 'as:object', '@id'); @@ -843,6 +850,14 @@ class Receiver } break; + case 'as:Flag': + if (in_array($object_data['object_type'], self::ACCOUNT_TYPES)) { + ActivityPub\Processor::ReportAccount($object_data); + } else { + return false; + } + break; + case 'as:Remove': if (in_array($object_data['object_type'], self::CONTENT_TYPES)) { ActivityPub\Processor::removeFromFeaturedCollection($object_data); From 72e1d5d417375effc307227a19c4152ac67ce8b5 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 23 Dec 2022 22:43:32 +0000 Subject: [PATCH 0027/1145] Fix storing reports --- src/Moderation/Repository/Report.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Moderation/Repository/Report.php b/src/Moderation/Repository/Report.php index 3ffc0de8af..75a7f06dcd 100644 --- a/src/Moderation/Repository/Report.php +++ b/src/Moderation/Repository/Report.php @@ -45,7 +45,7 @@ class Report extends \Friendica\BaseRepository $this->factory = $factory; } - public function selectOneById(int $lastInsertId): \Friendica\Moderation\Factory\Report + public function selectOneById(int $lastInsertId): \Friendica\Moderation\Entity\Report { return $this->_selectOne(['id' => $lastInsertId]); } @@ -59,6 +59,8 @@ class Report extends \Friendica\BaseRepository 'forward' => $Report->forward, ]; + $postUriIds = $Report->postUriIds; + if ($Report->id) { $this->db->update(self::$table_name, $fields, ['id' => $Report->id]); } else { @@ -70,7 +72,7 @@ class Report extends \Friendica\BaseRepository $this->db->delete('report-post', ['rid' => $Report->id]); - foreach ($Report->postUriIds as $uriId) { + foreach ($postUriIds as $uriId) { if (Post::exists(['uri-id' => $uriId])) { $this->db->insert('report-post', ['rid' => $Report->id, 'uri-id' => $uriId]); } else { From 8cb85368ff3667201320ed7168317ae658592cec Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 23 Dec 2022 22:48:57 +0000 Subject: [PATCH 0028/1145] Added comment --- src/Protocol/ActivityPub/Processor.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index a4333217de..843f4b8cf6 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -1848,6 +1848,7 @@ class Processor } } + // @todo We should store the actor $report = DI::reportFactory()->createFromReportsRequest(0, $account_id, $activity['content'], false, $uri_ids); DI::report()->save($report); From 4c945850f4d9e09f41ea85b82a431943cf35ead3 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 24 Dec 2022 08:03:37 +0000 Subject: [PATCH 0029/1145] Reports: The reporting contact id is added --- database.sql | 5 +- doc/database/db_report.md | 31 ++++++----- src/Moderation/Entity/Report.php | 5 +- src/Moderation/Factory/Report.php | 5 +- src/Moderation/Repository/Report.php | 9 +-- src/Module/Api/Mastodon/Reports.php | 2 +- src/Protocol/ActivityPub/Processor.php | 12 +++- static/dbstructure.config.php | 4 +- tests/src/Moderation/Factory/ReportTest.php | 61 ++++++++++++--------- 9 files changed, 82 insertions(+), 52 deletions(-) diff --git a/database.sql b/database.sql index d93c979f05..2f8882d4b4 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2023.03-dev (Giant Rhubarb) --- DB_UPDATE_VERSION 1503 +-- DB_UPDATE_VERSION 1504 -- ------------------------------------------ @@ -1674,6 +1674,7 @@ CREATE TABLE IF NOT EXISTS `register` ( CREATE TABLE IF NOT EXISTS `report` ( `id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID', `uid` mediumint unsigned COMMENT 'Reporting user', + `reporter-id` int unsigned COMMENT 'Reporting contact', `cid` int unsigned NOT NULL COMMENT 'Reported contact', `comment` text COMMENT 'Report', `forward` boolean COMMENT 'Forward the report to the remote server', @@ -1682,7 +1683,9 @@ CREATE TABLE IF NOT EXISTS `report` ( PRIMARY KEY(`id`), INDEX `uid` (`uid`), INDEX `cid` (`cid`), + INDEX `reporter-id` (`reporter-id`), FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE, + FOREIGN KEY (`reporter-id`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE, FOREIGN KEY (`cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE ) DEFAULT COLLATE utf8mb4_general_ci COMMENT=''; diff --git a/doc/database/db_report.md b/doc/database/db_report.md index 9a87abe1f4..fcec88234d 100644 --- a/doc/database/db_report.md +++ b/doc/database/db_report.md @@ -6,24 +6,26 @@ Table report Fields ------ -| Field | Description | Type | Null | Key | Default | Extra | -| ------- | --------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- | -| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment | -| uid | Reporting user | mediumint unsigned | YES | | NULL | | -| cid | Reported contact | int unsigned | NO | | NULL | | -| comment | Report | text | YES | | NULL | | -| forward | Forward the report to the remote server | boolean | YES | | NULL | | -| created | | datetime | NO | | 0001-01-01 00:00:00 | | -| status | Status of the report | tinyint unsigned | YES | | NULL | | +| Field | Description | Type | Null | Key | Default | Extra | +| ----------- | --------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- | +| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment | +| uid | Reporting user | mediumint unsigned | YES | | NULL | | +| reporter-id | Reporting contact | int unsigned | YES | | NULL | | +| cid | Reported contact | int unsigned | NO | | NULL | | +| comment | Report | text | YES | | NULL | | +| forward | Forward the report to the remote server | boolean | YES | | NULL | | +| created | | datetime | NO | | 0001-01-01 00:00:00 | | +| status | Status of the report | tinyint unsigned | YES | | NULL | | Indexes ------------ -| Name | Fields | -| ------- | ------ | -| PRIMARY | id | -| uid | uid | -| cid | cid | +| Name | Fields | +| ----------- | ----------- | +| PRIMARY | id | +| uid | uid | +| cid | cid | +| reporter-id | reporter-id | Foreign Keys ------------ @@ -31,6 +33,7 @@ Foreign Keys | Field | Target Table | Target Field | |-------|--------------|--------------| | uid | [user](help/database/db_user) | uid | +| reporter-id | [contact](help/database/db_contact) | id | | cid | [contact](help/database/db_contact) | id | Return to [database documentation](help/database) diff --git a/src/Moderation/Entity/Report.php b/src/Moderation/Entity/Report.php index 93d42b94ef..957cef8652 100644 --- a/src/Moderation/Entity/Report.php +++ b/src/Moderation/Entity/Report.php @@ -35,6 +35,8 @@ class Report extends \Friendica\BaseEntity /** @var int|null */ protected $id; /** @var int ID of the user making a moderation report*/ + protected $reporterId; + /** @var int ID of the contact making a moderation report*/ protected $uid; /** @var int ID of the contact being reported*/ protected $cid; @@ -47,9 +49,10 @@ class Report extends \Friendica\BaseEntity /** @var array Optional list of URI IDs of posts supporting the report*/ protected $postUriIds; - public function __construct(int $uid, int $cid, \DateTime $created, string $comment = '', bool $forward = false, array $postUriIds = [], int $id = null) + public function __construct(int $uid = null, int $reporterId, int $cid, \DateTime $created, string $comment = '', bool $forward = false, array $postUriIds = [], int $id = null) { $this->uid = $uid; + $this->reporterId = $reporterId; $this->cid = $cid; $this->created = $created; $this->comment = $comment; diff --git a/src/Moderation/Factory/Report.php b/src/Moderation/Factory/Report.php index 17203d3078..918c10bc84 100644 --- a/src/Moderation/Factory/Report.php +++ b/src/Moderation/Factory/Report.php @@ -36,6 +36,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow { return new Entity\Report( $row['uid'], + $row['reporter-id'], $row['cid'], new \DateTime($row['created'] ?? 'now', new \DateTimeZone('UTC')), $row['comment'], @@ -51,6 +52,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow * @see \Friendica\Module\Api\Mastodon\Reports::post() * * @param int $uid + * @param int $reporterId * @param int $cid * @param string $comment * @param bool $forward @@ -58,10 +60,11 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow * @return Entity\Report * @throws \Exception */ - public function createFromReportsRequest(int $uid, int $cid, string $comment = '', bool $forward = false, array $postUriIds = []): Entity\Report + public function createFromReportsRequest(int $uid = null, int $reporterId, int $cid, string $comment = '', bool $forward = false, array $postUriIds = []): Entity\Report { return new Entity\Report( $uid, + $reporterId, $cid, new \DateTime('now', new \DateTimeZone('UTC')), $comment, diff --git a/src/Moderation/Repository/Report.php b/src/Moderation/Repository/Report.php index 75a7f06dcd..1882d85710 100644 --- a/src/Moderation/Repository/Report.php +++ b/src/Moderation/Repository/Report.php @@ -53,10 +53,11 @@ class Report extends \Friendica\BaseRepository public function save(\Friendica\Moderation\Entity\Report $Report) { $fields = [ - 'uid' => $Report->uid, - 'cid' => $Report->cid, - 'comment' => $Report->comment, - 'forward' => $Report->forward, + 'uid' => $Report->uid, + 'reporter-id' => $Report->reporterId, + 'cid' => $Report->cid, + 'comment' => $Report->comment, + 'forward' => $Report->forward, ]; $postUriIds = $Report->postUriIds; diff --git a/src/Module/Api/Mastodon/Reports.php b/src/Module/Api/Mastodon/Reports.php index 6ae54eb6f6..c8dc0044c3 100644 --- a/src/Module/Api/Mastodon/Reports.php +++ b/src/Module/Api/Mastodon/Reports.php @@ -65,7 +65,7 @@ class Reports extends BaseApi throw new HTTPException\NotFoundException('Account ' . $request['account_id'] . ' not found'); } - $report = $this->reportFactory->createFromReportsRequest(self::getCurrentUserID(), $request['account_id'], $request['comment'], $request['forward'], $request['status_ids']); + $report = $this->reportFactory->createFromReportsRequest(self::getCurrentUserID(), Contact::getPublicIdByUserId(self::getCurrentUserID()), $request['account_id'], $request['comment'], $request['forward'], $request['status_ids']); $this->reportRepo->save($report); diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 843f4b8cf6..76d050bd29 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -1837,6 +1837,13 @@ class Processor return; } + $reporter_id = Contact::getIdForURL($activity['actor']); + if (empty($account_id)) { + Logger::info('Unknown actor', ['activity' => $activity]); + Queue::remove($activity); + return; + } + $status_ids = $activity['object_ids']; array_shift($status_ids); @@ -1848,11 +1855,10 @@ class Processor } } - // @todo We should store the actor - $report = DI::reportFactory()->createFromReportsRequest(0, $account_id, $activity['content'], false, $uri_ids); + $report = DI::reportFactory()->createFromReportsRequest(null, $reporter_id, $account_id, $activity['content'], false, $uri_ids); DI::report()->save($report); - Logger::info('Stored report', ['account_id' => $account_id, 'comment' => $activity['content'], 'status_ids' => $status_ids]); + Logger::info('Stored report', ['reporter' => $reporter_id, 'account_id' => $account_id, 'comment' => $activity['content'], 'status_ids' => $status_ids]); } /** diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index ac2bb0e1ea..59046a6cc4 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -55,7 +55,7 @@ use Friendica\Database\DBA; if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1503); + define('DB_UPDATE_VERSION', 1504); } return [ @@ -1673,6 +1673,7 @@ return [ "fields" => [ "id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"], "uid" => ["type" => "mediumint unsigned", "foreign" => ["user" => "uid"], "comment" => "Reporting user"], + "reporter-id" => ["type" => "int unsigned", "foreign" => ["contact" => "id"], "comment" => "Reporting contact"], "cid" => ["type" => "int unsigned", "not null" => "1", "foreign" => ["contact" => "id"], "comment" => "Reported contact"], "comment" => ["type" => "text", "comment" => "Report"], "forward" => ["type" => "boolean", "comment" => "Forward the report to the remote server"], @@ -1683,6 +1684,7 @@ return [ "PRIMARY" => ["id"], "uid" => ["uid"], "cid" => ["cid"], + "reporter-id" => ["reporter-id"], ] ], "report-post" => [ diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php index 0f29709100..fa9461529d 100644 --- a/tests/src/Moderation/Factory/ReportTest.php +++ b/tests/src/Moderation/Factory/ReportTest.php @@ -33,16 +33,18 @@ class ReportTest extends MockedTest return [ 'default' => [ 'row' => [ - 'id' => 11, - 'uid' => 12, - 'cid' => 13, - 'comment' => '', - 'forward' => false, - 'created' => null + 'id' => 11, + 'uid' => 12, + 'reporter-id' => 14, + 'cid' => 13, + 'comment' => '', + 'forward' => false, + 'created' => null ], 'postUriIds' => [], 'assertion' => new Entity\Report( 12, + 14, 13, new \DateTime('now', new \DateTimeZone('UTC')), '', @@ -53,16 +55,18 @@ class ReportTest extends MockedTest ], 'full' => [ 'row' => [ - 'id' => 11, - 'uid' => 12, - 'cid' => 13, - 'comment' => 'Report', - 'forward' => true, - 'created' => '2021-10-12 12:23:00' + 'id' => 11, + 'uid' => 12, + 'reporter-id' => 14, + 'cid' => 13, + 'comment' => 'Report', + 'forward' => true, + 'created' => '2021-10-12 12:23:00' ], 'postUriIds' => [89, 90], 'assertion' => new Entity\Report( 12, + 14, 13, new \DateTime('2021-10-12 12:23:00', new \DateTimeZone('UTC')), 'Report', @@ -81,6 +85,7 @@ class ReportTest extends MockedTest $report->id ); self::assertEquals($assertion->uid, $report->uid); + self::assertEquals($assertion->reporterId, $report->reporterId); self::assertEquals($assertion->cid, $report->cid); self::assertEquals($assertion->comment, $report->comment); self::assertEquals($assertion->forward, $report->forward); @@ -103,13 +108,15 @@ class ReportTest extends MockedTest { return [ 'default' => [ - 'uid' => 12, - 'cid' => 13, - 'comment' => '', - 'forward' => false, - 'postUriIds' => [], - 'assertion' => new Entity\Report( + 'uid' => 12, + 'reporter-id' => 14, + 'cid' => 13, + 'comment' => '', + 'forward' => false, + 'postUriIds' => [], + 'assertion' => new Entity\Report( 12, + 14, 13, new \DateTime('now', new \DateTimeZone('UTC')), '', @@ -119,13 +126,15 @@ class ReportTest extends MockedTest ), ], 'full' => [ - 'uid' => 12, - 'cid' => 13, - 'comment' => 'Report', - 'forward' => true, - 'postUriIds' => [89, 90], - 'assertion' => new Entity\Report( + 'uid' => 12, + 'reporter-id' => 14, + 'cid' => 13, + 'comment' => 'Report', + 'forward' => true, + 'postUriIds' => [89, 90], + 'assertion' => new Entity\Report( 12, + 14, 13, new \DateTime('now', new \DateTimeZone('UTC')), 'Report', @@ -140,10 +149,10 @@ class ReportTest extends MockedTest /** * @dataProvider dataCreateFromReportsRequest */ - public function testCreateFromReportsRequest(int $uid, int $cid, string $comment, bool $forward, array $postUriIds, Entity\Report $assertion) + public function testCreateFromReportsRequest(int $uid, int $reporter, int $cid, string $comment, bool $forward, array $postUriIds, Entity\Report $assertion) { $factory = new Factory\Report(new NullLogger()); - $this->assertReport($factory->createFromReportsRequest($uid, $cid, $comment, $forward, $postUriIds), $assertion); + $this->assertReport($factory->createFromReportsRequest($uid, $reporter, $cid, $comment, $forward, $postUriIds), $assertion); } } From bf4d321aa3b37916be7b57c82f668c0d8c4c808a Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 24 Dec 2022 08:09:23 +0000 Subject: [PATCH 0030/1145] Wrong variable --- src/Protocol/ActivityPub/Processor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 76d050bd29..25c09c9cb5 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -1838,7 +1838,7 @@ class Processor } $reporter_id = Contact::getIdForURL($activity['actor']); - if (empty($account_id)) { + if (empty($reporter_id)) { Logger::info('Unknown actor', ['activity' => $activity]); Queue::remove($activity); return; From 8dcfafcfb0a79eaaa27ee617f4aff44cad44ec4b Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Sat, 24 Dec 2022 14:52:26 +0100 Subject: [PATCH 0031/1145] issue 12515 --- view/templates/media/browser.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/view/templates/media/browser.tpl b/view/templates/media/browser.tpl index 749c2bea7e..38feee5e07 100644 --- a/view/templates/media/browser.tpl +++ b/view/templates/media/browser.tpl @@ -33,7 +33,7 @@ {{foreach $files as $f}} From 509715068a8f59f9073e9d5360e0738292fafceb Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Sat, 24 Dec 2022 14:57:03 +0100 Subject: [PATCH 0032/1145] use correct field for ALT test --- view/templates/media/browser.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/view/templates/media/browser.tpl b/view/templates/media/browser.tpl index 38feee5e07..0dc57a983f 100644 --- a/view/templates/media/browser.tpl +++ b/view/templates/media/browser.tpl @@ -33,7 +33,7 @@ {{foreach $files as $f}} From 8a7d08ae2860d82fe98a26f4e86626b3c7eb4d1e Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 24 Dec 2022 13:57:43 +0000 Subject: [PATCH 0033/1145] Category added --- database.sql | 1 + doc/database/db_report.md | 21 +++++++++++---------- src/Moderation/Entity/Report.php | 5 ++++- src/Moderation/Factory/Report.php | 4 +++- src/Moderation/Repository/Report.php | 1 + src/Module/Api/Mastodon/Reports.php | 11 ++++++----- src/Protocol/ActivityPub/Processor.php | 2 +- static/dbstructure.config.php | 1 + tests/src/Moderation/Factory/ReportTest.php | 9 +++++++-- 9 files changed, 35 insertions(+), 20 deletions(-) diff --git a/database.sql b/database.sql index 2f8882d4b4..8c24dd4eb6 100644 --- a/database.sql +++ b/database.sql @@ -1677,6 +1677,7 @@ CREATE TABLE IF NOT EXISTS `report` ( `reporter-id` int unsigned COMMENT 'Reporting contact', `cid` int unsigned NOT NULL COMMENT 'Reported contact', `comment` text COMMENT 'Report', + `category` varchar(20) COMMENT 'Category of the report (spam, violation, other)', `forward` boolean COMMENT 'Forward the report to the remote server', `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '', `status` tinyint unsigned COMMENT 'Status of the report', diff --git a/doc/database/db_report.md b/doc/database/db_report.md index fcec88234d..56f51bdd41 100644 --- a/doc/database/db_report.md +++ b/doc/database/db_report.md @@ -6,16 +6,17 @@ Table report Fields ------ -| Field | Description | Type | Null | Key | Default | Extra | -| ----------- | --------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- | -| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment | -| uid | Reporting user | mediumint unsigned | YES | | NULL | | -| reporter-id | Reporting contact | int unsigned | YES | | NULL | | -| cid | Reported contact | int unsigned | NO | | NULL | | -| comment | Report | text | YES | | NULL | | -| forward | Forward the report to the remote server | boolean | YES | | NULL | | -| created | | datetime | NO | | 0001-01-01 00:00:00 | | -| status | Status of the report | tinyint unsigned | YES | | NULL | | +| Field | Description | Type | Null | Key | Default | Extra | +| ----------- | ----------------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- | +| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment | +| uid | Reporting user | mediumint unsigned | YES | | NULL | | +| reporter-id | Reporting contact | int unsigned | YES | | NULL | | +| cid | Reported contact | int unsigned | NO | | NULL | | +| comment | Report | text | YES | | NULL | | +| category | Category of the report (spam, violation, other) | varchar(20) | YES | | NULL | | +| forward | Forward the report to the remote server | boolean | YES | | NULL | | +| created | | datetime | NO | | 0001-01-01 00:00:00 | | +| status | Status of the report | tinyint unsigned | YES | | NULL | | Indexes ------------ diff --git a/src/Moderation/Entity/Report.php b/src/Moderation/Entity/Report.php index 957cef8652..4689a11b33 100644 --- a/src/Moderation/Entity/Report.php +++ b/src/Moderation/Entity/Report.php @@ -42,6 +42,8 @@ class Report extends \Friendica\BaseEntity protected $cid; /** @var string Optional comment */ protected $comment; + /** @var string Optional category */ + protected $category; /** @var bool Whether this report should be forwarded to the remote server */ protected $forward; /** @var \DateTime|null When the report was created */ @@ -49,13 +51,14 @@ class Report extends \Friendica\BaseEntity /** @var array Optional list of URI IDs of posts supporting the report*/ protected $postUriIds; - public function __construct(int $uid = null, int $reporterId, int $cid, \DateTime $created, string $comment = '', bool $forward = false, array $postUriIds = [], int $id = null) + public function __construct(int $uid = null, int $reporterId, int $cid, \DateTime $created, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = [], int $id = null) { $this->uid = $uid; $this->reporterId = $reporterId; $this->cid = $cid; $this->created = $created; $this->comment = $comment; + $this->category = $category; $this->forward = $forward; $this->postUriIds = $postUriIds; $this->id = $id; diff --git a/src/Moderation/Factory/Report.php b/src/Moderation/Factory/Report.php index 918c10bc84..fbe0aa58b6 100644 --- a/src/Moderation/Factory/Report.php +++ b/src/Moderation/Factory/Report.php @@ -40,6 +40,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow $row['cid'], new \DateTime($row['created'] ?? 'now', new \DateTimeZone('UTC')), $row['comment'], + $row['category'], $row['forward'], $postUriIds, $row['id'], @@ -60,7 +61,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow * @return Entity\Report * @throws \Exception */ - public function createFromReportsRequest(int $uid = null, int $reporterId, int $cid, string $comment = '', bool $forward = false, array $postUriIds = []): Entity\Report + public function createFromReportsRequest(int $uid = null, int $reporterId, int $cid, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = []): Entity\Report { return new Entity\Report( $uid, @@ -68,6 +69,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow $cid, new \DateTime('now', new \DateTimeZone('UTC')), $comment, + $category, $forward, $postUriIds, ); diff --git a/src/Moderation/Repository/Report.php b/src/Moderation/Repository/Report.php index 1882d85710..78d8893788 100644 --- a/src/Moderation/Repository/Report.php +++ b/src/Moderation/Repository/Report.php @@ -57,6 +57,7 @@ class Report extends \Friendica\BaseRepository 'reporter-id' => $Report->reporterId, 'cid' => $Report->cid, 'comment' => $Report->comment, + 'category' => $Report->category, 'forward' => $Report->forward, ]; diff --git a/src/Module/Api/Mastodon/Reports.php b/src/Module/Api/Mastodon/Reports.php index c8dc0044c3..13d41eb233 100644 --- a/src/Module/Api/Mastodon/Reports.php +++ b/src/Module/Api/Mastodon/Reports.php @@ -54,10 +54,11 @@ class Reports extends BaseApi self::checkAllowedScope(self::SCOPE_WRITE); $request = $this->getRequest([ - 'account_id' => '', // ID of the account to report - 'status_ids' => [], // Array of Statuses to attach to the report, for context - 'comment' => '', // Reason for the report (default max 1000 characters) - 'forward' => false, // If the account is remote, should the report be forwarded to the remote admin? + 'account_id' => '', // ID of the account to report + 'status_ids' => [], // Array of Statuses to attach to the report, for context + 'comment' => '', // Reason for the report (default max 1000 characters) + 'category' => 'other', // Specify if the report is due to spam, violation of enumerated instance rules, or some other reason. + 'forward' => false, // If the account is remote, should the report be forwarded to the remote admin? ], $request); $contact = Contact::getById($request['account_id'], ['id']); @@ -65,7 +66,7 @@ class Reports extends BaseApi throw new HTTPException\NotFoundException('Account ' . $request['account_id'] . ' not found'); } - $report = $this->reportFactory->createFromReportsRequest(self::getCurrentUserID(), Contact::getPublicIdByUserId(self::getCurrentUserID()), $request['account_id'], $request['comment'], $request['forward'], $request['status_ids']); + $report = $this->reportFactory->createFromReportsRequest(self::getCurrentUserID(), Contact::getPublicIdByUserId(self::getCurrentUserID()), $request['account_id'], $request['comment'], $request['category'], $request['forward'], $request['status_ids']); $this->reportRepo->save($report); diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 25c09c9cb5..35bbc56233 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -1855,7 +1855,7 @@ class Processor } } - $report = DI::reportFactory()->createFromReportsRequest(null, $reporter_id, $account_id, $activity['content'], false, $uri_ids); + $report = DI::reportFactory()->createFromReportsRequest(null, $reporter_id, $account_id, $activity['content'], null, false, $uri_ids); DI::report()->save($report); Logger::info('Stored report', ['reporter' => $reporter_id, 'account_id' => $account_id, 'comment' => $activity['content'], 'status_ids' => $status_ids]); diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 59046a6cc4..8971118147 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -1676,6 +1676,7 @@ return [ "reporter-id" => ["type" => "int unsigned", "foreign" => ["contact" => "id"], "comment" => "Reporting contact"], "cid" => ["type" => "int unsigned", "not null" => "1", "foreign" => ["contact" => "id"], "comment" => "Reported contact"], "comment" => ["type" => "text", "comment" => "Report"], + "category" => ["type" => "varchar(20)", "comment" => "Category of the report (spam, violation, other)"], "forward" => ["type" => "boolean", "comment" => "Forward the report to the remote server"], "created" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""], "status" => ["type" => "tinyint unsigned", "comment" => "Status of the report"], diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php index fa9461529d..ea4133fea4 100644 --- a/tests/src/Moderation/Factory/ReportTest.php +++ b/tests/src/Moderation/Factory/ReportTest.php @@ -48,6 +48,7 @@ class ReportTest extends MockedTest 13, new \DateTime('now', new \DateTimeZone('UTC')), '', + null, false, [], 11, @@ -70,6 +71,7 @@ class ReportTest extends MockedTest 13, new \DateTime('2021-10-12 12:23:00', new \DateTimeZone('UTC')), 'Report', + 'violation', true, [89, 90], 11 @@ -88,6 +90,7 @@ class ReportTest extends MockedTest self::assertEquals($assertion->reporterId, $report->reporterId); self::assertEquals($assertion->cid, $report->cid); self::assertEquals($assertion->comment, $report->comment); + self::assertEquals($assertion->category, $report->category); self::assertEquals($assertion->forward, $report->forward); // No way to test "now" at the moment //self::assertEquals($assertion->created, $report->created); @@ -120,6 +123,7 @@ class ReportTest extends MockedTest 13, new \DateTime('now', new \DateTimeZone('UTC')), '', + null, false, [], null @@ -138,6 +142,7 @@ class ReportTest extends MockedTest 13, new \DateTime('now', new \DateTimeZone('UTC')), 'Report', + 'violation', true, [89, 90], null @@ -149,10 +154,10 @@ class ReportTest extends MockedTest /** * @dataProvider dataCreateFromReportsRequest */ - public function testCreateFromReportsRequest(int $uid, int $reporter, int $cid, string $comment, bool $forward, array $postUriIds, Entity\Report $assertion) + public function testCreateFromReportsRequest(int $uid, int $reporter, int $cid, string $comment, string $category = null, bool $forward, array $postUriIds, Entity\Report $assertion) { $factory = new Factory\Report(new NullLogger()); - $this->assertReport($factory->createFromReportsRequest($uid, $reporter, $cid, $comment, $forward, $postUriIds), $assertion); + $this->assertReport($factory->createFromReportsRequest($uid, $reporter, $cid, $comment, $category, $forward, $postUriIds), $assertion); } } From 59a848c8ec0d4ab94ef7f59d2d60fd9de0619c94 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 24 Dec 2022 23:26:54 +0000 Subject: [PATCH 0034/1145] Tests --- tests/src/Moderation/Factory/ReportTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php index ea4133fea4..5eb4cb323e 100644 --- a/tests/src/Moderation/Factory/ReportTest.php +++ b/tests/src/Moderation/Factory/ReportTest.php @@ -38,6 +38,7 @@ class ReportTest extends MockedTest 'reporter-id' => 14, 'cid' => 13, 'comment' => '', + 'category' => null, 'forward' => false, 'created' => null ], @@ -61,6 +62,7 @@ class ReportTest extends MockedTest 'reporter-id' => 14, 'cid' => 13, 'comment' => 'Report', + 'category' => 'violation', 'forward' => true, 'created' => '2021-10-12 12:23:00' ], @@ -115,6 +117,7 @@ class ReportTest extends MockedTest 'reporter-id' => 14, 'cid' => 13, 'comment' => '', + 'category' => null, 'forward' => false, 'postUriIds' => [], 'assertion' => new Entity\Report( @@ -134,6 +137,7 @@ class ReportTest extends MockedTest 'reporter-id' => 14, 'cid' => 13, 'comment' => 'Report', + 'category' => 'violation', 'forward' => true, 'postUriIds' => [89, 90], 'assertion' => new Entity\Report( From dc73cbe30c1b19cbc22e2c1279a3dd53bf947860 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 24 Dec 2022 23:33:21 +0000 Subject: [PATCH 0035/1145] Simplified code --- src/Protocol/ActivityPub/Processor.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 35bbc56233..0390913be0 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -1844,11 +1844,8 @@ class Processor return; } - $status_ids = $activity['object_ids']; - array_shift($status_ids); - $uri_ids = []; - foreach ($status_ids as $status_id) { + foreach ($activity['object_ids'] as $status_id) { $post = Post::selectFirst(['uri-id'], ['uri' => $status_id]); if (!empty($post['uri-id'])) { $uri_ids[] = $post['uri-id']; @@ -1858,7 +1855,7 @@ class Processor $report = DI::reportFactory()->createFromReportsRequest(null, $reporter_id, $account_id, $activity['content'], null, false, $uri_ids); DI::report()->save($report); - Logger::info('Stored report', ['reporter' => $reporter_id, 'account_id' => $account_id, 'comment' => $activity['content'], 'status_ids' => $status_ids]); + Logger::info('Stored report', ['reporter' => $reporter_id, 'account_id' => $account_id, 'comment' => $activity['content'], 'object_ids' => $activity['object_ids']]); } /** From cef434942177fdef2645c0a2e99a9ac44c3b7cc0 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 25 Dec 2022 07:30:39 +0000 Subject: [PATCH 0036/1145] Changed parameter order --- src/Moderation/Entity/Report.php | 14 ++++++++------ src/Moderation/Factory/Report.php | 6 +++--- src/Module/Api/Mastodon/Reports.php | 2 +- src/Protocol/ActivityPub/Processor.php | 2 +- tests/src/Moderation/Factory/ReportTest.php | 12 ++++++------ 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/Moderation/Entity/Report.php b/src/Moderation/Entity/Report.php index 4689a11b33..2bb4350d48 100644 --- a/src/Moderation/Entity/Report.php +++ b/src/Moderation/Entity/Report.php @@ -23,21 +23,21 @@ namespace Friendica\Moderation\Entity; /** * @property-read int $id - * @property-read int $uid + * @property-read int $reporterId * @property-read int $cid * @property-read string $comment + * @property-read string|null $category * @property-read bool $forward * @property-read array $postUriIds + * @property-read int $uid * @property-read \DateTime|null $created */ class Report extends \Friendica\BaseEntity { /** @var int|null */ protected $id; - /** @var int ID of the user making a moderation report*/ - protected $reporterId; /** @var int ID of the contact making a moderation report*/ - protected $uid; + protected $reporterId; /** @var int ID of the contact being reported*/ protected $cid; /** @var string Optional comment */ @@ -50,10 +50,11 @@ class Report extends \Friendica\BaseEntity protected $created; /** @var array Optional list of URI IDs of posts supporting the report*/ protected $postUriIds; + /** @var int ID of the user making a moderation report*/ + protected $uid; - public function __construct(int $uid = null, int $reporterId, int $cid, \DateTime $created, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = [], int $id = null) + public function __construct(int $reporterId, int $cid, \DateTime $created, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = [], int $uid = null, int $id = null) { - $this->uid = $uid; $this->reporterId = $reporterId; $this->cid = $cid; $this->created = $created; @@ -61,6 +62,7 @@ class Report extends \Friendica\BaseEntity $this->category = $category; $this->forward = $forward; $this->postUriIds = $postUriIds; + $this->uid = $uid; $this->id = $id; } } diff --git a/src/Moderation/Factory/Report.php b/src/Moderation/Factory/Report.php index fbe0aa58b6..bbcbe8eb12 100644 --- a/src/Moderation/Factory/Report.php +++ b/src/Moderation/Factory/Report.php @@ -35,7 +35,6 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow public function createFromTableRow(array $row, array $postUriIds = []): Entity\Report { return new Entity\Report( - $row['uid'], $row['reporter-id'], $row['cid'], new \DateTime($row['created'] ?? 'now', new \DateTimeZone('UTC')), @@ -43,6 +42,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow $row['category'], $row['forward'], $postUriIds, + $row['uid'], $row['id'], ); } @@ -61,10 +61,9 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow * @return Entity\Report * @throws \Exception */ - public function createFromReportsRequest(int $uid = null, int $reporterId, int $cid, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = []): Entity\Report + public function createFromReportsRequest(int $reporterId, int $cid, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = [], int $uid = null): Entity\Report { return new Entity\Report( - $uid, $reporterId, $cid, new \DateTime('now', new \DateTimeZone('UTC')), @@ -72,6 +71,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow $category, $forward, $postUriIds, + $uid, ); } } diff --git a/src/Module/Api/Mastodon/Reports.php b/src/Module/Api/Mastodon/Reports.php index 13d41eb233..7d98a5e664 100644 --- a/src/Module/Api/Mastodon/Reports.php +++ b/src/Module/Api/Mastodon/Reports.php @@ -66,7 +66,7 @@ class Reports extends BaseApi throw new HTTPException\NotFoundException('Account ' . $request['account_id'] . ' not found'); } - $report = $this->reportFactory->createFromReportsRequest(self::getCurrentUserID(), Contact::getPublicIdByUserId(self::getCurrentUserID()), $request['account_id'], $request['comment'], $request['category'], $request['forward'], $request['status_ids']); + $report = $this->reportFactory->createFromReportsRequest(Contact::getPublicIdByUserId(self::getCurrentUserID()), $request['account_id'], $request['comment'], $request['category'], $request['forward'], $request['status_ids'], self::getCurrentUserID()); $this->reportRepo->save($report); diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 0390913be0..400a52b327 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -1852,7 +1852,7 @@ class Processor } } - $report = DI::reportFactory()->createFromReportsRequest(null, $reporter_id, $account_id, $activity['content'], null, false, $uri_ids); + $report = DI::reportFactory()->createFromReportsRequest($reporter_id, $account_id, $activity['content'], null, false, $uri_ids); DI::report()->save($report); Logger::info('Stored report', ['reporter' => $reporter_id, 'account_id' => $account_id, 'comment' => $activity['content'], 'object_ids' => $activity['object_ids']]); diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php index 5eb4cb323e..f21dd2ec4e 100644 --- a/tests/src/Moderation/Factory/ReportTest.php +++ b/tests/src/Moderation/Factory/ReportTest.php @@ -44,7 +44,6 @@ class ReportTest extends MockedTest ], 'postUriIds' => [], 'assertion' => new Entity\Report( - 12, 14, 13, new \DateTime('now', new \DateTimeZone('UTC')), @@ -52,6 +51,7 @@ class ReportTest extends MockedTest null, false, [], + 12, 11, ), ], @@ -68,7 +68,6 @@ class ReportTest extends MockedTest ], 'postUriIds' => [89, 90], 'assertion' => new Entity\Report( - 12, 14, 13, new \DateTime('2021-10-12 12:23:00', new \DateTimeZone('UTC')), @@ -76,6 +75,7 @@ class ReportTest extends MockedTest 'violation', true, [89, 90], + 12, 11 ), ], @@ -121,7 +121,6 @@ class ReportTest extends MockedTest 'forward' => false, 'postUriIds' => [], 'assertion' => new Entity\Report( - 12, 14, 13, new \DateTime('now', new \DateTimeZone('UTC')), @@ -129,6 +128,7 @@ class ReportTest extends MockedTest null, false, [], + 12, null ), ], @@ -141,7 +141,6 @@ class ReportTest extends MockedTest 'forward' => true, 'postUriIds' => [89, 90], 'assertion' => new Entity\Report( - 12, 14, 13, new \DateTime('now', new \DateTimeZone('UTC')), @@ -149,6 +148,7 @@ class ReportTest extends MockedTest 'violation', true, [89, 90], + 12, null ), ], @@ -158,10 +158,10 @@ class ReportTest extends MockedTest /** * @dataProvider dataCreateFromReportsRequest */ - public function testCreateFromReportsRequest(int $uid, int $reporter, int $cid, string $comment, string $category = null, bool $forward, array $postUriIds, Entity\Report $assertion) + public function testCreateFromReportsRequest(int $reporter, int $cid, string $comment, string $category = null, bool $forward, array $postUriIds, int $uid, Entity\Report $assertion) { $factory = new Factory\Report(new NullLogger()); - $this->assertReport($factory->createFromReportsRequest($uid, $reporter, $cid, $comment, $category, $forward, $postUriIds), $assertion); + $this->assertReport($factory->createFromReportsRequest($reporter, $cid, $comment, $category, $forward, $postUriIds, $uid), $assertion); } } From fd53cf824fdc138880d7300587741c29b466331a Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 25 Dec 2022 07:40:19 +0000 Subject: [PATCH 0037/1145] Tests --- tests/src/Moderation/Factory/ReportTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php index f21dd2ec4e..be406f499e 100644 --- a/tests/src/Moderation/Factory/ReportTest.php +++ b/tests/src/Moderation/Factory/ReportTest.php @@ -113,13 +113,13 @@ class ReportTest extends MockedTest { return [ 'default' => [ - 'uid' => 12, 'reporter-id' => 14, 'cid' => 13, 'comment' => '', 'category' => null, 'forward' => false, 'postUriIds' => [], + 'uid' => 12, 'assertion' => new Entity\Report( 14, 13, @@ -133,13 +133,13 @@ class ReportTest extends MockedTest ), ], 'full' => [ - 'uid' => 12, 'reporter-id' => 14, 'cid' => 13, 'comment' => 'Report', 'category' => 'violation', 'forward' => true, 'postUriIds' => [89, 90], + 'uid' => 12, 'assertion' => new Entity\Report( 14, 13, From 5298cd73b3a798fcf2cc0a1a41139839d3dbe63d Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 25 Dec 2022 10:44:06 +0000 Subject: [PATCH 0038/1145] We now store the violation as well --- database.sql | 1 + doc/database/db_report.md | 1 + src/Core/System.php | 9 +++++++-- src/Moderation/Entity/Report.php | 5 ++++- src/Moderation/Factory/Report.php | 4 +++- src/Moderation/Repository/Report.php | 1 + src/Module/Api/Mastodon/Reports.php | 12 +++++++++++- src/Protocol/ActivityPub/Processor.php | 2 +- static/dbstructure.config.php | 1 + tests/src/Moderation/Factory/ReportTest.php | 10 ++++++++-- 10 files changed, 38 insertions(+), 8 deletions(-) diff --git a/database.sql b/database.sql index 8c24dd4eb6..7eb756cf2a 100644 --- a/database.sql +++ b/database.sql @@ -1678,6 +1678,7 @@ CREATE TABLE IF NOT EXISTS `report` ( `cid` int unsigned NOT NULL COMMENT 'Reported contact', `comment` text COMMENT 'Report', `category` varchar(20) COMMENT 'Category of the report (spam, violation, other)', + `rules` text COMMENT 'Violated rules', `forward` boolean COMMENT 'Forward the report to the remote server', `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '', `status` tinyint unsigned COMMENT 'Status of the report', diff --git a/doc/database/db_report.md b/doc/database/db_report.md index 56f51bdd41..92c0cced36 100644 --- a/doc/database/db_report.md +++ b/doc/database/db_report.md @@ -14,6 +14,7 @@ Fields | cid | Reported contact | int unsigned | NO | | NULL | | | comment | Report | text | YES | | NULL | | | category | Category of the report (spam, violation, other) | varchar(20) | YES | | NULL | | +| rules | Violated rules | text | YES | | NULL | | | forward | Forward the report to the remote server | boolean | YES | | NULL | | | created | | datetime | NO | | 0001-01-01 00:00:00 | | | status | Status of the report | tinyint unsigned | YES | | NULL | | diff --git a/src/Core/System.php b/src/Core/System.php index ec214fea9d..65dce1bc0e 100644 --- a/src/Core/System.php +++ b/src/Core/System.php @@ -665,10 +665,11 @@ class System /** * Fetch the system rules + * @param bool $numeric_id If set to "true", the rules are returned with a numeric id as key. * * @return array */ - public static function getRules(): array + public static function getRules(bool $numeric_id = false): array { $rules = []; $id = 0; @@ -681,7 +682,11 @@ class System foreach (explode("\n", trim($msg)) as $line) { $line = trim($line); if ($line) { - $rules[] = ['id' => (string)++$id, 'text' => $line]; + if ($numeric_id) { + $rules[++$id] = $line; + } else { + $rules[] = ['id' => (string)++$id, 'text' => $line]; + } } } } diff --git a/src/Moderation/Entity/Report.php b/src/Moderation/Entity/Report.php index 2bb4350d48..3fbd772568 100644 --- a/src/Moderation/Entity/Report.php +++ b/src/Moderation/Entity/Report.php @@ -44,6 +44,8 @@ class Report extends \Friendica\BaseEntity protected $comment; /** @var string Optional category */ protected $category; + /** @var string Violated rules */ + protected $rules; /** @var bool Whether this report should be forwarded to the remote server */ protected $forward; /** @var \DateTime|null When the report was created */ @@ -53,13 +55,14 @@ class Report extends \Friendica\BaseEntity /** @var int ID of the user making a moderation report*/ protected $uid; - public function __construct(int $reporterId, int $cid, \DateTime $created, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = [], int $uid = null, int $id = null) + public function __construct(int $reporterId, int $cid, \DateTime $created, string $comment = '', string $category = null, string $rules = '', bool $forward = false, array $postUriIds = [], int $uid = null, int $id = null) { $this->reporterId = $reporterId; $this->cid = $cid; $this->created = $created; $this->comment = $comment; $this->category = $category; + $this->rules = $rules; $this->forward = $forward; $this->postUriIds = $postUriIds; $this->uid = $uid; diff --git a/src/Moderation/Factory/Report.php b/src/Moderation/Factory/Report.php index bbcbe8eb12..8e66d8ad59 100644 --- a/src/Moderation/Factory/Report.php +++ b/src/Moderation/Factory/Report.php @@ -40,6 +40,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow new \DateTime($row['created'] ?? 'now', new \DateTimeZone('UTC')), $row['comment'], $row['category'], + $row['rules'], $row['forward'], $postUriIds, $row['uid'], @@ -61,7 +62,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow * @return Entity\Report * @throws \Exception */ - public function createFromReportsRequest(int $reporterId, int $cid, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = [], int $uid = null): Entity\Report + public function createFromReportsRequest(int $reporterId, int $cid, string $comment = '', string $category = null, string $rules = '', bool $forward = false, array $postUriIds = [], int $uid = null): Entity\Report { return new Entity\Report( $reporterId, @@ -69,6 +70,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow new \DateTime('now', new \DateTimeZone('UTC')), $comment, $category, + $rules, $forward, $postUriIds, $uid, diff --git a/src/Moderation/Repository/Report.php b/src/Moderation/Repository/Report.php index 78d8893788..5322a4ffba 100644 --- a/src/Moderation/Repository/Report.php +++ b/src/Moderation/Repository/Report.php @@ -58,6 +58,7 @@ class Report extends \Friendica\BaseRepository 'cid' => $Report->cid, 'comment' => $Report->comment, 'category' => $Report->category, + 'rules' => $Report->rules, 'forward' => $Report->forward, ]; diff --git a/src/Module/Api/Mastodon/Reports.php b/src/Module/Api/Mastodon/Reports.php index 7d98a5e664..98213f9be8 100644 --- a/src/Module/Api/Mastodon/Reports.php +++ b/src/Module/Api/Mastodon/Reports.php @@ -58,6 +58,7 @@ class Reports extends BaseApi 'status_ids' => [], // Array of Statuses to attach to the report, for context 'comment' => '', // Reason for the report (default max 1000 characters) 'category' => 'other', // Specify if the report is due to spam, violation of enumerated instance rules, or some other reason. + 'rule_ids' => [], // For violation category reports, specify the ID of the exact rules broken. 'forward' => false, // If the account is remote, should the report be forwarded to the remote admin? ], $request); @@ -66,7 +67,16 @@ class Reports extends BaseApi throw new HTTPException\NotFoundException('Account ' . $request['account_id'] . ' not found'); } - $report = $this->reportFactory->createFromReportsRequest(Contact::getPublicIdByUserId(self::getCurrentUserID()), $request['account_id'], $request['comment'], $request['category'], $request['forward'], $request['status_ids'], self::getCurrentUserID()); + $violation = ''; + $rules = System::getRules(true); + + foreach ($request['rule_ids'] as $key) { + if (!empty($rules[$key])) { + $violation .= $rules[$key] . "\n"; + } + } + + $report = $this->reportFactory->createFromReportsRequest(Contact::getPublicIdByUserId(self::getCurrentUserID()), $request['account_id'], $request['comment'], $request['category'], trim($violation), $request['forward'], $request['status_ids'], self::getCurrentUserID()); $this->reportRepo->save($report); diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 400a52b327..e98fa4596c 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -1852,7 +1852,7 @@ class Processor } } - $report = DI::reportFactory()->createFromReportsRequest($reporter_id, $account_id, $activity['content'], null, false, $uri_ids); + $report = DI::reportFactory()->createFromReportsRequest($reporter_id, $account_id, $activity['content'], null, '', false, $uri_ids); DI::report()->save($report); Logger::info('Stored report', ['reporter' => $reporter_id, 'account_id' => $account_id, 'comment' => $activity['content'], 'object_ids' => $activity['object_ids']]); diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 8971118147..1d573fa87e 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -1677,6 +1677,7 @@ return [ "cid" => ["type" => "int unsigned", "not null" => "1", "foreign" => ["contact" => "id"], "comment" => "Reported contact"], "comment" => ["type" => "text", "comment" => "Report"], "category" => ["type" => "varchar(20)", "comment" => "Category of the report (spam, violation, other)"], + "rules" => ["type" => "text", "comment" => "Violated rules"], "forward" => ["type" => "boolean", "comment" => "Forward the report to the remote server"], "created" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""], "status" => ["type" => "tinyint unsigned", "comment" => "Status of the report"], diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php index be406f499e..8d1e8131ee 100644 --- a/tests/src/Moderation/Factory/ReportTest.php +++ b/tests/src/Moderation/Factory/ReportTest.php @@ -49,6 +49,7 @@ class ReportTest extends MockedTest new \DateTime('now', new \DateTimeZone('UTC')), '', null, + '', false, [], 12, @@ -63,6 +64,7 @@ class ReportTest extends MockedTest 'cid' => 13, 'comment' => 'Report', 'category' => 'violation', + 'rules' => 'Rules', 'forward' => true, 'created' => '2021-10-12 12:23:00' ], @@ -73,6 +75,7 @@ class ReportTest extends MockedTest new \DateTime('2021-10-12 12:23:00', new \DateTimeZone('UTC')), 'Report', 'violation', + 'Rules', true, [89, 90], 12, @@ -117,6 +120,7 @@ class ReportTest extends MockedTest 'cid' => 13, 'comment' => '', 'category' => null, + 'rules' => null, 'forward' => false, 'postUriIds' => [], 'uid' => 12, @@ -126,6 +130,7 @@ class ReportTest extends MockedTest new \DateTime('now', new \DateTimeZone('UTC')), '', null, + '', false, [], 12, @@ -146,6 +151,7 @@ class ReportTest extends MockedTest new \DateTime('now', new \DateTimeZone('UTC')), 'Report', 'violation', + 'Rules', true, [89, 90], 12, @@ -158,10 +164,10 @@ class ReportTest extends MockedTest /** * @dataProvider dataCreateFromReportsRequest */ - public function testCreateFromReportsRequest(int $reporter, int $cid, string $comment, string $category = null, bool $forward, array $postUriIds, int $uid, Entity\Report $assertion) + public function testCreateFromReportsRequest(int $reporter, int $cid, string $comment, string $category = null, string $rules = null, bool $forward, array $postUriIds, int $uid, Entity\Report $assertion) { $factory = new Factory\Report(new NullLogger()); - $this->assertReport($factory->createFromReportsRequest($reporter, $cid, $comment, $category, $forward, $postUriIds, $uid), $assertion); + $this->assertReport($factory->createFromReportsRequest($reporter, $cid, $comment, $category, $rules, $forward, $postUriIds, $uid), $assertion); } } From c0c70427f35f877c092aa3e41430b5381eae3282 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 25 Dec 2022 10:52:47 +0000 Subject: [PATCH 0039/1145] Tests --- tests/src/Moderation/Factory/ReportTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php index 8d1e8131ee..7ce6ab0f09 100644 --- a/tests/src/Moderation/Factory/ReportTest.php +++ b/tests/src/Moderation/Factory/ReportTest.php @@ -39,6 +39,7 @@ class ReportTest extends MockedTest 'cid' => 13, 'comment' => '', 'category' => null, + 'rules' => '', 'forward' => false, 'created' => null ], @@ -96,6 +97,7 @@ class ReportTest extends MockedTest self::assertEquals($assertion->cid, $report->cid); self::assertEquals($assertion->comment, $report->comment); self::assertEquals($assertion->category, $report->category); + self::assertEquals($assertion->rules, $report->rules); self::assertEquals($assertion->forward, $report->forward); // No way to test "now" at the moment //self::assertEquals($assertion->created, $report->created); @@ -142,6 +144,7 @@ class ReportTest extends MockedTest 'cid' => 13, 'comment' => 'Report', 'category' => 'violation', + 'rules' => 'Rules', 'forward' => true, 'postUriIds' => [89, 90], 'uid' => 12, @@ -164,7 +167,7 @@ class ReportTest extends MockedTest /** * @dataProvider dataCreateFromReportsRequest */ - public function testCreateFromReportsRequest(int $reporter, int $cid, string $comment, string $category = null, string $rules = null, bool $forward, array $postUriIds, int $uid, Entity\Report $assertion) + public function testCreateFromReportsRequest(int $reporter, int $cid, string $comment, string $category = null, string $rules = '', bool $forward, array $postUriIds, int $uid, Entity\Report $assertion) { $factory = new Factory\Report(new NullLogger()); From 80247bd1ca407003510ca05e80a472ae47bceb35 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 25 Dec 2022 10:57:27 +0000 Subject: [PATCH 0040/1145] Fix tests --- tests/src/Moderation/Factory/ReportTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php index 7ce6ab0f09..286b529925 100644 --- a/tests/src/Moderation/Factory/ReportTest.php +++ b/tests/src/Moderation/Factory/ReportTest.php @@ -122,7 +122,7 @@ class ReportTest extends MockedTest 'cid' => 13, 'comment' => '', 'category' => null, - 'rules' => null, + 'rules' => '', 'forward' => false, 'postUriIds' => [], 'uid' => 12, From 46fdf696ee47f3b71e8c7a77690998b5c9700c76 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 25 Dec 2022 22:45:34 +0000 Subject: [PATCH 0041/1145] Issue 12524: Fix first day of week --- src/Module/Settings/Display.php | 2 +- src/Util/Temporal.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Module/Settings/Display.php b/src/Module/Settings/Display.php index 0766d2a13e..87134103fe 100644 --- a/src/Module/Settings/Display.php +++ b/src/Module/Settings/Display.php @@ -219,7 +219,7 @@ class Display extends BaseSettings ]; - $first_day_of_week = $this->pConfig->get($uid, 'system', 'first_day_of_week', 0); + $first_day_of_week = $this->pConfig->get($uid, 'calendar', 'first_day_of_week', 0); $weekdays = [ 0 => $this->t('Sunday'), 1 => $this->t('Monday'), diff --git a/src/Util/Temporal.php b/src/Util/Temporal.php index f6805a9222..24d7d7e23d 100644 --- a/src/Util/Temporal.php +++ b/src/Util/Temporal.php @@ -238,7 +238,7 @@ class Temporal bool $required = false): string { // First day of the week (0 = Sunday) - $firstDay = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'system', 'first_day_of_week', 0); + $firstDay = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'calendar', 'first_day_of_week', 0); $lang = substr(DI::l10n()->getCurrentLang(), 0, 2); From e05cbf46e163b5ff039cfacec3121f1d46a101ec Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 26 Dec 2022 08:41:40 +0000 Subject: [PATCH 0042/1145] Activity "Read" is now stored --- src/Content/Conversation.php | 2 +- src/Protocol/Activity.php | 8 ++++++++ src/Protocol/ActivityPub/Receiver.php | 15 ++++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/Content/Conversation.php b/src/Content/Conversation.php index d9036c7839..eb9af133c1 100644 --- a/src/Content/Conversation.php +++ b/src/Content/Conversation.php @@ -970,7 +970,7 @@ class Conversation } $condition = DBA::mergeConditions($condition, - ["`uid` IN (0, ?) AND (NOT `vid` IN (?, ?) OR `vid` IS NULL)", $uid, Verb::getID(Activity::FOLLOW), Verb::getID(Activity::VIEW)]); + ["`uid` IN (0, ?) AND (NOT `vid` IN (?, ?, ?) OR `vid` IS NULL)", $uid, Verb::getID(Activity::FOLLOW), Verb::getID(Activity::VIEW), Verb::getID(Activity::READ)]); $thread_parents = Post::select(['uri-id', 'causer-id'], $condition, ['order' => ['uri-id' => false, 'uid']]); diff --git a/src/Protocol/Activity.php b/src/Protocol/Activity.php index ea1feeefee..7212e91941 100644 --- a/src/Protocol/Activity.php +++ b/src/Protocol/Activity.php @@ -163,6 +163,13 @@ final class Activity * @var string */ const ANNOUNCE = ActivityNamespace::ACTIVITY2 . 'Announce'; + /** + * Indicates that the actor has read the object. + * + * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-read + * @var string + */ + const READ = ActivityNamespace::ACTIVITY2 . 'read'; const O_UNFOLLOW = ActivityNamespace::OSTATUS . '/unfollow'; const O_UNFAVOURITE = ActivityNamespace::OSTATUS . '/unfavorite'; @@ -194,6 +201,7 @@ final class Activity self::ANNOUNCE, self::EMOJIREACT, self::VIEW, + self::READ, ]; /** diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index 85965d7129..41a3ca0ad7 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -63,7 +63,7 @@ class Receiver const PUBLIC_COLLECTION = 'as:Public'; const ACCOUNT_TYPES = ['as:Person', 'as:Organization', 'as:Service', 'as:Group', 'as:Application']; const CONTENT_TYPES = ['as:Note', 'as:Article', 'as:Video', 'as:Image', 'as:Event', 'as:Audio', 'as:Page', 'as:Question']; - const ACTIVITY_TYPES = ['as:Like', 'as:Dislike', 'as:Accept', 'as:Reject', 'as:TentativeAccept']; + const ACTIVITY_TYPES = ['as:Like', 'as:Dislike', 'as:Accept', 'as:Reject', 'as:TentativeAccept', 'as:Read']; const TARGET_UNKNOWN = 0; const TARGET_TO = 1; @@ -934,6 +934,9 @@ class Receiver } elseif (in_array($object_data['object_type'], ['as:Delete'])) { // We cannot undo deletions, so we just ignore this Queue::remove($object_data); + } elseif (in_array($object_data['object_object_type'], ['as:Tombstone'])) { + // The object is a tombstone, we ignore any actions on it. + Queue::remove($object_data); } else { return false; } @@ -949,6 +952,16 @@ class Receiver return false; } break; + case 'as:Read': + if (in_array($object_data['object_type'], self::CONTENT_TYPES)) { + ActivityPub\Processor::createActivity($object_data, Activity::READ); + } elseif ($object_data['object_type'] == '') { + // The object type couldn't be determined. Most likely we don't have it here. We ignore this activity. + Queue::remove($object_data); + } else { + return false; + } + break; case 'litepub:EmojiReact': if (in_array($object_data['object_type'], self::CONTENT_TYPES)) { From e718d39ef00382fecb59ed8971adb536c8c75d5a Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 26 Dec 2022 12:14:45 +0000 Subject: [PATCH 0043/1145] Fixes "E_WARNING: Undefined variable $subject" --- src/Navigation/Notifications/Repository/Notify.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Navigation/Notifications/Repository/Notify.php b/src/Navigation/Notifications/Repository/Notify.php index 278451936d..60e801d039 100644 --- a/src/Navigation/Notifications/Repository/Notify.php +++ b/src/Navigation/Notifications/Repository/Notify.php @@ -783,6 +783,8 @@ class Notify extends BaseRepository $subject = $l10n->t('%s %s shared a new post', $subjectPrefix, $contact['name']); } else { $params['type'] = Model\Notification\Type::COMMENT; + $subject = $l10n->t('%1$s Comment to conversation #%2$d by %3$s', $subjectPrefix, $item['parent'], $contact['name']); + if ($params['verb'] = Activity::LIKE) { switch ($Notification->type) { case Model\Post\UserNotification::TYPE_DIRECT_COMMENT: @@ -792,8 +794,6 @@ class Notify extends BaseRepository $subject = $l10n->t('%1$s %2$s liked your comment on #%3$d', $subjectPrefix, $contact['name'], $item['parent']); break; } - } else { - $subject = $l10n->t('%1$s Comment to conversation #%2$d by %3$s', $subjectPrefix, $item['parent'], $contact['name']); } } From e8420dcb7155af7fb8bd29fb63c79367125dd551 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 26 Dec 2022 09:10:55 -0500 Subject: [PATCH 0044/1145] Query expected photo.type field in Protocol\DFRN::relocate - Address first part of https://github.com/friendica/friendica/issues/12488#issuecomment-1364487793 --- src/Protocol/DFRN.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index e29cfcc5ab..52ae12f9c3 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -301,16 +301,15 @@ class DFRN DI::config()->set('system', 'site_pubkey', $res['pubkey']); } - $profilephotos = Photo::selectToArray(['resource-id' , 'scale'], ['profile' => true, 'uid' => $uid], ['order' => ['scale']]); + $profilephotos = Photo::selectToArray(['resource-id', 'scale', 'type'], ['profile' => true, 'uid' => $uid], ['order' => ['scale']]); $photos = []; $ext = Images::supportedTypes(); foreach ($profilephotos as $p) { - $photos[$p['scale']] = DI::baseUrl().'/photo/'.$p['resource-id'].'-'.$p['scale'].'.'.$ext[$p['type']]; + $photos[$p['scale']] = DI::baseUrl() . '/photo/' . $p['resource-id'] . '-' . $p['scale'] . '.' . $ext[$p['type']]; } - $doc = new DOMDocument('1.0', 'utf-8'); $doc->formatOutput = true; From 482eeb71090720bc0af6ca7fbd7c8ba8ec7c3669 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 26 Dec 2022 09:11:37 -0500 Subject: [PATCH 0045/1145] Fix wrong square bracket position in Worker\Delivery->deliverDFRN - Address second part of https://github.com/friendica/friendica/issues/12488#issuecomment-1364487793 --- src/Worker/Delivery.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Worker/Delivery.php b/src/Worker/Delivery.php index 1a0758987a..195f9fdcab 100644 --- a/src/Worker/Delivery.php +++ b/src/Worker/Delivery.php @@ -213,7 +213,7 @@ class Delivery // Also transmit via Diaspora if this is a direct answer to a Diaspora comment. // This is done since the uri wouldn't match (Diaspora doesn't transmit it) // Also transmit relayed posts from Diaspora contacts via Diaspora. - if (($contact['network'] != Protocol::DIASPORA) && in_array(Protocol::DIASPORA, [$parent['network'] ?? '', $thr_parent['network'] ?? '', $target_item['network']] ?? '')) { + if (($contact['network'] != Protocol::DIASPORA) && in_array(Protocol::DIASPORA, [$parent['network'] ?? '', $thr_parent['network'] ?? '', $target_item['network'] ?? ''])) { Logger::info('Enforcing the Diaspora protocol', ['id' => $contact['id'], 'network' => $contact['network'], 'parent' => $parent['network'], 'thread-parent' => $thr_parent['network'], 'post' => $target_item['network']]); $contact['network'] = Protocol::DIASPORA; } From 74229fe230ec9fa9bfbec016faca4937708f4df8 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 26 Dec 2022 09:22:44 -0500 Subject: [PATCH 0046/1145] Ward against empty $target_item array (relocation) in Worker\Delivery->deliverDFRN - Address third part of https://github.com/friendica/friendica/issues/12488#issuecomment-1364487793 --- src/Worker/Delivery.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Worker/Delivery.php b/src/Worker/Delivery.php index 195f9fdcab..59b4ea6c30 100644 --- a/src/Worker/Delivery.php +++ b/src/Worker/Delivery.php @@ -276,14 +276,16 @@ class Delivery */ private static function deliverDFRN(string $cmd, array $contact, array $owner, array $items, array $target_item, bool $public_message, bool $top_level, bool $followup, int $server_protocol = null) { + $target_item_id = $target_item['guid'] ?? '' ?: $target_item['id'] ?? null; + // Transmit Diaspora reshares via Diaspora if the Friendica contact support Diaspora - if (Diaspora::getReshareDetails($target_item ?? []) && Diaspora::isSupportedByContactUrl($contact['addr'])) { - Logger::info('Reshare will be transmitted via Diaspora', ['url' => $contact['url'], 'guid' => ($target_item['guid'] ?? '') ?: $target_item['id']]); + if (Diaspora::getReshareDetails($target_item) && Diaspora::isSupportedByContactUrl($contact['addr'])) { + Logger::info('Reshare will be transmitted via Diaspora', ['url' => $contact['url'], 'guid' => $target_item_id]); self::deliverDiaspora($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup); return; } - Logger::info('Deliver ' . (($target_item['guid'] ?? '') ?: $target_item['id']) . ' via DFRN to ' . (($contact['addr'] ?? '') ?: $contact['url'])); + Logger::info('Deliver ' . ($target_item_id ?? 'relocation') . ' via DFRN to ' . ($contact['addr'] ?? '' ?: $contact['url'])); if ($cmd == self::MAIL) { $item = $target_item; @@ -315,7 +317,7 @@ class Delivery $atom = DFRN::entries($msgitems, $owner); } - Logger::debug('Notifier entry: ' . $contact['url'] . ' ' . (($target_item['guid'] ?? '') ?: $target_item['id']) . ' entry: ' . $atom); + Logger::debug('Notifier entry: ' . $contact['url'] . ' ' . ($target_item_id ?? 'relocation') . ' entry: ' . $atom); $protocol = Post\DeliveryData::DFRN; @@ -353,7 +355,7 @@ class Delivery $deliver_status = DFRN::transmit($owner, $contact, $atom); } - Logger::info('DFRN Delivery', ['cmd' => $cmd, 'url' => $contact['url'], 'guid' => ($target_item['guid'] ?? '') ?: $target_item['id'], 'return' => $deliver_status]); + Logger::info('DFRN Delivery', ['cmd' => $cmd, 'url' => $contact['url'], 'guid' => $target_item_id, 'return' => $deliver_status]); if (($deliver_status >= 200) && ($deliver_status <= 299)) { // We successfully delivered a message, the contact is alive @@ -368,7 +370,7 @@ class Delivery // The message could not be delivered. We mark the contact as "dead" Contact::markForArchival($contact); - Logger::info('Delivery failed: defer message', ['id' => ($target_item['guid'] ?? '') ?: $target_item['id']]); + Logger::info('Delivery failed: defer message', ['id' => $target_item_id]); if (!Worker::defer() && $cmd == Delivery::POST) { Post\DeliveryData::incrementQueueFailed($target_item['uri-id']); } From 1be9d6b2cba7f0e61e4701a70ade7dd4b8a40832 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 26 Dec 2022 09:26:57 -0500 Subject: [PATCH 0047/1145] Fix wrong variable reference in view wall_thread template - Address https://github.com/friendica/friendica/issues/12488#issuecomment-1364715116 --- view/theme/vier/templates/wall_thread.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/view/theme/vier/templates/wall_thread.tpl b/view/theme/vier/templates/wall_thread.tpl index 7d851d0015..a9ec4c90ad 100644 --- a/view/theme/vier/templates/wall_thread.tpl +++ b/view/theme/vier/templates/wall_thread.tpl @@ -128,7 +128,7 @@ {{/if}}{{if $item.vote.dislike}} {{$item.vote.dislike.0}} {{/if}}{{if $item.vote.announce}} - {{$item.vote.dislike.0}} + {{$item.vote.announce.0}} {{/if}} {{if $item.vote.share}} {{$item.vote.share.0}} From 7c4b320f30e28ac7915fcb4e4f5b57769bce7f6d Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 26 Dec 2022 15:08:46 +0000 Subject: [PATCH 0048/1145] Cleanup work with the activity types --- src/Protocol/ActivityPub/Receiver.php | 32 +++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index 41a3ca0ad7..fbe8c32dc7 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -63,7 +63,7 @@ class Receiver const PUBLIC_COLLECTION = 'as:Public'; const ACCOUNT_TYPES = ['as:Person', 'as:Organization', 'as:Service', 'as:Group', 'as:Application']; const CONTENT_TYPES = ['as:Note', 'as:Article', 'as:Video', 'as:Image', 'as:Event', 'as:Audio', 'as:Page', 'as:Question']; - const ACTIVITY_TYPES = ['as:Like', 'as:Dislike', 'as:Accept', 'as:Reject', 'as:TentativeAccept', 'as:Read']; + const ACTIVITY_TYPES = ['as:Like', 'as:Dislike', 'as:Accept', 'as:Reject', 'as:TentativeAccept', 'as:View', 'as:Read', 'litepub:EmojiReact']; const TARGET_UNKNOWN = 0; const TARGET_TO = 1; @@ -449,7 +449,7 @@ class Receiver } else { $object_data['directmessage'] = JsonLD::fetchElement($activity, 'litepub:directMessage'); } - } elseif (in_array($type, array_merge(self::ACTIVITY_TYPES, ['as:Follow', 'litepub:EmojiReact', 'as:View'])) && in_array($object_type, self::CONTENT_TYPES)) { + } elseif (in_array($type, array_merge(self::ACTIVITY_TYPES, ['as:Follow'])) && in_array($object_type, self::CONTENT_TYPES)) { // Create a mostly empty array out of the activity data (instead of the object). // This way we later don't have to check for the existence of each individual array element. $object_data = self::processObject($activity); @@ -726,8 +726,8 @@ class Receiver ActivityPub\Processor::addTag($object_data); } elseif (in_array($object_data['object_type'], self::CONTENT_TYPES)) { ActivityPub\Processor::addToFeaturedCollection($object_data); - } elseif ($object_data['object_type'] == '') { - // The object type couldn't be determined. We don't have it and we can't fetch it. We ignore this activity. + } elseif (in_array($object_data['object_type'], ['as:Tombstone', ''])) { + // We don't have the object here or it is deleted. We ignore this activity. Queue::remove($object_data); } else { return false; @@ -781,8 +781,8 @@ class Receiver case 'as:Like': if (in_array($object_data['object_type'], self::CONTENT_TYPES)) { ActivityPub\Processor::createActivity($object_data, Activity::LIKE); - } elseif (in_array($object_data['object_type'], ['', 'as:Tombstone'])) { - // The object type couldn't be determined. We don't have it and we can't fetch it. We ignore this activity. + } elseif (in_array($object_data['object_type'], ['as:Tombstone', ''])) { + // We don't have the object here or it is deleted. We ignore this activity. Queue::remove($object_data); } else { return false; @@ -792,8 +792,8 @@ class Receiver case 'as:Dislike': if (in_array($object_data['object_type'], self::CONTENT_TYPES)) { ActivityPub\Processor::createActivity($object_data, Activity::DISLIKE); - } elseif (in_array($object_data['object_type'], ['', 'as:Tombstone'])) { - // The object type couldn't be determined. We don't have it and we can't fetch it. We ignore this activity. + } elseif (in_array($object_data['object_type'], ['as:Tombstone', ''])) { + // We don't have the object here or it is deleted. We ignore this activity. Queue::remove($object_data); } else { return false; @@ -861,8 +861,8 @@ class Receiver case 'as:Remove': if (in_array($object_data['object_type'], self::CONTENT_TYPES)) { ActivityPub\Processor::removeFromFeaturedCollection($object_data); - } elseif ($object_data['object_type'] == '') { - // The object type couldn't be determined. We don't have it and we can't fetch it. We ignore this activity. + } elseif (in_array($object_data['object_type'], ['as:Tombstone', ''])) { + // We don't have the object here or it is deleted. We ignore this activity. Queue::remove($object_data); } else { return false; @@ -945,8 +945,8 @@ class Receiver case 'as:View': if (in_array($object_data['object_type'], self::CONTENT_TYPES)) { ActivityPub\Processor::createActivity($object_data, Activity::VIEW); - } elseif ($object_data['object_type'] == '') { - // The object type couldn't be determined. Most likely we don't have it here. We ignore this activity. + } elseif (in_array($object_data['object_type'], ['as:Tombstone', ''])) { + // We don't have the object here or it is deleted. We ignore this activity. Queue::remove($object_data); } else { return false; @@ -955,8 +955,8 @@ class Receiver case 'as:Read': if (in_array($object_data['object_type'], self::CONTENT_TYPES)) { ActivityPub\Processor::createActivity($object_data, Activity::READ); - } elseif ($object_data['object_type'] == '') { - // The object type couldn't be determined. Most likely we don't have it here. We ignore this activity. + } elseif (in_array($object_data['object_type'], ['as:Tombstone', ''])) { + // We don't have the object here or it is deleted. We ignore this activity. Queue::remove($object_data); } else { return false; @@ -966,8 +966,8 @@ class Receiver case 'litepub:EmojiReact': if (in_array($object_data['object_type'], self::CONTENT_TYPES)) { ActivityPub\Processor::createActivity($object_data, Activity::EMOJIREACT); - } elseif ($object_data['object_type'] == '') { - // The object type couldn't be determined. We don't have it and we can't fetch it. We ignore this activity. + } elseif (in_array($object_data['object_type'], ['as:Tombstone', ''])) { + // We don't have the object here or it is deleted. We ignore this activity. Queue::remove($object_data); } else { return false; From bfc1c157f1e4d2e84437e6f149bdb3e8b6290b8a Mon Sep 17 00:00:00 2001 From: Philipp Date: Mon, 26 Dec 2022 13:08:41 +0100 Subject: [PATCH 0049/1145] Adapt UserSession - Move from App methods to UserSession methods - Deprecate corresponding App methods --- src/App.php | 52 +++++-------------- .../Capability/IHandleUserSessions.php | 14 +++++ src/Core/Session/Model/UserSession.php | 17 ++++++ src/Model/User.php | 16 ++++++ src/Security/Authentication.php | 3 -- .../Api/Twitter/DirectMessages/NewDMTest.php | 6 +-- 6 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/App.php b/src/App.php index eb0d1cc217..b41215380f 100644 --- a/src/App.php +++ b/src/App.php @@ -29,7 +29,6 @@ use Friendica\Core\Config\Factory\Config; use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Database\Definition\DbaDefinition; use Friendica\Database\Definition\ViewDefinition; -use Friendica\Model\User; use Friendica\Module\Maintenance; use Friendica\Security\Authentication; use Friendica\Core\Config\ValueObject\Cache; @@ -73,8 +72,6 @@ class App 'videoheight' => 350, ]; - private $user_id = 0; - private $nickname = ''; private $timezone = ''; private $profile_owner = 0; private $contact_id = 0; @@ -136,64 +133,39 @@ class App private $session; /** - * Set the user ID - * - * @param int $user_id - * @return void + * @deprecated 2022.03 + * @see IHandleUserSessions::isAuthenticated() */ - public function setLoggedInUserId(int $user_id) - { - $this->user_id = $user_id; - } - - /** - * Set the nickname - * - * @param int $user_id - * @return void - */ - public function setLoggedInUserNickname(string $nickname) - { - $this->nickname = $nickname; - } - public function isLoggedIn(): bool { - return $this->session->getLocalUserId() && $this->user_id && ($this->user_id == $this->session->getLocalUserId()); + return $this->session->isAuthenticated(); } /** - * Check if current user has admin role. - * - * @return bool true if user is an admin - * @throws Exception + * @deprecated 2022.03 + * @see IHandleUserSessions::isSiteAdmin() */ public function isSiteAdmin(): bool { - return - $this->session->getLocalUserId() - && $this->database->exists('user', [ - 'uid' => $this->getLoggedInUserId(), - 'email' => User::getAdminEmailList() - ]); + return $this->session->isSiteAdmin(); } /** - * Fetch the user id - * @return int User id + * @deprecated 2022.03 + * @see IHandleUserSessions::getLocalUserId() */ public function getLoggedInUserId(): int { - return $this->user_id; + return $this->session->getLocalUserId(); } /** - * Fetch the user nick name - * @return string User's nickname + * @deprecated 2022.03 + * @see IHandleUserSessions::getLocalUserNickname() */ public function getLoggedInUserNickname(): string { - return $this->nickname; + return $this->session->getLocalUserNickname(); } /** diff --git a/src/Core/Session/Capability/IHandleUserSessions.php b/src/Core/Session/Capability/IHandleUserSessions.php index e65749c8df..7a6ca64ba1 100644 --- a/src/Core/Session/Capability/IHandleUserSessions.php +++ b/src/Core/Session/Capability/IHandleUserSessions.php @@ -33,6 +33,13 @@ interface IHandleUserSessions extends IHandleSessions */ public function getLocalUserId(); + /** + * Returns the user nickname of locally logged-in user. + * + * @return string|false User's nickname or false + */ + public function getLocalUserNickname(); + /** * Returns the public contact id of logged-in user or false. * @@ -79,6 +86,13 @@ interface IHandleUserSessions extends IHandleSessions */ public function isAuthenticated(): bool; + /** + * Check if current user has admin role. + * + * @return bool true if user is an admin + */ + public function isSiteAdmin(): bool; + /** * Returns User ID of the managed user in case it's a different identity * diff --git a/src/Core/Session/Model/UserSession.php b/src/Core/Session/Model/UserSession.php index 959ca1af2d..6cd689e9c7 100644 --- a/src/Core/Session/Model/UserSession.php +++ b/src/Core/Session/Model/UserSession.php @@ -24,6 +24,7 @@ namespace Friendica\Core\Session\Model; use Friendica\Core\Session\Capability\IHandleSessions; use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Model\Contact; +use Friendica\Model\User; /** * This class handles user sessions, which is directly extended from regular session @@ -50,6 +51,16 @@ class UserSession implements IHandleUserSessions return false; } + /** {@inheritDoc} */ + public function getLocalUserNickname() + { + if ($this->isAuthenticated()) { + return $this->session->get('nickname'); + } + + return false; + } + /** {@inheritDoc} */ public function getPublicContactId() { @@ -122,6 +133,12 @@ class UserSession implements IHandleUserSessions return $this->session->get('authenticated', false); } + /** {@inheritDoc} */ + public function isSiteAdmin(): bool + { + return User::isSiteAdmin($this->getLocalUserId()); + } + /** {@inheritDoc} */ public function setVisitorsContacts() { diff --git a/src/Model/User.php b/src/Model/User.php index 132e4f11a9..916844251e 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -830,6 +830,22 @@ class User return DBA::update('user', $fields, ['uid' => $uid]); } + /** + * Returns if the given uid is valid and in the admin list + * + * @param int $uid + * + * @return bool + * @throws Exception + */ + public static function isSiteAdmin(int $uid): bool + { + return DBA::exists('user', [ + 'uid' => $uid, + 'email' => self::getAdminEmailList() + ]); + } + /** * Checks if a nickname is in the list of the forbidden nicknames * diff --git a/src/Security/Authentication.php b/src/Security/Authentication.php index 5dcc399403..c6a8403672 100644 --- a/src/Security/Authentication.php +++ b/src/Security/Authentication.php @@ -392,9 +392,6 @@ class Authentication } } - $a->setLoggedInUserId($user_record['uid']); - $a->setLoggedInUserNickname($user_record['nickname']); - if ($login_initial) { Hook::callAll('logged_in', $user_record); } diff --git a/tests/src/Module/Api/Twitter/DirectMessages/NewDMTest.php b/tests/src/Module/Api/Twitter/DirectMessages/NewDMTest.php index b2bcfb37fa..cab3c22026 100644 --- a/tests/src/Module/Api/Twitter/DirectMessages/NewDMTest.php +++ b/tests/src/Module/Api/Twitter/DirectMessages/NewDMTest.php @@ -88,7 +88,7 @@ class NewDMTest extends ApiTest */ public function testApiDirectMessagesNewWithScreenName() { - DI::app()->setLoggedInUserNickname('selfcontact'); + DI::session()->set('nickname', 'selfcontact'); $directMessage = new DirectMessage(DI::logger(), DI::dba(), DI::twitterUser()); @@ -112,7 +112,7 @@ class NewDMTest extends ApiTest */ public function testApiDirectMessagesNewWithTitle() { - DI::app()->setLoggedInUserNickname('selfcontact'); + DI::session()->set('nickname', 'selfcontact'); $directMessage = new DirectMessage(DI::logger(), DI::dba(), DI::twitterUser()); @@ -138,7 +138,7 @@ class NewDMTest extends ApiTest */ public function testApiDirectMessagesNewWithRss() { - DI::app()->setLoggedInUserNickname('selfcontact'); + DI::session()->set('nickname', 'selfcontact'); $directMessage = new DirectMessage(DI::logger(), DI::dba(), DI::twitterUser()); From 10864e50c722ba73afd013e41d90aaa497ea6300 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 25 Dec 2022 16:48:09 +0100 Subject: [PATCH 0050/1145] Adapt Logger\Introspection - Create an interface - Add it as constructor parameter --- .../Capabilities/IHaveCallIntrospections.php | 52 +++++++++++++++++++ src/Core/Logger/Factory/Logger.php | 26 +++------- src/Core/Logger/Util/Introspection.php | 6 ++- static/dependencies.config.php | 6 +++ 4 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 src/Core/Logger/Capabilities/IHaveCallIntrospections.php diff --git a/src/Core/Logger/Capabilities/IHaveCallIntrospections.php b/src/Core/Logger/Capabilities/IHaveCallIntrospections.php new file mode 100644 index 0000000000..e9f27ee1ad --- /dev/null +++ b/src/Core/Logger/Capabilities/IHaveCallIntrospections.php @@ -0,0 +1,52 @@ +. + * + */ + +namespace Friendica\Core\Logger\Capabilities; +use Friendica\Core\Logger\Factory\Logger; +use Friendica\Util\Profiler; + +interface IHaveCallIntrospections +{ + /** + * A list of classes, which shouldn't get logged + * + * @var string[] + */ + public const IGNORE_CLASS_LIST = [ + Logger::class, + Profiler::class, + 'Friendica\\Core\\Logger\\Type', + ]; + + /** + * Adds new classes to get skipped + * + * @param array $classNames + */ + public function addClasses(array $classNames): void; + + /** + * Returns the introspection record of the current call + * + * @return array + */ + public function getRecord(): array; +} diff --git a/src/Core/Logger/Factory/Logger.php b/src/Core/Logger/Factory/Logger.php index 4df7d8ecaf..30e949a681 100644 --- a/src/Core/Logger/Factory/Logger.php +++ b/src/Core/Logger/Factory/Logger.php @@ -23,11 +23,11 @@ namespace Friendica\Core\Logger\Factory; use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core; +use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections; use Friendica\Core\Logger\Exception\LogLevelException; use Friendica\Database\Database; use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Util\FileSystem; -use Friendica\Core\Logger\Util\Introspection; use Friendica\Core\Logger\Type\ProfilerLogger; use Friendica\Core\Logger\Type\StreamLogger; use Friendica\Core\Logger\Type\SyslogLogger; @@ -43,17 +43,6 @@ class Logger { const DEV_CHANNEL = 'dev'; - /** - * A list of classes, which shouldn't get logged - * - * @var string[] - */ - private static $ignoreClassList = [ - Core\Logger::class, - Profiler::class, - 'Friendica\\Core\\Logger\\Type', - ]; - /** @var string The log-channel (app, worker, ...) */ private $channel; @@ -79,7 +68,7 @@ class Logger * * @return LoggerInterface The PSR-3 compliant logger instance */ - public function create(Database $database, IManageConfigValues $config, Profiler $profiler, FileSystem $fileSystem, ?string $minLevel = null): LoggerInterface + public function create(Database $database, IManageConfigValues $config, Profiler $profiler, FileSystem $fileSystem, IHaveCallIntrospections $introspection, ?string $minLevel = null): LoggerInterface { if (empty($config->get('system', 'debugging', false))) { $logger = new NullLogger(); @@ -87,7 +76,6 @@ class Logger return $logger; } - $introspection = new Introspection(self::$ignoreClassList); $minLevel = $minLevel ?? $config->get('system', 'loglevel'); $loglevel = self::mapLegacyConfigDebugLevel((string)$minLevel); @@ -99,7 +87,7 @@ class Logger $logger = new SyslogLogger($this->channel, $introspection, $loglevel, $config->get('system', 'syslog_flags', SyslogLogger::DEFAULT_FLAGS), $config->get('system', 'syslog_facility', SyslogLogger::DEFAULT_FACILITY)); } catch (LogLevelException $exception) { // If there's a wrong config value for loglevel, try again with standard - $logger = $this->create($database, $config, $profiler, $fileSystem, LogLevel::NOTICE); + $logger = $this->create($database, $config, $profiler, $fileSystem, $introspection, LogLevel::NOTICE); $logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]); } catch (\Throwable $e) { // No logger ... @@ -134,7 +122,7 @@ class Logger $logger = new StreamLogger($this->channel, $stream, $introspection, $fileSystem, $loglevel); } catch (LogLevelException $exception) { // If there's a wrong config value for loglevel, try again with standard - $logger = $this->create($database, $config, $profiler, $fileSystem, LogLevel::NOTICE); + $logger = $this->create($database, $config, $profiler, $fileSystem, $introspection, LogLevel::NOTICE); $logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]); } catch (\Throwable $t) { // No logger ... @@ -145,7 +133,7 @@ class Logger $logger = new SyslogLogger($this->channel, $introspection, $loglevel); } catch (LogLevelException $exception) { // If there's a wrong config value for loglevel, try again with standard - $logger = $this->create($database, $config, $profiler, $fileSystem, LogLevel::NOTICE); + $logger = $this->create($database, $config, $profiler, $fileSystem, $introspection, LogLevel::NOTICE); $logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]); } catch (\Throwable $e) { // No logger ... @@ -182,7 +170,7 @@ class Logger * @return LoggerInterface The PSR-3 compliant logger instance * @throws \Exception */ - public static function createDev(IManageConfigValues $config, Profiler $profiler, FileSystem $fileSystem) + public static function createDev(IManageConfigValues $config, Profiler $profiler, FileSystem $fileSystem, IHaveCallIntrospections $introspection) { $debugging = $config->get('system', 'debugging'); $stream = $config->get('system', 'dlogfile'); @@ -193,8 +181,6 @@ class Logger return new NullLogger(); } - $introspection = new Introspection(self::$ignoreClassList); - $name = $config->get('system', 'logger_config', 'stream'); switch ($name) { diff --git a/src/Core/Logger/Util/Introspection.php b/src/Core/Logger/Util/Introspection.php index 83d1b6faf5..444af2409e 100644 --- a/src/Core/Logger/Util/Introspection.php +++ b/src/Core/Logger/Util/Introspection.php @@ -21,10 +21,12 @@ namespace Friendica\Core\Logger\Util; +use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections; + /** * Get Introspection information about the current call */ -class Introspection +class Introspection implements IHaveCallIntrospections { /** @var int */ private $skipStackFramesCount; @@ -52,7 +54,7 @@ class Introspection * * @param array $classNames */ - public function addClasses(array $classNames) + public function addClasses(array $classNames): void { $this->skipClassesPartials = array_merge($this->skipClassesPartials, $classNames); } diff --git a/static/dependencies.config.php b/static/dependencies.config.php index a7de89d614..fd242c3417 100644 --- a/static/dependencies.config.php +++ b/static/dependencies.config.php @@ -176,6 +176,12 @@ return [ ['createDev', [], Dice::CHAIN_CALL], ] ], + \Friendica\Core\Logger\Capabilities\IHaveCallIntrospections::class => [ + 'instanceOf' => \Friendica\Core\Logger\Util\Introspection::class, + 'constructParams' => [ + \Friendica\Core\Logger\Util\Introspection::IGNORE_CLASS_LIST, + ], + ], Cache\Capability\ICanCache::class => [ 'instanceOf' => Cache\Factory\Cache::class, 'call' => [ From 5584e7a4e5725944020ba6972c724b2371e2bdd6 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 25 Dec 2022 19:19:06 +0100 Subject: [PATCH 0051/1145] Use X-REQUEST-ID for Logging --- src/App/Request.php | 20 ++++++++++++++++++++ src/Core/Logger/Util/Introspection.php | 14 ++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/App/Request.php b/src/App/Request.php index 71b6a9ea3f..1af1206d1f 100644 --- a/src/App/Request.php +++ b/src/App/Request.php @@ -22,6 +22,7 @@ namespace Friendica\App; use Friendica\Core\Config\Capability\IManageConfigValues; +use Friendica\Core\System; /** * Container for the whole request @@ -38,9 +39,17 @@ class Request * @var string */ const DEFAULT_FORWARD_FOR_HEADER = 'HTTP_X_FORWARDED_FOR'; + /** + * The default Request-ID header to retrieve the current transaction ID from the HTTP header (if set) + * + * @var string + */ + const DEFAULT_REQUEST_ID_HEADER = 'HTTP_X_REQUEST_ID'; /** @var string The remote IP address of the current request */ protected $remoteAddress; + /** @var string The request-id of the current request */ + protected $requestId; /** * @return string The remote IP address of the current request @@ -52,9 +61,20 @@ class Request return $this->remoteAddress; } + /** + * @return string The request ID of the current request + * + * Do always use this instead of $_SERVER['X_REQUEST_ID'] + */ + public function getRequestId(): string + { + return $this->requestId; + } + public function __construct(IManageConfigValues $config, array $server = []) { $this->remoteAddress = $this->determineRemoteAddress($config, $server); + $this->requestId = $server[static::DEFAULT_REQUEST_ID_HEADER] ?? System::createGUID(8); } /** diff --git a/src/Core/Logger/Util/Introspection.php b/src/Core/Logger/Util/Introspection.php index 444af2409e..987a4e3cba 100644 --- a/src/Core/Logger/Util/Introspection.php +++ b/src/Core/Logger/Util/Introspection.php @@ -21,6 +21,7 @@ namespace Friendica\Core\Logger\Util; +use Friendica\App\Request; use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections; /** @@ -28,6 +29,9 @@ use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections; */ class Introspection implements IHaveCallIntrospections { + /** @var string */ + private $requestId; + /** @var int */ private $skipStackFramesCount; @@ -43,8 +47,9 @@ class Introspection implements IHaveCallIntrospections * @param string[] $skipClassesPartials An array of classes to skip during logging * @param int $skipStackFramesCount If the logger should use information from other hierarchy levels of the call */ - public function __construct(array $skipClassesPartials = [], int $skipStackFramesCount = 0) + public function __construct(Request $request, array $skipClassesPartials = [], int $skipStackFramesCount = 0) { + $this->requestId = $request->getRequestId(); $this->skipClassesPartials = $skipClassesPartials; $this->skipStackFramesCount = $skipStackFramesCount; } @@ -77,9 +82,10 @@ class Introspection implements IHaveCallIntrospections $i += $this->skipStackFramesCount; return [ - 'file' => isset($trace[$i - 1]['file']) ? basename($trace[$i - 1]['file']) : null, - 'line' => $trace[$i - 1]['line'] ?? null, - 'function' => $trace[$i]['function'] ?? null, + 'file' => isset($trace[$i - 1]['file']) ? basename($trace[$i - 1]['file']) : null, + 'line' => $trace[$i - 1]['line'] ?? null, + 'function' => $trace[$i]['function'] ?? null, + 'request-id' => $this->requestId, ]; } From 4f1bb0d274f3a28ca6513184bc21a98b8c32fe56 Mon Sep 17 00:00:00 2001 From: Philipp Date: Mon, 26 Dec 2022 21:17:32 +0100 Subject: [PATCH 0052/1145] Use X-REQUEST-ID for Error pages --- index.php | 1 + src/App.php | 9 +-- src/BaseModule.php | 4 +- src/Capabilities/ICanHandleRequests.php | 6 +- src/Module/Api/Mastodon/Apps.php | 5 +- src/Module/BaseApi.php | 5 +- src/Module/HTTPException/MethodNotAllowed.php | 3 +- src/Module/HTTPException/PageNotFound.php | 8 +-- src/Module/OAuth/Acknowledge.php | 5 +- src/Module/OAuth/Revoke.php | 5 +- src/Module/OAuth/Token.php | 5 +- src/Module/Special/HTTPException.php | 70 ++++++++++++++----- static/dependencies.config.php | 7 +- tests/src/Module/Api/ApiTest.php | 7 ++ .../Friendica/DirectMessages/SearchTest.php | 6 +- .../Module/Api/Friendica/NotificationTest.php | 4 +- .../Module/Api/Friendica/Photo/DeleteTest.php | 8 +-- .../Api/Friendica/Photoalbum/DeleteTest.php | 6 +- .../Api/Friendica/Photoalbum/UpdateTest.php | 8 +-- .../Api/GnuSocial/GnuSocial/ConfigTest.php | 2 +- .../Api/GnuSocial/GnuSocial/VersionTest.php | 2 +- .../Module/Api/GnuSocial/Help/TestTest.php | 4 +- .../Accounts/VerifyCredentialsTest.php | 2 +- .../Twitter/Account/RateLimitStatusTest.php | 4 +- .../Api/Twitter/Account/UpdateProfileTest.php | 2 +- .../Module/Api/Twitter/Blocks/ListsTest.php | 2 +- .../Api/Twitter/DirectMessages/AllTest.php | 2 +- .../DirectMessages/ConversationTest.php | 2 +- .../Twitter/DirectMessages/DestroyTest.php | 10 +-- .../Api/Twitter/DirectMessages/InboxTest.php | 2 +- .../Api/Twitter/DirectMessages/NewDMTest.php | 10 +-- .../Api/Twitter/DirectMessages/SentTest.php | 4 +- .../Api/Twitter/Favorites/CreateTest.php | 6 +- .../Api/Twitter/Favorites/DestroyTest.php | 4 +- .../src/Module/Api/Twitter/FavoritesTest.php | 4 +- .../Api/Twitter/Followers/ListsTest.php | 2 +- .../Module/Api/Twitter/Friends/ListsTest.php | 2 +- .../Api/Twitter/Friendships/IncomingTest.php | 2 +- .../Module/Api/Twitter/Lists/StatusesTest.php | 6 +- .../Module/Api/Twitter/Media/UploadTest.php | 8 +-- .../Module/Api/Twitter/SavedSearchesTest.php | 2 +- .../Api/Twitter/Statuses/DestroyTest.php | 4 +- .../Api/Twitter/Statuses/MentionsTest.php | 6 +- .../Statuses/NetworkPublicTimelineTest.php | 6 +- .../Api/Twitter/Statuses/RetweetTest.php | 6 +- .../Module/Api/Twitter/Statuses/ShowTest.php | 6 +- .../Api/Twitter/Statuses/UpdateTest.php | 4 +- .../Api/Twitter/Statuses/UserTimelineTest.php | 6 +- .../Module/Api/Twitter/Users/LookupTest.php | 4 +- .../Module/Api/Twitter/Users/SearchTest.php | 6 +- .../src/Module/Api/Twitter/Users/ShowTest.php | 4 +- tests/src/Module/NodeInfoTest.php | 18 ++++- tests/src/Module/Special/OptionsTest.php | 16 ++++- view/templates/exception.tpl | 3 + view/templates/http_status.tpl | 3 + 55 files changed, 218 insertions(+), 130 deletions(-) diff --git a/index.php b/index.php index ba990532b8..c8d0037df0 100644 --- a/index.php +++ b/index.php @@ -45,6 +45,7 @@ $a->runFrontend( $dice->create(\Friendica\Core\PConfig\Capability\IManagePersonalConfigValues::class), $dice->create(\Friendica\Security\Authentication::class), $dice->create(\Friendica\App\Page::class), + $dice->create(Friendica\Module\Special\HTTPException::class), new \Friendica\Util\HTTPInputData($_SERVER), $start_time ); diff --git a/src/App.php b/src/App.php index b41215380f..b84c3b6294 100644 --- a/src/App.php +++ b/src/App.php @@ -573,13 +573,14 @@ class App * @param IManagePersonalConfigValues $pconfig * @param Authentication $auth The Authentication backend of the node * @param App\Page $page The Friendica page printing container + * @param ModuleHTTPException $httpException The possible HTTP Exception container * @param HTTPInputData $httpInput A library for processing PHP input streams * @param float $start_time The start time of the overall script execution * * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public function runFrontend(App\Router $router, IManagePersonalConfigValues $pconfig, Authentication $auth, App\Page $page, HTTPInputData $httpInput, float $start_time) + public function runFrontend(App\Router $router, IManagePersonalConfigValues $pconfig, Authentication $auth, App\Page $page, ModuleHTTPException $httpException, HTTPInputData $httpInput, float $start_time) { $this->profiler->set($start_time, 'start'); $this->profiler->set(microtime(true), 'classinit'); @@ -713,9 +714,9 @@ class App $httpinput = $httpInput->process(); $input = array_merge($httpinput['variables'], $httpinput['files'], $request ?? $_REQUEST); - // Let the module run it's internal process (init, get, post, ...) + // Let the module run its internal process (init, get, post, ...) $timestamp = microtime(true); - $response = $module->run($input); + $response = $module->run($httpException, $input); $this->profiler->set(microtime(true) - $timestamp, 'content'); if ($response->getHeaderLine(ICanCreateResponses::X_HEADER) === ICanCreateResponses::TYPE_HTML) { $page->run($this, $this->baseURL, $this->args, $this->mode, $response, $this->l10n, $this->profiler, $this->config, $pconfig, $this->session->getLocalUserId()); @@ -723,7 +724,7 @@ class App $page->exit($response); } } catch (HTTPException $e) { - (new ModuleHTTPException())->rawContent($e); + $httpException->rawContent($e); } $page->logRuntime($this->config, 'runFrontend'); } diff --git a/src/BaseModule.php b/src/BaseModule.php index 09107f0472..12efbce811 100644 --- a/src/BaseModule.php +++ b/src/BaseModule.php @@ -181,7 +181,7 @@ abstract class BaseModule implements ICanHandleRequests /** * {@inheritDoc} */ - public function run(array $request = []): ResponseInterface + public function run(ModuleHTTPException $httpException, array $request = []): ResponseInterface { // @see https://github.com/tootsuite/mastodon/blob/c3aef491d66aec743a3a53e934a494f653745b61/config/initializers/cors.rb if (substr($this->args->getQueryString(), 0, 12) == '.well-known/') { @@ -243,7 +243,7 @@ abstract class BaseModule implements ICanHandleRequests $this->response->addContent($arr['content']); $this->response->addContent($this->content($request)); } catch (HTTPException $e) { - $this->response->addContent((new ModuleHTTPException())->content($e)); + $this->response->addContent($httpException->content($e)); } finally { $this->profiler->set(microtime(true) - $timestamp, 'content'); } diff --git a/src/Capabilities/ICanHandleRequests.php b/src/Capabilities/ICanHandleRequests.php index 154eae69e5..c0f99eaa1b 100644 --- a/src/Capabilities/ICanHandleRequests.php +++ b/src/Capabilities/ICanHandleRequests.php @@ -21,6 +21,7 @@ namespace Friendica\Capabilities; +use Friendica\Module\Special\HTTPException as ModuleHTTPException; use Friendica\Network\HTTPException; use Psr\Http\Message\ResponseInterface; @@ -30,11 +31,12 @@ use Psr\Http\Message\ResponseInterface; interface ICanHandleRequests { /** - * @param array $request The $_REQUEST content (including content from the PHP input stream) + * @param ModuleHTTPException $httpException The special HTTPException Module in case of underlying errors + * @param array $request The $_REQUEST content (including content from the PHP input stream) * * @return ResponseInterface responding to the request handling * * @throws HTTPException\InternalServerErrorException */ - public function run(array $request = []): ResponseInterface; + public function run(ModuleHTTPException $httpException, array $request = []): ResponseInterface; } diff --git a/src/Module/Api/Mastodon/Apps.php b/src/Module/Api/Mastodon/Apps.php index f14ff68177..1c1ec80602 100644 --- a/src/Module/Api/Mastodon/Apps.php +++ b/src/Module/Api/Mastodon/Apps.php @@ -25,6 +25,7 @@ use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Module\BaseApi; +use Friendica\Module\Special\HTTPException; use Friendica\Util\Network; use Psr\Http\Message\ResponseInterface; @@ -33,9 +34,9 @@ use Psr\Http\Message\ResponseInterface; */ class Apps extends BaseApi { - public function run(array $request = [], bool $scopecheck = true): ResponseInterface + public function run(HTTPException $httpException, array $request = [], bool $scopecheck = true): ResponseInterface { - return parent::run($request, false); + return parent::run($httpException, $request, false); } /** diff --git a/src/Module/BaseApi.php b/src/Module/BaseApi.php index 1d5249ac85..82dda9de9f 100644 --- a/src/Module/BaseApi.php +++ b/src/Module/BaseApi.php @@ -33,6 +33,7 @@ use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Model\User; use Friendica\Module\Api\ApiResponse; +use Friendica\Module\Special\HTTPException as ModuleHTTPException; use Friendica\Network\HTTPException; use Friendica\Security\BasicAuth; use Friendica\Security\OAuth; @@ -80,7 +81,7 @@ class BaseApi extends BaseModule * * @throws HTTPException\ForbiddenException */ - public function run(array $request = [], bool $scopecheck = true): ResponseInterface + public function run(ModuleHTTPException $httpException, array $request = [], bool $scopecheck = true): ResponseInterface { if ($scopecheck) { switch ($this->args->getMethod()) { @@ -97,7 +98,7 @@ class BaseApi extends BaseModule } } - return parent::run($request); + return parent::run($httpException, $request); } /** diff --git a/src/Module/HTTPException/MethodNotAllowed.php b/src/Module/HTTPException/MethodNotAllowed.php index 7dc3737596..5728e0a376 100644 --- a/src/Module/HTTPException/MethodNotAllowed.php +++ b/src/Module/HTTPException/MethodNotAllowed.php @@ -22,13 +22,12 @@ namespace Friendica\Module\HTTPException; use Friendica\BaseModule; -use Friendica\DI; use Friendica\Network\HTTPException; class MethodNotAllowed extends BaseModule { protected function content(array $request = []): string { - throw new HTTPException\MethodNotAllowedException(DI::l10n()->t('Method Not Allowed.')); + throw new HTTPException\MethodNotAllowedException($this->t('Method Not Allowed.')); } } diff --git a/src/Module/HTTPException/PageNotFound.php b/src/Module/HTTPException/PageNotFound.php index ecebc7757a..2b6e546527 100644 --- a/src/Module/HTTPException/PageNotFound.php +++ b/src/Module/HTTPException/PageNotFound.php @@ -25,8 +25,8 @@ use Friendica\App; use Friendica\BaseModule; use Friendica\Core\L10n; use Friendica\Core\System; -use Friendica\DI; use Friendica\Module\Response; +use Friendica\Module\Special\HTTPException as ModuleHTTPException; use Friendica\Network\HTTPException; use Friendica\Util\Profiler; use Psr\Http\Message\ResponseInterface; @@ -46,10 +46,10 @@ class PageNotFound extends BaseModule protected function content(array $request = []): string { - throw new HTTPException\NotFoundException(DI::l10n()->t('Page not found.')); + throw new HTTPException\NotFoundException($this->t('Page not found.')); } - public function run(array $request = []): ResponseInterface + public function run(ModuleHTTPException $httpException, array $request = []): ResponseInterface { /* The URL provided does not resolve to a valid module. * @@ -77,6 +77,6 @@ class PageNotFound extends BaseModule 'query' => $this->server['QUERY_STRING'] ]); - return parent::run($request); // TODO: Change the autogenerated stub + return parent::run($httpException, $request); } } diff --git a/src/Module/OAuth/Acknowledge.php b/src/Module/OAuth/Acknowledge.php index fe947a63c0..e2a65a0e28 100644 --- a/src/Module/OAuth/Acknowledge.php +++ b/src/Module/OAuth/Acknowledge.php @@ -24,6 +24,7 @@ namespace Friendica\Module\OAuth; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Module\BaseApi; +use Friendica\Module\Special\HTTPException; use Psr\Http\Message\ResponseInterface; /** @@ -31,9 +32,9 @@ use Psr\Http\Message\ResponseInterface; */ class Acknowledge extends BaseApi { - public function run(array $request = [], bool $scopecheck = true): ResponseInterface + public function run(HTTPException $httpException, array $request = [], bool $scopecheck = true): ResponseInterface { - return parent::run($request, false); + return parent::run($httpException, $request, false); } protected function post(array $request = []) diff --git a/src/Module/OAuth/Revoke.php b/src/Module/OAuth/Revoke.php index 0604e90bf7..11d65420c0 100644 --- a/src/Module/OAuth/Revoke.php +++ b/src/Module/OAuth/Revoke.php @@ -26,6 +26,7 @@ use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Module\BaseApi; +use Friendica\Module\Special\HTTPException; use Psr\Http\Message\ResponseInterface; /** @@ -33,9 +34,9 @@ use Psr\Http\Message\ResponseInterface; */ class Revoke extends BaseApi { - public function run(array $request = [], bool $scopecheck = true): ResponseInterface + public function run(HTTPException $httpException, array $request = [], bool $scopecheck = true): ResponseInterface { - return parent::run($request, false); + return parent::run($httpException, $request, false); } protected function post(array $request = []) diff --git a/src/Module/OAuth/Token.php b/src/Module/OAuth/Token.php index 1da8df18d5..14e9be7a69 100644 --- a/src/Module/OAuth/Token.php +++ b/src/Module/OAuth/Token.php @@ -26,6 +26,7 @@ use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Module\BaseApi; +use Friendica\Module\Special\HTTPException; use Friendica\Security\OAuth; use Friendica\Util\DateTimeFormat; use Psr\Http\Message\ResponseInterface; @@ -36,9 +37,9 @@ use Psr\Http\Message\ResponseInterface; */ class Token extends BaseApi { - public function run(array $request = [], bool $scopecheck = true): ResponseInterface + public function run(HTTPException $httpException, array $request = [], bool $scopecheck = true): ResponseInterface { - return parent::run($request, false); + return parent::run($httpException, $request, false); } protected function post(array $request = []) diff --git a/src/Module/Special/HTTPException.php b/src/Module/Special/HTTPException.php index 0cd7817ed4..6928cf810f 100644 --- a/src/Module/Special/HTTPException.php +++ b/src/Module/Special/HTTPException.php @@ -21,10 +21,13 @@ namespace Friendica\Module\Special; -use Friendica\Core\Logger; +use Friendica\App\Arguments; +use Friendica\App\Request; +use Friendica\Core\L10n; use Friendica\Core\Renderer; +use Friendica\Core\Session\Model\UserSession; use Friendica\Core\System; -use Friendica\DI; +use Psr\Log\LoggerInterface; /** * This special module displays HTTPException when they are thrown in modules. @@ -33,27 +36,52 @@ use Friendica\DI; */ class HTTPException { + /** @var L10n */ + protected $l10n; + /** @var LoggerInterface */ + protected $logger; + /** @var Arguments */ + protected $args; + /** @var bool */ + protected $isSiteAdmin; + /** @var array */ + protected $server; + /** @var string */ + protected $requestId; + + public function __construct(L10n $l10n, LoggerInterface $logger, Arguments $args, UserSession $session, Request $request, array $server = []) + { + $this->logger = $logger; + $this->l10n = $l10n; + $this->args = $args; + $this->isSiteAdmin = $session->isSiteAdmin(); + $this->server = $server; + $this->requestId = $request->getRequestId(); + } + /** * Generates the necessary template variables from the caught HTTPException. * * Fills in the blanks if title or descriptions aren't provided by the exception. * * @param \Friendica\Network\HTTPException $e + * * @return array ['$title' => ..., '$description' => ...] */ - private static function getVars(\Friendica\Network\HTTPException $e) + private function getVars(\Friendica\Network\HTTPException $e) { // Explanations are mostly taken from https://en.wikipedia.org/wiki/List_of_HTTP_status_codes $vars = [ - '$title' => $e->getDescription() ?: 'Error ' . $e->getCode(), - '$message' => $e->getMessage() ?: $e->getExplanation(), - '$back' => DI::l10n()->t('Go back'), - '$stack_trace' => DI::l10n()->t('Stack trace:'), + '$title' => $e->getDescription() ?: 'Error ' . $e->getCode(), + '$message' => $e->getMessage() ?: $e->getExplanation(), + '$back' => $this->l10n->t('Go back'), + '$stack_trace' => $this->l10n->t('Stack trace:'), + '$request_id' => $this->requestId, ]; - if (DI::app()->isSiteAdmin()) { - $vars['$thrown'] = DI::l10n()->t('Exception thrown in %s:%d', $e->getFile(), $e->getLine()); - $vars['$trace'] = $e->getTraceAsString(); + if ($this->isSiteAdmin) { + $vars['$thrown'] = $this->l10n->t('Exception thrown in %s:%d', $e->getFile(), $e->getLine()); + $vars['$trace'] = $e->getTraceAsString(); } return $vars; @@ -63,6 +91,7 @@ class HTTPException * Displays a bare message page with no theming at all. * * @param \Friendica\Network\HTTPException $e + * * @throws \Exception */ public function rawContent(\Friendica\Network\HTTPException $e) @@ -70,13 +99,13 @@ class HTTPException $content = ''; if ($e->getCode() >= 400) { - $vars = self::getVars($e); + $vars = $this->getVars($e); try { - $tpl = Renderer::getMarkupTemplate('http_status.tpl'); + $tpl = Renderer::getMarkupTemplate('http_status.tpl'); $content = Renderer::replaceMacros($tpl, $vars); } catch (\Exception $e) { $content = "

{$vars['$title']}

{$vars['$message']}

"; - if (DI::app()->isSiteAdmin()) { + if ($this->isSiteAdmin) { $content .= "

{$vars['$thrown']}

"; $content .= "
{$vars['$trace']}
"; } @@ -90,19 +119,28 @@ class HTTPException * Returns a content string that can be integrated in the current theme. * * @param \Friendica\Network\HTTPException $e + * * @return string * @throws \Exception */ public function content(\Friendica\Network\HTTPException $e): string { - header($_SERVER["SERVER_PROTOCOL"] . ' ' . $e->getCode() . ' ' . $e->getDescription()); + header($this->server['SERVER_PROTOCOL'] ?? 'HTTP/1.0' . ' ' . $e->getCode() . ' ' . $e->getDescription()); if ($e->getCode() >= 400) { - Logger::debug('Exit with error', ['code' => $e->getCode(), 'description' => $e->getDescription(), 'query' => DI::args()->getQueryString(), 'callstack' => System::callstack(20), 'method' => DI::args()->getMethod(), 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '']); + $this->logger->debug('Exit with error', + [ + 'code' => $e->getCode(), + 'description' => $e->getDescription(), + 'query' => $this->args->getQueryString(), + 'callstack' => System::callstack(20), + 'method' => $this->args->getMethod(), + 'agent' => $this->server['HTTP_USER_AGENT'] ?? '' + ]); } $tpl = Renderer::getMarkupTemplate('exception.tpl'); - return Renderer::replaceMacros($tpl, self::getVars($e)); + return Renderer::replaceMacros($tpl, $this->getVars($e)); } } diff --git a/static/dependencies.config.php b/static/dependencies.config.php index fd242c3417..a4c52e0043 100644 --- a/static/dependencies.config.php +++ b/static/dependencies.config.php @@ -273,5 +273,10 @@ return [ ], \Psr\Clock\ClockInterface::class => [ 'instanceOf' => Util\Clock\SystemClock::class - ] + ], + \Friendica\Module\Special\HTTPException::class => [ + 'constructParams' => [ + $_SERVER + ], + ], ]; diff --git a/tests/src/Module/Api/ApiTest.php b/tests/src/Module/Api/ApiTest.php index 890bba19b6..c01f39f4c9 100644 --- a/tests/src/Module/Api/ApiTest.php +++ b/tests/src/Module/Api/ApiTest.php @@ -27,12 +27,14 @@ use Friendica\Core\Addon; use Friendica\Core\Hook; use Friendica\Database\Database; use Friendica\DI; +use Friendica\Module\Special\HTTPException; use Friendica\Security\Authentication; use Friendica\Security\BasicAuth; use Friendica\Test\FixtureTest; use Friendica\Test\Util\AppDouble; use Friendica\Test\Util\AuthenticationDouble; use Friendica\Test\Util\AuthTestConfig; +use Mockery\MockInterface; use Psr\Http\Message\ResponseInterface; abstract class ApiTest extends FixtureTest @@ -59,6 +61,9 @@ abstract class ApiTest extends FixtureTest 'nurl' => 'http://localhost/profile/othercontact' ]; + /** @var HTTPException */ + protected $httpExceptionMock; + // User ID that we know is not in the database const WRONG_USER_ID = 666; @@ -175,6 +180,8 @@ abstract class ApiTest extends FixtureTest // Manual override to bypass API authentication DI::app()->setIsLoggedIn(true); + $this->httpExceptionMock = $this->dice->create(HTTPException::class); + AuthTestConfig::$authenticated = true; AuthTestConfig::$user_id = 42; diff --git a/tests/src/Module/Api/Friendica/DirectMessages/SearchTest.php b/tests/src/Module/Api/Friendica/DirectMessages/SearchTest.php index 09845a99b4..9ec0f6f0dc 100644 --- a/tests/src/Module/Api/Friendica/DirectMessages/SearchTest.php +++ b/tests/src/Module/Api/Friendica/DirectMessages/SearchTest.php @@ -35,7 +35,7 @@ class SearchTest extends ApiTest $directMessage = new DirectMessage(new NullLogger(), DI::dba(), DI::twitterUser()); $response = (new Search($directMessage, DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); $json = $this->toJson($response); @@ -53,7 +53,7 @@ class SearchTest extends ApiTest $directMessage = new DirectMessage(new NullLogger(), DI::dba(), DI::twitterUser()); $response = (new Search($directMessage, DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'searchstring' => 'item_body' ]); @@ -74,7 +74,7 @@ class SearchTest extends ApiTest $directMessage = new DirectMessage(new NullLogger(), DI::dba(), DI::twitterUser()); $response = (new Search($directMessage, DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'searchstring' => 'test' ]); diff --git a/tests/src/Module/Api/Friendica/NotificationTest.php b/tests/src/Module/Api/Friendica/NotificationTest.php index 3c17471b03..1599b8abc1 100644 --- a/tests/src/Module/Api/Friendica/NotificationTest.php +++ b/tests/src/Module/Api/Friendica/NotificationTest.php @@ -67,7 +67,7 @@ class NotificationTest extends ApiTest XML; $response = (new Notification(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'xml'])) - ->run(); + ->run($this->httpExceptionMock); self::assertXmlStringEqualsXmlString($assertXml, (string)$response->getBody()); self::assertEquals([ @@ -79,7 +79,7 @@ XML; public function testWithJsonResult() { $response = (new Notification(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run(); + ->run($this->httpExceptionMock); $json = $this->toJson($response); diff --git a/tests/src/Module/Api/Friendica/Photo/DeleteTest.php b/tests/src/Module/Api/Friendica/Photo/DeleteTest.php index e3e208ff02..b946affe2b 100644 --- a/tests/src/Module/Api/Friendica/Photo/DeleteTest.php +++ b/tests/src/Module/Api/Friendica/Photo/DeleteTest.php @@ -39,7 +39,7 @@ class DeleteTest extends ApiTest public function testEmpty() { $this->expectException(BadRequestException::class); - (new Delete(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), []))->run(); + (new Delete(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), []))->run($this->httpExceptionMock); } public function testWithoutAuthenticatedUser() @@ -50,7 +50,7 @@ class DeleteTest extends ApiTest public function testWrong() { $this->expectException(BadRequestException::class); - (new Delete(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), []))->run(['photo_id' => 1]); + (new Delete(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), []))->run($this->httpExceptionMock, ['photo_id' => 1]); } public function testValidWithPost() @@ -58,7 +58,7 @@ class DeleteTest extends ApiTest $this->loadFixture(__DIR__ . '/../../../../../datasets/photo/photo.fixture.php', DI::dba()); $response = (new Delete(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'photo_id' => '709057080661a283a6aa598501504178' ]); @@ -73,7 +73,7 @@ class DeleteTest extends ApiTest $this->loadFixture(__DIR__ . '/../../../../../datasets/photo/photo.fixture.php', DI::dba()); $response = (new Delete(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'photo_id' => '709057080661a283a6aa598501504178' ]); diff --git a/tests/src/Module/Api/Friendica/Photoalbum/DeleteTest.php b/tests/src/Module/Api/Friendica/Photoalbum/DeleteTest.php index 6ce77f63aa..db16adfb90 100644 --- a/tests/src/Module/Api/Friendica/Photoalbum/DeleteTest.php +++ b/tests/src/Module/Api/Friendica/Photoalbum/DeleteTest.php @@ -40,7 +40,7 @@ class DeleteTest extends ApiTest { $this->expectException(BadRequestException::class); (new Delete(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); } @@ -48,7 +48,7 @@ class DeleteTest extends ApiTest { $this->expectException(BadRequestException::class); (new Delete(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'album' => 'album_name' ]); } @@ -58,7 +58,7 @@ class DeleteTest extends ApiTest $this->loadFixture(__DIR__ . '/../../../../../datasets/photo/photo.fixture.php', DI::dba()); $response = (new Delete(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'album' => 'test_album'] ); diff --git a/tests/src/Module/Api/Friendica/Photoalbum/UpdateTest.php b/tests/src/Module/Api/Friendica/Photoalbum/UpdateTest.php index 5f25a62ac0..9a2b053dde 100644 --- a/tests/src/Module/Api/Friendica/Photoalbum/UpdateTest.php +++ b/tests/src/Module/Api/Friendica/Photoalbum/UpdateTest.php @@ -40,14 +40,14 @@ class UpdateTest extends ApiTest { $this->expectException(BadRequestException::class); (new Update(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); } public function testTooFewArgs() { $this->expectException(BadRequestException::class); (new Update(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'album' => 'album_name' ]); } @@ -56,7 +56,7 @@ class UpdateTest extends ApiTest { $this->expectException(BadRequestException::class); (new Update(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'album' => 'album_name', 'album_new' => 'album_name' ]); @@ -72,7 +72,7 @@ class UpdateTest extends ApiTest $this->loadFixture(__DIR__ . '/../../../../../datasets/photo/photo.fixture.php', DI::dba()); $response = (new Update(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'album' => 'test_album', 'album_new' => 'test_album_2' ]); diff --git a/tests/src/Module/Api/GnuSocial/GnuSocial/ConfigTest.php b/tests/src/Module/Api/GnuSocial/GnuSocial/ConfigTest.php index 64d2a77826..52beb98019 100644 --- a/tests/src/Module/Api/GnuSocial/GnuSocial/ConfigTest.php +++ b/tests/src/Module/Api/GnuSocial/GnuSocial/ConfigTest.php @@ -37,7 +37,7 @@ class ConfigTest extends ApiTest DI::config()->set('system', 'ssl_policy', BaseURL::SSL_POLICY_FULL); $response = (new Config(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); $json = $this->toJson($response); self::assertEquals('localhost', $json->site->server); diff --git a/tests/src/Module/Api/GnuSocial/GnuSocial/VersionTest.php b/tests/src/Module/Api/GnuSocial/GnuSocial/VersionTest.php index 175aaabda3..b0ec8f832e 100644 --- a/tests/src/Module/Api/GnuSocial/GnuSocial/VersionTest.php +++ b/tests/src/Module/Api/GnuSocial/GnuSocial/VersionTest.php @@ -31,7 +31,7 @@ class VersionTest extends ApiTest public function test() { $response = (new Version(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run(); + ->run($this->httpExceptionMock); self::assertEquals([ 'Content-type' => ['application/json'], diff --git a/tests/src/Module/Api/GnuSocial/Help/TestTest.php b/tests/src/Module/Api/GnuSocial/Help/TestTest.php index be0e187a63..47f6492b1e 100644 --- a/tests/src/Module/Api/GnuSocial/Help/TestTest.php +++ b/tests/src/Module/Api/GnuSocial/Help/TestTest.php @@ -31,7 +31,7 @@ class TestTest extends ApiTest public function testJson() { $response = (new Test(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run(); + ->run($this->httpExceptionMock); $json = $this->toJson($response); @@ -45,7 +45,7 @@ class TestTest extends ApiTest public function testXml() { $response = (new Test(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'xml'])) - ->run(); + ->run($this->httpExceptionMock); self::assertEquals([ 'Content-type' => ['text/xml'], diff --git a/tests/src/Module/Api/Mastodon/Accounts/VerifyCredentialsTest.php b/tests/src/Module/Api/Mastodon/Accounts/VerifyCredentialsTest.php index 5d3e33d132..daea2ca53e 100644 --- a/tests/src/Module/Api/Mastodon/Accounts/VerifyCredentialsTest.php +++ b/tests/src/Module/Api/Mastodon/Accounts/VerifyCredentialsTest.php @@ -36,7 +36,7 @@ class VerifyCredentialsTest extends ApiTest public function testApiAccountVerifyCredentials() { $response = (new VerifyCredentials(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); $json = $this->toJson($response); diff --git a/tests/src/Module/Api/Twitter/Account/RateLimitStatusTest.php b/tests/src/Module/Api/Twitter/Account/RateLimitStatusTest.php index 8d928b3ee3..ef566de2dd 100644 --- a/tests/src/Module/Api/Twitter/Account/RateLimitStatusTest.php +++ b/tests/src/Module/Api/Twitter/Account/RateLimitStatusTest.php @@ -32,7 +32,7 @@ class RateLimitStatusTest extends ApiTest public function testWithJson() { $response = (new RateLimitStatus(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run(); + ->run($this->httpExceptionMock); $result = $this->toJson($response); @@ -48,7 +48,7 @@ class RateLimitStatusTest extends ApiTest public function testWithXml() { $response = (new RateLimitStatus(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'xml'])) - ->run(); + ->run($this->httpExceptionMock); self::assertEquals([ 'Content-type' => ['text/xml'], diff --git a/tests/src/Module/Api/Twitter/Account/UpdateProfileTest.php b/tests/src/Module/Api/Twitter/Account/UpdateProfileTest.php index d3c8f93024..abdde24861 100644 --- a/tests/src/Module/Api/Twitter/Account/UpdateProfileTest.php +++ b/tests/src/Module/Api/Twitter/Account/UpdateProfileTest.php @@ -36,7 +36,7 @@ class UpdateProfileTest extends ApiTest $this->useHttpMethod(Router::POST); $response = (new UpdateProfile(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run([ + ->run($this->httpExceptionMock, [ 'name' => 'new_name', 'description' => 'new_description' ]); diff --git a/tests/src/Module/Api/Twitter/Blocks/ListsTest.php b/tests/src/Module/Api/Twitter/Blocks/ListsTest.php index 1212a3f8e9..30d42414d4 100644 --- a/tests/src/Module/Api/Twitter/Blocks/ListsTest.php +++ b/tests/src/Module/Api/Twitter/Blocks/ListsTest.php @@ -34,7 +34,7 @@ class ListsTest extends ApiTest public function testApiStatusesFWithBlocks() { $response = (new Lists(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); $json = $this->toJson($response); diff --git a/tests/src/Module/Api/Twitter/DirectMessages/AllTest.php b/tests/src/Module/Api/Twitter/DirectMessages/AllTest.php index 666299cc69..6d74b87128 100644 --- a/tests/src/Module/Api/Twitter/DirectMessages/AllTest.php +++ b/tests/src/Module/Api/Twitter/DirectMessages/AllTest.php @@ -40,7 +40,7 @@ class AllTest extends ApiTest $directMessage = new DirectMessage(DI::logger(), DI::dba(), DI::twitterUser()); $response = (new All($directMessage, DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run(); + ->run($this->httpExceptionMock); $json = $this->toJson($response); diff --git a/tests/src/Module/Api/Twitter/DirectMessages/ConversationTest.php b/tests/src/Module/Api/Twitter/DirectMessages/ConversationTest.php index e895845aad..834a5150e0 100644 --- a/tests/src/Module/Api/Twitter/DirectMessages/ConversationTest.php +++ b/tests/src/Module/Api/Twitter/DirectMessages/ConversationTest.php @@ -39,7 +39,7 @@ class ConversationTest extends ApiTest $directMessage = new DirectMessage(DI::logger(), DI::dba(), DI::twitterUser()); $response = (new Conversation($directMessage, DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run([ + ->run($this->httpExceptionMock, [ 'friendica_verbose' => true, ]); diff --git a/tests/src/Module/Api/Twitter/DirectMessages/DestroyTest.php b/tests/src/Module/Api/Twitter/DirectMessages/DestroyTest.php index b9317190b6..2145905379 100644 --- a/tests/src/Module/Api/Twitter/DirectMessages/DestroyTest.php +++ b/tests/src/Module/Api/Twitter/DirectMessages/DestroyTest.php @@ -38,7 +38,7 @@ class DestroyTest extends ApiTest { $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class); (new Destroy(DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run(); + ->run($this->httpExceptionMock); } /** @@ -49,7 +49,7 @@ class DestroyTest extends ApiTest public function testApiDirectMessagesDestroyWithVerbose() { $response = (new Destroy(DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run([ + ->run($this->httpExceptionMock, [ 'friendica_verbose' => true, ]); @@ -85,7 +85,7 @@ class DestroyTest extends ApiTest { $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class); (new Destroy(DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run([ + ->run($this->httpExceptionMock, [ 'id' => 1 ]); } @@ -98,7 +98,7 @@ class DestroyTest extends ApiTest public function testApiDirectMessagesDestroyWithIdAndVerbose() { $response = (new Destroy(DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run([ + ->run($this->httpExceptionMock, [ 'id' => 1, 'friendica_parenturi' => 'parent_uri', 'friendica_verbose' => true, @@ -122,7 +122,7 @@ class DestroyTest extends ApiTest $id = $ids[0]['id']; $response = (new Destroy(DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run([ + ->run($this->httpExceptionMock, [ 'id' => $id, 'friendica_verbose' => true, ]); diff --git a/tests/src/Module/Api/Twitter/DirectMessages/InboxTest.php b/tests/src/Module/Api/Twitter/DirectMessages/InboxTest.php index cee1450cf7..f239755b3e 100644 --- a/tests/src/Module/Api/Twitter/DirectMessages/InboxTest.php +++ b/tests/src/Module/Api/Twitter/DirectMessages/InboxTest.php @@ -41,7 +41,7 @@ class InboxTest extends ApiTest $directMessage = new DirectMessage(DI::logger(), DI::dba(), DI::twitterUser()); $response = (new Inbox($directMessage, DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run(); + ->run($this->httpExceptionMock); $json = $this->toJson($response); diff --git a/tests/src/Module/Api/Twitter/DirectMessages/NewDMTest.php b/tests/src/Module/Api/Twitter/DirectMessages/NewDMTest.php index cab3c22026..2b473fb48b 100644 --- a/tests/src/Module/Api/Twitter/DirectMessages/NewDMTest.php +++ b/tests/src/Module/Api/Twitter/DirectMessages/NewDMTest.php @@ -39,7 +39,7 @@ class NewDMTest extends ApiTest $directMessage = new DirectMessage(DI::logger(), DI::dba(), DI::twitterUser()); $response = (new NewDM($directMessage, DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run(); + ->run($this->httpExceptionMock); self::assertEmpty((string)$response->getBody()); } @@ -71,7 +71,7 @@ class NewDMTest extends ApiTest $directMessage = new DirectMessage(DI::logger(), DI::dba(), DI::twitterUser()); $response = (new NewDM($directMessage, DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run([ + ->run($this->httpExceptionMock, [ 'text' => 'message_text', 'user_id' => 43 ]); @@ -93,7 +93,7 @@ class NewDMTest extends ApiTest $directMessage = new DirectMessage(DI::logger(), DI::dba(), DI::twitterUser()); $response = (new NewDM($directMessage, DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run([ + ->run($this->httpExceptionMock, [ 'text' => 'message_text', 'user_id' => 44 ]); @@ -117,7 +117,7 @@ class NewDMTest extends ApiTest $directMessage = new DirectMessage(DI::logger(), DI::dba(), DI::twitterUser()); $response = (new NewDM($directMessage, DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run([ + ->run($this->httpExceptionMock, [ 'text' => 'message_text', 'user_id' => 44, 'title' => 'message_title', @@ -143,7 +143,7 @@ class NewDMTest extends ApiTest $directMessage = new DirectMessage(DI::logger(), DI::dba(), DI::twitterUser()); $response = (new NewDM($directMessage, DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'rss'])) - ->run([ + ->run($this->httpExceptionMock, [ 'text' => 'message_text', 'user_id' => 44, 'title' => 'message_title', diff --git a/tests/src/Module/Api/Twitter/DirectMessages/SentTest.php b/tests/src/Module/Api/Twitter/DirectMessages/SentTest.php index 9c498af5f6..f63a24f806 100644 --- a/tests/src/Module/Api/Twitter/DirectMessages/SentTest.php +++ b/tests/src/Module/Api/Twitter/DirectMessages/SentTest.php @@ -39,7 +39,7 @@ class SentTest extends ApiTest $directMessage = new DirectMessage(DI::logger(), DI::dba(), DI::twitterUser()); $response = (new Sent($directMessage, DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run([ + ->run($this->httpExceptionMock, [ 'friendica_verbose' => true, ]); @@ -59,7 +59,7 @@ class SentTest extends ApiTest $directMessage = new DirectMessage(DI::logger(), DI::dba(), DI::twitterUser()); $response = (new Sent($directMessage, DI::dba(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'rss'])) - ->run(); + ->run($this->httpExceptionMock); self::assertXml((string)$response->getBody(), 'direct-messages'); } diff --git a/tests/src/Module/Api/Twitter/Favorites/CreateTest.php b/tests/src/Module/Api/Twitter/Favorites/CreateTest.php index 61e235700c..fd0f86b6aa 100644 --- a/tests/src/Module/Api/Twitter/Favorites/CreateTest.php +++ b/tests/src/Module/Api/Twitter/Favorites/CreateTest.php @@ -47,7 +47,7 @@ class CreateTest extends ApiTest $this->expectException(BadRequestException::class); (new Create(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); } /** @@ -58,7 +58,7 @@ class CreateTest extends ApiTest public function testApiFavoritesCreateDestroyWithCreateAction() { $response = (new Create(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'id' => 3 ]); @@ -75,7 +75,7 @@ class CreateTest extends ApiTest public function testApiFavoritesCreateDestroyWithCreateActionAndRss() { $response = (new Create(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => ICanCreateResponses::TYPE_RSS])) - ->run([ + ->run($this->httpExceptionMock, [ 'id' => 3 ]); diff --git a/tests/src/Module/Api/Twitter/Favorites/DestroyTest.php b/tests/src/Module/Api/Twitter/Favorites/DestroyTest.php index bb7b54ee42..e65c120142 100644 --- a/tests/src/Module/Api/Twitter/Favorites/DestroyTest.php +++ b/tests/src/Module/Api/Twitter/Favorites/DestroyTest.php @@ -46,7 +46,7 @@ class DestroyTest extends ApiTest $this->expectException(BadRequestException::class); (new Destroy(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); } /** @@ -57,7 +57,7 @@ class DestroyTest extends ApiTest public function testApiFavoritesCreateDestroyWithDestroyAction() { $response = (new Destroy(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'id' => 3 ]); diff --git a/tests/src/Module/Api/Twitter/FavoritesTest.php b/tests/src/Module/Api/Twitter/FavoritesTest.php index 6da92e667d..c95aff6917 100644 --- a/tests/src/Module/Api/Twitter/FavoritesTest.php +++ b/tests/src/Module/Api/Twitter/FavoritesTest.php @@ -37,7 +37,7 @@ class FavoritesTest extends ApiTest public function testApiFavorites() { $response = (new Favorites(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'page' => -1, 'max_id' => 10, ]); @@ -58,7 +58,7 @@ class FavoritesTest extends ApiTest { $response = (new Favorites(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], [ 'extension' => ICanCreateResponses::TYPE_RSS - ]))->run(); + ]))->run($this->httpExceptionMock); self::assertEquals(ICanCreateResponses::TYPE_RSS, $response->getHeaderLine(ICanCreateResponses::X_HEADER)); diff --git a/tests/src/Module/Api/Twitter/Followers/ListsTest.php b/tests/src/Module/Api/Twitter/Followers/ListsTest.php index 02e2745492..f48916ce80 100644 --- a/tests/src/Module/Api/Twitter/Followers/ListsTest.php +++ b/tests/src/Module/Api/Twitter/Followers/ListsTest.php @@ -34,7 +34,7 @@ class ListsTest extends ApiTest public function testApiStatusesFWithFollowers() { $response = (new Lists(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); $json = $this->toJson($response); diff --git a/tests/src/Module/Api/Twitter/Friends/ListsTest.php b/tests/src/Module/Api/Twitter/Friends/ListsTest.php index 07fdc891f3..53d8d8d866 100644 --- a/tests/src/Module/Api/Twitter/Friends/ListsTest.php +++ b/tests/src/Module/Api/Twitter/Friends/ListsTest.php @@ -36,7 +36,7 @@ class ListsTest extends ApiTest public function testApiStatusesFWithFriends() { $response = (new Lists(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); $json = $this->toJson($response); diff --git a/tests/src/Module/Api/Twitter/Friendships/IncomingTest.php b/tests/src/Module/Api/Twitter/Friendships/IncomingTest.php index 89a296b066..f93375b14e 100644 --- a/tests/src/Module/Api/Twitter/Friendships/IncomingTest.php +++ b/tests/src/Module/Api/Twitter/Friendships/IncomingTest.php @@ -36,7 +36,7 @@ class IncomingTest extends ApiTest public function testApiFriendshipsIncoming() { $response = (new Incoming(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); $json = $this->toJson($response); diff --git a/tests/src/Module/Api/Twitter/Lists/StatusesTest.php b/tests/src/Module/Api/Twitter/Lists/StatusesTest.php index 8bc8257c0c..f642181533 100644 --- a/tests/src/Module/Api/Twitter/Lists/StatusesTest.php +++ b/tests/src/Module/Api/Twitter/Lists/StatusesTest.php @@ -39,7 +39,7 @@ class StatusesTest extends ApiTest $this->expectException(BadRequestException::class); (new Statuses(DI::dba(), DI::twitterStatus(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); } /** @@ -48,7 +48,7 @@ class StatusesTest extends ApiTest public function testApiListsStatusesWithListId() { $response = (new Statuses(DI::dba(), DI::twitterStatus(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'list_id' => 1, 'page' => -1, 'max_id' => 10 @@ -68,7 +68,7 @@ class StatusesTest extends ApiTest public function testApiListsStatusesWithListIdAndRss() { $response = (new Statuses(DI::dba(), DI::twitterStatus(), DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'rss'])) - ->run([ + ->run($this->httpExceptionMock, [ 'list_id' => 1 ]); diff --git a/tests/src/Module/Api/Twitter/Media/UploadTest.php b/tests/src/Module/Api/Twitter/Media/UploadTest.php index 7d64971917..f1930e2444 100644 --- a/tests/src/Module/Api/Twitter/Media/UploadTest.php +++ b/tests/src/Module/Api/Twitter/Media/UploadTest.php @@ -47,7 +47,7 @@ class UploadTest extends ApiTest $this->expectException(BadRequestException::class); (new Upload(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); } /** @@ -61,7 +61,7 @@ class UploadTest extends ApiTest AuthTestConfig::$authenticated = false; (new Upload(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); } /** @@ -80,7 +80,7 @@ class UploadTest extends ApiTest ]; (new Upload(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); } /** @@ -103,7 +103,7 @@ class UploadTest extends ApiTest ]; $response = (new Upload(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); $media = $this->toJson($response); diff --git a/tests/src/Module/Api/Twitter/SavedSearchesTest.php b/tests/src/Module/Api/Twitter/SavedSearchesTest.php index 1d6e140bd1..ab03919c99 100644 --- a/tests/src/Module/Api/Twitter/SavedSearchesTest.php +++ b/tests/src/Module/Api/Twitter/SavedSearchesTest.php @@ -31,7 +31,7 @@ class SavedSearchesTest extends ApiTest public function test() { $response = (new SavedSearches(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json'])) - ->run(); + ->run($this->httpExceptionMock); $result = $this->toJson($response); diff --git a/tests/src/Module/Api/Twitter/Statuses/DestroyTest.php b/tests/src/Module/Api/Twitter/Statuses/DestroyTest.php index 68ec195ce3..4a29525578 100644 --- a/tests/src/Module/Api/Twitter/Statuses/DestroyTest.php +++ b/tests/src/Module/Api/Twitter/Statuses/DestroyTest.php @@ -46,7 +46,7 @@ class DestroyTest extends ApiTest $this->expectException(BadRequestException::class); (new Destroy(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); } /** @@ -72,7 +72,7 @@ class DestroyTest extends ApiTest public function testApiStatusesDestroyWithId() { $response = (new Destroy(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'id' => 1 ]); diff --git a/tests/src/Module/Api/Twitter/Statuses/MentionsTest.php b/tests/src/Module/Api/Twitter/Statuses/MentionsTest.php index 0bb694528d..59daef80c7 100644 --- a/tests/src/Module/Api/Twitter/Statuses/MentionsTest.php +++ b/tests/src/Module/Api/Twitter/Statuses/MentionsTest.php @@ -37,7 +37,7 @@ class MentionsTest extends ApiTest public function testApiStatusesMentions() { $response = (new Mentions(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'max_id' => 10 ]); @@ -55,7 +55,7 @@ class MentionsTest extends ApiTest public function testApiStatusesMentionsWithNegativePage() { $response = (new Mentions(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'page' => -2 ]); @@ -87,7 +87,7 @@ class MentionsTest extends ApiTest public function testApiStatusesMentionsWithRss() { $response = (new Mentions(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => ICanCreateResponses::TYPE_RSS])) - ->run([ + ->run($this->httpExceptionMock, [ 'page' => -2 ]); diff --git a/tests/src/Module/Api/Twitter/Statuses/NetworkPublicTimelineTest.php b/tests/src/Module/Api/Twitter/Statuses/NetworkPublicTimelineTest.php index a09cd44d1e..542cb28bac 100644 --- a/tests/src/Module/Api/Twitter/Statuses/NetworkPublicTimelineTest.php +++ b/tests/src/Module/Api/Twitter/Statuses/NetworkPublicTimelineTest.php @@ -37,7 +37,7 @@ class NetworkPublicTimelineTest extends ApiTest public function testApiStatusesNetworkpublicTimeline() { $response = (new NetworkPublicTimeline(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'max_id' => 10 ]); @@ -59,7 +59,7 @@ class NetworkPublicTimelineTest extends ApiTest public function testApiStatusesNetworkpublicTimelineWithNegativePage() { $response = (new NetworkPublicTimeline(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'page' => -2 ]); @@ -96,7 +96,7 @@ class NetworkPublicTimelineTest extends ApiTest { $response = (new NetworkPublicTimeline(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], [ 'extension' => ICanCreateResponses::TYPE_RSS - ]))->run([ + ]))->run($this->httpExceptionMock, [ 'page' => -2 ]); diff --git a/tests/src/Module/Api/Twitter/Statuses/RetweetTest.php b/tests/src/Module/Api/Twitter/Statuses/RetweetTest.php index f2c99baa8f..9f498b6920 100644 --- a/tests/src/Module/Api/Twitter/Statuses/RetweetTest.php +++ b/tests/src/Module/Api/Twitter/Statuses/RetweetTest.php @@ -46,7 +46,7 @@ class RetweetTest extends ApiTest $this->expectException(BadRequestException::class); (new Retweet(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); } /** @@ -72,7 +72,7 @@ class RetweetTest extends ApiTest public function testApiStatusesRepeatWithId() { $response = (new Retweet(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'id' => 1 ]); @@ -89,7 +89,7 @@ class RetweetTest extends ApiTest public function testApiStatusesRepeatWithSharedId() { $response = (new Retweet(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'id' => 5 ]); diff --git a/tests/src/Module/Api/Twitter/Statuses/ShowTest.php b/tests/src/Module/Api/Twitter/Statuses/ShowTest.php index 656aa5e91a..df284df2ae 100644 --- a/tests/src/Module/Api/Twitter/Statuses/ShowTest.php +++ b/tests/src/Module/Api/Twitter/Statuses/ShowTest.php @@ -40,7 +40,7 @@ class ShowTest extends ApiTest (new Show(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); } /** @@ -51,7 +51,7 @@ class ShowTest extends ApiTest public function testApiStatusesShowWithId() { $response = (new Show(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'id' => 1 ]); @@ -69,7 +69,7 @@ class ShowTest extends ApiTest public function testApiStatusesShowWithConversation() { $response = (new Show(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'id' => 1, 'conversation' => 1 ]); diff --git a/tests/src/Module/Api/Twitter/Statuses/UpdateTest.php b/tests/src/Module/Api/Twitter/Statuses/UpdateTest.php index 92ca0702e3..4754a34d7e 100644 --- a/tests/src/Module/Api/Twitter/Statuses/UpdateTest.php +++ b/tests/src/Module/Api/Twitter/Statuses/UpdateTest.php @@ -55,7 +55,7 @@ class UpdateTest extends ApiTest ]; $response = (new Update(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'status' => 'Status content #friendica', 'in_reply_to_status_id' => 0, 'lat' => 48, @@ -77,7 +77,7 @@ class UpdateTest extends ApiTest public function testApiStatusesUpdateWithHtml() { $response = (new Update(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'htmlstatus' => 'Status content', ]); diff --git a/tests/src/Module/Api/Twitter/Statuses/UserTimelineTest.php b/tests/src/Module/Api/Twitter/Statuses/UserTimelineTest.php index 078a88f96f..240ebc8e8e 100644 --- a/tests/src/Module/Api/Twitter/Statuses/UserTimelineTest.php +++ b/tests/src/Module/Api/Twitter/Statuses/UserTimelineTest.php @@ -37,7 +37,7 @@ class UserTimelineTest extends ApiTest public function testApiStatusesUserTimeline() { $response = (new UserTimeline(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'user_id' => 42, 'max_id' => 10, 'exclude_replies' => true, @@ -62,7 +62,7 @@ class UserTimelineTest extends ApiTest public function testApiStatusesUserTimelineWithNegativePage() { $response = (new UserTimeline(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'user_id' => 42, 'page' => -2, ]); @@ -86,7 +86,7 @@ class UserTimelineTest extends ApiTest { $response = (new UserTimeline(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], [ 'extension' => ICanCreateResponses::TYPE_RSS - ]))->run(); + ]))->run($this->httpExceptionMock); self::assertEquals(ICanCreateResponses::TYPE_RSS, $response->getHeaderLine(ICanCreateResponses::X_HEADER)); diff --git a/tests/src/Module/Api/Twitter/Users/LookupTest.php b/tests/src/Module/Api/Twitter/Users/LookupTest.php index 9b5134fd8a..677e53df55 100644 --- a/tests/src/Module/Api/Twitter/Users/LookupTest.php +++ b/tests/src/Module/Api/Twitter/Users/LookupTest.php @@ -39,7 +39,7 @@ class LookupTest extends ApiTest $this->expectException(NotFoundException::class); (new Lookup(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); } /** @@ -50,7 +50,7 @@ class LookupTest extends ApiTest public function testApiUsersLookupWithUserId() { $respone = (new Lookup(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'user_id' => static::OTHER_USER['id'] ]); diff --git a/tests/src/Module/Api/Twitter/Users/SearchTest.php b/tests/src/Module/Api/Twitter/Users/SearchTest.php index 903bbe9fda..0c816b5ab9 100644 --- a/tests/src/Module/Api/Twitter/Users/SearchTest.php +++ b/tests/src/Module/Api/Twitter/Users/SearchTest.php @@ -38,7 +38,7 @@ class SearchTest extends ApiTest public function testApiUsersSearch() { $respone = (new Search(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run([ + ->run($this->httpExceptionMock, [ 'q' => static::OTHER_USER['name'] ]); @@ -56,7 +56,7 @@ class SearchTest extends ApiTest { $respone = (new Search(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], [ 'extension' => ICanCreateResponses::TYPE_XML - ]))->run([ + ]))->run($this->httpExceptionMock, [ 'q' => static::OTHER_USER['name'] ]); @@ -73,6 +73,6 @@ class SearchTest extends ApiTest $this->expectException(BadRequestException::class); (new Search(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); } } diff --git a/tests/src/Module/Api/Twitter/Users/ShowTest.php b/tests/src/Module/Api/Twitter/Users/ShowTest.php index 703ad4f6cb..3cec455352 100644 --- a/tests/src/Module/Api/Twitter/Users/ShowTest.php +++ b/tests/src/Module/Api/Twitter/Users/ShowTest.php @@ -37,7 +37,7 @@ class ShowTest extends ApiTest public function testApiUsersShow() { $response = (new Show(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [])) - ->run(); + ->run($this->httpExceptionMock); $json = $this->toJson($response); @@ -58,7 +58,7 @@ class ShowTest extends ApiTest { $response = (new Show(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], [ 'extension' => ICanCreateResponses::TYPE_XML - ]))->run(); + ]))->run($this->httpExceptionMock); self::assertEquals(ICanCreateResponses::TYPE_XML, $response->getHeaderLine(ICanCreateResponses::X_HEADER)); diff --git a/tests/src/Module/NodeInfoTest.php b/tests/src/Module/NodeInfoTest.php index a7766d2472..101ee021c7 100644 --- a/tests/src/Module/NodeInfoTest.php +++ b/tests/src/Module/NodeInfoTest.php @@ -27,14 +27,26 @@ use Friendica\DI; use Friendica\Module\NodeInfo110; use Friendica\Module\NodeInfo120; use Friendica\Module\NodeInfo210; +use Friendica\Module\Special\HTTPException; use Friendica\Test\FixtureTest; +use Mockery\MockInterface; class NodeInfoTest extends FixtureTest { + /** @var MockInterface|HTTPException */ + protected $httpExceptionMock; + + protected function setUp(): void + { + parent::setUp(); + + $this->httpExceptionMock = \Mockery::mock(HTTPException::class); + } + public function testNodeInfo110() { $response = (new NodeInfo110(DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), DI::config(), [])) - ->run(); + ->run($this->httpExceptionMock); self::assertJson($response->getBody()); self::assertEquals(['Content-type' => ['application/json'], ICanCreateResponses::X_HEADER => ['json']], $response->getHeaders()); @@ -55,7 +67,7 @@ class NodeInfoTest extends FixtureTest public function testNodeInfo120() { $response = (new NodeInfo120(DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), DI::config(), [])) - ->run(); + ->run($this->httpExceptionMock); self::assertJson($response->getBody()); self::assertEquals(['Content-type' => ['application/json; charset=utf-8'], ICanCreateResponses::X_HEADER => ['json']], $response->getHeaders()); @@ -75,7 +87,7 @@ class NodeInfoTest extends FixtureTest public function testNodeInfo210() { $response = (new NodeInfo210(DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), DI::config(), [])) - ->run(); + ->run($this->httpExceptionMock); self::assertJson($response->getBody()); self::assertEquals(['Content-type' => ['application/json; charset=utf-8'], ICanCreateResponses::X_HEADER => ['json']], $response->getHeaders()); diff --git a/tests/src/Module/Special/OptionsTest.php b/tests/src/Module/Special/OptionsTest.php index 62ad1b3de2..cd16720505 100644 --- a/tests/src/Module/Special/OptionsTest.php +++ b/tests/src/Module/Special/OptionsTest.php @@ -24,16 +24,28 @@ namespace Friendica\Test\src\Module\Special; use Friendica\App\Router; use Friendica\Capabilities\ICanCreateResponses; use Friendica\DI; +use Friendica\Module\Special\HTTPException; use Friendica\Module\Special\Options; use Friendica\Test\FixtureTest; +use Mockery\MockInterface; class OptionsTest extends FixtureTest { + /** @var MockInterface|HTTPException */ + protected $httpExceptionMock; + + protected function setUp(): void + { + parent::setUp(); + + $this->httpExceptionMock = \Mockery::mock(HTTPException::class); + } + public function testOptionsAll() { $this->useHttpMethod(Router::OPTIONS); - $response = (new Options(DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), []))->run(); + $response = (new Options(DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), []))->run($this->httpExceptionMock); self::assertEmpty((string)$response->getBody()); self::assertEquals(204, $response->getStatusCode()); @@ -51,7 +63,7 @@ class OptionsTest extends FixtureTest $response = (new Options(DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], [ 'AllowedMethods' => [Router::GET, Router::POST], - ]))->run(); + ]))->run($this->httpExceptionMock); self::assertEmpty((string)$response->getBody()); self::assertEquals(204, $response->getStatusCode()); diff --git a/view/templates/exception.tpl b/view/templates/exception.tpl index ad1a15f878..3499a5cb15 100644 --- a/view/templates/exception.tpl +++ b/view/templates/exception.tpl @@ -7,6 +7,9 @@ {{$stack_trace}} {{$trace}} {{/if}} +{{if $request_id}} +
Request: {{$request_id}}
+{{/if}} {{if $back}}

{{/if}} diff --git a/view/templates/http_status.tpl b/view/templates/http_status.tpl index a9c094c4b2..874bf96691 100644 --- a/view/templates/http_status.tpl +++ b/view/templates/http_status.tpl @@ -8,5 +8,8 @@ {{if $trace}}
{{$trace nofilter}}
{{/if}} + {{if $request_id}} +
Request: {{$request_id}}
+ {{/if}} From 1dfe0fc6034cf48b4c6d844766c07a242a8e6aa6 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 25 Dec 2022 20:43:08 +0100 Subject: [PATCH 0053/1145] adapt examples --- mods/sample-nginx-reverse-proxy.config | 20 ++++++++++++++++++++ mods/sample-nginx.config | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/mods/sample-nginx-reverse-proxy.config b/mods/sample-nginx-reverse-proxy.config index afc74dfc4a..e5faa64034 100644 --- a/mods/sample-nginx-reverse-proxy.config +++ b/mods/sample-nginx-reverse-proxy.config @@ -15,6 +15,25 @@ # ----- ... + +## +# by https://syshero.org/2018-04-13-nginx-unique-request-identifier/ +# if X-Request-ID is set, NGINX will forward the same value to the next upstream +# if the header is not set, NGINX will generate a random request identifier and add it to the request. +# +# To guarantee backward compatibility, map to format the $request_id variable to a format that matches any old setups. +## + +map $request_id $formatted_id { + "~*(?[0-9a-f]{8})(?[0-9a-f]{4})(?[0-9a-f]{4})(?[0-9a-f]{4})(?.*)$" "${p1}-${p2}-${p3}-${p4}-${p5}"; +} + +map $http_x_request_id $uuid { + default "${request_id}"; + ~* "${http_x_request_id}"; +} + + server { ... @@ -30,6 +49,7 @@ server { proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Forwarded "for=$proxy_add_x_forwarded_for; proto=$scheme"; + proxy_set_header X-Request-ID $uuid; } ... diff --git a/mods/sample-nginx.config b/mods/sample-nginx.config index 5530bfaefd..88edf19162 100644 --- a/mods/sample-nginx.config +++ b/mods/sample-nginx.config @@ -20,6 +20,24 @@ # http://wiki.nginx.org/Configuration ## +## +# by https://syshero.org/2018-04-13-nginx-unique-request-identifier/ +# if X-Request-ID is set, NGINX will forward the same value to the next upstream +# if the header is not set, NGINX will generate a random request identifier and add it to the request. +# +# To guarantee backward compatibility, map to format the $request_id variable to a format that matches any old setups. +## + +map $request_id $formatted_id { + "~*(?[0-9a-f]{8})(?[0-9a-f]{4})(?[0-9a-f]{4})(?[0-9a-f]{4})(?.*)$" "${p1}-${p2}-${p3}-${p4}-${p5}"; +} + +map $http_x_request_id $uuid { + default "${request_id}"; + ~* "${http_x_request_id}"; +} + + ## # This configuration assumes your domain is example.net # You have a separate subdomain friendica.example.net @@ -80,6 +98,9 @@ server { client_max_body_size 20m; client_body_buffer_size 128k; + # add the request id header to show it in the HTTP header output + add_header X-Request-ID $uuid; + # rewrite to front controller as default rule location / { try_files $uri /index.php?pagename=$uri&$args; @@ -125,6 +146,7 @@ server { include fastcgi_params; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param HTTP_X_REQUEST_ID $uuid; fastcgi_buffers 16 16k; fastcgi_buffer_size 32k; From 45fce5c15e3f38e3e55c7466e45dffc729fd3517 Mon Sep 17 00:00:00 2001 From: MarekBenjamin <117765478+MarekBenjamin@users.noreply.github.com> Date: Tue, 27 Dec 2022 15:00:25 +0100 Subject: [PATCH 0054/1145] Update sample-nginx-certbot.config in accordance to https://github.com/friendica/friendica/commit/1dfe0fc6034cf48b4c6d844766c07a242a8e6aa6 --- mods/sample-nginx-certbot.config | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/mods/sample-nginx-certbot.config b/mods/sample-nginx-certbot.config index 1e081404f8..280bb2ab60 100644 --- a/mods/sample-nginx-certbot.config +++ b/mods/sample-nginx-certbot.config @@ -36,6 +36,23 @@ # You have Friendica installed in /var/www/friendica ## +## +# by https://syshero.org/2018-04-13-nginx-unique-request-identifier/ +# if X-Request-ID is set, NGINX will forward the same value to the next upstream +# if the header is not set, NGINX will generate a random request identifier and add it to the request. +# +# To guarantee backward compatibility, map to format the $request_id variable to a format that matches any old setups. +## + +map $request_id $formatted_id { + "~*(?[0-9a-f]{8})(?[0-9a-f]{4})(?[0-9a-f]{4})(?[0-9a-f]{4})(?.*)$" "${p1}-${p2}-${p3}-${p4}-${p5}"; +} + +map $http_x_request_id $uuid { + default "${request_id}"; + ~* "${http_x_request_id}"; +} + server { listen 80; server_name friendica.example.net; @@ -59,6 +76,9 @@ server { # allow uploads up to 20MB in size client_max_body_size 20m; client_body_buffer_size 128k; + + # add the request id header to show it in the HTTP header output + add_header X-Request-ID $uuid; # rewrite to front controller as default rule location / { @@ -105,6 +125,8 @@ server { include fastcgi_params; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + + fastcgi_param HTTP_X_REQUEST_ID $uuid; fastcgi_buffers 16 16k; fastcgi_buffer_size 32k; From ca0e3e3db72c4120a194c3e213690b597cbb95e9 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 27 Dec 2022 16:14:04 +0000 Subject: [PATCH 0055/1145] Distribute forum comments only via the forum --- src/Core/Protocol.php | 2 +- src/Protocol/ActivityPub/Transmitter.php | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Core/Protocol.php b/src/Core/Protocol.php index 25955abd50..e4490da732 100644 --- a/src/Core/Protocol.php +++ b/src/Core/Protocol.php @@ -52,7 +52,6 @@ class Protocol // Supported through a connector const DIASPORA2 = 'dspc'; // Diaspora connector - const LINKEDIN = 'lnkd'; // LinkedIn const PUMPIO = 'pump'; // pump.io const STATUSNET = 'stac'; // Statusnet connector const TWITTER = 'twit'; // Twitter @@ -66,6 +65,7 @@ class Protocol // Currently unsupported const ICALENDAR = 'ical'; // iCalendar const MYSPACE = 'mysp'; // MySpace + const LINKEDIN = 'lnkd'; // LinkedIn const NEWS = 'nntp'; // Network News Transfer Protocol const PNUT = 'pnut'; // pnut.io const XMPP = 'xmpp'; // XMPP diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index 0ea11c6ad1..6b0064c3e9 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -675,6 +675,19 @@ class Transmitter $exclusive = false; + if ($is_forum_thread) { + foreach (Tag::getByURIId($item['parent-uri-id'], [Tag::MENTION, Tag::EXCLUSIVE_MENTION]) as $term) { + $profile = APContact::getByURL($term['url'], false); + if (!empty($profile) && ($profile['type'] == 'Group')) { + if ($term['type'] == Tag::EXCLUSIVE_MENTION) { + $exclusive = true; + } elseif ($term['type'] == Tag::MENTION) { + $exclusive = false; + } + } + } + } + $terms = Tag::getByURIId($item['uri-id'], [Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION]); if ($item['private'] != Item::PRIVATE) { @@ -704,6 +717,8 @@ class Transmitter if (!empty($profile['followers']) && ($profile['type'] == 'Group')) { $data['cc'][] = $profile['followers']; } + } elseif (($term['type'] == Tag::MENTION) && ($profile['type'] == 'Group')) { + $exclusive = false; } $data['to'][] = $profile['url']; } @@ -726,6 +741,8 @@ class Transmitter if (!empty($profile['followers']) && ($profile['type'] == 'Group')) { $data['cc'][] = $profile['followers']; } + } elseif (($term['type'] == Tag::MENTION) && ($profile['type'] == 'Group')) { + $exclusive = false; } $data['to'][] = $profile['url']; } From b7e461d2f38c63f7e5a27ac9b714f3ae1f6b9134 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 27 Dec 2022 17:01:40 +0000 Subject: [PATCH 0056/1145] Improved handling of forum mentions --- src/Protocol/ActivityPub/Transmitter.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index 6b0064c3e9..66ee9e4b5c 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -674,6 +674,7 @@ class Transmitter } $exclusive = false; + $mention = false; if ($is_forum_thread) { foreach (Tag::getByURIId($item['parent-uri-id'], [Tag::MENTION, Tag::EXCLUSIVE_MENTION]) as $term) { @@ -682,7 +683,7 @@ class Transmitter if ($term['type'] == Tag::EXCLUSIVE_MENTION) { $exclusive = true; } elseif ($term['type'] == Tag::MENTION) { - $exclusive = false; + $mention = true; } } } @@ -718,7 +719,7 @@ class Transmitter $data['cc'][] = $profile['followers']; } } elseif (($term['type'] == Tag::MENTION) && ($profile['type'] == 'Group')) { - $exclusive = false; + $mention = true; } $data['to'][] = $profile['url']; } @@ -742,13 +743,17 @@ class Transmitter $data['cc'][] = $profile['followers']; } } elseif (($term['type'] == Tag::MENTION) && ($profile['type'] == 'Group')) { - $exclusive = false; + $mention = true; } $data['to'][] = $profile['url']; } } } + if ($mention) { + $exclusive = false; + } + if ($is_forum && !$exclusive && !empty($follower)) { $data['cc'][] = $follower; } elseif (!$exclusive) { From c19dd39fe3d7ee586cacaff4236eef608a49a977 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Tue, 27 Dec 2022 13:24:19 -0500 Subject: [PATCH 0057/1145] Remove counter-productive role="heading" and aria-level attributes --- view/theme/frio/css/style.css | 4 ++-- view/theme/frio/templates/search_item.tpl | 4 ++-- view/theme/frio/templates/wall_thread.tpl | 2 +- view/theme/vier/templates/wall_thread.tpl | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/view/theme/frio/css/style.css b/view/theme/frio/css/style.css index e376a8dc43..3f62919e53 100644 --- a/view/theme/frio/css/style.css +++ b/view/theme/frio/css/style.css @@ -1717,13 +1717,13 @@ aside .panel-body { } /* wall items action dropdown menu */ -.media [role="heading"] { +.media .contact-info { position: relative; } /* Workaround for Firefox where the post heading covers the avatar, preventing hovercard interaction, 48px is the width of the avatar image and should be adjusted accordingly if it ever changes. */ -.media .dropdown.pull-left + [role="heading"] { +.media .dropdown.pull-left + .contact-info { margin-left: 48px; } diff --git a/view/theme/frio/templates/search_item.tpl b/view/theme/frio/templates/search_item.tpl index c3f2e8c858..5a283ce3f0 100644 --- a/view/theme/frio/templates/search_item.tpl +++ b/view/theme/frio/templates/search_item.tpl @@ -23,7 +23,7 @@ {{* contact info header*}} -