Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved handling of native quotes #12076

Merged
merged 6 commits into from
Oct 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 8 additions & 2 deletions mod/item.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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 = [
Expand Down
120 changes: 38 additions & 82 deletions src/Content/Item.php
Original file line number Diff line number Diff line change
Expand Up @@ -574,57 +574,30 @@ public function getOwnerAvatar(array $item): string
}

/**
* Add a share block for the given url
* Add a share block for the given uri-id
*
* @param string $url
* @param integer $uid
* @param bool $add_media
* @param array $item
* @param string $body
* @return string
*/
public function createSharedPostByUrl(string $url, int $uid = 0, bool $add_media = false): string
public function addSharedPost(array $item, string $body = ''): 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 '';
if (empty($body)) {
$body = $item['body'];
}

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 '';
if (empty($item['quote-uri-id'])) {
return $body;
}

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
* @return string
*/
public function createSharedPostByUriId(int $UriId, int $uid = 0, bool $add_media = false): 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]]);
$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' => $UriId, 'uid' => $uid]);
return '';
Logger::notice('Post does not exist.', ['uri-id' => $item['quote-uri-id'], 'uid' => $item['uid']]);
return $body;
}

return $this->createSharedBlockByArray($shared_item, $add_media);
return $body . "\n" . $this->createSharedBlockByArray($shared_item, true);
}

/**
Expand All @@ -635,20 +608,13 @@ public function createSharedPostByUriId(int $UriId, int $uid = 0, bool $add_medi
* @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 '';
}

Expand All @@ -669,8 +635,9 @@ public function createSharedBlockByArray(array $item, bool $add_media = false):
} 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']);
}

Expand All @@ -684,7 +651,7 @@ public function createSharedBlockByArray(array $item, bool $add_media = false):

// 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']);
}

Expand Down Expand Up @@ -730,36 +697,6 @@ public function getSharedPost(array $item, array $fields = []): array
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
Expand Down Expand Up @@ -796,4 +733,23 @@ private function getShareArray(array $item): array

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;
}

$body .= "\n♲ " . ($post['plink'] ?: $post['uri']);

return $body;
}
}
42 changes: 1 addition & 41 deletions src/Content/Text/BBCode.php
Original file line number Diff line number Diff line change
Expand Up @@ -1070,46 +1070,6 @@ private static function extractShareAttributes(string $shareString): array
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
*
Expand All @@ -1118,7 +1078,7 @@ function (array $attributes) {
*/
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));
}

/**
Expand Down
4 changes: 3 additions & 1 deletion src/Factory/Api/Mastodon/Status.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public function __construct(LoggerInterface $logger, Database $dba,
public function createFromUriId(int $uriId, int $uid = 0): \Friendica\Object\Api\Mastodon\Status
{
$fields = ['uri-id', 'uid', 'author-id', 'author-uri-id', 'author-link', 'starred', 'app', 'title', 'body', 'raw-body', 'content-warning', 'question-id',
'created', 'network', 'thr-parent-id', 'parent-author-id', 'language', 'uri', 'plink', 'private', 'vid', 'gravity', 'featured', 'has-media'];
'created', 'network', 'thr-parent-id', 'parent-author-id', 'language', 'uri', 'plink', 'private', 'vid', 'gravity', 'featured', 'has-media', 'quote-uri-id'];
$item = Post::selectFirst($fields, ['uri-id' => $uriId, 'uid' => [0, $uid]], ['order' => ['uid' => true]]);
if (!$item) {
$mail = DBA::selectFirst('mail', ['id'], ['uri-id' => $uriId, 'uid' => $uid]);
Expand Down Expand Up @@ -178,6 +178,8 @@ public function createFromUriId(int $uriId, int $uid = 0): \Friendica\Object\Api
$item['title'] = $reshared_item['title'] ?? $item['title'];
$item['body'] = $reshared_item['body'] ?? $item['body'];
} else {
$item['body'] = $this->contentItem->addSharedPost($item);
$item['raw-body'] = $this->contentItem->addSharedPost($item, $item['raw-body']);
$reshare = [];
}

Expand Down
4 changes: 2 additions & 2 deletions src/Factory/Api/Twitter/Status.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public function createFromItemId(int $id, int $uid, bool $include_entities = fal
{
$fields = ['parent-uri-id', 'uri-id', 'uid', 'author-id', 'author-link', 'author-network', 'owner-id', 'causer-id',
'starred', 'app', 'title', 'body', 'raw-body', 'created', 'network','post-reason', 'language', 'gravity',
'thr-parent-id', 'parent-author-id', 'parent-author-nick', 'uri', 'plink', 'private', 'vid', 'coord'];
'thr-parent-id', 'parent-author-id', 'parent-author-nick', 'uri', 'plink', 'private', 'vid', 'coord', 'quote-uri-id'];
$item = Post::selectFirst($fields, ['id' => $id], ['order' => ['uid' => true]]);
if (!$item) {
throw new HTTPException\NotFoundException('Item with ID ' . $id . ' not found.');
Expand Down Expand Up @@ -146,7 +146,7 @@ private function createFromArray(array $item, int $uid, bool $include_entities):
$statusnetHtml = BBCode::convertForUriId($item['uri-id'], BBCode::setMentionsToNicknames($title . ($item['raw-body'] ?? $item['body'])), BBCode::API);
$friendicaHtml = BBCode::convertForUriId($item['uri-id'], $title . $item['body'], BBCode::EXTERNAL);

$text .= Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']);
$text .= Post\Media::addAttachmentsToBody($item['uri-id'], $this->contentItem->addSharedPost($item));

$text = trim(HTML::toPlaintext(BBCode::convertForUriId($item['uri-id'], $text, BBCode::API), 0));

Expand Down