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 */ 16*c04dd3c1SGreg Roachdeclare(strict_types=1); 17*c04dd3c1SGreg 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 */ 25a25f0a04SGreg Roachclass User { 26*c04dd3c1SGreg Roach /** @var int The primary key of this user. */ 27a25f0a04SGreg Roach private $user_id; 28a25f0a04SGreg Roach 29a25f0a04SGreg Roach /** @var string The login name of this user. */ 30a25f0a04SGreg Roach private $user_name; 31a25f0a04SGreg Roach 32a25f0a04SGreg Roach /** @var string The real (display) name of this user. */ 33a25f0a04SGreg Roach private $real_name; 34a25f0a04SGreg Roach 35a25f0a04SGreg Roach /** @var string The email address of this user. */ 36a25f0a04SGreg Roach private $email; 37a25f0a04SGreg Roach 3815d603e7SGreg Roach /** @var string[] Cached copy of the wt_user_setting table. */ 3915d603e7SGreg Roach private $preferences = []; 40a25f0a04SGreg Roach 41a25f0a04SGreg Roach /** @var User[] Only fetch users from the database once. */ 4213abd6f3SGreg Roach private static $cache = []; 43a25f0a04SGreg Roach 44a25f0a04SGreg Roach /** 45f7fb7d41SGreg Roach * Create a new user object from a row in the database. 46f7fb7d41SGreg Roach * 47f7fb7d41SGreg Roach * @param stdclass $user A row from the wt_user table 48f7fb7d41SGreg Roach */ 49f7fb7d41SGreg Roach public function __construct(stdClass $user) { 50*c04dd3c1SGreg Roach $this->user_id = (int) $user->user_id; 51f7fb7d41SGreg Roach $this->user_name = $user->user_name; 52f7fb7d41SGreg Roach $this->real_name = $user->real_name; 53f7fb7d41SGreg Roach $this->email = $user->email; 54f7fb7d41SGreg Roach } 55f7fb7d41SGreg Roach 56f7fb7d41SGreg Roach /** 57f7fb7d41SGreg Roach * Create a new user. 58f7fb7d41SGreg Roach * 59f7fb7d41SGreg Roach * The calling code needs to check for duplicates identifiers before calling 60f7fb7d41SGreg Roach * this function. 61f7fb7d41SGreg Roach * 62f7fb7d41SGreg Roach * @param string $user_name 63f7fb7d41SGreg Roach * @param string $real_name 64f7fb7d41SGreg Roach * @param string $email 65f7fb7d41SGreg Roach * @param string $password 66f7fb7d41SGreg Roach * 67f7fb7d41SGreg Roach * @return User 68f7fb7d41SGreg Roach */ 69f7fb7d41SGreg Roach public static function create($user_name, $real_name, $email, $password) { 70f7fb7d41SGreg Roach Database::prepare( 71f7fb7d41SGreg Roach "INSERT INTO `##user` (user_name, real_name, email, password) VALUES (:user_name, :real_name, :email, :password)" 72f7fb7d41SGreg Roach )->execute([ 73f7fb7d41SGreg Roach 'user_name' => $user_name, 74f7fb7d41SGreg Roach 'real_name' => $real_name, 75f7fb7d41SGreg Roach 'email' => $email, 76f7fb7d41SGreg Roach 'password' => password_hash($password, PASSWORD_DEFAULT), 77f7fb7d41SGreg Roach ]); 78f7fb7d41SGreg Roach 79f7fb7d41SGreg Roach // Set default blocks for this user 80f7fb7d41SGreg Roach $user = self::findByIdentifier($user_name); 81f7fb7d41SGreg Roach Database::prepare( 82f7fb7d41SGreg Roach "INSERT INTO `##block` (`user_id`, `location`, `block_order`, `module_name`)" . 83f7fb7d41SGreg Roach " SELECT :user_id , `location`, `block_order`, `module_name` FROM `##block` WHERE `user_id` = -1" 84f7fb7d41SGreg Roach )->execute(['user_id' => $user->getUserId()]); 85f7fb7d41SGreg Roach 86f7fb7d41SGreg Roach return $user; 87f7fb7d41SGreg Roach } 88f7fb7d41SGreg Roach 89f7fb7d41SGreg Roach /** 90f7fb7d41SGreg Roach * Delete a user 91f7fb7d41SGreg Roach */ 92f7fb7d41SGreg Roach public function delete() { 93f7fb7d41SGreg Roach // Don't delete the logs. 94f7fb7d41SGreg Roach Database::prepare("UPDATE `##log` SET user_id=NULL WHERE user_id =?")->execute([$this->user_id]); 95f7fb7d41SGreg Roach // Take over the user’s pending changes. (What else could we do with them?) 96f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##change` WHERE user_id=? AND status='rejected'")->execute([$this->user_id]); 97f7fb7d41SGreg Roach Database::prepare("UPDATE `##change` SET user_id=? WHERE user_id=?")->execute([Auth::id(), $this->user_id]); 98f7fb7d41SGreg Roach Database::prepare("DELETE `##block_setting` FROM `##block_setting` JOIN `##block` USING (block_id) WHERE user_id=?")->execute([$this->user_id]); 99f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##block` WHERE user_id=?")->execute([$this->user_id]); 100f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##user_gedcom_setting` WHERE user_id=?")->execute([$this->user_id]); 101f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##gedcom_setting` WHERE setting_value=? AND setting_name IN ('CONTACT_USER_ID', 'WEBMASTER_USER_ID')")->execute([$this->user_id]); 102f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##user_setting` WHERE user_id=?")->execute([$this->user_id]); 103f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##message` WHERE user_id=?")->execute([$this->user_id]); 104f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##user` WHERE user_id=?")->execute([$this->user_id]); 105f7fb7d41SGreg Roach } 106f7fb7d41SGreg Roach 107f7fb7d41SGreg Roach /** 108a25f0a04SGreg Roach * Find the user with a specified user_id. 109a25f0a04SGreg Roach * 110cbc1590aSGreg Roach * @param int|null $user_id 111a25f0a04SGreg Roach * 112a25f0a04SGreg Roach * @return User|null 113a25f0a04SGreg Roach */ 114a25f0a04SGreg Roach public static function find($user_id) { 115a25f0a04SGreg Roach if (!array_key_exists($user_id, self::$cache)) { 116a25f0a04SGreg Roach $row = Database::prepare( 117a25f0a04SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email FROM `##user` WHERE user_id = ?" 11813abd6f3SGreg Roach )->execute([$user_id])->fetchOneRow(); 119a25f0a04SGreg Roach if ($row) { 12006ef8e02SGreg Roach self::$cache[$user_id] = new self($row); 121a25f0a04SGreg Roach } else { 122a25f0a04SGreg Roach self::$cache[$user_id] = null; 123a25f0a04SGreg Roach } 124a25f0a04SGreg Roach } 125a25f0a04SGreg Roach 126a25f0a04SGreg Roach return self::$cache[$user_id]; 127a25f0a04SGreg Roach } 128a25f0a04SGreg Roach 129a25f0a04SGreg Roach /** 130a982a56eSGreg Roach * Find the user with a specified email address. 131a982a56eSGreg Roach * 132a982a56eSGreg Roach * @param string $email 133a982a56eSGreg Roach * 134a982a56eSGreg Roach * @return User|null 135a982a56eSGreg Roach */ 136a982a56eSGreg Roach public static function findByEmail($email) { 137a982a56eSGreg Roach $user_id = Database::prepare( 138a982a56eSGreg Roach "SELECT SQL_CACHE user_id FROM `##user` WHERE email = :email" 13913abd6f3SGreg Roach )->execute([ 140a982a56eSGreg Roach 'email' => $email, 14113abd6f3SGreg Roach ])->fetchOne(); 142a982a56eSGreg Roach 143a982a56eSGreg Roach return self::find($user_id); 144a982a56eSGreg Roach } 145a982a56eSGreg Roach 146a982a56eSGreg Roach /** 147a982a56eSGreg Roach * Find the user with a specified user_name or email address. 148a25f0a04SGreg Roach * 149a25f0a04SGreg Roach * @param string $identifier 150a25f0a04SGreg Roach * 151a25f0a04SGreg Roach * @return User|null 152a25f0a04SGreg Roach */ 153a25f0a04SGreg Roach public static function findByIdentifier($identifier) { 154a25f0a04SGreg Roach $user_id = Database::prepare( 155a25f0a04SGreg Roach "SELECT SQL_CACHE user_id FROM `##user` WHERE ? IN (user_name, email)" 15613abd6f3SGreg Roach )->execute([$identifier])->fetchOne(); 157a25f0a04SGreg Roach 158a25f0a04SGreg Roach return self::find($user_id); 159a25f0a04SGreg Roach } 160a25f0a04SGreg Roach 161a25f0a04SGreg Roach /** 162a25f0a04SGreg Roach * Find the user with a specified genealogy record. 163a25f0a04SGreg Roach * 164a25f0a04SGreg Roach * @param Individual $individual 165a25f0a04SGreg Roach * 166a25f0a04SGreg Roach * @return User|null 167a25f0a04SGreg Roach */ 168f7fb7d41SGreg Roach public static function findByIndividual(Individual $individual) { 169a25f0a04SGreg Roach $user_id = Database::prepare( 170a25f0a04SGreg Roach "SELECT SQL_CACHE user_id" . 171a25f0a04SGreg Roach " FROM `##user_gedcom_setting`" . 172a5adda01SGreg Roach " WHERE gedcom_id = :tree_id AND setting_name = 'gedcomid' AND setting_value = :xref" 17313abd6f3SGreg Roach )->execute([ 174a5adda01SGreg Roach 'tree_id' => $individual->getTree()->getTreeId(), 175cbc1590aSGreg Roach 'xref' => $individual->getXref(), 17613abd6f3SGreg Roach ])->fetchOne(); 177a25f0a04SGreg Roach 178a25f0a04SGreg Roach return self::find($user_id); 179a25f0a04SGreg Roach } 180a25f0a04SGreg Roach 181a25f0a04SGreg Roach /** 182f7fb7d41SGreg Roach * Find the user with a specified user_name. 183f7fb7d41SGreg Roach * 184f7fb7d41SGreg Roach * @param string $user_name 185f7fb7d41SGreg Roach * 186f7fb7d41SGreg Roach * @return User|null 187f7fb7d41SGreg Roach */ 188f7fb7d41SGreg Roach public static function findByUserName($user_name) { 189f7fb7d41SGreg Roach $user_id = Database::prepare( 190f7fb7d41SGreg Roach "SELECT SQL_CACHE user_id FROM `##user` WHERE user_name = :user_name" 191f7fb7d41SGreg Roach )->execute([ 192f7fb7d41SGreg Roach 'user_name' => $user_name, 193f7fb7d41SGreg Roach ])->fetchOne(); 194f7fb7d41SGreg Roach 195f7fb7d41SGreg Roach return self::find($user_id); 196f7fb7d41SGreg Roach } 197f7fb7d41SGreg Roach 198f7fb7d41SGreg Roach /** 199a25f0a04SGreg Roach * Find the latest user to register. 200a25f0a04SGreg Roach * 201a25f0a04SGreg Roach * @return User|null 202a25f0a04SGreg Roach */ 203a25f0a04SGreg Roach public static function findLatestToRegister() { 204a25f0a04SGreg Roach $user_id = Database::prepare( 205a25f0a04SGreg Roach "SELECT SQL_CACHE u.user_id" . 206a25f0a04SGreg Roach " FROM `##user` u" . 207a25f0a04SGreg Roach " LEFT JOIN `##user_setting` us ON (u.user_id=us.user_id AND us.setting_name='reg_timestamp') " . 208a25f0a04SGreg Roach " ORDER BY us.setting_value DESC LIMIT 1" 209a25f0a04SGreg Roach )->execute()->fetchOne(); 210a25f0a04SGreg Roach 211a25f0a04SGreg Roach return self::find($user_id); 212a25f0a04SGreg Roach } 213a25f0a04SGreg Roach 214a25f0a04SGreg Roach /** 215a25f0a04SGreg Roach * Get a list of all users. 216a25f0a04SGreg Roach * 217a25f0a04SGreg Roach * @return User[] 218a25f0a04SGreg Roach */ 219a25f0a04SGreg Roach public static function all() { 220a25f0a04SGreg Roach $rows = Database::prepare( 221a25f0a04SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 222a25f0a04SGreg Roach " FROM `##user`" . 223a25f0a04SGreg Roach " WHERE user_id > 0" . 224f7fb7d41SGreg Roach " ORDER BY real_name" 225a25f0a04SGreg Roach )->fetchAll(); 226a25f0a04SGreg Roach 2278d68cabeSGreg Roach return array_map(function($row) { 2288d68cabeSGreg Roach return new static($row); 2298d68cabeSGreg Roach }, $rows); 230a25f0a04SGreg Roach } 231a25f0a04SGreg Roach 232a25f0a04SGreg Roach /** 233a25f0a04SGreg Roach * Get a list of all administrators. 234a25f0a04SGreg Roach * 235a25f0a04SGreg Roach * @return User[] 236a25f0a04SGreg Roach */ 237f7fb7d41SGreg Roach public static function administrators() { 238a25f0a04SGreg Roach $rows = Database::prepare( 239a25f0a04SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 240a25f0a04SGreg Roach " FROM `##user`" . 241a25f0a04SGreg Roach " JOIN `##user_setting` USING (user_id)" . 242f7fb7d41SGreg Roach " WHERE user_id > 0 AND setting_name = 'canadmin' AND setting_value = '1'" . 243f7fb7d41SGreg Roach " ORDER BY real_name" 244a25f0a04SGreg Roach )->fetchAll(); 245a25f0a04SGreg Roach 2468d68cabeSGreg Roach return array_map(function($row) { 2478d68cabeSGreg Roach return new static($row); 2488d68cabeSGreg Roach }, $rows); 249a25f0a04SGreg Roach } 250a25f0a04SGreg Roach 251a25f0a04SGreg Roach /** Validate a supplied password 252a25f0a04SGreg Roach * @param string $password 253a25f0a04SGreg Roach * 254cbc1590aSGreg Roach * @return bool 255a25f0a04SGreg Roach */ 256a25f0a04SGreg Roach public function checkPassword($password) { 257a25f0a04SGreg Roach $password_hash = Database::prepare( 258a25f0a04SGreg Roach "SELECT password FROM `##user` WHERE user_id = ?" 25913abd6f3SGreg Roach )->execute([$this->user_id])->fetchOne(); 260a25f0a04SGreg Roach 261015c99a2SGreg Roach if (password_verify($password, $password_hash)) { 262015c99a2SGreg Roach if (password_needs_rehash($password_hash, PASSWORD_DEFAULT)) { 263a25f0a04SGreg Roach $this->setPassword($password); 264a25f0a04SGreg Roach } 265cbc1590aSGreg Roach 266a25f0a04SGreg Roach return true; 267a25f0a04SGreg Roach } else { 268a25f0a04SGreg Roach return false; 269a25f0a04SGreg Roach } 270a25f0a04SGreg Roach } 271a25f0a04SGreg Roach 272a25f0a04SGreg Roach /** 273f7fb7d41SGreg Roach * Get a list of all managers. 274f7fb7d41SGreg Roach * 275f7fb7d41SGreg Roach * @return User[] 276f7fb7d41SGreg Roach */ 277f7fb7d41SGreg Roach public static function managers() { 278f7fb7d41SGreg Roach $rows = Database::prepare( 279f7fb7d41SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 280f7fb7d41SGreg Roach " FROM `##user` JOIN `##user_gedcom_setting` USING (user_id)" . 281f7fb7d41SGreg Roach " WHERE setting_name = 'canedit' AND setting_value='admin'" . 282f7fb7d41SGreg Roach " GROUP BY user_id, real_name" . 283f7fb7d41SGreg Roach " ORDER BY real_name" 284f7fb7d41SGreg Roach )->fetchAll(); 285f7fb7d41SGreg Roach 2868d68cabeSGreg Roach return array_map(function($row) { 2878d68cabeSGreg Roach return new static($row); 2888d68cabeSGreg Roach }, $rows); 289f7fb7d41SGreg Roach } 290f7fb7d41SGreg Roach 291f7fb7d41SGreg Roach /** 292f7fb7d41SGreg Roach * Get a list of all moderators. 293f7fb7d41SGreg Roach * 294f7fb7d41SGreg Roach * @return User[] 295f7fb7d41SGreg Roach */ 296f7fb7d41SGreg Roach public static function moderators() { 297f7fb7d41SGreg Roach $rows = Database::prepare( 298f7fb7d41SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 299f7fb7d41SGreg Roach " FROM `##user` JOIN `##user_gedcom_setting` USING (user_id)" . 300f7fb7d41SGreg Roach " WHERE setting_name = 'canedit' AND setting_value='accept'" . 301f7fb7d41SGreg Roach " GROUP BY user_id, real_name" . 302f7fb7d41SGreg Roach " ORDER BY real_name" 303f7fb7d41SGreg Roach )->fetchAll(); 304f7fb7d41SGreg Roach 3058d68cabeSGreg Roach return array_map(function($row) { 3068d68cabeSGreg Roach return new static($row); 3078d68cabeSGreg Roach }, $rows); 308f7fb7d41SGreg Roach } 309f7fb7d41SGreg Roach 310f7fb7d41SGreg Roach /** 311f7fb7d41SGreg Roach * Get a list of all verified users. 312f7fb7d41SGreg Roach * 313f7fb7d41SGreg Roach * @return User[] 314f7fb7d41SGreg Roach */ 315f7fb7d41SGreg Roach public static function unapproved() { 316f7fb7d41SGreg Roach $rows = Database::prepare( 317f7fb7d41SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 318f7fb7d41SGreg Roach " FROM `##user` JOIN `##user_setting` USING (user_id)" . 319f7fb7d41SGreg Roach " WHERE setting_name = 'verified_by_admin' AND setting_value = '0'" . 320f7fb7d41SGreg Roach " ORDER BY real_name" 321f7fb7d41SGreg Roach )->fetchAll(); 322f7fb7d41SGreg Roach 3238d68cabeSGreg Roach return array_map(function($row) { 3248d68cabeSGreg Roach return new static($row); 3258d68cabeSGreg Roach }, $rows); 326f7fb7d41SGreg Roach } 327f7fb7d41SGreg Roach 328f7fb7d41SGreg Roach /** 329f7fb7d41SGreg Roach * Get a list of all verified users. 330f7fb7d41SGreg Roach * 331f7fb7d41SGreg Roach * @return User[] 332f7fb7d41SGreg Roach */ 333f7fb7d41SGreg Roach public static function unverified() { 334f7fb7d41SGreg Roach $rows = Database::prepare( 335f7fb7d41SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 336f7fb7d41SGreg Roach " FROM `##user` JOIN `##user_setting` USING (user_id)" . 337f7fb7d41SGreg Roach " WHERE setting_name = 'verified' AND setting_value = '0'" . 338f7fb7d41SGreg Roach " ORDER BY real_name" 339f7fb7d41SGreg Roach )->fetchAll(); 340f7fb7d41SGreg Roach 3418d68cabeSGreg Roach return array_map(function($row) { 3428d68cabeSGreg Roach return new static($row); 3438d68cabeSGreg Roach }, $rows); 344f7fb7d41SGreg Roach } 345f7fb7d41SGreg Roach 346f7fb7d41SGreg Roach /** 347f7fb7d41SGreg Roach * Get a list of all users who are currently logged in. 348f7fb7d41SGreg Roach * 349f7fb7d41SGreg Roach * @return User[] 350f7fb7d41SGreg Roach */ 351f7fb7d41SGreg Roach public static function allLoggedIn() { 352f7fb7d41SGreg Roach $rows = Database::prepare( 353f7fb7d41SGreg Roach "SELECT SQL_NO_CACHE DISTINCT user_id, user_name, real_name, email" . 354f7fb7d41SGreg Roach " FROM `##user`" . 355f7fb7d41SGreg Roach " JOIN `##session` USING (user_id)" 356f7fb7d41SGreg Roach )->fetchAll(); 357f7fb7d41SGreg Roach 3588d68cabeSGreg Roach return array_map(function($row) { 3598d68cabeSGreg Roach return new static($row); 3608d68cabeSGreg Roach }, $rows); 361f7fb7d41SGreg Roach } 362f7fb7d41SGreg Roach 363f7fb7d41SGreg Roach /** 364a25f0a04SGreg Roach * Get the numeric ID for this user. 365a25f0a04SGreg Roach * 366*c04dd3c1SGreg Roach * @return int 367a25f0a04SGreg Roach */ 368*c04dd3c1SGreg Roach public function getUserId(): int { 369a25f0a04SGreg Roach return $this->user_id; 370a25f0a04SGreg Roach } 371a25f0a04SGreg Roach 372a25f0a04SGreg Roach /** 373a25f0a04SGreg Roach * Get the login name for this user. 374a25f0a04SGreg Roach * 375a25f0a04SGreg Roach * @return string 376a25f0a04SGreg Roach */ 377a25f0a04SGreg Roach public function getUserName() { 378a25f0a04SGreg Roach return $this->user_name; 379a25f0a04SGreg Roach } 380a25f0a04SGreg Roach 381a25f0a04SGreg Roach /** 382a25f0a04SGreg Roach * Set the login name for this user. 383a25f0a04SGreg Roach * 384a25f0a04SGreg Roach * @param string $user_name 385a25f0a04SGreg Roach * 386a25f0a04SGreg Roach * @return $this 387a25f0a04SGreg Roach */ 388a25f0a04SGreg Roach public function setUserName($user_name) { 389a25f0a04SGreg Roach if ($this->user_name !== $user_name) { 390a25f0a04SGreg Roach $this->user_name = $user_name; 391a25f0a04SGreg Roach Database::prepare( 392a25f0a04SGreg Roach "UPDATE `##user` SET user_name = ? WHERE user_id = ?" 39313abd6f3SGreg Roach )->execute([$user_name, $this->user_id]); 394a25f0a04SGreg Roach } 395a25f0a04SGreg Roach 396a25f0a04SGreg Roach return $this; 397a25f0a04SGreg Roach } 398a25f0a04SGreg Roach 399a25f0a04SGreg Roach /** 400a25f0a04SGreg Roach * Get the real name of this user. 401a25f0a04SGreg Roach * 402a25f0a04SGreg Roach * @return string 403a25f0a04SGreg Roach */ 404a25f0a04SGreg Roach public function getRealName() { 405a25f0a04SGreg Roach return $this->real_name; 406a25f0a04SGreg Roach } 407a25f0a04SGreg Roach 408a25f0a04SGreg Roach /** 409524c0fabSGreg Roach * Get the real name of this user, for display on screen. 410524c0fabSGreg Roach * 411524c0fabSGreg Roach * @return string 412524c0fabSGreg Roach */ 413524c0fabSGreg Roach public function getRealNameHtml() { 414cc5ab399SGreg Roach return '<span dir="auto">' . Html::escape($this->real_name) . '</span>'; 415524c0fabSGreg Roach } 416524c0fabSGreg Roach 417524c0fabSGreg Roach /** 418a25f0a04SGreg Roach * Set the real name of this user. 419a25f0a04SGreg Roach * 420a25f0a04SGreg Roach * @param string $real_name 421a25f0a04SGreg Roach * 422a25f0a04SGreg Roach * @return User 423a25f0a04SGreg Roach */ 424a25f0a04SGreg Roach public function setRealName($real_name) { 425a25f0a04SGreg Roach if ($this->real_name !== $real_name) { 426a25f0a04SGreg Roach $this->real_name = $real_name; 427a25f0a04SGreg Roach Database::prepare( 428a25f0a04SGreg Roach "UPDATE `##user` SET real_name = ? WHERE user_id = ?" 42913abd6f3SGreg Roach )->execute([$real_name, $this->user_id]); 430a25f0a04SGreg Roach } 431a25f0a04SGreg Roach 432a25f0a04SGreg Roach return $this; 433a25f0a04SGreg Roach } 434a25f0a04SGreg Roach 435a25f0a04SGreg Roach /** 436a25f0a04SGreg Roach * Get the email address of this user. 437a25f0a04SGreg Roach * 438a25f0a04SGreg Roach * @return string 439a25f0a04SGreg Roach */ 440a25f0a04SGreg Roach public function getEmail() { 441a25f0a04SGreg Roach return $this->email; 442a25f0a04SGreg Roach } 443a25f0a04SGreg Roach 444a25f0a04SGreg Roach /** 445a25f0a04SGreg Roach * Set the email address of this user. 446a25f0a04SGreg Roach * 447a25f0a04SGreg Roach * @param string $email 448a25f0a04SGreg Roach * 449a25f0a04SGreg Roach * @return User 450a25f0a04SGreg Roach */ 451a25f0a04SGreg Roach public function setEmail($email) { 452a25f0a04SGreg Roach if ($this->email !== $email) { 453a25f0a04SGreg Roach $this->email = $email; 454a25f0a04SGreg Roach Database::prepare( 455a25f0a04SGreg Roach "UPDATE `##user` SET email = ? WHERE user_id = ?" 45613abd6f3SGreg Roach )->execute([$email, $this->user_id]); 457a25f0a04SGreg Roach } 458a25f0a04SGreg Roach 459a25f0a04SGreg Roach return $this; 460a25f0a04SGreg Roach } 461a25f0a04SGreg Roach 462a25f0a04SGreg Roach /** 463a25f0a04SGreg Roach * Set the password of this user. 464a25f0a04SGreg Roach * 465a25f0a04SGreg Roach * @param string $password 466a25f0a04SGreg Roach * 467a25f0a04SGreg Roach * @return User 468a25f0a04SGreg Roach */ 469a25f0a04SGreg Roach public function setPassword($password) { 470a25f0a04SGreg Roach Database::prepare( 471015c99a2SGreg Roach "UPDATE `##user` SET password = :password WHERE user_id = :user_id" 472015c99a2SGreg Roach )->execute([ 473015c99a2SGreg Roach 'password' => password_hash($password, PASSWORD_DEFAULT), 474015c99a2SGreg Roach 'user_id' => $this->user_id, 475015c99a2SGreg Roach ]); 476a25f0a04SGreg Roach 477a25f0a04SGreg Roach return $this; 478a25f0a04SGreg Roach } 479a25f0a04SGreg Roach 480a25f0a04SGreg Roach /** 481a25f0a04SGreg Roach * Fetch a user option/setting from the wt_user_setting table. 482a25f0a04SGreg Roach * 483a25f0a04SGreg Roach * Since we'll fetch several settings for each user, and since there aren’t 484a25f0a04SGreg Roach * that many of them, fetch them all in one database query 485a25f0a04SGreg Roach * 486a25f0a04SGreg Roach * @param string $setting_name 48715d603e7SGreg Roach * @param string $default 488a25f0a04SGreg Roach * 48915d603e7SGreg Roach * @return string 490a25f0a04SGreg Roach */ 49115d603e7SGreg Roach public function getPreference($setting_name, $default = '') { 492*c04dd3c1SGreg Roach if (empty($this->preferences) && $this->user_id !== 0) { 493a25f0a04SGreg Roach $this->preferences = Database::prepare( 49415d603e7SGreg Roach "SELECT SQL_CACHE setting_name, setting_value" . 49515d603e7SGreg Roach " FROM `##user_setting`" . 49615d603e7SGreg Roach " WHERE user_id = :user_id" 49715d603e7SGreg Roach )->execute([ 49815d603e7SGreg Roach 'user_id' => $this->user_id, 49915d603e7SGreg Roach ])->fetchAssoc(); 500a25f0a04SGreg Roach } 501a25f0a04SGreg Roach 50215d603e7SGreg Roach if (!array_key_exists($setting_name, $this->preferences)) { 50315d603e7SGreg Roach $this->preferences[$setting_name] = $default; 504a25f0a04SGreg Roach } 50515d603e7SGreg Roach 50615d603e7SGreg Roach return $this->preferences[$setting_name]; 507a25f0a04SGreg Roach } 508a25f0a04SGreg Roach 509a25f0a04SGreg Roach /** 510a25f0a04SGreg Roach * Update a setting for the user. 511a25f0a04SGreg Roach * 512a25f0a04SGreg Roach * @param string $setting_name 513a25f0a04SGreg Roach * @param string $setting_value 514a25f0a04SGreg Roach * 515a25f0a04SGreg Roach * @return User 516a25f0a04SGreg Roach */ 517a25f0a04SGreg Roach public function setPreference($setting_name, $setting_value) { 518*c04dd3c1SGreg Roach if ($this->user_id !== 0 && $this->getPreference($setting_name) !== $setting_value) { 519a25f0a04SGreg Roach Database::prepare("REPLACE INTO `##user_setting` (user_id, setting_name, setting_value) VALUES (?, ?, LEFT(?, 255))") 52013abd6f3SGreg Roach ->execute([$this->user_id, $setting_name, $setting_value]); 52115d603e7SGreg Roach 522a25f0a04SGreg Roach $this->preferences[$setting_name] = $setting_value; 523a25f0a04SGreg Roach } 524a25f0a04SGreg Roach 525a25f0a04SGreg Roach return $this; 526a25f0a04SGreg Roach } 527a25f0a04SGreg Roach} 528