18add1155SRico Sonntag<?php 28add1155SRico Sonntag/** 38add1155SRico Sonntag * webtrees: online genealogy 4*242a7862SGreg Roach * Copyright (C) 2019 webtrees development team 58add1155SRico Sonntag * This program is free software: you can redistribute it and/or modify 68add1155SRico Sonntag * it under the terms of the GNU General Public License as published by 78add1155SRico Sonntag * the Free Software Foundation, either version 3 of the License, or 88add1155SRico Sonntag * (at your option) any later version. 98add1155SRico Sonntag * This program is distributed in the hope that it will be useful, 108add1155SRico Sonntag * but WITHOUT ANY WARRANTY; without even the implied warranty of 118add1155SRico Sonntag * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 128add1155SRico Sonntag * GNU General Public License for more details. 138add1155SRico Sonntag * You should have received a copy of the GNU General Public License 148add1155SRico Sonntag * along with this program. If not, see <http://www.gnu.org/licenses/>. 158add1155SRico Sonntag */ 168add1155SRico Sonntagdeclare(strict_types=1); 178add1155SRico Sonntag 188add1155SRico Sonntagnamespace Fisharebest\Webtrees\Statistics\Repository; 198add1155SRico Sonntag 208add1155SRico Sonntaguse Fisharebest\Webtrees\Auth; 21e5a6b4d4SGreg Roachuse Fisharebest\Webtrees\Contracts\UserInterface; 228add1155SRico Sonntaguse Fisharebest\Webtrees\I18N; 23e5a6b4d4SGreg Roachuse Fisharebest\Webtrees\Services\UserService; 248add1155SRico Sonntaguse Fisharebest\Webtrees\Statistics\Repository\Interfaces\UserRepositoryInterface; 258add1155SRico Sonntaguse Fisharebest\Webtrees\Tree; 268add1155SRico Sonntag 278add1155SRico Sonntag/** 288add1155SRico Sonntag * A repository providing methods for user related statistics. 298add1155SRico Sonntag */ 308add1155SRico Sonntagclass UserRepository implements UserRepositoryInterface 318add1155SRico Sonntag{ 328add1155SRico Sonntag /** 338add1155SRico Sonntag * @var Tree 348add1155SRico Sonntag */ 358add1155SRico Sonntag private $tree; 36e5a6b4d4SGreg Roach /** 37e5a6b4d4SGreg Roach * @var UserService 38e5a6b4d4SGreg Roach */ 39e5a6b4d4SGreg Roach private $user_service; 408add1155SRico Sonntag 418add1155SRico Sonntag /** 428add1155SRico Sonntag * Constructor. 438add1155SRico Sonntag * 448add1155SRico Sonntag * @param Tree $tree 45e5a6b4d4SGreg Roach * @param UserService $user_service 468add1155SRico Sonntag */ 47e5a6b4d4SGreg Roach public function __construct(Tree $tree, UserService $user_service) 488add1155SRico Sonntag { 498add1155SRico Sonntag $this->tree = $tree; 50e5a6b4d4SGreg Roach $this->user_service = $user_service; 518add1155SRico Sonntag } 528add1155SRico Sonntag 538add1155SRico Sonntag /** 548add1155SRico Sonntag * Who is currently logged in? 558add1155SRico Sonntag * 568add1155SRico Sonntag * @TODO - this is duplicated from the LoggedInUsersModule class. 578add1155SRico Sonntag * 588add1155SRico Sonntag * @param string $type 598add1155SRico Sonntag * 608add1155SRico Sonntag * @return string 618add1155SRico Sonntag */ 628add1155SRico Sonntag private function usersLoggedInQuery($type = 'nolist'): string 638add1155SRico Sonntag { 648add1155SRico Sonntag $content = ''; 658add1155SRico Sonntag 668add1155SRico Sonntag // List active users 678add1155SRico Sonntag $NumAnonymous = 0; 688add1155SRico Sonntag $loggedusers = []; 698add1155SRico Sonntag 70e5a6b4d4SGreg Roach foreach ($this->user_service->allLoggedIn() as $user) { 718add1155SRico Sonntag if (Auth::isAdmin() || $user->getPreference('visibleonline')) { 728add1155SRico Sonntag $loggedusers[] = $user; 738add1155SRico Sonntag } else { 748add1155SRico Sonntag $NumAnonymous++; 758add1155SRico Sonntag } 768add1155SRico Sonntag } 778add1155SRico Sonntag 788add1155SRico Sonntag $LoginUsers = \count($loggedusers); 798add1155SRico Sonntag if ($LoginUsers === 0 && $NumAnonymous === 0) { 808add1155SRico Sonntag return I18N::translate('No signed-in and no anonymous users'); 818add1155SRico Sonntag } 828add1155SRico Sonntag 838add1155SRico Sonntag if ($NumAnonymous > 0) { 848add1155SRico Sonntag $content .= '<b>' . I18N::plural('%s anonymous signed-in user', '%s anonymous signed-in users', $NumAnonymous, I18N::number($NumAnonymous)) . '</b>'; 858add1155SRico Sonntag } 868add1155SRico Sonntag 878add1155SRico Sonntag if ($LoginUsers > 0) { 888add1155SRico Sonntag if ($NumAnonymous) { 898add1155SRico Sonntag if ($type === 'list') { 908add1155SRico Sonntag $content .= '<br><br>'; 918add1155SRico Sonntag } else { 928add1155SRico Sonntag $content .= ' ' . I18N::translate('and') . ' '; 938add1155SRico Sonntag } 948add1155SRico Sonntag } 958add1155SRico Sonntag $content .= '<b>' . I18N::plural('%s signed-in user', '%s signed-in users', $LoginUsers, I18N::number($LoginUsers)) . '</b>'; 968add1155SRico Sonntag if ($type === 'list') { 978add1155SRico Sonntag $content .= '<ul>'; 988add1155SRico Sonntag } else { 998add1155SRico Sonntag $content .= ': '; 1008add1155SRico Sonntag } 1018add1155SRico Sonntag } 1028add1155SRico Sonntag 1038add1155SRico Sonntag if (Auth::check()) { 1048add1155SRico Sonntag foreach ($loggedusers as $user) { 1058add1155SRico Sonntag if ($type === 'list') { 106e5a6b4d4SGreg Roach $content .= '<li>' . e($user->realName()) . ' - ' . e($user->userName()); 1078add1155SRico Sonntag } else { 108e5a6b4d4SGreg Roach $content .= e($user->realName()) . ' - ' . e($user->userName()); 1098add1155SRico Sonntag } 1108add1155SRico Sonntag 1118add1155SRico Sonntag if (($user->getPreference('contactmethod') !== 'none') 1128add1155SRico Sonntag && (Auth::id() !== $user->id()) 1138add1155SRico Sonntag ) { 1148add1155SRico Sonntag if ($type === 'list') { 1158add1155SRico Sonntag $content .= '<br>'; 1168add1155SRico Sonntag } 117e5a6b4d4SGreg Roach $content .= '<a href="' . e(route('message', ['to' => $user->userName(), 'ged' => $this->tree->name()])) . '" class="btn btn-link" title="' . I18N::translate('Send a message') . '">' . view('icons/email') . '</a>'; 1188add1155SRico Sonntag } 1198add1155SRico Sonntag 1208add1155SRico Sonntag if ($type === 'list') { 1218add1155SRico Sonntag $content .= '</li>'; 1228add1155SRico Sonntag } 1238add1155SRico Sonntag } 1248add1155SRico Sonntag } 1258add1155SRico Sonntag 1268add1155SRico Sonntag if ($type === 'list') { 1278add1155SRico Sonntag $content .= '</ul>'; 1288add1155SRico Sonntag } 1298add1155SRico Sonntag 1308add1155SRico Sonntag return $content; 1318add1155SRico Sonntag } 1328add1155SRico Sonntag 1338add1155SRico Sonntag /** 1348add1155SRico Sonntag * @inheritDoc 1358add1155SRico Sonntag */ 1368add1155SRico Sonntag public function usersLoggedIn(): string 1378add1155SRico Sonntag { 1388add1155SRico Sonntag return $this->usersLoggedInQuery(); 1398add1155SRico Sonntag } 1408add1155SRico Sonntag 1418add1155SRico Sonntag /** 1428add1155SRico Sonntag * @inheritDoc 1438add1155SRico Sonntag */ 1448add1155SRico Sonntag public function usersLoggedInList(): string 1458add1155SRico Sonntag { 1468add1155SRico Sonntag return $this->usersLoggedInQuery('list'); 1478add1155SRico Sonntag } 1488add1155SRico Sonntag 1498add1155SRico Sonntag /** 1508add1155SRico Sonntag * Returns true if the given user is visible to others. 1518add1155SRico Sonntag * 152e5a6b4d4SGreg Roach * @param UserInterface $user 1538add1155SRico Sonntag * 1548add1155SRico Sonntag * @return bool 1558add1155SRico Sonntag */ 156e5a6b4d4SGreg Roach private function isUserVisible(UserInterface $user): bool 1578add1155SRico Sonntag { 1588add1155SRico Sonntag return Auth::isAdmin() || $user->getPreference('visibleonline'); 1598add1155SRico Sonntag } 1608add1155SRico Sonntag 1618add1155SRico Sonntag /** 1628add1155SRico Sonntag * @inheritDoc 1638add1155SRico Sonntag */ 1648add1155SRico Sonntag public function usersLoggedInTotal(): int 1658add1155SRico Sonntag { 166e5a6b4d4SGreg Roach return \count($this->user_service->allLoggedIn()); 1678add1155SRico Sonntag } 1688add1155SRico Sonntag 1698add1155SRico Sonntag /** 1708add1155SRico Sonntag * @inheritDoc 1718add1155SRico Sonntag */ 1728add1155SRico Sonntag public function usersLoggedInTotalAnon(): int 1738add1155SRico Sonntag { 1748add1155SRico Sonntag $anonymous = 0; 1758add1155SRico Sonntag 176e5a6b4d4SGreg Roach foreach ($this->user_service->allLoggedIn() as $user) { 1778add1155SRico Sonntag if (!$this->isUserVisible($user)) { 1788add1155SRico Sonntag ++$anonymous; 1798add1155SRico Sonntag } 1808add1155SRico Sonntag } 1818add1155SRico Sonntag 1828add1155SRico Sonntag return $anonymous; 1838add1155SRico Sonntag } 1848add1155SRico Sonntag 1858add1155SRico Sonntag /** 1868add1155SRico Sonntag * @inheritDoc 1878add1155SRico Sonntag */ 1888add1155SRico Sonntag public function usersLoggedInTotalVisible(): int 1898add1155SRico Sonntag { 1908add1155SRico Sonntag $visible = 0; 1918add1155SRico Sonntag 192e5a6b4d4SGreg Roach foreach ($this->user_service->allLoggedIn() as $user) { 1938add1155SRico Sonntag if ($this->isUserVisible($user)) { 1948add1155SRico Sonntag ++$visible; 1958add1155SRico Sonntag } 1968add1155SRico Sonntag } 1978add1155SRico Sonntag 1988add1155SRico Sonntag return $visible; 1998add1155SRico Sonntag } 2008add1155SRico Sonntag 2018add1155SRico Sonntag /** 2028add1155SRico Sonntag * @inheritDoc 2038add1155SRico Sonntag */ 2048add1155SRico Sonntag public function userId(): string 2058add1155SRico Sonntag { 2068add1155SRico Sonntag return (string) Auth::id(); 2078add1155SRico Sonntag } 2088add1155SRico Sonntag 2098add1155SRico Sonntag /** 2108add1155SRico Sonntag * @inheritDoc 2118add1155SRico Sonntag */ 2128add1155SRico Sonntag public function userName(string $visitor_text = ''): string 2138add1155SRico Sonntag { 2148add1155SRico Sonntag if (Auth::check()) { 215e5a6b4d4SGreg Roach return e(Auth::user()->userName()); 2168add1155SRico Sonntag } 2178add1155SRico Sonntag 2188add1155SRico Sonntag // if #username:visitor# was specified, then "visitor" will be returned when the user is not logged in 2198add1155SRico Sonntag return e($visitor_text); 2208add1155SRico Sonntag } 2218add1155SRico Sonntag 2228add1155SRico Sonntag /** 2238add1155SRico Sonntag * @inheritDoc 2248add1155SRico Sonntag */ 2258add1155SRico Sonntag public function userFullName(): string 2268add1155SRico Sonntag { 227e5a6b4d4SGreg Roach return Auth::check() ? '<span dir="auto">' . e(Auth::user()->realName()) . '</span>' : ''; 2288add1155SRico Sonntag } 2298add1155SRico Sonntag 2308add1155SRico Sonntag /** 2318add1155SRico Sonntag * Returns the user count. 2328add1155SRico Sonntag * 2338add1155SRico Sonntag * @return int 2348add1155SRico Sonntag */ 2358add1155SRico Sonntag private function getUserCount(): int 2368add1155SRico Sonntag { 237e5a6b4d4SGreg Roach return \count($this->user_service->all()); 2388add1155SRico Sonntag } 2398add1155SRico Sonntag 2408add1155SRico Sonntag /** 2418add1155SRico Sonntag * Returns the administrator count. 2428add1155SRico Sonntag * 2438add1155SRico Sonntag * @return int 2448add1155SRico Sonntag */ 2458add1155SRico Sonntag private function getAdminCount(): int 2468add1155SRico Sonntag { 247e5a6b4d4SGreg Roach return \count($this->user_service->administrators()); 2488add1155SRico Sonntag } 2498add1155SRico Sonntag 2508add1155SRico Sonntag /** 2518add1155SRico Sonntag * @inheritDoc 2528add1155SRico Sonntag */ 2538add1155SRico Sonntag public function totalUsers(): string 2548add1155SRico Sonntag { 2558add1155SRico Sonntag return I18N::number($this->getUserCount()); 2568add1155SRico Sonntag } 2578add1155SRico Sonntag 2588add1155SRico Sonntag /** 2598add1155SRico Sonntag * @inheritDoc 2608add1155SRico Sonntag */ 2618add1155SRico Sonntag public function totalAdmins(): string 2628add1155SRico Sonntag { 2638add1155SRico Sonntag return I18N::number($this->getAdminCount()); 2648add1155SRico Sonntag } 2658add1155SRico Sonntag 2668add1155SRico Sonntag /** 2678add1155SRico Sonntag * @inheritDoc 2688add1155SRico Sonntag */ 2698add1155SRico Sonntag public function totalNonAdmins(): string 2708add1155SRico Sonntag { 2718add1155SRico Sonntag return I18N::number($this->getUserCount() - $this->getAdminCount()); 2728add1155SRico Sonntag } 2738add1155SRico Sonntag} 274