X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FProtocol%2FDFRN.php;h=10c43626a1d3e72b2653e3d40e16dbbda5acf241;hb=64b40254b001ee69e9b040680f4cc632405cffce;hp=625afb215a92ff4604b7c8777a0febee4f213564;hpb=2e9d1a904618247ff35f7f37a1f1a0a15106eba6;p=friendica.git diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index 625afb215a..10c43626a1 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -1,6 +1,6 @@ set('system', 'site_pubkey', $res['pubkey']); } - $profilephotos = Photo::selectToArray(['resource-id' , 'scale'], ['profile' => true, 'uid' => $uid], ['order' => ['scale']]); + $profilephotos = Photo::selectToArray(['resource-id', 'scale', 'type'], ['profile' => true, 'uid' => $uid], ['order' => ['scale']]); $photos = []; $ext = Images::supportedTypes(); foreach ($profilephotos as $p) { - $photos[$p['scale']] = DI::baseUrl().'/photo/'.$p['resource-id'].'-'.$p['scale'].'.'.$ext[$p['type']]; + $photos[$p['scale']] = DI::baseUrl() . '/photo/' . $p['resource-id'] . '-' . $p['scale'] . '.' . $ext[$p['type']]; } - $doc = new DOMDocument('1.0', 'utf-8'); $doc->formatOutput = true; @@ -369,8 +369,8 @@ class DFRN XML::addElement($doc, $root, 'id', DI::baseUrl() . '/profile/' . $owner['nick']); XML::addElement($doc, $root, 'title', $owner['name']); - $attributes = ['uri' => 'https://friendi.ca', 'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION]; - XML::addElement($doc, $root, 'generator', FRIENDICA_PLATFORM, $attributes); + $attributes = ['uri' => 'https://friendi.ca', 'version' => App::VERSION . '-' . DB_UPDATE_VERSION]; + XML::addElement($doc, $root, 'generator', App::PLATFORM, $attributes); $attributes = ['rel' => 'license', 'href' => 'http://creativecommons.org/licenses/by/3.0/']; XML::addElement($doc, $root, 'link', '', $attributes); @@ -537,7 +537,7 @@ class DFRN XML::addElement($doc, $author, 'poco:utcOffset', DateTimeFormat::timezoneNow($profile['timezone'], 'P')); - if (trim($profile['homepage']) != '') { + if (trim($profile['homepage'])) { $urls = $doc->createElement('poco:urls'); XML::addElement($doc, $urls, 'poco:type', 'homepage'); XML::addElement($doc, $urls, 'poco:value', $profile['homepage']); @@ -545,7 +545,7 @@ class DFRN $author->appendChild($urls); } - if (trim($profile['pub_keywords']) != '') { + if (trim($profile['pub_keywords'] ?? '')) { $keywords = explode(',', $profile['pub_keywords']); foreach ($keywords as $keyword) { @@ -553,7 +553,7 @@ class DFRN } } - if (trim($profile['xmpp']) != '') { + if (trim($profile['xmpp'])) { $ims = $doc->createElement('poco:ims'); XML::addElement($doc, $ims, 'poco:type', 'xmpp'); XML::addElement($doc, $ims, 'poco:value', $profile['xmpp']); @@ -561,7 +561,7 @@ class DFRN $author->appendChild($ims); } - if (trim($profile['locality'] . $profile['region'] . $profile['country-name']) != '') { + if (trim($profile['locality'] . $profile['region'] . $profile['country-name'])) { $element = $doc->createElement('poco:address'); XML::addElement($doc, $element, 'poco:formatted', Profile::formatLocation($profile)); @@ -710,7 +710,7 @@ class DFRN */ private static function getAttachment($doc, $root, array $item) { - 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']]; @@ -747,7 +747,7 @@ class DFRN $mentioned = []; if (!$item['parent']) { - Logger::notice('Item without parent found.', ['type' => $type, 'item' => $item]); + Logger::warning('Item without parent found.', ['type' => $type, 'item' => $item]); return null; } @@ -773,7 +773,8 @@ 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)); + $body = Post\Media::addHTMLAttachmentToBody($item['uri-id'], $body); if ($item['private'] == Item::PRIVATE) { $body = Item::fixPrivatePhotos($body, $owner['uid'], $item, $cid); @@ -799,7 +800,7 @@ class DFRN $dfrnowner = self::addEntryAuthor($doc, "dfrn:owner", $item["owner-link"], $item); $entry->appendChild($dfrnowner); - if ($item['gravity'] != GRAVITY_PARENT) { + if ($item['gravity'] != Item::GRAVITY_PARENT) { $parent = Post::selectFirst(['guid', 'plink'], ['uri' => $item['thr-parent'], 'uid' => $item['uid']]); if (DBA::isResult($parent)) { $attributes = ["ref" => $item['thr-parent'], "type" => "text/html", @@ -810,27 +811,12 @@ class DFRN } // Add conversation data. This is used for OStatus - $conversation_href = DI::baseUrl()."/display/".$item["parent-guid"]; - $conversation_uri = $conversation_href; - - if (isset($parent_item)) { - $conversation = DBA::selectFirst('conversation', ['conversation-uri', 'conversation-href'], ['item-uri' => $item['thr-parent']]); - if (DBA::isResult($conversation)) { - if ($conversation['conversation-uri'] != '') { - $conversation_uri = $conversation['conversation-uri']; - } - if ($conversation['conversation-href'] != '') { - $conversation_href = $conversation['conversation-href']; - } - } - } - $attributes = [ - 'href' => $conversation_href, - 'ref' => $conversation_uri, + 'href' => $item['conversation'], + 'ref' => $item['conversation'], ]; - XML::addElement($doc, $entry, 'ostatus:conversation', $conversation_uri, $attributes); + XML::addElement($doc, $entry, 'ostatus:conversation', $item['conversation'], $attributes); XML::addElement($doc, $entry, 'id', $item['uri']); XML::addElement($doc, $entry, 'title', $item['title']); @@ -903,7 +889,7 @@ class DFRN if ($item['object-type'] != '') { XML::addElement($doc, $entry, 'activity:object-type', $item['object-type']); - } elseif ($item['gravity'] == GRAVITY_PARENT) { + } elseif ($item['gravity'] == Item::GRAVITY_PARENT) { XML::addElement($doc, $entry, 'activity:object-type', Activity\ObjectType::NOTE); } else { XML::addElement($doc, $entry, 'activity:object-type', Activity\ObjectType::COMMENT); @@ -995,12 +981,12 @@ class DFRN } } - $fcontact = FContact::getByURL($contact['addr']); - if (empty($fcontact)) { + try { + $pubkey = DI::dsprContact()->getByAddr(WebFingerUri::fromString($contact['addr']))->pubKey; + } catch (HTTPException\NotFoundException|\InvalidArgumentException $e) { Logger::notice('Unable to find contact details for ' . $contact['id'] . ' - ' . $contact['addr']); return -22; } - $pubkey = $fcontact['pubkey']; } else { $pubkey = ''; } @@ -1013,7 +999,7 @@ class DFRN $path_parts = explode('/', $parts['path']); array_pop($path_parts); $parts['path'] = implode('/', $path_parts); - $contact['batch'] = Uri::fromParts($parts); + $contact['batch'] = (string)Uri::fromParts($parts); } $dest_url = ($public_batch ? $contact['batch'] : $contact['notify']); @@ -1029,6 +1015,10 @@ class DFRN $xml = $postResult->getBody(); $curl_stat = $postResult->getReturnCode(); + if (!empty($contact['gsid']) && ($postResult->isTimeout() || empty($curl_stat))) { + GServer::setFailureById($contact['gsid']); + } + if (empty($curl_stat) || empty($xml)) { Logger::notice('Empty answer from ' . $contact['id'] . ' - ' . $dest_url); return -9; // timed out @@ -1050,6 +1040,10 @@ class DFRN return -23; } + if (!empty($contact['gsid'])) { + GServer::setReachableById($contact['gsid'], Protocol::DFRN); + } + if (!empty($res->message)) { Logger::info('Transmit to ' . $dest_url . ' returned status '.$res->status.' - '.$res->message); } @@ -1080,8 +1074,8 @@ class DFRN $fields = ['id', 'uid', 'url', 'network', 'avatar-date', 'avatar', 'name-date', 'uri-date', 'addr', 'name', 'nick', 'about', 'location', 'keywords', 'xmpp', 'bdyear', 'bd', 'hidden', 'contact-type']; - $condition = ["`uid` = ? AND `nurl` = ? AND `network` != ? AND NOT `pending` AND NOT `blocked`", - $importer["importer_uid"], Strings::normaliseLink($author["link"]), Protocol::STATUSNET]; + $condition = ["`uid` = ? AND `nurl` = ? AND NOT `pending` AND NOT `blocked`", + $importer["importer_uid"], Strings::normaliseLink($author["link"])]; if ($importer['account-type'] != User::ACCOUNT_TYPE_COMMUNITY) { $condition = DBA::mergeConditions($condition, ['rel' => [Contact::SHARING, Contact::FRIEND]]); @@ -1348,7 +1342,7 @@ class DFRN */ private static function processMail(DOMXPath $xpath, DOMNode $mail, array $importer) { - Logger::notice("Processing mails"); + Logger::info("Processing mails"); $msg = []; $msg['uid'] = $importer['importer_uid']; @@ -1376,7 +1370,7 @@ class DFRN */ private static function processSuggestion(DOMXPath $xpath, DOMNode $suggestion, array $importer) { - Logger::notice('Processing suggestions'); + Logger::info('Processing suggestions'); $url = $xpath->evaluate('string(dfrn:url[1]/text())', $suggestion); $cid = Contact::getIdForURL($url); @@ -1452,7 +1446,7 @@ class DFRN */ private static function processRelocation(DOMXPath $xpath, DOMNode $relocation, array $importer): bool { - Logger::notice("Processing relocations"); + Logger::info("Processing relocations"); /// @TODO Rewrite this to one statement $relocate = []; @@ -1481,9 +1475,8 @@ class DFRN // update contact $old = Contact::selectFirst(['photo', 'url'], ['id' => $importer['id'], 'uid' => $importer['importer_uid']]); - if (!DBA::isResult($old)) { - Logger::notice("Query failed to execute, no result returned in " . __FUNCTION__); + Logger::warning('Existing contact had not been fetched', ['id' => $importer['id']]); return false; } @@ -1506,7 +1499,7 @@ class DFRN Contact::updateAvatar($importer['id'], $relocate['avatar'], true); - Logger::notice('Contacts are updated.'); + Logger::info('Contacts are updated.'); /// @TODO /// merge with current record, current contents have priority @@ -1565,85 +1558,15 @@ class DFRN private static function getEntryType(array $importer, array $item): int { if ($item['thr-parent'] != $item['uri']) { - $community = false; - - if ($importer['account-type'] == User::ACCOUNT_TYPE_COMMUNITY) { - $sql_extra = ''; - $community = true; - Logger::notice("possible community action"); - } else { - $sql_extra = " AND `self` AND `wall`"; - } - // was the top-level post for this action written by somebody on this site? // Specifically, the recipient? - $parent = Post::selectFirst(['wall'], - ["`uri` = ? AND `uid` = ?" . $sql_extra, $item['thr-parent'], $importer['importer_uid']]); - - $is_a_remote_action = DBA::isResult($parent); - - if ($is_a_remote_action) { - return DFRN::REPLY_RC; + if (Post::exists(['uri' => $item['thr-parent'], 'uid' => $importer['importer_uid'], 'self' => true, 'wall' => true])) { + return self::REPLY_RC; } else { - return DFRN::REPLY; + return self::REPLY; } } else { - return DFRN::TOP_LEVEL; - } - } - - /** - * Send a "poke" - * - * @param array $item The new item record - * @param array $importer Record of the importer user mixed with contact of the content - * @return void - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - * @todo set proper type-hints (array?) - */ - private static function doPoke(array $item, array $importer) - { - $verb = urldecode(substr($item['verb'], strpos($item['verb'], '#')+1)); - if (!$verb) { - return; - } - $xo = XML::parseString($item['object']); - - if (($xo->type == Activity\ObjectType::PERSON) && ($xo->id)) { - // somebody was poked/prodded. Was it me? - $Blink = ''; - foreach ($xo->link as $l) { - $atts = $l->attributes(); - switch ($atts['rel']) { - case 'alternate': - $Blink = $atts['href']; - break; - - default: - break; - } - } - - if ($Blink && Strings::compareLink($Blink, DI::baseUrl() . '/profile/' . $importer['nickname'])) { - $author = DBA::selectFirst('contact', ['id', 'name', 'thumb', 'url'], ['id' => $item['author-id']]); - - $parent = Post::selectFirst(['id'], ['uri' => $item['thr-parent'], 'uid' => $importer['importer_uid']]); - $item['parent'] = $parent['id']; - - // send a notification - DI::notify()->createFromArray( - [ - 'type' => Notification\Type::POKE, - 'otype' => Notification\ObjectType::PERSON, - 'activity' => $verb, - 'verb' => $item['verb'], - 'uid' => $importer['importer_uid'], - 'cid' => $author['id'], - 'item' => $item, - 'link' => DI::baseUrl() . '/display/' . urlencode($item['guid']), - ] - ); - } + return self::TOP_LEVEL; } } @@ -1653,16 +1576,15 @@ class DFRN * @param int $entrytype Is it a toplevel entry, a comment or a relayed comment? * @param array $importer Record of the importer user mixed with contact of the content * @param array $item the new item record - * @param bool $is_like Is the verb a "like"? * * @return bool Should the processing of the entries be continued? * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function processVerbs(int $entrytype, array $importer, array &$item, bool &$is_like) + private static function processVerbs(int $entrytype, array $importer, array &$item) { Logger::info('Process verb ' . $item['verb'] . ' and object-type ' . $item['object-type'] . ' for entrytype ' . $entrytype); - if (($entrytype == DFRN::TOP_LEVEL) && !empty($importer['id'])) { + if (($entrytype == self::TOP_LEVEL) && !empty($importer['id'])) { // The filling of the the "contact" variable is done for legcy reasons // The functions below are partly used by ostatus.php as well - where we have this variable $contact = Contact::selectFirst([], ['id' => $importer['id']]); @@ -1672,22 +1594,22 @@ class DFRN // Big question: Do we need these functions? They were part of the "consume_feed" function. // This function once was responsible for DFRN and OStatus. if ($activity->match($item['verb'], Activity::FOLLOW)) { - Logger::notice("New follower"); + Logger::info("New follower"); Contact::addRelationship($importer, $contact, $item); return false; } if ($activity->match($item['verb'], Activity::UNFOLLOW)) { - Logger::notice("Lost follower"); + Logger::info("Lost follower"); Contact::removeFollower($contact); return false; } if ($activity->match($item['verb'], Activity::REQ_FRIEND)) { - Logger::notice("New friend request"); + Logger::info("New friend request"); Contact::addRelationship($importer, $contact, $item, true); return false; } if ($activity->match($item['verb'], Activity::UNFRIEND)) { - Logger::notice("Lost sharer"); + Logger::info("Lost sharer"); Contact::removeSharer($contact); return false; } @@ -1699,22 +1621,21 @@ class DFRN || ($item['verb'] == Activity::ATTENDMAYBE) || ($item['verb'] == Activity::ANNOUNCE) ) { - $is_like = true; - $item['gravity'] = GRAVITY_ACTIVITY; + $item['gravity'] = Item::GRAVITY_ACTIVITY; // only one like or dislike per person // split into two queries for performance issues $condition = [ - 'uid' => $item['uid'], - 'author-id' => $item['author-id'], - 'gravity' => GRAVITY_ACTIVITY, - 'verb' => $item['verb'], + 'uid' => $item['uid'], + 'author-id' => $item['author-id'], + 'gravity' => Item::GRAVITY_ACTIVITY, + 'verb' => $item['verb'], 'parent-uri' => $item['thr-parent'], ]; if (Post::exists($condition)) { return false; } - $condition = ['uid' => $item['uid'], 'author-id' => $item['author-id'], 'gravity' => GRAVITY_ACTIVITY, + $condition = ['uid' => $item['uid'], 'author-id' => $item['author-id'], 'gravity' => Item::GRAVITY_ACTIVITY, 'verb' => $item['verb'], 'thr-parent' => $item['thr-parent']]; if (Post::exists($condition)) { return false; @@ -1725,8 +1646,6 @@ class DFRN $item['owner-link'] = $item['author-link']; $item['owner-avatar'] = $item['author-avatar']; $item['owner-id'] = $item['author-id']; - } else { - $is_like = false; } if (($item['verb'] == Activity::TAG) && ($item['object-type'] == Activity\ObjectType::TAGTERM)) { @@ -1735,9 +1654,8 @@ class DFRN if ($xt->type == Activity\ObjectType::NOTE) { $item_tag = Post::selectFirst(['id', 'uri-id'], ['uri' => $xt->id, 'uid' => $importer['importer_uid']]); - if (!DBA::isResult($item_tag)) { - Logger::notice("Query failed to execute, no result returned in " . __FUNCTION__); + Logger::warning('Post had not been fetched', ['uri' => $xt->id, 'uid' => $importer['importer_uid']]); return false; } @@ -1795,7 +1713,7 @@ class DFRN * Checks if an incoming message is wanted * * @param array $item - * @param array $imporer + * @param array $importer * @return boolean Is the message wanted? */ private static function isSolicitedMessage(array $item, array $importer): bool @@ -1841,12 +1759,10 @@ class DFRN */ private static function processEntry(array $header, DOMXPath $xpath, DOMNode $entry, array $importer, string $xml, int $protocol) { - Logger::notice("Processing entries"); + Logger::info("Processing entries"); $item = $header; - $item['protocol'] = $protocol; - $item['source'] = $xml; // Get the uri @@ -1930,7 +1846,11 @@ class DFRN $item['uri-id'] = ItemURI::insert(['uri' => $item['uri'], 'guid' => $item['guid']]); - $item['body'] = Item::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']); @@ -1994,16 +1914,16 @@ class DFRN self::parseLinks($links, $item); } - $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; } } } @@ -2030,7 +1950,9 @@ class DFRN $entrytype = self::getEntryType($importer, $item); // Now assign the rest of the values that depend on the type of the message - if (in_array($entrytype, [DFRN::REPLY, DFRN::REPLY_RC])) { + if (in_array($entrytype, [self::REPLY, self::REPLY_RC])) { + $item['gravity'] = Item::GRAVITY_COMMENT; + if (!isset($item['object-type'])) { $item['object-type'] = Activity\ObjectType::COMMENT; } @@ -2052,12 +1974,11 @@ class DFRN } } - // Ensure to have the correct share data - $item = Item::addShareDataFromOriginal($item); - - if ($entrytype == DFRN::REPLY_RC) { + if ($entrytype == self::REPLY_RC) { $item['wall'] = 1; - } elseif ($entrytype == DFRN::TOP_LEVEL) { + } elseif ($entrytype == self::TOP_LEVEL) { + $item['gravity'] = Item::GRAVITY_PARENT; + if (!isset($item['object-type'])) { $item['object-type'] = Activity\ObjectType::NOTE; } @@ -2094,16 +2015,13 @@ class DFRN } } - // Need to initialize variable, otherwise E_NOTICE will happen - $is_like = false; - - if (!self::processVerbs($entrytype, $importer, $item, $is_like)) { + if (!self::processVerbs($entrytype, $importer, $item)) { Logger::info("Exiting because 'processVerbs' told us so"); return; } // This check is done here to be able to receive connection requests in "processVerbs" - if (($entrytype == DFRN::TOP_LEVEL) && $owner_unknown) { + if (($entrytype == self::TOP_LEVEL) && $owner_unknown) { Logger::info("Item won't be stored because user " . $importer['importer_uid'] . " doesn't follow " . $item['owner-link'] . "."); return; } @@ -2119,9 +2037,27 @@ class DFRN return; } - if (in_array($entrytype, [DFRN::REPLY, DFRN::REPLY_RC])) { + if (in_array($entrytype, [self::REPLY, self::REPLY_RC])) { + if (($item['uid'] != 0) && !Post::exists(['uid' => $item['uid'], 'uri' => $item['thr-parent']])) { + if (DI::pConfig()->get($item['uid'], 'system', 'accept_only_sharer') == Item::COMPLETION_NONE) { + Logger::info('Completion is set to "none", so we stop here.', ['uid' => $item['uid'], 'owner-id' => $item['owner-id'], 'author-id' => $item['author-id'], 'gravity' => $item['gravity'], 'uri' => $item['uri']]); + return; + } + if (!Contact::isSharing($item['owner-id'], $item['uid']) && !Contact::isSharing($item['author-id'], $item['uid'])) { + Logger::info('Contact is not sharing with the user', ['uid' => $item['uid'], 'owner-id' => $item['owner-id'], 'author-id' => $item['author-id'], 'gravity' => $item['gravity'], 'uri' => $item['uri']]); + return; + } + if (($item['gravity'] == Item::GRAVITY_ACTIVITY) && DI::pConfig()->get($item['uid'], 'system', 'accept_only_sharer') == Item::COMPLETION_COMMENT) { + Logger::info('Completion is set to "comment", but this is an activity. so we stop here.', ['uid' => $item['uid'], 'owner-id' => $item['owner-id'], 'author-id' => $item['author-id'], 'gravity' => $item['gravity'], 'uri' => $item['uri']]); + return; + } + Logger::debug('Post is accepted.', ['uid' => $item['uid'], 'owner-id' => $item['owner-id'], 'author-id' => $item['author-id'], 'gravity' => $item['gravity'], 'uri' => $item['uri']]); + } else { + Logger::debug('Thread parent exists.', ['uid' => $item['uid'], 'owner-id' => $item['owner-id'], 'author-id' => $item['author-id'], 'gravity' => $item['gravity'], 'uri' => $item['uri']]); + } + // Will be overwritten for sharing accounts in Item::insert - if (empty($item['post-reason']) && ($entrytype == DFRN::REPLY)) { + if (empty($item['post-reason']) && ($entrytype == self::REPLY)) { $item['post-reason'] = Item::PR_COMMENT; } @@ -2135,31 +2071,16 @@ class DFRN return true; } - } else { // $entrytype == DFRN::TOP_LEVEL - if (($importer['uid'] == 0) && ($importer['importer_uid'] != 0)) { - Logger::info("Contact " . $importer['id'] . " isn't known to user " . $importer['importer_uid'] . ". The post will be ignored."); - return; - } - if (!Strings::compareLink($item['owner-link'], $importer['url'])) { - /* - * The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery, - * but otherwise there's a possible data mixup on the sender's system. - * the tgroup delivery code called from Item::insert will correct it if it's a forum, - * but we're going to unconditionally correct it here so that the post will always be owned by our contact. - */ - Logger::info('Correcting item owner.'); - $item['owner-link'] = $importer['url']; - $item['owner-id'] = Contact::getIdForURL($importer['url'], 0); - } - - if (($importer['rel'] == Contact::FOLLOWER) && (!self::tgroupCheck($importer['importer_uid'], $item))) { - Logger::info("Contact " . $importer['id'] . " is only follower and tgroup check was negative."); + } else { // $entrytype == self::TOP_LEVEL + if (($item['uid'] != 0) && !Contact::isSharing($item['owner-id'], $item['uid']) && !Contact::isSharing($item['author-id'], $item['uid'])) { + Logger::info('Contact is not sharing with the user', ['uid' => $item['uid'], 'owner-id' => $item['owner-id'], 'author-id' => $item['author-id'], 'gravity' => $item['gravity'], 'uri' => $item['uri']]); return; } // This is my contact on another system, but it's really me. // Turn this into a wall post. $notify = Item::isRemoteSelf($importer, $item); + $item['wall'] = (bool)$notify; $posted_id = Item::insert($item, $notify); @@ -2172,11 +2093,6 @@ class DFRN if ($item['uid'] == 0) { Item::distribute($posted_id); } - - if (stristr($item['verb'], Activity::POKE)) { - $item['id'] = $posted_id; - self::doPoke($item, $importer); - } } } @@ -2191,7 +2107,7 @@ class DFRN */ private static function processDeletion(DOMXPath $xpath, DOMNode $deletion, array $importer) { - Logger::notice("Processing deletions"); + Logger::info("Processing deletions"); $uri = null; foreach ($deletion->attributes as $attributes) { @@ -2217,13 +2133,13 @@ class DFRN } // When it is a starting post it has to belong to the person that wants to delete it - if (($item['gravity'] == GRAVITY_PARENT) && ($item['contact-id'] != $importer['id'])) { + if (($item['gravity'] == Item::GRAVITY_PARENT) && ($item['contact-id'] != $importer['id'])) { Logger::info('Item with URI ' . $uri . ' do not belong to contact ' . $importer['id'] . ' - ignoring deletion.'); return; } // Comments can be deleted by the thread owner or comment owner - if (($item['gravity'] != GRAVITY_PARENT) && ($item['contact-id'] != $importer['id'])) { + if (($item['gravity'] != Item::GRAVITY_PARENT) && ($item['contact-id'] != $importer['id'])) { $condition = ['id' => $item['parent'], 'contact-id' => $importer['id']]; if (!Post::exists($condition)) { Logger::info('Item with URI ' . $uri . ' was not found or must not be deleted by contact ' . $importer['id'] . ' - ignoring deletion.'); @@ -2275,10 +2191,12 @@ class DFRN $header = []; $header['uid'] = $importer['importer_uid']; $header['network'] = Protocol::DFRN; + $header['protocol'] = $protocol; $header['wall'] = 0; $header['origin'] = 0; $header['contact-id'] = $importer['id']; - $header['direction'] = $direction; + + $header = Diaspora::setDirection($header, $direction); if ($direction === Conversation::RELAY) { $header['post-reason'] = Item::PR_RELAY; @@ -2369,7 +2287,7 @@ class DFRN self::processDeletion($xpath, $deletion, $importer); } if (count($deletions) > 0) { - Logger::notice(count($deletions) . ' deletions had been processed'); + Logger::info(count($deletions) . ' deletions had been processed'); return 200; } } @@ -2398,47 +2316,6 @@ class DFRN return Activity::POST; } - // @TODO Documentation missing - private static function tgroupCheck(int $uid, array $item): bool - { - $mention = false; - - // check that the message originated elsewhere and is a top-level post - - if ($item['wall'] || $item['origin'] || ($item['uri'] != $item['thr-parent'])) { - return false; - } - - $user = DBA::selectFirst('user', ['account-type', 'nickname'], ['uid' => $uid]); - if (!DBA::isResult($user)) { - return false; - } - - $link = Strings::normaliseLink(DI::baseUrl() . '/profile/' . $user['nickname']); - - /* - * Diaspora uses their own hardwired link URL in @-tags - * instead of the one we supply with webfinger - */ - $dlink = Strings::normaliseLink(DI::baseUrl() . '/u/' . $user['nickname']); - - $cnt = preg_match_all('/[\@\!]\[url\=(.*?)\](.*?)\[\/url\]/ism', $item['body'], $matches, PREG_SET_ORDER); - if ($cnt) { - foreach ($matches as $mtch) { - if (Strings::compareLink($link, $mtch[1]) || Strings::compareLink($dlink, $mtch[1])) { - $mention = true; - Logger::notice('mention found: ' . $mtch[2]); - } - } - } - - if (!$mention) { - return false; - } - - return ($user['account-type'] == User::ACCOUNT_TYPE_COMMUNITY); - } - /** * This function returns true if $update has an edited timestamp newer * than $existing, i.e. $update contains new data which should override