/**
* 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;
}
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)) {
/**
* 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;
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'] ?? '';
Logger::info('Deleting item', ['object' => $activity['object_id'], 'owner' => $owner]);
Item::markForDeletion(['uri' => $activity['object_id'], 'owner-id' => $owner]);
+ Receiver::removeFromQueue($activity);
}
/**
/**
* 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;
}
$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']]);
}
}
// 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') {
/**
* 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']);
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']]);
Logger::info('Updating profile', ['object' => $activity['object_id']]);
Contact::updateFromProbeByURL($activity['object_id']);
+ Receiver::removeFromQueue($activity);
}
/**
DBA::close($contacts);
Logger::info('Deleted contact', ['object' => $activity['object_id']]);
+ Receiver::removeFromQueue($activity);
}
/**