]> git.mxchange.org Git - friendica.git/blobdiff - src/Module/Contact/Profile.php
Merge pull request #13314 from MrPetovan/bug/13311-removeme-delegate
[friendica.git] / src / Module / Contact / Profile.php
index 886798a5f83a672403b88b5508c168d9e18e6bd1..04def1a4f96974651de2cf012126b4c80919f67a 100644 (file)
@@ -23,8 +23,7 @@ namespace Friendica\Module\Contact;
 
 use Friendica\App;
 use Friendica\BaseModule;
-use Friendica\Contact\LocalRelationship\Entity;
-use Friendica\Contact\LocalRelationship\Repository;
+use Friendica\Contact\LocalRelationship;
 use Friendica\Content\ContactSelector;
 use Friendica\Content\Nav;
 use Friendica\Content\Text\BBCode;
@@ -34,13 +33,16 @@ use Friendica\Core\Hook;
 use Friendica\Core\L10n;
 use Friendica\Core\Protocol;
 use Friendica\Core\Renderer;
+use Friendica\Core\Session\Capability\IHandleUserSessions;
+use Friendica\Database\Database;
 use Friendica\Database\DBA;
-use Friendica\DI;
+use Friendica\Model\Circle;
 use Friendica\Model\Contact;
-use Friendica\Model\Group;
 use Friendica\Module;
 use Friendica\Module\Response;
+use Friendica\Navigation\SystemMessages;
 use Friendica\Network\HTTPException;
+use Friendica\User\Settings;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Profiler;
 use Psr\Log\LoggerInterface;
@@ -50,31 +52,37 @@ use Psr\Log\LoggerInterface;
  */
 class Profile extends BaseModule
 {
-       /**
-        * @var Repository\LocalRelationship
-        */
+       /** @var LocalRelationship\Repository\LocalRelationship */
        private $localRelationship;
-       /**
-        * @var App\Page
-        */
+       /** @var App\Page */
        private $page;
-       /**
-        * @var IManageConfigValues
-        */
+       /** @var IManageConfigValues */
        private $config;
-
-       public function __construct(L10n $l10n, Repository\LocalRelationship $localRelationship, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, App\Page $page, IManageConfigValues $config, array $server, array $parameters = [])
+       /** @var IHandleUserSessions */
+       private $session;
+       /** @var SystemMessages */
+       private $systemMessages;
+       /** @var Database */
+       private $db;
+       /** @var Settings\Repository\UserGServer */
+       private $userGServer;
+
+       public function __construct(Settings\Repository\UserGServer $userGServer, Database $db, SystemMessages $systemMessages, IHandleUserSessions $session, L10n $l10n, LocalRelationship\Repository\LocalRelationship $localRelationship, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, App\Page $page, IManageConfigValues $config, array $server, array $parameters = [])
        {
                parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
 
                $this->localRelationship = $localRelationship;
                $this->page              = $page;
                $this->config            = $config;
+               $this->session           = $session;
+               $this->systemMessages    = $systemMessages;
+               $this->db                = $db;
+               $this->userGServer       = $userGServer;
        }
 
        protected function post(array $request = [])
        {
-               if (!DI::userSession()->getLocalUserId()) {
+               if (!$this->session->getLocalUserId()) {
                        return;
                }
 
@@ -82,8 +90,8 @@ class Profile extends BaseModule
 
                // Backward compatibility: The update still needs a user-specific contact ID
                // Change to user-contact table check by version 2022.03
-               $cdata = Contact::getPublicAndUserContactID($contact_id, DI::userSession()->getLocalUserId());
-               if (empty($cdata['user']) || !DBA::exists('contact', ['id' => $cdata['user'], 'deleted' => false])) {
+               $cdata = Contact::getPublicAndUserContactID($contact_id, $this->session->getLocalUserId());
+               if (empty($cdata['user']) || !$this->db->exists('contact', ['id' => $cdata['user'], 'deleted' => false])) {
                        return;
                }
 
@@ -124,35 +132,39 @@ class Profile extends BaseModule
                        $fields['info'] = $_POST['info'];
                }
 
-               if (!Contact::update($fields, ['id' => $cdata['user'], 'uid' => DI::userSession()->getLocalUserId()])) {
-                       DI::sysmsg()->addNotice($this->t('Failed to update contact record.'));
+               if (isset($_POST['channel_frequency'])) {
+                       Contact\User::setChannelFrequency($cdata['user'], $this->session->getLocalUserId(), $_POST['channel_frequency']);
+               }
+
+               if (!Contact::update($fields, ['id' => $cdata['user'], 'uid' => $this->session->getLocalUserId()])) {
+                       $this->systemMessages->addNotice($this->t('Failed to update contact record.'));
                }
        }
 
        protected function content(array $request = []): string
        {
-               if (!DI::userSession()->getLocalUserId()) {
+               if (!$this->session->getLocalUserId()) {
                        return Module\Security\Login::form($_SERVER['REQUEST_URI']);
                }
 
                // Backward compatibility: Ensure to use the public contact when the user contact is provided
                // Remove by version 2022.03
-               $data = Contact::getPublicAndUserContactID(intval($this->parameters['id']), DI::userSession()->getLocalUserId());
+               $data = Contact::getPublicAndUserContactID(intval($this->parameters['id']), $this->session->getLocalUserId());
                if (empty($data)) {
                        throw new HTTPException\NotFoundException($this->t('Contact not found.'));
                }
 
                $contact = Contact::getById($data['public']);
-               if (!DBA::isResult($contact)) {
+               if (!$this->db->isResult($contact)) {
                        throw new HTTPException\NotFoundException($this->t('Contact not found.'));
                }
 
                // Don't display contacts that are about to be deleted
-               if (DBA::isResult($contact) && (!empty($contact['deleted']) || !empty($contact['network']) && $contact['network'] == Protocol::PHANTOM)) {
+               if ($this->db->isResult($contact) && (!empty($contact['deleted']) || !empty($contact['network']) && $contact['network'] == Protocol::PHANTOM)) {
                        throw new HTTPException\NotFoundException($this->t('Contact not found.'));
                }
 
-               $localRelationship = $this->localRelationship->getForUserContact(DI::userSession()->getLocalUserId(), $contact['id']);
+               $localRelationship = $this->localRelationship->getForUserContact($this->session->getLocalUserId(), $contact['id']);
 
                if ($localRelationship->rel === Contact::SELF) {
                        $this->baseUrl->redirect('profile/' . $contact['nick'] . '/profile');
@@ -167,68 +179,68 @@ class Profile extends BaseModule
                        }
 
                        if ($cmd === 'updateprofile') {
-                               self::updateContactFromProbe($contact['id']);
+                               $this->updateContactFromProbe($contact['id']);
                        }
 
                        if ($cmd === 'block') {
                                if ($localRelationship->blocked) {
                                        // @TODO Backward compatibility, replace with $localRelationship->unblock()
-                                       Contact\User::setBlocked($contact['id'], DI::userSession()->getLocalUserId(), false);
+                                       Contact\User::setBlocked($contact['id'], $this->session->getLocalUserId(), false);
 
                                        $message = $this->t('Contact has been unblocked');
                                } else {
                                        // @TODO Backward compatibility, replace with $localRelationship->block()
-                                       Contact\User::setBlocked($contact['id'], DI::userSession()->getLocalUserId(), true);
+                                       Contact\User::setBlocked($contact['id'], $this->session->getLocalUserId(), true);
                                        $message = $this->t('Contact has been blocked');
                                }
 
                                // @TODO: add $this->localRelationship->save($localRelationship);
-                               DI::sysmsg()->addInfo($message);
+                               $this->systemMessages->addInfo($message);
                        }
 
                        if ($cmd === 'ignore') {
                                if ($localRelationship->ignored) {
                                        // @TODO Backward compatibility, replace with $localRelationship->unblock()
-                                       Contact\User::setIgnored($contact['id'], DI::userSession()->getLocalUserId(), false);
+                                       Contact\User::setIgnored($contact['id'], $this->session->getLocalUserId(), false);
 
                                        $message = $this->t('Contact has been unignored');
                                } else {
                                        // @TODO Backward compatibility, replace with $localRelationship->block()
-                                       Contact\User::setIgnored($contact['id'], DI::userSession()->getLocalUserId(), true);
+                                       Contact\User::setIgnored($contact['id'], $this->session->getLocalUserId(), true);
                                        $message = $this->t('Contact has been ignored');
                                }
-       
+
                                // @TODO: add $this->localRelationship->save($localRelationship);
-                               DI::sysmsg()->addInfo($message);
+                               $this->systemMessages->addInfo($message);
                        }
 
                        if ($cmd === 'collapse') {
                                if ($localRelationship->collapsed) {
                                        // @TODO Backward compatibility, replace with $localRelationship->unblock()
-                                       Contact\User::setCollapsed($contact['id'], DI::userSession()->getLocalUserId(), false);
+                                       Contact\User::setCollapsed($contact['id'], $this->session->getLocalUserId(), false);
 
-                                       $message = $this->t('Contact has been collapsed');
+                                       $message = $this->t('Contact has been uncollapsed');
                                } else {
                                        // @TODO Backward compatibility, replace with $localRelationship->block()
-                                       Contact\User::setCollapsed($contact['id'], DI::userSession()->getLocalUserId(), true);
+                                       Contact\User::setCollapsed($contact['id'], $this->session->getLocalUserId(), true);
                                        $message = $this->t('Contact has been collapsed');
                                }
-                                       
+
                                // @TODO: add $this->localRelationship->save($localRelationship);
-                               DI::sysmsg()->addInfo($message);
+                               $this->systemMessages->addInfo($message);
                        }
 
                        $this->baseUrl->redirect('contact/' . $contact['id']);
                }
 
                $vcard_widget  = Widget\VCard::getHTML($contact);
-               $groups_widget = '';
+               $circles_widget = '';
 
                if (!in_array($localRelationship->rel, [Contact::NOTHING, Contact::SELF])) {
-                       $groups_widget = Group::sidebarWidget('contact', 'group', 'full', 'everyone', $data['user']);
+                       $circles_widget = Circle::sidebarWidget('contact', 'circle', 'full', 'everyone', $data['user']);
                }
 
-               $this->page['aside'] .= $vcard_widget . $groups_widget;
+               $this->page['aside'] .= $vcard_widget . $circles_widget;
 
                $o = '';
                Nav::setSelected('contact');
@@ -236,12 +248,8 @@ class Profile extends BaseModule
                $_SESSION['return_path'] = $this->args->getQueryString();
 
                $this->page['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('contact_head.tpl'), [
-                       '$baseurl' => $this->baseUrl->get(true),
                ]);
 
-               $contact['blocked']  = Contact\User::isBlocked($contact['id'], DI::userSession()->getLocalUserId());
-               $contact['readonly'] = Contact\User::isIgnored($contact['id'], DI::userSession()->getLocalUserId());
-
                switch ($localRelationship->rel) {
                        case Contact::FRIEND:   $relation_text = $this->t('You are mutual friends with %s', $contact['name']); break;
                        case Contact::FOLLOWER: $relation_text = $this->t('You are sharing with %s', $contact['name']); break;
@@ -250,7 +258,7 @@ class Profile extends BaseModule
                                $relation_text = '';
                }
 
-               if (!in_array($contact['network'], array_merge(Protocol::FEDERATED, [Protocol::TWITTER]))) {
+               if (!Protocol::supportsFollow($contact['network'])) {
                        $relation_text = '';
                }
 
@@ -263,6 +271,17 @@ class Profile extends BaseModule
 
                $insecure = $this->t('Private communications are not available for this contact.');
 
+               // @TODO: Figure out why gsid can be empty
+               if (empty($contact['gsid'])) {
+                       $this->logger->notice('Empty gsid for contact', ['contact' => $contact]);
+               }
+
+               $serverIgnored =
+                       $contact['gsid'] &&
+                       $this->userGServer->isIgnoredByUser($this->session->getLocalUserId(), $contact['gsid']) ?
+                               $this->t('This contact is on a server you ignored.')
+                               : '';
+
                $last_update = (($contact['last-update'] <= DBA::NULL_DATETIME) ? $this->t('Never') : DateTimeFormat::local($contact['last-update'], 'D, j M Y, g:i A'));
 
                if ($contact['last-update'] > DBA::NULL_DATETIME) {
@@ -287,10 +306,10 @@ class Profile extends BaseModule
                                $localRelationship->fetchFurtherInformation,
                                $this->t('Fetch information like preview pictures, title and teaser from the feed item. You can activate this if the feed doesn\'t contain much text. Keywords are taken from the meta header in the feed item and are posted as hash tags.'),
                                [
-                                       '0' => $this->t('Disabled'),
-                                       '1' => $this->t('Fetch information'),
-                                       '3' => $this->t('Fetch keywords'),
-                                       '2' => $this->t('Fetch information and keywords')
+                                       LocalRelationship\Entity\LocalRelationship::FFI_NONE        => $this->t('Disabled'),
+                                       LocalRelationship\Entity\LocalRelationship::FFI_INFORMATION => $this->t('Fetch information'),
+                                       LocalRelationship\Entity\LocalRelationship::FFI_KEYWORD     => $this->t('Fetch keywords'),
+                                       LocalRelationship\Entity\LocalRelationship::FFI_BOTH        => $this->t('Fetch information and keywords')
                                ]
                        ];
                }
@@ -321,6 +340,8 @@ class Profile extends BaseModule
                        ];
                }
 
+               $channel_frequency     = Contact\User::getChannelFrequency($contact['id'], $this->session->getLocalUserId());
+
                $poll_interval = null;
                if ((($contact['network'] == Protocol::FEED) && !$this->config->get('system', 'adjust_poll_frequency')) || ($contact['network'] == Protocol::MAIL)) {
                        $poll_interval = ContactSelector::pollInterval($localRelationship->priority, !$poll_enabled);
@@ -361,16 +382,15 @@ class Profile extends BaseModule
                        '$last_update'               => $last_update,
                        '$udnow'                     => $this->t('Update now'),
                        '$contact_id'                => $contact['id'],
-                       '$block_text'                => ($contact['blocked'] ? $this->t('Unblock') : $this->t('Block')),
-                       '$ignore_text'               => ($contact['readonly'] ? $this->t('Unignore') : $this->t('Ignore')),
+                       '$pending'                   => $localRelationship->pending   ? $this->t('Awaiting connection acknowledge') : '',
+                       '$blocked'                   => $localRelationship->blocked   ? $this->t('Currently blocked') : '',
+                       '$ignored'                   => $localRelationship->ignored   ? $this->t('Currently ignored') : '',
+                       '$collapsed'                 => $localRelationship->collapsed ? $this->t('Currently collapsed') : '',
+                       '$archived'                  => ($contact['archive'] ? $this->t('Currently archived') : ''),
                        '$insecure'                  => (in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::MAIL, Protocol::DIASPORA]) ? '' : $insecure),
-                       '$info'                      => $localRelationship->info,
+                       '$serverIgnored'             => $serverIgnored,
+                       '$manageServers'             => $this->t('Manage remote servers'),
                        '$cinfo'                     => ['info', '', $localRelationship->info, ''],
-                       '$blocked'                   => ($contact['blocked'] ? $this->t('Currently blocked') : ''),
-                       '$ignored'                   => ($contact['readonly'] ? $this->t('Currently ignored') : ''),
-                       '$collapsed'                 => (Contact\User::isCollapsed($contact['id'], DI::userSession()->getLocalUserId()) ? $this->t('Currently collapsed') : ''),
-                       '$archived'                  => ($contact['archive'] ? $this->t('Currently archived') : ''),
-                       '$pending'                   => ($contact['pending'] ? $this->t('Awaiting connection acknowledge') : ''),
                        '$hidden'                    => ['hidden', $this->t('Hide this contact from others'), $localRelationship->hidden, $this->t('Replies/likes to your public posts <strong>may</strong> still be visible')],
                        '$notify_new_posts'          => ['notify_new_posts', $this->t('Notification for new posts'), ($localRelationship->notifyNewPosts), $this->t('Send a notification of every new post of this contact')],
                        '$fetch_further_information' => $fetch_further_information,
@@ -401,10 +421,17 @@ class Profile extends BaseModule
                        '$remote_self'               => [
                                'remote_self',
                                $this->t('Mirror postings from this contact'),
-                               $localRelationship->isRemoteSelf,
+                               $localRelationship->remoteSelf,
                                $this->t('Mark this contact as remote_self, this will cause friendica to repost new entries from this contact.'),
                                $remote_self_options
                        ],
+                       '$channel_settings_label' => $this->t('Channel Settings'),
+                       '$frequency_label'        => $this->t('Frequency of this contact in relevant channels'),
+                       '$frequency_description'  => $this->t("Depending on the type of the channel not all posts from this contact are displayed. By default, posts need to have a minimum amount of interactions (comments, likes) to show in your channels. On the other hand there can be contacts who flood the channel, so you might want to see only some of their posts. Or you don't want to see their content at all, but you don't want to block or hide the contact completely."),
+                       '$frequency_default'      => ['channel_frequency', $this->t('Default frequency'), Contact\User::FREQUENCY_DEFAULT, $this->t('Posts by this contact are displayed in the "for you" channel if you interact often with this contact or if a post reached some level of interaction.'), $channel_frequency == Contact\User::FREQUENCY_DEFAULT],
+                       '$frequency_always'       => ['channel_frequency', $this->t('Display all posts of this contact'), Contact\User::FREQUENCY_ALWAYS, $this->t('All posts from this contact will appear on the "for you" channel'), $channel_frequency == Contact\User::FREQUENCY_ALWAYS],
+                       '$frequency_reduced'      => ['channel_frequency', $this->t('Display only few posts'), Contact\User::FREQUENCY_REDUCED, $this->t('When a contact creates a lot of posts in a short period, this setting reduces the number of displayed posts in every channel.'), $channel_frequency == Contact\User::FREQUENCY_REDUCED],
+                       '$frequency_never'        => ['channel_frequency', $this->t('Never display posts'), Contact\User::FREQUENCY_NEVER, $this->t('Posts from this contact will never be displayed in any channel'), $channel_frequency == Contact\User::FREQUENCY_NEVER],
                ]);
 
                $arr = ['contact' => $contact, 'output' => $o];
@@ -420,11 +447,11 @@ class Profile extends BaseModule
         * This includes actions like e.g. 'block', 'hide', 'delete' and others
         *
         * @param array                    $contact           Public contact row
-        * @param Entity\LocalRelationship $localRelationship
+        * @param LocalRelationship\Entity\LocalRelationship $localRelationship
         * @return array with contact related actions
         * @throws HTTPException\InternalServerErrorException
         */
-       private function getContactActions(array $contact, Entity\LocalRelationship $localRelationship): array
+       private function getContactActions(array $contact, LocalRelationship\Entity\LocalRelationship $localRelationship): array
        {
                $poll_enabled    = in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::FEED, Protocol::MAIL]);
                $contact_actions = [];
@@ -470,7 +497,7 @@ class Profile extends BaseModule
                        ];
                }
 
-               if (in_array($contact['network'], Protocol::NATIVE_SUPPORT)) {
+               if (Protocol::supportsProbe($contact['network'])) {
                        $contact_actions['updateprofile'] = [
                                'label' => $this->t('Refetch contact data'),
                                'url'   => 'contact/' . $contact['id'] . '/updateprofile?t=' . $formSecurityToken,
@@ -525,10 +552,9 @@ class Profile extends BaseModule
         * @throws HTTPException\InternalServerErrorException
         * @throws \ImagickException
         */
-       private static function updateContactFromProbe(int $contact_id)
+       private function updateContactFromProbe(int $contact_id)
        {
-               $contact = DBA::selectFirst('contact', ['url'], ['id' => $contact_id, 'uid' => [0, DI::userSession()->getLocalUserId()], 'deleted' => false]);
-               if (!DBA::isResult($contact)) {
+               if (!$this->db->exists('contact', ['id' => $contact_id, 'uid' => [0, $this->session->getLocalUserId()], 'deleted' => false])) {
                        return;
                }