]> git.mxchange.org Git - friendica.git/blobdiff - src/Content/Conversation.php
Issue 11353: Suppress the forum sharer
[friendica.git] / src / Content / Conversation.php
index b5a9ab9766ef478fce7a698f50c4c2d90dc52ce6..89d9ca4c1b712e59de059595a3e8ce6b662bd30e 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * @copyright Copyright (C) 2010-2021, the Friendica project
+ * @copyright Copyright (C) 2010-2022, the Friendica project
  *
  * @license GNU AGPL version 3 or any later version
  *
@@ -25,14 +25,11 @@ use Friendica\App;
 use Friendica\App\Arguments;
 use Friendica\App\BaseURL;
 use Friendica\BaseModule;
-use Friendica\Content\ContactSelector;
-use Friendica\Content\Feature;
-use Friendica\Content\Item;
 use Friendica\Core\ACL;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\Hook;
 use Friendica\Core\L10n;
-use Friendica\Core\PConfig\IPConfig;
+use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
 use Friendica\Core\Protocol;
 use Friendica\Core\Renderer;
 use Friendica\Core\Session;
@@ -40,6 +37,7 @@ use Friendica\Core\Theme;
 use Friendica\Database\DBA;
 use Friendica\Model\Contact;
 use Friendica\Model\Item as ItemModel;
+use Friendica\Model\Photo;
 use Friendica\Model\Post;
 use Friendica\Model\Tag;
 use Friendica\Model\User;
@@ -69,11 +67,11 @@ class Conversation
        private $item;
        /** @var App\Arguments */
        private $args;
-       /** @var IPConfig */
+       /** @var IManagePersonalConfigValues */
        private $pConfig;
        /** @var BaseURL */
        private $baseURL;
-       /** @var IConfig */
+       /** @var IManageConfigValues */
        private $config;
        /** @var App */
        private $app;
@@ -82,7 +80,7 @@ class Conversation
        /** @var App\Mode */
        private $mode;
 
-       public function __construct(LoggerInterface $logger, Profiler $profiler, Activity $activity, L10n $l10n, Item $item, Arguments $args, BaseURL $baseURL, IConfig $config, IPConfig $pConfig, App\Page $page, App\Mode $mode, App $app)
+       public function __construct(LoggerInterface $logger, Profiler $profiler, Activity $activity, L10n $l10n, Item $item, Arguments $args, BaseURL $baseURL, IManageConfigValues $config, IManagePersonalConfigValues $pConfig, App\Page $page, App\Mode $mode, App $app)
        {
                $this->activity = $activity;
                $this->item     = $item;
@@ -111,6 +109,8 @@ class Conversation
         */
        public function builtinActivityPuller(array $activity, array &$conv_responses)
        {
+               $thread_parent = $activity['thr-parent-row'] ?? [];
+
                foreach ($conv_responses as $mode => $v) {
                        $sparkle = '';
 
@@ -155,9 +155,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])) {
+                               // 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;
                                }
 
@@ -226,12 +225,12 @@ class Conversation
                                        break;
                        }
                } elseif ($total > 1) {
-                       if ($total < MAX_LIKERS) {
+                       if ($total < $this->config->get('system', 'max_likers')) {
                                $likers = implode(', ', array_slice($links, 0, -1));
                                $likers .= ' ' . $this->l10n->t('and') . ' ' . $links[count($links) - 1];
                        } else {
-                               $likers = implode(', ', array_slice($links, 0, MAX_LIKERS - 1));
-                               $likers .= ' ' . $this->l10n->t('and %d other people', $total - MAX_LIKERS);
+                               $likers = implode(', ', array_slice($links, 0, $this->config->get('system', 'max_likers') - 1));
+                               $likers .= ' ' . $this->l10n->t('and %d other people', $total - $this->config->get('system', 'max_likers'));
                        }
 
                        $spanatts = "class=\"fakelink\" onclick=\"openClose('{$verb}list-$id');\"";
@@ -288,15 +287,15 @@ class Conversation
                $this->profiler->startRecording('rendering');
                $o = '';
 
-               $x['allow_location']   = $x['allow_location'] ?? $user['allow_location'];
+               $x['allow_location']   = $x['allow_location']   ?? $user['allow_location'];
                $x['default_location'] = $x['default_location'] ?? $user['default-location'];
-               $x['nickname']         = $x['nickname'] ?? $user['nickname'];
-               $x['lockstate']        = $x['lockstate'] ?? ACL::getLockstateForUserId($user['uid']) ? 'lock' : 'unlock';
-               $x['acl']              = $x['acl'] ?? ACL::getFullSelectorHTML($this->page, $user['uid'], true);
-               $x['bang']             = $x['bang'] ?? '';
-               $x['visitor']          = $x['visitor'] ?? 'block';
-               $x['is_owner']         = $x['is_owner'] ?? true;
-               $x['profile_uid']      = $x['profile_uid'] ?? local_user();
+               $x['nickname']         = $x['nickname']         ?? $user['nickname'];
+               $x['lockstate']        = $x['lockstate']        ?? ACL::getLockstateForUserId($user['uid']) ? 'lock' : 'unlock';
+               $x['acl']              = $x['acl']              ?? ACL::getFullSelectorHTML($this->page, $user['uid'], true);
+               $x['bang']             = $x['bang']             ?? '';
+               $x['visitor']          = $x['visitor']          ?? 'block';
+               $x['is_owner']         = $x['is_owner']         ?? true;
+               $x['profile_uid']      = $x['profile_uid']      ?? local_user();
 
 
                $geotag = !empty($x['allow_location']) ? Renderer::replaceMacros(Renderer::getMarkupTemplate('jot_geotag.tpl'), []) : '';
@@ -319,6 +318,18 @@ class Conversation
                $jotplugins = '';
                Hook::callAll('jot_tool', $jotplugins);
 
+               if ($this->config->get('system', 'set_creation_date')) {
+                       $created_at = Temporal::getDateTimeField(
+                               new \DateTime(DBA::NULL_DATETIME),
+                               new \DateTime('now'),
+                               null,
+                               $this->l10n->t('Created at'),
+                               'created_at'
+                       );
+               } else {
+                       $created_at = '';
+               }
+
                $tpl = Renderer::getMarkupTemplate("jot.tpl");
 
                $o .= Renderer::replaceMacros($tpl, [
@@ -355,6 +366,7 @@ class Conversation
                                $this->l10n->t('Scheduled at'),
                                'scheduled_at'
                        ),
+                       '$created_at'   => $created_at,
                        '$wait'         => $this->l10n->t('Please wait'),
                        '$permset'      => $this->l10n->t('Permission settings'),
                        '$shortpermset' => $this->l10n->t('Permissions'),
@@ -443,21 +455,21 @@ class Conversation
                                        . "; var netargs = '" . substr($this->args->getCommand(), 8)
                                        . '?f='
                                        . (!empty($_GET['contactid']) ? '&contactid=' . rawurlencode($_GET['contactid']) : '')
-                                       . (!empty($_GET['search']) ? '&search=' . rawurlencode($_GET['search']) : '')
-                                       . (!empty($_GET['star']) ? '&star=' . rawurlencode($_GET['star']) : '')
-                                       . (!empty($_GET['order']) ? '&order=' . rawurlencode($_GET['order']) : '')
-                                       . (!empty($_GET['bmark']) ? '&bmark=' . rawurlencode($_GET['bmark']) : '')
-                                       . (!empty($_GET['liked']) ? '&liked=' . rawurlencode($_GET['liked']) : '')
-                                       . (!empty($_GET['conv']) ? '&conv=' . rawurlencode($_GET['conv']) : '')
-                                       . (!empty($_GET['nets']) ? '&nets=' . rawurlencode($_GET['nets']) : '')
-                                       . (!empty($_GET['cmin']) ? '&cmin=' . rawurlencode($_GET['cmin']) : '')
-                                       . (!empty($_GET['cmax']) ? '&cmax=' . rawurlencode($_GET['cmax']) : '')
-                                       . (!empty($_GET['file']) ? '&file=' . rawurlencode($_GET['file']) : '')
+                                       . (!empty($_GET['search'])    ? '&search='    . rawurlencode($_GET['search'])    : '')
+                                       . (!empty($_GET['star'])      ? '&star='      . rawurlencode($_GET['star'])      : '')
+                                       . (!empty($_GET['order'])     ? '&order='     . rawurlencode($_GET['order'])     : '')
+                                       . (!empty($_GET['bmark'])     ? '&bmark='     . rawurlencode($_GET['bmark'])     : '')
+                                       . (!empty($_GET['liked'])     ? '&liked='     . rawurlencode($_GET['liked'])     : '')
+                                       . (!empty($_GET['conv'])      ? '&conv='      . rawurlencode($_GET['conv'])      : '')
+                                       . (!empty($_GET['nets'])      ? '&nets='      . rawurlencode($_GET['nets'])      : '')
+                                       . (!empty($_GET['cmin'])      ? '&cmin='      . rawurlencode($_GET['cmin'])      : '')
+                                       . (!empty($_GET['cmax'])      ? '&cmax='      . rawurlencode($_GET['cmax'])      : '')
+                                       . (!empty($_GET['file'])      ? '&file='      . rawurlencode($_GET['file'])      : '')
 
                                        . "'; </script>\r\n";
                        }
                } elseif ($mode === 'profile') {
-                       $items = $this->addChildren($items, false, $order, local_user());
+                       $items = $this->addChildren($items, false, $order, $uid);
 
                        if (!$update) {
                                $tab = !empty($_GET['tab']) ? trim($_GET['tab']) : 'posts';
@@ -632,12 +644,41 @@ class Conversation
 
                                        $body_html = ItemModel::prepareBody($item, true, $preview);
 
-                                       list($categories, $folders) = $this->item->determineCategoriesTerms($item, local_user());
+                                       [$categories, $folders] = $this->item->determineCategoriesTerms($item, local_user());
 
-                                       if (!empty($item['content-warning']) && $this->pConfig->get(local_user(), 'system', 'disable_cw', false)) {
+                                       if (!empty($item['title'])) {
+                                               $title = $item['title'];
+                                       } elseif (!empty($item['content-warning']) && $this->pConfig->get(local_user(), 'system', 'disable_cw', false)) {
                                                $title = ucfirst($item['content-warning']);
                                        } else {
-                                               $title = $item['title'];
+                                               $title = '';
+                                       }
+
+                                       if (!empty($item['featured'])) {
+                                               $pinned = $this->l10n->t('Pinned item');
+                                       } else {
+                                               $pinned = '';
+                                       }
+
+                                       if (in_array($item['network'], [Protocol::FEED, Protocol::MAIL])) {
+                                               $owner_avatar  = $author_avatar  = $item['contact-id'];
+                                               $owner_updated = $author_updated = '';
+                                               $owner_thumb   = $author_thumb   = $item['contact-avatar'];
+                                       } else {
+                                               $owner_avatar   = $item['owner-id'];
+                                               $owner_updated  = $item['owner-updated'];
+                                               $owner_thumb    = $item['owner-avatar'];
+                                               $author_avatar  = $item['author-id'];
+                                               $author_updated = $item['author-updated'];
+                                               $author_thumb   = $item['author-avatar'];
+                                       }
+
+                                       if (empty($owner_thumb) || Photo::isPhotoURI($owner_thumb)) {
+                                               $owner_thumb = Contact::getAvatarUrlForId($owner_avatar, Proxy::SIZE_THUMB, $owner_updated);
+                                       }
+                       
+                                       if (empty($author_thumb) || Photo::isPhotoURI($author_thumb)) {
+                                               $author_thumb = Contact::getAvatarUrlForId($author_avatar, Proxy::SIZE_THUMB, $author_updated);
                                        }
 
                                        $tmp_item = [
@@ -649,15 +690,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($author_thumb),
                                                'title'                => $title,
                                                'body_html'            => $body_html,
                                                'tags'                 => $tags['tags'],
@@ -672,14 +713,16 @@ class Conversation
                                                'folders'              => $folders,
                                                'text'                 => strip_tags($body_html),
                                                'localtime'            => DateTimeFormat::local($item['created'], 'r'),
+                                               'utc'                  => DateTimeFormat::utc($item['created'], 'c'),
                                                'ago'                  => (($item['app']) ? $this->l10n->t('%s from %s', Temporal::getRelativeDate($item['created']), $item['app']) : Temporal::getRelativeDate($item['created'])),
                                                'location_html'        => $location_html,
                                                '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($owner_thumb),
                                                'plink'                => ItemModel::getPlink($item),
                                                'edpost'               => false,
+                                               'pinned'               => $pinned,
                                                'isstarred'            => 'unstarred',
                                                'star'                 => false,
                                                'drop'                 => $drop,
@@ -687,7 +730,7 @@ class Conversation
                                                'like_html'            => '',
                                                'dislike_html '        => '',
                                                'comment_html'         => '',
-                                               'conv'                 => ($preview ? '' : ['href' => 'display/' . $item['guid'], 'title'=> $this->l10n->t('View in context')]),
+                                               'conv'                 => ($preview ? '' : ['href' => 'display/' . $item['guid'], 'title' => $this->l10n->t('View in context')]),
                                                'previewing'           => $previewing,
                                                'wait'                 => $this->l10n->t('Please wait'),
                                                'thread_level'         => 1,
@@ -699,7 +742,6 @@ class Conversation
                                        $threads[$threadsid]['id']      = $item['id'];
                                        $threads[$threadsid]['network'] = $item['network'];
                                        $threads[$threadsid]['items']   = [$arr['output']];
-
                                }
                        } else {
                                // Normal View
@@ -790,12 +832,13 @@ 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)
        {
                $this->profiler->startRecording('rendering');
 
@@ -846,9 +889,9 @@ class Conversation
                                        $row['owner-name']   = $row['causer-name'];
                                }
 
-                               if (($row['gravity'] == GRAVITY_PARENT) && !empty($row['causer-id'])) {
-                                       $causer = ['uid' => 0, 'id' => $row['causer-id'],
-                                               'network' => $row['causer-network'], 'url' => $row['causer-link']];
+                               if (in_array($row['gravity'], [GRAVITY_PARENT, GRAVITY_COMMENT]) && !empty($row['causer-id'])) {
+                                       $causer = ['uid' => 0, 'id' => $row['causer-id'], 'network' => $row['causer-network'], 'url' => $row['causer-link']];
+
                                        $row['reshared'] = $this->l10n->t('%s reshared this.', '<a href="'. htmlentities(Contact::magicLinkByContact($causer)) .'">' . htmlentities($row['causer-name']) . '</a>');
                                }
                                $row['direction'] = ['direction' => 3, 'title' => (empty($row['causer-id']) ? $this->l10n->t('Reshared') : $this->l10n->t('Reshared by %s <%s>', $row['causer-name'], $row['causer-link']))];
@@ -870,6 +913,8 @@ class Conversation
                                break;
                }
 
+               $row['thr-parent-row'] = $thr_parent;
+
                $this->profiler->stopRecording();
                return $row;
        }
@@ -897,8 +942,6 @@ class Conversation
                        $max_comments = $this->config->get('system', 'max_display_comments', 1000);
                }
 
-               $params = ['order' => ['uri-id' => true, 'uid' => true]];
-
                $activities      = [];
                $uriids          = [];
                $commentcounter  = [];
@@ -932,7 +975,18 @@ class Conversation
                $condition = DBA::mergeConditions($condition,
                        ["`uid` IN (0, ?) AND (`vid` != ? OR `vid` IS NULL)", $uid, Verb::getID(Activity::FOLLOW)]);
 
-               $thread_items = Post::selectForUser(local_user(), array_merge(ItemModel::DISPLAY_FIELDLIST, ['pinned', 'contact-uid', 'gravity', 'post-type', 'post-reason']), $condition, $params);
+               $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 = [];
 
@@ -949,7 +1003,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);
@@ -1136,11 +1191,15 @@ class Conversation
                }
 
                if (stristr($order, 'pinned_received')) {
-                       usort($parents, [$this, 'sortThrPinnedReceived']);
+                       usort($parents, [$this, 'sortThrFeaturedReceived']);
+               } elseif (stristr($order, 'pinned_commented')) {
+                       usort($parents, [$this, 'sortThrFeaturedCommented']);
                } elseif (stristr($order, 'received')) {
                        usort($parents, [$this, 'sortThrReceived']);
                } elseif (stristr($order, 'commented')) {
                        usort($parents, [$this, 'sortThrCommented']);
+               } elseif (stristr($order, 'created')) {
+                       usort($parents, [$this, 'sortThrCreated']);
                }
 
                /*
@@ -1175,23 +1234,41 @@ class Conversation
        }
 
        /**
-        * usort() callback to sort item arrays by pinned and the received key
+        * usort() callback to sort item arrays by featured and the received key
         *
         * @param array $a
         * @param array $b
         * @return int
         */
-       private function sortThrPinnedReceived(array $a, array $b)
+       private function sortThrFeaturedReceived(array $a, array $b)
        {
-               if ($b['pinned'] && !$a['pinned']) {
+               if ($b['featured'] && !$a['featured']) {
                        return 1;
-               } elseif (!$b['pinned'] && $a['pinned']) {
+               } elseif (!$b['featured'] && $a['featured']) {
                        return -1;
                }
 
                return strcmp($b['received'], $a['received']);
        }
 
+       /**
+        * usort() callback to sort item arrays by featured and the received key
+        *
+        * @param array $a
+        * @param array $b
+        * @return int
+        */
+       private function sortThrFeaturedCommented(array $a, array $b)
+       {
+               if ($b['featured'] && !$a['featured']) {
+                       return 1;
+               } elseif (!$b['featured'] && $a['featured']) {
+                       return -1;
+               }
+
+               return strcmp($b['commented'], $a['commented']);
+       }
+
        /**
         * usort() callback to sort item arrays by the received key
         *
@@ -1227,4 +1304,16 @@ class Conversation
        {
                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)
+       {
+               return strcmp($b['created'], $a['created']);
+       }
 }