mirror of
https://github.com/friendica/friendica
synced 2024-12-23 07:20:15 +00:00
Merge pull request #7903 from annando/add-share-data
Add data for shared posts from the original
This commit is contained in:
commit
0f476498f3
9 changed files with 143 additions and 214 deletions
105
include/api.php
105
include/api.php
|
@ -2019,7 +2019,7 @@ function api_statuses_repeat($type)
|
|||
|
||||
Logger::log('API: api_statuses_repeat: '.$id);
|
||||
|
||||
$fields = ['body', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink'];
|
||||
$fields = ['body', 'title', 'attach', 'tag', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink'];
|
||||
$item = Item::selectFirst($fields, ['id' => $id, 'private' => false]);
|
||||
|
||||
if (DBA::isResult($item) && $item['body'] != "") {
|
||||
|
@ -2029,10 +2029,16 @@ function api_statuses_repeat($type)
|
|||
} else {
|
||||
$post = share_header($item['author-name'], $item['author-link'], $item['author-avatar'], $item['guid'], $item['created'], $item['plink']);
|
||||
|
||||
if (!empty($item['title'])) {
|
||||
$post .= '[h3]' . $item['title'] . "[/h3]\n";
|
||||
}
|
||||
|
||||
$post .= $item['body'];
|
||||
$post .= "[/share]";
|
||||
}
|
||||
$_REQUEST['body'] = $post;
|
||||
$_REQUEST['tag'] = $item['tag'];
|
||||
$_REQUEST['attach'] = $item['attach'];
|
||||
$_REQUEST['profile_uid'] = api_user();
|
||||
$_REQUEST['api_source'] = true;
|
||||
|
||||
|
@ -5150,99 +5156,30 @@ function api_share_as_retweet(&$item)
|
|||
}
|
||||
}
|
||||
|
||||
/// @TODO "$1" should maybe mean '$1' ?
|
||||
$attributes = preg_replace("/\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism", "$1", $body);
|
||||
/*
|
||||
* Skip if there is no shared message in there
|
||||
* we already checked this in diaspora::isReshare()
|
||||
* but better one more than one less...
|
||||
*/
|
||||
if (($body == $attributes) || empty($attributes)) {
|
||||
$reshared = Item::getShareArray($item);
|
||||
if (empty($reshared)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// build the fake reshared item
|
||||
$reshared_item = $item;
|
||||
|
||||
$author = "";
|
||||
preg_match("/author='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$author = html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
preg_match('/author="(.*?)"/ism', $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$author = $matches[1];
|
||||
}
|
||||
|
||||
$profile = "";
|
||||
preg_match("/profile='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$profile = $matches[1];
|
||||
}
|
||||
|
||||
preg_match('/profile="(.*?)"/ism', $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$profile = $matches[1];
|
||||
}
|
||||
|
||||
$avatar = "";
|
||||
preg_match("/avatar='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$avatar = $matches[1];
|
||||
}
|
||||
|
||||
preg_match('/avatar="(.*?)"/ism', $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$avatar = $matches[1];
|
||||
}
|
||||
|
||||
$link = "";
|
||||
preg_match("/link='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$link = $matches[1];
|
||||
}
|
||||
|
||||
preg_match('/link="(.*?)"/ism', $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$link = $matches[1];
|
||||
}
|
||||
|
||||
$posted = "";
|
||||
preg_match("/posted='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$posted = $matches[1];
|
||||
}
|
||||
|
||||
preg_match('/posted="(.*?)"/ism', $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$posted = $matches[1];
|
||||
}
|
||||
|
||||
if (!preg_match("/(.*?)\[share.*?\]\s?(.*?)\s?\[\/share\]\s?(.*?)/ism", $body, $matches)) {
|
||||
if (empty($reshared['shared']) || empty($reshared['profile']) || empty($reshared['author']) || empty($reshared['avatar']) || empty($reshared['posted'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$pre_body = trim($matches[1]);
|
||||
if ($pre_body != '') {
|
||||
$item['body'] = $pre_body;
|
||||
if (!empty($reshared['comment'])) {
|
||||
$item['body'] = $reshared['comment'];
|
||||
}
|
||||
|
||||
$shared_body = trim($matches[2]);
|
||||
|
||||
if (($shared_body == "") || ($profile == "") || ($author == "") || ($avatar == "") || ($posted == "")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$reshared_item["share-pre-body"] = $pre_body;
|
||||
$reshared_item["body"] = $shared_body;
|
||||
$reshared_item["author-id"] = Contact::getIdForURL($profile, 0, true);
|
||||
$reshared_item["author-name"] = $author;
|
||||
$reshared_item["author-link"] = $profile;
|
||||
$reshared_item["author-avatar"] = $avatar;
|
||||
$reshared_item["plink"] = $link;
|
||||
$reshared_item["created"] = $posted;
|
||||
$reshared_item["edited"] = $posted;
|
||||
$reshared_item["share-pre-body"] = $reshared['comment'];
|
||||
$reshared_item["body"] = $reshared['shared'];
|
||||
$reshared_item["author-id"] = Contact::getIdForURL($reshared['profile'], 0, true);
|
||||
$reshared_item["author-name"] = $reshared['author'];
|
||||
$reshared_item["author-link"] = $reshared['profile'];
|
||||
$reshared_item["author-avatar"] = $reshared['avatar'];
|
||||
$reshared_item["plink"] = $reshared['link'] ?? '';
|
||||
$reshared_item["created"] = $reshared['posted'];
|
||||
$reshared_item["edited"] = $reshared['posted'];
|
||||
|
||||
return $reshared_item;
|
||||
}
|
||||
|
|
|
@ -133,51 +133,20 @@ function display_fetchauthor($a, $item)
|
|||
$profiledata['network'] = $author['network'];
|
||||
|
||||
// Check for a repeated message
|
||||
$skip = false;
|
||||
$body = trim($item["body"]);
|
||||
|
||||
// Skip if it isn't a pure repeated messages
|
||||
// Does it start with a share?
|
||||
if (!$skip && strpos($body, "[share") > 0) {
|
||||
$skip = true;
|
||||
}
|
||||
// Does it end with a share?
|
||||
if (!$skip && (strlen($body) > (strrpos($body, "[/share]") + 8))) {
|
||||
$skip = true;
|
||||
}
|
||||
if (!$skip) {
|
||||
$attributes = preg_replace("/\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism","$1",$body);
|
||||
// Skip if there is no shared message in there
|
||||
if ($body == $attributes) {
|
||||
$skip = true;
|
||||
}
|
||||
$shared = Item::getShareArray($item);
|
||||
if (!empty($shared) && empty($shared['comment'])) {
|
||||
if (!empty($shared['author'])) {
|
||||
$profiledata['name'] = $shared['author'];
|
||||
}
|
||||
|
||||
if (!$skip) {
|
||||
preg_match("/author='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$profiledata["name"] = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
|
||||
if (!empty($shared['profile'])) {
|
||||
$profiledata['url'] = $shared['profile'];
|
||||
}
|
||||
preg_match('/author="(.*?)"/ism', $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$profiledata["name"] = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
|
||||
}
|
||||
preg_match("/profile='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$profiledata["url"] = $matches[1];
|
||||
}
|
||||
preg_match('/profile="(.*?)"/ism', $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$profiledata["url"] = $matches[1];
|
||||
}
|
||||
preg_match("/avatar='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$profiledata["photo"] = $matches[1];
|
||||
}
|
||||
preg_match('/avatar="(.*?)"/ism', $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$profiledata["photo"] = $matches[1];
|
||||
|
||||
if (!empty($shared['avatar'])) {
|
||||
$profiledata['photo'] = $shared['avatar'];
|
||||
}
|
||||
|
||||
$profiledata["nickname"] = $profiledata["name"];
|
||||
$profiledata["network"] = Protocol::matchByProfileUrl($profiledata["url"]);
|
||||
|
||||
|
|
|
@ -730,6 +730,9 @@ function item_post(App $a) {
|
|||
}
|
||||
}
|
||||
|
||||
// If this was a share, add missing data here
|
||||
$datarray = Item::addShareDataFromOriginal($datarray);
|
||||
|
||||
$post_id = Item::insert($datarray);
|
||||
|
||||
if (!$post_id) {
|
||||
|
|
|
@ -1055,7 +1055,7 @@ class BBCode extends BaseObject
|
|||
$text = ($is_quote_share? '<br />' : '') . '<p>' . html_entity_decode('♲ ', ENT_QUOTES, 'UTF-8') . ' @' . $author_contact['addr'] . ': ' . $content . '</p>' . "\n";
|
||||
break;
|
||||
case 9: // ActivityPub
|
||||
$author = '@<span class="vcard"><a href="' . $author_contact['url'] . '" class="url u-url mention" title="' . $author_contact['addr'] . '"><span class="fn nickname mention">' . $author_contact['addr'] . ':</span></a></span>';
|
||||
$author = '@<span class="vcard"><a href="' . $author_contact['url'] . '" class="url u-url mention" title="' . $author_contact['addr'] . '"><span class="fn nickname mention">' . $author_contact['addr'] . '</span></a>:</span>';
|
||||
$text = '<div><a href="' . $attributes['link'] . '">' . html_entity_decode('♲', ENT_QUOTES, 'UTF-8') . '</a> ' . $author . '<blockquote>' . $content . '</blockquote></div>' . "\n";
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -3759,4 +3759,83 @@ class Item extends BaseObject
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* we hopefully will define these values not in the body anymore but in some item fields.
|
||||
* This function is meant to replace all similar functions in the system.
|
||||
*
|
||||
* @param array $item
|
||||
*
|
||||
* @return array with share information
|
||||
*/
|
||||
public static function getShareArray($item)
|
||||
{
|
||||
if (!preg_match("/(.*?)\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism", $item['body'], $matches)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$attribute_string = $matches[2];
|
||||
$attributes = ['comment' => trim($matches[1]), 'shared' => trim($matches[3])];
|
||||
foreach (['author', 'profile', 'avatar', 'guid', 'posted', 'link'] as $field) {
|
||||
if (preg_match("/$field=(['\"])(.+?)\\1/ism", $attribute_string, $matches)) {
|
||||
$attributes[$field] = trim(html_entity_decode($matches[2] ?? '', ENT_QUOTES, 'UTF-8'));
|
||||
}
|
||||
}
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch item information for shared items from the original items and adds it.
|
||||
*
|
||||
* @param array $item
|
||||
*
|
||||
* @return array item array with data from the original item
|
||||
*/
|
||||
public static function addShareDataFromOriginal($item)
|
||||
{
|
||||
$shared = self::getShareArray($item);
|
||||
if (empty($shared)) {
|
||||
return $item;
|
||||
}
|
||||
|
||||
// Real reshares always have got a GUID.
|
||||
if (empty($shared['guid'])) {
|
||||
return $item;
|
||||
}
|
||||
|
||||
$uid = $item['uid'] ?? 0;
|
||||
|
||||
// first try to fetch the item via the GUID. This will work for all reshares that had been created on this system
|
||||
$shared_item = self::selectFirst(['title', 'body', 'attach'], ['guid' => $shared['guid'], 'uid' => [0, $uid]]);
|
||||
if (!DBA::isResult($shared_item)) {
|
||||
// Otherwhise try to find (and possibly fetch) the item via the link. This should work for Diaspora and ActivityPub posts
|
||||
$id = self::fetchByLink($shared['link'], $uid);
|
||||
if (empty($id)) {
|
||||
Logger::info('Original item not found', ['url' => $shared['link'], 'callstack' => System::callstack()]);
|
||||
return $item;
|
||||
}
|
||||
|
||||
$shared_item = self::selectFirst(['title', 'body', 'attach'], ['id' => $id]);
|
||||
if (!DBA::isResult($shared_item)) {
|
||||
return $item;
|
||||
}
|
||||
Logger::info('Got shared data from url', ['url' => $shared['link'], 'callstack' => System::callstack()]);
|
||||
} else {
|
||||
Logger::info('Got shared data from guid', ['guid' => $shared['guid'], 'callstack' => System::callstack()]);
|
||||
}
|
||||
|
||||
if (!empty($shared_item['title'])) {
|
||||
$body = '[h3]' . $shared_item['title'] . "[/h3]\n" . $shared_item['body'];
|
||||
unset($shared_item['title']);
|
||||
} else {
|
||||
$body = $shared_item['body'];
|
||||
}
|
||||
|
||||
$item['body'] = preg_replace("/(.*?\[share.*?\]\s?).*?(\s?\[\/share\]\s?)/ism", '$1' . $body . '$2', $item['body']);
|
||||
unset($shared_item['body']);
|
||||
|
||||
return array_merge($item, $shared_item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1401,23 +1401,12 @@ class Transmitter
|
|||
*/
|
||||
public static function getAnnounceArray($item)
|
||||
{
|
||||
if (!preg_match("/(.*?)\[share(.*?)\]\s?.*?\s?\[\/share\]\s?/ism", $item['body'], $matches)) {
|
||||
$reshared = Item::getShareArray($item);
|
||||
if (empty($reshared['guid'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$attributes = $matches[2];
|
||||
$comment = $matches[1];
|
||||
|
||||
preg_match("/guid='(.*?)'/ism", $attributes, $matches);
|
||||
if (empty($matches[1])) {
|
||||
preg_match('/guid="(.*?)"/ism', $attributes, $matches);
|
||||
}
|
||||
|
||||
if (empty($matches[1])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$reshared_item = Item::selectFirst([], ['guid' => $matches[1]]);
|
||||
$reshared_item = Item::selectFirst([], ['guid' => $reshared['guid']]);
|
||||
if (!DBA::isResult($reshared_item)) {
|
||||
return [];
|
||||
}
|
||||
|
@ -1431,7 +1420,7 @@ class Transmitter
|
|||
return [];
|
||||
}
|
||||
|
||||
return ['object' => $reshared_item, 'actor' => $profile, 'comment' => trim($comment)];
|
||||
return ['object' => $reshared_item, 'actor' => $profile, 'comment' => $reshared['comment']];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2537,6 +2537,9 @@ class DFRN
|
|||
}
|
||||
}
|
||||
|
||||
// Ensure to have the correct share data
|
||||
$item = Item::addShareDataFromOriginal($item);
|
||||
|
||||
if ($entrytype == DFRN::REPLY_RC) {
|
||||
$item["wall"] = 1;
|
||||
} elseif ($entrytype == DFRN::TOP_LEVEL) {
|
||||
|
|
|
@ -2523,7 +2523,7 @@ class Diaspora
|
|||
}
|
||||
|
||||
// Do we already have this item?
|
||||
$fields = ['body', 'tag', 'app', 'created', 'object-type', 'uri', 'guid',
|
||||
$fields = ['body', 'title', 'attach', 'tag', 'app', 'created', 'object-type', 'uri', 'guid',
|
||||
'author-name', 'author-link', 'author-avatar'];
|
||||
$condition = ['guid' => $guid, 'visible' => true, 'deleted' => false, 'private' => false];
|
||||
$item = Item::selectFirst($fields, $condition);
|
||||
|
@ -2701,9 +2701,15 @@ class Diaspora
|
|||
$original_item["created"],
|
||||
$orig_url
|
||||
);
|
||||
|
||||
if (!empty($original_item['title'])) {
|
||||
$prefix .= '[h3]' . $original_item['title'] . "[/h3]\n";
|
||||
}
|
||||
|
||||
$datarray["body"] = $prefix.$original_item["body"]."[/share]";
|
||||
|
||||
$datarray["tag"] = $original_item["tag"];
|
||||
$datarray["attach"] = $original_item["attach"];
|
||||
$datarray["app"] = $original_item["app"];
|
||||
|
||||
$datarray["plink"] = self::plink($author, $guid);
|
||||
|
@ -3385,69 +3391,37 @@ class Diaspora
|
|||
{
|
||||
$body = trim($body);
|
||||
|
||||
$reshared = Item::getShareArray(['body' => $body]);
|
||||
if (empty($reshared)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip if it isn't a pure repeated messages
|
||||
// Does it start with a share?
|
||||
if ((strpos($body, "[share") > 0) && $complete) {
|
||||
if (!empty($reshared['comment']) && $complete) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Does it end with a share?
|
||||
if (strlen($body) > (strrpos($body, "[/share]") + 8)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$attributes = preg_replace("/\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism", "$1", $body);
|
||||
// Skip if there is no shared message in there
|
||||
if ($body == $attributes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we don't do the complete check we quit here
|
||||
|
||||
$guid = "";
|
||||
preg_match("/guid='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$guid = $matches[1];
|
||||
}
|
||||
|
||||
preg_match('/guid="(.*?)"/ism', $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$guid = $matches[1];
|
||||
}
|
||||
|
||||
if (($guid != "") && $complete) {
|
||||
$condition = ['guid' => $guid, 'network' => [Protocol::DFRN, Protocol::DIASPORA]];
|
||||
if (!empty($reshared['guid']) && $complete) {
|
||||
$condition = ['guid' => $reshared['guid'], 'network' => [Protocol::DFRN, Protocol::DIASPORA]];
|
||||
$item = Item::selectFirst(['contact-id'], $condition);
|
||||
if (DBA::isResult($item)) {
|
||||
$ret = [];
|
||||
$ret["root_handle"] = self::handleFromContact($item["contact-id"]);
|
||||
$ret["root_guid"] = $guid;
|
||||
$ret["root_guid"] = $reshared['guid'];
|
||||
return $ret;
|
||||
} elseif ($complete) {
|
||||
// We are resharing something that isn't a DFRN or Diaspora post.
|
||||
// So we have to return "false" on "$complete" to not trigger a reshare.
|
||||
return false;
|
||||
}
|
||||
} elseif (($guid == "") && $complete) {
|
||||
} elseif (empty($reshared['guid']) && $complete) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$ret["root_guid"] = $guid;
|
||||
|
||||
$profile = "";
|
||||
preg_match("/profile='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$profile = $matches[1];
|
||||
}
|
||||
|
||||
preg_match('/profile="(.*?)"/ism', $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$profile = $matches[1];
|
||||
}
|
||||
|
||||
$ret = [];
|
||||
|
||||
if (!empty($profile) && ($cid = Contact::getIdForURL($profile))) {
|
||||
if (!empty($reshared['profile']) && ($cid = Contact::getIdForURL($reshared['profile']))) {
|
||||
$contact = DBA::selectFirst('contact', ['addr'], ['id' => $cid]);
|
||||
if (!empty($contact['addr'])) {
|
||||
$ret['root_handle'] = $contact['addr'];
|
||||
|
|
|
@ -1199,37 +1199,12 @@ class OStatus
|
|||
*/
|
||||
private static function getResharedGuid(array $item)
|
||||
{
|
||||
$body = trim($item["body"]);
|
||||
|
||||
// Skip if it isn't a pure repeated messages
|
||||
// Does it start with a share?
|
||||
if (strpos($body, "[share") > 0) {
|
||||
return "";
|
||||
$reshared = Item::getShareArray($item);
|
||||
if (empty($reshared['guid']) || !empty($reshared['comment'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Does it end with a share?
|
||||
if (strlen($body) > (strrpos($body, "[/share]") + 8)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
$attributes = preg_replace("/\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism", "$1", $body);
|
||||
// Skip if there is no shared message in there
|
||||
if ($body == $attributes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$guid = "";
|
||||
preg_match("/guid='(.*?)'/ism", $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$guid = $matches[1];
|
||||
}
|
||||
|
||||
preg_match('/guid="(.*?)"/ism', $attributes, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$guid = $matches[1];
|
||||
}
|
||||
|
||||
return $guid;
|
||||
return $reshared['guid'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue