diff --git a/mod/common.php b/mod/common.php deleted file mode 100644 index d4ee97c4ff..0000000000 --- a/mod/common.php +++ /dev/null @@ -1,146 +0,0 @@ -. - * - */ - -use Friendica\App; -use Friendica\Content\Pager; -use Friendica\Core\Renderer; -use Friendica\Database\DBA; -use Friendica\DI; -use Friendica\Model; -use Friendica\Module; -use Friendica\Util\Strings; - -function common_content(App $a) -{ - $o = ''; - - $cmd = $a->argv[1]; - $uid = intval($a->argv[2]); - $cid = intval($a->argv[3]); - $zcid = 0; - - if (!local_user()) { - notice(DI::l10n()->t('Permission denied.')); - return; - } - - if ($cmd !== 'loc' && $cmd != 'rem') { - return; - } - - if (!$uid) { - return; - } - - if ($cmd === 'loc' && $cid) { - $contact = DBA::selectFirst('contact', ['name', 'url', 'photo', 'uid', 'id'], ['id' => $cid, 'uid' => $uid]); - - if (DBA::isResult($contact)) { - DI::page()['aside'] = ""; - Model\Profile::load($a, "", Model\Contact::getByURL($contact["url"], false)); - } - } else { - $contact = DBA::selectFirst('contact', ['name', 'url', 'photo', 'uid', 'id'], ['self' => true, 'uid' => $uid]); - - if (DBA::isResult($contact)) { - $vcard_widget = Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/vcard.tpl'), [ - '$name' => $contact['name'], - '$photo' => $contact['photo'], - 'url' => 'contact/' . $cid - ]); - - if (empty(DI::page()['aside'])) { - DI::page()['aside'] = ''; - } - DI::page()['aside'] .= $vcard_widget; - } - } - - if (!DBA::isResult($contact)) { - return; - } - - if (!$cid && Model\Profile::getMyURL()) { - $contact = DBA::selectFirst('contact', ['id'], ['nurl' => Strings::normaliseLink(Model\Profile::getMyURL()), 'uid' => $uid]); - if (DBA::isResult($contact)) { - $cid = $contact['id']; - } else { - $gcontact = DBA::selectFirst('gcontact', ['id'], ['nurl' => Strings::normaliseLink(Model\Profile::getMyURL())]); - if (DBA::isResult($gcontact)) { - $zcid = $gcontact['id']; - } - } - } - - if ($cid == 0 && $zcid == 0) { - return; - } - - if ($cid) { - $total = Model\GContact::countCommonFriends($uid, $cid); - } else { - $total = Model\GContact::countCommonFriendsZcid($uid, $zcid); - } - - if ($total < 1) { - notice(DI::l10n()->t('No contacts in common.')); - return $o; - } - - $pager = new Pager(DI::l10n(), DI::args()->getQueryString()); - - if ($cid) { - $common_friends = Model\GContact::commonFriends($uid, $cid, $pager->getStart(), $pager->getItemsPerPage()); - } else { - $common_friends = Model\GContact::commonFriendsZcid($uid, $zcid, $pager->getStart(), $pager->getItemsPerPage()); - } - - if (!DBA::isResult($common_friends)) { - return $o; - } - - $title = ''; - $tab_str = ''; - if ($cmd === 'loc' && $cid && local_user() == $uid) { - $tab_str = Module\Contact::getTabsHTML($a, $contact, 5); - } else { - $title = DI::l10n()->t('Common Friends'); - } - - $entries = []; - foreach ($common_friends as $common_friend) { - $contact = Model\Contact::getByURLForUser($common_friend['url'], local_user()); - if (!empty($contact)) { - $entries[] = Module\Contact::getContactTemplateVars($contact); - } - } - - $tpl = Renderer::getMarkupTemplate('viewcontact_template.tpl'); - - $o .= Renderer::replaceMacros($tpl, [ - '$title' => $title, - '$tab_str' => $tab_str, - '$contacts' => $entries, - '$paginate' => $pager->renderFull($total), - ]); - - return $o; -} diff --git a/src/BaseModule.php b/src/BaseModule.php index 0e0fedb80c..ce7774bfd0 100644 --- a/src/BaseModule.php +++ b/src/BaseModule.php @@ -171,4 +171,40 @@ abstract class BaseModule throw new \Friendica\Network\HTTPException\ForbiddenException(); } } + + protected static function getContactFilterTabs(string $baseUrl, string $current, bool $displayCommonTab) + { + $tabs = [ + [ + 'label' => DI::l10n()->t('All contacts'), + 'url' => $baseUrl . '/contacts', + 'sel' => !$current || $current == 'all' ? 'active' : '', + ], + [ + 'label' => DI::l10n()->t('Followers'), + 'url' => $baseUrl . '/contacts/followers', + 'sel' => $current == 'followers' ? 'active' : '', + ], + [ + 'label' => DI::l10n()->t('Following'), + 'url' => $baseUrl . '/contacts/following', + 'sel' => $current == 'following' ? 'active' : '', + ], + [ + 'label' => DI::l10n()->t('Mutual friends'), + 'url' => $baseUrl . '/contacts/mutuals', + 'sel' => $current == 'mutuals' ? 'active' : '', + ], + ]; + + if ($displayCommonTab) { + $tabs[] = [ + 'label' => DI::l10n()->t('Common'), + 'url' => $baseUrl . '/contacts/common', + 'sel' => $current == 'common' ? 'active' : '', + ]; + } + + return $tabs; + } } diff --git a/src/Core/Session/Native.php b/src/Core/Session/Native.php index 49550a27c0..83ed0f6e6e 100644 --- a/src/Core/Session/Native.php +++ b/src/Core/Session/Native.php @@ -53,4 +53,9 @@ class Native extends AbstractSession implements ISession session_start(); return $this; } + + public function clear() + { + session_destroy(); + } } diff --git a/src/Model/Contact/Relation.php b/src/Model/Contact/Relation.php index cc0570ec63..d1e51811ff 100644 --- a/src/Model/Contact/Relation.php +++ b/src/Model/Contact/Relation.php @@ -335,7 +335,6 @@ class Relation * Returns a paginated list of contacts that are followed the provided public contact. * * @param int $cid Public contact id - * @param array $field Field list * @param array $condition Additional condition on the contact table * @param int $count * @param int $offset @@ -343,14 +342,14 @@ class Relation * @return array * @throws Exception */ - public static function listFollows(int $cid, array $fields = [], array $condition = [], int $count = 30, int $offset = 0, bool $shuffle = false) + public static function listFollows(int $cid, array $condition = [], int $count = 30, int $offset = 0, bool $shuffle = false) { $condition = DBA::mergeConditions($condition, ['`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`)', $cid] ); - return DI::dba()->selectToArray('contact', $fields, $condition, + return DI::dba()->selectToArray('contact', [], $condition, ['limit' => [$offset, $count], 'order' => [$shuffle ? 'RAND()' : 'name']] ); } @@ -377,7 +376,6 @@ class Relation * Returns a paginated list of contacts that follow the provided public contact. * * @param int $cid Public contact id - * @param array $field Field list * @param array $condition Additional condition on the contact table * @param int $count * @param int $offset @@ -385,17 +383,104 @@ class Relation * @return array * @throws Exception */ - public static function listFollowers(int $cid, array $fields = [], array $condition = [], int $count = 30, int $offset = 0, bool $shuffle = false) + public static function listFollowers(int $cid, array $condition = [], int $count = 30, int $offset = 0, bool $shuffle = false) { $condition = DBA::mergeConditions($condition, ['`id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND `follows`)', $cid] ); - return DI::dba()->selectToArray('contact', $fields, $condition, + return DI::dba()->selectToArray('contact', [], $condition, ['limit' => [$offset, $count], 'order' => [$shuffle ? 'RAND()' : 'name']] ); } + /** + * Counts the number of contacts that are known mutuals with the provided public contact. + * + * @param int $cid Public contact id + * @param array $condition Additional condition array on the contact table + * @return int + * @throws Exception + */ + public static function countMutuals(int $cid, array $condition = []) + { + $condition = DBA::mergeConditions($condition, + ['`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`) + AND `id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND `follows`)', + $cid, $cid] + ); + + return DI::dba()->count('contact', $condition); + } + + /** + * Returns a paginated list of contacts that are known mutuals with the provided public contact. + * + * @param int $cid Public contact id + * @param array $condition Additional condition on the contact table + * @param int $count + * @param int $offset + * @param bool $shuffle + * @return array + * @throws Exception + */ + public static function listMutuals(int $cid, array $condition = [], int $count = 30, int $offset = 0, bool $shuffle = false) + { + $condition = DBA::mergeConditions($condition, + ['`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`) + AND `id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND `follows`)', + $cid, $cid] + ); + + return DI::dba()->selectToArray('contact', [], $condition, + ['limit' => [$offset, $count], 'order' => [$shuffle ? 'name' : 'RAND()']] + ); + } + + + /** + * Counts the number of contacts with any relationship with the provided public contact. + * + * @param int $cid Public contact id + * @param array $condition Additional condition array on the contact table + * @return int + * @throws Exception + */ + public static function countAll(int $cid, array $condition = []) + { + $condition = DBA::mergeConditions($condition, + ['`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`) + OR `id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND `follows`)', + $cid, $cid] + ); + + return DI::dba()->count('contact', $condition); + } + + /** + * Returns a paginated list of contacts with any relationship with the provided public contact. + * + * @param int $cid Public contact id + * @param array $condition Additional condition on the contact table + * @param int $count + * @param int $offset + * @param bool $shuffle + * @return array + * @throws Exception + */ + public static function listAll(int $cid, array $condition = [], int $count = 30, int $offset = 0, bool $shuffle = false) + { + $condition = DBA::mergeConditions($condition, + ['`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`) + OR `id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND `follows`)', + $cid, $cid] + ); + + return DI::dba()->selectToArray('contact', [], $condition, + ['limit' => [$offset, $count], 'order' => [$shuffle ? 'name' : 'RAND()']] + ); + } + /** * Counts the number of contacts that both provided public contacts have interacted with at least once. * Interactions include follows and likes and comments on public posts. @@ -423,7 +508,6 @@ class Relation * * @param int $sourceId Public contact id * @param int $targetId Public contact id - * @param array $field Field list * @param array $condition Additional condition on the contact table * @param int $count * @param int $offset @@ -434,8 +518,8 @@ class Relation public static function listCommon(int $sourceId, int $targetId, array $condition = [], int $count = 30, int $offset = 0, bool $shuffle = false) { $condition = DBA::mergeConditions($condition, - ["`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`) - AND `id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`)", + ["`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ?) + AND `id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ?)", $sourceId, $targetId] ); @@ -444,7 +528,6 @@ class Relation ); } - /** * Counts the number of contacts that are followed by both provided public contacts. * diff --git a/src/Model/GContact.php b/src/Model/GContact.php deleted file mode 100644 index 3fe123e15f..0000000000 --- a/src/Model/GContact.php +++ /dev/null @@ -1,139 +0,0 @@ -. - * - */ - -namespace Friendica\Model; - -use Exception; -use Friendica\DI; - -/** - * This class handles GlobalContact related functions - */ -class GContact -{ - /** - * @param integer $uid id - * @param integer $cid id - * @return integer - * @throws Exception - */ - public static function countCommonFriends($uid, $cid) - { - $sourceId = Contact::getPublicIdByUserId($uid); - - $targetIds = Contact::getPublicAndUserContacID($cid, $uid); - - $condition = [ - 'NOT `self` AND NOT `blocked` AND NOT `hidden` AND `id` != ?', - $sourceId, - ]; - - return Contact\Relation::countCommonFollows($sourceId, $targetIds['public'] ?? 0, $condition); - } - - /** - * @param integer $uid id - * @param integer $zcid zcid - * @return integer - * @throws Exception - */ - public static function countCommonFriendsZcid($uid, $zcid) - { - $sourceId = Contact::getPublicIdByUserId($uid); - - $targetPublicContact = DI::dba()->fetchFirst(" -SELECT `id` -FROM `contact` c -JOIN `gcontact` z ON z.`nurl` = c.`nurl` -AND z.`id` = ? -AND c.`uid` = 0 -LIMIT 1", - $zcid - ); - - $condition = [ - 'NOT `self` AND NOT `blocked` AND NOT `hidden` AND `id` != ?', - $sourceId, - ]; - - return Contact\Relation::countCommonFollowers($sourceId, $targetPublicContact['id'] ?? 0, $condition); - } - - /** - * Returns the cross-section between the local user contacts and one of their contact's own relationships - * as known by the local node. - * - * @param integer $uid local user id - * @param integer $cid user contact id to compare friends with - * @param integer $start optional, default 0 - * @param integer $limit optional, default 9999 - * @param boolean $shuffle optional, default false - * @return array - * @throws Exception - */ - public static function commonFriends($uid, $cid, $start = 0, $limit = 9999, $shuffle = false) - { - $sourceId = Contact::getPublicIdByUserId($uid); - - $targetIds = Contact::getPublicAndUserContacID($cid, $uid); - - $condition = [ - 'NOT `self` AND NOT `blocked` AND NOT `hidden` AND `id` != ?', - $sourceId, - ]; - - return Contact\Relation::listCommonFollows($sourceId, $targetIds['public'] ?? 0, $condition, $limit, $start, $shuffle); - } - - /** - * Returns the cross-section between a local user and a remote visitor contact's own relationships - * as known by the local node. - * - * @param integer $uid local user id - * @param integer $zcid remote visitor contact zcid - * @param integer $start optional, default 0 - * @param integer $limit optional, default 9999 - * @param boolean $shuffle optional, default false - * @return array - * @throws Exception - */ - public static function commonFriendsZcid($uid, $zcid, $start = 0, $limit = 9999, $shuffle = false) - { - $sourceId = Contact::getPublicIdByUserId($uid); - - $targetPublicContact = DI::dba()->fetchFirst(" -SELECT c.`id` -FROM `contact` c -JOIN `gcontact` z ON z.`nurl` = c.`nurl` -AND z.`id` = ? -AND c.`uid` = 0 -LIMIT 1", - $zcid - ); - - $condition = [ - 'NOT `self` AND NOT `blocked` AND NOT `hidden` AND `id` != ?', - $sourceId, - ]; - - return Contact\Relation::listCommonFollows($sourceId, $targetPublicContact['id'] ?? 0, $condition, $limit, $start, $shuffle); - } -} diff --git a/src/Module/AllFriends.php b/src/Module/AllFriends.php deleted file mode 100644 index f41b8b0d71..0000000000 --- a/src/Module/AllFriends.php +++ /dev/null @@ -1,89 +0,0 @@ -. - * - */ - -namespace Friendica\Module; - -use Friendica\BaseModule; -use Friendica\Content\Pager; -use Friendica\Core\Renderer; -use Friendica\DI; -use Friendica\Model; -use Friendica\Network\HTTPException; - -/** - * This module shows all public friends of the selected contact - */ -class AllFriends extends BaseModule -{ - public static function content(array $parameters = []) - { - $app = DI::app(); - - if (!local_user()) { - throw new HTTPException\ForbiddenException(); - } - - $cid = 0; - - // @TODO: Replace with parameter from router - if ($app->argc > 1) { - $cid = intval($app->argv[1]); - } - - if (!$cid) { - throw new HTTPException\BadRequestException(DI::l10n()->t('Invalid contact.')); - } - - $uid = $app->user['uid']; - - $contact = Model\Contact::getById($cid, []); - - if (empty($contact)) { - throw new HTTPException\BadRequestException(DI::l10n()->t('Invalid contact.')); - } - - DI::page()['aside'] = ""; - Model\Profile::load($app, "", $contact); - - $total = Model\Contact\Relation::countFollows($cid); - - $pager = new Pager(DI::l10n(), DI::args()->getQueryString()); - - $friends = Model\Contact\Relation::listFollows($cid, [], [], $pager->getItemsPerPage(), $pager->getStart()); - if (empty($friends)) { - return DI::l10n()->t('No friends to display.'); - } - - $tab_str = Contact::getTabsHTML($app, $contact, 4); - - $entries = []; - foreach ($friends as $friend) { - $entries[] = Contact::getContactTemplateVars($friend); - } - - $tpl = Renderer::getMarkupTemplate('viewcontact_template.tpl'); - return Renderer::replaceMacros($tpl, [ - '$tab_str' => $tab_str, - '$contacts' => $entries, - '$paginate' => $pager->renderFull($total), - ]); - } -} diff --git a/src/Module/Contact.php b/src/Module/Contact.php index 3cb57f8f20..6425df8df1 100644 --- a/src/Module/Contact.php +++ b/src/Module/Contact.php @@ -47,6 +47,12 @@ use Friendica\Util\Strings; */ class Contact extends BaseModule { + const TAB_CONVERSATIONS = 1; + const TAB_POSTS = 2; + const TAB_PROFILE = 3; + const TAB_CONTACTS = 4; + const TAB_ADVANCED = 5; + private static function batchActions() { if (empty($_POST['contact_batch']) || !is_array($_POST['contact_batch'])) { @@ -531,7 +537,7 @@ class Contact extends BaseModule $nettype = DI::l10n()->t('Network type: %s', ContactSelector::networkToName($contact['network'], $contact['url'], $contact['protocol'])); // tabs - $tab_str = self::getTabsHTML($a, $contact, 3); + $tab_str = self::getTabsHTML($contact, self::TAB_PROFILE); $lost_contact = (($contact['archive'] && $contact['term-date'] > DBA::NULL_DATETIME && $contact['term-date'] < DateTimeFormat::utcNow()) ? DI::l10n()->t('Communications lost with this contact!') : ''); @@ -576,7 +582,7 @@ class Contact extends BaseModule '$lbl_info2' => DI::l10n()->t('Their personal note'), '$reason' => trim(Strings::escapeTags($contact['reason'])), '$infedit' => DI::l10n()->t('Edit contact notes'), - '$common_link' => 'common/loc/' . local_user() . '/' . $contact['id'], + '$common_link' => 'contact/' . $contact['id'] . '/contacts/common', '$relation_text' => $relation_text, '$visit' => DI::l10n()->t('Visit %s\'s profile [%s]', $contact['name'], $contact['url']), '$blockunblock' => DI::l10n()->t('Block/Unblock contact'), @@ -855,14 +861,14 @@ class Contact extends BaseModule * * Available Pages are 'Status', 'Profile', 'Contacts' and 'Common Friends' * - * @param App $a * @param array $contact The contact array * @param int $active_tab 1 if tab should be marked as active * * @return string HTML string of the contact page tabs buttons. * @throws \Friendica\Network\HTTPException\InternalServerErrorException + * @throws \ImagickException */ - public static function getTabsHTML($a, $contact, $active_tab) + public static function getTabsHTML(array $contact, int $active_tab) { $cid = $pcid = $contact['id']; $data = Model\Contact::getPublicAndUserContacID($contact['id'], local_user()); @@ -876,57 +882,41 @@ class Contact extends BaseModule $tabs = [ [ 'label' => DI::l10n()->t('Status'), - 'url' => "contact/" . $pcid . "/conversations", - 'sel' => (($active_tab == 1) ? 'active' : ''), + 'url' => 'contact/' . $pcid . '/conversations', + 'sel' => (($active_tab == self::TAB_CONVERSATIONS) ? 'active' : ''), 'title' => DI::l10n()->t('Conversations started by this contact'), 'id' => 'status-tab', 'accesskey' => 'm', ], [ 'label' => DI::l10n()->t('Posts and Comments'), - 'url' => "contact/" . $pcid . "/posts", - 'sel' => (($active_tab == 2) ? 'active' : ''), + 'url' => 'contact/' . $pcid . '/posts', + 'sel' => (($active_tab == self::TAB_POSTS) ? 'active' : ''), 'title' => DI::l10n()->t('Status Messages and Posts'), 'id' => 'posts-tab', 'accesskey' => 'p', ], [ 'label' => DI::l10n()->t('Profile'), - 'url' => "contact/" . $cid, - 'sel' => (($active_tab == 3) ? 'active' : ''), + 'url' => 'contact/' . $cid, + 'sel' => (($active_tab == self::TAB_PROFILE) ? 'active' : ''), 'title' => DI::l10n()->t('Profile Details'), 'id' => 'profile-tab', 'accesskey' => 'o', - ] + ], + ['label' => DI::l10n()->t('Contacts'), + 'url' => 'contact/' . $pcid . '/contacts', + 'sel' => (($active_tab == self::TAB_CONTACTS) ? 'active' : ''), + 'title' => DI::l10n()->t('View all known contacts'), + 'id' => 'contacts-tab', + 'accesskey' => 't' + ], ]; - // Show this tab only if there is visible friend list - $x = Model\Contact\Relation::countFollows($pcid); - if ($x) { - $tabs[] = ['label' => DI::l10n()->t('Contacts'), - 'url' => "allfriends/" . $pcid, - 'sel' => (($active_tab == 4) ? 'active' : ''), - 'title' => DI::l10n()->t('View all contacts'), - 'id' => 'allfriends-tab', - 'accesskey' => 't']; - } - - // Show this tab only if there is visible common friend list - $common = Model\GContact::countCommonFriends(local_user(), $cid); - if ($common) { - $tabs[] = ['label' => DI::l10n()->t('Common Friends'), - 'url' => "common/loc/" . local_user() . "/" . $cid, - 'sel' => (($active_tab == 5) ? 'active' : ''), - 'title' => DI::l10n()->t('View all common friends'), - 'id' => 'common-loc-tab', - 'accesskey' => 'd' - ]; - } - if ($cid != $pcid) { $tabs[] = ['label' => DI::l10n()->t('Advanced'), 'url' => 'contact/' . $cid . '/advanced/', - 'sel' => (($active_tab == 6) ? 'active' : ''), + 'sel' => (($active_tab == self::TAB_ADVANCED) ? 'active' : ''), 'title' => DI::l10n()->t('Advanced Contact Settings'), 'id' => 'advanced-tab', 'accesskey' => 'r' @@ -964,7 +954,7 @@ class Contact extends BaseModule $contact = DBA::selectFirst('contact', ['uid', 'url', 'id'], ['id' => $contact_id, 'deleted' => false]); if (!$update) { - $o .= self::getTabsHTML($a, $contact, 1); + $o .= self::getTabsHTML($contact, self::TAB_CONVERSATIONS); } if (DBA::isResult($contact)) { @@ -988,7 +978,7 @@ class Contact extends BaseModule { $contact = DBA::selectFirst('contact', ['uid', 'url', 'id'], ['id' => $contact_id, 'deleted' => false]); - $o = self::getTabsHTML($a, $contact, 2); + $o = self::getTabsHTML($contact, self::TAB_POSTS); if (DBA::isResult($contact)) { DI::page()['aside'] = ''; diff --git a/src/Module/Contact/Advanced.php b/src/Module/Contact/Advanced.php index be1e874a57..a7ee29036c 100644 --- a/src/Module/Contact/Advanced.php +++ b/src/Module/Contact/Advanced.php @@ -125,7 +125,7 @@ class Advanced extends BaseModule $remote_self_options = ['0' => DI::l10n()->t('No mirroring'), '2' => DI::l10n()->t('Mirror as my own posting')]; } - $tab_str = Contact::getTabsHTML(DI::app(), $contact, 6); + $tab_str = Contact::getTabsHTML($contact, Contact::TAB_ADVANCED); $tpl = Renderer::getMarkupTemplate('contact/advanced.tpl'); return Renderer::replaceMacros($tpl, [ diff --git a/src/Module/Contact/Contacts.php b/src/Module/Contact/Contacts.php new file mode 100644 index 0000000000..31e81cb83d --- /dev/null +++ b/src/Module/Contact/Contacts.php @@ -0,0 +1,123 @@ +t('Invalid contact.')); + } + + $contact = Model\Contact::getById($cid, []); + if (empty($contact)) { + throw new HTTPException\NotFoundException(DI::l10n()->t('Contact not found.')); + } + + $localContactId = Model\Contact::getPublicIdByUserId(local_user()); + + Model\Profile::load($app, '', $contact); + + $condition = [ + 'blocked' => false, + 'self' => false, + 'hidden' => false, + ]; + + $noresult_label = DI::l10n()->t('No known contacts.'); + + switch ($type) { + case 'followers': + $total = Model\Contact\Relation::countFollowers($cid, $condition); + break; + case 'following': + $total = Model\Contact\Relation::countFollows($cid, $condition); + break; + case 'mutuals': + $total = Model\Contact\Relation::countMutuals($cid, $condition); + break; + case 'common': + $condition = [ + 'NOT `self` AND NOT `blocked` AND NOT `hidden` AND `id` != ?', + $localContactId, + ]; + $total = Model\Contact\Relation::countCommon($localContactId, $cid, $condition); + $noresult_label = DI::l10n()->t('No common contacts.'); + break; + default: + $total = Model\Contact\Relation::countAll($cid, $condition); + } + + $pager = new Pager(DI::l10n(), DI::args()->getQueryString()); + $desc = ''; + + switch ($type) { + case 'followers': + $friends = Model\Contact\Relation::listFollowers($cid, $condition, $pager->getItemsPerPage(), $pager->getStart()); + $title = DI::l10n()->tt('Follower (%s)', 'Followers (%s)', $total); + break; + case 'following': + $friends = Model\Contact\Relation::listFollows($cid, $condition, $pager->getItemsPerPage(), $pager->getStart()); + $title = DI::l10n()->tt('Following (%s)', 'Following (%s)', $total); + break; + case 'mutuals': + $friends = Model\Contact\Relation::listMutuals($cid, $condition, $pager->getItemsPerPage(), $pager->getStart()); + $title = DI::l10n()->tt('Mutual friend (%s)', 'Mutual friends (%s)', $total); + $desc = DI::l10n()->t( + 'These contacts both follow and are followed by %s.', + htmlentities($contact['name'], ENT_COMPAT, 'UTF-8') + ); + break; + case 'common': + $friends = Model\Contact\Relation::listCommon($localContactId, $cid, $condition, $pager->getItemsPerPage(), $pager->getStart()); + $title = DI::l10n()->tt('Common contact (%s)', 'Common contacts (%s)', $total); + $desc = DI::l10n()->t( + 'Both %s and yourself have publicly interacted with these contacts (follow, comment or likes on public posts).', + htmlentities($contact['name'], ENT_COMPAT, 'UTF-8') + ); + break; + default: + $friends = Model\Contact\Relation::listAll($cid, $condition, $pager->getItemsPerPage(), $pager->getStart()); + $title = DI::l10n()->tt('Contact (%s)', 'Contacts (%s)', $total); + } + + $o = Module\Contact::getTabsHTML($contact, Module\Contact::TAB_CONTACTS); + + $tabs = self::getContactFilterTabs('contact/' . $cid, $type, true); + + $contacts = array_map([Module\Contact::class, 'getContactTemplateVars'], $friends); + + $tpl = Renderer::getMarkupTemplate('profile/contacts.tpl'); + $o .= Renderer::replaceMacros($tpl, [ + '$title' => $title, + '$desc' => $desc, + '$tabs' => $tabs, + + '$noresult_label' => $noresult_label, + + '$contacts' => $contacts, + '$paginate' => $pager->renderFull($total), + ]); + + return $o; + } +} diff --git a/src/Module/Profile/Common.php b/src/Module/Profile/Common.php index 0b08d327c9..a9d00fce5f 100644 --- a/src/Module/Profile/Common.php +++ b/src/Module/Profile/Common.php @@ -53,8 +53,6 @@ class Common extends BaseProfile throw new HTTPException\NotFoundException(DI::l10n()->t('User not found.')); } - $o = self::getTabsHTML($a, 'contacts', false, $nickname); - if (!empty($a->profile['hide-friends'])) { throw new HTTPException\ForbiddenException(DI::l10n()->t('Permission denied.')); } @@ -65,6 +63,10 @@ class Common extends BaseProfile $a->redirect('profile/' . $nickname . '/contacts'); }; + $o = self::getTabsHTML($a, 'contacts', false, $nickname); + + $tabs = self::getContactFilterTabs('profile/' . $nickname, 'common', $displayCommonTab); + $sourceId = Contact::getIdForURL(Profile::getMyURL()); $targetId = Contact::getPublicIdByUserId($a->profile['uid']); @@ -92,15 +94,8 @@ class Common extends BaseProfile $o .= Renderer::replaceMacros($tpl, [ '$title' => $title, '$desc' => $desc, - '$nickname' => $nickname, - '$type' => 'common', - '$displayCommonTab' => $displayCommonTab, + '$tabs' => $tabs, - '$all_label' => DI::l10n()->t('All contacts'), - '$followers_label' => DI::l10n()->t('Followers'), - '$following_label' => DI::l10n()->t('Following'), - '$mutuals_label' => DI::l10n()->t('Mutual friends'), - '$common_label' => DI::l10n()->t('Common'), '$noresult_label' => DI::l10n()->t('No common contacts.'), '$contacts' => $contacts, diff --git a/src/Module/Profile/Contacts.php b/src/Module/Profile/Contacts.php index 938dbd3d05..6981b43a42 100644 --- a/src/Module/Profile/Contacts.php +++ b/src/Module/Profile/Contacts.php @@ -61,6 +61,8 @@ class Contacts extends Module\BaseProfile $o = self::getTabsHTML($a, 'contacts', $is_owner, $nickname); + $tabs = self::getContactFilterTabs('profile/' . $nickname, $type, Session::isAuthenticated() && $a->profile['uid'] != local_user()); + $condition = [ 'uid' => $a->profile['uid'], 'blocked' => false, @@ -113,15 +115,8 @@ class Contacts extends Module\BaseProfile $o .= Renderer::replaceMacros($tpl, [ '$title' => $title, '$desc' => $desc, - '$nickname' => $nickname, - '$type' => $type, - '$displayCommonTab' => Session::isAuthenticated() && $a->profile['uid'] != local_user(), + '$tabs' => $tabs, - '$all_label' => DI::l10n()->t('All contacts'), - '$followers_label' => DI::l10n()->t('Followers'), - '$following_label' => DI::l10n()->t('Following'), - '$mutuals_label' => DI::l10n()->t('Mutual friends'), - '$common_label' => DI::l10n()->t('Common'), '$noresult_label' => DI::l10n()->t('No contacts.'), '$contacts' => $contacts, diff --git a/static/routes.config.php b/static/routes.config.php index 15eec298e9..3991ec4e36 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -103,7 +103,6 @@ return [ ], '/amcd' => [Module\AccountManagementControlDocument::class, [R::GET]], '/acctlink' => [Module\Acctlink::class, [R::GET]], - '/allfriends/{id:\d+}' => [Module\AllFriends::class, [R::GET]], '/apps' => [Module\Apps::class, [R::GET]], '/attach/{item:\d+}' => [Module\Attach::class, [R::GET]], '/babel' => [Module\Debug\Babel::class, [R::GET, R::POST]], @@ -115,25 +114,26 @@ return [ '/compose[/{type}]' => [Module\Item\Compose::class, [R::GET, R::POST]], '/contact' => [ - '[/]' => [Module\Contact::class, [R::GET]], - '/{id:\d+}[/]' => [Module\Contact::class, [R::GET, R::POST]], - '/{id:\d+}/archive' => [Module\Contact::class, [R::GET]], - '/{id:\d+}/advanced' => [Module\Contact\Advanced::class, [R::GET, R::POST]], - '/{id:\d+}/block' => [Module\Contact::class, [R::GET]], - '/{id:\d+}/conversations' => [Module\Contact::class, [R::GET]], - '/{id:\d+}/drop' => [Module\Contact::class, [R::GET]], - '/{id:\d+}/ignore' => [Module\Contact::class, [R::GET]], - '/{id:\d+}/poke' => [Module\Contact\Poke::class, [R::GET, R::POST]], - '/{id:\d+}/posts' => [Module\Contact::class, [R::GET]], - '/{id:\d+}/update' => [Module\Contact::class, [R::GET]], - '/{id:\d+}/updateprofile' => [Module\Contact::class, [R::GET]], - '/archived' => [Module\Contact::class, [R::GET]], - '/batch' => [Module\Contact::class, [R::GET, R::POST]], - '/pending' => [Module\Contact::class, [R::GET]], - '/blocked' => [Module\Contact::class, [R::GET]], - '/hidden' => [Module\Contact::class, [R::GET]], - '/ignored' => [Module\Contact::class, [R::GET]], - '/hovercard' => [Module\Contact\Hovercard::class, [R::GET]], + '[/]' => [Module\Contact::class, [R::GET]], + '/{id:\d+}[/]' => [Module\Contact::class, [R::GET, R::POST]], + '/{id:\d+}/archive' => [Module\Contact::class, [R::GET]], + '/{id:\d+}/advanced' => [Module\Contact\Advanced::class, [R::GET, R::POST]], + '/{id:\d+}/block' => [Module\Contact::class, [R::GET]], + '/{id:\d+}/conversations' => [Module\Contact::class, [R::GET]], + '/{id:\d+}/contacts[/{type}]' => [Module\Contact\Contacts::class, [R::GET]], + '/{id:\d+}/drop' => [Module\Contact::class, [R::GET]], + '/{id:\d+}/ignore' => [Module\Contact::class, [R::GET]], + '/{id:\d+}/poke' => [Module\Contact\Poke::class, [R::GET, R::POST]], + '/{id:\d+}/posts' => [Module\Contact::class, [R::GET]], + '/{id:\d+}/update' => [Module\Contact::class, [R::GET]], + '/{id:\d+}/updateprofile' => [Module\Contact::class, [R::GET]], + '/archived' => [Module\Contact::class, [R::GET]], + '/batch' => [Module\Contact::class, [R::GET, R::POST]], + '/pending' => [Module\Contact::class, [R::GET]], + '/blocked' => [Module\Contact::class, [R::GET]], + '/hidden' => [Module\Contact::class, [R::GET]], + '/ignored' => [Module\Contact::class, [R::GET]], + '/hovercard' => [Module\Contact\Hovercard::class, [R::GET]], ], '/credits' => [Module\Credits::class, [R::GET]], diff --git a/view/templates/page_tabs.tpl b/view/templates/page_tabs.tpl new file mode 100644 index 0000000000..d5bf9c5761 --- /dev/null +++ b/view/templates/page_tabs.tpl @@ -0,0 +1 @@ +{{include file="common_tabs.tpl" tabs=$tabs}} \ No newline at end of file diff --git a/view/templates/profile/contacts.tpl b/view/templates/profile/contacts.tpl index 4a1379f17b..7e2ae9e83d 100644 --- a/view/templates/profile/contacts.tpl +++ b/view/templates/profile/contacts.tpl @@ -5,15 +5,8 @@

{{$desc nofilter}}

{{/if}} - + {{include file="page_tabs.tpl" tabs=$tabs}} + {{if $contacts}}
{{foreach $contacts as $contact}} diff --git a/view/theme/frio/css/style.css b/view/theme/frio/css/style.css index 853fb057a3..84779c36a7 100644 --- a/view/theme/frio/css/style.css +++ b/view/theme/frio/css/style.css @@ -2248,8 +2248,8 @@ ul.dropdown-menu li:hover { *********/ section > .generic-page-wrapper, .videos-content-wrapper, - .suggest-content-wrapper, .common-content-wrapper, .help-content-wrapper, -.allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper, +.suggest-content-wrapper, .help-content-wrapper, +.match-content-wrapper, .dirfind-content-wrapper, .delegation-content-wrapper, .notes-content-wrapper, .message-content-wrapper, .apps-content-wrapper, #adminpage, .delegate-content-wrapper, .uexport-content-wrapper, @@ -3487,7 +3487,7 @@ section .profile-match-wrapper { right: 10px; } - .generic-page-wrapper, .videos-content-wrapper, .suggest-content-wrapper, .common-content-wrapper, .help-content-wrapper, .allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper, .directory-content-wrapper, .delegation-content-wrapper, .notes-content-wrapper, .message-content-wrapper, .apps-content-wrapper, #adminpage, .delegate-content-wrapper, .uexport-content-wrapper, .dfrn_request-content-wrapper, .friendica-content-wrapper, .credits-content-wrapper, .nogroup-content-wrapper, .profperm-content-wrapper, .invite-content-wrapper, .tos-content-wrapper, .fsuggest-content-wrapper { + .generic-page-wrapper, .videos-content-wrapper, .suggest-content-wrapper, .help-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper, .directory-content-wrapper, .delegation-content-wrapper, .notes-content-wrapper, .message-content-wrapper, .apps-content-wrapper, #adminpage, .delegate-content-wrapper, .uexport-content-wrapper, .dfrn_request-content-wrapper, .friendica-content-wrapper, .credits-content-wrapper, .nogroup-content-wrapper, .profperm-content-wrapper, .invite-content-wrapper, .tos-content-wrapper, .fsuggest-content-wrapper { border-radius: 0; padding: 10px; } diff --git a/view/theme/frio/templates/common_tabs.tpl b/view/theme/frio/templates/common_tabs.tpl index 76c6db0398..27ae11686b 100644 --- a/view/theme/frio/templates/common_tabs.tpl +++ b/view/theme/frio/templates/common_tabs.tpl @@ -4,7 +4,7 @@