]> git.mxchange.org Git - friendica.git/blobdiff - src/Content/Conversation.php
Merge pull request #11671 from MrPetovan/bug/fatal-errors
[friendica.git] / src / Content / Conversation.php
index fd1701483b4945dc63b38ced340f00b84f735f03..1088497983522f432dd008523efd3fede925ae27 100644 (file)
@@ -47,7 +47,6 @@ use Friendica\Protocol\Activity;
 use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Profiler;
-use Friendica\Util\Proxy;
 use Friendica\Util\Strings;
 use Friendica\Util\Temporal;
 use Psr\Log\LoggerInterface;
@@ -108,6 +107,8 @@ class Conversation
         */
        public function builtinActivityPuller(array $activity, array &$conv_responses)
        {
+               $thread_parent = $activity['thr-parent-row'] ?? [];
+
                foreach ($conv_responses as $mode => $v) {
                        $sparkle = '';
 
@@ -152,9 +153,8 @@ class Conversation
                                        $activity['thr-parent-id'] = $activity['parent-uri-id'];
                                }
 
-                               // Skip when the causer of the parent is the same than the author of the announce
-                               if (($verb == Activity::ANNOUNCE) && Post::exists(['uri-id' => $activity['thr-parent-id'],
-                                       'uid' => $activity['uid'], 'causer-id' => $activity['author-id'], 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT]])) {
+                               // Skip when the causer of the parent is the same as the author of the announce
+                               if (($verb == Activity::ANNOUNCE) && !empty($thread_parent['causer-id']) && ($thread_parent['causer-id'] == $activity['author-id'])) {
                                        continue;
                                }
 
@@ -189,7 +189,7 @@ class Conversation
         * @return string formatted text
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       public function formatActivity(array $links, $verb, $id)
+       public function formatActivity(array $links, string $verb, int $id): string
        {
                $this->profiler->startRecording('rendering');
                $o        = '';
@@ -275,7 +275,7 @@ class Conversation
                return $o;
        }
 
-       public function statusEditor(array $x = [], $notes_cid = 0, $popup = false)
+       public function statusEditor(array $x = [], int $notes_cid = 0, bool $popup = false): string
        {
                $user = User::getById($this->app->getLoggedInUserId(), ['uid', 'nickname', 'allow_location', 'default-location']);
                if (empty($user['uid'])) {
@@ -414,8 +414,8 @@ class Conversation
         * figures out how to determine page owner and other contextual items
         * that are based on unique features of the calling module.
         * @param array  $items
-        * @param        $mode
-        * @param        $update
+        * @param string $mode
+        * @param        $update @TODO Which type?
         * @param bool   $preview
         * @param string $order
         * @param int    $uid
@@ -423,7 +423,7 @@ class Conversation
         * @throws ImagickException
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       public function create(array $items, $mode, $update, $preview = false, $order = 'commented', $uid = 0)
+       public function create(array $items, string $mode, $update, bool $preview = false, string $order = 'commented', int $uid = 0): string
        {
                $this->profiler->startRecording('rendering');
 
@@ -441,7 +441,7 @@ class Conversation
                $previewing = (($preview) ? ' preview ' : '');
 
                if ($mode === 'network') {
-                       $items = $this->addChildren($items, false, $order, $uid);
+                       $items = $this->addChildren($items, false, $order, $uid, $mode);
                        if (!$update) {
                                /*
                                * The special div is needed for liveUpdate to kick in for this page.
@@ -467,7 +467,7 @@ class Conversation
                                        . "'; </script>\r\n";
                        }
                } elseif ($mode === 'profile') {
-                       $items = $this->addChildren($items, false, $order, $uid);
+                       $items = $this->addChildren($items, false, $order, $uid, $mode);
 
                        if (!$update) {
                                $tab = !empty($_GET['tab']) ? trim($_GET['tab']) : 'posts';
@@ -484,7 +484,7 @@ class Conversation
                                }
                        }
                } elseif ($mode === 'notes') {
-                       $items = $this->addChildren($items, false, $order, local_user());
+                       $items = $this->addChildren($items, false, $order, local_user(), $mode);
 
                        if (!$update) {
                                $live_update_div = '<div id="live-notes"></div>' . "\r\n"
@@ -492,7 +492,7 @@ class Conversation
                                        . "; var netargs = '/?f='; </script>\r\n";
                        }
                } elseif ($mode === 'display') {
-                       $items = $this->addChildren($items, false, $order, $uid);
+                       $items = $this->addChildren($items, false, $order, $uid, $mode);
 
                        if (!$update) {
                                $live_update_div = '<div id="live-display"></div>' . "\r\n"
@@ -500,17 +500,18 @@ class Conversation
                                        . "</script>";
                        }
                } elseif ($mode === 'community') {
-                       $items = $this->addChildren($items, true, $order, $uid);
+                       $items = $this->addChildren($items, true, $order, $uid, $mode);
 
                        if (!$update) {
                                $live_update_div = '<div id="live-community"></div>' . "\r\n"
                                        . "<script> var profile_uid = -1; var netargs = '" . substr($this->args->getCommand(), 10)
                                        . '?f='
                                        . (!empty($_GET['no_sharer']) ? '&no_sharer=' . rawurlencode($_GET['no_sharer']) : '')
+                                       . (!empty($_GET['accounttype']) ? '&accounttype=' . rawurlencode($_GET['accounttype']) : '')
                                        . "'; </script>\r\n";
                        }
                } elseif ($mode === 'contacts') {
-                       $items = $this->addChildren($items, false, $order, $uid);
+                       $items = $this->addChildren($items, false, $order, $uid, $mode);
 
                        if (!$update) {
                                $live_update_div = '<div id="live-contact"></div>' . "\r\n"
@@ -556,7 +557,7 @@ class Conversation
                        if (in_array($mode, ['community', 'contacts', 'profile'])) {
                                $writable = true;
                        } else {
-                               $writable = ($items[0]['uid'] == 0) && in_array($items[0]['network'], Protocol::FEDERATED);
+                               $writable = $items[0]['writable'] || ($items[0]['uid'] == 0) && in_array($items[0]['network'], Protocol::FEDERATED);
                        }
 
                        if (!local_user()) {
@@ -667,15 +668,15 @@ class Conversation
                                                'created_date'         => $item['created'],
                                                'uriid'                => $item['uri-id'],
                                                'network'              => $item['network'],
-                                               'network_name'         => ContactSelector::networkToName($item['author-network'], $item['author-link'], $item['network']),
-                                               'network_icon'         => ContactSelector::networkToIcon($item['network'], $item['author-link']),
+                                               'network_name'         => ContactSelector::networkToName($item['author-network'], $item['author-link'], $item['network'], $item['author-gsid']),
+                                               'network_icon'         => ContactSelector::networkToIcon($item['network'], $item['author-link'], $item['author-gsid']),
                                                'linktitle'            => $this->l10n->t('View %s\'s profile @ %s', $profile_name, $item['author-link']),
                                                'profile_url'          => $profile_link,
                                                'item_photo_menu_html' => $this->item->photoMenu($item, $formSecurityToken),
                                                'name'                 => $profile_name,
                                                'sparkle'              => $sparkle,
                                                'lock'                 => false,
-                                               'thumb'                => $this->baseURL->remove(Contact::getAvatarUrlForUrl($item['author-link'], $item['uid'], Proxy::SIZE_THUMB)),
+                                               'thumb'                => $this->baseURL->remove($this->item->getAuthorAvatar($item)),
                                                'title'                => $title,
                                                'body_html'            => $body_html,
                                                'tags'                 => $tags['tags'],
@@ -696,7 +697,7 @@ class Conversation
                                                'indent'               => '',
                                                'owner_name'           => '',
                                                'owner_url'            => '',
-                                               'owner_photo'          => $this->baseURL->remove(Contact::getAvatarUrlForUrl($item['owner-link'], $item['uid'], Proxy::SIZE_THUMB)),
+                                               'owner_photo'          => $this->baseURL->remove($this->item->getOwnerAvatar($item)),
                                                'plink'                => ItemModel::getPlink($item),
                                                'edpost'               => false,
                                                'pinned'               => $pinned,
@@ -783,7 +784,7 @@ class Conversation
                return $o;
        }
 
-       private function getBlocklist()
+       private function getBlocklist(): array
        {
                if (!local_user()) {
                        return [];
@@ -809,16 +810,17 @@ class Conversation
        /**
         * Adds some information (Causer, post reason, direction) to the fetched post row.
         *
-        * @param array   $row      Post row
-        * @param array   $activity Contact data of the resharer
+        * @param array   $row        Post row
+        * @param array   $activity   Contact data of the resharer
+        * @param array   $thr_parent Thread parent row
         *
         * @return array items with parents and comments
         */
-       private function addRowInformation(array $row, array $activity)
+       private function addRowInformation(array $row, array $activity, array $thr_parent): array
        {
                $this->profiler->startRecording('rendering');
 
-               if ($row['uid'] == 0) {
+               if (!$row['writable']) {
                        $row['writable'] = in_array($row['network'], Protocol::FEDERATED);
                }
 
@@ -889,6 +891,8 @@ class Conversation
                                break;
                }
 
+               $row['thr-parent-row'] = $thr_parent;
+
                $this->profiler->stopRecording();
                return $row;
        }
@@ -899,15 +903,15 @@ class Conversation
         * The system will fetch the comments for the local user whenever possible.
         * This behaviour is currently needed to allow commenting on Friendica posts.
         *
-        * @param array $parents Parent items
-        *
-        * @param       $block_authors
-        * @param       $order
-        * @param       $uid
+        * @param array  $parents       Parent items
+        * @param bool   $block_authors
+        * @param bool   $order
+        * @param int    $uid
+        * @param string $mode
         * @return array items with parents and comments
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       private function addChildren(array $parents, $block_authors, $order, $uid)
+       private function addChildren(array $parents, bool $block_authors, string $order, int $uid, string $mode): array
        {
                $this->profiler->startRecording('rendering');
                if (count($parents) > 1) {
@@ -916,8 +920,6 @@ class Conversation
                        $max_comments = $this->config->get('system', 'max_display_comments', 1000);
                }
 
-               $params = ['order' => ['uri-id' => true, 'uid' => true]];
-
                $activities      = [];
                $uriids          = [];
                $commentcounter  = [];
@@ -951,6 +953,17 @@ class Conversation
                $condition = DBA::mergeConditions($condition,
                        ["`uid` IN (0, ?) AND (`vid` != ? OR `vid` IS NULL)", $uid, Verb::getID(Activity::FOLLOW)]);
 
+               $thread_parents = Post::select(['uri-id', 'causer-id'], $condition, ['order' => ['uri-id' => false, 'uid']]);
+
+               $thr_parent = [];
+
+               while ($row = Post::fetch($thread_parents)) {
+                       $thr_parent[$row['uri-id']] = $row;
+               }
+               DBA::close($thread_parents);
+
+               $params = ['order' => ['uri-id' => true, 'uid' => true]];
+
                $thread_items = Post::selectForUser($uid, array_merge(ItemModel::DISPLAY_FIELDLIST, ['featured', 'contact-uid', 'gravity', 'post-type', 'post-reason']), $condition, $params);
 
                $items = [];
@@ -960,6 +973,10 @@ class Conversation
                                continue;
                        }
 
+                       if (($mode != 'contacts') && !$row['origin']) {
+                               $row['featured'] = false;
+                       }
+
                        if ($max_comments > 0) {
                                if (($row['gravity'] == GRAVITY_COMMENT) && (++$commentcounter[$row['parent-uri-id']] > $max_comments)) {
                                        continue;
@@ -968,7 +985,8 @@ class Conversation
                                        continue;
                                }
                        }
-                       $items[$row['uri-id']] = $this->addRowInformation($row, $activities[$row['uri-id']] ?? []);
+
+                       $items[$row['uri-id']] = $this->addRowInformation($row, $activities[$row['uri-id']] ?? [], $thr_parent[$row['thr-parent-id']] ?? []);
                }
 
                DBA::close($thread_items);
@@ -987,7 +1005,7 @@ class Conversation
         * @param bool  $recursive
         * @return array
         */
-       private function getItemChildren(array &$item_list, array $parent, $recursive = true)
+       private function getItemChildren(array &$item_list, array $parent, bool $recursive = true): array
        {
                $this->profiler->startRecording('rendering');
                $children = [];
@@ -1022,7 +1040,7 @@ class Conversation
         * @param array $items
         * @return array
         */
-       private function sortItemChildren(array $items)
+       private function sortItemChildren(array $items): array
        {
                $this->profiler->startRecording('rendering');
                $result = $items;
@@ -1068,7 +1086,7 @@ class Conversation
         * @param array $parent A tree-like array of items
         * @return array
         */
-       private function smartFlattenConversation(array $parent)
+       private function smartFlattenConversation(array $parent): array
        {
                $this->profiler->startRecording('rendering');
                if (!isset($parent['children']) || count($parent['children']) == 0) {
@@ -1124,7 +1142,7 @@ class Conversation
         * @return array
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       private function convSort(array $item_list, $order)
+       private function convSort(array $item_list, string $order): array
        {
                $this->profiler->startRecording('rendering');
                $parents = [];
@@ -1162,6 +1180,8 @@ class Conversation
                        usort($parents, [$this, 'sortThrReceived']);
                } elseif (stristr($order, 'commented')) {
                        usort($parents, [$this, 'sortThrCommented']);
+               } elseif (stristr($order, 'created')) {
+                       usort($parents, [$this, 'sortThrCreated']);
                }
 
                /*
@@ -1202,7 +1222,7 @@ class Conversation
         * @param array $b
         * @return int
         */
-       private function sortThrFeaturedReceived(array $a, array $b)
+       private function sortThrFeaturedReceived(array $a, array $b): int
        {
                if ($b['featured'] && !$a['featured']) {
                        return 1;
@@ -1220,7 +1240,7 @@ class Conversation
         * @param array $b
         * @return int
         */
-       private function sortThrFeaturedCommented(array $a, array $b)
+       private function sortThrFeaturedCommented(array $a, array $b): int
        {
                if ($b['featured'] && !$a['featured']) {
                        return 1;
@@ -1238,7 +1258,7 @@ class Conversation
         * @param array $b
         * @return int
         */
-       private function sortThrReceived(array $a, array $b)
+       private function sortThrReceived(array $a, array $b): int
        {
                return strcmp($b['received'], $a['received']);
        }
@@ -1250,7 +1270,7 @@ class Conversation
         * @param array $b
         * @return int
         */
-       private function sortThrReceivedRev(array $a, array $b)
+       private function sortThrReceivedRev(array $a, array $b): int
        {
                return strcmp($a['received'], $b['received']);
        }
@@ -1262,8 +1282,20 @@ class Conversation
         * @param array $b
         * @return int
         */
-       private function sortThrCommented(array $a, array $b)
+       private function sortThrCommented(array $a, array $b): int
        {
                return strcmp($b['commented'], $a['commented']);
        }
+
+       /**
+        * usort() callback to sort item arrays by the created key
+        *
+        * @param array $a
+        * @param array $b
+        * @return int
+        */
+       private function sortThrCreated(array $a, array $b): int
+       {
+               return strcmp($b['created'], $a['created']);
+       }
 }