From 58d6e7e2bb25831249bda5a5e88433ea448257a6 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sun, 30 Oct 2022 15:51:41 -0400 Subject: [PATCH] Create Contact\Unfollow module class --- src/Content/Widget/VCard.php | 2 +- src/Model/Contact.php | 2 +- src/Model/Profile.php | 4 +- src/Module/Contact/Unfollow.php | 184 ++++++++++++++++++++++++++++++++ static/routes.config.php | 1 + 5 files changed, 189 insertions(+), 4 deletions(-) create mode 100644 src/Module/Contact/Unfollow.php diff --git a/src/Content/Widget/VCard.php b/src/Content/Widget/VCard.php index 9794270e2..1edbf63c8 100644 --- a/src/Content/Widget/VCard.php +++ b/src/Content/Widget/VCard.php @@ -83,7 +83,7 @@ class VCard if (empty($contact['self']) && Protocol::supportsFollow($contact['network'])) { if (in_array($rel, [Contact::SHARING, Contact::FRIEND])) { - $unfollow_link = 'unfollow?url=' . urlencode($contact['url']) . '&auto=1'; + $unfollow_link = 'contact/unfollow?url=' . urlencode($contact['url']) . '&auto=1'; } elseif (!$pending) { $follow_link = 'follow?url=' . urlencode($contact['url']) . '&auto=1'; } diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 91e89b2f2..0ae7003f0 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1176,7 +1176,7 @@ class Contact $unfollow_link = ''; if (!$contact['self'] && Protocol::supportsFollow($contact['network'])) { if ($contact['uid'] && in_array($contact['rel'], [self::SHARING, self::FRIEND])) { - $unfollow_link = 'unfollow?url=' . urlencode($contact['url']) . '&auto=1'; + $unfollow_link = 'contact/unfollow?url=' . urlencode($contact['url']) . '&auto=1'; } elseif(!$contact['pending']) { $follow_link = 'follow?url=' . urlencode($contact['url']) . '&auto=1'; } diff --git a/src/Model/Profile.php b/src/Model/Profile.php index 8538bfde2..b73b23538 100644 --- a/src/Model/Profile.php +++ b/src/Model/Profile.php @@ -339,9 +339,9 @@ class Profile } } else { if ($visitor_is_following) { - $unfollow_link = $visitor_base_path . '/unfollow?url=' . urlencode($profile_url) . '&auto=1'; + $unfollow_link = $visitor_base_path . '/contact/unfollow?url=' . urlencode($profile_url) . '&auto=1'; } else { - $follow_link = $visitor_base_path .'/follow?url=' . urlencode($profile_url) . '&auto=1'; + $follow_link = $visitor_base_path . '/follow?url=' . urlencode($profile_url) . '&auto=1'; } } diff --git a/src/Module/Contact/Unfollow.php b/src/Module/Contact/Unfollow.php new file mode 100644 index 000000000..913638a9e --- /dev/null +++ b/src/Module/Contact/Unfollow.php @@ -0,0 +1,184 @@ +. + * + */ + +namespace Friendica\Module\Contact; + +use Friendica\App; +use Friendica\Content\Widget; +use Friendica\Core\L10n; +use Friendica\Core\Protocol; +use Friendica\Core\Renderer; +use Friendica\Core\Session\Capability\IHandleUserSessions; +use Friendica\Database\Database; +use Friendica\Model\Contact; +use Friendica\Model\User; +use Friendica\Module\Response; +use Friendica\Navigation\SystemMessages; +use Friendica\Util\Profiler; +use Friendica\Util\Strings; +use Psr\Log\LoggerInterface; + +class Unfollow extends \Friendica\BaseModule +{ + /** @var IHandleUserSessions */ + private $userSession; + + /** @var SystemMessages */ + private $systemMessages; + + /** @var Database */ + private $database; + + /** @var App\Page */ + private $page; + + public function __construct(App\Page $page, Database $database, SystemMessages $systemMessages, IHandleUserSessions $userSession, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = []) + { + parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters); + + $this->userSession = $userSession; + $this->systemMessages = $systemMessages; + $this->database = $database; + $this->page = $page; + } + + protected function post(array $request = []) + { + if (!$this->userSession->getLocalUserId()) { + $this->systemMessages->addNotice($this->t('Permission denied.')); + $this->baseUrl->redirect('login'); + } + + $url = trim($request['url'] ?? ''); + + $this->process($url); + } + + protected function content(array $request = []): string + { + $base_return_path = 'contact'; + + if (!$this->userSession->getLocalUserId()) { + $this->systemMessages->addNotice($this->t('Permission denied.')); + $this->baseUrl->redirect('login'); + } + + $uid = $this->userSession->getLocalUserId(); + $url = trim($request['url']); + + $condition = [ + "`uid` = ? + AND (`rel` = ? OR `rel` = ?) + AND (`nurl` = ? OR `alias` = ? OR `alias` = ?)", + $this->userSession->getLocalUserId(), + Contact::SHARING, Contact::FRIEND, + Strings::normaliseLink($url), Strings::normaliseLink($url), $url, + ]; + + $contact = $this->database->selectFirst('contact', ['url', 'id', 'uid', 'network', 'addr', 'name'], $condition); + if (!$this->database->isResult($contact)) { + $this->systemMessages->addNotice($this->t("You aren't following this contact.")); + $this->baseUrl->redirect($base_return_path); + } + + if (!Protocol::supportsFollow($contact['network'])) { + $this->systemMessages->addNotice($this->t('Unfollowing is currently not supported by your network.')); + $this->baseUrl->redirect($base_return_path . '/' . $contact['id']); + } + + $tpl = Renderer::getMarkupTemplate('auto_request.tpl'); + + $self = $this->database->selectFirst('contact', ['url'], ['uid' => $uid, 'self' => true]); + + if (!$this->database->isResult($self)) { + $this->systemMessages->addNotice($this->t('Permission denied.')); + $this->baseUrl->redirect($base_return_path); + } + + if (!empty($request['auto'])) { + $this->process($contact['url']); + } + + $o = Renderer::replaceMacros($tpl, [ + '$header' => $this->t('Disconnect/Unfollow'), + '$page_desc' => '', + '$your_address' => $this->t('Your Identity Address:'), + '$invite_desc' => '', + '$submit' => $this->t('Submit Request'), + '$cancel' => $this->t('Cancel'), + '$url' => $contact['url'], + '$zrl' => Contact::magicLinkByContact($contact), + '$url_label' => $this->t('Profile URL'), + '$myaddr' => $self['url'], + '$action' => $this->baseUrl . '/contact/unfollow', + '$keywords' => '', + '$keywords_label' => '' + ]); + + $this->page['aside'] = Widget\VCard::getHTML(Contact::getByURL($contact['url'], false)); + + $o .= Renderer::replaceMacros(Renderer::getMarkupTemplate('section_title.tpl'), ['$title' => $this->t('Status Messages and Posts')]); + + // Show last public posts + $o .= Contact::getPostsFromUrl($contact['url']); + + return $o; + } + + private function process(string $url): void + { + $base_return_path = 'contact'; + + $uid = $this->userSession->getLocalUserId(); + + $owner = User::getOwnerDataById($uid); + if (!$owner) { + throw new \Friendica\Network\HTTPException\NotFoundException(); + } + + $condition = [ + "`uid` = ? + AND (`rel` = ? OR `rel` = ?) + AND (`nurl` = ? OR `alias` = ? OR `alias` = ?)", + $uid, Contact::SHARING, Contact::FRIEND, + Strings::normaliseLink($url), Strings::normaliseLink($url), $url, + ]; + $contact = $this->database->selectFirst('contact', [], $condition); + + if (!$this->database->isResult($contact)) { + $this->systemMessages->addNotice($this->t("You aren't following this contact.")); + $this->baseUrl->redirect($base_return_path); + } + + $return_path = $base_return_path . '/' . $contact['id']; + + try { + Contact::unfollow($contact); + $notice_message = $this->t('Contact was successfully unfollowed'); + } catch (\Exception $e) { + $this->logger->error($e->getMessage(), ['contact' => $contact]); + $notice_message = $this->t('Unable to unfollow this contact, please contact your administrator'); + } + + $this->systemMessages->addNotice($notice_message); + $this->baseUrl->redirect($return_path); + } +} diff --git a/static/routes.config.php b/static/routes.config.php index c5685acea..62742b659 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -387,6 +387,7 @@ return [ '/hidden' => [Module\Contact::class, [R::GET]], '/ignored' => [Module\Contact::class, [R::GET]], '/hovercard' => [Module\Contact\Hovercard::class, [R::GET]], + '/unfollow' => [Module\Contact\Unfollow::class, [R::GET, R::POST]], ], '/credits' => [Module\Credits::class, [R::GET]],