+ /**
+ * Fetch and process parent posts for the given activity
+ *
+ * @param array $activity
+ *
+ * @return string
+ */
+ private static function fetchParent(array $activity): string
+ {
+ if (self::hasJustBeenFetched($activity['reply-to-id'])) {
+ Logger::notice('We just have tried to fetch this activity. We don\'t try it again.', ['parent' => $activity['reply-to-id']]);
+ return '';
+ }
+
+ $recursion_depth = $activity['recursion-depth'] ?? 0;
+
+ if ($recursion_depth < DI::config()->get('system', 'max_recursion_depth')) {
+ Logger::notice('Parent not found. Try to refetch it.', ['parent' => $activity['reply-to-id'], 'recursion-depth' => $recursion_depth]);
+ $result = self::fetchMissingActivity($activity['reply-to-id'], $activity, '', Receiver::COMPLETION_AUTO);
+ if (empty($result) && self::isActivityGone($activity['reply-to-id'])) {
+ Logger::notice('The activity is gone, the queue entry will be deleted', ['parent' => $activity['reply-to-id']]);
+ if (!empty($activity['entry-id'])) {
+ Queue::deleteById($activity['entry-id']);
+ }
+ return '';
+ } elseif (!empty($result)) {
+ $exists = Post::exists(['uri' => [$result, $activity['reply-to-id']]]);
+ if ($exists) {
+ Logger::notice('The activity has been fetched and created.', ['parent' => $result]);
+ return $result;
+ } elseif (DI::config()->get('system', 'fetch_by_worker') || DI::config()->get('system', 'decoupled_receiver')) {
+ Logger::notice('The activity has been fetched and will hopefully be created later.', ['parent' => $result]);
+ } else {
+ Logger::notice('The activity exists but has not been created, the queue entry will be deleted.', ['parent' => $result]);
+ if (!empty($activity['entry-id'])) {
+ Queue::deleteById($activity['entry-id']);
+ }
+ }
+ return '';
+ }
+ if (empty($result) && !DI::config()->get('system', 'fetch_by_worker')) {
+ return '';
+ }
+ } elseif (self::isActivityGone($activity['reply-to-id'])) {
+ Logger::notice('The activity is gone. We will not spawn a worker. The queue entry will be deleted', ['parent' => $activity['reply-to-id']]);
+ if (!empty($activity['entry-id'])) {
+ Queue::deleteById($activity['entry-id']);
+ }
+ return '';
+ } else {
+ Logger::notice('Recursion level is too high.', ['parent' => $activity['reply-to-id'], 'recursion-depth' => $recursion_depth]);
+ }
+
+ if (Queue::hasWorker($activity['worker-id'] ?? 0)) {
+ Logger::notice('There is already a worker task to fetch the post.', ['id' => $activity['id'], 'parent' => $activity['reply-to-id']]);
+ return '';
+ }
+
+ if (!Fetch::hasWorker($activity['reply-to-id'])) {
+ Logger::notice('Fetching is done by worker.', ['parent' => $activity['reply-to-id'], 'recursion-depth' => $recursion_depth]);
+ Fetch::add($activity['reply-to-id']);
+ $activity['recursion-depth'] = 0;
+ $wid = Worker::add(PRIORITY_HIGH, 'FetchMissingActivity', $activity['reply-to-id'], $activity, '', Receiver::COMPLETION_AUTO);
+ Fetch::setWorkerId($activity['reply-to-id'], $wid);
+ } else {
+ Logger::debug('Activity will already be fetched via a worker.', ['url' => $activity['reply-to-id']]);
+ }
+
+ return '';
+ }
+