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