]> git.mxchange.org Git - friendica.git/blobdiff - src/Model/Item.php
Merge pull request #5060 from annando/item-delete
[friendica.git] / src / Model / Item.php
index 11594486eaa13a86a7bd6b7d69c5a2a1470ef794..fb3e59eb259e0f267cfa1470abdfa164378e59ff 100644 (file)
@@ -52,17 +52,24 @@ class Item extends BaseObject
                        return false;
                }
 
+               // To ensure the data integrity we do it in an transaction
+               dba::transaction();
+
+               // We cannot simply expand the condition to check for origin entries
+               // The condition needn't to be a simple array but could be a complex condition.
+               // And we have to execute this query before the update to ensure to fetch the same data.
+               $items = dba::select('item', ['id', 'origin'], $condition);
+
                $success = dba::update('item', $fields, $condition);
 
                if (!$success) {
+                       dba::close($items);
+                       dba::rollback();
                        return false;
                }
 
                $rows = dba::affected_rows();
 
-               // We cannot simply expand the condition to check for origin entries
-               // The condition needn't to be a simple array but could be a complex condition.
-               $items = dba::select('item', ['id', 'origin'], $condition);
                while ($item = dba::fetch($items)) {
                        Term::insertFromTagFieldByItemId($item['id']);
                        Term::insertFromFileFieldByItemId($item['id']);
@@ -74,6 +81,8 @@ class Item extends BaseObject
                        }
                }
 
+               dba::close($items);
+               dba::commit();
                return $rows;
        }
 
@@ -103,15 +112,17 @@ class Item extends BaseObject
        public static function deleteById($item_id, $priority = PRIORITY_HIGH)
        {
                // locate item to be deleted
-               $fields = ['id', 'uid', 'parent', 'parent-uri', 'origin', 'deleted',
-                       'file', 'resource-id', 'event-id', 'attach',
+               $fields = ['id', 'uri', 'uid', 'parent', 'parent-uri', 'origin',
+                       'deleted', 'file', 'resource-id', 'event-id', 'attach',
                        'verb', 'object-type', 'object', 'target', 'contact-id'];
                $item = dba::selectFirst('item', $fields, ['id' => $item_id]);
                if (!DBM::is_result($item)) {
+                       logger('Item with ID ' . $item_id . " hasn't been found.", LOGGER_DEBUG);
                        return false;
                }
 
                if ($item['deleted']) {
+                       logger('Item with ID ' . $item_id . ' has already been deleted.', LOGGER_DEBUG);
                        return false;
                }
 
@@ -120,8 +131,6 @@ class Item extends BaseObject
                        $parent = ['origin' => false];
                }
 
-               logger('delete item: ' . $item['id'], LOGGER_DEBUG);
-
                // clean up categories and tags so they don't end up as orphans
 
                $matches = false;
@@ -174,16 +183,27 @@ class Item extends BaseObject
                Term::insertFromFileFieldByItemId($item['id']);
                self::deleteThread($item['id'], $item['parent-uri']);
 
+               if (!dba::exists('item', ["`uri` = ? AND `uid` != 0 AND NOT `deleted`", $item['uri']])) {
+                       self::delete(['uri' => $item['uri'], 'uid' => 0, 'deleted' => false], $priority);
+               }
+
                // If it's the parent of a comment thread, kill all the kids
                if ($item['id'] == $item['parent']) {
-                       self::delete(['parent' => $item['parent']], $priority);
+                       self::delete(['parent' => $item['parent'], 'deleted' => false], $priority);
                }
 
-               // send the notification upstream/downstream
+               // Is it our comment and/or our thread?
                if ($item['origin'] || $parent['origin']) {
+
+                       // When we delete the original post we will delete all existing copies on the server as well
+                       self::delete(['uri' => $item['uri'], 'deleted' => false], $priority);
+
+                       // send the notification upstream/downstream
                        Worker::add(['priority' => $priority, 'dont_fork' => true], "Notifier", "drop", intval($item['id']));
                }
 
+               logger('Item with ID ' . $item_id . " has been deleted.", LOGGER_DEBUG);
+
                return true;
        }
 
@@ -324,6 +344,12 @@ class Item extends BaseObject
                        $item['origin'] = 1;
                        $item['network'] = NETWORK_DFRN;
                        $item['protocol'] = PROTOCOL_DFRN;
+
+                       if (is_int($notify)) {
+                               $priority = $notify;
+                       } else {
+                               $priority = PRIORITY_HIGH;
+                       }
                } else {
                        $item['network'] = trim(defaults($item, 'network', NETWORK_PHANTOM));
                }
@@ -346,6 +372,13 @@ class Item extends BaseObject
                        unset($item['dsprsig']);
                }
 
+               if (!empty($item['diaspora_signed_text'])) {
+                       $diaspora_signed_text = $item['diaspora_signed_text'];
+                       unset($item['diaspora_signed_text']);
+               } else {
+                       $diaspora_signed_text = '';
+               }
+
                // Converting the plink
                /// @TODO Check if this is really still needed
                if ($item['network'] == NETWORK_OSTATUS) {
@@ -479,14 +512,20 @@ class Item extends BaseObject
                // The contact-id should be set before "self::insert" was called - but there seems to be issues sometimes
                $item["contact-id"] = self::contactId($item);
 
-               $item['author-id'] = defaults($item, 'author-id', Contact::getIdForURL($item["author-link"]));
+               $default = ['url' => $item['author-link'], 'name' => $item['author-name'],
+                       'photo' => $item['author-avatar'], 'network' => $item['network']];
+
+               $item['author-id'] = defaults($item, 'author-id', Contact::getIdForURL($item["author-link"], 0, false, $default));
 
                if (Contact::isBlocked($item["author-id"])) {
                        logger('Contact '.$item["author-id"].' is blocked, item '.$item["uri"].' will not be stored');
                        return 0;
                }
 
-               $item['owner-id'] = defaults($item, 'owner-id', Contact::getIdForURL($item["owner-link"]));
+               $default = ['url' => $item['owner-link'], 'name' => $item['owner-name'],
+                       'photo' => $item['owner-avatar'], 'network' => $item['network']];
+
+               $item['owner-id'] = defaults($item, 'owner-id', Contact::getIdForURL($item["owner-link"], 0, false, $default));
 
                if (Contact::isBlocked($item["owner-id"])) {
                        logger('Contact '.$item["owner-id"].' is blocked, item '.$item["uri"].' will not be stored');
@@ -538,7 +577,7 @@ class Item extends BaseObject
 
                        $fields = ['uri', 'parent-uri', 'id', 'deleted',
                                'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid',
-                               'wall', 'private', 'forum_mode'];
+                               'wall', 'private', 'forum_mode', 'origin'];
                        $condition = ['uri' => $item['parent-uri'], 'uid' => $item['uid']];
                        $params = ['order' => ['id' => false]];
                        $parent = dba::selectFirst('item', $fields, $condition, $params);
@@ -790,6 +829,12 @@ class Item extends BaseObject
                                                'signature' => $dsprsig->signature, 'signer' => $dsprsig->signer]);
                }
 
+               if (!empty($diaspora_signed_text)) {
+                       // Formerly we stored the signed text, the signature and the author in different fields.
+                       // We now store the raw data so that we are more flexible.
+                       dba::insert('sign', ['iid' => $current_post, 'signed_text' => $diaspora_signed_text]);
+               }
+
                $deleted = self::tagDeliver($item['uid'], $current_post);
 
                /*
@@ -833,12 +878,126 @@ class Item extends BaseObject
                check_user_notification($current_post);
 
                if ($notify) {
-                       Worker::add(['priority' => PRIORITY_HIGH, 'dont_fork' => true], "Notifier", $notify_type, $current_post);
+                       Worker::add(['priority' => $priority, 'dont_fork' => true], "Notifier", $notify_type, $current_post);
+               } elseif (!empty($parent) && $parent['origin']) {
+                       Worker::add(['priority' => PRIORITY_HIGH, 'dont_fork' => true], "Notifier", "comment-import", $current_post);
                }
 
                return $current_post;
        }
 
+       /**
+        * @brief Distributes public items to the receivers
+        *
+        * @param integer $itemid      Item ID that should be added
+        * @param string  $signed_text Original text (for Diaspora signatures), JSON encoded.
+        */
+       public static function distribute($itemid, $signed_text = '')
+       {
+               $condition = ["`id` IN (SELECT `parent` FROM `item` WHERE `id` = ?)", $itemid];
+               $parent = dba::selectFirst('item', ['owner-id'], $condition);
+               if (!DBM::is_result($parent)) {
+                       return;
+               }
+
+               // Only distribute public items from native networks
+               $condition = ['id' => $itemid, 'uid' => 0,
+                       'network' => [NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""],
+                       'visible' => true, 'deleted' => false, 'moderated' => false, 'private' => false];
+               $item = dba::selectFirst('item', [], ['id' => $itemid]);
+               if (!DBM::is_result($item)) {
+                       return;
+               }
+
+               unset($item['id']);
+               unset($item['parent']);
+               unset($item['mention']);
+               unset($item['wall']);
+               unset($item['origin']);
+               unset($item['starred']);
+               unset($item['rendered-hash']);
+               unset($item['rendered-html']);
+
+               $users = [];
+
+               $condition = ["`nurl` IN (SELECT `nurl` FROM `contact` WHERE `id` = ?) AND `uid` != 0 AND NOT `blocked` AND `rel` IN (?, ?)",
+                       $parent['owner-id'], CONTACT_IS_SHARING,  CONTACT_IS_FRIEND];
+               $contacts = dba::select('contact', ['uid'], $condition);
+               while ($contact = dba::fetch($contacts)) {
+                       $users[$contact['uid']] = $contact['uid'];
+               }
+
+               $origin_uid = 0;
+
+               if ($item['uri'] != $item['parent-uri']) {
+                       $parents = dba::select('item', ['uid', 'origin'], ["`uri` = ? AND `uid` != 0", $item['parent-uri']]);
+                       while ($parent = dba::fetch($parents)) {
+                               $users[$parent['uid']] = $parent['uid'];
+                               if ($parent['origin'] && !$item['origin']) {
+                                       $origin_uid = $parent['uid'];
+                               }
+                       }
+               }
+
+               foreach ($users as $uid) {
+                       if ($origin_uid == $uid) {
+                               $item['diaspora_signed_text'] = $signed_text;
+                       }
+                       self::storeForUser($itemid, $item, $uid);
+               }
+       }
+
+       /**
+        * @brief Store public items for the receivers
+        *
+        * @param integer $itemid Item ID that should be added
+        * @param array   $item   The item entry that will be stored
+        * @param integer $uid    The user that will receive the item entry
+        */
+       private static function storeForUser($itemid, $item, $uid)
+       {
+               $item['uid'] = $uid;
+               $item['origin'] = 0;
+               $item['wall'] = 0;
+               if ($item['uri'] == $item['parent-uri']) {
+                       $item['contact-id'] = Contact::getIdForURL($item['owner-link'], $uid);
+               } else {
+                       $item['contact-id'] = Contact::getIdForURL($item['author-link'], $uid);
+               }
+
+               if (empty($item['contact-id'])) {
+                       $self = dba::selectFirst('contact', ['id'], ['self' => true, 'uid' => $uid]);
+                       if (!DBM::is_result($self)) {
+                               return;
+                       }
+                       $item['contact-id'] = $self['id'];
+               }
+
+               if (in_array($item['type'], ["net-comment", "wall-comment"])) {
+                       $item['type'] = 'remote-comment';
+               } elseif ($item['type'] == 'wall') {
+                       $item['type'] = 'remote';
+               }
+
+               /// @todo Handling of "event-id"
+
+               $notify = false;
+               if ($item['uri'] == $item['parent-uri']) {
+                       $contact = dba::selectFirst('contact', [], ['id' => $item['contact-id'], 'self' => false]);
+                       if (DBM::is_result($contact)) {
+                               $notify = self::isRemoteSelf($contact, $item);
+                       }
+               }
+
+               $distributed = self::insert($item, false, $notify, true);
+
+               if (!$distributed) {
+                       logger("Distributed public item " . $itemid . " for user " . $uid . " wasn't stored", LOGGER_DEBUG);
+               } else {
+                       logger("Distributed public item " . $itemid . " for user " . $uid . " with id " . $distributed, LOGGER_DEBUG);
+               }
+       }
+
        /**
         * @brief Add a shadow entry for a given item id that is a thread starter
         *
@@ -850,8 +1009,8 @@ class Item extends BaseObject
         */
        public static function addShadow($itemid)
        {
-               $fields = ['uid', 'wall', 'private', 'moderated', 'visible', 'contact-id', 'deleted', 'network', 'author-id', 'owner-id'];
-               $condition = ["`id` = ? AND (`parent` = ? OR `parent` = 0)", $itemid, $itemid];
+               $fields = ['uid', 'private', 'moderated', 'visible', 'deleted', 'network'];
+               $condition = ['id' => $itemid, 'parent' => [0, $itemid]];
                $item = dba::selectFirst('item', $fields, $condition);
 
                if (!DBM::is_result($item)) {
@@ -873,35 +1032,22 @@ class Item extends BaseObject
                        return;
                }
 
-               // Only do these checks if the post isn't a wall post
-               if (!$item["wall"]) {
-                       // Check, if hide-friends is activated - then don't do a shadow entry
-                       if (dba::exists('profile', ['is-default' => true, 'uid' => $item['uid'], 'hide-friends' => true])) {
-                               return;
-                       }
-
-                       // Check if the contact is hidden or blocked
-                       if (!dba::exists('contact', ['hidden' => false, 'blocked' => false, 'id' => $item['contact-id']])) {
-                               return;
-                       }
-               }
-
-               // Only add a shadow, if the profile isn't hidden
-               if (dba::exists('user', ['uid' => $item['uid'], 'hidewall' => true])) {
-                       return;
-               }
-
                $item = dba::selectFirst('item', [], ['id' => $itemid]);
 
-               if (DBM::is_result($item) && ($item["allow_cid"] == '')  && ($item["allow_gid"] == '') &&
+               if (DBM::is_result($item) && ($item["allow_cid"] == '') && ($item["allow_gid"] == '') &&
                        ($item["deny_cid"] == '') && ($item["deny_gid"] == '')) {
 
                        if (!dba::exists('item', ['uri' => $item['uri'], 'uid' => 0])) {
                                // Preparing public shadow (removing user specific data)
-                               unset($item['id']);
                                $item['uid'] = 0;
-                               $item['origin'] = 0;
-                               $item['wall'] = 0;
+                               unset($item['id']);
+                               unset($item['parent']);
+                               unset($item['wall']);
+                               unset($item['mention']);
+                               unset($item['origin']);
+                               unset($item['starred']);
+                               unset($item['rendered-hash']);
+                               unset($item['rendered-html']);
                                if ($item['uri'] == $item['parent-uri']) {
                                        $item['contact-id'] = Contact::getIdForURL($item['owner-link']);
                                } else {
@@ -955,11 +1101,20 @@ class Item extends BaseObject
                        return;
                }
 
+               // Save "origin" and "parent" state
+               $origin = $item['origin'];
+               $parent = $item['parent'];
+
                // Preparing public shadow (removing user specific data)
-               unset($item['id']);
                $item['uid'] = 0;
-               $item['origin'] = 0;
-               $item['wall'] = 0;
+               unset($item['id']);
+               unset($item['parent']);
+               unset($item['wall']);
+               unset($item['mention']);
+               unset($item['origin']);
+               unset($item['starred']);
+               unset($item['rendered-hash']);
+               unset($item['rendered-html']);
                $item['contact-id'] = Contact::getIdForURL($item['author-link']);
 
                if (in_array($item['type'], ["net-comment", "wall-comment"])) {
@@ -971,6 +1126,14 @@ class Item extends BaseObject
                $public_shadow = self::insert($item, false, false, true);
 
                logger("Stored public shadow for comment ".$item['uri']." under id ".$public_shadow, LOGGER_DEBUG);
+
+               // If this was a comment to a Diaspora post we don't get our comment back.
+               // This means that we have to distribute the comment by ourselves.
+               if ($origin) {
+                       if (dba::exists('item', ['id' => $parent, 'network' => NETWORK_DIASPORA])) {
+                               self::distribute($public_shadow);
+                       }
+               }
        }
 
         /**
@@ -978,35 +1141,35 @@ class Item extends BaseObject
         * if possible and not already present.
         * Expects "body" element to exist in $arr.
         */
-       private static function addLanguageInPostopts(&$arr)
+       private static function addLanguageInPostopts(&$item)
        {
-               if (x($arr, 'postopts')) {
-                       if (strstr($arr['postopts'], 'lang=')) {
+               if (!empty($item['postopts'])) {
+                       if (strstr($item['postopts'], 'lang=')) {
                                // do not override
                                return;
                        }
-                       $postopts = $arr['postopts'];
+                       $postopts = $item['postopts'];
                } else {
                        $postopts = "";
                }
 
-               $naked_body = preg_replace('/\[(.+?)\]/','', $arr['body']);
-               $l = new Text_LanguageDetect();
-               $lng = $l->detect($naked_body, 3);
+               $naked_body = Text\BBCode::toPlaintext($item['body'], false);
 
-               if (sizeof($lng) > 0) {
-                       if ($postopts != "") {
+               $languages = (new Text_LanguageDetect())->detect($naked_body, 3);
+
+               if (sizeof($languages) > 0) {
+                       if ($postopts != '') {
                                $postopts .= '&'; // arbitrary separator, to be reviewed
                        }
 
                        $postopts .= 'lang=';
                        $sep = "";
 
-                       foreach ($lng as $language => $score) {
+                       foreach ($languages as $language => $score) {
                                $postopts .= $sep . $language . ";" . $score;
                                $sep = ':';
                        }
-                       $arr['postopts'] = $postopts;
+                       $item['postopts'] = $postopts;
                }
        }
 
@@ -1307,20 +1470,24 @@ class Item extends BaseObject
 
                // Prevent the forwarding of posts that are forwarded
                if ($datarray["extid"] == NETWORK_DFRN) {
+                       logger('Already forwarded', LOGGER_DEBUG);
                        return false;
                }
 
                // Prevent to forward already forwarded posts
                if ($datarray["app"] == $a->get_hostname()) {
+                       logger('Already forwarded (second test)', LOGGER_DEBUG);
                        return false;
                }
 
                // Only forward posts
                if ($datarray["verb"] != ACTIVITY_POST) {
+                       logger('No post', LOGGER_DEBUG);
                        return false;
                }
 
                if (($contact['network'] != NETWORK_FEED) && $datarray['private']) {
+                       logger('Not public', LOGGER_DEBUG);
                        return false;
                }
 
@@ -1342,6 +1509,10 @@ class Item extends BaseObject
 
                                unset($datarray['created']);
                                unset($datarray['edited']);
+
+                               unset($datarray['network']);
+                               unset($datarray['owner-id']);
+                               unset($datarray['author-id']);
                        }
 
                        if ($contact['network'] != NETWORK_FEED) {
@@ -1349,7 +1520,8 @@ class Item extends BaseObject
                                unset($datarray["plink"]);
                                $datarray["uri"] = item_new_uri($a->get_hostname(), $contact['uid'], $datarray["guid"]);
                                $datarray["parent-uri"] = $datarray["uri"];
-                               $datarray["extid"] = $contact['network'];
+                               $datarray["thr-parent"] = $datarray["uri"];
+                               $datarray["extid"] = NETWORK_DFRN;
                                $urlpart = parse_url($datarray2['author-link']);
                                $datarray["app"] = $urlpart["host"];
                        } else {
@@ -1359,10 +1531,11 @@ class Item extends BaseObject
 
                if ($contact['network'] != NETWORK_FEED) {
                        // Store the original post
-                       $r = self::insert($datarray2, false, false);
-                       logger('remote-self post original item - Contact '.$contact['url'].' return '.$r.' Item '.print_r($datarray2, true), LOGGER_DEBUG);
+                       $result = self::insert($datarray2, false, false);
+                       logger('remote-self post original item - Contact '.$contact['url'].' return '.$result.' Item '.print_r($datarray2, true), LOGGER_DEBUG);
                } else {
                        $datarray["app"] = "Feed";
+                       $result = true;
                }
 
                // Trigger automatic reactions for addons
@@ -1372,7 +1545,7 @@ class Item extends BaseObject
                $_SESSION["authenticated"] = true;
                $_SESSION["uid"] = $contact['uid'];
 
-               return true;
+               return $result;
        }
 
        /**
@@ -1554,165 +1727,6 @@ class Item extends BaseObject
                return $ret;
        }
 
-       /**
-        * @brief Convert a message into plaintext for connectors to other networks
-        *
-        * @param array  $item           The message array that is about to be posted
-        * @param int    $limit          The maximum number of characters when posting to that network
-        * @param bool   $includedlinks  Has an attached link to be included into the message?
-        * @param int    $htmlmode       This controls the behavior of the BBCode conversion
-        * @param string $target_network Name of the network where the post should go to.
-        *
-        * @see \Friendica\Content\Text\BBCode::getAttachedData
-        *
-        * @return array Same array structure than \Friendica\Content\Text\BBCode::getAttachedData
-        */
-       public static function getPlaintextPost($item, $limit = 0, $includedlinks = false, $htmlmode = 2, $target_network = '')
-       {
-               // Remove hashtags
-               $URLSearchString = '^\[\]';
-               $body = preg_replace("/([#@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$1$3', $item['body']);
-
-               // Add an URL element if the text contains a raw link
-               $body = preg_replace('/([^\]\=\'"]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism',
-                       '$1[url]$2[/url]', $body);
-
-               // Remove the abstract
-               $body = Text\BBCode::stripAbstract($body);
-
-               // At first look at data that is attached via "type-..." stuff
-               // This will hopefully replaced with a dedicated bbcode later
-               //$post = self::getAttachedData($b['body']);
-               $post = Text\BBCode::getAttachedData($body, $item);
-
-               if (($item['title'] != '') && ($post['text'] != '')) {
-                       $post['text'] = trim($item['title'] . "\n\n" . $post['text']);
-               } elseif ($item['title'] != '') {
-                       $post['text'] = trim($item['title']);
-               }
-
-               $abstract = '';
-
-               // Fetch the abstract from the given target network
-               if ($target_network != '') {
-                       $default_abstract = Text\BBCode::getAbstract($item['body']);
-                       $abstract = Text\BBCode::getAbstract($item['body'], $target_network);
-
-                       // If we post to a network with no limit we only fetch
-                       // an abstract exactly for this network
-                       if (($limit == 0) && ($abstract == $default_abstract)) {
-                               $abstract = '';
-                       }
-               } else {// Try to guess the correct target network
-                       switch ($htmlmode) {
-                               case 8:
-                                       $abstract = Text\BBCode::getAbstract($item['body'], NETWORK_TWITTER);
-                                       break;
-                               case 7:
-                                       $abstract = Text\BBCode::getAbstract($item['body'], NETWORK_STATUSNET);
-                                       break;
-                               case 6:
-                                       $abstract = Text\BBCode::getAbstract($item['body'], NETWORK_APPNET);
-                                       break;
-                               default: // We don't know the exact target.
-                                       // We fetch an abstract since there is a posting limit.
-                                       if ($limit > 0) {
-                                               $abstract = Text\BBCode::getAbstract($item['body']);
-                                       }
-                       }
-               }
-
-               if ($abstract != '') {
-                       $post['text'] = $abstract;
-
-                       if ($post['type'] == 'text') {
-                               $post['type'] = 'link';
-                               $post['url'] = $item['plink'];
-                       }
-               }
-
-               $html = Text\BBCode::convert($post['text'] . $post['after'], false, $htmlmode);
-               $msg = Text\HTML::toPlaintext($html, 0, true);
-               $msg = trim(html_entity_decode($msg, ENT_QUOTES, 'UTF-8'));
-
-               $link = '';
-               if ($includedlinks) {
-                       if ($post['type'] == 'link') {
-                               $link = $post['url'];
-                       } elseif ($post['type'] == 'text') {
-                               $link = $post['url'];
-                       } elseif ($post['type'] == 'video') {
-                               $link = $post['url'];
-                       } elseif ($post['type'] == 'photo') {
-                               $link = $post['image'];
-                       }
-
-                       if (($msg == '') && isset($post['title'])) {
-                               $msg = trim($post['title']);
-                       }
-
-                       if (($msg == '') && isset($post['description'])) {
-                               $msg = trim($post['description']);
-                       }
-
-                       // If the link is already contained in the post, then it neeedn't to be added again
-                       // But: if the link is beyond the limit, then it has to be added.
-                       if (($link != '') && strstr($msg, $link)) {
-                               $pos = strpos($msg, $link);
-
-                               // Will the text be shortened in the link?
-                               // Or is the link the last item in the post?
-                               if (($limit > 0) && ($pos < $limit) && (($pos + 23 > $limit) || ($pos + strlen($link) == strlen($msg)))) {
-                                       $msg = trim(str_replace($link, '', $msg));
-                               } elseif (($limit == 0) || ($pos < $limit)) {
-                                       // The limit has to be increased since it will be shortened - but not now
-                                       // Only do it with Twitter (htmlmode = 8)
-                                       if (($limit > 0) && (strlen($link) > 23) && ($htmlmode == 8)) {
-                                               $limit = $limit - 23 + strlen($link);
-                                       }
-
-                                       $link = '';
-
-                                       if ($post['type'] == 'text') {
-                                               unset($post['url']);
-                                       }
-                               }
-                       }
-               }
-
-               if ($limit > 0) {
-                       // Reduce multiple spaces
-                       // When posted to a network with limited space, we try to gain space where possible
-                       while (strpos($msg, '  ') !== false) {
-                               $msg = str_replace('  ', ' ', $msg);
-                       }
-
-                       // Twitter is using its own limiter, so we always assume that shortened links will have this length
-                       if (iconv_strlen($link, 'UTF-8') > 0) {
-                               $limit = $limit - 23;
-                       }
-
-                       if (iconv_strlen($msg, 'UTF-8') > $limit) {
-                               if (($post['type'] == 'text') && isset($post['url'])) {
-                                       $post['url'] = $item['plink'];
-                               } elseif (!isset($post['url'])) {
-                                       $limit = $limit - 23;
-                                       $post['url'] = $item['plink'];
-                                       // Which purpose has this line? It is now uncommented, but left as a reminder
-                                       //} elseif (strpos($b['body'], '[share') !== false) {
-                                       //      $post['url'] = $b['plink'];
-                               } elseif (PConfig::get($item['uid'], 'system', 'no_intelligent_shortening')) {
-                                       $post['url'] = $item['plink'];
-                               }
-                               $msg = Text\Plaintext::shorten($msg, $limit);
-                       }
-               }
-
-               $post['text'] = trim($msg);
-
-               return $post;
-       }
-
        public static function expire($uid, $days, $network = "", $force = false)
        {
                if (!$uid || ($days < 1)) {
@@ -2050,7 +2064,7 @@ EOT;
        {
                $fields = ['uid', 'guid', 'title', 'body', 'created', 'edited', 'commented', 'received', 'changed',
                        'wall', 'private', 'pubmail', 'moderated', 'visible', 'spam', 'starred', 'bookmark', 'contact-id',
-                       'deleted', 'origin', 'forum_mode', 'network', 'rendered-html', 'rendered-hash'];
+                       'deleted', 'origin', 'forum_mode', 'network', 'author-id', 'owner-id', 'rendered-html', 'rendered-hash'];
                $condition = ["`id` = ? AND (`parent` = ? OR `parent` = 0)", $itemid, $itemid];
 
                $item = dba::selectFirst('item', $fields, $condition);
@@ -2074,7 +2088,7 @@ EOT;
 
                $result = dba::update('thread', $fields, ['iid' => $itemid]);
 
-               logger("Update thread for item ".$itemid." - guid ".$item["guid"]." - ".(int)$result." ".print_r($item, true), LOGGER_DEBUG);
+               logger("Update thread for item ".$itemid." - guid ".$item["guid"]." - ".(int)$result, LOGGER_DEBUG);
 
                // Updating a shadow item entry
                $items = dba::selectFirst('item', ['id'], ['guid' => $item['guid'], 'uid' => 0]);