xref: /webtrees/app/User.php (revision 60bc3e3fa6818f7ba65df666d54efde701a9fe49)
1a25f0a04SGreg Roach<?php
2a25f0a04SGreg Roach/**
3a25f0a04SGreg Roach * webtrees: online genealogy
46bdf7674SGreg Roach * Copyright (C) 2017 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 */
1676692c8bSGreg Roachnamespace Fisharebest\Webtrees;
17a25f0a04SGreg Roach
18*60bc3e3fSGreg Roachuse stdclass;
19*60bc3e3fSGreg Roach
20a25f0a04SGreg Roach/**
2176692c8bSGreg Roach * Provide an interface to the wt_user table.
22a25f0a04SGreg Roach */
23a25f0a04SGreg Roachclass User {
24a25f0a04SGreg Roach	/** @var  string The primary key of this user. */
25a25f0a04SGreg Roach	private $user_id;
26a25f0a04SGreg Roach
27a25f0a04SGreg Roach	/** @var  string The login name of this user. */
28a25f0a04SGreg Roach	private $user_name;
29a25f0a04SGreg Roach
30a25f0a04SGreg Roach	/** @var  string The real (display) name of this user. */
31a25f0a04SGreg Roach	private $real_name;
32a25f0a04SGreg Roach
33a25f0a04SGreg Roach	/** @var  string The email address of this user. */
34a25f0a04SGreg Roach	private $email;
35a25f0a04SGreg Roach
3615d603e7SGreg Roach	/** @var string[] Cached copy of the wt_user_setting table. */
3715d603e7SGreg Roach	private $preferences = [];
38a25f0a04SGreg Roach
39a25f0a04SGreg Roach	/** @var  User[] Only fetch users from the database once. */
4013abd6f3SGreg Roach	private static $cache = [];
41a25f0a04SGreg Roach
42a25f0a04SGreg Roach	/**
43a25f0a04SGreg Roach	 * Find the user with a specified user_id.
44a25f0a04SGreg Roach	 *
45cbc1590aSGreg Roach	 * @param int|null $user_id
46a25f0a04SGreg Roach	 *
47a25f0a04SGreg Roach	 * @return User|null
48a25f0a04SGreg Roach	 */
49a25f0a04SGreg Roach	public static function find($user_id) {
50a25f0a04SGreg Roach		if (!array_key_exists($user_id, self::$cache)) {
51a25f0a04SGreg Roach			$row = Database::prepare(
52a25f0a04SGreg Roach				"SELECT SQL_CACHE user_id, user_name, real_name, email FROM `##user` WHERE user_id = ?"
5313abd6f3SGreg Roach			)->execute([$user_id])->fetchOneRow();
54a25f0a04SGreg Roach			if ($row) {
5506ef8e02SGreg Roach				self::$cache[$user_id] = new self($row);
56a25f0a04SGreg Roach			} else {
57a25f0a04SGreg Roach				self::$cache[$user_id] = null;
58a25f0a04SGreg Roach			}
59a25f0a04SGreg Roach		}
60a25f0a04SGreg Roach
61a25f0a04SGreg Roach		return self::$cache[$user_id];
62a25f0a04SGreg Roach	}
63a25f0a04SGreg Roach
64a25f0a04SGreg Roach	/**
65a982a56eSGreg Roach	 * Find the user with a specified user_name.
66a982a56eSGreg Roach	 *
67a982a56eSGreg Roach	 * @param string $user_name
68a982a56eSGreg Roach	 *
69a982a56eSGreg Roach	 * @return User|null
70a982a56eSGreg Roach	 */
71a982a56eSGreg Roach	public static function findByUserName($user_name) {
72a982a56eSGreg Roach		$user_id = Database::prepare(
73a982a56eSGreg Roach			"SELECT SQL_CACHE user_id FROM `##user` WHERE user_name = :user_name"
7413abd6f3SGreg Roach		)->execute([
75a982a56eSGreg Roach			'user_name' => $user_name,
7613abd6f3SGreg Roach		])->fetchOne();
77a982a56eSGreg Roach
78a982a56eSGreg Roach		return self::find($user_id);
79a982a56eSGreg Roach	}
80a982a56eSGreg Roach
81a982a56eSGreg Roach	/**
82a982a56eSGreg Roach	 * Find the user with a specified email address.
83a982a56eSGreg Roach	 *
84a982a56eSGreg Roach	 * @param string $email
85a982a56eSGreg Roach	 *
86a982a56eSGreg Roach	 * @return User|null
87a982a56eSGreg Roach	 */
88a982a56eSGreg Roach	public static function findByEmail($email) {
89a982a56eSGreg Roach		$user_id = Database::prepare(
90a982a56eSGreg Roach			"SELECT SQL_CACHE user_id FROM `##user` WHERE email = :email"
9113abd6f3SGreg Roach		)->execute([
92a982a56eSGreg Roach			'email' => $email,
9313abd6f3SGreg Roach		])->fetchOne();
94a982a56eSGreg Roach
95a982a56eSGreg Roach		return self::find($user_id);
96a982a56eSGreg Roach	}
97a982a56eSGreg Roach
98a982a56eSGreg Roach	/**
99a982a56eSGreg Roach	 * Find the user with a specified user_name or email address.
100a25f0a04SGreg Roach	 *
101a25f0a04SGreg Roach	 * @param string $identifier
102a25f0a04SGreg Roach	 *
103a25f0a04SGreg Roach	 * @return User|null
104a25f0a04SGreg Roach	 */
105a25f0a04SGreg Roach	public static function findByIdentifier($identifier) {
106a25f0a04SGreg Roach		$user_id = Database::prepare(
107a25f0a04SGreg Roach			"SELECT SQL_CACHE user_id FROM `##user` WHERE ? IN (user_name, email)"
10813abd6f3SGreg Roach		)->execute([$identifier])->fetchOne();
109a25f0a04SGreg Roach
110a25f0a04SGreg Roach		return self::find($user_id);
111a25f0a04SGreg Roach	}
112a25f0a04SGreg Roach
113a25f0a04SGreg Roach	/**
114a25f0a04SGreg Roach	 * Find the user with a specified genealogy record.
115a25f0a04SGreg Roach	 *
116a25f0a04SGreg Roach	 * @param Individual $individual
117a25f0a04SGreg Roach	 *
118a25f0a04SGreg Roach	 * @return User|null
119a25f0a04SGreg Roach	 */
120a5adda01SGreg Roach	public static function findByGenealogyRecord(Individual $individual) {
121a25f0a04SGreg Roach		$user_id = Database::prepare(
122a25f0a04SGreg Roach			"SELECT SQL_CACHE user_id" .
123a25f0a04SGreg Roach			" FROM `##user_gedcom_setting`" .
124a5adda01SGreg Roach			" WHERE gedcom_id = :tree_id AND setting_name = 'gedcomid' AND setting_value = :xref"
12513abd6f3SGreg Roach		)->execute([
126a5adda01SGreg Roach			'tree_id' => $individual->getTree()->getTreeId(),
127cbc1590aSGreg Roach			'xref'    => $individual->getXref(),
12813abd6f3SGreg Roach		])->fetchOne();
129a25f0a04SGreg Roach
130a25f0a04SGreg Roach		return self::find($user_id);
131a25f0a04SGreg Roach	}
132a25f0a04SGreg Roach
133a25f0a04SGreg Roach	/**
134a25f0a04SGreg Roach	 * Find the latest user to register.
135a25f0a04SGreg Roach	 *
136a25f0a04SGreg Roach	 * @return User|null
137a25f0a04SGreg Roach	 */
138a25f0a04SGreg Roach	public static function findLatestToRegister() {
139a25f0a04SGreg Roach		$user_id = Database::prepare(
140a25f0a04SGreg Roach			"SELECT SQL_CACHE u.user_id" .
141a25f0a04SGreg Roach			" FROM `##user` u" .
142a25f0a04SGreg Roach			" LEFT JOIN `##user_setting` us ON (u.user_id=us.user_id AND us.setting_name='reg_timestamp') " .
143a25f0a04SGreg Roach			" ORDER BY us.setting_value DESC LIMIT 1"
144a25f0a04SGreg Roach		)->execute()->fetchOne();
145a25f0a04SGreg Roach
146a25f0a04SGreg Roach		return self::find($user_id);
147a25f0a04SGreg Roach	}
148a25f0a04SGreg Roach
149a25f0a04SGreg Roach	/**
150a25f0a04SGreg Roach	 * Create a new user.
151a25f0a04SGreg Roach	 *
152a25f0a04SGreg Roach	 * The calling code needs to check for duplicates identifiers before calling
153a25f0a04SGreg Roach	 * this function.
154a25f0a04SGreg Roach	 *
155a25f0a04SGreg Roach	 * @param string $user_name
156a25f0a04SGreg Roach	 * @param string $real_name
157a25f0a04SGreg Roach	 * @param string $email
158a25f0a04SGreg Roach	 * @param string $password
159a25f0a04SGreg Roach	 *
160a25f0a04SGreg Roach	 * @return User
161a25f0a04SGreg Roach	 */
162a25f0a04SGreg Roach	public static function create($user_name, $real_name, $email, $password) {
163a25f0a04SGreg Roach		Database::prepare(
164a25f0a04SGreg Roach			"INSERT INTO `##user` (user_name, real_name, email, password) VALUES (:user_name, :real_name, :email, :password)"
16513abd6f3SGreg Roach		)->execute([
166a25f0a04SGreg Roach			'user_name' => $user_name,
167a25f0a04SGreg Roach			'real_name' => $real_name,
168a25f0a04SGreg Roach			'email'     => $email,
169015c99a2SGreg Roach			'password'  => password_hash($password, PASSWORD_DEFAULT),
17013abd6f3SGreg Roach		]);
171a25f0a04SGreg Roach
172a25f0a04SGreg Roach		// Set default blocks for this user
17306ef8e02SGreg Roach		$user = self::findByIdentifier($user_name);
174a25f0a04SGreg Roach		Database::prepare(
175a25f0a04SGreg Roach			"INSERT INTO `##block` (`user_id`, `location`, `block_order`, `module_name`)" .
176a25f0a04SGreg Roach			" SELECT :user_id , `location`, `block_order`, `module_name` FROM `##block` WHERE `user_id` = -1"
17713abd6f3SGreg Roach		)->execute(['user_id' => $user->getUserId()]);
178cbc1590aSGreg Roach
179a25f0a04SGreg Roach		return $user;
180a25f0a04SGreg Roach	}
181a25f0a04SGreg Roach
182a25f0a04SGreg Roach	/**
183a25f0a04SGreg Roach	 * Get a count of all users.
184a25f0a04SGreg Roach	 *
185cbc1590aSGreg Roach	 * @return int
186a25f0a04SGreg Roach	 */
187a25f0a04SGreg Roach	public static function count() {
188a25f0a04SGreg Roach		return (int) Database::prepare(
189a25f0a04SGreg Roach			"SELECT SQL_CACHE COUNT(*)" .
190a25f0a04SGreg Roach			" FROM `##user`" .
191a25f0a04SGreg Roach			" WHERE user_id > 0"
192a25f0a04SGreg Roach		)->fetchOne();
193a25f0a04SGreg Roach	}
194a25f0a04SGreg Roach
195a25f0a04SGreg Roach	/**
196a25f0a04SGreg Roach	 * Get a list of all users.
197a25f0a04SGreg Roach	 *
198a25f0a04SGreg Roach	 * @return User[]
199a25f0a04SGreg Roach	 */
200a25f0a04SGreg Roach	public static function all() {
20113abd6f3SGreg Roach		$users = [];
202a25f0a04SGreg Roach
203a25f0a04SGreg Roach		$rows = Database::prepare(
204a25f0a04SGreg Roach			"SELECT SQL_CACHE user_id, user_name, real_name, email" .
205a25f0a04SGreg Roach			" FROM `##user`" .
206a25f0a04SGreg Roach			" WHERE user_id > 0" .
207a25f0a04SGreg Roach			" ORDER BY user_name"
208a25f0a04SGreg Roach		)->fetchAll();
209a25f0a04SGreg Roach
210a25f0a04SGreg Roach		foreach ($rows as $row) {
21106ef8e02SGreg Roach			$users[] = new self($row);
212a25f0a04SGreg Roach		}
213a25f0a04SGreg Roach
214a25f0a04SGreg Roach		return $users;
215a25f0a04SGreg Roach	}
216a25f0a04SGreg Roach
217a25f0a04SGreg Roach	/**
218a25f0a04SGreg Roach	 * Get a list of all administrators.
219a25f0a04SGreg Roach	 *
220a25f0a04SGreg Roach	 * @return User[]
221a25f0a04SGreg Roach	 */
222a25f0a04SGreg Roach	public static function allAdmins() {
223a25f0a04SGreg Roach		$rows = Database::prepare(
224a25f0a04SGreg Roach			"SELECT SQL_CACHE user_id, user_name, real_name, email" .
225a25f0a04SGreg Roach			" FROM `##user`" .
226a25f0a04SGreg Roach			" JOIN `##user_setting` USING (user_id)" .
227a25f0a04SGreg Roach			" WHERE user_id > 0" .
228a25f0a04SGreg Roach			"   AND setting_name = 'canadmin'" .
229a25f0a04SGreg Roach			"   AND setting_value = '1'"
230a25f0a04SGreg Roach		)->fetchAll();
231a25f0a04SGreg Roach
23213abd6f3SGreg Roach		$users = [];
233a25f0a04SGreg Roach		foreach ($rows as $row) {
23406ef8e02SGreg Roach			$users[] = new self($row);
235a25f0a04SGreg Roach		}
236a25f0a04SGreg Roach
237a25f0a04SGreg Roach		return $users;
238a25f0a04SGreg Roach	}
239a25f0a04SGreg Roach
240a25f0a04SGreg Roach	/**
241a25f0a04SGreg Roach	 * Get a list of all verified uses.
242a25f0a04SGreg Roach	 *
243a25f0a04SGreg Roach	 * @return User[]
244a25f0a04SGreg Roach	 */
245a25f0a04SGreg Roach	public static function allVerified() {
246a25f0a04SGreg Roach		$rows = Database::prepare(
247a25f0a04SGreg Roach			"SELECT SQL_CACHE user_id, user_name, real_name, email" .
248a25f0a04SGreg Roach			" FROM `##user`" .
249a25f0a04SGreg Roach			" JOIN `##user_setting` USING (user_id)" .
250a25f0a04SGreg Roach			" WHERE user_id > 0" .
251a25f0a04SGreg Roach			"   AND setting_name = 'verified'" .
252a25f0a04SGreg Roach			"   AND setting_value = '1'"
253a25f0a04SGreg Roach		)->fetchAll();
254a25f0a04SGreg Roach
25513abd6f3SGreg Roach		$users = [];
256a25f0a04SGreg Roach		foreach ($rows as $row) {
25706ef8e02SGreg Roach			$users[] = new self($row);
258a25f0a04SGreg Roach		}
259a25f0a04SGreg Roach
260a25f0a04SGreg Roach		return $users;
261a25f0a04SGreg Roach	}
262a25f0a04SGreg Roach
263a25f0a04SGreg Roach	/**
264a25f0a04SGreg Roach	 * Get a list of all users who are currently logged in.
265a25f0a04SGreg Roach	 *
266a25f0a04SGreg Roach	 * @return User[]
267a25f0a04SGreg Roach	 */
268a25f0a04SGreg Roach	public static function allLoggedIn() {
269a25f0a04SGreg Roach		$rows = Database::prepare(
270a25f0a04SGreg Roach			"SELECT SQL_NO_CACHE DISTINCT user_id, user_name, real_name, email" .
271a25f0a04SGreg Roach			" FROM `##user`" .
272a25f0a04SGreg Roach			" JOIN `##session` USING (user_id)"
273a25f0a04SGreg Roach		)->fetchAll();
274a25f0a04SGreg Roach
27513abd6f3SGreg Roach		$users = [];
276a25f0a04SGreg Roach		foreach ($rows as $row) {
27706ef8e02SGreg Roach			$users[] = new self($row);
278a25f0a04SGreg Roach		}
279a25f0a04SGreg Roach
280a25f0a04SGreg Roach		return $users;
281a25f0a04SGreg Roach	}
282a25f0a04SGreg Roach
283a25f0a04SGreg Roach	/**
284a25f0a04SGreg Roach	 * Create a new user object from a row in the database.
285a25f0a04SGreg Roach	 *
286*60bc3e3fSGreg Roach	 * @param stdclass $user A row from the wt_user table
287a25f0a04SGreg Roach	 */
288*60bc3e3fSGreg Roach	public function __construct(stdClass $user) {
289a25f0a04SGreg Roach		$this->user_id   = $user->user_id;
290a25f0a04SGreg Roach		$this->user_name = $user->user_name;
291a25f0a04SGreg Roach		$this->real_name = $user->real_name;
292a25f0a04SGreg Roach		$this->email     = $user->email;
293a25f0a04SGreg Roach	}
294a25f0a04SGreg Roach
295a25f0a04SGreg Roach	/**
296a25f0a04SGreg Roach	 * Delete a user
297a25f0a04SGreg Roach	 */
298ffd703eaSGreg Roach	public function delete() {
299a25f0a04SGreg Roach		// Don't delete the logs.
30013abd6f3SGreg Roach		Database::prepare("UPDATE `##log` SET user_id=NULL WHERE user_id =?")->execute([$this->user_id]);
301a25f0a04SGreg Roach		// Take over the user’s pending changes. (What else could we do with them?)
30213abd6f3SGreg Roach		Database::prepare("DELETE FROM `##change` WHERE user_id=? AND status='rejected'")->execute([$this->user_id]);
30313abd6f3SGreg Roach		Database::prepare("UPDATE `##change` SET user_id=? WHERE user_id=?")->execute([Auth::id(), $this->user_id]);
30413abd6f3SGreg Roach		Database::prepare("DELETE `##block_setting` FROM `##block_setting` JOIN `##block` USING (block_id) WHERE user_id=?")->execute([$this->user_id]);
30513abd6f3SGreg Roach		Database::prepare("DELETE FROM `##block` WHERE user_id=?")->execute([$this->user_id]);
30613abd6f3SGreg Roach		Database::prepare("DELETE FROM `##user_gedcom_setting` WHERE user_id=?")->execute([$this->user_id]);
30713abd6f3SGreg Roach		Database::prepare("DELETE FROM `##gedcom_setting` WHERE setting_value=? AND setting_name IN ('CONTACT_USER_ID', 'WEBMASTER_USER_ID')")->execute([$this->user_id]);
30813abd6f3SGreg Roach		Database::prepare("DELETE FROM `##user_setting` WHERE user_id=?")->execute([$this->user_id]);
30913abd6f3SGreg Roach		Database::prepare("DELETE FROM `##message` WHERE user_id=?")->execute([$this->user_id]);
31013abd6f3SGreg Roach		Database::prepare("DELETE FROM `##user` WHERE user_id=?")->execute([$this->user_id]);
311a25f0a04SGreg Roach	}
312a25f0a04SGreg Roach
313a25f0a04SGreg Roach	/** Validate a supplied password
314a25f0a04SGreg Roach	 * @param string $password
315a25f0a04SGreg Roach	 *
316cbc1590aSGreg Roach	 * @return bool
317a25f0a04SGreg Roach	 */
318a25f0a04SGreg Roach	public function checkPassword($password) {
319a25f0a04SGreg Roach		$password_hash = Database::prepare(
320a25f0a04SGreg Roach			"SELECT password FROM `##user` WHERE user_id = ?"
32113abd6f3SGreg Roach		)->execute([$this->user_id])->fetchOne();
322a25f0a04SGreg Roach
323015c99a2SGreg Roach		if (password_verify($password, $password_hash)) {
324015c99a2SGreg Roach			if (password_needs_rehash($password_hash, PASSWORD_DEFAULT)) {
325a25f0a04SGreg Roach				$this->setPassword($password);
326a25f0a04SGreg Roach			}
327cbc1590aSGreg Roach
328a25f0a04SGreg Roach			return true;
329a25f0a04SGreg Roach		} else {
330a25f0a04SGreg Roach			return false;
331a25f0a04SGreg Roach		}
332a25f0a04SGreg Roach	}
333a25f0a04SGreg Roach
334a25f0a04SGreg Roach	/**
335a25f0a04SGreg Roach	 * Get the numeric ID for this user.
336a25f0a04SGreg Roach	 *
337a25f0a04SGreg Roach	 * @return string
338a25f0a04SGreg Roach	 */
339a25f0a04SGreg Roach	public function getUserId() {
340a25f0a04SGreg Roach		return $this->user_id;
341a25f0a04SGreg Roach	}
342a25f0a04SGreg Roach
343a25f0a04SGreg Roach	/**
344a25f0a04SGreg Roach	 * Get the login name for this user.
345a25f0a04SGreg Roach	 *
346a25f0a04SGreg Roach	 * @return string
347a25f0a04SGreg Roach	 */
348a25f0a04SGreg Roach	public function getUserName() {
349a25f0a04SGreg Roach		return $this->user_name;
350a25f0a04SGreg Roach	}
351a25f0a04SGreg Roach
352a25f0a04SGreg Roach	/**
353a25f0a04SGreg Roach	 * Set the login name for this user.
354a25f0a04SGreg Roach	 *
355a25f0a04SGreg Roach	 * @param string $user_name
356a25f0a04SGreg Roach	 *
357a25f0a04SGreg Roach	 * @return $this
358a25f0a04SGreg Roach	 */
359a25f0a04SGreg Roach	public function setUserName($user_name) {
360a25f0a04SGreg Roach		if ($this->user_name !== $user_name) {
361a25f0a04SGreg Roach			$this->user_name = $user_name;
362a25f0a04SGreg Roach			Database::prepare(
363a25f0a04SGreg Roach				"UPDATE `##user` SET user_name = ? WHERE user_id = ?"
36413abd6f3SGreg Roach			)->execute([$user_name, $this->user_id]);
365a25f0a04SGreg Roach		}
366a25f0a04SGreg Roach
367a25f0a04SGreg Roach		return $this;
368a25f0a04SGreg Roach	}
369a25f0a04SGreg Roach
370a25f0a04SGreg Roach	/**
371a25f0a04SGreg Roach	 * Get the real name of this user.
372a25f0a04SGreg Roach	 *
373a25f0a04SGreg Roach	 * @return string
374a25f0a04SGreg Roach	 */
375a25f0a04SGreg Roach	public function getRealName() {
376a25f0a04SGreg Roach		return $this->real_name;
377a25f0a04SGreg Roach	}
378a25f0a04SGreg Roach
379a25f0a04SGreg Roach	/**
380524c0fabSGreg Roach	 * Get the real name of this user, for display on screen.
381524c0fabSGreg Roach	 *
382524c0fabSGreg Roach	 * @return string
383524c0fabSGreg Roach	 */
384524c0fabSGreg Roach	public function getRealNameHtml() {
385524c0fabSGreg Roach		return '<span dir="auto">' . Filter::escapeHtml($this->real_name) . '</span>';
386524c0fabSGreg Roach	}
387524c0fabSGreg Roach
388524c0fabSGreg Roach	/**
389a25f0a04SGreg Roach	 * Set the real name of this user.
390a25f0a04SGreg Roach	 *
391a25f0a04SGreg Roach	 * @param string $real_name
392a25f0a04SGreg Roach	 *
393a25f0a04SGreg Roach	 * @return User
394a25f0a04SGreg Roach	 */
395a25f0a04SGreg Roach	public function setRealName($real_name) {
396a25f0a04SGreg Roach		if ($this->real_name !== $real_name) {
397a25f0a04SGreg Roach			$this->real_name = $real_name;
398a25f0a04SGreg Roach			Database::prepare(
399a25f0a04SGreg Roach				"UPDATE `##user` SET real_name = ? WHERE user_id = ?"
40013abd6f3SGreg Roach			)->execute([$real_name, $this->user_id]);
401a25f0a04SGreg Roach		}
402a25f0a04SGreg Roach
403a25f0a04SGreg Roach		return $this;
404a25f0a04SGreg Roach	}
405a25f0a04SGreg Roach
406a25f0a04SGreg Roach	/**
407a25f0a04SGreg Roach	 * Get the email address of this user.
408a25f0a04SGreg Roach	 *
409a25f0a04SGreg Roach	 * @return string
410a25f0a04SGreg Roach	 */
411a25f0a04SGreg Roach	public function getEmail() {
412a25f0a04SGreg Roach		return $this->email;
413a25f0a04SGreg Roach	}
414a25f0a04SGreg Roach
415a25f0a04SGreg Roach	/**
416a25f0a04SGreg Roach	 * Set the email address of this user.
417a25f0a04SGreg Roach	 *
418a25f0a04SGreg Roach	 * @param string $email
419a25f0a04SGreg Roach	 *
420a25f0a04SGreg Roach	 * @return User
421a25f0a04SGreg Roach	 */
422a25f0a04SGreg Roach	public function setEmail($email) {
423a25f0a04SGreg Roach		if ($this->email !== $email) {
424a25f0a04SGreg Roach			$this->email = $email;
425a25f0a04SGreg Roach			Database::prepare(
426a25f0a04SGreg Roach				"UPDATE `##user` SET email = ? WHERE user_id = ?"
42713abd6f3SGreg Roach			)->execute([$email, $this->user_id]);
428a25f0a04SGreg Roach		}
429a25f0a04SGreg Roach
430a25f0a04SGreg Roach		return $this;
431a25f0a04SGreg Roach	}
432a25f0a04SGreg Roach
433a25f0a04SGreg Roach	/**
434a25f0a04SGreg Roach	 * Set the password of this user.
435a25f0a04SGreg Roach	 *
436a25f0a04SGreg Roach	 * @param string $password
437a25f0a04SGreg Roach	 *
438a25f0a04SGreg Roach	 * @return User
439a25f0a04SGreg Roach	 */
440a25f0a04SGreg Roach	public function setPassword($password) {
441a25f0a04SGreg Roach		Database::prepare(
442015c99a2SGreg Roach			"UPDATE `##user` SET password = :password WHERE user_id = :user_id"
443015c99a2SGreg Roach		)->execute([
444015c99a2SGreg Roach			'password' => password_hash($password, PASSWORD_DEFAULT),
445015c99a2SGreg Roach			'user_id'  => $this->user_id,
446015c99a2SGreg Roach		]);
447a25f0a04SGreg Roach
448a25f0a04SGreg Roach		return $this;
449a25f0a04SGreg Roach	}
450a25f0a04SGreg Roach
451a25f0a04SGreg Roach	/**
452a25f0a04SGreg Roach	 * Fetch a user option/setting from the wt_user_setting table.
453a25f0a04SGreg Roach	 *
454a25f0a04SGreg Roach	 * Since we'll fetch several settings for each user, and since there aren’t
455a25f0a04SGreg Roach	 * that many of them, fetch them all in one database query
456a25f0a04SGreg Roach	 *
457a25f0a04SGreg Roach	 * @param string $setting_name
45815d603e7SGreg Roach	 * @param string $default
459a25f0a04SGreg Roach	 *
46015d603e7SGreg Roach	 * @return string
461a25f0a04SGreg Roach	 */
46215d603e7SGreg Roach	public function getPreference($setting_name, $default = '') {
46315d603e7SGreg Roach		if (empty($this->preferences) && $this->user_id !== null) {
464a25f0a04SGreg Roach			$this->preferences = Database::prepare(
46515d603e7SGreg Roach				"SELECT SQL_CACHE setting_name, setting_value" .
46615d603e7SGreg Roach				" FROM `##user_setting`" .
46715d603e7SGreg Roach				" WHERE user_id = :user_id"
46815d603e7SGreg Roach			)->execute([
46915d603e7SGreg Roach				'user_id' => $this->user_id,
47015d603e7SGreg Roach			])->fetchAssoc();
471a25f0a04SGreg Roach		}
472a25f0a04SGreg Roach
47315d603e7SGreg Roach		if (!array_key_exists($setting_name, $this->preferences)) {
47415d603e7SGreg Roach			$this->preferences[$setting_name] = $default;
475a25f0a04SGreg Roach		}
47615d603e7SGreg Roach
47715d603e7SGreg Roach		return $this->preferences[$setting_name];
478a25f0a04SGreg Roach	}
479a25f0a04SGreg Roach
480a25f0a04SGreg Roach	/**
481a25f0a04SGreg Roach	 * Update a setting for the user.
482a25f0a04SGreg Roach	 *
483a25f0a04SGreg Roach	 * @param string $setting_name
484a25f0a04SGreg Roach	 * @param string $setting_value
485a25f0a04SGreg Roach	 *
486a25f0a04SGreg Roach	 * @return User
487a25f0a04SGreg Roach	 */
488a25f0a04SGreg Roach	public function setPreference($setting_name, $setting_value) {
489a25f0a04SGreg Roach		if ($this->user_id && $this->getPreference($setting_name) !== $setting_value) {
490a25f0a04SGreg Roach			Database::prepare("REPLACE INTO `##user_setting` (user_id, setting_name, setting_value) VALUES (?, ?, LEFT(?, 255))")
49113abd6f3SGreg Roach				->execute([$this->user_id, $setting_name, $setting_value]);
49215d603e7SGreg Roach
493a25f0a04SGreg Roach			$this->preferences[$setting_name] = $setting_value;
494a25f0a04SGreg Roach		}
495a25f0a04SGreg Roach
496a25f0a04SGreg Roach		return $this;
497a25f0a04SGreg Roach	}
498a25f0a04SGreg Roach}
499