xref: /webtrees/app/Statistics/Repository/UserRepository.php (revision 4ca7e03c48ab545219e9f91c7860d56cae5e1f09)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2018 webtrees development team
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16declare(strict_types=1);
17
18namespace Fisharebest\Webtrees\Statistics\Repository;
19
20use Fisharebest\Webtrees\Auth;
21use Fisharebest\Webtrees\I18N;
22use Fisharebest\Webtrees\Statistics\Repository\Interfaces\UserRepositoryInterface;
23use Fisharebest\Webtrees\Tree;
24use Fisharebest\Webtrees\User;
25
26/**
27 * A repository providing methods for user related statistics.
28 */
29class UserRepository implements UserRepositoryInterface
30{
31    /**
32     * @var Tree
33     */
34    private $tree;
35
36    /**
37     * Constructor.
38     *
39     * @param Tree $tree
40     */
41    public function __construct(Tree $tree)
42    {
43        $this->tree = $tree;
44    }
45
46    /**
47     * Who is currently logged in?
48     *
49     * @TODO - this is duplicated from the LoggedInUsersModule class.
50     *
51     * @param string $type
52     *
53     * @return string
54     */
55    private function usersLoggedInQuery($type = 'nolist'): string
56    {
57        $content = '';
58
59        // List active users
60        $NumAnonymous = 0;
61        $loggedusers  = [];
62
63        foreach (User::allLoggedIn() as $user) {
64            if (Auth::isAdmin() || $user->getPreference('visibleonline')) {
65                $loggedusers[] = $user;
66            } else {
67                $NumAnonymous++;
68            }
69        }
70
71        $LoginUsers = \count($loggedusers);
72        if ($LoginUsers === 0 && $NumAnonymous === 0) {
73            return I18N::translate('No signed-in and no anonymous users');
74        }
75
76        if ($NumAnonymous > 0) {
77            $content .= '<b>' . I18N::plural('%s anonymous signed-in user', '%s anonymous signed-in users', $NumAnonymous, I18N::number($NumAnonymous)) . '</b>';
78        }
79
80        if ($LoginUsers > 0) {
81            if ($NumAnonymous) {
82                if ($type === 'list') {
83                    $content .= '<br><br>';
84                } else {
85                    $content .= ' ' . I18N::translate('and') . ' ';
86                }
87            }
88            $content .= '<b>' . I18N::plural('%s signed-in user', '%s signed-in users', $LoginUsers, I18N::number($LoginUsers)) . '</b>';
89            if ($type === 'list') {
90                $content .= '<ul>';
91            } else {
92                $content .= ': ';
93            }
94        }
95
96        if (Auth::check()) {
97            foreach ($loggedusers as $user) {
98                if ($type === 'list') {
99                    $content .= '<li>' . e($user->getRealName()) . ' - ' . e($user->getUserName());
100                } else {
101                    $content .= e($user->getRealName()) . ' - ' . e($user->getUserName());
102                }
103
104                if (($user->getPreference('contactmethod') !== 'none')
105                    && (Auth::id() !== $user->id())
106                ) {
107                    if ($type === 'list') {
108                        $content .= '<br>';
109                    }
110                    $content .= '<a href="' . e(route('message', ['to'  => $user->getUserName(), 'ged' => $this->tree->name()])) . '" class="btn btn-link" title="' . I18N::translate('Send a message') . '">' . view('icons/email') . '</a>';
111                }
112
113                if ($type === 'list') {
114                    $content .= '</li>';
115                }
116            }
117        }
118
119        if ($type === 'list') {
120            $content .= '</ul>';
121        }
122
123        return $content;
124    }
125
126    /**
127     * @inheritDoc
128     */
129    public function usersLoggedIn(): string
130    {
131        return $this->usersLoggedInQuery();
132    }
133
134    /**
135     * @inheritDoc
136     */
137    public function usersLoggedInList(): string
138    {
139        return $this->usersLoggedInQuery('list');
140    }
141
142    /**
143     * Returns true if the given user is visible to others.
144     *
145     * @param User $user
146     *
147     * @return bool
148     */
149    private function isUserVisible(User $user): bool
150    {
151        return Auth::isAdmin() || $user->getPreference('visibleonline');
152    }
153
154    /**
155     * @inheritDoc
156     */
157    public function usersLoggedInTotal(): int
158    {
159        return \count(User::allLoggedIn());
160    }
161
162    /**
163     * @inheritDoc
164     */
165    public function usersLoggedInTotalAnon(): int
166    {
167        $anonymous = 0;
168
169        foreach (User::allLoggedIn() as $user) {
170            if (!$this->isUserVisible($user)) {
171                ++$anonymous;
172            }
173        }
174
175        return $anonymous;
176    }
177
178    /**
179     * @inheritDoc
180     */
181    public function usersLoggedInTotalVisible(): int
182    {
183        $visible = 0;
184
185        foreach (User::allLoggedIn() as $user) {
186            if ($this->isUserVisible($user)) {
187                ++$visible;
188            }
189        }
190
191        return $visible;
192    }
193
194    /**
195     * @inheritDoc
196     */
197    public function userId(): string
198    {
199        return (string) Auth::id();
200    }
201
202    /**
203     * @inheritDoc
204     */
205    public function userName(string $visitor_text = ''): string
206    {
207        if (Auth::check()) {
208            return e(Auth::user()->getUserName());
209        }
210
211        // if #username:visitor# was specified, then "visitor" will be returned when the user is not logged in
212        return e($visitor_text);
213    }
214
215    /**
216     * @inheritDoc
217     */
218    public function userFullName(): string
219    {
220        return Auth::check() ? '<span dir="auto">' . e(Auth::user()->getRealName()) . '</span>' : '';
221    }
222
223    /**
224     * Returns the user count.
225     *
226     * @return int
227     */
228    private function getUserCount(): int
229    {
230        return \count(User::all());
231    }
232
233    /**
234     * Returns the administrator count.
235     *
236     * @return int
237     */
238    private function getAdminCount(): int
239    {
240        return \count(User::administrators());
241    }
242
243    /**
244     * @inheritDoc
245     */
246    public function totalUsers(): string
247    {
248        return I18N::number($this->getUserCount());
249    }
250
251    /**
252     * @inheritDoc
253     */
254    public function totalAdmins(): string
255    {
256        return I18N::number($this->getAdminCount());
257    }
258
259    /**
260     * @inheritDoc
261     */
262    public function totalNonAdmins(): string
263    {
264        return I18N::number($this->getUserCount() - $this->getAdminCount());
265    }
266}
267