xref: /webtrees/app/User.php (revision fa4036e8df4c01f079954ed7162507a57cf4a62c)
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
20b0b72ea4SGreg Roachuse stdClass;
2160bc3e3fSGreg Roach
22a25f0a04SGreg Roach/**
2376692c8bSGreg Roach * Provide an interface to the wt_user table.
24a25f0a04SGreg Roach */
25c1010edaSGreg Roachclass User
26c1010edaSGreg 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     *
48b0b72ea4SGreg Roach     * @param stdClass $user A row from the wt_user table
49f7fb7d41SGreg Roach     */
50c1010edaSGreg Roach    public function __construct(stdClass $user)
51c1010edaSGreg 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     * The calling code needs to check for duplicates identifiers before calling
61f7fb7d41SGreg Roach     * this function.
62f7fb7d41SGreg Roach     *
63f7fb7d41SGreg Roach     * @param string $user_name
64f7fb7d41SGreg Roach     * @param string $real_name
65f7fb7d41SGreg Roach     * @param string $email
66f7fb7d41SGreg Roach     * @param string $password
67f7fb7d41SGreg Roach     *
68f7fb7d41SGreg Roach     * @return User
69f7fb7d41SGreg Roach     */
70c1010edaSGreg Roach    public static function create($user_name, $real_name, $email, $password)
71c1010edaSGreg Roach    {
72f7fb7d41SGreg Roach        Database::prepare(
73f7fb7d41SGreg Roach            "INSERT INTO `##user` (user_name, real_name, email, password) VALUES (:user_name, :real_name, :email, :password)"
74f7fb7d41SGreg Roach        )->execute([
75f7fb7d41SGreg Roach            'user_name' => $user_name,
76f7fb7d41SGreg Roach            'real_name' => $real_name,
77f7fb7d41SGreg Roach            'email'     => $email,
78f7fb7d41SGreg Roach            'password'  => password_hash($password, PASSWORD_DEFAULT),
79f7fb7d41SGreg Roach        ]);
80f7fb7d41SGreg Roach
81f7fb7d41SGreg Roach        // Set default blocks for this user
82f7fb7d41SGreg Roach        $user = self::findByIdentifier($user_name);
83f7fb7d41SGreg Roach        Database::prepare(
84f7fb7d41SGreg Roach            "INSERT INTO `##block` (`user_id`, `location`, `block_order`, `module_name`)" .
85f7fb7d41SGreg Roach            " SELECT :user_id , `location`, `block_order`, `module_name` FROM `##block` WHERE `user_id` = -1"
86*fa4036e8SGreg Roach        )->execute([
87*fa4036e8SGreg Roach            'user_id' => $user->getUserId(),
88*fa4036e8SGreg Roach        ]);
89f7fb7d41SGreg Roach
90f7fb7d41SGreg Roach        return $user;
91f7fb7d41SGreg Roach    }
92f7fb7d41SGreg Roach
93f7fb7d41SGreg Roach    /**
94f7fb7d41SGreg Roach     * Delete a user
95*fa4036e8SGreg Roach     *
96*fa4036e8SGreg Roach     * @return void
97f7fb7d41SGreg Roach     */
98c1010edaSGreg Roach    public function delete()
99c1010edaSGreg Roach    {
100f7fb7d41SGreg Roach        // Don't delete the logs.
101f7fb7d41SGreg Roach        Database::prepare("UPDATE `##log` SET user_id=NULL WHERE user_id =?")->execute([$this->user_id]);
102f7fb7d41SGreg Roach        // Take over the user’s pending changes. (What else could we do with them?)
103f7fb7d41SGreg Roach        Database::prepare("DELETE FROM `##change` WHERE user_id=? AND status='rejected'")->execute([$this->user_id]);
104c1010edaSGreg Roach        Database::prepare("UPDATE `##change` SET user_id=? WHERE user_id=?")->execute([
105c1010edaSGreg Roach            Auth::id(),
106c1010edaSGreg Roach            $this->user_id,
107c1010edaSGreg Roach        ]);
108f7fb7d41SGreg Roach        Database::prepare("DELETE `##block_setting` FROM `##block_setting` JOIN `##block` USING (block_id) WHERE user_id=?")->execute([$this->user_id]);
109f7fb7d41SGreg Roach        Database::prepare("DELETE FROM `##block` WHERE user_id=?")->execute([$this->user_id]);
110f7fb7d41SGreg Roach        Database::prepare("DELETE FROM `##user_gedcom_setting` WHERE user_id=?")->execute([$this->user_id]);
1117ff5d33bSGreg 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]);
112f7fb7d41SGreg Roach        Database::prepare("DELETE FROM `##user_setting` WHERE user_id=?")->execute([$this->user_id]);
113f7fb7d41SGreg Roach        Database::prepare("DELETE FROM `##message` WHERE user_id=?")->execute([$this->user_id]);
114f7fb7d41SGreg Roach        Database::prepare("DELETE FROM `##user` WHERE user_id=?")->execute([$this->user_id]);
115f7fb7d41SGreg Roach    }
116f7fb7d41SGreg Roach
117f7fb7d41SGreg Roach    /**
118a25f0a04SGreg Roach     * Find the user with a specified user_id.
119a25f0a04SGreg Roach     *
120cbc1590aSGreg Roach     * @param int|null $user_id
121a25f0a04SGreg Roach     *
122a25f0a04SGreg Roach     * @return User|null
123a25f0a04SGreg Roach     */
124c1010edaSGreg Roach    public static function find($user_id)
125c1010edaSGreg Roach    {
126a25f0a04SGreg Roach        if (!array_key_exists($user_id, self::$cache)) {
127a25f0a04SGreg Roach            $row = Database::prepare(
128e5588fb0SGreg Roach                "SELECT user_id, user_name, real_name, email FROM `##user` WHERE user_id = ?"
12913abd6f3SGreg Roach            )->execute([$user_id])->fetchOneRow();
130a25f0a04SGreg Roach            if ($row) {
13106ef8e02SGreg Roach                self::$cache[$user_id] = new self($row);
132a25f0a04SGreg Roach            } else {
133a25f0a04SGreg Roach                self::$cache[$user_id] = null;
134a25f0a04SGreg Roach            }
135a25f0a04SGreg Roach        }
136a25f0a04SGreg Roach
137a25f0a04SGreg Roach        return self::$cache[$user_id];
138a25f0a04SGreg Roach    }
139a25f0a04SGreg Roach
140a25f0a04SGreg Roach    /**
141a982a56eSGreg Roach     * Find the user with a specified email address.
142a982a56eSGreg Roach     *
143a982a56eSGreg Roach     * @param string $email
144a982a56eSGreg Roach     *
145a982a56eSGreg Roach     * @return User|null
146a982a56eSGreg Roach     */
147c1010edaSGreg Roach    public static function findByEmail($email)
148c1010edaSGreg Roach    {
149*fa4036e8SGreg Roach        $user_id = (int) Database::prepare(
150e5588fb0SGreg Roach            "SELECT user_id FROM `##user` WHERE email = :email"
15113abd6f3SGreg Roach        )->execute([
152a982a56eSGreg Roach            'email' => $email,
15313abd6f3SGreg Roach        ])->fetchOne();
154a982a56eSGreg Roach
155a982a56eSGreg Roach        return self::find($user_id);
156a982a56eSGreg Roach    }
157a982a56eSGreg Roach
158a982a56eSGreg Roach    /**
159a982a56eSGreg Roach     * Find the user with a specified user_name or email address.
160a25f0a04SGreg Roach     *
161a25f0a04SGreg Roach     * @param string $identifier
162a25f0a04SGreg Roach     *
163a25f0a04SGreg Roach     * @return User|null
164a25f0a04SGreg Roach     */
165c1010edaSGreg Roach    public static function findByIdentifier($identifier)
166c1010edaSGreg Roach    {
167*fa4036e8SGreg Roach        $user_id = (int) Database::prepare(
168e5588fb0SGreg Roach            "SELECT user_id FROM `##user` WHERE ? IN (user_name, email)"
16913abd6f3SGreg Roach        )->execute([$identifier])->fetchOne();
170a25f0a04SGreg Roach
171a25f0a04SGreg Roach        return self::find($user_id);
172a25f0a04SGreg Roach    }
173a25f0a04SGreg Roach
174a25f0a04SGreg Roach    /**
175a25f0a04SGreg Roach     * Find the user with a specified genealogy record.
176a25f0a04SGreg Roach     *
177a25f0a04SGreg Roach     * @param Individual $individual
178a25f0a04SGreg Roach     *
179a25f0a04SGreg Roach     * @return User|null
180a25f0a04SGreg Roach     */
181c1010edaSGreg Roach    public static function findByIndividual(Individual $individual)
182c1010edaSGreg Roach    {
183*fa4036e8SGreg Roach        $user_id = (int) Database::prepare(
184e5588fb0SGreg Roach            "SELECT user_id" .
185a25f0a04SGreg Roach            " FROM `##user_gedcom_setting`" .
186a5adda01SGreg Roach            " WHERE gedcom_id = :tree_id AND setting_name = 'gedcomid' AND setting_value = :xref"
18713abd6f3SGreg Roach        )->execute([
188a5adda01SGreg Roach            'tree_id' => $individual->getTree()->getTreeId(),
189cbc1590aSGreg Roach            'xref'    => $individual->getXref(),
19013abd6f3SGreg Roach        ])->fetchOne();
191a25f0a04SGreg Roach
192a25f0a04SGreg Roach        return self::find($user_id);
193a25f0a04SGreg Roach    }
194a25f0a04SGreg Roach
195a25f0a04SGreg Roach    /**
196f7fb7d41SGreg Roach     * Find the user with a specified user_name.
197f7fb7d41SGreg Roach     *
198f7fb7d41SGreg Roach     * @param string $user_name
199f7fb7d41SGreg Roach     *
200f7fb7d41SGreg Roach     * @return User|null
201f7fb7d41SGreg Roach     */
202c1010edaSGreg Roach    public static function findByUserName($user_name)
203c1010edaSGreg Roach    {
204*fa4036e8SGreg Roach        $user_id = (int) Database::prepare(
205e5588fb0SGreg Roach            "SELECT user_id FROM `##user` WHERE user_name = :user_name"
206f7fb7d41SGreg Roach        )->execute([
207f7fb7d41SGreg Roach            'user_name' => $user_name,
208f7fb7d41SGreg Roach        ])->fetchOne();
209f7fb7d41SGreg Roach
210f7fb7d41SGreg Roach        return self::find($user_id);
211f7fb7d41SGreg Roach    }
212f7fb7d41SGreg Roach
213f7fb7d41SGreg Roach    /**
214a25f0a04SGreg Roach     * Find the latest user to register.
215a25f0a04SGreg Roach     *
216a25f0a04SGreg Roach     * @return User|null
217a25f0a04SGreg Roach     */
218c1010edaSGreg Roach    public static function findLatestToRegister()
219c1010edaSGreg Roach    {
220*fa4036e8SGreg Roach        $user_id = (int) Database::prepare(
221e5588fb0SGreg Roach            "SELECT u.user_id" .
222a25f0a04SGreg Roach            " FROM `##user` u" .
223a25f0a04SGreg Roach            " LEFT JOIN `##user_setting` us ON (u.user_id=us.user_id AND us.setting_name='reg_timestamp') " .
224a25f0a04SGreg Roach            " ORDER BY us.setting_value DESC LIMIT 1"
225a25f0a04SGreg Roach        )->execute()->fetchOne();
226a25f0a04SGreg Roach
227a25f0a04SGreg Roach        return self::find($user_id);
228a25f0a04SGreg Roach    }
229a25f0a04SGreg Roach
230a25f0a04SGreg Roach    /**
231a25f0a04SGreg Roach     * Get a list of all users.
232a25f0a04SGreg Roach     *
233a25f0a04SGreg Roach     * @return User[]
234a25f0a04SGreg Roach     */
235*fa4036e8SGreg Roach    public static function all(): array
236c1010edaSGreg Roach    {
237a25f0a04SGreg Roach        $rows = Database::prepare(
238e5588fb0SGreg Roach            "SELECT user_id, user_name, real_name, email" .
239a25f0a04SGreg Roach            " FROM `##user`" .
240a25f0a04SGreg Roach            " WHERE user_id > 0" .
241f7fb7d41SGreg Roach            " ORDER BY real_name"
242a25f0a04SGreg Roach        )->fetchAll();
243a25f0a04SGreg Roach
2448d68cabeSGreg Roach        return array_map(function ($row) {
2458d68cabeSGreg Roach            return new static($row);
2468d68cabeSGreg Roach        }, $rows);
247a25f0a04SGreg Roach    }
248a25f0a04SGreg Roach
249a25f0a04SGreg Roach    /**
250a25f0a04SGreg Roach     * Get a list of all administrators.
251a25f0a04SGreg Roach     *
252a25f0a04SGreg Roach     * @return User[]
253a25f0a04SGreg Roach     */
254*fa4036e8SGreg Roach    public static function administrators(): array
255c1010edaSGreg Roach    {
256a25f0a04SGreg Roach        $rows = Database::prepare(
257e5588fb0SGreg Roach            "SELECT user_id, user_name, real_name, email" .
258a25f0a04SGreg Roach            " FROM `##user`" .
259a25f0a04SGreg Roach            " JOIN `##user_setting` USING (user_id)" .
260f7fb7d41SGreg Roach            " WHERE user_id > 0 AND setting_name = 'canadmin' AND setting_value = '1'" .
261f7fb7d41SGreg Roach            " ORDER BY real_name"
262a25f0a04SGreg Roach        )->fetchAll();
263a25f0a04SGreg Roach
264*fa4036e8SGreg Roach        return array_map(function (stdClass $row) {
2658d68cabeSGreg Roach            return new static($row);
2668d68cabeSGreg Roach        }, $rows);
267a25f0a04SGreg Roach    }
268a25f0a04SGreg Roach
269*fa4036e8SGreg Roach    /**
270*fa4036e8SGreg Roach     * Validate a supplied password
271c1010edaSGreg Roach     *
272a25f0a04SGreg Roach     * @param string $password
273a25f0a04SGreg Roach     *
274cbc1590aSGreg Roach     * @return bool
275a25f0a04SGreg Roach     */
276*fa4036e8SGreg Roach    public function checkPassword(string $password): bool
277c1010edaSGreg Roach    {
278a25f0a04SGreg Roach        $password_hash = Database::prepare(
279a25f0a04SGreg Roach            "SELECT password FROM `##user` WHERE user_id = ?"
28013abd6f3SGreg Roach        )->execute([$this->user_id])->fetchOne();
281a25f0a04SGreg Roach
282015c99a2SGreg Roach        if (password_verify($password, $password_hash)) {
283015c99a2SGreg Roach            if (password_needs_rehash($password_hash, PASSWORD_DEFAULT)) {
284a25f0a04SGreg Roach                $this->setPassword($password);
285a25f0a04SGreg Roach            }
286cbc1590aSGreg Roach
287a25f0a04SGreg Roach            return true;
288a25f0a04SGreg Roach        } else {
289a25f0a04SGreg Roach            return false;
290a25f0a04SGreg Roach        }
291a25f0a04SGreg Roach    }
292a25f0a04SGreg Roach
293a25f0a04SGreg Roach    /**
294f7fb7d41SGreg Roach     * Get a list of all managers.
295f7fb7d41SGreg Roach     *
296f7fb7d41SGreg Roach     * @return User[]
297f7fb7d41SGreg Roach     */
298*fa4036e8SGreg Roach    public static function managers(): array
299c1010edaSGreg Roach    {
300f7fb7d41SGreg Roach        $rows = Database::prepare(
301e5588fb0SGreg Roach            "SELECT user_id, user_name, real_name, email" .
302f7fb7d41SGreg Roach            " FROM `##user` JOIN `##user_gedcom_setting` USING (user_id)" .
303f7fb7d41SGreg Roach            " WHERE setting_name = 'canedit' AND setting_value='admin'" .
304f7fb7d41SGreg Roach            " GROUP BY user_id, real_name" .
305f7fb7d41SGreg Roach            " ORDER BY real_name"
306f7fb7d41SGreg Roach        )->fetchAll();
307f7fb7d41SGreg Roach
308*fa4036e8SGreg Roach        return array_map(function (stdClass $row) {
3098d68cabeSGreg Roach            return new static($row);
3108d68cabeSGreg Roach        }, $rows);
311f7fb7d41SGreg Roach    }
312f7fb7d41SGreg Roach
313f7fb7d41SGreg Roach    /**
314f7fb7d41SGreg Roach     * Get a list of all moderators.
315f7fb7d41SGreg Roach     *
316f7fb7d41SGreg Roach     * @return User[]
317f7fb7d41SGreg Roach     */
318*fa4036e8SGreg Roach    public static function moderators(): array
319c1010edaSGreg Roach    {
320f7fb7d41SGreg Roach        $rows = Database::prepare(
321e5588fb0SGreg Roach            "SELECT user_id, user_name, real_name, email" .
322f7fb7d41SGreg Roach            " FROM `##user` JOIN `##user_gedcom_setting` USING (user_id)" .
323f7fb7d41SGreg Roach            " WHERE setting_name = 'canedit' AND setting_value='accept'" .
324f7fb7d41SGreg Roach            " GROUP BY user_id, real_name" .
325f7fb7d41SGreg Roach            " ORDER BY real_name"
326f7fb7d41SGreg Roach        )->fetchAll();
327f7fb7d41SGreg Roach
328*fa4036e8SGreg Roach        return array_map(function (stdClass $row) {
3298d68cabeSGreg Roach            return new static($row);
3308d68cabeSGreg Roach        }, $rows);
331f7fb7d41SGreg Roach    }
332f7fb7d41SGreg Roach
333f7fb7d41SGreg Roach    /**
334f7fb7d41SGreg Roach     * Get a list of all verified users.
335f7fb7d41SGreg Roach     *
336f7fb7d41SGreg Roach     * @return User[]
337f7fb7d41SGreg Roach     */
338*fa4036e8SGreg Roach    public static function unapproved(): array
339c1010edaSGreg Roach    {
340f7fb7d41SGreg Roach        $rows = Database::prepare(
341e5588fb0SGreg Roach            "SELECT user_id, user_name, real_name, email" .
342f7fb7d41SGreg Roach            " FROM `##user` JOIN `##user_setting` USING (user_id)" .
343f7fb7d41SGreg Roach            " WHERE setting_name = 'verified_by_admin' AND setting_value = '0'" .
344f7fb7d41SGreg Roach            " ORDER BY real_name"
345f7fb7d41SGreg Roach        )->fetchAll();
346f7fb7d41SGreg Roach
347*fa4036e8SGreg Roach        return array_map(function (stdClass $row) {
3488d68cabeSGreg Roach            return new static($row);
3498d68cabeSGreg Roach        }, $rows);
350f7fb7d41SGreg Roach    }
351f7fb7d41SGreg Roach
352f7fb7d41SGreg Roach    /**
353f7fb7d41SGreg Roach     * Get a list of all verified users.
354f7fb7d41SGreg Roach     *
355f7fb7d41SGreg Roach     * @return User[]
356f7fb7d41SGreg Roach     */
357*fa4036e8SGreg Roach    public static function unverified(): array
358c1010edaSGreg Roach    {
359f7fb7d41SGreg Roach        $rows = Database::prepare(
360e5588fb0SGreg Roach            "SELECT user_id, user_name, real_name, email" .
361f7fb7d41SGreg Roach            " FROM `##user` JOIN `##user_setting` USING (user_id)" .
362f7fb7d41SGreg Roach            " WHERE setting_name = 'verified' AND setting_value = '0'" .
363f7fb7d41SGreg Roach            " ORDER BY real_name"
364f7fb7d41SGreg Roach        )->fetchAll();
365f7fb7d41SGreg Roach
366*fa4036e8SGreg Roach        return array_map(function (stdClass $row) {
3678d68cabeSGreg Roach            return new static($row);
3688d68cabeSGreg Roach        }, $rows);
369f7fb7d41SGreg Roach    }
370f7fb7d41SGreg Roach
371f7fb7d41SGreg Roach    /**
372f7fb7d41SGreg Roach     * Get a list of all users who are currently logged in.
373f7fb7d41SGreg Roach     *
374f7fb7d41SGreg Roach     * @return User[]
375f7fb7d41SGreg Roach     */
376*fa4036e8SGreg Roach    public static function allLoggedIn(): array
377c1010edaSGreg Roach    {
378f7fb7d41SGreg Roach        $rows = Database::prepare(
379e5588fb0SGreg Roach            "SELECT DISTINCT user_id, user_name, real_name, email" .
380f7fb7d41SGreg Roach            " FROM `##user`" .
381f7fb7d41SGreg Roach            " JOIN `##session` USING (user_id)"
382f7fb7d41SGreg Roach        )->fetchAll();
383f7fb7d41SGreg Roach
384*fa4036e8SGreg Roach        return array_map(function (stdClass $row) {
3858d68cabeSGreg Roach            return new static($row);
3868d68cabeSGreg Roach        }, $rows);
387f7fb7d41SGreg Roach    }
388f7fb7d41SGreg Roach
389f7fb7d41SGreg Roach    /**
390a25f0a04SGreg Roach     * Get the numeric ID for this user.
391a25f0a04SGreg Roach     *
392c04dd3c1SGreg Roach     * @return int
393a25f0a04SGreg Roach     */
394c1010edaSGreg Roach    public function getUserId(): int
395c1010edaSGreg Roach    {
396a25f0a04SGreg Roach        return $this->user_id;
397a25f0a04SGreg Roach    }
398a25f0a04SGreg Roach
399a25f0a04SGreg Roach    /**
400a25f0a04SGreg Roach     * Get the login name for this user.
401a25f0a04SGreg Roach     *
402a25f0a04SGreg Roach     * @return string
403a25f0a04SGreg Roach     */
404c1010edaSGreg Roach    public function getUserName()
405c1010edaSGreg Roach    {
406a25f0a04SGreg Roach        return $this->user_name;
407a25f0a04SGreg Roach    }
408a25f0a04SGreg Roach
409a25f0a04SGreg Roach    /**
410a25f0a04SGreg Roach     * Set the login name for this user.
411a25f0a04SGreg Roach     *
412a25f0a04SGreg Roach     * @param string $user_name
413a25f0a04SGreg Roach     *
414a25f0a04SGreg Roach     * @return $this
415a25f0a04SGreg Roach     */
416c1010edaSGreg Roach    public function setUserName($user_name)
417c1010edaSGreg Roach    {
418a25f0a04SGreg Roach        if ($this->user_name !== $user_name) {
419a25f0a04SGreg Roach            $this->user_name = $user_name;
420a25f0a04SGreg Roach            Database::prepare(
421a25f0a04SGreg Roach                "UPDATE `##user` SET user_name = ? WHERE user_id = ?"
422c1010edaSGreg Roach            )->execute([
423c1010edaSGreg Roach                $user_name,
424c1010edaSGreg Roach                $this->user_id,
425c1010edaSGreg Roach            ]);
426a25f0a04SGreg Roach        }
427a25f0a04SGreg Roach
428a25f0a04SGreg Roach        return $this;
429a25f0a04SGreg Roach    }
430a25f0a04SGreg Roach
431a25f0a04SGreg Roach    /**
432a25f0a04SGreg Roach     * Get the real name of this user.
433a25f0a04SGreg Roach     *
434a25f0a04SGreg Roach     * @return string
435a25f0a04SGreg Roach     */
436c1010edaSGreg Roach    public function getRealName()
437c1010edaSGreg Roach    {
438a25f0a04SGreg Roach        return $this->real_name;
439a25f0a04SGreg Roach    }
440a25f0a04SGreg Roach
441a25f0a04SGreg Roach    /**
442a25f0a04SGreg Roach     * Set the real name of this user.
443a25f0a04SGreg Roach     *
444a25f0a04SGreg Roach     * @param string $real_name
445a25f0a04SGreg Roach     *
446a25f0a04SGreg Roach     * @return User
447a25f0a04SGreg Roach     */
448c1010edaSGreg Roach    public function setRealName($real_name)
449c1010edaSGreg Roach    {
450a25f0a04SGreg Roach        if ($this->real_name !== $real_name) {
451a25f0a04SGreg Roach            $this->real_name = $real_name;
452a25f0a04SGreg Roach            Database::prepare(
453a25f0a04SGreg Roach                "UPDATE `##user` SET real_name = ? WHERE user_id = ?"
454c1010edaSGreg Roach            )->execute([
455c1010edaSGreg Roach                $real_name,
456c1010edaSGreg Roach                $this->user_id,
457c1010edaSGreg Roach            ]);
458a25f0a04SGreg Roach        }
459a25f0a04SGreg Roach
460a25f0a04SGreg Roach        return $this;
461a25f0a04SGreg Roach    }
462a25f0a04SGreg Roach
463a25f0a04SGreg Roach    /**
464a25f0a04SGreg Roach     * Get the email address of this user.
465a25f0a04SGreg Roach     *
466a25f0a04SGreg Roach     * @return string
467a25f0a04SGreg Roach     */
468c1010edaSGreg Roach    public function getEmail()
469c1010edaSGreg Roach    {
470a25f0a04SGreg Roach        return $this->email;
471a25f0a04SGreg Roach    }
472a25f0a04SGreg Roach
473a25f0a04SGreg Roach    /**
474a25f0a04SGreg Roach     * Set the email address of this user.
475a25f0a04SGreg Roach     *
476a25f0a04SGreg Roach     * @param string $email
477a25f0a04SGreg Roach     *
478a25f0a04SGreg Roach     * @return User
479a25f0a04SGreg Roach     */
480c1010edaSGreg Roach    public function setEmail($email)
481c1010edaSGreg Roach    {
482a25f0a04SGreg Roach        if ($this->email !== $email) {
483a25f0a04SGreg Roach            $this->email = $email;
484a25f0a04SGreg Roach            Database::prepare(
485a25f0a04SGreg Roach                "UPDATE `##user` SET email = ? WHERE user_id = ?"
486c1010edaSGreg Roach            )->execute([
487c1010edaSGreg Roach                $email,
488c1010edaSGreg Roach                $this->user_id,
489c1010edaSGreg Roach            ]);
490a25f0a04SGreg Roach        }
491a25f0a04SGreg Roach
492a25f0a04SGreg Roach        return $this;
493a25f0a04SGreg Roach    }
494a25f0a04SGreg Roach
495a25f0a04SGreg Roach    /**
496a25f0a04SGreg Roach     * Set the password of this user.
497a25f0a04SGreg Roach     *
498a25f0a04SGreg Roach     * @param string $password
499a25f0a04SGreg Roach     *
500a25f0a04SGreg Roach     * @return User
501a25f0a04SGreg Roach     */
502c1010edaSGreg Roach    public function setPassword($password)
503c1010edaSGreg Roach    {
504a25f0a04SGreg Roach        Database::prepare(
505015c99a2SGreg Roach            "UPDATE `##user` SET password = :password WHERE user_id = :user_id"
506015c99a2SGreg Roach        )->execute([
507015c99a2SGreg Roach            'password' => password_hash($password, PASSWORD_DEFAULT),
508015c99a2SGreg Roach            'user_id'  => $this->user_id,
509015c99a2SGreg Roach        ]);
510a25f0a04SGreg Roach
511a25f0a04SGreg Roach        return $this;
512a25f0a04SGreg Roach    }
513a25f0a04SGreg Roach
514a25f0a04SGreg Roach    /**
515a25f0a04SGreg Roach     * Fetch a user option/setting from the wt_user_setting table.
516a25f0a04SGreg Roach     * Since we'll fetch several settings for each user, and since there aren’t
517a25f0a04SGreg Roach     * that many of them, fetch them all in one database query
518a25f0a04SGreg Roach     *
519a25f0a04SGreg Roach     * @param string $setting_name
52015d603e7SGreg Roach     * @param string $default
521a25f0a04SGreg Roach     *
52215d603e7SGreg Roach     * @return string
523a25f0a04SGreg Roach     */
524c1010edaSGreg Roach    public function getPreference($setting_name, $default = '')
525c1010edaSGreg Roach    {
526c04dd3c1SGreg Roach        if (empty($this->preferences) && $this->user_id !== 0) {
527a25f0a04SGreg Roach            $this->preferences = Database::prepare(
528e5588fb0SGreg Roach                "SELECT setting_name, setting_value" .
52915d603e7SGreg Roach                " FROM `##user_setting`" .
53015d603e7SGreg Roach                " WHERE user_id = :user_id"
53115d603e7SGreg Roach            )->execute([
53215d603e7SGreg Roach                'user_id' => $this->user_id,
53315d603e7SGreg Roach            ])->fetchAssoc();
534a25f0a04SGreg Roach        }
535a25f0a04SGreg Roach
53615d603e7SGreg Roach        if (!array_key_exists($setting_name, $this->preferences)) {
53715d603e7SGreg Roach            $this->preferences[$setting_name] = $default;
538a25f0a04SGreg Roach        }
53915d603e7SGreg Roach
54015d603e7SGreg Roach        return $this->preferences[$setting_name];
541a25f0a04SGreg Roach    }
542a25f0a04SGreg Roach
543a25f0a04SGreg Roach    /**
544a25f0a04SGreg Roach     * Update a setting for the user.
545a25f0a04SGreg Roach     *
546a25f0a04SGreg Roach     * @param string $setting_name
547a25f0a04SGreg Roach     * @param string $setting_value
548a25f0a04SGreg Roach     *
549a25f0a04SGreg Roach     * @return User
550a25f0a04SGreg Roach     */
551c1010edaSGreg Roach    public function setPreference($setting_name, $setting_value)
552c1010edaSGreg Roach    {
553c04dd3c1SGreg Roach        if ($this->user_id !== 0 && $this->getPreference($setting_name) !== $setting_value) {
554a25f0a04SGreg Roach            Database::prepare("REPLACE INTO `##user_setting` (user_id, setting_name, setting_value) VALUES (?, ?, LEFT(?, 255))")
555c1010edaSGreg Roach                ->execute([
556c1010edaSGreg Roach                    $this->user_id,
557c1010edaSGreg Roach                    $setting_name,
558c1010edaSGreg Roach                    $setting_value,
559c1010edaSGreg Roach                ]);
56015d603e7SGreg Roach
561a25f0a04SGreg Roach            $this->preferences[$setting_name] = $setting_value;
562a25f0a04SGreg Roach        }
563a25f0a04SGreg Roach
564a25f0a04SGreg Roach        return $this;
565a25f0a04SGreg Roach    }
566a25f0a04SGreg Roach}
567