+ $item['uid'] == local_user())
+ );
+ }
+
+ public function expandTags(array $item, bool $setPermissions = false): array
+ {
+ // Look for any tags and linkify them
+ $item['inform'] = '';
+ $private_forum = false;
+ $private_id = null;
+ $only_to_forum = false;
+ $forum_contact = [];
+ $receivers = [];
+
+ // Convert mentions in the body to a unified format
+ $item['body'] = BBCode::setMentions($item['body'], $item['uid'], $item['network']);
+
+ // Search for forum mentions
+ foreach (Tag::getFromBody($item['body'], Tag::TAG_CHARACTER[Tag::MENTION] . Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]) as $tag) {
+ $contact = Contact::getByURLForUser($tag[2], $item['uid']);
+ if (empty($contact)) {
+ continue;
+ }
+
+ $receivers[] = $contact['id'];
+
+ if (!empty($item['inform'])) {
+ $item['inform'] .= ',';
+ }
+ $item['inform'] .= 'cid:' . $contact['id'];
+
+ if (($item['gravity'] == GRAVITY_COMMENT) || empty($contact['cid']) || ($contact['contact-type'] != Contact::TYPE_COMMUNITY)) {
+ continue;
+ }
+
+ if (!empty($contact['prv']) || ($tag[1] == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION])) {
+ $private_forum = $contact['prv'];
+ $only_to_forum = ($tag[1] == Tag::TAG_CHARACTER[Tag::EXCLUSIVE_MENTION]);
+ $private_id = $contact['id'];
+ $forum_contact = $contact;
+ Logger::info('Private forum or exclusive mention', ['url' => $tag[2], 'mention' => $tag[1]]);
+ } elseif ($item['allow_cid'] == '<' . $contact['id'] . '>') {
+ $private_forum = false;
+ $only_to_forum = true;
+ $private_id = $contact['id'];
+ $forum_contact = $contact;
+ Logger::info('Public forum', ['url' => $tag[2], 'mention' => $tag[1]]);
+ } else {
+ Logger::info('Post with forum mention will not be converted to a forum post', ['url' => $tag[2], 'mention' => $tag[1]]);
+ }
+ }
+ Logger::info('Got inform', ['inform' => $item['inform']]);
+
+ if (($item['gravity'] == GRAVITY_PARENT) && !empty($forum_contact) && ($private_forum || $only_to_forum)) {
+ // we tagged a forum in a top level post. Now we change the post
+ $item['private'] = $private_forum ? ModelItem::PRIVATE : ModelItem::UNLISTED;
+
+ if ($only_to_forum) {
+ $item['postopts'] = '';
+ }
+
+ $item['deny_cid'] = '';
+ $item['deny_gid'] = '';
+
+ if ($private_forum) {
+ $item['allow_cid'] = '<' . $private_id . '>';
+ $item['allow_gid'] = '<' . Group::getIdForForum($forum_contact['id']) . '>';
+ } else {
+ $item['allow_cid'] = '';
+ $item['allow_gid'] = '';
+ }
+ } elseif ($setPermissions && ($item['gravity'] == GRAVITY_PARENT)) {
+ if (empty($receivers)) {
+ // For security reasons direct posts without any receiver will be posts to yourself
+ $self = Contact::selectFirst(['id'], ['uid' => $item['uid'], 'self' => true]);
+ $receivers[] = $self['id'];
+ }
+
+ $item['private'] = ModelItem::PRIVATE;
+ $item['allow_cid'] = '';
+ $item['allow_gid'] = '';
+ $item['deny_cid'] = '';
+ $item['deny_gid'] = '';
+
+ foreach ($receivers as $receiver) {
+ $item['allow_cid'] .= '<' . $receiver . '>';
+ }
+ }
+ return $item;
+ }
+
+ public function getAuthorAvatar(array $item): string
+ {
+ if (in_array($item['network'], [Protocol::FEED, Protocol::MAIL])) {
+ $author_avatar = $item['contact-id'];
+ $author_updated = '';
+ $author_thumb = $item['contact-avatar'];
+ } else {
+ $author_avatar = $item['author-id'];
+ $author_updated = $item['author-updated'];
+ $author_thumb = $item['author-avatar'];
+ }
+
+
+ if (empty($author_thumb) || Photo::isPhotoURI($author_thumb)) {
+ $author_thumb = Contact::getAvatarUrlForId($author_avatar, Proxy::SIZE_THUMB, $author_updated);
+ }
+
+ return $author_thumb;
+ }
+
+ public function getOwnerAvatar(array $item): string
+ {
+ if (in_array($item['network'], [Protocol::FEED, Protocol::MAIL])) {
+ $owner_avatar = $item['contact-id'];
+ $owner_updated = '';
+ $owner_thumb = $item['contact-avatar'];
+ } else {
+ $owner_avatar = $item['owner-id'];
+ $owner_updated = $item['owner-updated'];
+ $owner_thumb = $item['owner-avatar'];
+ }
+
+ if (empty($owner_thumb) || Photo::isPhotoURI($owner_thumb)) {
+ $owner_thumb = Contact::getAvatarUrlForId($owner_avatar, Proxy::SIZE_THUMB, $owner_updated);
+ }
+
+ return $owner_thumb;
+ }
+
+ /**
+ * Add a share block for the given url
+ *
+ * @param string $url
+ * @param integer $uid
+ * @return string
+ */
+ public function createSharedPostByUrl(string $url, int $uid = 0): string
+ {
+ if (!empty($uid)) {
+ $id = ModelItem::searchByLink($url, $uid);
+ }
+
+ if (empty($id)) {
+ $id = ModelItem::fetchByLink($url);
+ }
+
+ if (!$id) {
+ Logger::notice('Post could not be fetched.', ['url' => $url, 'uid' => $uid, 'callstack' => System::callstack()]);
+ return '';
+ }
+
+ Logger::debug('Fetched shared post', ['id' => $id, 'url' => $url, 'uid' => $uid, 'callstack' => System::callstack()]);
+
+ $shared_item = Post::selectFirst(['uri-id', 'uri', 'body', 'title', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink', 'network'], ['id' => $id]);
+ if (!DBA::isResult($shared_item)) {
+ Logger::warning('Post does not exist.', ['id' => $id, 'url' => $url, 'uid' => $uid]);
+ return '';
+ }
+
+ return $this->createSharedBlockByArray($shared_item);
+ }
+
+ /**
+ * Add a share block for the given uri-id
+ *
+ * @param integer $UriId
+ * @param integer $uid
+ * @return string
+ */
+ public function createSharedPostByUriId(int $UriId, int $uid = 0): string
+ {
+ $fields = ['uri-id', 'uri', 'body', 'title', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink', 'network'];
+ $shared_item = Post::selectFirst($fields, ['uri-id' => $UriId, 'uid' => [$uid, 0], 'private' => [ModelItem::PUBLIC, ModelItem::UNLISTED]]);
+ if (!DBA::isResult($shared_item)) {
+ Logger::notice('Post does not exist.', ['uri-id' => $UriId, 'uid' => $uid]);
+ return '';