]> git.mxchange.org Git - friendica.git/blobdiff - src/Model/Item.php
Merge remote-tracking branch 'upstream/develop' into reworked-delivery
[friendica.git] / src / Model / Item.php
index 926552a17e6b7e24e008f483fcbd1e07451decba..aa3800cbe175c55c5897969a36f9bf9d97f32926 100644 (file)
@@ -7,6 +7,7 @@
 namespace Friendica\Model;
 
 use Friendica\BaseObject;
+use Friendica\Content\Text;
 use Friendica\Core\Addon;
 use Friendica\Core\Config;
 use Friendica\Core\L10n;
@@ -22,13 +23,13 @@ use Friendica\Object\Image;
 use Friendica\Protocol\Diaspora;
 use Friendica\Protocol\OStatus;
 use Friendica\Util\DateTimeFormat;
+use Friendica\Util\XML;
 use dba;
 use Text_LanguageDetect;
 
 require_once 'boot.php';
 require_once 'include/items.php';
 require_once 'include/text.php';
-require_once 'include/event.php';
 
 class Item extends BaseObject
 {
@@ -97,7 +98,7 @@ class Item extends BaseObject
         * @param integer $item_id Item ID that should be delete
         * @param integer $priority Priority for the notification
         *
-        * @return $boolean success
+        * @return boolean success
         */
        public static function deleteById($item_id, $priority = PRIORITY_HIGH)
        {
@@ -152,7 +153,7 @@ class Item extends BaseObject
 
                // If item is a link to an event, delete the event.
                if (intval($item['event-id'])) {
-                       event_delete($item['event-id']);
+                       Event::delete($item['event-id']);
                }
 
                // If item has attachments, drop them
@@ -355,6 +356,10 @@ class Item extends BaseObject
                        }
                }
 
+               if (!empty($item['thr-parent'])) {
+                       $item['parent-uri'] = $item['thr-parent'];
+               }
+
                if (x($item, 'gravity')) {
                        $item['gravity'] = intval($item['gravity']);
                } elseif ($item['parent-uri'] === $item['uri']) {
@@ -834,6 +839,102 @@ class Item extends BaseObject
                return $current_post;
        }
 
+       /**
+        * @brief Distributes public items to the receivers
+        *
+        * @param integer $itemid Item ID that should be added
+        */
+       public static function distribute($itemid)
+       {
+               $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['global']);
+               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 NOT `readonly` 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'];
+               }
+
+               if ($item['uri'] != $item['parent-uri']) {
+                       $parents = dba::select('item', ['uid'], ["`uri` = ? AND `uid` != 0", $item['parent-uri']]);
+                       while ($parent = dba::fetch($parents)) {
+                               $users[$parent['uid']] = $parent['uid'];
+                       }
+               }
+
+               foreach ($users as $uid) {
+                       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"
+
+               $distributed = self::insert($item, false, false, 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
         *
@@ -845,8 +946,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)) {
@@ -868,27 +969,9 @@ 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])) {
@@ -897,7 +980,11 @@ class Item extends BaseObject
                                $item['uid'] = 0;
                                $item['origin'] = 0;
                                $item['wall'] = 0;
-                               $item['contact-id'] = Contact::getIdForURL($item['author-link']);
+                               if ($item['uri'] == $item['parent-uri']) {
+                                       $item['contact-id'] = Contact::getIdForURL($item['owner-link']);
+                               } else {
+                                       $item['contact-id'] = Contact::getIdForURL($item['author-link']);
+                               }
 
                                if (in_array($item['type'], ["net-comment", "wall-comment"])) {
                                        $item['type'] = 'remote-comment';
@@ -969,35 +1056,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;
                }
        }
 
@@ -1264,21 +1351,23 @@ class Item extends BaseObject
                }
 
                // now change this copy of the post to a forum head message and deliver to all the tgroup members
-               $self = dba::selectFirst('contact', ['name', 'url', 'thumb'], ['uid' => $uid, 'self' => true]);
+               $self = dba::selectFirst('contact', ['id', 'name', 'url', 'thumb'], ['uid' => $uid, 'self' => true]);
                if (!DBM::is_result($self)) {
                        return;
                }
 
+               $owner_id = Contact::getIdForURL($self['url']);
+
                // also reset all the privacy bits to the forum default permissions
 
                $private = ($user['allow_cid'] || $user['allow_gid'] || $user['deny_cid'] || $user['deny_gid']) ? 1 : 0;
 
                $forum_mode = ($prvgroup ? 2 : 1);
 
-               $fields = ['wall' => true, 'origin' => true, 'forum_mode' => $forum_mode,
-                       'owner-name' => $self['name'], 'owner-link' => $self['url'], 'owner-avatar' => $self['thumb'],
-                       'private' => $private, 'allow_cid' => $user['allow_cid'], 'allow_gid' => $user['allow_gid'],
-                       'deny_cid' => $user['deny_cid'], 'deny_gid' => $user['deny_gid']];
+               $fields = ['wall' => true, 'origin' => true, 'forum_mode' => $forum_mode, 'contact-id' => $self['id'],
+                       'owner-id' => $owner_id, 'owner-name' => $self['name'], 'owner-link' => $self['url'],
+                       'owner-avatar' => $self['thumb'], 'private' => $private, 'allow_cid' => $user['allow_cid'],
+                       'allow_gid' => $user['allow_gid'], 'deny_cid' => $user['deny_cid'], 'deny_gid' => $user['deny_gid']];
                dba::update('item', $fields, ['id' => $item_id]);
 
                self::updateThread($item_id);
@@ -1723,7 +1812,7 @@ class Item extends BaseObject
                        $item_contact_id = $owner_self_contact['id'];
                        $item_contact = $owner_self_contact;
                } else {
-                       $item_contact_id = Contact::getIdForURL($author_contact['url'], $uid);
+                       $item_contact_id = Contact::getIdForURL($author_contact['url'], $uid, true);
                        $item_contact = dba::selectFirst('contact', [], ['id' => $item_contact_id]);
                        if (!DBM::is_result($item_contact)) {
                                logger('like: unknown item contact ' . $item_contact_id);