From 3c169b534e1f2bb5c530eb0c8f031a863d3b4ef0 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 29 Oct 2022 22:11:39 +0000 Subject: [PATCH] Improved handling of native quotes --- mod/item.php | 10 +- src/Content/Item.php | 131 ++++++++--------------- src/Content/Text/BBCode.php | 42 +------- src/Model/Item.php | 84 ++++++++++++--- src/Model/Post/Media.php | 14 --- src/Model/Tag.php | 8 +- src/Protocol/ActivityPub/Processor.php | 22 +++- src/Protocol/ActivityPub/Transmitter.php | 34 +++--- src/Protocol/DFRN.php | 8 +- src/Protocol/Diaspora.php | 66 +++++++----- src/Protocol/OStatus.php | 2 +- 11 files changed, 204 insertions(+), 217 deletions(-) diff --git a/mod/item.php b/mod/item.php index a0bab514ec..f1224b1f57 100644 --- a/mod/item.php +++ b/mod/item.php @@ -611,7 +611,8 @@ function item_post(App $a) { $datarray['author-uri-id'] = ItemURI::getIdByURI($datarray['author-link']); $datarray['owner-updated'] = ''; $datarray['has-media'] = false; - $datarray['body'] = DI::contentItem()->improveSharedDataInBody($datarray); + $datarray['quote-uri-id'] = Item::getQuoteUriId($datarray['body'], $datarray['uid']); + $datarray['body'] = BBCode::removeSharedData($datarray['body']); $o = DI::conversation()->create([array_merge($contact_record, $datarray)], 'search', false, true); @@ -652,7 +653,12 @@ function item_post(App $a) { } $datarray['uri-id'] = ItemURI::getIdByURI($datarray['uri']); - $datarray['body'] = DI::contentItem()->improveSharedDataInBody($datarray); + + $quote_uri_id = Item::getQuoteUriId($datarray['body'], $datarray['uid']); + if (!empty($quote_uri_id)) { + $datarray['quote-uri-id'] = $quote_uri_id; + $datarray['body'] = BBCode::removeSharedData($datarray['body']); + } if ($orig_post) { $fields = [ diff --git a/src/Content/Item.php b/src/Content/Item.php index 510bae9703..f226867ec8 100644 --- a/src/Content/Item.php +++ b/src/Content/Item.php @@ -573,58 +573,31 @@ class Item return $owner_thumb; } - /** - * Add a share block for the given url - * - * @param string $url - * @param integer $uid - * @param bool $add_media - * @return string - */ - public function createSharedPostByUrl(string $url, int $uid = 0, bool $add_media = false): string - { - if (!empty($uid)) { - $id = ItemModel::searchByLink($url, $uid); - } - - if (empty($id)) { - $id = ItemModel::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_media); - } - /** * Add a share block for the given uri-id * - * @param integer $UriId - * @param integer $uid - * @param bool $add_media + * @param array $item + * @param string $body * @return string */ - public function createSharedPostByUriId(int $UriId, int $uid = 0, bool $add_media = false): string + public function addSharedPost(array $item, string $body = ''): 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' => [ItemModel::PUBLIC, ItemModel::UNLISTED]]); - if (!DBA::isResult($shared_item)) { - Logger::notice('Post does not exist.', ['uri-id' => $UriId, 'uid' => $uid]); - return ''; + if (empty($body)) { + $body = $item['body']; } - return $this->createSharedBlockByArray($shared_item, $add_media); + if (empty($item['quote-uri-id'])) { + return $body; + } + + $fields = ['uri-id', 'uri', 'body', 'title', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink', 'network']; + $shared_item = Post::selectFirst($fields, ['uri-id' => $item['quote-uri-id'], 'uid' => [$item['uid'], 0], 'private' => [ItemModel::PUBLIC, ItemModel::UNLISTED]]); + if (!DBA::isResult($shared_item)) { + Logger::notice('Post does not exist.', ['uri-id' => $item['quote-uri-id'], 'uid' => $item['uid']]); + return $body; + } + + return $body . "\n" . $this->createSharedBlockByArray($shared_item, true); } /** @@ -635,20 +608,13 @@ class Item * @param bool $add_media * @return string */ - public function createSharedPostByGuid(string $guid, int $uid = 0, string $host = '', bool $add_media = false): string + private function createSharedPostByGuid(string $guid, bool $add_media): string { $fields = ['uri-id', 'uri', 'body', 'title', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink', 'network']; - $shared_item = Post::selectFirst($fields, ['guid' => $guid, 'uid' => [$uid, 0], 'private' => [ItemModel::PUBLIC, ItemModel::UNLISTED]]); - - if (!DBA::isResult($shared_item) && !empty($host) && Diaspora::storeByGuid($guid, $host, true)) { - Logger::debug('Fetched post', ['guid' => $guid, 'host' => $host, 'uid' => $uid]); - $shared_item = Post::selectFirst($fields, ['guid' => $guid, 'uid' => [$uid, 0], 'private' => [ItemModel::PUBLIC, ItemModel::UNLISTED]]); - } elseif (DBA::isResult($shared_item)) { - Logger::debug('Found existing post', ['guid' => $guid, 'host' => $host, 'uid' => $uid]); - } + $shared_item = Post::selectFirst($fields, ['guid' => $guid, 'uid' => 0, 'private' => [ItemModel::PUBLIC, ItemModel::UNLISTED]]); if (!DBA::isResult($shared_item)) { - Logger::notice('Post does not exist.', ['guid' => $guid, 'host' => $host, 'uid' => $uid]); + Logger::notice('Post does not exist.', ['guid' => $guid]); return ''; } @@ -669,8 +635,9 @@ class Item } elseif (!in_array($item['network'] ?? '', Protocol::FEDERATED)) { $item['guid'] = ''; $item['uri'] = ''; - $item['body'] = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']); - } elseif ($add_media) { + } + + if ($add_media) { $item['body'] = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']); } @@ -684,7 +651,7 @@ class Item // If it is a reshared post then reformat it to avoid display problems with two share elements if (!empty($shared)) { - if (!empty($shared['guid']) && ($encaspulated_share = $this->createSharedPostByGuid($shared['guid'], 0, '', $add_media))) { + if (!empty($shared['guid']) && ($encaspulated_share = $this->createSharedPostByGuid($shared['guid'], $add_media))) { $item['body'] = preg_replace("/\[share.*?\](.*)\[\/share\]/ism", $encaspulated_share, $item['body']); } @@ -730,36 +697,6 @@ class Item return []; } - /** - * Improve the data in shared posts - * - * @param array $item - * @param bool $add_media - * @return string body - */ - public function improveSharedDataInBody(array $item, bool $add_media = false): string - { - $shared = BBCode::fetchShareAttributes($item['body']); - if (empty($shared['guid']) && empty($shared['message_id'])) { - return $item['body']; - } - - $link = $shared['link'] ?: $shared['message_id']; - - if (empty($shared_content)) { - $shared_content = $this->createSharedPostByUrl($link, $item['uid'] ?? 0, $add_media); - } - - if (empty($shared_content)) { - return $item['body']; - } - - $item['body'] = preg_replace("/\[share.*?\](.*)\[\/share\]/ism", $shared_content, $item['body']); - - Logger::debug('New shared data', ['uri-id' => $item['uri-id'], 'link' => $link, 'guid' => $item['guid']]); - return $item['body']; - } - /** * Return share data from an item array (if the item is shared item) * We are providing the complete Item array, because at some time in the future @@ -796,4 +733,24 @@ class Item return []; } + + /** + * Add a link to a shared post at the end of the post + * + * @param string $body + * @param integer $quote_uri_id + * @return string + */ + public function addShareLink(string $body, int $quote_uri_id): string + { + $post = Post::selectFirstPost(['uri', 'plink'], ['uri-id' => $quote_uri_id]); + if (empty($post)) { + return $body; + } + + $link = $post['plink'] ?: $post['uri']; + $body .= "\n♲ " . $link; + + return $body; + } } diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index aa413cd022..e8a396a35a 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -1070,46 +1070,6 @@ class BBCode return $attributes; } - /** - * Checks, if the provided body contains a native reshare - * - * @param string $body - * @return boolean - */ - public static function isNativeReshare(string $body): bool - { - $shared = BBCode::fetchShareAttributes($body); - return !empty($shared['guid'] ?? ''); - } - - /** - * Checks if the provided body contains a "share" element - * - * @param string $body - * @return boolean - */ - public static function existsShare(string $body): bool - { - $shared = BBCode::fetchShareAttributes($body); - return !empty($shared['link'] ?? ''); - } - - /** - * Replace the share block with a link - * - * @param string $body - * @return string - */ - public static function replaceSharedData(string $body): string - { - return BBCode::convertShare( - $body, - function (array $attributes) { - return '♲ ' . $attributes['link']; - } - ); - } - /** * Remove the share block * @@ -1118,7 +1078,7 @@ class BBCode */ public static function removeSharedData(string $body): string { - return trim(preg_replace("/\s*\[share .*?\].*?\[\/share\]\s*/ism", '', $body)); + return trim(preg_replace("/\s*\[share.*?\].*?\[\/share\]\s*/ism", '', $body)); } /** diff --git a/src/Model/Item.php b/src/Model/Item.php index c09b2754df..5f2f518345 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -197,12 +197,20 @@ class Item Logger::info('Updating per single row method', ['fields' => $fields, 'condition' => $condition]); - $items = Post::select(['id', 'origin', 'uri-id', 'uid', 'author-network'], $condition); + $items = Post::select(['id', 'origin', 'uri-id', 'uid', 'author-network', 'quote-uri-id'], $condition); $notify_items = []; while ($item = DBA::fetch($items)) { if (!empty($fields['body'])) { + if (!empty($item['quote-uri-id'])) { + $fields['body'] = BBCode::removeSharedData($fields['body']); + + if (!empty($fields['raw-body'])) { + $fields['raw-body'] = BBCode::removeSharedData($fields['raw-body']); + } + } + Post\Media::insertFromAttachmentData($item['uri-id'], $fields['body']); $content_fields = ['raw-body' => trim($fields['raw-body'] ?? $fields['body'])]; @@ -578,7 +586,7 @@ class Item public static function isValid(array $item): bool { // When there is no content then we don't post it - if (($item['body'] . $item['title'] == '') && (empty($item['uri-id']) || !Post\Media::existsByURIId($item['uri-id']))) { + if (($item['body'] . $item['title'] == '') && empty($item['quote-uri-id']) && (empty($item['uri-id']) || !Post\Media::existsByURIId($item['uri-id']))) { Logger::notice('No body, no title.'); return false; } @@ -1119,19 +1127,27 @@ class Item unset($item['attachments']); } + if (empty($item['quote-uri-id'])) { + $quote_id = self::getQuoteUriId($item['body']); + if (!empty($quote_id)) { + // This is one of these "should not happen" situations. + // The protocol implementations should already have done this job. + Logger::notice('Quote-uri-id detected in post', ['id' => $quote_id, 'guid' => $item['guid'], 'uri-id' => $item['uri-id'], 'callstack' => System::callstack(20)]); + $item['quote-uri-id'] = $quote_id; + } + } + + if (!empty($item['quote-uri-id'])) { + $item['raw-body'] = BBCode::removeSharedData($item['raw-body']); + $item['body'] = BBCode::removeSharedData($item['body']); + } + Post\Media::insertFromAttachmentData($item['uri-id'], $item['body']); // Remove all media attachments from the body and store them in the post-media table $item['raw-body'] = Post\Media::insertFromBody($item['uri-id'], $item['raw-body']); $item['raw-body'] = self::setHashtags($item['raw-body']); - $quote_id = self::getQuoteUriId($item['body']); - - if (!empty($quote_id) && Post::exists(['uri-id' => $quote_id, 'network' => Protocol::FEDERATED])) { - $item['quote-uri-id'] = $quote_id; - $item['raw-body'] = BBCode::removeSharedData($item['raw-body']); - } - if (!DBA::exists('contact', ['id' => $item['author-id'], 'network' => Protocol::DFRN])) { Post\Media::insertFromRelevantUrl($item['uri-id'], $item['raw-body']); } @@ -3630,12 +3646,56 @@ class Item * @param string $body * @return integer */ - private static function getQuoteUriId(string $body): int + public static function getQuoteUriId(string $body, int $uid = 0): int { $shared = BBCode::fetchShareAttributes($body); - if (empty($shared['message_id'])) { + if (empty($shared['guid']) && empty($shared['message_id'])) { return 0; } - return ItemURI::getIdByURI($shared['message_id']); + + if (empty($shared['link']) && empty($shared['message_id'])) { + Logger::notice('Invalid share block.', ['share' => $shared]); + return 0; + } + + if (!empty($shared['guid'])) { + $shared_item = Post::selectFirst(['uri-id'], ['guid' => $shared['guid'], 'uid' => [0, $uid]]); + if (!empty($shared_item['uri-id'])) { + Logger::debug('Found post by guid', ['guid' => $shared['guid'], 'uid' => $uid]); + } + } + + if (empty($shared_item['uri-id']) && !empty($shared['message_id'])) { + $shared_item = Post::selectFirst(['uri-id'], ['uri' => $shared['message_id'], 'uid' => [0, $uid]]); + if (!empty($shared_item['uri-id'])) { + Logger::debug('Found post by message_id', ['message_id' => $shared['message_id'], 'uid' => $uid]); + } + } + + if (empty($shared_item['uri-id']) && !empty($shared['link'])) { + $shared_item = Post::selectFirst(['uri-id'], ['plink' => $shared['link'], 'uid' => [0, $uid]]); + if (!empty($shared_item['uri-id'])) { + Logger::debug('Found post by link', ['link' => $shared['link'], 'uid' => $uid]); + } + } + + if (empty($shared_item['uri-id'])) { + $url = $shared['message_id'] ?: $shared['link']; + $id = self::fetchByLink($url); + if (!$id) { + Logger::notice('Post could not be fetched.', ['url' => $url, 'uid' => $uid]); + return 0; + } + + Logger::debug('Fetched shared post', ['id' => $id, 'url' => $url, 'uid' => $uid]); + + $shared_item = Post::selectFirst(['uri-id'], ['id' => $id]); + if (!DBA::isResult($shared_item)) { + Logger::warning('Post does not exist.', ['id' => $id, 'url' => $url, 'uid' => $uid]); + return 0; + } + } + + return $shared_item['uri-id']; } } diff --git a/src/Model/Post/Media.php b/src/Model/Post/Media.php index 37603ad372..478097effa 100644 --- a/src/Model/Post/Media.php +++ b/src/Model/Post/Media.php @@ -403,11 +403,6 @@ class Media // Simplify image codes $unshared_body = $body = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $body); - // Only remove the shared data from "real" reshares - if (BBCode::isNativeReshare($body)) { - $unshared_body = BBCode::removeSharedData($body); - } - $attachments = []; if (preg_match_all("#\[url=([^\]]+?)\]\s*\[img=([^\[\]]*)\]([^\[\]]*)\[\/img\]\s*\[/url\]#ism", $body, $pictures, PREG_SET_ORDER)) { foreach ($pictures as $picture) { @@ -484,12 +479,6 @@ class Media */ public static function insertFromRelevantUrl(int $uriid, string $body) { - // Only remove the shared data from "real" reshares - if (BBCode::isNativeReshare($body)) { - // Don't look at the shared content - $body = BBCode::removeSharedData($body); - } - // Remove all hashtags and mentions $body = preg_replace("/([#@!])\[url\=(.*?)\](.*?)\[\/url\]/ism", '', $body); @@ -519,9 +508,6 @@ class Media */ public static function insertFromAttachmentData(int $uriid, string $body) { - // Don't look at the shared content - $body = BBCode::removeSharedData($body); - $data = BBCode::getAttachmentData($body); if (empty($data)) { return; diff --git a/src/Model/Tag.php b/src/Model/Tag.php index 2f034e92b7..799296dfbf 100644 --- a/src/Model/Tag.php +++ b/src/Model/Tag.php @@ -319,16 +319,12 @@ class Tag $tags = self::TAG_CHARACTER[self::HASHTAG] . self::TAG_CHARACTER[self::MENTION] . self::TAG_CHARACTER[self::EXCLUSIVE_MENTION]; } - // Only remove the shared data from "real" reshares - $shared = DI::contentItem()->getSharedPost($item, ['uri-id']); - if (!empty($shared)) { - $item['body'] = BBCode::removeSharedData($item['body']); - } - foreach (self::getFromBody($item['body'], $tags) as $tag) { self::storeByHash($item['uri-id'], $tag[1], $tag[3], $tag[2]); } + $shared = DI::contentItem()->getSharedPost($item, ['uri-id']); + // Search for hashtags in the shared body (but only if hashtags are wanted) if (!empty($shared) && (strpos($tags, self::TAG_CHARACTER[self::HASHTAG]) !== false)) { foreach (self::getByURIId($shared['post']['uri-id'], [self::HASHTAG]) as $tag) { diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 38361ec069..98fed12a33 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -827,10 +827,26 @@ class Processor $content = self::addMentionLinks($content, $activity['tags']); + if (!empty($activity['quote-url'])) { + $id = Item::fetchByLink($activity['quote-url']); + if ($id) { + $shared_item = Post::selectFirst(['uri-id'], ['id' => $id]); + $item['quote-uri-id'] = $shared_item['uri-id']; + } else { + Logger::info('Quote was not fetched', ['guid' => $item['guid'], 'uri-id' => $item['uri-id'], 'quote' => $activity['quote-url']]); + } + } + if (!empty($activity['source'])) { $item['body'] = $activity['source']; $item['raw-body'] = $content; - $item['body'] = DI::contentItem()->improveSharedDataInBody($item); + + $quote_uri_id = Item::getQuoteUriId($item['body']); + if (empty($item['quote-uri-id']) && !empty($quote_uri_id)) { + $item['quote-uri-id'] = $quote_uri_id; + } + + $item['body'] = BBCode::removeSharedData($item['body']); } else { $parent_uri = $item['parent-uri'] ?? $item['thr-parent']; if (empty($activity['directmessage']) && ($parent_uri != $item['uri']) && ($item['gravity'] == Item::GRAVITY_COMMENT)) { @@ -848,10 +864,6 @@ class Processor } $item['content-warning'] = HTML::toBBCode($activity['summary'] ?? ''); $item['raw-body'] = $item['body'] = $content; - - if (!empty($activity['quote-url'])) { - $item['body'] .= DI::contentItem()->createSharedPostByUrl($activity['quote-url']); - } } self::storeFromBody($item); diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index afc2d5eac0..6a601b6f98 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -1664,20 +1664,17 @@ class Transmitter $body = preg_replace("/\s*\[attachment .*?\].*?\[\/attachment\]\s*/ism", '', $body); } - $body = BBCode::setMentionsToNicknames($body); - $exists_reshare = BBCode::existsShare($body); + $body = BBCode::setMentionsToNicknames($body); - if (!empty($item['quote-uri']) && Post::exists(['uri-id' => $item['quote-uri-id'], 'network' => [Protocol::ACTIVITYPUB, Protocol::DFRN]])) { - $real_quote = true; - if ($exists_reshare) { - $body = BBCode::replaceSharedData($body); - } elseif (strpos($body, $item['quote-uri']) === false) { - $body .= "\n♲ " . $item['quote-uri']; + if (!empty($item['quote-uri-id'])) { + $body = BBCode::removeSharedData($body); + if (Post::exists(['uri-id' => $item['quote-uri-id'], 'network' => [Protocol::ACTIVITYPUB, Protocol::DFRN]])) { + $real_quote = true; + $data['quoteUrl'] = $item['quote-uri']; + $body = DI::contentItem()->addShareLink($body, $item['quote-uri-id']); + } else { + $body = DI::contentItem()->addSharedPost($item, $body); } - $data['quoteUrl'] = $item['quote-uri']; - } elseif (!empty($item['quote-uri']) && !$exists_reshare) { - $body .= "\n" . DI::contentItem()->createSharedPostByUriId($item['quote-uri-id'], $item['uid'], true); - $item['body'] = DI::contentItem()->improveSharedDataInBody($item, true); } $data['content'] = BBCode::convertForUriId($item['uri-id'], $body, BBCode::ACTIVITYPUB); @@ -1689,15 +1686,14 @@ class Transmitter $language = self::getLanguage($item); if (!empty($language)) { $richbody = BBCode::setMentionsToNicknames($item['body'] ?? ''); - - if ($real_quote) { - if (BBCode::existsShare($richbody)) { - $richbody = BBCode::replaceSharedData($richbody); - } elseif (strpos($richbody, $item['quote-uri']) === false) { - $richbody .= "\n♲ " . $item['quote-uri']; + if (!empty($item['quote-uri-id'])) { + $richbody = BBCode::removeSharedData($richbody); + if ($real_quote) { + $richbody = DI::contentItem()->addShareLink($richbody, $item['quote-uri-id']); + } else { + $richbody = DI::contentItem()->addSharedPost($item, $richbody); } } - $richbody = BBCode::removeAttachment($richbody); $data['contentMap'][$language] = BBCode::convertForUriId($item['uri-id'], $richbody, BBCode::EXTERNAL); diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index f626582bab..da4db5d9ad 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -774,7 +774,7 @@ class DFRN $entry->setAttribute("xmlns:statusnet", ActivityNamespace::STATUSNET); } - $body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body'] ?? ''); + $body = Post\Media::addAttachmentsToBody($item['uri-id'], DI::contentItem()->addSharedPost($item)); if ($item['private'] == Item::PRIVATE) { $body = Item::fixPrivatePhotos($body, $owner['uid'], $item, $cid); @@ -1838,7 +1838,11 @@ class DFRN $item['uri-id'] = ItemURI::insert(['uri' => $item['uri'], 'guid' => $item['guid']]); - $item['body'] = DI::contentItem()->improveSharedDataInBody($item); + $quote_uri_id = Item::getQuoteUriId($item['body'], $item['uid']); + if (!empty($quote_uri_id)) { + $item['quote-uri-id'] = $quote_uri_id; + $item['body'] = BBCode::removeSharedData($item['body']); + } Tag::storeFromBody($item['uri-id'], $item['body']); diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index bd5da5445a..ffffaf6199 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -2364,13 +2364,13 @@ class Diaspora $datarray = self::setDirection($datarray, $direction); - $datarray['body'] = DI::contentItem()->createSharedPostByGuid($root_guid, $importer['uid'], $original_person['url']); - $datarray['body'] = Diaspora::replacePeopleGuid($datarray['body'], $datarray['author-link']); + $datarray['quote-uri-id'] = self::getQuoteUriId($root_guid, $importer['uid'], $original_person['url']); + if (empty($datarray['quote-uri-id'])) { + return false; + } - /// @todo Copy tag data from original post - Tag::storeFromBody($datarray['uri-id'], $datarray['body']); - - $datarray['plink'] = self::plink($author, $guid); + $datarray['body'] = ''; + $datarray['plink'] = self::plink($author, $guid); $datarray['private'] = (($public == 'false') ? Item::PRIVATE : Item::PUBLIC); $datarray['changed'] = $datarray['created'] = $datarray['edited'] = $created_at; @@ -2401,6 +2401,25 @@ class Diaspora } } + private static function getQuoteUriId(string $guid, int $uid, string $host): int + { + $shared_item = Post::selectFirst(['uri-id'], ['guid' => $guid, 'uid' => [$uid, 0], 'private' => [Item::PUBLIC, Item::UNLISTED]]); + + if (!DBA::isResult($shared_item) && !empty($host) && Diaspora::storeByGuid($guid, $host, true)) { + Logger::debug('Fetched post', ['guid' => $guid, 'host' => $host, 'uid' => $uid]); + $shared_item = Post::selectFirst(['uri-id'], ['guid' => $guid, 'uid' => [$uid, 0], 'private' => [Item::PUBLIC, Item::UNLISTED]]); + } elseif (DBA::isResult($shared_item)) { + Logger::debug('Found existing post', ['guid' => $guid, 'host' => $host, 'uid' => $uid]); + } + + if (!DBA::isResult($shared_item)) { + Logger::notice('Post does not exist.', ['guid' => $guid, 'host' => $host, 'uid' => $uid]); + return 0; + } + + return $shared_item['uri-id']; + } + /** * Processes retractions * @@ -3305,7 +3324,7 @@ class Diaspora $type = 'reshare'; } else { $title = $item['title']; - $body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']); + $body = Post\Media::addAttachmentsToBody($item['uri-id'], DI::contentItem()->addSharedPost($item)); // Fetch the title from an attached link - if there is one if (empty($item['title']) && DI::pConfig()->get($owner['uid'], 'system', 'attach_link_title')) { @@ -3315,11 +3334,6 @@ class Diaspora } } - // @todo Check if this is obsolete and if we are still using different owners. (Possibly a fragment from the forum functionality) - if ($item['author-link'] != $item['owner-link']) { - $body = DI::contentItem()->createSharedBlockByArray($item); - } - // convert to markdown $body = html_entity_decode(BBCode::toMarkdown($body)); @@ -3527,7 +3541,7 @@ class Diaspora $thread_parent_item = Post::selectFirst(['guid', 'author-id', 'author-link', 'gravity'], ['uri' => $item['thr-parent'], 'uid' => $item['uid']]); } - $body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']); + $body = Post\Media::addAttachmentsToBody($item['uri-id'], DI::contentItem()->addSharedPost($item)); // The replied to autor mention is prepended for clarity if: // - Item replied isn't yours @@ -4022,25 +4036,21 @@ class Diaspora public static function performReshare(int $UriId, int $uid): int { - $post = DI::contentItem()->createSharedPostByUriId($UriId, $uid); - if (empty($post)) { - return 0; - } - $owner = User::getOwnerDataById($uid); $author = Contact::getPublicIdByUserId($uid); $item = [ - 'uid' => $uid, - 'verb' => Activity::POST, - 'contact-id' => $owner['id'], - 'author-id' => $author, - 'owner-id' => $author, - 'body' => $post, - 'allow_cid' => $owner['allow_cid'] ?? '', - 'allow_gid' => $owner['allow_gid']?? '', - 'deny_cid' => $owner['deny_cid'] ?? '', - 'deny_gid' => $owner['deny_gid'] ?? '', + 'uid' => $uid, + 'verb' => Activity::POST, + 'contact-id' => $owner['id'], + 'author-id' => $author, + 'owner-id' => $author, + 'body' => '', + 'quote-uri-id' => $UriId, + 'allow_cid' => $owner['allow_cid'] ?? '', + 'allow_gid' => $owner['allow_gid']?? '', + 'deny_cid' => $owner['deny_cid'] ?? '', + 'deny_gid' => $owner['deny_gid'] ?? '', ]; if (!empty($item['allow_cid'] . $item['allow_gid'] . $item['deny_cid'] . $item['deny_gid'])) { diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index 6ec9b9fea1..06f849d1fc 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -1598,7 +1598,7 @@ class OStatus XML::addElement($doc, $entry, 'id', $item['uri']); XML::addElement($doc, $entry, 'title', html_entity_decode($title, ENT_QUOTES, 'UTF-8')); - $body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']); + $body = Post\Media::addAttachmentsToBody($item['uri-id'], DI::contentItem()->addSharedPost($item)); $body = self::formatPicturePost($body, $item['uri-id']); if (!empty($item['title'])) {