xref: /webtrees/app/Services/UserService.php (revision e5a6b4d4f6f6e7ff2fba7ae2cf27546ae68a79cc)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2019 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\Services;
19
20use Fisharebest\Webtrees\Auth;
21use Fisharebest\Webtrees\Individual;
22use Fisharebest\Webtrees\User;
23use Illuminate\Database\Capsule\Manager as DB;
24use Illuminate\Database\Query\JoinClause;
25use Illuminate\Support\Collection;
26
27/**
28 * Functions for managing users.
29 */
30class UserService
31{
32    /**
33     * Find the user with a specified user_id.
34     *
35     * @param int|null $user_id
36     *
37     * @return User|null
38     */
39    public function find($user_id)
40    {
41        return app('cache.array')->rememberForever(__CLASS__ . $user_id, function () use ($user_id) {
42            return DB::table('user')
43                ->where('user_id', '=', $user_id)
44                ->get()
45                ->map(User::rowMapper())
46                ->first();
47        });
48    }
49
50    /**
51     * Find the user with a specified email address.
52     *
53     * @param string $email
54     *
55     * @return User|null
56     */
57    public function findByEmail($email)
58    {
59        return DB::table('user')
60            ->where('email', '=', $email)
61            ->get()
62            ->map(User::rowMapper())
63            ->first();
64    }
65
66    /**
67     * Find the user with a specified user_name or email address.
68     *
69     * @param string $identifier
70     *
71     * @return User|null
72     */
73    public function findByIdentifier($identifier)
74    {
75        return DB::table('user')
76            ->where('user_name', '=', $identifier)
77            ->orWhere('email', '=', $identifier)
78            ->get()
79            ->map(User::rowMapper())
80            ->first();
81    }
82
83    /**
84     * Find the user(s) with a specified genealogy record.
85     *
86     * @param Individual $individual
87     *
88     * @return Collection|User[]
89     */
90    public function findByIndividual(Individual $individual): Collection
91    {
92        return DB::table('user')
93            ->join('user_gedcom_setting', 'user_gedcom_setting.user_id', '=', 'user.user_id')
94            ->where('gedcom_id', '=', $individual->tree()->id())
95            ->where('setting_value', '=', $individual->xref())
96            ->where('setting_name', '=', 'gedcomid')
97            ->select(['user.*'])
98            ->get()
99            ->map(User::rowMapper());
100    }
101
102    /**
103     * Find the user with a specified user_name.
104     *
105     * @param string $user_name
106     *
107     * @return User|null
108     */
109    public function findByUserName($user_name)
110    {
111        return DB::table('user')
112            ->where('user_name', '=', $user_name)
113            ->get()
114            ->map(User::rowMapper())
115            ->first();
116    }
117
118    /**
119     * Get a list of all users.
120     *
121     * @return Collection|User[]
122     */
123    public function all(): Collection
124    {
125        return DB::table('user')
126            ->where('user_id', '>', 0)
127            ->orderBy('real_name')
128            ->get()
129            ->map(User::rowMapper());
130    }
131
132    /**
133     * Get a list of all administrators.
134     *
135     * @return Collection|User[]
136     */
137    public function administrators(): Collection
138    {
139        return DB::table('user')
140            ->join('user_setting', function (JoinClause $join): void {
141                $join
142                    ->on('user_setting.user_id', '=', 'user.user_id')
143                    ->where('user_setting.setting_name', '=', 'canadmin')
144                    ->where('user_setting.setting_value', '=', '1');
145            })
146            ->where('user.user_id', '>', 0)
147            ->orderBy('real_name')
148            ->select(['user.*'])
149            ->get()
150            ->map(User::rowMapper());
151    }
152
153    /**
154     * Get a list of all managers.
155     *
156     * @return Collection|User[]
157     */
158    public function managers(): Collection
159    {
160        return DB::table('user')
161            ->join('user_gedcom_setting', function (JoinClause $join): void {
162                $join
163                    ->on('user_gedcom_setting.user_id', '=', 'user.user_id')
164                    ->where('user_gedcom_setting.setting_name', '=', 'canedit')
165                    ->where('user_gedcom_setting.setting_value', '=', 'admin');
166            })
167            ->where('user.user_id', '>', 0)
168            ->orderBy('real_name')
169            ->select(['user.*'])
170            ->get()
171            ->map(User::rowMapper());
172    }
173
174    /**
175     * Get a list of all moderators.
176     *
177     * @return Collection|User[]
178     */
179    public function moderators(): Collection
180    {
181        return DB::table('user')
182            ->join('user_gedcom_setting', function (JoinClause $join): void {
183                $join
184                    ->on('user_gedcom_setting.user_id', '=', 'user.user_id')
185                    ->where('user_gedcom_setting.setting_name', '=', 'canedit')
186                    ->where('user_gedcom_setting.setting_value', '=', 'accept');
187            })
188            ->where('user.user_id', '>', 0)
189            ->orderBy('real_name')
190            ->select(['user.*'])
191            ->get()
192            ->map(User::rowMapper());
193    }
194
195    /**
196     * Get a list of all verified users.
197     *
198     * @return Collection|User[]
199     */
200    public function unapproved(): Collection
201    {
202        return DB::table('user')
203            ->join('user_setting', function (JoinClause $join): void {
204                $join
205                    ->on('user_setting.user_id', '=', 'user.user_id')
206                    ->where('user_setting.setting_name', '=', 'verified_by_admin')
207                    ->where('user_setting.setting_value', '=', '0');
208            })
209            ->where('user.user_id', '>', 0)
210            ->orderBy('real_name')
211            ->select(['user.*'])
212            ->get()
213            ->map(User::rowMapper());
214    }
215
216    /**
217     * Get a list of all verified users.
218     *
219     * @return Collection|User[]
220     */
221    public function unverified(): Collection
222    {
223        return DB::table('user')
224            ->join('user_setting', function (JoinClause $join): void {
225                $join
226                    ->on('user_setting.user_id', '=', 'user.user_id')
227                    ->where('user_setting.setting_name', '=', 'verified')
228                    ->where('user_setting.setting_value', '=', '0');
229            })
230            ->where('user.user_id', '>', 0)
231            ->orderBy('real_name')
232            ->select(['user.*'])
233            ->get()
234            ->map(User::rowMapper());
235    }
236
237    /**
238     * Get a list of all users who are currently logged in.
239     *
240     * @return Collection|User[]
241     */
242    public function allLoggedIn(): Collection
243    {
244        return DB::table('user')
245            ->join('session', 'session.user_id', '=', 'user.user_id')
246            ->where('user.user_id', '>', 0)
247            ->orderBy('real_name')
248            ->select(['user.*'])
249            ->distinct()
250            ->get()
251            ->map(User::rowMapper());
252    }
253
254    /**
255     * Create a new user.
256     * The calling code needs to check for duplicates identifiers before calling
257     * this function.
258     *
259     * @param string $user_name
260     * @param string $real_name
261     * @param string $email
262     * @param string $password
263     *
264     * @return User
265     */
266    public static function create($user_name, $real_name, $email, $password): User
267    {
268        DB::table('user')->insert([
269            'user_name' => $user_name,
270            'real_name' => $real_name,
271            'email'     => $email,
272            'password'  => password_hash($password, PASSWORD_DEFAULT),
273        ]);
274
275        $user_id = (int) DB::connection()->getPdo()->lastInsertId();
276
277        return new User($user_id, $user_name, $real_name, $email);
278    }
279
280    /**
281     * Delete a user
282     *
283     * @param User $user
284     *
285     * @return void
286     */
287    public function delete(User $user)
288    {
289        // Don't delete the logs, just set the user to null.
290        DB::table('log')
291            ->where('user_id', '=', $user->id())
292            ->update(['user_id' => null]);
293
294        // Take over the user’s pending changes. (What else could we do with them?)
295        DB::table('change')
296            ->where('user_id', '=', $user->id())
297            ->where('status', '=', 'rejected')
298            ->delete();
299
300        DB::table('change')
301            ->where('user_id', '=', $user->id())
302            ->update(['user_id' => Auth::id()]);
303
304        // Take over the user's contact details
305        DB::table('gedcom_setting')
306            ->where('setting_value', '=', $user->id())
307            ->whereIn('setting_name', ['CONTACT_USER_ID', 'WEBMASTER_USER_ID'])
308            ->update(['setting_value' => Auth::id()]);
309
310        // Delete settings and preferences
311        DB::table('block_setting')
312            ->join('block', 'block_setting.block_id', '=', 'block.block_id')
313            ->where('user_id', '=', $user->id())
314            ->delete();
315
316        DB::table('block')->where('user_id', '=', $user->id())->delete();
317        DB::table('user_gedcom_setting')->where('user_id', '=', $user->id())->delete();
318        DB::table('user_setting')->where('user_id', '=', $user->id())->delete();
319        DB::table('message')->where('user_id', '=', $user->id())->delete();
320        DB::table('user')->where('user_id', '=', $user->id())->delete();
321    }
322}
323