xref: /webtrees/app/User.php (revision 8b67c11a1199191915b4af08a3841e7ce9d528b6)
1a25f0a04SGreg Roach<?php
2a25f0a04SGreg Roach/**
3a25f0a04SGreg Roach * webtrees: online genealogy
48fcd0d32SGreg Roach * Copyright (C) 2019 webtrees development team
5a25f0a04SGreg Roach * This program is free software: you can redistribute it and/or modify
6a25f0a04SGreg Roach * it under the terms of the GNU General Public License as published by
7a25f0a04SGreg Roach * the Free Software Foundation, either version 3 of the License, or
8a25f0a04SGreg Roach * (at your option) any later version.
9a25f0a04SGreg Roach * This program is distributed in the hope that it will be useful,
10a25f0a04SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
11a25f0a04SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12a25f0a04SGreg Roach * GNU General Public License for more details.
13a25f0a04SGreg Roach * You should have received a copy of the GNU General Public License
14a25f0a04SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
15a25f0a04SGreg Roach */
16c04dd3c1SGreg Roachdeclare(strict_types=1);
17c04dd3c1SGreg Roach
1876692c8bSGreg Roachnamespace Fisharebest\Webtrees;
19a25f0a04SGreg Roach
20*8b67c11aSGreg Roachuse Closure;
2101461f86SGreg Roachuse Illuminate\Database\Capsule\Manager as DB;
2201461f86SGreg Roachuse Illuminate\Database\Query\Builder;
23639e2984SGreg Roachuse Illuminate\Database\Query\JoinClause;
24*8b67c11aSGreg Roachuse Illuminate\Support\Collection;
25b0b72ea4SGreg Roachuse stdClass;
2660bc3e3fSGreg Roach
27a25f0a04SGreg Roach/**
2876692c8bSGreg Roach * Provide an interface to the wt_user table.
29a25f0a04SGreg Roach */
30c1010edaSGreg Roachclass User
31c1010edaSGreg Roach{
32c04dd3c1SGreg Roach    /** @var  int The primary key of this user. */
33a25f0a04SGreg Roach    private $user_id;
34a25f0a04SGreg Roach
35a25f0a04SGreg Roach    /** @var  string The login name of this user. */
36a25f0a04SGreg Roach    private $user_name;
37a25f0a04SGreg Roach
38a25f0a04SGreg Roach    /** @var  string The real (display) name of this user. */
39a25f0a04SGreg Roach    private $real_name;
40a25f0a04SGreg Roach
41a25f0a04SGreg Roach    /** @var  string The email address of this user. */
42a25f0a04SGreg Roach    private $email;
43a25f0a04SGreg Roach
4415d603e7SGreg Roach    /** @var string[] Cached copy of the wt_user_setting table. */
4515d603e7SGreg Roach    private $preferences = [];
46a25f0a04SGreg Roach
47a25f0a04SGreg Roach    /**
48f7fb7d41SGreg Roach     * Create a new user object from a row in the database.
49f7fb7d41SGreg Roach     *
50*8b67c11aSGreg Roach     * @param int    $user_id
51*8b67c11aSGreg Roach     * @param string $user_name
52*8b67c11aSGreg Roach     * @param string $real_name
53*8b67c11aSGreg Roach     * @param string $email
54f7fb7d41SGreg Roach     */
55*8b67c11aSGreg Roach    private function __construct(int $user_id, string $user_name, string $real_name, string $email)
56c1010edaSGreg Roach    {
57*8b67c11aSGreg Roach        $this->user_id   = $user_id;
58*8b67c11aSGreg Roach        $this->user_name = $user_name;
59*8b67c11aSGreg Roach        $this->real_name = $real_name;
60*8b67c11aSGreg Roach        $this->email     = $email;
61*8b67c11aSGreg Roach    }
62*8b67c11aSGreg Roach
63*8b67c11aSGreg Roach    /**
64*8b67c11aSGreg Roach     * A closure which will create an object from a database row.
65*8b67c11aSGreg Roach     *
66*8b67c11aSGreg Roach     * @return Closure
67*8b67c11aSGreg Roach     */
68*8b67c11aSGreg Roach    public static function rowMapper(): Closure
69*8b67c11aSGreg Roach    {
70*8b67c11aSGreg Roach        return function (stdClass $row): User {
71*8b67c11aSGreg Roach            return new static((int) $row->user_id, $row->user_name, $row->real_name, $row->email);
72*8b67c11aSGreg Roach        };
73*8b67c11aSGreg Roach    }
74*8b67c11aSGreg Roach
75*8b67c11aSGreg Roach    /**
76*8b67c11aSGreg Roach     * Create a dummy user from a tree, to send messages.
77*8b67c11aSGreg Roach     *
78*8b67c11aSGreg Roach     * @param Tree $tree
79*8b67c11aSGreg Roach     *
80*8b67c11aSGreg Roach     * @return User
81*8b67c11aSGreg Roach     */
82*8b67c11aSGreg Roach    public static function userFromTree(Tree $tree): User{
83*8b67c11aSGreg Roach        return  new static(0, '', $tree->title(),$tree->getPreference('WEBTREES_EMAIL'));
84*8b67c11aSGreg Roach    }
85*8b67c11aSGreg Roach
86*8b67c11aSGreg Roach    /**
87*8b67c11aSGreg Roach     * A dummy/null user for visitors.
88*8b67c11aSGreg Roach     *
89*8b67c11aSGreg Roach     * @param string $real_name
90*8b67c11aSGreg Roach     * @param string $email
91*8b67c11aSGreg Roach     *
92*8b67c11aSGreg Roach     * @return User
93*8b67c11aSGreg Roach     */
94*8b67c11aSGreg Roach    public static function visitor(string $real_name = '', string $email = ''): User
95*8b67c11aSGreg Roach    {
96*8b67c11aSGreg Roach        return new static(0, '', $real_name, $email);
97f7fb7d41SGreg Roach    }
98f7fb7d41SGreg Roach
99f7fb7d41SGreg Roach    /**
100f7fb7d41SGreg Roach     * Create a new user.
101f7fb7d41SGreg Roach     * The calling code needs to check for duplicates identifiers before calling
102f7fb7d41SGreg Roach     * this function.
103f7fb7d41SGreg Roach     *
104f7fb7d41SGreg Roach     * @param string $user_name
105f7fb7d41SGreg Roach     * @param string $real_name
106f7fb7d41SGreg Roach     * @param string $email
107f7fb7d41SGreg Roach     * @param string $password
108f7fb7d41SGreg Roach     *
109f7fb7d41SGreg Roach     * @return User
110f7fb7d41SGreg Roach     */
1118f53f488SRico Sonntag    public static function create($user_name, $real_name, $email, $password): User
112c1010edaSGreg Roach    {
11301461f86SGreg Roach        DB::table('user')->insert([
114f7fb7d41SGreg Roach            'user_name' => $user_name,
115f7fb7d41SGreg Roach            'real_name' => $real_name,
116f7fb7d41SGreg Roach            'email'     => $email,
117f7fb7d41SGreg Roach            'password'  => password_hash($password, PASSWORD_DEFAULT),
118f7fb7d41SGreg Roach        ]);
119f7fb7d41SGreg Roach
120f7fb7d41SGreg Roach        // Set default blocks for this user
121f7fb7d41SGreg Roach        $user = self::findByIdentifier($user_name);
12201461f86SGreg Roach
12301461f86SGreg Roach        (new Builder(DB::connection()))->from('block')->insertUsing(
12401461f86SGreg Roach            ['user_id', 'location', 'block_order', 'module_name'],
12501461f86SGreg Roach            function (Builder $query) use ($user): void {
12601461f86SGreg Roach                $query
12701461f86SGreg Roach                    ->select([DB::raw($user->getuserId()), 'location', 'block_order', 'module_name'])
12801461f86SGreg Roach                    ->from('block')
12901461f86SGreg Roach                    ->where('user_id', '=', -1);
13001461f86SGreg Roach            }
13101461f86SGreg Roach        );
132f7fb7d41SGreg Roach
133f7fb7d41SGreg Roach        return $user;
134f7fb7d41SGreg Roach    }
135f7fb7d41SGreg Roach
136f7fb7d41SGreg Roach    /**
137f7fb7d41SGreg Roach     * Delete a user
138fa4036e8SGreg Roach     *
139fa4036e8SGreg Roach     * @return void
140f7fb7d41SGreg Roach     */
141c1010edaSGreg Roach    public function delete()
142c1010edaSGreg Roach    {
14337b0f34fSGreg Roach        // Don't delete the logs, just set the user to null.
14437b0f34fSGreg Roach        DB::table('log')
14537b0f34fSGreg Roach            ->where('user_id', '=', $this->user_id)
14637b0f34fSGreg Roach            ->update(['user_id' => null]);
14737b0f34fSGreg Roach
148f7fb7d41SGreg Roach        // Take over the user’s pending changes. (What else could we do with them?)
14937b0f34fSGreg Roach        DB::table('change')
15037b0f34fSGreg Roach            ->where('user_id', '=', $this->user_id)
15137b0f34fSGreg Roach            ->where('status', '=', 'rejected')
15237b0f34fSGreg Roach            ->delete();
15337b0f34fSGreg Roach
15437b0f34fSGreg Roach        DB::table('change')
15537b0f34fSGreg Roach            ->where('user_id', '=', $this->user_id)
15637b0f34fSGreg Roach            ->update(['user_id' => Auth::id()]);
15737b0f34fSGreg Roach
15837b0f34fSGreg Roach        // Take over the user's contact details
15937b0f34fSGreg Roach        DB::table('gedcom_setting')
16037b0f34fSGreg Roach            ->where('setting_value', '=', $this->user_id)
16137b0f34fSGreg Roach            ->whereIn('setting_name', ['CONTACT_USER_ID', 'WEBMASTER_USER_ID'])
16237b0f34fSGreg Roach            ->update(['setting_value' => Auth::id()]);
16337b0f34fSGreg Roach
16437b0f34fSGreg Roach        // Delete settings and preferences
16537b0f34fSGreg Roach        DB::table('block_setting')
16637b0f34fSGreg Roach            ->join('block', 'block_setting.block_id', '=', 'block.block_id')
16737b0f34fSGreg Roach            ->where('user_id', '=', $this->user_id)
16837b0f34fSGreg Roach            ->delete();
16937b0f34fSGreg Roach
17037b0f34fSGreg Roach        DB::table('block')->where('user_id', '=', $this->user_id)->delete();
17137b0f34fSGreg Roach        DB::table('user_gedcom_setting')->where('user_id', '=', $this->user_id)->delete();
17237b0f34fSGreg Roach        DB::table('user_setting')->where('user_id', '=', $this->user_id)->delete();
17337b0f34fSGreg Roach        DB::table('message')->where('user_id', '=', $this->user_id)->delete();
17437b0f34fSGreg Roach        DB::table('user')->where('user_id', '=', $this->user_id)->delete();
175f7fb7d41SGreg Roach    }
176f7fb7d41SGreg Roach
177f7fb7d41SGreg Roach    /**
178a25f0a04SGreg Roach     * Find the user with a specified user_id.
179a25f0a04SGreg Roach     *
180cbc1590aSGreg Roach     * @param int|null $user_id
181a25f0a04SGreg Roach     *
182a25f0a04SGreg Roach     * @return User|null
183a25f0a04SGreg Roach     */
184c1010edaSGreg Roach    public static function find($user_id)
185c1010edaSGreg Roach    {
186*8b67c11aSGreg Roach        return app('cache.array')->rememberForever(__CLASS__ . $user_id, function () use ($user_id) {
187*8b67c11aSGreg Roach            return DB::table('user')
18801461f86SGreg Roach                ->where('user_id', '=', $user_id)
189*8b67c11aSGreg Roach                ->get();
190*8b67c11aSGreg Roach        })
191*8b67c11aSGreg Roach        ->map(static::rowMapper())
19201461f86SGreg Roach        ->first();
193a25f0a04SGreg Roach    }
194a25f0a04SGreg Roach
195a25f0a04SGreg Roach    /**
196a982a56eSGreg Roach     * Find the user with a specified email address.
197a982a56eSGreg Roach     *
198a982a56eSGreg Roach     * @param string $email
199a982a56eSGreg Roach     *
200a982a56eSGreg Roach     * @return User|null
201a982a56eSGreg Roach     */
202c1010edaSGreg Roach    public static function findByEmail($email)
203c1010edaSGreg Roach    {
204*8b67c11aSGreg Roach        return DB::table('user')
20501461f86SGreg Roach            ->where('email', '=', $email)
206*8b67c11aSGreg Roach            ->get()
207*8b67c11aSGreg Roach            ->map(static::rowMapper())
208*8b67c11aSGreg Roach            ->first();
209a982a56eSGreg Roach    }
210a982a56eSGreg Roach
211a982a56eSGreg Roach    /**
212a982a56eSGreg Roach     * Find the user with a specified user_name or email address.
213a25f0a04SGreg Roach     *
214a25f0a04SGreg Roach     * @param string $identifier
215a25f0a04SGreg Roach     *
216a25f0a04SGreg Roach     * @return User|null
217a25f0a04SGreg Roach     */
218c1010edaSGreg Roach    public static function findByIdentifier($identifier)
219c1010edaSGreg Roach    {
220*8b67c11aSGreg Roach        return DB::table('user')
22101461f86SGreg Roach            ->where('user_name', '=', $identifier)
22201461f86SGreg Roach            ->orWhere('email', '=', $identifier)
223*8b67c11aSGreg Roach            ->get()
224*8b67c11aSGreg Roach            ->map(static::rowMapper())
225*8b67c11aSGreg Roach            ->first();
226a25f0a04SGreg Roach    }
227a25f0a04SGreg Roach
228a25f0a04SGreg Roach    /**
229bc09afc5SGreg Roach     * Find the user(s) with a specified genealogy record.
230a25f0a04SGreg Roach     *
231a25f0a04SGreg Roach     * @param Individual $individual
232a25f0a04SGreg Roach     *
233*8b67c11aSGreg Roach     * @return Collection|User[]
234a25f0a04SGreg Roach     */
235*8b67c11aSGreg Roach    public static function findByIndividual(Individual $individual): Collection
236c1010edaSGreg Roach    {
237*8b67c11aSGreg Roach        return DB::table('user')
238*8b67c11aSGreg Roach            ->join('user_gedcom_setting', 'user_gedcom_setting.user_id', '=', 'user.user_id')
239bc09afc5SGreg Roach            ->where('gedcom_id', '=', $individual->tree()->id())
240bc09afc5SGreg Roach            ->where('setting_value', '=', $individual->xref())
241bc09afc5SGreg Roach            ->where('setting_name', '=', 'gedcomid')
242*8b67c11aSGreg Roach            ->select(['user.*'])
243*8b67c11aSGreg Roach            ->get()
244*8b67c11aSGreg Roach            ->map(static::rowMapper());
245a25f0a04SGreg Roach    }
246a25f0a04SGreg Roach
247a25f0a04SGreg Roach    /**
248f7fb7d41SGreg Roach     * Find the user with a specified user_name.
249f7fb7d41SGreg Roach     *
250f7fb7d41SGreg Roach     * @param string $user_name
251f7fb7d41SGreg Roach     *
252f7fb7d41SGreg Roach     * @return User|null
253f7fb7d41SGreg Roach     */
254c1010edaSGreg Roach    public static function findByUserName($user_name)
255c1010edaSGreg Roach    {
256*8b67c11aSGreg Roach        return DB::table('user')
25701461f86SGreg Roach            ->where('user_name', '=', $user_name)
258*8b67c11aSGreg Roach            ->get()
259*8b67c11aSGreg Roach            ->map(static::rowMapper())
260*8b67c11aSGreg Roach            ->first();
261f7fb7d41SGreg Roach    }
262f7fb7d41SGreg Roach
263f7fb7d41SGreg Roach    /**
264a25f0a04SGreg Roach     * Get a list of all users.
265a25f0a04SGreg Roach     *
266*8b67c11aSGreg Roach     * @return Collection|User[]
267a25f0a04SGreg Roach     */
268*8b67c11aSGreg Roach    public static function all(): Collection
269c1010edaSGreg Roach    {
270*8b67c11aSGreg Roach        return DB::table('user')
271639e2984SGreg Roach            ->where('user_id', '>', 0)
272639e2984SGreg Roach            ->orderBy('real_name')
273639e2984SGreg Roach            ->select(['user_id', 'user_name', 'real_name', 'email'])
274*8b67c11aSGreg Roach            ->get()
275*8b67c11aSGreg Roach            ->map(static::rowMapper());
276a25f0a04SGreg Roach    }
277a25f0a04SGreg Roach
278a25f0a04SGreg Roach    /**
279a25f0a04SGreg Roach     * Get a list of all administrators.
280a25f0a04SGreg Roach     *
281*8b67c11aSGreg Roach     * @return Collection|User[]
282a25f0a04SGreg Roach     */
283*8b67c11aSGreg Roach    public static function administrators(): Collection
284c1010edaSGreg Roach    {
285*8b67c11aSGreg Roach        return DB::table('user')
286639e2984SGreg Roach            ->join('user_setting', function (JoinClause $join): void {
287639e2984SGreg Roach                $join
288639e2984SGreg Roach                    ->on('user_setting.user_id', '=', 'user.user_id')
289639e2984SGreg Roach                    ->where('user_setting.setting_name', '=', 'canadmin')
290639e2984SGreg Roach                    ->where('user_setting.setting_value', '=', '1');
291639e2984SGreg Roach            })
292639e2984SGreg Roach            ->where('user.user_id', '>', 0)
293639e2984SGreg Roach            ->orderBy('real_name')
294639e2984SGreg Roach            ->select(['user.user_id', 'user_name', 'real_name', 'email'])
295*8b67c11aSGreg Roach            ->get()
296*8b67c11aSGreg Roach            ->map(static::rowMapper());
297a25f0a04SGreg Roach    }
298a25f0a04SGreg Roach
299fa4036e8SGreg Roach    /**
300fa4036e8SGreg Roach     * Validate a supplied password
301c1010edaSGreg Roach     *
302a25f0a04SGreg Roach     * @param string $password
303a25f0a04SGreg Roach     *
304cbc1590aSGreg Roach     * @return bool
305a25f0a04SGreg Roach     */
306fa4036e8SGreg Roach    public function checkPassword(string $password): bool
307c1010edaSGreg Roach    {
308639e2984SGreg Roach        $password_hash = DB::table('user')
309639e2984SGreg Roach            ->where('user_id', '=', $this->user_id)
310639e2984SGreg Roach            ->value('password');
311a25f0a04SGreg Roach
312bbd8bd1bSGreg Roach        if ($password_hash !== null && password_verify($password, $password_hash)) {
313015c99a2SGreg Roach            if (password_needs_rehash($password_hash, PASSWORD_DEFAULT)) {
314a25f0a04SGreg Roach                $this->setPassword($password);
315a25f0a04SGreg Roach            }
316cbc1590aSGreg Roach
317a25f0a04SGreg Roach            return true;
318a25f0a04SGreg Roach        }
319b2ce94c6SRico Sonntag
320b2ce94c6SRico Sonntag        return false;
321a25f0a04SGreg Roach    }
322a25f0a04SGreg Roach
323a25f0a04SGreg Roach    /**
324f7fb7d41SGreg Roach     * Get a list of all managers.
325f7fb7d41SGreg Roach     *
326*8b67c11aSGreg Roach     * @return Collection|User[]
327f7fb7d41SGreg Roach     */
328*8b67c11aSGreg Roach    public static function managers(): Collection
329c1010edaSGreg Roach    {
330*8b67c11aSGreg Roach        return DB::table('user')
331639e2984SGreg Roach            ->join('user_gedcom_setting', function (JoinClause $join): void {
332639e2984SGreg Roach                $join
333639e2984SGreg Roach                    ->on('user_gedcom_setting.user_id', '=', 'user.user_id')
334639e2984SGreg Roach                    ->where('user_gedcom_setting.setting_name', '=', 'canedit')
335639e2984SGreg Roach                    ->where('user_gedcom_setting.setting_value', '=', 'admin');
336639e2984SGreg Roach            })
337639e2984SGreg Roach            ->where('user.user_id', '>', 0)
338639e2984SGreg Roach            ->orderBy('real_name')
339639e2984SGreg Roach            ->select(['user.user_id', 'user_name', 'real_name', 'email'])
340*8b67c11aSGreg Roach            ->get()
341*8b67c11aSGreg Roach            ->map(static::rowMapper());
342f7fb7d41SGreg Roach    }
343f7fb7d41SGreg Roach
344f7fb7d41SGreg Roach    /**
345f7fb7d41SGreg Roach     * Get a list of all moderators.
346f7fb7d41SGreg Roach     *
347*8b67c11aSGreg Roach     * @return Collection|User[]
348f7fb7d41SGreg Roach     */
349*8b67c11aSGreg Roach    public static function moderators(): Collection
350c1010edaSGreg Roach    {
351*8b67c11aSGreg Roach        return DB::table('user')
352639e2984SGreg Roach            ->join('user_gedcom_setting', function (JoinClause $join): void {
353639e2984SGreg Roach                $join
354639e2984SGreg Roach                    ->on('user_gedcom_setting.user_id', '=', 'user.user_id')
355639e2984SGreg Roach                    ->where('user_gedcom_setting.setting_name', '=', 'canedit')
356639e2984SGreg Roach                    ->where('user_gedcom_setting.setting_value', '=', 'accept');
357639e2984SGreg Roach            })
358639e2984SGreg Roach            ->where('user.user_id', '>', 0)
359639e2984SGreg Roach            ->orderBy('real_name')
360639e2984SGreg Roach            ->select(['user.user_id', 'user_name', 'real_name', 'email'])
361*8b67c11aSGreg Roach            ->get()
362*8b67c11aSGreg Roach            ->map(static::rowMapper());
363f7fb7d41SGreg Roach    }
364f7fb7d41SGreg Roach
365f7fb7d41SGreg Roach    /**
366f7fb7d41SGreg Roach     * Get a list of all verified users.
367f7fb7d41SGreg Roach     *
368*8b67c11aSGreg Roach     * @return Collection|User[]
369f7fb7d41SGreg Roach     */
370*8b67c11aSGreg Roach    public static function unapproved(): Collection
371c1010edaSGreg Roach    {
372*8b67c11aSGreg Roach        return DB::table('user')
373639e2984SGreg Roach            ->join('user_setting', function (JoinClause $join): void {
374639e2984SGreg Roach                $join
375639e2984SGreg Roach                    ->on('user_setting.user_id', '=', 'user.user_id')
376639e2984SGreg Roach                    ->where('user_setting.setting_name', '=', 'verified_by_admin')
377639e2984SGreg Roach                    ->where('user_setting.setting_value', '=', '0');
378639e2984SGreg Roach            })
379639e2984SGreg Roach            ->where('user.user_id', '>', 0)
380639e2984SGreg Roach            ->orderBy('real_name')
381639e2984SGreg Roach            ->select(['user.user_id', 'user_name', 'real_name', 'email'])
382*8b67c11aSGreg Roach            ->get()
383*8b67c11aSGreg Roach            ->map(static::rowMapper());
384f7fb7d41SGreg Roach    }
385f7fb7d41SGreg Roach
386f7fb7d41SGreg Roach    /**
387f7fb7d41SGreg Roach     * Get a list of all verified users.
388f7fb7d41SGreg Roach     *
389*8b67c11aSGreg Roach     * @return Collection|User[]
390f7fb7d41SGreg Roach     */
391*8b67c11aSGreg Roach    public static function unverified(): Collection
392c1010edaSGreg Roach    {
393*8b67c11aSGreg Roach        return DB::table('user')
394639e2984SGreg Roach            ->join('user_setting', function (JoinClause $join): void {
395639e2984SGreg Roach                $join
396639e2984SGreg Roach                    ->on('user_setting.user_id', '=', 'user.user_id')
397639e2984SGreg Roach                    ->where('user_setting.setting_name', '=', 'verified')
398639e2984SGreg Roach                    ->where('user_setting.setting_value', '=', '0');
399639e2984SGreg Roach            })
400639e2984SGreg Roach            ->where('user.user_id', '>', 0)
401639e2984SGreg Roach            ->orderBy('real_name')
402639e2984SGreg Roach            ->select(['user.user_id', 'user_name', 'real_name', 'email'])
403*8b67c11aSGreg Roach            ->get()
404*8b67c11aSGreg Roach            ->map(static::rowMapper());
405f7fb7d41SGreg Roach    }
406f7fb7d41SGreg Roach
407f7fb7d41SGreg Roach    /**
408f7fb7d41SGreg Roach     * Get a list of all users who are currently logged in.
409f7fb7d41SGreg Roach     *
410*8b67c11aSGreg Roach     * @return Collection|User[]
411f7fb7d41SGreg Roach     */
412*8b67c11aSGreg Roach    public static function allLoggedIn(): Collection
413c1010edaSGreg Roach    {
414*8b67c11aSGreg Roach        return DB::table('user')
415639e2984SGreg Roach            ->join('session', 'session.user_id', '=', 'user.user_id')
416639e2984SGreg Roach            ->where('user.user_id', '>', 0)
417639e2984SGreg Roach            ->orderBy('real_name')
418639e2984SGreg Roach            ->select(['user.user_id', 'user_name', 'real_name', 'email'])
419639e2984SGreg Roach            ->distinct()
420*8b67c11aSGreg Roach            ->get()
421*8b67c11aSGreg Roach            ->map(static::rowMapper());
422f7fb7d41SGreg Roach    }
423f7fb7d41SGreg Roach
424f7fb7d41SGreg Roach    /**
425a25f0a04SGreg Roach     * Get the numeric ID for this user.
426a25f0a04SGreg Roach     *
427c04dd3c1SGreg Roach     * @return int
428a25f0a04SGreg Roach     */
429c1010edaSGreg Roach    public function getUserId(): int
430c1010edaSGreg Roach    {
431a25f0a04SGreg Roach        return $this->user_id;
432a25f0a04SGreg Roach    }
433a25f0a04SGreg Roach
434a25f0a04SGreg Roach    /**
435a25f0a04SGreg Roach     * Get the login name for this user.
436a25f0a04SGreg Roach     *
437a25f0a04SGreg Roach     * @return string
438a25f0a04SGreg Roach     */
4398f53f488SRico Sonntag    public function getUserName(): string
440c1010edaSGreg Roach    {
441a25f0a04SGreg Roach        return $this->user_name;
442a25f0a04SGreg Roach    }
443a25f0a04SGreg Roach
444a25f0a04SGreg Roach    /**
445a25f0a04SGreg Roach     * Set the login name for this user.
446a25f0a04SGreg Roach     *
447a25f0a04SGreg Roach     * @param string $user_name
448a25f0a04SGreg Roach     *
449a25f0a04SGreg Roach     * @return $this
450a25f0a04SGreg Roach     */
4518f53f488SRico Sonntag    public function setUserName($user_name): self
452c1010edaSGreg Roach    {
453a25f0a04SGreg Roach        if ($this->user_name !== $user_name) {
454a25f0a04SGreg Roach            $this->user_name = $user_name;
45501461f86SGreg Roach
45601461f86SGreg Roach            DB::table('user')
45701461f86SGreg Roach                ->where('user_id', '=', $this->user_id)
45801461f86SGreg Roach                ->update([
45901461f86SGreg Roach                    'user_name' => $user_name,
460c1010edaSGreg Roach                ]);
461a25f0a04SGreg Roach        }
462a25f0a04SGreg Roach
463a25f0a04SGreg Roach        return $this;
464a25f0a04SGreg Roach    }
465a25f0a04SGreg Roach
466a25f0a04SGreg Roach    /**
467a25f0a04SGreg Roach     * Get the real name of this user.
468a25f0a04SGreg Roach     *
469a25f0a04SGreg Roach     * @return string
470a25f0a04SGreg Roach     */
4718f53f488SRico Sonntag    public function getRealName(): string
472c1010edaSGreg Roach    {
473a25f0a04SGreg Roach        return $this->real_name;
474a25f0a04SGreg Roach    }
475a25f0a04SGreg Roach
476a25f0a04SGreg Roach    /**
477a25f0a04SGreg Roach     * Set the real name of this user.
478a25f0a04SGreg Roach     *
479a25f0a04SGreg Roach     * @param string $real_name
480a25f0a04SGreg Roach     *
481a25f0a04SGreg Roach     * @return User
482a25f0a04SGreg Roach     */
4838f53f488SRico Sonntag    public function setRealName($real_name): User
484c1010edaSGreg Roach    {
485a25f0a04SGreg Roach        if ($this->real_name !== $real_name) {
486a25f0a04SGreg Roach            $this->real_name = $real_name;
48701461f86SGreg Roach
48801461f86SGreg Roach            DB::table('user')
48901461f86SGreg Roach                ->where('user_id', '=', $this->user_id)
49001461f86SGreg Roach                ->update([
49101461f86SGreg Roach                    'real_name' => $real_name,
492c1010edaSGreg Roach                ]);
493a25f0a04SGreg Roach        }
494a25f0a04SGreg Roach
495a25f0a04SGreg Roach        return $this;
496a25f0a04SGreg Roach    }
497a25f0a04SGreg Roach
498a25f0a04SGreg Roach    /**
499a25f0a04SGreg Roach     * Get the email address of this user.
500a25f0a04SGreg Roach     *
501a25f0a04SGreg Roach     * @return string
502a25f0a04SGreg Roach     */
5038f53f488SRico Sonntag    public function getEmail(): string
504c1010edaSGreg Roach    {
505a25f0a04SGreg Roach        return $this->email;
506a25f0a04SGreg Roach    }
507a25f0a04SGreg Roach
508a25f0a04SGreg Roach    /**
509a25f0a04SGreg Roach     * Set the email address of this user.
510a25f0a04SGreg Roach     *
511a25f0a04SGreg Roach     * @param string $email
512a25f0a04SGreg Roach     *
513a25f0a04SGreg Roach     * @return User
514a25f0a04SGreg Roach     */
5158f53f488SRico Sonntag    public function setEmail($email): User
516c1010edaSGreg Roach    {
517a25f0a04SGreg Roach        if ($this->email !== $email) {
518a25f0a04SGreg Roach            $this->email = $email;
51901461f86SGreg Roach
52001461f86SGreg Roach            DB::table('user')
52101461f86SGreg Roach                ->where('user_id', '=', $this->user_id)
52201461f86SGreg Roach                ->update([
52301461f86SGreg Roach                    'email' => $email,
524c1010edaSGreg Roach                ]);
525a25f0a04SGreg Roach        }
526a25f0a04SGreg Roach
527a25f0a04SGreg Roach        return $this;
528a25f0a04SGreg Roach    }
529a25f0a04SGreg Roach
530a25f0a04SGreg Roach    /**
531a25f0a04SGreg Roach     * Set the password of this user.
532a25f0a04SGreg Roach     *
533a25f0a04SGreg Roach     * @param string $password
534a25f0a04SGreg Roach     *
535a25f0a04SGreg Roach     * @return User
536a25f0a04SGreg Roach     */
5378f53f488SRico Sonntag    public function setPassword($password): User
538c1010edaSGreg Roach    {
53901461f86SGreg Roach        DB::table('user')
54001461f86SGreg Roach            ->where('user_id', '=', $this->user_id)
54101461f86SGreg Roach            ->update([
542015c99a2SGreg Roach                'password' => password_hash($password, PASSWORD_DEFAULT),
543015c99a2SGreg Roach            ]);
544a25f0a04SGreg Roach
545a25f0a04SGreg Roach        return $this;
546a25f0a04SGreg Roach    }
547a25f0a04SGreg Roach
548a25f0a04SGreg Roach    /**
549a25f0a04SGreg Roach     * Fetch a user option/setting from the wt_user_setting table.
550a25f0a04SGreg Roach     * Since we'll fetch several settings for each user, and since there aren’t
551a25f0a04SGreg Roach     * that many of them, fetch them all in one database query
552a25f0a04SGreg Roach     *
553a25f0a04SGreg Roach     * @param string $setting_name
55415d603e7SGreg Roach     * @param string $default
555a25f0a04SGreg Roach     *
55615d603e7SGreg Roach     * @return string
557a25f0a04SGreg Roach     */
5588f53f488SRico Sonntag    public function getPreference($setting_name, $default = ''): string
559c1010edaSGreg Roach    {
560c04dd3c1SGreg Roach        if (empty($this->preferences) && $this->user_id !== 0) {
56101461f86SGreg Roach            $this->preferences = DB::table('user_setting')
56201461f86SGreg Roach                ->where('user_id', '=', $this->user_id)
56301461f86SGreg Roach                ->pluck('setting_value', 'setting_name')
56401461f86SGreg Roach                ->all();
565a25f0a04SGreg Roach        }
566a25f0a04SGreg Roach
56701461f86SGreg Roach        return $this->preferences[$setting_name] ?? $default;
568a25f0a04SGreg Roach    }
569a25f0a04SGreg Roach
570a25f0a04SGreg Roach    /**
571a25f0a04SGreg Roach     * Update a setting for the user.
572a25f0a04SGreg Roach     *
573a25f0a04SGreg Roach     * @param string $setting_name
574a25f0a04SGreg Roach     * @param string $setting_value
575a25f0a04SGreg Roach     *
576a25f0a04SGreg Roach     * @return User
577a25f0a04SGreg Roach     */
5788f53f488SRico Sonntag    public function setPreference($setting_name, $setting_value): User
579c1010edaSGreg Roach    {
580c04dd3c1SGreg Roach        if ($this->user_id !== 0 && $this->getPreference($setting_name) !== $setting_value) {
58101461f86SGreg Roach            DB::table('user_setting')->updateOrInsert([
58201461f86SGreg Roach                'user_id'      => $this->user_id,
58301461f86SGreg Roach                'setting_name' => $setting_name,
58401461f86SGreg Roach            ], [
58501461f86SGreg Roach                'setting_value' => $setting_value,
586c1010edaSGreg Roach            ]);
58715d603e7SGreg Roach
588a25f0a04SGreg Roach            $this->preferences[$setting_name] = $setting_value;
589a25f0a04SGreg Roach        }
590a25f0a04SGreg Roach
591a25f0a04SGreg Roach        return $this;
592a25f0a04SGreg Roach    }
593a25f0a04SGreg Roach}
594