From: Art4 Date: Thu, 23 Jan 2025 12:11:18 +0000 (+0000) Subject: Rename ItemInserter into ItemHelper X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=7a2e1e0511893d07c17021971d20545b483aa6a4;p=friendica.git Rename ItemInserter into ItemHelper --- diff --git a/src/Model/Item.php b/src/Model/Item.php index 18015b700a..b0ec029563 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -760,7 +760,7 @@ class Item */ public static function insert(array $item, int $notify = 0, bool $post_local = true): int { - $itemInserter = new ItemInserter( + $itemHelper = new ItemHelper( DI::contentItem(), DI::activity(), DI::logger(), @@ -776,7 +776,7 @@ class Item // If it is a posting where users should get notifications, then define it as wall posting if ($notify) { - $item = $itemInserter->prepareOriginPost($item); + $item = $itemHelper->prepareOriginPost($item); if (is_int($notify) && in_array($notify, Worker::PRIORITIES)) { $priority = $notify; @@ -789,7 +789,7 @@ class Item $item['network'] = trim(($item['network'] ?? '') ?: Protocol::PHANTOM); } - $item = $itemInserter->prepareItemData($item, (bool) $notify); + $item = $itemHelper->prepareItemData($item, (bool) $notify); // Store conversation data $source = $item['source'] ?? ''; @@ -830,7 +830,7 @@ class Item } } - $item = $itemInserter->validateItemData($item); + $item = $itemHelper->validateItemData($item); // Ensure that there is an avatar cache Contact::checkAvatarCache($item['author-id']); @@ -851,13 +851,13 @@ class Item } if ($item['gravity'] !== self::GRAVITY_PARENT) { - $toplevel_parent = $itemInserter->getTopLevelParent($item); + $toplevel_parent = $itemHelper->getTopLevelParent($item); if (empty($toplevel_parent)) { return 0; } $parent_id = (int) $toplevel_parent['id']; - $item = $itemInserter->handleToplevelParent($item, $toplevel_parent, $defined_permissions); + $item = $itemHelper->handleToplevelParent($item, $toplevel_parent, $defined_permissions); $parent_origin = $toplevel_parent['origin']; } else { $parent_id = 0; diff --git a/src/Model/ItemHelper.php b/src/Model/ItemHelper.php new file mode 100644 index 0000000000..ab17b845a9 --- /dev/null +++ b/src/Model/ItemHelper.php @@ -0,0 +1,318 @@ +itemContent = $itemContent; + $this->activity = $activity; + $this->logger = $logger; + $this->database = $database; + $this->baseUrl = $baseURL->__toString(); + } + + public function prepareOriginPost(array $item): array + { + $item = $this->itemContent->initializePost($item); + $item = $this->itemContent->finalizePost($item, false); + + return $item; + } + + public function prepareItemData(array $item, bool $notify): array + { + $item['guid'] = Item::guid($item, $notify); + $item['uri'] = substr(trim($item['uri'] ?? '') ?: Item::newURI($item['guid']), 0, 255); + + // Store URI data + $item['uri-id'] = ItemURI::insert(['uri' => $item['uri'], 'guid' => $item['guid']]); + + // Backward compatibility: parent-uri used to be the direct parent uri. + // If it is provided without a thr-parent, it probably is the old behavior. + if (empty($item['thr-parent']) || empty($item['parent-uri'])) { + $item['thr-parent'] = trim($item['thr-parent'] ?? $item['parent-uri'] ?? $item['uri']); + $item['parent-uri'] = $item['thr-parent']; + } + + $item['thr-parent-id'] = ItemURI::getIdByURI($item['thr-parent']); + $item['parent-uri-id'] = ItemURI::getIdByURI($item['parent-uri']); + + return $item; + } + + public function validateItemData(array $item): array + { + $item['wall'] = intval($item['wall'] ?? 0); + $item['extid'] = trim($item['extid'] ?? ''); + $item['author-name'] = trim($item['author-name'] ?? ''); + $item['author-link'] = trim($item['author-link'] ?? ''); + $item['author-avatar'] = trim($item['author-avatar'] ?? ''); + $item['owner-name'] = trim($item['owner-name'] ?? ''); + $item['owner-link'] = trim($item['owner-link'] ?? ''); + $item['owner-avatar'] = trim($item['owner-avatar'] ?? ''); + $item['received'] = (isset($item['received']) ? DateTimeFormat::utc($item['received']) : DateTimeFormat::utcNow()); + $item['created'] = (isset($item['created']) ? DateTimeFormat::utc($item['created']) : $item['received']); + $item['edited'] = (isset($item['edited']) ? DateTimeFormat::utc($item['edited']) : $item['created']); + $item['changed'] = (isset($item['changed']) ? DateTimeFormat::utc($item['changed']) : $item['created']); + $item['commented'] = (isset($item['commented']) ? DateTimeFormat::utc($item['commented']) : $item['created']); + $item['title'] = substr(trim($item['title'] ?? ''), 0, 255); + $item['location'] = trim($item['location'] ?? ''); + $item['coord'] = trim($item['coord'] ?? ''); + $item['visible'] = (isset($item['visible']) ? intval($item['visible']) : 1); + $item['deleted'] = 0; + $item['verb'] = trim($item['verb'] ?? ''); + $item['object-type'] = trim($item['object-type'] ?? ''); + $item['object'] = trim($item['object'] ?? ''); + $item['target-type'] = trim($item['target-type'] ?? ''); + $item['target'] = trim($item['target'] ?? ''); + $item['plink'] = substr(trim($item['plink'] ?? ''), 0, 255); + $item['allow_cid'] = trim($item['allow_cid'] ?? ''); + $item['allow_gid'] = trim($item['allow_gid'] ?? ''); + $item['deny_cid'] = trim($item['deny_cid'] ?? ''); + $item['deny_gid'] = trim($item['deny_gid'] ?? ''); + $item['private'] = intval($item['private'] ?? Item::PUBLIC); + $item['body'] = trim($item['body'] ?? ''); + $item['raw-body'] = trim($item['raw-body'] ?? $item['body']); + $item['app'] = trim($item['app'] ?? ''); + $item['origin'] = intval($item['origin'] ?? 0); + $item['postopts'] = trim($item['postopts'] ?? ''); + $item['resource-id'] = trim($item['resource-id'] ?? ''); + $item['event-id'] = intval($item['event-id'] ?? 0); + $item['inform'] = trim($item['inform'] ?? ''); + $item['file'] = trim($item['file'] ?? ''); + + // Items cannot be stored before they happen ... + if ($item['created'] > DateTimeFormat::utcNow()) { + $item['created'] = DateTimeFormat::utcNow(); + } + + // We haven't invented time travel by now. + if ($item['edited'] > DateTimeFormat::utcNow()) { + $item['edited'] = DateTimeFormat::utcNow(); + } + + $item['plink'] = ($item['plink'] ?? '') ?: $this->baseUrl . '/display/' . urlencode($item['guid']); + + $item['gravity'] = $this->getGravity($item); + + if ($item['gravity'] === Item::GRAVITY_UNKNOWN) { + $this->logger->info('Unknown gravity for verb', ['verb' => $item['verb']]); + } + + $default = [ + 'url' => $item['author-link'], 'name' => $item['author-name'], + 'photo' => $item['author-avatar'], 'network' => $item['network'] + ]; + $item['author-id'] = ($item['author-id'] ?? 0) ?: Contact::getIdForURL($item['author-link'], 0, null, $default); + + $default = [ + 'url' => $item['owner-link'], 'name' => $item['owner-name'], + 'photo' => $item['owner-avatar'], 'network' => $item['network'] + ]; + $item['owner-id'] = ($item['owner-id'] ?? 0) ?: Contact::getIdForURL($item['owner-link'], 0, null, $default); + + $item['post-reason'] = Item::getPostReason($item); + + return $item; + } + + /** + * Fetch top-level parent data for the given item array + * + * @param array $item + * @return array item array with parent data + * @throws \Exception + */ + public function getTopLevelParent(array $item): array + { + $fields = [ + 'uid', 'uri', 'parent-uri', 'id', 'deleted', + 'uri-id', 'parent-uri-id', 'restrictions', 'verb', + 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', + 'wall', 'private', 'origin', 'author-id' + ]; + $condition = ['uri-id' => [$item['thr-parent-id'], $item['parent-uri-id']], 'uid' => $item['uid']]; + $params = ['order' => ['id' => false]]; + $parent = Post::selectFirst($fields, $condition, $params); + + if (!$this->database->isResult($parent) && Post::exists(['uri-id' => [$item['thr-parent-id'], $item['parent-uri-id']], 'uid' => 0])) { + $stored = Item::storeForUserByUriId($item['thr-parent-id'], $item['uid'], ['post-reason' => Item::PR_COMPLETION]); + if (!$stored && ($item['thr-parent-id'] != $item['parent-uri-id'])) { + $stored = Item::storeForUserByUriId($item['parent-uri-id'], $item['uid'], ['post-reason' => Item::PR_COMPLETION]); + } + if ($stored) { + $this->logger->info('Stored thread parent item for user', ['uri-id' => $item['thr-parent-id'], 'uid' => $item['uid'], 'stored' => $stored]); + $parent = Post::selectFirst($fields, $condition, $params); + } + } + + if (!$this->database->isResult($parent)) { + $this->logger->notice('item parent was not found - ignoring item', ['uri-id' => $item['uri-id'], 'thr-parent-id' => $item['thr-parent-id'], 'uid' => $item['uid']]); + return []; + } + + if ($this->hasRestrictions($item, $parent['author-id'], $parent['restrictions'])) { + $this->logger->notice('Restrictions apply - ignoring item', ['restrictions' => $parent['restrictions'], 'verb' => $parent['verb'], 'uri-id' => $item['uri-id'], 'thr-parent-id' => $item['thr-parent-id'], 'uid' => $item['uid']]); + return []; + } + + if ($parent['uri-id'] == $parent['parent-uri-id']) { + return $parent; + } + + $condition = [ + 'uri-id' => $parent['parent-uri-id'], + 'parent-uri-id' => $parent['parent-uri-id'], + 'uid' => $parent['uid'] + ]; + $params = ['order' => ['id' => false]]; + $toplevel_parent = Post::selectFirst($fields, $condition, $params); + + if (!$this->database->isResult($toplevel_parent) && $item['origin']) { + $stored = Item::storeForUserByUriId($item['parent-uri-id'], $item['uid'], ['post-reason' => Item::PR_COMPLETION]); + $this->logger->info('Stored parent item for user', ['uri-id' => $item['parent-uri-id'], 'uid' => $item['uid'], 'stored' => $stored]); + $toplevel_parent = Post::selectFirst($fields, $condition, $params); + } + + if (!$this->database->isResult($toplevel_parent)) { + $this->logger->notice('item top level parent was not found - ignoring item', ['parent-uri-id' => $parent['parent-uri-id'], 'uid' => $parent['uid']]); + return []; + } + + return $toplevel_parent; + } + + public function handleToplevelParent(array $item, array $toplevel_parent, bool $defined_permissions): array + { + $parent_id = (int) $toplevel_parent['id']; + $item['parent-uri'] = $toplevel_parent['uri']; + $item['parent-uri-id'] = $toplevel_parent['uri-id']; + $item['deleted'] = $toplevel_parent['deleted']; + $item['wall'] = $toplevel_parent['wall']; + + // Reshares have to keep their permissions to allow groups to work + if (!$defined_permissions && (!$item['origin'] || ($item['verb'] != Activity::ANNOUNCE))) { + // Don't store the permissions on pure AP posts + $store_permissions = ($item['network'] != Protocol::ACTIVITYPUB) || $item['origin'] || !empty($item['diaspora_signed_text']); + $item['allow_cid'] = $store_permissions ? $toplevel_parent['allow_cid'] : ''; + $item['allow_gid'] = $store_permissions ? $toplevel_parent['allow_gid'] : ''; + $item['deny_cid'] = $store_permissions ? $toplevel_parent['deny_cid'] : ''; + $item['deny_gid'] = $store_permissions ? $toplevel_parent['deny_gid'] : ''; + } + + // Don't federate received participation messages + if ($item['verb'] != Activity::FOLLOW) { + $item['wall'] = $toplevel_parent['wall']; + } else { + $item['wall'] = false; + // Participations are technical messages, so they are set to "seen" automatically + $item['unseen'] = false; + } + + /* + * If the parent is private, force privacy for the entire conversation + * This differs from the above settings as it subtly allows comments from + * email correspondents to be private even if the overall thread is not. + */ + if (!$defined_permissions && $toplevel_parent['private']) { + $item['private'] = $toplevel_parent['private']; + } + + // If its a post that originated here then tag the thread as "mention" + if ($item['origin'] && $item['uid']) { + $this->database->update('post-thread-user', ['mention' => true], ['uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]); + $this->logger->info('tagged thread as mention', ['parent' => $parent_id, 'parent-uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]); + } + + // Update the contact relations + Contact\Relation::store($toplevel_parent['author-id'], $item['author-id'], $item['created']); + + return $item; + } + + private function hasRestrictions(array $item, int $author_id, int $restrictions = null): bool + { + if (empty($restrictions) || ($author_id == $item['author-id'])) { + return false; + } + + // We only have to apply restrictions if the post originates from our server or is federated. + // Every other time we can trust the remote system. + if (!in_array($item['network'], Protocol::FEDERATED) && !$item['origin']) { + return false; + } + + if (($restrictions & Item::CANT_REPLY) && ($item['verb'] == Activity::POST)) { + return true; + } + + if (($restrictions & Item::CANT_ANNOUNCE) && ($item['verb'] == Activity::ANNOUNCE)) { + return true; + } + + if (($restrictions & Item::CANT_LIKE) && in_array($item['verb'], [Activity::LIKE, Activity::DISLIKE, Activity::ATTEND, Activity::ATTENDMAYBE, Activity::ATTENDNO])) { + return true; + } + + return false; + } + + /** + * Get the gravity for the given item array + * + * @return int gravity + */ + private function getGravity(array $item): int + { + if (isset($item['gravity'])) { + return intval($item['gravity']); + } elseif ($item['parent-uri-id'] === $item['uri-id']) { + return Item::GRAVITY_PARENT; + } elseif ($this->activity->match($item['verb'], Activity::POST)) { + return Item::GRAVITY_COMMENT; + } elseif ($this->activity->match($item['verb'], Activity::FOLLOW)) { + return Item::GRAVITY_ACTIVITY; + } elseif ($this->activity->match($item['verb'], Activity::ANNOUNCE)) { + return Item::GRAVITY_ACTIVITY; + } + + return Item::GRAVITY_UNKNOWN; // Should not happen + } +} diff --git a/src/Model/ItemInserter.php b/src/Model/ItemInserter.php deleted file mode 100644 index fc042bb04b..0000000000 --- a/src/Model/ItemInserter.php +++ /dev/null @@ -1,318 +0,0 @@ -itemContent = $itemContent; - $this->activity = $activity; - $this->logger = $logger; - $this->database = $database; - $this->baseUrl = $baseURL->__toString(); - } - - public function prepareOriginPost(array $item): array - { - $item = $this->itemContent->initializePost($item); - $item = $this->itemContent->finalizePost($item, false); - - return $item; - } - - public function prepareItemData(array $item, bool $notify): array - { - $item['guid'] = Item::guid($item, $notify); - $item['uri'] = substr(trim($item['uri'] ?? '') ?: Item::newURI($item['guid']), 0, 255); - - // Store URI data - $item['uri-id'] = ItemURI::insert(['uri' => $item['uri'], 'guid' => $item['guid']]); - - // Backward compatibility: parent-uri used to be the direct parent uri. - // If it is provided without a thr-parent, it probably is the old behavior. - if (empty($item['thr-parent']) || empty($item['parent-uri'])) { - $item['thr-parent'] = trim($item['thr-parent'] ?? $item['parent-uri'] ?? $item['uri']); - $item['parent-uri'] = $item['thr-parent']; - } - - $item['thr-parent-id'] = ItemURI::getIdByURI($item['thr-parent']); - $item['parent-uri-id'] = ItemURI::getIdByURI($item['parent-uri']); - - return $item; - } - - public function validateItemData(array $item): array - { - $item['wall'] = intval($item['wall'] ?? 0); - $item['extid'] = trim($item['extid'] ?? ''); - $item['author-name'] = trim($item['author-name'] ?? ''); - $item['author-link'] = trim($item['author-link'] ?? ''); - $item['author-avatar'] = trim($item['author-avatar'] ?? ''); - $item['owner-name'] = trim($item['owner-name'] ?? ''); - $item['owner-link'] = trim($item['owner-link'] ?? ''); - $item['owner-avatar'] = trim($item['owner-avatar'] ?? ''); - $item['received'] = (isset($item['received']) ? DateTimeFormat::utc($item['received']) : DateTimeFormat::utcNow()); - $item['created'] = (isset($item['created']) ? DateTimeFormat::utc($item['created']) : $item['received']); - $item['edited'] = (isset($item['edited']) ? DateTimeFormat::utc($item['edited']) : $item['created']); - $item['changed'] = (isset($item['changed']) ? DateTimeFormat::utc($item['changed']) : $item['created']); - $item['commented'] = (isset($item['commented']) ? DateTimeFormat::utc($item['commented']) : $item['created']); - $item['title'] = substr(trim($item['title'] ?? ''), 0, 255); - $item['location'] = trim($item['location'] ?? ''); - $item['coord'] = trim($item['coord'] ?? ''); - $item['visible'] = (isset($item['visible']) ? intval($item['visible']) : 1); - $item['deleted'] = 0; - $item['verb'] = trim($item['verb'] ?? ''); - $item['object-type'] = trim($item['object-type'] ?? ''); - $item['object'] = trim($item['object'] ?? ''); - $item['target-type'] = trim($item['target-type'] ?? ''); - $item['target'] = trim($item['target'] ?? ''); - $item['plink'] = substr(trim($item['plink'] ?? ''), 0, 255); - $item['allow_cid'] = trim($item['allow_cid'] ?? ''); - $item['allow_gid'] = trim($item['allow_gid'] ?? ''); - $item['deny_cid'] = trim($item['deny_cid'] ?? ''); - $item['deny_gid'] = trim($item['deny_gid'] ?? ''); - $item['private'] = intval($item['private'] ?? Item::PUBLIC); - $item['body'] = trim($item['body'] ?? ''); - $item['raw-body'] = trim($item['raw-body'] ?? $item['body']); - $item['app'] = trim($item['app'] ?? ''); - $item['origin'] = intval($item['origin'] ?? 0); - $item['postopts'] = trim($item['postopts'] ?? ''); - $item['resource-id'] = trim($item['resource-id'] ?? ''); - $item['event-id'] = intval($item['event-id'] ?? 0); - $item['inform'] = trim($item['inform'] ?? ''); - $item['file'] = trim($item['file'] ?? ''); - - // Items cannot be stored before they happen ... - if ($item['created'] > DateTimeFormat::utcNow()) { - $item['created'] = DateTimeFormat::utcNow(); - } - - // We haven't invented time travel by now. - if ($item['edited'] > DateTimeFormat::utcNow()) { - $item['edited'] = DateTimeFormat::utcNow(); - } - - $item['plink'] = ($item['plink'] ?? '') ?: $this->baseUrl . '/display/' . urlencode($item['guid']); - - $item['gravity'] = $this->getGravity($item); - - if ($item['gravity'] === Item::GRAVITY_UNKNOWN) { - $this->logger->info('Unknown gravity for verb', ['verb' => $item['verb']]); - } - - $default = [ - 'url' => $item['author-link'], 'name' => $item['author-name'], - 'photo' => $item['author-avatar'], 'network' => $item['network'] - ]; - $item['author-id'] = ($item['author-id'] ?? 0) ?: Contact::getIdForURL($item['author-link'], 0, null, $default); - - $default = [ - 'url' => $item['owner-link'], 'name' => $item['owner-name'], - 'photo' => $item['owner-avatar'], 'network' => $item['network'] - ]; - $item['owner-id'] = ($item['owner-id'] ?? 0) ?: Contact::getIdForURL($item['owner-link'], 0, null, $default); - - $item['post-reason'] = Item::getPostReason($item); - - return $item; - } - - /** - * Fetch top-level parent data for the given item array - * - * @param array $item - * @return array item array with parent data - * @throws \Exception - */ - public function getTopLevelParent(array $item): array - { - $fields = [ - 'uid', 'uri', 'parent-uri', 'id', 'deleted', - 'uri-id', 'parent-uri-id', 'restrictions', 'verb', - 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', - 'wall', 'private', 'origin', 'author-id' - ]; - $condition = ['uri-id' => [$item['thr-parent-id'], $item['parent-uri-id']], 'uid' => $item['uid']]; - $params = ['order' => ['id' => false]]; - $parent = Post::selectFirst($fields, $condition, $params); - - if (!$this->database->isResult($parent) && Post::exists(['uri-id' => [$item['thr-parent-id'], $item['parent-uri-id']], 'uid' => 0])) { - $stored = Item::storeForUserByUriId($item['thr-parent-id'], $item['uid'], ['post-reason' => Item::PR_COMPLETION]); - if (!$stored && ($item['thr-parent-id'] != $item['parent-uri-id'])) { - $stored = Item::storeForUserByUriId($item['parent-uri-id'], $item['uid'], ['post-reason' => Item::PR_COMPLETION]); - } - if ($stored) { - $this->logger->info('Stored thread parent item for user', ['uri-id' => $item['thr-parent-id'], 'uid' => $item['uid'], 'stored' => $stored]); - $parent = Post::selectFirst($fields, $condition, $params); - } - } - - if (!$this->database->isResult($parent)) { - $this->logger->notice('item parent was not found - ignoring item', ['uri-id' => $item['uri-id'], 'thr-parent-id' => $item['thr-parent-id'], 'uid' => $item['uid']]); - return []; - } - - if ($this->hasRestrictions($item, $parent['author-id'], $parent['restrictions'])) { - $this->logger->notice('Restrictions apply - ignoring item', ['restrictions' => $parent['restrictions'], 'verb' => $parent['verb'], 'uri-id' => $item['uri-id'], 'thr-parent-id' => $item['thr-parent-id'], 'uid' => $item['uid']]); - return []; - } - - if ($parent['uri-id'] == $parent['parent-uri-id']) { - return $parent; - } - - $condition = [ - 'uri-id' => $parent['parent-uri-id'], - 'parent-uri-id' => $parent['parent-uri-id'], - 'uid' => $parent['uid'] - ]; - $params = ['order' => ['id' => false]]; - $toplevel_parent = Post::selectFirst($fields, $condition, $params); - - if (!$this->database->isResult($toplevel_parent) && $item['origin']) { - $stored = Item::storeForUserByUriId($item['parent-uri-id'], $item['uid'], ['post-reason' => Item::PR_COMPLETION]); - $this->logger->info('Stored parent item for user', ['uri-id' => $item['parent-uri-id'], 'uid' => $item['uid'], 'stored' => $stored]); - $toplevel_parent = Post::selectFirst($fields, $condition, $params); - } - - if (!$this->database->isResult($toplevel_parent)) { - $this->logger->notice('item top level parent was not found - ignoring item', ['parent-uri-id' => $parent['parent-uri-id'], 'uid' => $parent['uid']]); - return []; - } - - return $toplevel_parent; - } - - public function handleToplevelParent(array $item, array $toplevel_parent, bool $defined_permissions): array - { - $parent_id = (int) $toplevel_parent['id']; - $item['parent-uri'] = $toplevel_parent['uri']; - $item['parent-uri-id'] = $toplevel_parent['uri-id']; - $item['deleted'] = $toplevel_parent['deleted']; - $item['wall'] = $toplevel_parent['wall']; - - // Reshares have to keep their permissions to allow groups to work - if (!$defined_permissions && (!$item['origin'] || ($item['verb'] != Activity::ANNOUNCE))) { - // Don't store the permissions on pure AP posts - $store_permissions = ($item['network'] != Protocol::ACTIVITYPUB) || $item['origin'] || !empty($item['diaspora_signed_text']); - $item['allow_cid'] = $store_permissions ? $toplevel_parent['allow_cid'] : ''; - $item['allow_gid'] = $store_permissions ? $toplevel_parent['allow_gid'] : ''; - $item['deny_cid'] = $store_permissions ? $toplevel_parent['deny_cid'] : ''; - $item['deny_gid'] = $store_permissions ? $toplevel_parent['deny_gid'] : ''; - } - - // Don't federate received participation messages - if ($item['verb'] != Activity::FOLLOW) { - $item['wall'] = $toplevel_parent['wall']; - } else { - $item['wall'] = false; - // Participations are technical messages, so they are set to "seen" automatically - $item['unseen'] = false; - } - - /* - * If the parent is private, force privacy for the entire conversation - * This differs from the above settings as it subtly allows comments from - * email correspondents to be private even if the overall thread is not. - */ - if (!$defined_permissions && $toplevel_parent['private']) { - $item['private'] = $toplevel_parent['private']; - } - - // If its a post that originated here then tag the thread as "mention" - if ($item['origin'] && $item['uid']) { - $this->database->update('post-thread-user', ['mention' => true], ['uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]); - $this->logger->info('tagged thread as mention', ['parent' => $parent_id, 'parent-uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]); - } - - // Update the contact relations - Contact\Relation::store($toplevel_parent['author-id'], $item['author-id'], $item['created']); - - return $item; - } - - private function hasRestrictions(array $item, int $author_id, int $restrictions = null): bool - { - if (empty($restrictions) || ($author_id == $item['author-id'])) { - return false; - } - - // We only have to apply restrictions if the post originates from our server or is federated. - // Every other time we can trust the remote system. - if (!in_array($item['network'], Protocol::FEDERATED) && !$item['origin']) { - return false; - } - - if (($restrictions & Item::CANT_REPLY) && ($item['verb'] == Activity::POST)) { - return true; - } - - if (($restrictions & Item::CANT_ANNOUNCE) && ($item['verb'] == Activity::ANNOUNCE)) { - return true; - } - - if (($restrictions & Item::CANT_LIKE) && in_array($item['verb'], [Activity::LIKE, Activity::DISLIKE, Activity::ATTEND, Activity::ATTENDMAYBE, Activity::ATTENDNO])) { - return true; - } - - return false; - } - - /** - * Get the gravity for the given item array - * - * @return int gravity - */ - private function getGravity(array $item): int - { - if (isset($item['gravity'])) { - return intval($item['gravity']); - } elseif ($item['parent-uri-id'] === $item['uri-id']) { - return Item::GRAVITY_PARENT; - } elseif ($this->activity->match($item['verb'], Activity::POST)) { - return Item::GRAVITY_COMMENT; - } elseif ($this->activity->match($item['verb'], Activity::FOLLOW)) { - return Item::GRAVITY_ACTIVITY; - } elseif ($this->activity->match($item['verb'], Activity::ANNOUNCE)) { - return Item::GRAVITY_ACTIVITY; - } - - return Item::GRAVITY_UNKNOWN; // Should not happen - } -}