X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FProtocol%2FOStatus.php;h=81a0c38842edcc77ad8d298486e254da4f091f45;hb=d75cd8a00a88a52e6d7bf67c91ba464c81c644c1;hp=f03ed2b4fb3f95686e82ccff8118659f011ddad1;hpb=bf600905d3fca0d9a34adf51e19a57532c88ad6c;p=friendica.git diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index f03ed2b4fb..81a0c38842 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -24,6 +24,7 @@ namespace Friendica\Protocol; use DOMDocument; use DOMElement; use DOMXPath; +use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Core\Cache\Enum\Duration; @@ -102,9 +103,9 @@ class OStatus */ if ($aliaslink != '') { $contact = DBA::selectFirst('contact', [], [ - "`uid` = ? AND `alias` = ? AND `network` != ? AND `rel` IN (?, ?)", + "`uid` = ? AND `alias` = ? AND `rel` IN (?, ?)", $importer['uid'], - $aliaslink, Protocol::STATUSNET, + $aliaslink, Contact::SHARING, Contact::FRIEND, ]); } @@ -115,11 +116,10 @@ class OStatus } $contact = DBA::selectFirst('contact', [], [ - "`uid` = ? AND `nurl` IN (?, ?) AND `network` != ? AND `rel` IN (?, ?)", + "`uid` = ? AND `nurl` IN (?, ?) AND `rel` IN (?, ?)", $importer['uid'], Strings::normaliseLink($author['author-link']), Strings::normaliseLink($aliaslink), - Protocol::STATUSNET, Contact::SHARING, Contact::FRIEND, ]); @@ -127,10 +127,9 @@ class OStatus if (!DBA::isResult($contact) && ($addr != '')) { $contact = DBA::selectFirst('contact', [], [ - "`uid` = ? AND `addr` = ? AND `network` != ? AND `rel` IN (?, ?)", + "`uid` = ? AND `addr` = ? AND `rel` IN (?, ?)", $importer['uid'], $addr, - Protocol::STATUSNET, Contact::SHARING, Contact::FRIEND, ]); @@ -391,7 +390,7 @@ class OStatus $header['network'] = Protocol::OSTATUS; $header['wall'] = 0; $header['origin'] = 0; - $header['gravity'] = GRAVITY_COMMENT; + $header['gravity'] = Item::GRAVITY_COMMENT; if (!is_object($doc->firstChild) || empty($doc->firstChild->tagName)) { return false; @@ -499,7 +498,7 @@ class OStatus $item['verb'] = Activity::LIKE; $item['thr-parent'] = $orig_uri; - $item['gravity'] = GRAVITY_ACTIVITY; + $item['gravity'] = Item::GRAVITY_ACTIVITY; $item['object-type'] = Activity\ObjectType::NOTE; } @@ -616,16 +615,16 @@ class OStatus $item['created'] = XML::getFirstNodeValue($xpath, 'atom:published/text()', $entry); $item['edited'] = XML::getFirstNodeValue($xpath, 'atom:updated/text()', $entry); - $item['conversation-uri'] = XML::getFirstNodeValue($xpath, 'ostatus:conversation/text()', $entry); + $item['conversation'] = XML::getFirstNodeValue($xpath, 'ostatus:conversation/text()', $entry); $conv = $xpath->query('ostatus:conversation', $entry); if (is_object($conv->item(0))) { foreach ($conv->item(0)->attributes as $attributes) { if ($attributes->name == 'ref') { - $item['conversation-uri'] = $attributes->textContent; + $item['conversation'] = $attributes->textContent; } if ($attributes->name == 'href') { - $item['conversation-href'] = $attributes->textContent; + $item['conversation'] = $attributes->textContent; } } } @@ -704,14 +703,6 @@ class OStatus } } - if (($self != '') && empty($item['protocol'])) { - self::fetchSelf($self, $item); - } - - if (!empty($item['conversation-href'])) { - self::fetchConversation($item['conversation-href'], $item['conversation-uri']); - } - if (isset($item['thr-parent'])) { if (!Post::exists(['uid' => $importer['uid'], 'uri' => $item['thr-parent']])) { if ($related != '') { @@ -722,197 +713,12 @@ class OStatus } } else { $item['thr-parent'] = $item['uri']; - $item['gravity'] = GRAVITY_PARENT; - } - - if (($item['author-link'] != '') && !empty($item['protocol'])) { - $item = Conversation::insert($item); + $item['gravity'] = Item::GRAVITY_PARENT; } self::$itemlist[] = $item; } - /** - * Fetch the conversation for posts - * - * @param string $conversation The link to the conversation - * @param string $conversation_uri The conversation in "uri" format - * @return void - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - */ - private static function fetchConversation(string $conversation, string $conversation_uri) - { - // Ensure that we only store a conversation once in a process - if (isset(self::$conv_list[$conversation])) { - return; - } - - self::$conv_list[$conversation] = true; - - $curlResult = DI::httpClient()->get($conversation, HttpClientAccept::ATOM_XML); - - if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { - return; - } - - $xml = ''; - - if ($curlResult->inHeader('Content-Type') && - in_array('application/atom+xml', $curlResult->getHeader('Content-Type'))) { - $xml = $curlResult->getBody(); - } - - if ($xml == '') { - $doc = new DOMDocument(); - if (!@$doc->loadHTML($curlResult->getBody())) { - return; - } - $xpath = new DOMXPath($doc); - - $links = $xpath->query('//link'); - if ($links) { - $file = ''; - foreach ($links as $link) { - $attribute = self::readAttributes($link); - if (($attribute['rel'] == 'alternate') && ($attribute['type'] == 'application/atom+xml')) { - $file = $attribute['href']; - } - } - if ($file != '') { - $conversation_atom = DI::httpClient()->get($attribute['href'], HttpClientAccept::ATOM_XML); - - if ($conversation_atom->isSuccess()) { - $xml = $conversation_atom->getBody(); - } - } - } - } - - if ($xml == '') { - return; - } - - self::storeConversation($xml, $conversation, $conversation_uri); - } - - /** - * Store a feed in several conversation entries - * - * @param string $xml The feed - * @param string $conversation conversation - * @param string $conversation_uri conversation uri - * @return void - * @throws \Exception - */ - private static function storeConversation(string $xml, string $conversation = '', string $conversation_uri = '') - { - $doc = new DOMDocument(); - @$doc->loadXML($xml); - - $xpath = new DOMXPath($doc); - $xpath->registerNamespace('atom', ActivityNamespace::ATOM1); - $xpath->registerNamespace('thr', ActivityNamespace::THREAD); - $xpath->registerNamespace('ostatus', ActivityNamespace::OSTATUS); - - $entries = $xpath->query('/atom:feed/atom:entry'); - - // Now store the entries - foreach ($entries as $entry) { - $doc2 = new DOMDocument(); - $doc2->preserveWhiteSpace = false; - $doc2->formatOutput = true; - - $conv_data = []; - - $conv_data['protocol'] = Conversation::PARCEL_SPLIT_CONVERSATION; - $conv_data['direction'] = Conversation::PULL; - $conv_data['network'] = Protocol::OSTATUS; - $conv_data['uri'] = XML::getFirstNodeValue($xpath, 'atom:id/text()', $entry); - - $inreplyto = $xpath->query('thr:in-reply-to', $entry); - if (is_object($inreplyto->item(0))) { - foreach ($inreplyto->item(0)->attributes as $attributes) { - if ($attributes->name == 'ref') { - $conv_data['reply-to-uri'] = $attributes->textContent; - } - } - } - - $conv_data['conversation-uri'] = XML::getFirstNodeValue($xpath, 'ostatus:conversation/text()', $entry); - - $conv = $xpath->query('ostatus:conversation', $entry); - if (is_object($conv->item(0))) { - foreach ($conv->item(0)->attributes as $attributes) { - if ($attributes->name == 'ref') { - $conv_data['conversation-uri'] = $attributes->textContent; - } - if ($attributes->name == 'href') { - $conv_data['conversation-href'] = $attributes->textContent; - } - } - } - - if ($conversation != '') { - $conv_data['conversation-uri'] = $conversation; - } - - if ($conversation_uri != '') { - $conv_data['conversation-uri'] = $conversation_uri; - } - - $entry = $doc2->importNode($entry, true); - - $doc2->appendChild($entry); - - $conv_data['source'] = $doc2->saveXML(); - - Logger::info('Store conversation data for uri '.$conv_data['uri']); - Conversation::insert($conv_data); - } - } - - /** - * Fetch the own post so that it can be stored later - * - * We want to store the original data for later processing. - * This function is meant for cases where we process a feed with multiple entries. - * In that case we need to fetch the single posts here. - * - * @param string $self The link to the self item - * @param array $item The item array - * @return void - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - */ - private static function fetchSelf(string $self, array &$item) - { - $condition = ['item-uri' => $self, 'protocol' => [Conversation::PARCEL_DFRN, - Conversation::PARCEL_DIASPORA_DFRN, Conversation::PARCEL_LOCAL_DFRN, - Conversation::PARCEL_DIRECT, Conversation::PARCEL_SALMON]]; - if (DBA::exists('conversation', $condition)) { - Logger::info('Conversation '.$item['uri'].' is already stored.'); - return; - } - - $curlResult = DI::httpClient()->get($self, HttpClientAccept::ATOM_XML); - - if (!$curlResult->isSuccess()) { - return; - } - - // We reformat the XML to make it better readable - $doc = new DOMDocument(); - $doc->loadXML($curlResult->getBody()); - $doc->preserveWhiteSpace = false; - $doc->formatOutput = true; - $xml = $doc->saveXML(); - - $item['protocol'] = Conversation::PARCEL_SALMON; - $item['source'] = $xml; - $item['direction'] = Conversation::PULL; - - Logger::info('Conversation '.$item['uri'].' is now fetched.'); - } - /** * Fetch related posts and processes them * @@ -925,30 +731,6 @@ class OStatus */ private static function fetchRelated(string $related, string $related_uri, array $importer) { - $condition = [ - 'item-uri' => $related_uri, - 'protocol' => [ - Conversation::PARCEL_DFRN, - Conversation::PARCEL_DIASPORA_DFRN, - Conversation::PARCEL_LOCAL_DFRN, - Conversation::PARCEL_DIRECT, - Conversation::PARCEL_SALMON, - ], - ]; - $conversation = DBA::selectFirst('conversation', ['source', 'protocol'], $condition); - if (DBA::isResult($conversation)) { - $stored = true; - $xml = $conversation['source']; - if (self::process($xml, $importer, $contact, $hub, $stored, false, Conversation::PULL)) { - Logger::info('Got valid cached XML for URI '.$related_uri); - return; - } - if ($conversation['protocol'] == Conversation::PARCEL_SALMON) { - Logger::info('Delete invalid cached XML for URI '.$related_uri); - DBA::delete('conversation', ['item-uri' => $related_uri]); - } - } - $stored = false; $curlResult = DI::httpClient()->get($related, HttpClientAccept::ATOM_XML); @@ -1013,18 +795,8 @@ class OStatus } } - // Finally we take the data that we fetched from "ostatus:conversation" - if ($xml == '') { - $condition = ['item-uri' => $related_uri, 'protocol' => Conversation::PARCEL_SPLIT_CONVERSATION]; - $conversation = DBA::selectFirst('conversation', ['source'], $condition); - if (DBA::isResult($conversation)) { - $stored = true; - Logger::info('Got cached XML from conversation for URI ' . $related_uri); - $xml = $conversation['source']; - } - } - if ($xml != '') { + $hub = ''; self::process($xml, $importer, $contact, $hub, $stored, false, Conversation::PULL); } else { Logger::info('XML could not be fetched for URI: ' . $related_uri . ' - href: ' . $related); @@ -1130,10 +902,7 @@ class OStatus case 'ostatus:conversation': $link_data['conversation'] = $attribute['href']; - $item['conversation-href'] = $link_data['conversation']; - if (!isset($item['conversation-uri'])) { - $item['conversation-uri'] = $item['conversation-href']; - } + $item['conversation'] = $link_data['conversation']; break; case 'enclosure': @@ -1168,7 +937,7 @@ class OStatus break; default: - Logger::warning('Unsupported rel=' . $attribute['rel'] . ', href=' . $attribute['href'] . ', object-type=' . $attribute['object-type']); + Logger::notice('Unsupported rel=' . $attribute['rel'] . ', href=' . $attribute['href'] . ', object-type=' . $item['object-type']); } } } @@ -1211,7 +980,7 @@ class OStatus * Cleans the body of a post if it contains picture links * * @param string $body The body - * @param integer $uriid URI id + * @param integer $uriId * @return string The cleaned body * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ @@ -1291,9 +1060,9 @@ class OStatus $attributes = [ 'uri' => 'https://friendi.ca', - 'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION, + 'version' => App::VERSION . '-' . DB_UPDATE_VERSION, ]; - XML::addElement($doc, $root, 'generator', FRIENDICA_PLATFORM, $attributes); + XML::addElement($doc, $root, 'generator', App::PLATFORM, $attributes); XML::addElement($doc, $root, 'id', DI::baseUrl() . '/profile/' . $owner['nick']); XML::addElement($doc, $root, 'title', $title); XML::addElement($doc, $root, 'subtitle', sprintf("Updates from %s on %s", $owner['name'], DI::config()->get('config', 'sitename'))); @@ -1399,10 +1168,6 @@ class OStatus ]; XML::addElement($doc, $root, 'link', '', $attributes); break; - - default: - Logger::warning('Unsupported type', ['type' => $siteinfo['type'], 'url' => $siteinfo['url'] ?? '']); - break; } if (!DI::config()->get('system', 'ostatus_not_attach_preview') && ($siteinfo['type'] != 'photo') && isset($siteinfo['image'])) { @@ -1419,7 +1184,7 @@ class OStatus } } - foreach (Post\Media::getByURIId($item['uri-id'], [Post\Media::DOCUMENT, Post\Media::TORRENT, Post\Media::UNKNOWN]) as $attachment) { + foreach (Post\Media::getByURIId($item['uri-id'], [Post\Media::DOCUMENT, Post\Media::TORRENT]) as $attachment) { $attributes = ['rel' => 'enclosure', 'href' => $attachment['url'], 'type' => $attachment['mimetype']]; @@ -1593,7 +1358,7 @@ class OStatus */ private static function likeEntry(DOMDocument $doc, array $item, array $owner, bool $toplevel): DOMElement { - if (($item['gravity'] != GRAVITY_PARENT) && (Strings::normaliseLink($item['author-link']) != Strings::normaliseLink($owner['url']))) { + if (($item['gravity'] != Item::GRAVITY_PARENT) && (Strings::normaliseLink($item['author-link']) != Strings::normaliseLink($owner['url']))) { Logger::info('OStatus entry is from author ' . $owner['url'] . ' - not from ' . $item['author-link'] . '. Quitting.'); } @@ -1743,7 +1508,7 @@ class OStatus */ private static function noteEntry(DOMDocument $doc, array $item, array $owner, bool $toplevel): DOMElement { - if (($item['gravity'] != GRAVITY_PARENT) && (Strings::normaliseLink($item['author-link']) != Strings::normaliseLink($owner['url']))) { + if (($item['gravity'] != Item::GRAVITY_PARENT) && (Strings::normaliseLink($item['author-link']) != Strings::normaliseLink($owner['url']))) { Logger::info('OStatus entry is from author ' . $owner['url'] . ' - not from ' . $item['author-link'] . '. Quitting.'); } @@ -1831,7 +1596,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'])) { @@ -1873,7 +1638,7 @@ class OStatus { $mentioned = []; - if ($item['gravity'] != GRAVITY_PARENT) { + if ($item['gravity'] != Item::GRAVITY_PARENT) { $parent = Post::selectFirst(['guid', 'author-link', 'owner-link'], ['id' => $item['parent']]); $thrparent = Post::selectFirst(['guid', 'author-link', 'owner-link', 'plink'], ['uid' => $owner['uid'], 'uri' => $item['thr-parent']]); @@ -1904,19 +1669,7 @@ class OStatus } if (intval($item['parent']) > 0) { - $conversation_href = $conversation_uri = str_replace('/objects/', '/context/', $item['thr-parent']); - - if (isset($parent_item)) { - $conversation = DBA::selectFirst('conversation', ['conversation-uri', 'conversation-href'], ['item-uri' => $parent_item]); - if (DBA::isResult($conversation)) { - if ($conversation['conversation-uri'] != '') { - $conversation_uri = $conversation['conversation-uri']; - } - if ($conversation['conversation-href'] != '') { - $conversation_href = $conversation['conversation-href']; - } - } - } + $conversation_href = $conversation_uri = $item['conversation']; XML::addElement($doc, $entry, 'link', '', ['rel' => 'ostatus:conversation', 'href' => $conversation_href]); @@ -2017,7 +1770,7 @@ class OStatus * cache or it is empty * * @param string $owner_nick Nickname of the feed owner - * @param string $last_update Date of the last update + * @param string $last_update Date of the last update (in "Y-m-d H:i:s" format) * @param integer $max_items Number of maximum items to fetch * @param string $filter Feed items filter (activity, posts or comments) * @param boolean $nocache Wether to bypass caching