xref: /webtrees/app/User.php (revision c1010eda29c0909ed4d5d463f32d32bfefdd4dfe)
1a25f0a04SGreg Roach<?php
2a25f0a04SGreg Roach/**
3a25f0a04SGreg Roach * webtrees: online genealogy
41062a142SGreg Roach * Copyright (C) 2018 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
2060bc3e3fSGreg Roachuse stdclass;
2160bc3e3fSGreg Roach
22a25f0a04SGreg Roach/**
2376692c8bSGreg Roach * Provide an interface to the wt_user table.
24a25f0a04SGreg Roach */
25*c1010edaSGreg Roachclass User
26*c1010edaSGreg Roach{
27c04dd3c1SGreg Roach    /** @var  int The primary key of this user. */
28a25f0a04SGreg Roach    private $user_id;
29a25f0a04SGreg Roach
30a25f0a04SGreg Roach    /** @var  string The login name of this user. */
31a25f0a04SGreg Roach    private $user_name;
32a25f0a04SGreg Roach
33a25f0a04SGreg Roach    /** @var  string The real (display) name of this user. */
34a25f0a04SGreg Roach    private $real_name;
35a25f0a04SGreg Roach
36a25f0a04SGreg Roach    /** @var  string The email address of this user. */
37a25f0a04SGreg Roach    private $email;
38a25f0a04SGreg Roach
3915d603e7SGreg Roach    /** @var string[] Cached copy of the wt_user_setting table. */
4015d603e7SGreg Roach    private $preferences = [];
41a25f0a04SGreg Roach
42a25f0a04SGreg Roach    /** @var  User[] Only fetch users from the database once. */
4313abd6f3SGreg Roach    private static $cache = [];
44a25f0a04SGreg Roach
45a25f0a04SGreg Roach    /**
46f7fb7d41SGreg Roach     * Create a new user object from a row in the database.
47f7fb7d41SGreg Roach     *
48f7fb7d41SGreg Roach     * @param stdclass $user A row from the wt_user table
49f7fb7d41SGreg Roach     */
50*c1010edaSGreg Roach    public function __construct(stdClass $user)
51*c1010edaSGreg Roach    {
52c04dd3c1SGreg Roach        $this->user_id = (int)$user->user_id;
53f7fb7d41SGreg Roach        $this->user_name = $user->user_name;
54f7fb7d41SGreg Roach        $this->real_name = $user->real_name;
55f7fb7d41SGreg Roach        $this->email = $user->email;
56f7fb7d41SGreg Roach    }
57f7fb7d41SGreg Roach
58f7fb7d41SGreg Roach    /**
59f7fb7d41SGreg Roach     * Create a new user.
60f7fb7d41SGreg Roach     *
61f7fb7d41SGreg Roach     * The calling code needs to check for duplicates identifiers before calling
62f7fb7d41SGreg Roach     * this function.
63f7fb7d41SGreg Roach     *
64f7fb7d41SGreg Roach     * @param string $user_name
65f7fb7d41SGreg Roach     * @param string $real_name
66f7fb7d41SGreg Roach     * @param string $email
67f7fb7d41SGreg Roach     * @param string $password
68f7fb7d41SGreg Roach     *
69f7fb7d41SGreg Roach     * @return User
70f7fb7d41SGreg Roach     */
71*c1010edaSGreg Roach    public static function create($user_name, $real_name, $email, $password)
72*c1010edaSGreg Roach    {
73f7fb7d41SGreg Roach        Database::prepare(
74f7fb7d41SGreg Roach            "INSERT INTO `##user` (user_name, real_name, email, password) VALUES (:user_name, :real_name, :email, :password)"
75f7fb7d41SGreg Roach        )->execute([
76f7fb7d41SGreg Roach            'user_name' => $user_name,
77f7fb7d41SGreg Roach            'real_name' => $real_name,
78f7fb7d41SGreg Roach            'email'     => $email,
79f7fb7d41SGreg Roach            'password'  => password_hash($password, PASSWORD_DEFAULT),
80f7fb7d41SGreg Roach        ]);
81f7fb7d41SGreg Roach
82f7fb7d41SGreg Roach        // Set default blocks for this user
83f7fb7d41SGreg Roach        $user = self::findByIdentifier($user_name);
84f7fb7d41SGreg Roach        Database::prepare(
85f7fb7d41SGreg Roach            "INSERT INTO `##block` (`user_id`, `location`, `block_order`, `module_name`)" .
86f7fb7d41SGreg Roach            " SELECT :user_id , `location`, `block_order`, `module_name` FROM `##block` WHERE `user_id` = -1"
87f7fb7d41SGreg Roach        )->execute(['user_id' => $user->getUserId()]);
88f7fb7d41SGreg Roach
89f7fb7d41SGreg Roach        return $user;
90f7fb7d41SGreg Roach    }
91f7fb7d41SGreg Roach
92f7fb7d41SGreg Roach    /**
93f7fb7d41SGreg Roach     * Delete a user
94f7fb7d41SGreg Roach     */
95*c1010edaSGreg Roach    public function delete()
96*c1010edaSGreg Roach    {
97f7fb7d41SGreg Roach        // Don't delete the logs.
98f7fb7d41SGreg Roach        Database::prepare("UPDATE `##log` SET user_id=NULL WHERE user_id =?")->execute([$this->user_id]);
99f7fb7d41SGreg Roach        // Take over the user’s pending changes. (What else could we do with them?)
100f7fb7d41SGreg Roach        Database::prepare("DELETE FROM `##change` WHERE user_id=? AND status='rejected'")->execute([$this->user_id]);
101*c1010edaSGreg Roach        Database::prepare("UPDATE `##change` SET user_id=? WHERE user_id=?")->execute([
102*c1010edaSGreg Roach            Auth::id(),
103*c1010edaSGreg Roach            $this->user_id,
104*c1010edaSGreg Roach        ]);
105f7fb7d41SGreg Roach        Database::prepare("DELETE `##block_setting` FROM `##block_setting` JOIN `##block` USING (block_id) WHERE user_id=?")->execute([$this->user_id]);
106f7fb7d41SGreg Roach        Database::prepare("DELETE FROM `##block` WHERE user_id=?")->execute([$this->user_id]);
107f7fb7d41SGreg Roach        Database::prepare("DELETE FROM `##user_gedcom_setting` WHERE user_id=?")->execute([$this->user_id]);
1087ff5d33bSGreg Roach        Database::prepare("DELETE FROM `##gedcom_setting` WHERE setting_value=? AND setting_name IN ('CONTACT_USER_ID', 'WEBMASTER_USER_ID')")->execute([(string)$this->user_id]);
109f7fb7d41SGreg Roach        Database::prepare("DELETE FROM `##user_setting` WHERE user_id=?")->execute([$this->user_id]);
110f7fb7d41SGreg Roach        Database::prepare("DELETE FROM `##message` WHERE user_id=?")->execute([$this->user_id]);
111f7fb7d41SGreg Roach        Database::prepare("DELETE FROM `##user` WHERE user_id=?")->execute([$this->user_id]);
112f7fb7d41SGreg Roach    }
113f7fb7d41SGreg Roach
114f7fb7d41SGreg Roach    /**
115a25f0a04SGreg Roach     * Find the user with a specified user_id.
116a25f0a04SGreg Roach     *
117cbc1590aSGreg Roach     * @param int|null $user_id
118a25f0a04SGreg Roach     *
119a25f0a04SGreg Roach     * @return User|null
120a25f0a04SGreg Roach     */
121*c1010edaSGreg Roach    public static function find($user_id)
122*c1010edaSGreg Roach    {
123a25f0a04SGreg Roach        if (!array_key_exists($user_id, self::$cache)) {
124a25f0a04SGreg Roach            $row = Database::prepare(
125e5588fb0SGreg Roach                "SELECT user_id, user_name, real_name, email FROM `##user` WHERE user_id = ?"
12613abd6f3SGreg Roach            )->execute([$user_id])->fetchOneRow();
127a25f0a04SGreg Roach            if ($row) {
12806ef8e02SGreg Roach                self::$cache[$user_id] = new self($row);
129a25f0a04SGreg Roach            } else {
130a25f0a04SGreg Roach                self::$cache[$user_id] = null;
131a25f0a04SGreg Roach            }
132a25f0a04SGreg Roach        }
133a25f0a04SGreg Roach
134a25f0a04SGreg Roach        return self::$cache[$user_id];
135a25f0a04SGreg Roach    }
136a25f0a04SGreg Roach
137a25f0a04SGreg Roach    /**
138a982a56eSGreg Roach     * Find the user with a specified email address.
139a982a56eSGreg Roach     *
140a982a56eSGreg Roach     * @param string $email
141a982a56eSGreg Roach     *
142a982a56eSGreg Roach     * @return User|null
143a982a56eSGreg Roach     */
144*c1010edaSGreg Roach    public static function findByEmail($email)
145*c1010edaSGreg Roach    {
146a982a56eSGreg Roach        $user_id = Database::prepare(
147e5588fb0SGreg Roach            "SELECT user_id FROM `##user` WHERE email = :email"
14813abd6f3SGreg Roach        )->execute([
149a982a56eSGreg Roach            'email' => $email,
15013abd6f3SGreg Roach        ])->fetchOne();
151a982a56eSGreg Roach
152a982a56eSGreg Roach        return self::find($user_id);
153a982a56eSGreg Roach    }
154a982a56eSGreg Roach
155a982a56eSGreg Roach    /**
156a982a56eSGreg Roach     * Find the user with a specified user_name or email address.
157a25f0a04SGreg Roach     *
158a25f0a04SGreg Roach     * @param string $identifier
159a25f0a04SGreg Roach     *
160a25f0a04SGreg Roach     * @return User|null
161a25f0a04SGreg Roach     */
162*c1010edaSGreg Roach    public static function findByIdentifier($identifier)
163*c1010edaSGreg Roach    {
164a25f0a04SGreg Roach        $user_id = Database::prepare(
165e5588fb0SGreg Roach            "SELECT user_id FROM `##user` WHERE ? IN (user_name, email)"
16613abd6f3SGreg Roach        )->execute([$identifier])->fetchOne();
167a25f0a04SGreg Roach
168a25f0a04SGreg Roach        return self::find($user_id);
169a25f0a04SGreg Roach    }
170a25f0a04SGreg Roach
171a25f0a04SGreg Roach    /**
172a25f0a04SGreg Roach     * Find the user with a specified genealogy record.
173a25f0a04SGreg Roach     *
174a25f0a04SGreg Roach     * @param Individual $individual
175a25f0a04SGreg Roach     *
176a25f0a04SGreg Roach     * @return User|null
177a25f0a04SGreg Roach     */
178*c1010edaSGreg Roach    public static function findByIndividual(Individual $individual)
179*c1010edaSGreg Roach    {
180a25f0a04SGreg Roach        $user_id = Database::prepare(
181e5588fb0SGreg Roach            "SELECT user_id" .
182a25f0a04SGreg Roach            " FROM `##user_gedcom_setting`" .
183a5adda01SGreg Roach            " WHERE gedcom_id = :tree_id AND setting_name = 'gedcomid' AND setting_value = :xref"
18413abd6f3SGreg Roach        )->execute([
185a5adda01SGreg Roach            'tree_id' => $individual->getTree()->getTreeId(),
186cbc1590aSGreg Roach            'xref'    => $individual->getXref(),
18713abd6f3SGreg Roach        ])->fetchOne();
188a25f0a04SGreg Roach
189a25f0a04SGreg Roach        return self::find($user_id);
190a25f0a04SGreg Roach    }
191a25f0a04SGreg Roach
192a25f0a04SGreg Roach    /**
193f7fb7d41SGreg Roach     * Find the user with a specified user_name.
194f7fb7d41SGreg Roach     *
195f7fb7d41SGreg Roach     * @param string $user_name
196f7fb7d41SGreg Roach     *
197f7fb7d41SGreg Roach     * @return User|null
198f7fb7d41SGreg Roach     */
199*c1010edaSGreg Roach    public static function findByUserName($user_name)
200*c1010edaSGreg Roach    {
201f7fb7d41SGreg Roach        $user_id = Database::prepare(
202e5588fb0SGreg Roach            "SELECT user_id FROM `##user` WHERE user_name = :user_name"
203f7fb7d41SGreg Roach        )->execute([
204f7fb7d41SGreg Roach            'user_name' => $user_name,
205f7fb7d41SGreg Roach        ])->fetchOne();
206f7fb7d41SGreg Roach
207f7fb7d41SGreg Roach        return self::find($user_id);
208f7fb7d41SGreg Roach    }
209f7fb7d41SGreg Roach
210f7fb7d41SGreg Roach    /**
211a25f0a04SGreg Roach     * Find the latest user to register.
212a25f0a04SGreg Roach     *
213a25f0a04SGreg Roach     * @return User|null
214a25f0a04SGreg Roach     */
215*c1010edaSGreg Roach    public static function findLatestToRegister()
216*c1010edaSGreg Roach    {
217a25f0a04SGreg Roach        $user_id = Database::prepare(
218e5588fb0SGreg Roach            "SELECT u.user_id" .
219a25f0a04SGreg Roach            " FROM `##user` u" .
220a25f0a04SGreg Roach            " LEFT JOIN `##user_setting` us ON (u.user_id=us.user_id AND us.setting_name='reg_timestamp') " .
221a25f0a04SGreg Roach            " ORDER BY us.setting_value DESC LIMIT 1"
222a25f0a04SGreg Roach        )->execute()->fetchOne();
223a25f0a04SGreg Roach
224a25f0a04SGreg Roach        return self::find($user_id);
225a25f0a04SGreg Roach    }
226a25f0a04SGreg Roach
227a25f0a04SGreg Roach    /**
228a25f0a04SGreg Roach     * Get a list of all users.
229a25f0a04SGreg Roach     *
230a25f0a04SGreg Roach     * @return User[]
231a25f0a04SGreg Roach     */
232*c1010edaSGreg Roach    public static function all()
233*c1010edaSGreg Roach    {
234a25f0a04SGreg Roach        $rows = Database::prepare(
235e5588fb0SGreg Roach            "SELECT user_id, user_name, real_name, email" .
236a25f0a04SGreg Roach            " FROM `##user`" .
237a25f0a04SGreg Roach            " WHERE user_id > 0" .
238f7fb7d41SGreg Roach            " ORDER BY real_name"
239a25f0a04SGreg Roach        )->fetchAll();
240a25f0a04SGreg Roach
2418d68cabeSGreg Roach        return array_map(function ($row) {
2428d68cabeSGreg Roach            return new static($row);
2438d68cabeSGreg Roach        }, $rows);
244a25f0a04SGreg Roach    }
245a25f0a04SGreg Roach
246a25f0a04SGreg Roach    /**
247a25f0a04SGreg Roach     * Get a list of all administrators.
248a25f0a04SGreg Roach     *
249a25f0a04SGreg Roach     * @return User[]
250a25f0a04SGreg Roach     */
251*c1010edaSGreg Roach    public static function administrators()
252*c1010edaSGreg Roach    {
253a25f0a04SGreg Roach        $rows = Database::prepare(
254e5588fb0SGreg Roach            "SELECT user_id, user_name, real_name, email" .
255a25f0a04SGreg Roach            " FROM `##user`" .
256a25f0a04SGreg Roach            " JOIN `##user_setting` USING (user_id)" .
257f7fb7d41SGreg Roach            " WHERE user_id > 0 AND setting_name = 'canadmin' AND setting_value = '1'" .
258f7fb7d41SGreg Roach            " ORDER BY real_name"
259a25f0a04SGreg Roach        )->fetchAll();
260a25f0a04SGreg Roach
2618d68cabeSGreg Roach        return array_map(function ($row) {
2628d68cabeSGreg Roach            return new static($row);
2638d68cabeSGreg Roach        }, $rows);
264a25f0a04SGreg Roach    }
265a25f0a04SGreg Roach
266a25f0a04SGreg Roach    /** Validate a supplied password
267*c1010edaSGreg Roach     *
268a25f0a04SGreg Roach     * @param string $password
269a25f0a04SGreg Roach     *
270cbc1590aSGreg Roach     * @return bool
271a25f0a04SGreg Roach     */
272*c1010edaSGreg Roach    public function checkPassword($password)
273*c1010edaSGreg Roach    {
274a25f0a04SGreg Roach        $password_hash = Database::prepare(
275a25f0a04SGreg Roach            "SELECT password FROM `##user` WHERE user_id = ?"
27613abd6f3SGreg Roach        )->execute([$this->user_id])->fetchOne();
277a25f0a04SGreg Roach
278015c99a2SGreg Roach        if (password_verify($password, $password_hash)) {
279015c99a2SGreg Roach            if (password_needs_rehash($password_hash, PASSWORD_DEFAULT)) {
280a25f0a04SGreg Roach                $this->setPassword($password);
281a25f0a04SGreg Roach            }
282cbc1590aSGreg Roach
283a25f0a04SGreg Roach            return true;
284a25f0a04SGreg Roach        } else {
285a25f0a04SGreg Roach            return false;
286a25f0a04SGreg Roach        }
287a25f0a04SGreg Roach    }
288a25f0a04SGreg Roach
289a25f0a04SGreg Roach    /**
290f7fb7d41SGreg Roach     * Get a list of all managers.
291f7fb7d41SGreg Roach     *
292f7fb7d41SGreg Roach     * @return User[]
293f7fb7d41SGreg Roach     */
294*c1010edaSGreg Roach    public static function managers()
295*c1010edaSGreg Roach    {
296f7fb7d41SGreg Roach        $rows = Database::prepare(
297e5588fb0SGreg Roach            "SELECT user_id, user_name, real_name, email" .
298f7fb7d41SGreg Roach            " FROM `##user` JOIN `##user_gedcom_setting` USING (user_id)" .
299f7fb7d41SGreg Roach            " WHERE setting_name = 'canedit' AND setting_value='admin'" .
300f7fb7d41SGreg Roach            " GROUP BY user_id, real_name" .
301f7fb7d41SGreg Roach            " ORDER BY real_name"
302f7fb7d41SGreg Roach        )->fetchAll();
303f7fb7d41SGreg Roach
3048d68cabeSGreg Roach        return array_map(function ($row) {
3058d68cabeSGreg Roach            return new static($row);
3068d68cabeSGreg Roach        }, $rows);
307f7fb7d41SGreg Roach    }
308f7fb7d41SGreg Roach
309f7fb7d41SGreg Roach    /**
310f7fb7d41SGreg Roach     * Get a list of all moderators.
311f7fb7d41SGreg Roach     *
312f7fb7d41SGreg Roach     * @return User[]
313f7fb7d41SGreg Roach     */
314*c1010edaSGreg Roach    public static function moderators()
315*c1010edaSGreg Roach    {
316f7fb7d41SGreg Roach        $rows = Database::prepare(
317e5588fb0SGreg Roach            "SELECT user_id, user_name, real_name, email" .
318f7fb7d41SGreg Roach            " FROM `##user` JOIN `##user_gedcom_setting` USING (user_id)" .
319f7fb7d41SGreg Roach            " WHERE setting_name = 'canedit' AND setting_value='accept'" .
320f7fb7d41SGreg Roach            " GROUP BY user_id, real_name" .
321f7fb7d41SGreg Roach            " ORDER BY real_name"
322f7fb7d41SGreg Roach        )->fetchAll();
323f7fb7d41SGreg Roach
3248d68cabeSGreg Roach        return array_map(function ($row) {
3258d68cabeSGreg Roach            return new static($row);
3268d68cabeSGreg Roach        }, $rows);
327f7fb7d41SGreg Roach    }
328f7fb7d41SGreg Roach
329f7fb7d41SGreg Roach    /**
330f7fb7d41SGreg Roach     * Get a list of all verified users.
331f7fb7d41SGreg Roach     *
332f7fb7d41SGreg Roach     * @return User[]
333f7fb7d41SGreg Roach     */
334*c1010edaSGreg Roach    public static function unapproved()
335*c1010edaSGreg Roach    {
336f7fb7d41SGreg Roach        $rows = Database::prepare(
337e5588fb0SGreg Roach            "SELECT user_id, user_name, real_name, email" .
338f7fb7d41SGreg Roach            " FROM `##user` JOIN `##user_setting` USING (user_id)" .
339f7fb7d41SGreg Roach            " WHERE setting_name = 'verified_by_admin' AND setting_value = '0'" .
340f7fb7d41SGreg Roach            " ORDER BY real_name"
341f7fb7d41SGreg Roach        )->fetchAll();
342f7fb7d41SGreg Roach
3438d68cabeSGreg Roach        return array_map(function ($row) {
3448d68cabeSGreg Roach            return new static($row);
3458d68cabeSGreg Roach        }, $rows);
346f7fb7d41SGreg Roach    }
347f7fb7d41SGreg Roach
348f7fb7d41SGreg Roach    /**
349f7fb7d41SGreg Roach     * Get a list of all verified users.
350f7fb7d41SGreg Roach     *
351f7fb7d41SGreg Roach     * @return User[]
352f7fb7d41SGreg Roach     */
353*c1010edaSGreg Roach    public static function unverified()
354*c1010edaSGreg Roach    {
355f7fb7d41SGreg Roach        $rows = Database::prepare(
356e5588fb0SGreg Roach            "SELECT user_id, user_name, real_name, email" .
357f7fb7d41SGreg Roach            " FROM `##user` JOIN `##user_setting` USING (user_id)" .
358f7fb7d41SGreg Roach            " WHERE setting_name = 'verified' AND setting_value = '0'" .
359f7fb7d41SGreg Roach            " ORDER BY real_name"
360f7fb7d41SGreg Roach        )->fetchAll();
361f7fb7d41SGreg Roach
3628d68cabeSGreg Roach        return array_map(function ($row) {
3638d68cabeSGreg Roach            return new static($row);
3648d68cabeSGreg Roach        }, $rows);
365f7fb7d41SGreg Roach    }
366f7fb7d41SGreg Roach
367f7fb7d41SGreg Roach    /**
368f7fb7d41SGreg Roach     * Get a list of all users who are currently logged in.
369f7fb7d41SGreg Roach     *
370f7fb7d41SGreg Roach     * @return User[]
371f7fb7d41SGreg Roach     */
372*c1010edaSGreg Roach    public static function allLoggedIn()
373*c1010edaSGreg Roach    {
374f7fb7d41SGreg Roach        $rows = Database::prepare(
375e5588fb0SGreg Roach            "SELECT DISTINCT user_id, user_name, real_name, email" .
376f7fb7d41SGreg Roach            " FROM `##user`" .
377f7fb7d41SGreg Roach            " JOIN `##session` USING (user_id)"
378f7fb7d41SGreg Roach        )->fetchAll();
379f7fb7d41SGreg Roach
3808d68cabeSGreg Roach        return array_map(function ($row) {
3818d68cabeSGreg Roach            return new static($row);
3828d68cabeSGreg Roach        }, $rows);
383f7fb7d41SGreg Roach    }
384f7fb7d41SGreg Roach
385f7fb7d41SGreg Roach    /**
386a25f0a04SGreg Roach     * Get the numeric ID for this user.
387a25f0a04SGreg Roach     *
388c04dd3c1SGreg Roach     * @return int
389a25f0a04SGreg Roach     */
390*c1010edaSGreg Roach    public function getUserId(): int
391*c1010edaSGreg Roach    {
392a25f0a04SGreg Roach        return $this->user_id;
393a25f0a04SGreg Roach    }
394a25f0a04SGreg Roach
395a25f0a04SGreg Roach    /**
396a25f0a04SGreg Roach     * Get the login name for this user.
397a25f0a04SGreg Roach     *
398a25f0a04SGreg Roach     * @return string
399a25f0a04SGreg Roach     */
400*c1010edaSGreg Roach    public function getUserName()
401*c1010edaSGreg Roach    {
402a25f0a04SGreg Roach        return $this->user_name;
403a25f0a04SGreg Roach    }
404a25f0a04SGreg Roach
405a25f0a04SGreg Roach    /**
406a25f0a04SGreg Roach     * Set the login name for this user.
407a25f0a04SGreg Roach     *
408a25f0a04SGreg Roach     * @param string $user_name
409a25f0a04SGreg Roach     *
410a25f0a04SGreg Roach     * @return $this
411a25f0a04SGreg Roach     */
412*c1010edaSGreg Roach    public function setUserName($user_name)
413*c1010edaSGreg Roach    {
414a25f0a04SGreg Roach        if ($this->user_name !== $user_name) {
415a25f0a04SGreg Roach            $this->user_name = $user_name;
416a25f0a04SGreg Roach            Database::prepare(
417a25f0a04SGreg Roach                "UPDATE `##user` SET user_name = ? WHERE user_id = ?"
418*c1010edaSGreg Roach            )->execute([
419*c1010edaSGreg Roach                $user_name,
420*c1010edaSGreg Roach                $this->user_id,
421*c1010edaSGreg Roach            ]);
422a25f0a04SGreg Roach        }
423a25f0a04SGreg Roach
424a25f0a04SGreg Roach        return $this;
425a25f0a04SGreg Roach    }
426a25f0a04SGreg Roach
427a25f0a04SGreg Roach    /**
428a25f0a04SGreg Roach     * Get the real name of this user.
429a25f0a04SGreg Roach     *
430a25f0a04SGreg Roach     * @return string
431a25f0a04SGreg Roach     */
432*c1010edaSGreg Roach    public function getRealName()
433*c1010edaSGreg Roach    {
434a25f0a04SGreg Roach        return $this->real_name;
435a25f0a04SGreg Roach    }
436a25f0a04SGreg Roach
437a25f0a04SGreg Roach    /**
438a25f0a04SGreg Roach     * Set the real name of this user.
439a25f0a04SGreg Roach     *
440a25f0a04SGreg Roach     * @param string $real_name
441a25f0a04SGreg Roach     *
442a25f0a04SGreg Roach     * @return User
443a25f0a04SGreg Roach     */
444*c1010edaSGreg Roach    public function setRealName($real_name)
445*c1010edaSGreg Roach    {
446a25f0a04SGreg Roach        if ($this->real_name !== $real_name) {
447a25f0a04SGreg Roach            $this->real_name = $real_name;
448a25f0a04SGreg Roach            Database::prepare(
449a25f0a04SGreg Roach                "UPDATE `##user` SET real_name = ? WHERE user_id = ?"
450*c1010edaSGreg Roach            )->execute([
451*c1010edaSGreg Roach                $real_name,
452*c1010edaSGreg Roach                $this->user_id,
453*c1010edaSGreg Roach            ]);
454a25f0a04SGreg Roach        }
455a25f0a04SGreg Roach
456a25f0a04SGreg Roach        return $this;
457a25f0a04SGreg Roach    }
458a25f0a04SGreg Roach
459a25f0a04SGreg Roach    /**
460a25f0a04SGreg Roach     * Get the email address of this user.
461a25f0a04SGreg Roach     *
462a25f0a04SGreg Roach     * @return string
463a25f0a04SGreg Roach     */
464*c1010edaSGreg Roach    public function getEmail()
465*c1010edaSGreg Roach    {
466a25f0a04SGreg Roach        return $this->email;
467a25f0a04SGreg Roach    }
468a25f0a04SGreg Roach
469a25f0a04SGreg Roach    /**
470a25f0a04SGreg Roach     * Set the email address of this user.
471a25f0a04SGreg Roach     *
472a25f0a04SGreg Roach     * @param string $email
473a25f0a04SGreg Roach     *
474a25f0a04SGreg Roach     * @return User
475a25f0a04SGreg Roach     */
476*c1010edaSGreg Roach    public function setEmail($email)
477*c1010edaSGreg Roach    {
478a25f0a04SGreg Roach        if ($this->email !== $email) {
479a25f0a04SGreg Roach            $this->email = $email;
480a25f0a04SGreg Roach            Database::prepare(
481a25f0a04SGreg Roach                "UPDATE `##user` SET email = ? WHERE user_id = ?"
482*c1010edaSGreg Roach            )->execute([
483*c1010edaSGreg Roach                $email,
484*c1010edaSGreg Roach                $this->user_id,
485*c1010edaSGreg Roach            ]);
486a25f0a04SGreg Roach        }
487a25f0a04SGreg Roach
488a25f0a04SGreg Roach        return $this;
489a25f0a04SGreg Roach    }
490a25f0a04SGreg Roach
491a25f0a04SGreg Roach    /**
492a25f0a04SGreg Roach     * Set the password of this user.
493a25f0a04SGreg Roach     *
494a25f0a04SGreg Roach     * @param string $password
495a25f0a04SGreg Roach     *
496a25f0a04SGreg Roach     * @return User
497a25f0a04SGreg Roach     */
498*c1010edaSGreg Roach    public function setPassword($password)
499*c1010edaSGreg Roach    {
500a25f0a04SGreg Roach        Database::prepare(
501015c99a2SGreg Roach            "UPDATE `##user` SET password = :password WHERE user_id = :user_id"
502015c99a2SGreg Roach        )->execute([
503015c99a2SGreg Roach            'password' => password_hash($password, PASSWORD_DEFAULT),
504015c99a2SGreg Roach            'user_id'  => $this->user_id,
505015c99a2SGreg Roach        ]);
506a25f0a04SGreg Roach
507a25f0a04SGreg Roach        return $this;
508a25f0a04SGreg Roach    }
509a25f0a04SGreg Roach
510a25f0a04SGreg Roach    /**
511a25f0a04SGreg Roach     * Fetch a user option/setting from the wt_user_setting table.
512a25f0a04SGreg Roach     *
513a25f0a04SGreg Roach     * Since we'll fetch several settings for each user, and since there aren’t
514a25f0a04SGreg Roach     * that many of them, fetch them all in one database query
515a25f0a04SGreg Roach     *
516a25f0a04SGreg Roach     * @param string $setting_name
51715d603e7SGreg Roach     * @param string $default
518a25f0a04SGreg Roach     *
51915d603e7SGreg Roach     * @return string
520a25f0a04SGreg Roach     */
521*c1010edaSGreg Roach    public function getPreference($setting_name, $default = '')
522*c1010edaSGreg Roach    {
523c04dd3c1SGreg Roach        if (empty($this->preferences) && $this->user_id !== 0) {
524a25f0a04SGreg Roach            $this->preferences = Database::prepare(
525e5588fb0SGreg Roach                "SELECT setting_name, setting_value" .
52615d603e7SGreg Roach                " FROM `##user_setting`" .
52715d603e7SGreg Roach                " WHERE user_id = :user_id"
52815d603e7SGreg Roach            )->execute([
52915d603e7SGreg Roach                'user_id' => $this->user_id,
53015d603e7SGreg Roach            ])->fetchAssoc();
531a25f0a04SGreg Roach        }
532a25f0a04SGreg Roach
53315d603e7SGreg Roach        if (!array_key_exists($setting_name, $this->preferences)) {
53415d603e7SGreg Roach            $this->preferences[$setting_name] = $default;
535a25f0a04SGreg Roach        }
53615d603e7SGreg Roach
53715d603e7SGreg Roach        return $this->preferences[$setting_name];
538a25f0a04SGreg Roach    }
539a25f0a04SGreg Roach
540a25f0a04SGreg Roach    /**
541a25f0a04SGreg Roach     * Update a setting for the user.
542a25f0a04SGreg Roach     *
543a25f0a04SGreg Roach     * @param string $setting_name
544a25f0a04SGreg Roach     * @param string $setting_value
545a25f0a04SGreg Roach     *
546a25f0a04SGreg Roach     * @return User
547a25f0a04SGreg Roach     */
548*c1010edaSGreg Roach    public function setPreference($setting_name, $setting_value)
549*c1010edaSGreg Roach    {
550c04dd3c1SGreg Roach        if ($this->user_id !== 0 && $this->getPreference($setting_name) !== $setting_value) {
551a25f0a04SGreg Roach            Database::prepare("REPLACE INTO `##user_setting` (user_id, setting_name, setting_value) VALUES (?, ?, LEFT(?, 255))")
552*c1010edaSGreg Roach                ->execute([
553*c1010edaSGreg Roach                    $this->user_id,
554*c1010edaSGreg Roach                    $setting_name,
555*c1010edaSGreg Roach                    $setting_value,
556*c1010edaSGreg Roach                ]);
55715d603e7SGreg Roach
558a25f0a04SGreg Roach            $this->preferences[$setting_name] = $setting_value;
559a25f0a04SGreg Roach        }
560a25f0a04SGreg Roach
561a25f0a04SGreg Roach        return $this;
562a25f0a04SGreg Roach    }
563a25f0a04SGreg Roach}
564