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