]> git.mxchange.org Git - friendica.git/blobdiff - src/Protocol/OStatus.php
Merge branch 'post-reason' of github.com:annando/friendica into post-reason
[friendica.git] / src / Protocol / OStatus.php
index c8405d953576d9dfbd226cf23052e2750271dd68..6531d75af1d8c765af170f3e02d5f682c8564317 100644 (file)
@@ -21,7 +21,6 @@
 
 namespace Friendica\Protocol;
 
-use DOMAttr;
 use DOMDocument;
 use DOMElement;
 use DOMXPath;
@@ -225,7 +224,7 @@ class OStatus
                        Contact::update($contact, ['id' => $contact['id']], $current);
 
                        if (!empty($author['author-avatar']) && ($author['author-avatar'] != $current['avatar'])) {
-                               Logger::info("Update profile picture for contact ".$contact["id"]);
+                               Logger::info('Update profile picture for contact ' . $contact['id']);
                                Contact::updateAvatar($contact['id'], $author['author-avatar']);
                        }
 
@@ -381,7 +380,7 @@ class OStatus
                                foreach ($hub_attributes as $hub_attribute) {
                                        if ($hub_attribute->name == 'href') {
                                                $hub = $hub_attribute->textContent;
-                                               Logger::info("Found hub ", ['hub' => $hub]);
+                                               Logger::info('Found hub ', ['hub' => $hub]);
                                        }
                                }
                        }
@@ -459,7 +458,7 @@ class OStatus
 
                        if (in_array($item['verb'], [Activity::O_UNFAVOURITE, Activity::UNFAVORITE])) {
                                // Ignore "Unfavorite" message
-                               Logger::info("Ignore unfavorite message ", ['item' => $item]);
+                               Logger::info('Ignore unfavorite message ', ['item' => $item]);
                                continue;
                        }
 
@@ -473,13 +472,13 @@ class OStatus
 
                        if ($item['verb'] == Activity::JOIN) {
                                // ignore "Join" messages
-                               Logger::info("Ignore join message ", ['item' => $item]);
+                               Logger::info('Ignore join message ', ['item' => $item]);
                                continue;
                        }
 
                        if ($item['verb'] == 'http://mastodon.social/schema/1.0/block') {
                                // ignore mastodon "block" messages
-                               Logger::info("Ignore block message ", ['item' => $item]);
+                               Logger::info('Ignore block message ', ['item' => $item]);
                                continue;
                        }
 
@@ -496,7 +495,7 @@ class OStatus
 
                        if ($item['verb'] == Activity::FAVORITE) {
                                $orig_uri = $xpath->query('activity:object/atom:id', $entry)->item(0)->nodeValue;
-                               Logger::notice("Favorite", ['uri' => $orig_uri, 'item' => $item]);
+                               Logger::notice('Favorite', ['uri' => $orig_uri, 'item' => $item]);
 
                                $item['verb'] = Activity::LIKE;
                                $item['thr-parent'] = $orig_uri;
@@ -506,7 +505,7 @@ class OStatus
 
                        // http://activitystrea.ms/schema/1.0/rsvp-yes
                        if (!in_array($item['verb'], [Activity::POST, Activity::LIKE, Activity::SHARE])) {
-                               Logger::info("Unhandled verb", ['verb' => $item['verb'], 'item' => $item]);
+                               Logger::info('Unhandled verb', ['verb' => $item['verb'], 'item' => $item]);
                        }
 
                        self::processPost($xpath, $entry, $item, $importer);
@@ -522,10 +521,10 @@ class OStatus
                                                $valid = !$uid || DI::pConfig()->get($uid, 'system', 'accept_only_sharer') != Item::COMPLETION_NONE;
 
                                                if ($valid) {
-                                                       Logger::info("Item with uri " . self::$itemlist[0]['uri'] . " will be imported due to the system settings.");
+                                                       Logger::info('Item with URI ' . self::$itemlist[0]['uri'] . ' will be imported due to the system settings.');
                                                }
                                        } else {
-                                               Logger::info("Item with uri " . self::$itemlist[0]['uri'] . " belongs to a contact (" . self::$itemlist[0]['contact-id'] . "). It will be imported.");
+                                               Logger::info('Item with URI ' . self::$itemlist[0]['uri'] . ' belongs to a contact (' . self::$itemlist[0]['contact-id'] . '). It will be imported.');
                                        }
 
                                        if ($valid && DI::pConfig()->get($uid, 'system', 'accept_only_sharer') != Item::COMPLETION_LIKE) {
@@ -538,7 +537,7 @@ class OStatus
                                                        }
                                                }
                                                if ($valid) {
-                                                       Logger::info("Item with URI " . self::$itemlist[0]['uri'] . " will be imported since the thread contains posts or shares.");
+                                                       Logger::info('Item with URI ' . self::$itemlist[0]['uri'] . ' will be imported since the thread contains posts or shares.');
                                                }
                                        }
                                } else {
@@ -557,12 +556,12 @@ class OStatus
                                        foreach (self::$itemlist as $item) {
                                                $found = Post::exists(['uid' => $importer['uid'], 'uri' => $item['uri']]);
                                                if ($found) {
-                                                       Logger::notice("Item with uri " . $item['uri'] . " for user " . $importer['uid'] . " already exists.");
+                                                       Logger::notice('Item with URI ' . $item['uri'] . ' for user ' . $importer['uid'] . ' already exists.');
                                                } elseif ($item['contact-id'] < 0) {
-                                                       Logger::notice("Item with uri " . $item['uri'] . " is from a blocked contact.");
+                                                       Logger::notice('Item with URI ' . $item['uri'] . ' is from a blocked contact.');
                                                } else {
                                                        $ret = Item::insert($item);
-                                                       Logger::info("Item with uri " . $item['uri'] . " for user " . $importer['uid'] . " stored. Return value: " . $ret);
+                                                       Logger::info('Item with URI ' . $item['uri'] . ' for user ' . $importer['uid'] . ' stored. Return value: ' . $ret);
                                                }
                                        }
                                }
@@ -617,16 +616,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;
                                }
                        }
                }
@@ -705,14 +704,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 != '') {
@@ -726,194 +717,9 @@ class OStatus
                        $item['gravity'] = GRAVITY_PARENT;
                }
 
-               if (($item['author-link'] != '') && !empty($item['protocol'])) {
-                       $item = Conversation::insert($item);
-               }
-
                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
         *
@@ -926,30 +732,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);
 
@@ -1014,21 +796,11 @@ 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 couldn't be fetched for URI: " . $related_uri . " - href: " . $related);
+                       Logger::info('XML could not be fetched for URI: ' . $related_uri . ' - href: ' . $related);
                }
                return;
        }
@@ -1131,10 +903,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':
@@ -1169,7 +938,7 @@ class OStatus
                                                break;
 
                                        default:
-                                               Logger::warning('Unsupported rel=' . $attribute['rel'] . ',href=' . $attribute['href'] . ',object-type=' . $attribute['object-type']);
+                                               Logger::warning('Unsupported rel=' . $attribute['rel'] . ', href=' . $attribute['href'] . ', object-type=' . $item['object-type']);
                                }
                        }
                }
@@ -1212,7 +981,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
         */
@@ -1240,7 +1009,7 @@ class OStatus
                                $url = $siteinfo['image'];
                        }
 
-                       $body = trim($siteinfo['text']) . " [url]" . $url . "[/url]\n[img]" . $preview . "[/img]";
+                       $body = trim($siteinfo['text']) . ' [url]' . $url . "[/url]\n[img]" . $preview . '[/img]';
                }
 
                return $body;
@@ -1253,10 +1022,10 @@ class OStatus
         * @param array       $owner     Contact data of the poster
         * @param string      $filter    The related feed filter (activity, posts or comments)
         *
-        * @return DOMAttr Header root element
+        * @return DOMElement Header root element
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       private static function addHeader(DOMDocument $doc, array $owner, string $filter): DOMAttr
+       private static function addHeader(DOMDocument $doc, array $owner, string $filter): DOMElement
        {
                $root = $doc->createElementNS(ActivityNamespace::ATOM1, 'feed');
                $doc->appendChild($root);
@@ -1333,11 +1102,11 @@ class OStatus
 
                if ($owner['contact-type'] == Contact::TYPE_COMMUNITY) {
                        $members = DBA::count('contact', [
-                               'uid' => $owner['uid'],
-                               'self' => false,
+                               'uid'     => $owner['uid'],
+                               'self'    => false,
                                'pending' => false,
                                'archive' => false,
-                               'hidden' => false,
+                               'hidden'  => false,
                                'blocked' => false,
                        ]);
                        XML::addElement($doc, $root, 'statusnet:group_info', '', ['member_count' => $members]);
@@ -1350,12 +1119,12 @@ class OStatus
         * Add the link to the push hubs to the XML document
         *
         * @param DOMDocument $doc  XML document
-        * @param addHubLink  $root XML root element where the hub links are added
+        * @param DOMElement  $root XML root element where the hub links are added
         * @param string      $nick Nickname
         * @return void
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       public static function addHubLink(DOMDocument $doc, DOMAttr $root, string $nick)
+       public static function addHubLink(DOMDocument $doc, DOMElement $root, string $nick)
        {
                $h = DI::baseUrl() . '/pubsubhubbub/' . $nick;
                XML::addElement($doc, $root, 'link', '', ['href' => $h, 'rel' => 'hub']);
@@ -1365,12 +1134,12 @@ class OStatus
         * Adds attachment data to the XML document
         *
         * @param DOMDocument $doc  XML document
-        * @param DOMAttr     $root XML root element where the hub links are added
+        * @param DOMElement  $root XML root element where the hub links are added
         * @param array       $item Data of the item that is to be posted
         * @return void
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       public static function getAttachment(DOMDocument $doc, DOMAttr $root, array $item)
+       public static function getAttachment(DOMDocument $doc, DOMElement $root, array $item)
        {
                $siteinfo = BBCode::getAttachedData($item['body']);
 
@@ -1389,6 +1158,7 @@ class OStatus
                                        }
                                }
                                break;
+
                        case 'video':
                                $attributes = [
                                        'rel' => 'enclosure',
@@ -1399,7 +1169,9 @@ class OStatus
                                ];
                                XML::addElement($doc, $root, 'link', '', $attributes);
                                break;
+
                        default:
+                               Logger::warning('Unsupported type', ['type' => $siteinfo['type'], 'url' => $siteinfo['url'] ?? '']);
                                break;
                }
 
@@ -1592,7 +1364,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']))) {
-                       Logger::info("OStatus entry is from author " . $owner['url'] . " - not from " . $item['author-link'] . ". Quitting.");
+                       Logger::info('OStatus entry is from author ' . $owner['url'] . ' - not from ' . $item['author-link'] . '. Quitting.');
                }
 
                $entry = self::entryHeader($doc, $owner, $item, $toplevel);
@@ -1742,17 +1514,17 @@ 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']))) {
-                       Logger::info("OStatus entry is from author " . $owner['url'] . " - not from " . $item['author-link'] . ". Quitting.");
+                       Logger::info('OStatus entry is from author ' . $owner['url'] . ' - not from ' . $item['author-link'] . '. Quitting.');
                }
 
                if (!$toplevel) {
                        if (!empty($item['title'])) {
                                $title = BBCode::convertForUriId($item['uri-id'], $item['title'], BBCode::OSTATUS);
                        } else {
-                               $title = sprintf("New note by %s", $owner['nick']);
+                               $title = sprintf('New note by %s', $owner['nick']);
                        }
                } else {
-                       $title = sprintf("New comment by %s", $owner['nick']);
+                       $title = sprintf('New comment by %s', $owner['nick']);
                }
 
                $entry = self::entryHeader($doc, $owner, $item, $toplevel);
@@ -1833,7 +1605,7 @@ class OStatus
                $body = self::formatPicturePost($body, $item['uri-id']);
 
                if (!empty($item['title'])) {
-                       $body = "[b]" . $item['title'] . "[/b]\n\n" . $body;
+                       $body = '[b]' . $item['title'] . "[/b]\n\n" . $body;
                }
 
                $body = BBCode::convertForUriId($item['uri-id'], $body, BBCode::OSTATUS);
@@ -1902,19 +1674,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]);
 
@@ -1945,14 +1705,14 @@ class OStatus
                        $contact = Contact::getByURL($mention, false, ['contact-type']);
                        if (!empty($contact) && ($contact['contact-type'] == Contact::TYPE_COMMUNITY)) {
                                XML::addElement($doc, $entry, 'link', '', [
-                                               'rel' => 'mentioned',
-                                               'ostatus:object-type' => Activity\ObjectType::GROUP,
-                                               'href' => $mention,
+                                       'rel' => 'mentioned',
+                                       'ostatus:object-type' => Activity\ObjectType::GROUP,
+                                       'href' => $mention,
                                ]);
                        } else {
                                XML::addElement($doc, $entry, 'link', '', [
-                                               'rel' => 'mentioned',
-                                               'ostatus:object-type' => Activity\ObjectType::PERSON,
+                                       'rel' => 'mentioned',
+                                       'ostatus:object-type' => Activity\ObjectType::PERSON,
                                                'href' => $mention,
                                ]);
                        }
@@ -2015,7 +1775,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