diff --git a/VKAPI/Handlers/Users.php b/VKAPI/Handlers/Users.php index b09e82a55..3bfb52311 100644 --- a/VKAPI/Handlers/Users.php +++ b/VKAPI/Handlers/Users.php @@ -297,7 +297,7 @@ public function get(string $user_ids = "0", string $fields = "", int $offset = 0 "notes" => (new Notes())->getUserNotesCount($usr), "groups" => $usr->getClubCount(), "online_friends" => $usr->getFriendsOnlineCount(), - "mutual_friends" => 0, // FIXME: not implemented + "mutual_friends" => $authuser ? $usr->getCommonFriendsCount($authuser) : 0, "user_photos" => 0, // FIXME: not implemented "albums" => (new Albums())->getUserAlbumsCount($usr), "followers" => $usr->getFollowersCount(), diff --git a/Web/Models/Entities/User.php b/Web/Models/Entities/User.php index 819efdd40..abe2c4b83 100644 --- a/Web/Models/Entities/User.php +++ b/Web/Models/Entities/User.php @@ -46,14 +46,16 @@ class User extends RowModel private $_avatarAlbum = null; private $_avatarPhoto = false; // false - not resolved, null - no avatar - protected function _abstractRelationGenerator(string $filename, int $page = 1, int $limit = 6): \Traversable + protected function _abstractRelationGenerator(string $filename, int $page = 1, int $limit = 6, $second_id = null): \Traversable { $id = $this->getId(); + $second_id ??= $id; + $query = "SELECT id FROM\n" . file_get_contents(__DIR__ . "/../sql/$filename.tsql"); $query .= "\n LIMIT " . $limit . " OFFSET " . (($page - 1) * $limit); $ids = []; - $rels = DatabaseConnection::i()->getConnection()->query($query, $id, $id); + $rels = DatabaseConnection::i()->getConnection()->query($query, $id, $second_id); foreach ($rels as $rel) { $rel = (new Users())->get($rel->id); if (!$rel) { @@ -68,12 +70,14 @@ protected function _abstractRelationGenerator(string $filename, int $page = 1, i } } - protected function _abstractRelationCount(string $filename): int + protected function _abstractRelationCount(string $filename, $second_id = null): int { $id = $this->getId(); + $second_id ??= $id; + $query = "SELECT COUNT(*) AS cnt FROM\n" . file_get_contents(__DIR__ . "/../sql/$filename.tsql"); - return (int) DatabaseConnection::i()->getConnection()->query($query, $id, $id)->fetch()->cnt; + return (int) DatabaseConnection::i()->getConnection()->query($query, $id, $second_id)->fetch()->cnt; } public function getId(): int @@ -701,6 +705,16 @@ public function getFriendsOnlineCount(): int return $this->_abstractRelationCount("get-online-friends"); } + public function getCommonFriends(User $me, int $page = 1, int $limit = 6): \Traversable + { + return $this->_abstractRelationGenerator("get-common-friends", $page, $limit, $me->getId()); + } + + public function getCommonFriendsCount(User $me): int + { + return $this->_abstractRelationCount("get-common-friends", $me->getId()); + } + public function getFriendsBday(bool $today): array { $users = $this->_abstractRelationGenerator($today ? "get-bday-today" : "get-bday-tomorrow", 1, 3000); diff --git a/Web/Models/sql/get-common-friends.tsql b/Web/Models/sql/get-common-friends.tsql new file mode 100644 index 000000000..ba6439285 --- /dev/null +++ b/Web/Models/sql/get-common-friends.tsql @@ -0,0 +1 @@ +(SELECT DISTINCT p.* FROM subscriptions af1 INNER JOIN subscriptions af2 ON af1.follower = af2.target AND af2.follower = af1.target AND af1.model="openvk\\Web\\Models\\Entities\\User" AND af2.model="openvk\\Web\\Models\\Entities\\User" INNER JOIN subscriptions bf1 ON bf1.follower = af1.follower INNER JOIN subscriptions bf2 ON bf1.follower = bf2.target AND bf2.follower = bf1.target AND bf1.model="openvk\\Web\\Models\\Entities\\User" AND bf2.model="openvk\\Web\\Models\\Entities\\User" INNER JOIN profiles p ON p.id = af1.follower WHERE af1.target = ? AND bf1.target = ?) as common \ No newline at end of file diff --git a/Web/Presenters/UserPresenter.php b/Web/Presenters/UserPresenter.php index 4a7e759df..94e443104 100644 --- a/Web/Presenters/UserPresenter.php +++ b/Web/Presenters/UserPresenter.php @@ -95,20 +95,54 @@ public function renderFriends(int $id): void $this->template->user = $user; } - $this->template->mode = in_array($this->queryParam("act"), [ - "incoming", "outcoming", "friends", + $this->template->act = in_array($this->queryParam("act"), [ + "incoming", "outcoming", "friends", "common", "online", ]) ? $this->queryParam("act") - : "friends"; + : "friends"; + $this->template->page = $page; if (!is_null($this->user->identity)) { - if ($this->template->mode !== "friends" && $this->user->id !== $id) { + if (!in_array($this->template->act, ["friends", "common"]) && $this->user->id !== $id) { $name = $user->getFullName(); $this->flash("err", tr("error_access_denied_short"), tr("error_viewing_subs", $name)); $this->redirect($user->getURL()); } } + + if ($this->template->act === "common" && is_null($this->user->identity)) { + $this->template->act = "friends"; + } + + switch ($this->template->act) { + case "incoming": + $iterator = $user->getRequests($page); + $count = $user->getRequestsCount(); + break; + case "outcoming": + $iterator = $user->getSubscriptions($page); + $count = $user->getSubscriptionsCount(); + break; + case "followers": + $iterator = $user->getFollowers($page); + $count = $user->getFollowersCount(); + break; + case "online": + $iterator = $user->getFriendsOnline($page); + $count = $user->getFriendsOnlineCount(); + break; + case "common": + $iterator = $user->getCommonFriends($this->user->identity, $page); + $count = $user->getCommonFriendsCount($this->user->identity); + break; + default: + $iterator = $user->getFriends($page); + $count = $user->getFriendsCount(); + break; + } + $this->template->iterator = iterator_to_array($iterator); + $this->template->count = $count; } public function renderGroups(int $id): void diff --git a/Web/Presenters/templates/User/Friends.latte b/Web/Presenters/templates/User/Friends.latte index 89f1f9fa3..216a51e9e 100644 --- a/Web/Presenters/templates/User/Friends.latte +++ b/Web/Presenters/templates/User/Friends.latte @@ -1,37 +1,8 @@ {extends "../@listView.latte"} {var $perPage = 6} {* Why 6? Check User::_abstractRelationGenerator *} -{var $act = $_GET["act"] ?? "friends"} - -{if $act == "incoming"} - {var $iterator = iterator_to_array($user->getRequests($page))} - {var $count = $user->getRequestsCount()} -{elseif $act == "outcoming"} - {var $iterator = iterator_to_array($user->getSubscriptions($page))} - {var $count = $user->getSubscriptionsCount()} -{elseif $act == "followers"} - {var $iterator = iterator_to_array($user->getFollowers($page))} - {var $count = $user->getFollowersCount()} -{elseif $act == "online"} - {var $iterator = iterator_to_array($user->getFriendsOnline($page))} - {var $count = $user->getFriendsOnlineCount()} -{else} - {var $iterator = iterator_to_array($user->getFriends($page))} - {var $count = $user->getFriendsCount()} -{/if} - {block title} - {if $act == "incoming"} - {_incoming_req} - {elseif $act == "outcoming"} - {_outcoming_req} - {elseif $act == "followers"} - {_followers} - {elseif $act == "online"} - {_friends_online} - {else} - {_friends} - {/if} + {include "Friends/Title.latte", act => $act} {/block} {block header} @@ -39,17 +10,7 @@ {_my_friends} {else} {$user->getCanonicalName()} » - {if $act == "incoming"} - {_incoming_req} - {elseif $act == "outcoming"} - {_outcoming_req} - {elseif $act == "followers"} - {_followers} - {elseif $act == "online"} - {_friends_online} - {else} - {_friends} - {/if} + {include "Friends/Title.latte", act => $act} {/if} {/block} @@ -63,6 +24,9 @@
{_req}
+
+ {_friends_common} +
{/block} {block size} @@ -97,6 +61,8 @@ {else} {tr("friends_list", $count)} {/if} + {elseif $act == "common"} + {tr("friends_list_common", $count)} {else} {tr("friends", $count)} {/if} diff --git a/Web/Presenters/templates/User/Friends/Title.latte b/Web/Presenters/templates/User/Friends/Title.latte new file mode 100644 index 000000000..24fde637e --- /dev/null +++ b/Web/Presenters/templates/User/Friends/Title.latte @@ -0,0 +1,13 @@ +{if $act == "incoming"} + {_incoming_req} +{elseif $act == "outcoming"} + {_outcoming_req} +{elseif $act == "followers"} + {_followers} +{elseif $act == "online"} + {_friends_online} +{elseif $act == "common"} + {_friends_common} +{else} + {_friends} +{/if} \ No newline at end of file diff --git a/Web/Presenters/templates/User/Thumb.latte b/Web/Presenters/templates/User/Thumb.latte new file mode 100644 index 000000000..484c8af31 --- /dev/null +++ b/Web/Presenters/templates/User/Thumb.latte @@ -0,0 +1,11 @@ +
+
+ + + +
+ + {$user->getFirstName()} + {$user->getLastName()} + +
\ No newline at end of file diff --git a/Web/Presenters/templates/User/View.latte b/Web/Presenters/templates/User/View.latte index eda7416d1..7d40a944f 100644 --- a/Web/Presenters/templates/User/View.latte +++ b/Web/Presenters/templates/User/View.latte @@ -215,6 +215,24 @@ {/if}
+
+
+ {_friends_common} +
+
+
+ {tr("friends_common", $commonFriendsCount)} +
+ {_all_title} +
+
+
+ {foreach $user->getCommonFriends($thisUser, 1) as $friend} + {include "Thumb.latte", user => $friend} + {/foreach} +
+
+
{var $friendCount = $user->getFriendsCount()} @@ -229,17 +247,9 @@
-
-
- - - -
- - {$friend->getFirstName()} - {$friend->getLastName()} - -
+ {foreach $user->getFriends(1) as $friend} + {include "Thumb.latte", user => $friend} + {/foreach}
@@ -257,17 +267,9 @@
-
-
- - - -
- - {$friend->getFirstName()} - {$friend->getLastName()} - -
+ {foreach $user->getFriendsOnline(1) as $friend} + {include "Thumb.latte", user => $friend} + {/foreach}
diff --git a/locales/ru.strings b/locales/ru.strings index 31c983417..2ad790bb9 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -330,6 +330,7 @@ "outcoming_req" = "Исходящие"; "req" = "Заявки"; "friends_online" = "Друзья онлайн"; +"friends_common" = "Общие друзья"; "all_friends" = "Все друзья"; "req_zero" = "Не найдено ни одной заявки..."; "req_one" = "Найдена $1 заявка"; @@ -346,6 +347,11 @@ "friends_online_few" = "$1 друга онлайн"; "friends_online_many" = "$1 друзей онлайн"; "friends_online_other" = "$1 друзей онлайн"; +"friends_common_zero" = "Ни одного общего друга "; +"friends_common_one" = "$1 общий друг"; +"friends_common_few" = "$1 общих друга"; +"friends_common_many" = "$1 общих друзей"; +"friends_common_other" = "$1 общих друзей"; "friends_list_zero" = "У Вас пока нет друзей"; "friends_list_one" = "У Вас $1 друг"; "friends_list_few" = "У Вас $1 друга"; @@ -366,6 +372,11 @@ "friends_list_online_few" = "У Вас $1 друга онлайн"; "friends_list_online_many" = "У Вас $1 друзей онлайн"; "friends_list_online_other" = "У Вас $1 друзей онлайн"; +"friends_list_common_zero" = "У Вас пока нет общих друзей"; +"friends_list_common_one" = "У Вас $1 общий друг"; +"friends_list_common_few" = "У Вас $1 общих друга"; +"friends_list_common_many" = "У Вас $1 общих друзей"; +"friends_list_common_other" = "У Вас $1 общих друзей"; /* Group */