]> git.mxchange.org Git - friendica.git/blobdiff - src/Protocol/Diaspora.php
rename rawContent() to content()
[friendica.git] / src / Protocol / Diaspora.php
index 3687fb9d4b537e75e4ef0dc30c1d8f00c2c3c141..41ed7e7d9f79b9db0f3d29ae37d24066b27012b8 100644 (file)
@@ -27,8 +27,8 @@ use Friendica\Model\Conversation;
 use Friendica\Model\GContact;
 use Friendica\Model\Group;
 use Friendica\Model\Item;
+use Friendica\Model\Mail;
 use Friendica\Model\Profile;
-use Friendica\Model\Queue;
 use Friendica\Model\User;
 use Friendica\Network\Probe;
 use Friendica\Util\Crypto;
@@ -212,7 +212,7 @@ class Diaspora
         */
        public static function participantsForThread($thread, array $contacts)
        {
-               $r = DBA::p("SELECT `contact`.`batch`, `contact`.`id`, `contact`.`name`, `contact`.`network`,
+               $r = DBA::p("SELECT `contact`.`batch`, `contact`.`id`, `contact`.`name`, `contact`.`network`, `contact`.`protocol`,
                                `fcontact`.`batch` AS `fbatch`, `fcontact`.`network` AS `fnetwork` FROM `participation`
                                INNER JOIN `contact` ON `contact`.`id` = `participation`.`cid`
                                INNER JOIN `fcontact` ON `fcontact`.`id` = `participation`.`fid`
@@ -224,6 +224,10 @@ class Diaspora
                        }
                        unset($contact['fnetwork']);
 
+                       if (empty($contact['protocol'])) {
+                               $contact['protocol'] = $contact['network'];
+                       }
+
                        if (empty($contact['batch']) && !empty($contact['fbatch'])) {
                                $contact['batch'] = $contact['fbatch'];
                        }
@@ -401,7 +405,7 @@ class Diaspora
                                if ($no_exit) {
                                        return false;
                                } else {
-                                       System::httpExit(400);
+                                       throw new \Friendica\Network\HTTPException\BadRequestException();
                                }
                        }
 
@@ -420,7 +424,7 @@ class Diaspora
                        if ($no_exit) {
                                return false;
                        } else {
-                               System::httpExit(400);
+                               throw new \Friendica\Network\HTTPException\BadRequestException();
                        }
                }
 
@@ -446,7 +450,7 @@ class Diaspora
                        if ($no_exit) {
                                return false;
                        } else {
-                               System::httpExit(400);
+                               throw new \Friendica\Network\HTTPException\BadRequestException();
                        }
                }
 
@@ -456,7 +460,7 @@ class Diaspora
                        if ($no_exit) {
                                return false;
                        } else {
-                               System::httpExit(400);
+                               throw new \Friendica\Network\HTTPException\BadRequestException();
                        }
                }
 
@@ -466,7 +470,7 @@ class Diaspora
                        if ($no_exit) {
                                return false;
                        } else {
-                               System::httpExit(400);
+                               throw new \Friendica\Network\HTTPException\BadRequestException();
                        }
                }
 
@@ -551,7 +555,7 @@ class Diaspora
 
                if (!$base) {
                        Logger::log('unable to locate salmon data in xml');
-                       System::httpExit(400);
+                       throw new \Friendica\Network\HTTPException\BadRequestException();
                }
 
 
@@ -589,7 +593,7 @@ class Diaspora
 
                if (!$author_link) {
                        Logger::log('Could not retrieve author URI.');
-                       System::httpExit(400);
+                       throw new \Friendica\Network\HTTPException\BadRequestException();
                }
                // Once we have the author URI, go to the web and try to find their public key
                // (first this will look it up locally if it is in the fcontact cache)
@@ -600,14 +604,14 @@ class Diaspora
 
                if (!$key) {
                        Logger::log('Could not retrieve author key.');
-                       System::httpExit(400);
+                       throw new \Friendica\Network\HTTPException\BadRequestException();
                }
 
                $verify = Crypto::rsaVerify($signed_data, $signature, $key);
 
                if (!$verify) {
                        Logger::log('Message did not verify. Discarding.');
-                       System::httpExit(400);
+                       throw new \Friendica\Network\HTTPException\BadRequestException();
                }
 
                Logger::log('Message verified.');
@@ -1135,8 +1139,11 @@ class Diaspora
                //      Logger::log("defining user ".$contact["nick"]." as friend");
                //}
 
-               // We don't seem to like that person
-               if ($contact["blocked"]) {
+               // Contact server is blocked
+               if (Network::isUrlBlocked($contact['url'])) {
+                       return false;
+                       // We don't seem to like that person
+               } elseif ($contact["blocked"]) {
                        // Maybe blocked, don't accept.
                        return false;
                        // We are following this person?
@@ -1839,14 +1846,7 @@ class Diaspora
 
                $person = self::personByHandle($msg_author);
 
-               DBA::lock('mail');
-
-               if (DBA::exists('mail', ['guid' => $msg_guid, 'uid' => $importer["uid"]])) {
-                       Logger::log("duplicate message already delivered.", Logger::DEBUG);
-                       return false;
-               }
-
-               DBA::insert('mail', [
+               return Mail::insert([
                        'uid'        => $importer['uid'],
                        'guid'       => $msg_guid,
                        'convid'     => $conversation['id'],
@@ -1856,36 +1856,10 @@ class Diaspora
                        'contact-id' => $contact['id'],
                        'title'      => $subject,
                        'body'       => $body,
-                       'seen'       => 0,
-                       'reply'      => 0,
                        'uri'        => $message_uri,
                        'parent-uri' => $author . ':' . $guid,
                        'created'    => $msg_created_at
                ]);
-
-               $message_id = DBA::lastInsertId();
-
-               DBA::unlock();
-
-               DBA::update('conv', ['updated' => DateTimeFormat::utcNow()], ['id' => $conversation["id"]]);
-
-               notification([
-                       "type" => NOTIFY_MAIL,
-                       "notify_flags" => $importer["notify-flags"],
-                       "language" => $importer["language"],
-                       "to_name" => $importer["username"],
-                       "to_email" => $importer["email"],
-                       "uid" => $importer["uid"],
-                       "item" => ["id" => $message_id, "title" => $subject, "subject" => $subject, "body" => $body],
-                       "parent" => $conversation["id"],
-                       "source_name" => $person["name"],
-                       "source_link" => $person["url"],
-                       "source_photo" => $person["photo"],
-                       "verb" => ACTIVITY_POST,
-                       "otype" => "mail"
-               ]);
-
-               return true;
        }
 
        /**
@@ -2103,14 +2077,7 @@ class Diaspora
 
                $body = self::replacePeopleGuid($body, $person["url"]);
 
-               DBA::lock('mail');
-
-               if (DBA::exists('mail', ['guid' => $guid, 'uid' => $importer["uid"]])) {
-                       Logger::log("duplicate message already delivered.", Logger::DEBUG);
-                       return false;
-               }
-
-               DBA::insert('mail', [
+               return Mail::insert([
                        'uid'        => $importer['uid'],
                        'guid'       => $guid,
                        'convid'     => $conversation['id'],
@@ -2120,36 +2087,11 @@ class Diaspora
                        'contact-id' => $contact['id'],
                        'title'      => $conversation['subject'],
                        'body'       => $body,
-                       'seen'       => 0,
                        'reply'      => 1,
                        'uri'        => $message_uri,
                        'parent-uri' => $author.":".$conversation['guid'],
                        'created'    => $created_at
                ]);
-
-               $message_id = DBA::lastInsertId();
-
-               DBA::unlock();
-
-               DBA::update('conv', ['updated' => DateTimeFormat::utcNow()], ['id' => $conversation["id"]]);
-
-               notification([
-                       "type" => NOTIFY_MAIL,
-                       "notify_flags" => $importer["notify-flags"],
-                       "language" => $importer["language"],
-                       "to_name" => $importer["username"],
-                       "to_email" => $importer["email"],
-                       "uid" => $importer["uid"],
-                       "item" => ["id" => $message_id, "title" => $conversation["subject"], "subject" => $conversation["subject"], "body" => $body],
-                       "parent" => $conversation["id"],
-                       "source_name" => $person["name"],
-                       "source_link" => $person["url"],
-                       "source_photo" => $person["photo"],
-                       "verb" => ACTIVITY_POST,
-                       "otype" => "mail"
-               ]);
-
-               return true;
        }
 
        /**
@@ -2625,6 +2567,54 @@ class Diaspora
                return false;
        }
 
+       /**
+        * @brief Stores a reshare activity
+        *
+        * @param array   $item              Array of reshare post
+        * @param integer $parent_message_id Id of the parent post
+        * @param string  $guid              GUID string of reshare action
+        * @param string  $author            Author handle
+        */
+       private static function addReshareActivity($item, $parent_message_id, $guid, $author)
+       {
+               $parent = Item::selectFirst(['uri', 'guid'], ['id' => $parent_message_id]);
+
+               $datarray = [];
+
+               $datarray['uid'] = $item['uid'];
+               $datarray['contact-id'] = $item['contact-id'];
+               $datarray['network'] = $item['network'];
+
+               $datarray['author-link'] = $item['author-link'];
+               $datarray['author-id'] = $item['author-id'];
+
+               $datarray['owner-link'] = $datarray['author-link'];
+               $datarray['owner-id'] = $datarray['author-id'];
+
+               $datarray['guid'] = $parent['guid'] . '-' . $guid;
+               $datarray['uri'] = self::getUriFromGuid($author, $datarray['guid']);
+               $datarray['parent-uri'] = $parent['uri'];
+
+               $datarray['verb'] = $datarray['body'] = ACTIVITY2_ANNOUNCE;
+               $datarray['gravity'] = GRAVITY_ACTIVITY;
+               $datarray['object-type'] = ACTIVITY_OBJ_NOTE;
+
+               $datarray['protocol'] = $item['protocol'];
+
+               $datarray['plink'] = self::plink($author, $datarray['guid']);
+               $datarray['private'] = $item['private'];
+               $datarray['changed'] = $datarray['created'] = $datarray['edited'] = $item['created'];
+
+               $message_id = Item::insert($datarray);
+
+               if ($message_id) {
+                       Logger::info('Stored reshare activity.', ['guid' => $guid, 'id' => $message_id]);
+                       if ($datarray['uid'] == 0) {
+                               Item::distribute($message_id);
+                       }
+               }
+       }
+
        /**
         * @brief Processes a reshare message
         *
@@ -2708,6 +2698,11 @@ class Diaspora
 
                self::sendParticipation($contact, $datarray);
 
+               $root_message_id = self::messageExists($importer["uid"], $root_guid);
+               if ($root_message_id) {
+                       self::addReshareActivity($datarray, $root_message_id, $guid, $author);
+               }
+
                if ($message_id) {
                        Logger::log("Stored reshare ".$datarray["guid"]." with message id ".$message_id, Logger::DEBUG);
                        if ($datarray['uid'] == 0) {
@@ -3114,15 +3109,14 @@ class Diaspora
         * @param array  $contact      Target of the communication
         * @param string $envelope     The message that is to be transmitted
         * @param bool   $public_batch Is it a public post?
-        * @param bool   $queue_run    Is the transmission called from the queue?
         * @param string $guid         message guid
+        * @param bool   $no_defer     Don't defer a failing delivery
         *
-        * @param bool   $no_queue
         * @return int Result of the transmission
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         * @throws \ImagickException
         */
-       public static function transmit(array $owner, array $contact, $envelope, $public_batch, $queue_run = false, $guid = "", $no_queue = false)
+       public static function transmit(array $owner, array $contact, $envelope, $public_batch, $guid = "", $no_defer = false)
        {
                $enabled = intval(Config::get("system", "diaspora_enabled"));
                if (!$enabled) {
@@ -3149,27 +3143,23 @@ class Diaspora
 
                Logger::log("transmit: ".$logid."-".$guid." ".$dest_url);
 
-               if (!$queue_run && Queue::wasDelayed($contact["id"])) {
-                       $return_code = 0;
-               } else {
-                       if (!intval(Config::get("system", "diaspora_test"))) {
-                               $content_type = (($public_batch) ? "application/magic-envelope+xml" : "application/json");
+               if (!intval(Config::get("system", "diaspora_test"))) {
+                       $content_type = (($public_batch) ? "application/magic-envelope+xml" : "application/json");
 
-                               $postResult = Network::post($dest_url."/", $envelope, ["Content-Type: ".$content_type]);
-                               $return_code = $postResult->getReturnCode();
-                       } else {
-                               Logger::log("test_mode");
-                               return 200;
-                       }
+                       $postResult = Network::post($dest_url."/", $envelope, ["Content-Type: ".$content_type]);
+                       $return_code = $postResult->getReturnCode();
+               } else {
+                       Logger::log("test_mode");
+                       return 200;
                }
 
                Logger::log("transmit: ".$logid."-".$guid." to ".$dest_url." returns: ".$return_code);
 
                if (!$return_code || (($return_code == 503) && (stristr($postResult->getHeader(), "retry-after")))) {
-                       if (!$no_queue && !empty($contact['contact-type']) && ($contact['contact-type'] != Contact::TYPE_RELAY)) {
-                               Logger::log("queue message");
-                               // queue message for redelivery
-                               Queue::add($contact["id"], Protocol::DIASPORA, $envelope, $public_batch, $guid);
+                       if (!$no_defer && !empty($contact['contact-type']) && ($contact['contact-type'] != Contact::TYPE_RELAY)) {
+                               Logger::info('defer message', ['log' => $logid, 'guid' => $guid, 'destination' => $dest_url]);
+                               // defer message for redelivery
+                               Worker::defer();
                        }
 
                        // The message could not be delivered. We mark the contact as "dead"
@@ -3207,13 +3197,13 @@ class Diaspora
         * @param array  $message      The message data
         * @param bool   $public_batch Is it a public post?
         * @param string $guid         message guid
-        * @param bool   $spool        Should the transmission be spooled or transmitted?
+        * @param bool   $no_defer     Don't defer a failing delivery
         *
         * @return int Result of the transmission
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         * @throws \ImagickException
         */
-       private static function buildAndTransmit(array $owner, array $contact, $type, $message, $public_batch = false, $guid = "", $spool = false)
+       private static function buildAndTransmit(array $owner, array $contact, $type, $message, $public_batch = false, $guid = "", $no_defer = false)
        {
                $msg = self::buildPostXml($type, $message);
 
@@ -3227,12 +3217,7 @@ class Diaspora
 
                $envelope = self::buildMessage($msg, $owner, $contact, $owner['uprvkey'], $contact['pubkey'], $public_batch);
 
-               if ($spool) {
-                       Queue::add($contact['id'], Protocol::DIASPORA, $envelope, $public_batch, $guid);
-                       return true;
-               } else {
-                       $return_code = self::transmit($owner, $contact, $envelope, $public_batch, false, $guid);
-               }
+               $return_code = self::transmit($owner, $contact, $envelope, $public_batch, $guid, $no_defer);
 
                Logger::log("guid: ".$guid." result ".$return_code, Logger::DEBUG);
 
@@ -3675,7 +3660,7 @@ class Diaspora
                        && !strstr($body, $profile['addr'])
                        && !strstr($body, $profile_url)
                ) {
-                       $body = '@[url=' . $profile_url . ']' . $profile['nick'] . '[/url] ' . $body;
+                       $body = '@[url=' . $profile_url . ']' . $profile['name'] . '[/url] ' . $body;
                }
 
                return $body;
@@ -3776,7 +3761,7 @@ class Diaspora
         * @param array $item  The item that will be exported
         * @param array $owner the array of the item owner
         *
-        * @return array The data for a comment
+        * @return array|false The data for a comment
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
        private static function constructComment(array $item, array $owner)
@@ -3788,30 +3773,40 @@ class Diaspora
                        return $result;
                }
 
-               $parent = Item::selectFirst(['guid', 'author-link'], ['id' => $item["parent"], 'parent' => $item["parent"]]);
-               if (!DBA::isResult($parent)) {
+               $toplevel_item = Item::selectFirst(['guid', 'author-link'], ['id' => $item["parent"], 'parent' => $item["parent"]]);
+               if (!DBA::isResult($toplevel_item)) {
+                       Logger::error('Missing parent conversation item', ['parent' => $item["parent"]]);
                        return false;
                }
 
+               $thread_parent_item = $toplevel_item;
+               if ($item['thr-parent'] != $item['parent-uri']) {
+                       $thread_parent_item = Item::selectFirst(['guid', 'author-link'], ['uri' => $item['thr-parent'], 'uid' => $item['uid']]);
+               }
+
                $body = $item["body"];
 
-               if (empty($item['uid']) || !Feature::isEnabled($item['uid'], 'explicit_mentions')) {
-                       $body = self::prependParentAuthorMention($body, $parent['author-link']);
+               if ((empty($item['uid']) || !Feature::isEnabled($item['uid'], 'explicit_mentions'))
+                       && !Config::get('system', 'disable_implicit_mentions')
+               ) {
+                       $body = self::prependParentAuthorMention($body, $thread_parent_item['author-link']);
                }
 
                $text = html_entity_decode(BBCode::toMarkdown($body));
                $created = DateTimeFormat::utc($item["created"], DateTimeFormat::ATOM);
 
-               $comment = ["author" => self::myHandle($owner),
-                               "guid" => $item["guid"],
-                               "created_at" => $created,
-                               "parent_guid" => $parent["guid"],
-                               "text" => $text,
-                               "author_signature" => ""];
+               $comment = [
+                       "author"      => self::myHandle($owner),
+                       "guid"        => $item["guid"],
+                       "created_at"  => $created,
+                       "parent_guid" => $toplevel_item["guid"],
+                       "text"        => $text,
+                       "author_signature" => ""
+               ];
 
                // Send the thread parent guid only if it is a threaded comment
                if ($item['thr-parent'] != $item['parent-uri']) {
-                       $comment['thread_parent_guid'] = self::getGuidFromUri($item['thr-parent'], $item['uid']);
+                       $comment['thread_parent_guid'] = $thread_parent_item['guid'];
                }
 
                Cache::set($cachekey, $comment, Cache::QUARTER_HOUR);
@@ -4218,7 +4213,7 @@ class Diaspora
 
                foreach ($recips as $recip) {
                        Logger::log("Send updated profile data for user ".$uid." to contact ".$recip["id"], Logger::DEBUG);
-                       self::buildAndTransmit($owner, $recip, "profile", $message, false, "", false);
+                       self::buildAndTransmit($owner, $recip, "profile", $message, false, '', true);
                }
        }