X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FProtocol%2FActivityPub%2FProcessor.php;h=6e81cb767f69a1e925225dc432c84cc12739f973;hb=a676cf8bed6075bf33642dc3351c7d057dcbaa29;hp=c2333004f517ec79e797b4dcd89add995e0beb48;hpb=c2e889cfaeaa1b35333750cd6beda4090ee99f84;p=friendica.git diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index c2333004f5..6e81cb767f 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -189,15 +189,17 @@ class Processor /** * Updates a message * - * @param array $activity Activity array + * @param FetchQueue $fetchQueue + * @param array $activity Activity array * @throws \Friendica\Network\HTTPException\InternalServerErrorException + * @throws \ImagickException */ - public static function updateItem(array $activity) + public static function updateItem(FetchQueue $fetchQueue, array $activity) { $item = Post::selectFirst(['uri', 'uri-id', 'thr-parent', 'gravity', 'post-type'], ['uri' => $activity['id']]); if (!DBA::isResult($item)) { Logger::warning('No existing item, item will be created', ['uri' => $activity['id']]); - $item = self::createItem($activity); + $item = self::createItem($fetchQueue, $activity); if (empty($item)) { return; } @@ -221,6 +223,8 @@ class Processor Post\History::add($item['uri-id'], $item); Item::update($item, ['uri' => $activity['id']]); + Receiver::removeFromQueue($activity); + if ($activity['object_type'] == 'as:Event') { $posts = Post::select(['event-id', 'uid'], ["`uri` = ? AND `event-id` > ?", $activity['id'], 0]); while ($post = DBA::fetch($posts)) { @@ -258,12 +262,13 @@ class Processor /** * Prepares data for a message * - * @param array $activity Activity array + * @param FetchQueue $fetchQueue + * @param array $activity Activity array * @return array Internal item * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function createItem(array $activity): array + public static function createItem(FetchQueue $fetchQueue, array $activity): array { $item = []; $item['verb'] = Activity::POST; @@ -279,7 +284,12 @@ class Processor if (empty($activity['directmessage']) && ($activity['id'] != $activity['reply-to-id']) && !Post::exists(['uri' => $activity['reply-to-id']])) { Logger::notice('Parent not found. Try to refetch it.', ['parent' => $activity['reply-to-id']]); - self::fetchMissingActivity($activity['reply-to-id'], $activity, '', Receiver::COMPLETION_AUTO); + /** + * Instead of calling recursively self::fetchMissingActivity which can hit PHP's default function nesting + * limit of 256 recursive calls, we push the parent activity fetch parameters in this queue. The initial + * caller is responsible for processing the remaining queue once the original activity has been processed. + */ + $fetchQueue->push(new FetchQueueItem($activity['reply-to-id'], $activity)); } $item['diaspora_signed_text'] = $activity['diaspora:comment'] ?? ''; @@ -418,6 +428,7 @@ class Processor Logger::info('Deleting item', ['object' => $activity['object_id'], 'owner' => $owner]); Item::markForDeletion(['uri' => $activity['object_id'], 'owner-id' => $owner]); + Receiver::removeFromQueue($activity); } /** @@ -453,14 +464,15 @@ class Processor /** * Prepare the item array for an activity * - * @param array $activity Activity array - * @param string $verb Activity verb + * @param FetchQueue $fetchQueue + * @param array $activity Activity array + * @param string $verb Activity verb * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function createActivity(array $activity, string $verb) + public static function createActivity(FetchQueue $fetchQueue, array $activity, string $verb) { - $item = self::createItem($activity); + $item = self::createItem($fetchQueue, $activity); if (empty($item)) { return; } @@ -881,6 +893,7 @@ class Processor $item_id = Item::insert($item); if ($item_id) { Logger::info('Item insertion successful', ['user' => $item['uid'], 'item_id' => $item_id]); + Receiver::removeFromQueue($activity); } else { Logger::notice('Item insertion aborted', ['user' => $item['uid']]); } @@ -891,7 +904,7 @@ class Processor } // Store send a follow request for every reshare - but only when the item had been stored - if ($stored && ($item['private'] != Item::PRIVATE) && ($item['gravity'] == GRAVITY_PARENT) && ($item['author-link'] != $item['owner-link'])) { + if ($stored && ($item['private'] != Item::PRIVATE) && ($item['gravity'] == GRAVITY_PARENT) && !empty($item['author-link']) && ($item['author-link'] != $item['owner-link'])) { $author = APContact::getByURL($item['owner-link'], false); // We send automatic follow requests for reshared messages. (We don't need though for forum posts) if ($author['type'] != 'Group') { @@ -1106,14 +1119,16 @@ class Processor /** * Fetches missing posts * - * @param string $url message URL - * @param array $child activity array with the child of this message - * @param string $relay_actor Relay actor - * @param int $completion Completion mode, see Receiver::COMPLETION_* + * @param FetchQueue $fetchQueue + * @param string $url message URL + * @param array $child activity array with the child of this message + * @param string $relay_actor Relay actor + * @param int $completion Completion mode, see Receiver::COMPLETION_* * @return string fetched message URL * @throws \Friendica\Network\HTTPException\InternalServerErrorException + * @throws \ImagickException */ - public static function fetchMissingActivity(string $url, array $child = [], string $relay_actor = '', int $completion = Receiver::COMPLETION_MANUAL): string + public static function fetchMissingActivity(FetchQueue $fetchQueue, string $url, array $child = [], string $relay_actor = '', int $completion = Receiver::COMPLETION_MANUAL): string { if (!empty($child['receiver'])) { $uid = ActivityPub\Receiver::getFirstUserFromReceivers($child['receiver']); @@ -1194,7 +1209,7 @@ class Processor return ''; } - ActivityPub\Receiver::processActivity($ldactivity, json_encode($activity), $uid, true, false, $signer); + ActivityPub\Receiver::processActivity($fetchQueue, $ldactivity, json_encode($activity), $uid, true, false, $signer); Logger::notice('Activity had been fetched and processed.', ['url' => $url, 'object' => $activity['id']]); @@ -1216,7 +1231,7 @@ class Processor } $replyto = JsonLD::fetchElement($activity['as:object'], 'as:inReplyTo', '@id'); - $uriid = ItemURI::getIdByURI($replyto); + $uriid = ItemURI::getIdByURI($replyto ?? ''); if (Post::exists(['uri-id' => $uriid])) { Logger::info('Post is a reply to an existing post - accepted', ['id' => $id, 'uri-id' => $uriid, 'replyto' => $replyto]); return true; @@ -1245,6 +1260,7 @@ class Processor * perform a "follow" request * * @param array $activity + * @return void * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ @@ -1266,8 +1282,10 @@ class Processor Contact::update(['hub-verify' => $activity['id'], 'protocol' => Protocol::ACTIVITYPUB], ['id' => $cid]); } - $item = ['author-id' => Contact::getIdForURL($activity['actor']), - 'author-link' => $activity['actor']]; + $item = [ + 'author-id' => Contact::getIdForURL($activity['actor']), + 'author-link' => $activity['actor'], + ]; // Ensure that the contact has got the right network type self::switchContact($item['author-id']); @@ -1296,8 +1314,8 @@ class Processor /** * Transmit pending events to the new follower * - * @param integer $cid - * @param integer $uid + * @param integer $cid Contact id + * @param integer $uid User id * @return void */ private static function transmitPendingEvents(int $cid, int $uid) @@ -1334,12 +1352,14 @@ class Processor Logger::info('Updating profile', ['object' => $activity['object_id']]); Contact::updateFromProbeByURL($activity['object_id']); + Receiver::removeFromQueue($activity); } /** * Delete the given profile * * @param array $activity + * @return void * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ public static function deletePerson(array $activity) @@ -1361,12 +1381,14 @@ class Processor DBA::close($contacts); Logger::info('Deleted contact', ['object' => $activity['object_id']]); + Receiver::removeFromQueue($activity); } /** * Blocks the user by the contact * * @param array $activity + * @return void * @throws \Exception */ public static function blockAccount(array $activity) @@ -1390,6 +1412,7 @@ class Processor * Unblocks the user by the contact * * @param array $activity + * @return void * @throws \Exception */ public static function unblockAccount(array $activity) @@ -1541,6 +1564,7 @@ class Processor * Switches a contact to AP if needed * * @param integer $cid Contact ID + * @return void * @throws \Exception */ private static function switchContact(int $cid)