]> git.mxchange.org Git - friendica.git/blobdiff - src/Protocol/Diaspora.php
Merge pull request #11887 from annando/maxload
[friendica.git] / src / Protocol / Diaspora.php
index 838d40550551fce3ea41dfb0e99d3410c2620314..9e80c130282428401353223353ec1cac6fd4c6d9 100644 (file)
@@ -50,6 +50,7 @@ use Friendica\Util\Network;
 use Friendica\Util\Strings;
 use Friendica\Util\XML;
 use Friendica\Worker\Delivery;
+use GuzzleHttp\Psr7\Uri;
 use SimpleXMLElement;
 
 /**
@@ -123,18 +124,18 @@ class Diaspora
                $basedom = XML::parseString($envelope, true);
 
                if (!is_object($basedom)) {
-                       Logger::notice("Envelope is no XML file");
+                       Logger::notice('Envelope is no XML file');
                        return false;
                }
 
-               $children = $basedom->children('http://salmon-protocol.org/ns/magic-env');
+               $children = $basedom->children(ActivityNamespace::SALMON_ME);
 
                if (sizeof($children) == 0) {
-                       Logger::notice("XML has no children");
+                       Logger::notice('XML has no children');
                        return false;
                }
 
-               $handle = "";
+               $handle = '';
 
                $data = Strings::base64UrlDecode($children->data);
                $type = $children->data->attributes()->type[0];
@@ -467,14 +468,14 @@ class Diaspora
         */
        public static function dispatchPublic(array $msg, int $direction)
        {
-               $enabled = intval(DI::config()->get("system", "diaspora_enabled"));
+               $enabled = intval(DI::config()->get('system', 'diaspora_enabled'));
                if (!$enabled) {
-                       Logger::notice("diaspora is disabled");
+                       Logger::notice('Diaspora is disabled');
                        return false;
                }
 
                if (!($fields = self::validPosting($msg))) {
-                       Logger::notice("Invalid posting");
+                       Logger::warning('Invalid posting');
                        return false;
                }
 
@@ -509,7 +510,7 @@ class Diaspora
                if (is_null($fields)) {
                        $private = true;
                        if (!($fields = self::validPosting($msg))) {
-                               Logger::notice("Invalid posting");
+                               Logger::warning('Invalid posting');
                                return false;
                        }
                } else {
@@ -588,7 +589,7 @@ class Diaspora
                                return self::receiveStatusMessage($importer, $fields, $msg['message'], $direction);
 
                        default:
-                               Logger::notice("Unknown message type " . $type);
+                               Logger::notice('Unknown message type ' . $type);
                                return false;
                }
        }
@@ -628,7 +629,7 @@ class Diaspora
                $type = $element->getName();
                $orig_type = $type;
 
-               Logger::debug("Got message type " . $type . ": " . $msg['message']);
+               Logger::debug('Got message', ['type' => $type, 'message' => $msg['message']]);
 
                // All retractions are handled identically from now on.
                // In the new version there will only be "retraction".
@@ -704,7 +705,7 @@ class Diaspora
                // This is something that shouldn't happen at all.
                if (in_array($type, ['status_message', 'reshare', 'profile'])) {
                        if ($msg['author'] != $fields->author) {
-                               Logger::notice("Message handle is not the same as envelope sender. Quitting this message.");
+                               Logger::notice('Message handle is not the same as envelope sender. Quitting this message.', ['author1' => $msg['author'], 'author2' => $fields->author]);
                                return false;
                        }
                }
@@ -713,9 +714,15 @@ class Diaspora
                if (!in_array($type, ['comment', 'like'])) {
                        return $fields;
                }
+
+               if (!isset($author_signature) && ($msg['author'] == $fields->author)) {
+                       Logger::debug('No author signature, but the sender matches the author', ['type' => $type, 'msg-author' => $msg['author'], 'message' => $msg['message']]);
+                       return $fields;
+               }
+
                // No author_signature? This is a must, so we quit.
                if (!isset($author_signature)) {
-                       Logger::info("No author signature for type " . $type . " - Message: " . $msg['message']);
+                       Logger::info('No author signature', ['type' => $type, 'msg-author' => $msg['author'], 'fields-author' => $fields->author, 'message' => $msg['message']]);
                        return false;
                }
 
@@ -727,7 +734,7 @@ class Diaspora
                        }
 
                        if (!Crypto::rsaVerify($signed_data, $parent_author_signature, $key, 'sha256')) {
-                               Logger::info("No valid parent author signature for parent author " . $msg['author'] . " in type " . $type . " - signed data: " . $signed_data . " - Message: " . $msg['message'] . " - Signature " . $parent_author_signature);
+                               Logger::info('No valid parent author signature', ['author' => $msg['author'], 'type' => $type, 'signed data' => $signed_data, 'message'  => $msg['message'], 'signature' => $parent_author_signature]);
                                return false;
                        }
                }
@@ -739,7 +746,7 @@ class Diaspora
                }
 
                if (!Crypto::rsaVerify($signed_data, $author_signature, $key, 'sha256')) {
-                       Logger::info("No valid author signature for author " . $fields->author . " in type " . $type . " - signed data: " . $signed_data . " - Message: " . $msg['message'] . " - Signature " . $author_signature);
+                       Logger::info('No valid author signature for author', ['author' => $fields->author, 'type' => $type, 'signed data' => $signed_data, 'message'  => $msg['message'], 'signature' => $author_signature]);
                        return false;
                } else {
                        return $fields;
@@ -755,14 +762,14 @@ class Diaspora
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         * @throws \ImagickException
         */
-       private static function key(string $handle): string
+       private static function key(string $handle = null): string
        {
                $handle = strval($handle);
 
-               Logger::notice("Fetching diaspora key for: " . $handle);
+               Logger::notice('Fetching diaspora key', ['handle' => $handle, 'callstack' => System::callstack(20)]);
 
                $fcontact = FContact::getByURL($handle);
-               if ($fcontact) {
+               if (!empty($fcontact['pubkey'])) {
                        return $fcontact['pubkey'];
                }
 
@@ -892,7 +899,7 @@ class Diaspora
        {
                $contact = self::contactByHandle($importer['uid'], $handle);
                if (!$contact) {
-                       Logger::notice("A Contact for handle " . $handle . " and user " . $importer['uid'] . " was not found");
+                       Logger::notice('A Contact for handle ' . $handle . ' and user ' . $importer['uid'] . ' was not found');
                        // If a contact isn't found, we accept it anyway if it is a comment
                        if ($is_comment && ($importer['uid'] != 0)) {
                                return self::contactByHandle(0, $handle);
@@ -904,7 +911,7 @@ class Diaspora
                }
 
                if (!self::postAllow($importer, $contact, $is_comment)) {
-                       Logger::notice("The handle: " . $handle . " is not allowed to post to user " . $importer['uid']);
+                       Logger::notice('The handle: ' . $handle . ' is not allowed to post to user ' . $importer['uid']);
                        return false;
                }
                return $contact;
@@ -923,7 +930,7 @@ class Diaspora
        {
                $item = Post::selectFirst(['id'], ['uid' => $uid, 'guid' => $guid]);
                if (DBA::isResult($item)) {
-                       Logger::notice("message " . $guid . " already exists for user " . $uid);
+                       Logger::notice('Message ' . $guid . ' already exists for user ' . $uid);
                        return $item['id'];
                }
 
@@ -1028,7 +1035,7 @@ class Diaspora
 
                $server = $serverparts['scheme'] . '://' . $serverparts['host'];
 
-               Logger::info("Trying to fetch item " . $guid . " from " . $server);
+               Logger::info('Trying to fetch item ' . $guid . ' from ' . $server);
 
                $msg = self::message($guid, $server);
 
@@ -1036,7 +1043,7 @@ class Diaspora
                        return false;
                }
 
-               Logger::info("Successfully fetched item " . $guid . " from " . $server);
+               Logger::info('Successfully fetched item ' . $guid . ' from ' . $server);
 
                // Now call the dispatcher
                return self::dispatchPublic($msg, $force ? self::FORCED_FETCH : self::FETCHED);
@@ -1064,16 +1071,16 @@ class Diaspora
                // This will work for new Diaspora servers and Friendica servers from 3.5
                $source_url = $server . '/fetch/post/' . urlencode($guid);
 
-               Logger::info("Fetch post from " . $source_url);
+               Logger::info('Fetch post from ' . $source_url);
 
                $envelope = DI::httpClient()->fetch($source_url, HttpClientAccept::MAGIC);
                if ($envelope) {
-                       Logger::info("Envelope was fetched.");
+                       Logger::info('Envelope was fetched.');
                        $x = self::verifyMagicEnvelope($envelope);
                        if (!$x) {
-                               Logger::info("Envelope could not be verified.");
+                               Logger::info('Envelope could not be verified.');
                        } else {
-                               Logger::info("Envelope was verified.");
+                               Logger::info('Envelope was verified.');
                        }
                } else {
                        $x = false;
@@ -1091,15 +1098,15 @@ class Diaspora
 
                if ($source_xml->post->reshare) {
                        // Reshare of a reshare - old Diaspora version
-                       Logger::info("Message is a reshare");
+                       Logger::info('Message is a reshare');
                        return self::message($source_xml->post->reshare->root_guid, $server, ++$level);
-               } elseif ($source_xml->getName() == "reshare") {
+               } elseif ($source_xml->getName() == 'reshare') {
                        // Reshare of a reshare - new Diaspora version
-                       Logger::info("Message is a new reshare");
+                       Logger::info('Message is a new reshare');
                        return self::message($source_xml->root_guid, $server, ++$level);
                }
 
-               $author = "";
+               $author = '';
 
                // Fetch the author - for the old and the new Diaspora version
                if ($source_xml->post->status_message && $source_xml->post->status_message->diaspora_handle) {
@@ -1177,6 +1184,7 @@ class Diaspora
                $fields = ['id', 'parent', 'body', 'wall', 'uri', 'guid', 'private', 'origin',
                        'author-name', 'author-link', 'author-avatar', 'gravity',
                        'owner-name', 'owner-link', 'owner-avatar'];
+
                $condition = ['uid' => $uid, 'guid' => $guid];
                $item = Post::selectFirst($fields, $condition);
 
@@ -1190,17 +1198,17 @@ class Diaspora
                        }
 
                        if ($result) {
-                               Logger::info("Fetched missing item " . $guid . " - result: " . $result);
+                               Logger::info('Fetched missing item ' . $guid . ' - result: ' . $result);
 
                                $item = Post::selectFirst($fields, $condition);
                        }
                }
 
                if (!DBA::isResult($item)) {
-                       Logger::notice("parent item not found: parent: " . $guid . " - user: " . $uid);
+                       Logger::notice('Parent item not found: parent: ' . $guid . ' - user: ' . $uid);
                        return false;
                } else {
-                       Logger::notice("parent item found: parent: " . $guid . " - user: " . $uid);
+                       Logger::notice('Parent item found: parent: ' . $guid . ' - user: ' . $uid);
                        return $item;
                }
        }
@@ -1330,11 +1338,11 @@ class Diaspora
 
                $contact = self::contactByHandle($importer['uid'], $old_handle);
                if (!$contact) {
-                       Logger::notice("cannot find contact for sender: " . $old_handle . " and user " . $importer['uid']);
+                       Logger::notice('Cannot find contact for sender: ' . $old_handle . ' and user ' . $importer['uid']);
                        return false;
                }
 
-               Logger::notice("Got migration for " . $old_handle . ", to " . $new_handle . " with user " . $importer['uid']);
+               Logger::notice('Got migration for ' . $old_handle . ', to ' . $new_handle . ' with user ' . $importer['uid']);
 
                // Check signature
                $signed_text = 'AccountMigration:' . $old_handle . ':' . $new_handle;
@@ -1355,15 +1363,15 @@ class Diaspora
                }
 
                $fields = [
-                       'url' => $data['url'],
-                       'nurl' => Strings::normaliseLink($data['url']),
-                       'name' => $data['name'],
-                       'nick' => $data['nick'],
-                       'addr' => $data['addr'],
-                       'batch' => $data['batch'],
-                       'notify' => $data['notify'],
-                       'poll' => $data['poll'],
-                       'network' => $data['network']
+                       'url'     => $data['url'],
+                       'nurl'    => Strings::normaliseLink($data['url']),
+                       'name'    => $data['name'],
+                       'nick'    => $data['nick'],
+                       'addr'    => $data['addr'],
+                       'batch'   => $data['batch'],
+                       'notify'  => $data['notify'],
+                       'poll'    => $data['poll'],
+                       'network' => $data['network'],
                ];
 
                Contact::update($fields, ['addr' => $old_handle]);
@@ -1417,7 +1425,7 @@ class Diaspora
 
                        $parts = parse_url($person['url']);
                        unset($parts['path']);
-                       $host_url = Network::unparseURL($parts);
+                       $host_url = (string)Uri::fromParts($parts);
 
                        return $host_url . '/objects/' . $guid;
                }
@@ -1513,7 +1521,7 @@ class Diaspora
 
                $person = FContact::getByURL($author);
                if (!is_array($person)) {
-                       Logger::notice("unable to find author details");
+                       Logger::notice('Unable to find author details');
                        return false;
                }
 
@@ -1533,13 +1541,7 @@ class Diaspora
                $datarray['owner-id'] = Contact::getIdForURL($contact['url'], 0);
 
                // Will be overwritten for sharing accounts in Item::insert
-               if (in_array($direction, [self::FETCHED, self::FORCED_FETCH])) {
-                       $datarray['post-reason'] = Item::PR_FETCHED;
-               } elseif ($datarray['uid'] == 0) {
-                       $datarray['post-reason'] = Item::PR_GLOBAL;
-               } else {
-                       $datarray['post-reason'] = Item::PR_COMMENT;
-               }
+               $datarray = self::setDirection($datarray, $direction);
 
                $datarray['guid'] = $guid;
                $datarray['uri'] = self::getUriFromGuid($author, $guid);
@@ -1555,7 +1557,8 @@ class Diaspora
 
                $datarray['protocol'] = Conversation::PARCEL_DIASPORA;
                $datarray['source'] = $xml;
-               $datarray['direction'] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH;
+
+               $datarray = self::setDirection($datarray, $direction);
 
                $datarray['changed'] = $datarray['created'] = $datarray['edited'] = $created_at;
 
@@ -1587,7 +1590,7 @@ class Diaspora
                }
 
                if ($message_id) {
-                       Logger::info("Stored comment " . $datarray['guid'] . " with message id " . $message_id);
+                       Logger::info('Stored comment ' . $datarray['guid'] . ' with message id ' . $message_id);
                        if ($datarray['uid'] == 0) {
                                Item::distribute($message_id, json_encode($data));
                        }
@@ -1632,12 +1635,12 @@ class Diaspora
                $msg_created_at = DateTimeFormat::utc(XML::unescape($mesg->created_at));
 
                if ($msg_conversation_guid != $guid) {
-                       Logger::notice("message conversation guid does not belong to the current conversation.");
+                       Logger::notice('Message conversation guid does not belong to the current conversation.', ['guid' => $guid]);
                        return false;
                }
 
                $body = Markdown::toBBCode($msg_text);
-               $message_uri = $msg_author.":".$msg_guid;
+               $message_uri = $msg_author . ':' . $msg_guid;
 
                $person = FContact::getByURL($msg_author);
 
@@ -1678,7 +1681,7 @@ class Diaspora
                $messages = $data->message;
 
                if (!count($messages)) {
-                       Logger::notice("empty conversation");
+                       Logger::notice('Empty conversation');
                        return false;
                }
 
@@ -1700,13 +1703,15 @@ class Diaspora
                                'created' => $created_at,
                                'updated' => DateTimeFormat::utcNow(),
                                'subject' => $subject,
-                               'recips'  => $participants]);
+                               'recips'  => $participants
+                       ]);
+
                        if ($r) {
                                $conversation = DBA::selectFirst('conv', [], ['uid' => $importer['uid'], 'guid' => $guid]);
                        }
                }
                if (!$conversation) {
-                       Logger::notice("unable to create conversation.");
+                       Logger::warning('Unable to create conversation.');
                        return false;
                }
 
@@ -1764,7 +1769,7 @@ class Diaspora
 
                $person = FContact::getByURL($author);
                if (!is_array($person)) {
-                       Logger::notice("unable to find author details");
+                       Logger::notice('Unable to find author details');
                        return false;
                }
 
@@ -1782,12 +1787,13 @@ class Diaspora
                $datarray = [];
 
                $datarray['protocol'] = Conversation::PARCEL_DIASPORA;
-               $datarray['direction'] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH;
 
                $datarray['uid'] = $importer['uid'];
                $datarray['contact-id'] = $author_contact['cid'];
                $datarray['network']  = $author_contact['network'];
 
+               $datarray = self::setDirection($datarray, $direction);
+
                $datarray['owner-link'] = $datarray['author-link'] = $person['url'];
                $datarray['owner-id'] = $datarray['author-id'] = Contact::getIdForURL($person['url'], 0);
 
@@ -1831,7 +1837,7 @@ class Diaspora
                }
 
                if ($message_id) {
-                       Logger::info("Stored like " . $datarray['guid'] . " with message id " . $message_id);
+                       Logger::info('Stored like ' . $datarray['guid'] . ' with message id ' . $message_id);
                        if ($datarray['uid'] == 0) {
                                Item::distribute($message_id, json_encode($data));
                        }
@@ -1872,7 +1878,7 @@ class Diaspora
                $conversation = DBA::selectFirst('conv', [], $condition);
 
                if (!DBA::isResult($conversation)) {
-                       Logger::notice("conversation not available.");
+                       Logger::notice('Conversation not available.');
                        return false;
                }
 
@@ -1880,13 +1886,13 @@ class Diaspora
 
                $person = FContact::getByURL($author);
                if (!$person) {
-                       Logger::notice("unable to find author details");
+                       Logger::notice('Unable to find author details');
                        return false;
                }
 
                $body = Markdown::toBBCode($text);
 
-               $body = self::replacePeopleGuid($body, $person["url"]);
+               $body = self::replacePeopleGuid($body, $person['url']);
 
                return Mail::insert([
                        'uid'        => $importer['uid'],
@@ -1900,7 +1906,7 @@ class Diaspora
                        'body'       => $body,
                        'reply'      => 1,
                        'uri'        => $message_uri,
-                       'parent-uri' => $author.":".$conversation['guid'],
+                       'parent-uri' => $author . ':' . $conversation['guid'],
                        'created'    => $created_at
                ]);
        }
@@ -1951,7 +1957,7 @@ class Diaspora
 
                $person = FContact::getByURL($author);
                if (!is_array($person)) {
-                       Logger::notice("Person not found: " . $author);
+                       Logger::notice('Person not found: ' . $author);
                        return false;
                }
 
@@ -1961,12 +1967,13 @@ class Diaspora
                $datarray = [];
 
                $datarray['protocol'] = Conversation::PARCEL_DIASPORA;
-               $datarray['direction'] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH;
 
                $datarray['uid'] = $importer['uid'];
                $datarray['contact-id'] = $author_contact['cid'];
                $datarray['network']  = $author_contact['network'];
 
+               $datarray = self::setDirection($datarray, $direction);
+
                $datarray['owner-link'] = $datarray['author-link'] = $person['url'];
                $datarray['owner-id'] = $datarray['author-id'] = Contact::getIdForURL($person['url'], 0);
 
@@ -1994,11 +2001,11 @@ class Diaspora
                Logger::info('Participation stored', ['id' => $message_id, 'guid' => $guid, 'parent_guid' => $parent_guid, 'author' => $author]);
 
                // Send all existing comments and likes to the requesting server
-               $comments = Post::select(['id', 'uri-id', 'parent-author-network', 'author-network', 'verb'],
+               $comments = Post::select(['id', 'uri-id', 'parent-author-network', 'author-network', 'verb', 'gravity'],
                        ['parent' => $toplevel_parent_item['id'], 'gravity' => [GRAVITY_COMMENT, GRAVITY_ACTIVITY]]);
                while ($comment = Post::fetch($comments)) {
-                       if (in_array($comment['verb'], [Activity::FOLLOW, Activity::TAG])) {
-                               Logger::info('participation messages are not relayed', ['item' => $comment['id']]);
+                       if (($comment['gravity'] == GRAVITY_ACTIVITY) && !in_array($comment['verb'], [Activity::LIKE, Activity::DISLIKE])) {
+                               Logger::info('Unsupported activities are not relayed', ['item' => $comment['id'], 'verb' => $comment['verb']]);
                                continue;
                        }
 
@@ -2013,7 +2020,7 @@ class Diaspora
                        }
 
                        Logger::info('Deliver participation', ['item' => $comment['id'], 'contact' => $author_contact['cid']]);
-                       if (Worker::add(PRIORITY_HIGH, 'Delivery', Delivery::POST, $comment['id'], $author_contact['cid'])) {
+                       if (Worker::add(PRIORITY_HIGH, 'Delivery', Delivery::POST, $comment['uri-id'], $author_contact['cid'], $datarray['uid'])) {
                                Post\DeliveryData::incrementQueueCount($comment['uri-id'], 1);
                        }
                }
@@ -2131,7 +2138,7 @@ class Diaspora
 
                Contact::update($fields, ['id' => $contact['id']]);
 
-               Logger::info("Profile of contact " . $contact['id'] . " stored for user " . $importer['uid']);
+               Logger::info('Profile of contact ' . $contact['id'] . ' stored for user ' . $importer['uid']);
 
                return true;
        }
@@ -2192,7 +2199,7 @@ class Diaspora
                // That makes us friends.
                if ($contact) {
                        if ($following) {
-                               Logger::info("Author " . $author . " (Contact " . $contact['id'] . ") wants to follow us.");
+                               Logger::info('Author ' . $author . ' (Contact ' . $contact['id'] . ') wants to follow us.');
                                self::receiveRequestMakeFriend($importer, $contact);
 
                                // refetch the contact array
@@ -2203,7 +2210,7 @@ class Diaspora
                                if (in_array($contact['rel'], [Contact::FRIEND])) {
                                        $user = DBA::selectFirst('user', [], ['uid' => $importer['uid']]);
                                        if (DBA::isResult($user)) {
-                                               Logger::info("Sending share message to author " . $author . " - Contact: " . $contact['id'] . " - User: " . $importer['uid']);
+                                               Logger::info('Sending share message to author ' . $author . ' - Contact: ' . $contact['id'] . ' - User: ' . $importer['uid']);
                                                self::sendShare($user, $contact);
                                        }
                                }
@@ -2314,12 +2321,12 @@ class Diaspora
                        }
 
                        $server = 'https://' . substr($orig_author, strpos($orig_author, '@') + 1);
-                       Logger::notice("1st try: reshared message " . $guid . " will be fetched via SSL from the server " . $server);
+                       Logger::notice('1st try: reshared message ' . $guid . ' will be fetched via SSL from the server ' . $server);
                        $stored = self::storeByGuid($guid, $server, true);
 
                        if (!$stored) {
                                $server = 'http://' . substr($orig_author, strpos($orig_author, '@') + 1);
-                               Logger::notice("2nd try: reshared message " . $guid . " will be fetched without SSL from the server " . $server);
+                               Logger::notice('2nd try: reshared message ' . $guid . ' will be fetched without SSL from the server ' . $server);
                                $stored = self::storeByGuid($guid, $server, true);
                        }
 
@@ -2378,6 +2385,7 @@ class Diaspora
                $datarray['protocol'] = $item['protocol'];
                $datarray['source'] = $item['source'];
                $datarray['direction'] = $item['direction'];
+               $datarray['post-reason'] = $item['post-reason'];
 
                $datarray['plink'] = self::plink($author, $datarray['guid']);
                $datarray['private'] = $item['private'];
@@ -2464,7 +2472,8 @@ class Diaspora
 
                $datarray['protocol'] = Conversation::PARCEL_DIASPORA;
                $datarray['source'] = $xml;
-               $datarray['direction'] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH;
+
+               $datarray = self::setDirection($datarray, $direction);
 
                /// @todo Copy tag data from original post
 
@@ -2510,7 +2519,7 @@ class Diaspora
                }
 
                if ($message_id) {
-                       Logger::info("Stored reshare " . $datarray['guid'] . " with message id " . $message_id);
+                       Logger::info('Stored reshare ' . $datarray['guid'] . ' with message id ' . $message_id);
                        if ($datarray['uid'] == 0) {
                                Item::distribute($message_id);
                        }
@@ -2538,7 +2547,7 @@ class Diaspora
 
                $person = FContact::getByURL($author);
                if (!is_array($person)) {
-                       Logger::notice("unable to find author detail for " . $author);
+                       Logger::notice('Unable to find author detail for ' . $author);
                        return false;
                }
 
@@ -2558,7 +2567,7 @@ class Diaspora
 
                $r = Post::select($fields, $condition);
                if (!DBA::isResult($r)) {
-                       Logger::notice("Target guid " . $target_guid . " was not found on this system for user " . $importer['uid'] . ".");
+                       Logger::notice('Target guid ' . $target_guid . ' was not found on this system for user ' . $importer['uid'] . '.');
                        return false;
                }
 
@@ -2579,7 +2588,7 @@ class Diaspora
 
                        Item::markForDeletion(['id' => $item['id']]);
 
-                       Logger::info("Deleted target " . $target_guid . " (" . $item['id'] . ") from user " . $item['uid'] . " parent: " . $item['parent']);
+                       Logger::info('Deleted target ' . $target_guid . ' (' . $item['id'] . ') from user ' . $item['uid'] . ' parent: ' . $item['parent']);
                }
                DBA::close($r);
 
@@ -2602,7 +2611,7 @@ class Diaspora
 
                $contact = self::contactByHandle($importer['uid'], $sender);
                if (!$contact && (in_array($target_type, ['Contact', 'Person']))) {
-                       Logger::notice("cannot find contact for sender: " . $sender . " and user " . $importer['uid']);
+                       Logger::notice('Cannot find contact for sender: ' . $sender . ' and user ' . $importer['uid']);
                        return false;
                }
 
@@ -2610,7 +2619,7 @@ class Diaspora
                        $contact = [];
                }
 
-               Logger::info("Got retraction for " . $target_type . ", sender " . $sender . " and user " . $importer['uid']);
+               Logger::info('Got retraction for ' . $target_type . ', sender ' . $sender . ' and user ' . $importer['uid']);
 
                switch ($target_type) {
                        case 'Comment':
@@ -2626,7 +2635,7 @@ class Diaspora
                                break;
 
                        default:
-                               Logger::notice("Unknown target type " . $target_type);
+                               Logger::notice('Unknown target type ' . $target_type);
                                return false;
                }
                return true;
@@ -2686,6 +2695,29 @@ class Diaspora
                Post\Media::insert($data);
        }
 
+       /**
+        * Set direction and post reason
+        *
+        * @param array $datarray
+        * @param integer $direction
+        *
+        * @return array
+        */
+       public static function setDirection(array $datarray, int $direction): array
+       {
+               $datarray['direction'] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH;
+
+               if (in_array($direction, [self::FETCHED, self::FORCED_FETCH])) {
+                       $datarray['post-reason'] = Item::PR_FETCHED;
+               } elseif ($datarray['uid'] == 0) {
+                       $datarray['post-reason'] = Item::PR_GLOBAL;
+               } else {
+                       $datarray['post-reason'] = Item::PR_PUSHED;
+               }
+
+               return $datarray;
+       }
+
        /**
         * Receives status messages
         *
@@ -2776,13 +2808,8 @@ class Diaspora
 
                $datarray['protocol'] = Conversation::PARCEL_DIASPORA;
                $datarray['source'] = $xml;
-               $datarray['direction'] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH;
 
-               if (in_array($direction, [self::FETCHED, self::FORCED_FETCH])) {
-                       $datarray['post-reason'] = Item::PR_FETCHED;
-               } elseif ($datarray['uid'] == 0) {
-                       $datarray['post-reason'] = Item::PR_GLOBAL;
-               }
+               $datarray = self::setDirection($datarray, $direction);
 
                $datarray['body'] = self::replacePeopleGuid($body, $contact['url']);
                $datarray['raw-body'] = self::replacePeopleGuid($raw_body, $contact['url']);
@@ -2808,7 +2835,7 @@ class Diaspora
                }
 
                if (isset($address['lat']) && isset($address['lng'])) {
-                       $datarray['coord'] = $address['lat'] . " " . $address['lng'];
+                       $datarray['coord'] = $address['lat'] . ' ' . $address['lng'];
                }
 
                self::fetchGuid($datarray);
@@ -2823,7 +2850,7 @@ class Diaspora
                self::sendParticipation($contact, $datarray);
 
                if ($message_id) {
-                       Logger::info("Stored item " . $datarray['guid'] . " with message id " . $message_id);
+                       Logger::info('Stored item ' . $datarray['guid'] . ' with message id ' . $message_id);
                        if ($datarray['uid'] == 0) {
                                Item::distribute($message_id);
                        }
@@ -2877,11 +2904,11 @@ class Diaspora
         */
        public static function encodePrivateData(string $msg, array $user, array $contact, string $prvkey, string $pubkey): string
        {
-               Logger::debug("Message: ".$msg);
+               Logger::debug('Message: ' . $msg);
 
                // without a public key nothing will work
                if (!$pubkey) {
-                       Logger::notice("pubkey missing: contact id: ".$contact["id"]);
+                       Logger::notice('pubkey missing: contact id: ' . $contact['id']);
                        return false;
                }
 
@@ -2948,7 +2975,7 @@ class Diaspora
                        ]
                ];
 
-               $namespaces = ['me' => 'http://salmon-protocol.org/ns/magic-env'];
+               $namespaces = ['me' => ActivityNamespace::SALMON_ME];
 
                return XML::fromArray($xmldata, $xml, false, $namespaces);
        }
@@ -3034,11 +3061,11 @@ class Diaspora
                }
 
                if (!$dest_url) {
-                       Logger::notice("no url for contact: " . $contact['id'] . " batch mode =" . $public_batch);
+                       Logger::notice('No URL for contact: ' . $contact['id'] . ' batch mode =' . $public_batch);
                        return 0;
                }
 
-               Logger::notice("transmit: " . $logid . "-" . $guid . " " . $dest_url);
+               Logger::notice('transmit: ' . $logid . '-' . $guid . ' ' . $dest_url);
 
                if (!intval(DI::config()->get('system', 'diaspora_test'))) {
                        $content_type = (($public_batch) ? 'application/magic-envelope+xml' : 'application/json');
@@ -3050,7 +3077,7 @@ class Diaspora
                        return 200;
                }
 
-               Logger::notice("transmit: " . $logid . "-" . $guid . " to " . $dest_url . " returns: " . $return_code);
+               Logger::notice('transmit: ' . $logid . '-' . $guid . ' to ' . $dest_url . ' returns: ' . $return_code);
 
                return $return_code ? $return_code : -1;
        }
@@ -3110,7 +3137,7 @@ class Diaspora
                        Logger::notice('Empty addr', ['contact' => $contact ?? [], 'callstack' => System::callstack(20)]);
                }
 
-               $envelope = self::buildMessage($msg, $owner, $contact, $owner['uprvkey'], $pubkey, $public_batch);
+               $envelope = self::buildMessage($msg, $owner, $contact, $owner['uprvkey'], $pubkey ?? '', $public_batch);
 
                $return_code = self::transmit($owner, $contact, $envelope, $public_batch, $guid);
 
@@ -3164,7 +3191,7 @@ class Diaspora
                        'parent_guid' => $item['guid']
                ];
 
-               Logger::info("Send participation for " . $item['guid'] . " by " . $author);
+               Logger::info('Send participation for ' . $item['guid'] . ' by ' . $author);
 
                // It doesn't matter what we store, we only want to avoid sending repeated notifications for the same item
                DI::cache()->set($cachekey, $item['guid'], Duration::QUARTER_HOUR);
@@ -3260,10 +3287,10 @@ class Diaspora
        public static function sendUnshare(array $owner, array $contact): int
        {
                $message = [
-                       'author' => self::myHandle($owner),
+                       'author'    => self::myHandle($owner),
                        'recipient' => $contact['addr'],
                        'following' => 'false',
-                       'sharing' => 'false'
+                       'sharing'   => 'false'
                ];
 
                Logger::info('Send unshare', ['msg' => $message]);
@@ -3425,13 +3452,13 @@ class Diaspora
                // Detect a share element and do a reshare
                if (($item['private'] != Item::PRIVATE) && ($ret = self::isReshare($item['body']))) {
                        $message = [
-                               'author' => $myaddr,
-                               'guid' => $item['guid'],
-                               'created_at' => $created,
-                               'root_author' => $ret['root_handle'],
-                               'root_guid' => $ret['root_guid'],
+                               'author'                => $myaddr,
+                               'guid'                  => $item['guid'],
+                               'created_at'            => $created,
+                               'root_author'           => $ret['root_handle'],
+                               'root_guid'             => $ret['root_guid'],
                                'provider_display_name' => $item['app'],
-                               'public' => $public
+                               'public'                => $public
                        ];
 
                        $type = 'reshare';
@@ -3515,7 +3542,7 @@ class Diaspora
                }
 
                $msg = [
-                       'type' => $type,
+                       'type'    => $type,
                        'message' => $message
                ];
 
@@ -3581,12 +3608,12 @@ class Diaspora
                }
 
                return [
-                       'author' => self::myHandle($owner),
-                       'guid' => $item['guid'],
-                       'parent_guid' => $parent['guid'],
-                       'parent_type' => $target_type,
-                       'positive' => $positive,
-                       'author_signature' => ''
+                       'author'           => self::myHandle($owner),
+                       'guid'             => $item['guid'],
+                       'parent_guid'      => $parent['guid'],
+                       'parent_type'      => $target_type,
+                       'positive'         => $positive,
+                       'author_signature' => '',
                ];
        }
 
@@ -3617,7 +3644,7 @@ class Diaspora
                                $attend_answer = 'tentative';
                                break;
                        default:
-                               Logger::notice('Unknown verb '.$item['verb'].' in item '.$item['guid']);
+                               Logger::warning('Unknown verb ' . $item['verb'] . ' in item ' . $item['guid']);
                                return false;
                }
 
@@ -3685,7 +3712,7 @@ class Diaspora
                        'edited_at'   => $edited,
                        'parent_guid' => $toplevel_item['guid'],
                        'text'        => $text,
-                       'author_signature' => ''
+                       'author_signature' => '',
                ];
 
                // Send the thread parent guid only if it is a threaded comment
@@ -3753,7 +3780,7 @@ class Diaspora
                        $type = 'comment';
                }
 
-               Logger::info("Got relayable data " . $type . " for item " . $item['guid'] . " (" . $item['id'] . ")");
+               Logger::info('Got relayable data ' . $type . ' for item ' . $item['guid'] . ' (' . $item['id'] . ')');
 
                $msg = json_decode($item['signed_text'], true);
 
@@ -3772,7 +3799,7 @@ class Diaspora
                                $message[$field] = $data;
                        }
                } else {
-                       Logger::info("Signature text for item " . $item["guid"] . " (" . $item["id"] . ") couldn't be extracted: " . $item['signed_text']);
+                       Logger::info('Signature text for item ' . $item['guid'] . ' (' . $item['id'] . ') could not be extracted: ' . $item['signed_text']);
                }
 
                $message['parent_author_signature'] = self::signature($owner, $message);
@@ -3836,7 +3863,7 @@ class Diaspora
 
                $cnv = DBA::selectFirst('conv', [], ['id' => $item['convid'], 'uid' => $item['uid']]);
                if (!DBA::isResult($cnv)) {
-                       Logger::notice("conversation not found.");
+                       Logger::notice('Conversation not found.');
                        return -1;
                }
 
@@ -3938,40 +3965,44 @@ class Diaspora
        private static function createProfileData(int $uid): array
        {
                $profile = DBA::selectFirst('owner-view', ['uid', 'addr', 'name', 'location', 'net-publish', 'dob', 'about', 'pub_keywords'], ['uid' => $uid]);
+
                if (!DBA::isResult($profile)) {
                        return [];
                }
 
-               $handle = $profile['addr'];
-
                $split_name = self::splitName($profile['name']);
-               $first = $split_name['first'];
-               $last = $split_name['last'];
 
-               $large = DI::baseUrl().'/photo/custom/300/'.$profile['uid'].'.jpg';
-               $medium = DI::baseUrl().'/photo/custom/100/'.$profile['uid'].'.jpg';
-               $small = DI::baseUrl().'/photo/custom/50/'  .$profile['uid'].'.jpg';
-               $searchable = ($profile['net-publish'] ? 'true' : 'false');
+               $data = [
+                       'author'           => $profile['addr'],
+                       'first_name'       => $split_name['first'],
+                       'last_name'        => $split_name['last'],
+                       'image_url'        => DI::baseUrl() . '/photo/custom/300/' . $profile['uid'] . '.jpg',
+                       'image_url_medium' => DI::baseUrl() . '/photo/custom/100/' . $profile['uid'] . '.jpg',
+                       'image_url_small'  => DI::baseUrl() . '/photo/custom/50/'  . $profile['uid'] . '.jpg',
+                       'searchable'       => ($profile['net-publish'] ? 'true' : 'false'),
+                       'birthday'         => null,
+                       'about'            => null,
+                       'location'         => null,
+                       'tag_string'       => null,
+                       'nsfw'             => 'false',
+               ];
 
-               $dob = null;
-               $about = null;
-               $location = null;
-               $tags = null;
-               if ($searchable === 'true') {
-                       $dob = '';
+               if ($data['searchable'] === 'true') {
+                       $data['birthday'] = '';
 
                        if ($profile['dob'] && ($profile['dob'] > '0000-00-00')) {
                                [$year, $month, $day] = sscanf($profile['dob'], '%4d-%2d-%2d');
                                if ($year < 1004) {
                                        $year = 1004;
                                }
-                               $dob = DateTimeFormat::utc($year . '-' . $month . '-'. $day, 'Y-m-d');
+                               $data['birthday'] = DateTimeFormat::utc($year . '-' . $month . '-' . $day, 'Y-m-d');
                        }
 
-                       $about = BBCode::toMarkdown($profile['about']);
+                       $data['about'] = BBCode::toMarkdown($profile['about'] ?? '');
+
+                       $data['location'] = $profile['location'];
+                       $data['tag_string'] = '';
 
-                       $location = $profile['location'];
-                       $tags = '';
                        if ($profile['pub_keywords']) {
                                $kw = str_replace(',', ' ', $profile['pub_keywords']);
                                $kw = str_replace('  ', ' ', $kw);
@@ -3979,63 +4010,55 @@ class Diaspora
                                if (count($arr)) {
                                        for ($x = 0; $x < 5; $x ++) {
                                                if (!empty($arr[$x])) {
-                                                       $tags .= '#'. trim($arr[$x]) .' ';
+                                                       $data['tag_string'] .= '#'. trim($arr[$x]) .' ';
                                                }
                                        }
                                }
                        }
-                       $tags = trim($tags);
+                       $data['tag_string'] = trim($data['tag_string']);
                }
 
-               return [
-                       'author' => $handle,
-                       'first_name' => $first,
-                       'last_name' => $last,
-                       'image_url' => $large,
-                       'image_url_medium' => $medium,
-                       'image_url_small' => $small,
-                       'birthday' => $dob,
-                       'bio' => $about,
-                       'location' => $location,
-                       'searchable' => $searchable,
-                       'nsfw' => 'false',
-                       'tag_string' => $tags
-               ];
+               return $data;
        }
 
        /**
         * Sends profile data
         *
-        * @param int  $uid    The user id
-        * @param bool $recips optional, default false
+        * @param int   $uid        The user id
+        * @param array $recipients optional, default empty array
+        *
         * @return void
         * @throws \Exception
         */
-       public static function sendProfile(int $uid, bool $recips = false)
+       public static function sendProfile(int $uid, array $recipients = [])
        {
                if (!$uid) {
+                       Logger::warning('Parameter "uid" is empty');
                        return;
                }
 
                $owner = User::getOwnerDataById($uid);
-               if (!$owner) {
+               if (empty($owner)) {
+                       Logger::warning('Cannot fetch User record', ['uid' => $uid]);
                        return;
                }
 
-               if (!$recips) {
-                       $recips = DBA::selectToArray('contact', [], ['network' => Protocol::DIASPORA, 'uid' => $uid, 'rel' => [Contact::FOLLOWER, Contact::FRIEND]]);
+               if (empty($recipients)) {
+                       Logger::debug('No recipients provided, fetching for user', ['uid' => $uid]);
+                       $recipients = DBA::selectToArray('contact', [], ['network' => Protocol::DIASPORA, 'uid' => $uid, 'rel' => [Contact::FOLLOWER, Contact::FRIEND]]);
                }
 
-               if (!$recips) {
+               if (empty($recipients)) {
+                       Logger::warning('Cannot fetch recipients', ['uid' => $uid]);
                        return;
                }
 
                $message = self::createProfileData($uid);
 
-               // @ToDo Split this into single worker jobs
-               foreach ($recips as $recip) {
-                       Logger::info("Send updated profile data for user " . $uid . " to contact " . $recip['id']);
-                       self::buildAndTransmit($owner, $recip, 'profile', $message);
+               // @todo Split this into single worker jobs
+               foreach ($recipients as $recipient) {
+                       Logger::info('Send updated profile data for user ' . $uid . ' to contact ' . $recipient['id']);
+                       self::buildAndTransmit($owner, $recipient, 'profile', $message);
                }
        }
 
@@ -4052,11 +4075,12 @@ class Diaspora
        {
                $owner = User::getOwnerDataById($uid);
                if (empty($owner)) {
-                       Logger::info('No owner post, so not storing signature');
+                       Logger::info('No owner post, so not storing signature', ['uid' => $uid]);
                        return false;
                }
 
                if (!in_array($item['verb'], [Activity::LIKE, Activity::DISLIKE])) {
+                       Logger::warning('Item is neither a like nor a dislike', ['uid' => $uid, 'item[verb]' => $item['verb']]);;
                        return false;
                }
 
@@ -4080,6 +4104,7 @@ class Diaspora
         */
        public static function createCommentSignature(array $item)
        {
+               $contact = [];
                if (!empty($item['author-link'])) {
                        $url = $item['author-link'];
                } else {
@@ -4093,7 +4118,7 @@ class Diaspora
 
                $uid = User::getIdForURL($url);
                if (empty($uid)) {
-                       Logger::info('No owner post, so not storing signature', ['url' => $contact['url']]);
+                       Logger::info('No owner post, so not storing signature', ['url' => $contact['url'] ?? 'No contact loaded']);
                        return false;
                }