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 1860bc3e3fSGreg Roachuse stdclass; 1960bc3e3fSGreg 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 /** 43*f7fb7d41SGreg Roach * Create a new user object from a row in the database. 44*f7fb7d41SGreg Roach * 45*f7fb7d41SGreg Roach * @param stdclass $user A row from the wt_user table 46*f7fb7d41SGreg Roach */ 47*f7fb7d41SGreg Roach public function __construct(stdClass $user) { 48*f7fb7d41SGreg Roach $this->user_id = $user->user_id; 49*f7fb7d41SGreg Roach $this->user_name = $user->user_name; 50*f7fb7d41SGreg Roach $this->real_name = $user->real_name; 51*f7fb7d41SGreg Roach $this->email = $user->email; 52*f7fb7d41SGreg Roach } 53*f7fb7d41SGreg Roach 54*f7fb7d41SGreg Roach /** 55*f7fb7d41SGreg Roach * Create a new user. 56*f7fb7d41SGreg Roach * 57*f7fb7d41SGreg Roach * The calling code needs to check for duplicates identifiers before calling 58*f7fb7d41SGreg Roach * this function. 59*f7fb7d41SGreg Roach * 60*f7fb7d41SGreg Roach * @param string $user_name 61*f7fb7d41SGreg Roach * @param string $real_name 62*f7fb7d41SGreg Roach * @param string $email 63*f7fb7d41SGreg Roach * @param string $password 64*f7fb7d41SGreg Roach * 65*f7fb7d41SGreg Roach * @return User 66*f7fb7d41SGreg Roach */ 67*f7fb7d41SGreg Roach public static function create($user_name, $real_name, $email, $password) { 68*f7fb7d41SGreg Roach Database::prepare( 69*f7fb7d41SGreg Roach "INSERT INTO `##user` (user_name, real_name, email, password) VALUES (:user_name, :real_name, :email, :password)" 70*f7fb7d41SGreg Roach )->execute([ 71*f7fb7d41SGreg Roach 'user_name' => $user_name, 72*f7fb7d41SGreg Roach 'real_name' => $real_name, 73*f7fb7d41SGreg Roach 'email' => $email, 74*f7fb7d41SGreg Roach 'password' => password_hash($password, PASSWORD_DEFAULT), 75*f7fb7d41SGreg Roach ]); 76*f7fb7d41SGreg Roach 77*f7fb7d41SGreg Roach // Set default blocks for this user 78*f7fb7d41SGreg Roach $user = self::findByIdentifier($user_name); 79*f7fb7d41SGreg Roach Database::prepare( 80*f7fb7d41SGreg Roach "INSERT INTO `##block` (`user_id`, `location`, `block_order`, `module_name`)" . 81*f7fb7d41SGreg Roach " SELECT :user_id , `location`, `block_order`, `module_name` FROM `##block` WHERE `user_id` = -1" 82*f7fb7d41SGreg Roach )->execute(['user_id' => $user->getUserId()]); 83*f7fb7d41SGreg Roach 84*f7fb7d41SGreg Roach return $user; 85*f7fb7d41SGreg Roach } 86*f7fb7d41SGreg Roach 87*f7fb7d41SGreg Roach /** 88*f7fb7d41SGreg Roach * Delete a user 89*f7fb7d41SGreg Roach */ 90*f7fb7d41SGreg Roach public function delete() { 91*f7fb7d41SGreg Roach // Don't delete the logs. 92*f7fb7d41SGreg Roach Database::prepare("UPDATE `##log` SET user_id=NULL WHERE user_id =?")->execute([$this->user_id]); 93*f7fb7d41SGreg Roach // Take over the user’s pending changes. (What else could we do with them?) 94*f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##change` WHERE user_id=? AND status='rejected'")->execute([$this->user_id]); 95*f7fb7d41SGreg Roach Database::prepare("UPDATE `##change` SET user_id=? WHERE user_id=?")->execute([Auth::id(), $this->user_id]); 96*f7fb7d41SGreg Roach Database::prepare("DELETE `##block_setting` FROM `##block_setting` JOIN `##block` USING (block_id) WHERE user_id=?")->execute([$this->user_id]); 97*f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##block` WHERE user_id=?")->execute([$this->user_id]); 98*f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##user_gedcom_setting` WHERE user_id=?")->execute([$this->user_id]); 99*f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##gedcom_setting` WHERE setting_value=? AND setting_name IN ('CONTACT_USER_ID', 'WEBMASTER_USER_ID')")->execute([$this->user_id]); 100*f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##user_setting` WHERE user_id=?")->execute([$this->user_id]); 101*f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##message` WHERE user_id=?")->execute([$this->user_id]); 102*f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##user` WHERE user_id=?")->execute([$this->user_id]); 103*f7fb7d41SGreg Roach } 104*f7fb7d41SGreg Roach 105*f7fb7d41SGreg Roach /** 106a25f0a04SGreg Roach * Find the user with a specified user_id. 107a25f0a04SGreg Roach * 108cbc1590aSGreg Roach * @param int|null $user_id 109a25f0a04SGreg Roach * 110a25f0a04SGreg Roach * @return User|null 111a25f0a04SGreg Roach */ 112a25f0a04SGreg Roach public static function find($user_id) { 113a25f0a04SGreg Roach if (!array_key_exists($user_id, self::$cache)) { 114a25f0a04SGreg Roach $row = Database::prepare( 115a25f0a04SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email FROM `##user` WHERE user_id = ?" 11613abd6f3SGreg Roach )->execute([$user_id])->fetchOneRow(); 117a25f0a04SGreg Roach if ($row) { 11806ef8e02SGreg Roach self::$cache[$user_id] = new self($row); 119a25f0a04SGreg Roach } else { 120a25f0a04SGreg Roach self::$cache[$user_id] = null; 121a25f0a04SGreg Roach } 122a25f0a04SGreg Roach } 123a25f0a04SGreg Roach 124a25f0a04SGreg Roach return self::$cache[$user_id]; 125a25f0a04SGreg Roach } 126a25f0a04SGreg Roach 127a25f0a04SGreg Roach /** 128a982a56eSGreg Roach * Find the user with a specified email address. 129a982a56eSGreg Roach * 130a982a56eSGreg Roach * @param string $email 131a982a56eSGreg Roach * 132a982a56eSGreg Roach * @return User|null 133a982a56eSGreg Roach */ 134a982a56eSGreg Roach public static function findByEmail($email) { 135a982a56eSGreg Roach $user_id = Database::prepare( 136a982a56eSGreg Roach "SELECT SQL_CACHE user_id FROM `##user` WHERE email = :email" 13713abd6f3SGreg Roach )->execute([ 138a982a56eSGreg Roach 'email' => $email, 13913abd6f3SGreg Roach ])->fetchOne(); 140a982a56eSGreg Roach 141a982a56eSGreg Roach return self::find($user_id); 142a982a56eSGreg Roach } 143a982a56eSGreg Roach 144a982a56eSGreg Roach /** 145a982a56eSGreg Roach * Find the user with a specified user_name or email address. 146a25f0a04SGreg Roach * 147a25f0a04SGreg Roach * @param string $identifier 148a25f0a04SGreg Roach * 149a25f0a04SGreg Roach * @return User|null 150a25f0a04SGreg Roach */ 151a25f0a04SGreg Roach public static function findByIdentifier($identifier) { 152a25f0a04SGreg Roach $user_id = Database::prepare( 153a25f0a04SGreg Roach "SELECT SQL_CACHE user_id FROM `##user` WHERE ? IN (user_name, email)" 15413abd6f3SGreg Roach )->execute([$identifier])->fetchOne(); 155a25f0a04SGreg Roach 156a25f0a04SGreg Roach return self::find($user_id); 157a25f0a04SGreg Roach } 158a25f0a04SGreg Roach 159a25f0a04SGreg Roach /** 160a25f0a04SGreg Roach * Find the user with a specified genealogy record. 161a25f0a04SGreg Roach * 162a25f0a04SGreg Roach * @param Individual $individual 163a25f0a04SGreg Roach * 164a25f0a04SGreg Roach * @return User|null 165a25f0a04SGreg Roach */ 166*f7fb7d41SGreg Roach public static function findByIndividual(Individual $individual) { 167a25f0a04SGreg Roach $user_id = Database::prepare( 168a25f0a04SGreg Roach "SELECT SQL_CACHE user_id" . 169a25f0a04SGreg Roach " FROM `##user_gedcom_setting`" . 170a5adda01SGreg Roach " WHERE gedcom_id = :tree_id AND setting_name = 'gedcomid' AND setting_value = :xref" 17113abd6f3SGreg Roach )->execute([ 172a5adda01SGreg Roach 'tree_id' => $individual->getTree()->getTreeId(), 173cbc1590aSGreg Roach 'xref' => $individual->getXref(), 17413abd6f3SGreg Roach ])->fetchOne(); 175a25f0a04SGreg Roach 176a25f0a04SGreg Roach return self::find($user_id); 177a25f0a04SGreg Roach } 178a25f0a04SGreg Roach 179a25f0a04SGreg Roach /** 180*f7fb7d41SGreg Roach * Find the user with a specified user_name. 181*f7fb7d41SGreg Roach * 182*f7fb7d41SGreg Roach * @param string $user_name 183*f7fb7d41SGreg Roach * 184*f7fb7d41SGreg Roach * @return User|null 185*f7fb7d41SGreg Roach */ 186*f7fb7d41SGreg Roach public static function findByUserName($user_name) { 187*f7fb7d41SGreg Roach $user_id = Database::prepare( 188*f7fb7d41SGreg Roach "SELECT SQL_CACHE user_id FROM `##user` WHERE user_name = :user_name" 189*f7fb7d41SGreg Roach )->execute([ 190*f7fb7d41SGreg Roach 'user_name' => $user_name, 191*f7fb7d41SGreg Roach ])->fetchOne(); 192*f7fb7d41SGreg Roach 193*f7fb7d41SGreg Roach return self::find($user_id); 194*f7fb7d41SGreg Roach } 195*f7fb7d41SGreg Roach 196*f7fb7d41SGreg Roach /** 197a25f0a04SGreg Roach * Find the latest user to register. 198a25f0a04SGreg Roach * 199a25f0a04SGreg Roach * @return User|null 200a25f0a04SGreg Roach */ 201a25f0a04SGreg Roach public static function findLatestToRegister() { 202a25f0a04SGreg Roach $user_id = Database::prepare( 203a25f0a04SGreg Roach "SELECT SQL_CACHE u.user_id" . 204a25f0a04SGreg Roach " FROM `##user` u" . 205a25f0a04SGreg Roach " LEFT JOIN `##user_setting` us ON (u.user_id=us.user_id AND us.setting_name='reg_timestamp') " . 206a25f0a04SGreg Roach " ORDER BY us.setting_value DESC LIMIT 1" 207a25f0a04SGreg Roach )->execute()->fetchOne(); 208a25f0a04SGreg Roach 209a25f0a04SGreg Roach return self::find($user_id); 210a25f0a04SGreg Roach } 211a25f0a04SGreg Roach 212a25f0a04SGreg Roach /** 213a25f0a04SGreg Roach * Get a list of all users. 214a25f0a04SGreg Roach * 215a25f0a04SGreg Roach * @return User[] 216a25f0a04SGreg Roach */ 217a25f0a04SGreg Roach public static function all() { 218a25f0a04SGreg Roach $rows = Database::prepare( 219a25f0a04SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 220a25f0a04SGreg Roach " FROM `##user`" . 221a25f0a04SGreg Roach " WHERE user_id > 0" . 222*f7fb7d41SGreg Roach " ORDER BY real_name" 223a25f0a04SGreg Roach )->fetchAll(); 224a25f0a04SGreg Roach 225*f7fb7d41SGreg Roach return array_map(function($row) { return new static($row); }, $rows); 226a25f0a04SGreg Roach } 227a25f0a04SGreg Roach 228a25f0a04SGreg Roach /** 229a25f0a04SGreg Roach * Get a list of all administrators. 230a25f0a04SGreg Roach * 231a25f0a04SGreg Roach * @return User[] 232a25f0a04SGreg Roach */ 233*f7fb7d41SGreg Roach public static function administrators() { 234a25f0a04SGreg Roach $rows = Database::prepare( 235a25f0a04SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 236a25f0a04SGreg Roach " FROM `##user`" . 237a25f0a04SGreg Roach " JOIN `##user_setting` USING (user_id)" . 238*f7fb7d41SGreg Roach " WHERE user_id > 0 AND setting_name = 'canadmin' AND setting_value = '1'" . 239*f7fb7d41SGreg Roach " ORDER BY real_name" 240a25f0a04SGreg Roach )->fetchAll(); 241a25f0a04SGreg Roach 242*f7fb7d41SGreg Roach return array_map(function($row) { return new static($row); }, $rows); 243a25f0a04SGreg Roach } 244a25f0a04SGreg Roach 245a25f0a04SGreg Roach /** Validate a supplied password 246a25f0a04SGreg Roach * @param string $password 247a25f0a04SGreg Roach * 248cbc1590aSGreg Roach * @return bool 249a25f0a04SGreg Roach */ 250a25f0a04SGreg Roach public function checkPassword($password) { 251a25f0a04SGreg Roach $password_hash = Database::prepare( 252a25f0a04SGreg Roach "SELECT password FROM `##user` WHERE user_id = ?" 25313abd6f3SGreg Roach )->execute([$this->user_id])->fetchOne(); 254a25f0a04SGreg Roach 255015c99a2SGreg Roach if (password_verify($password, $password_hash)) { 256015c99a2SGreg Roach if (password_needs_rehash($password_hash, PASSWORD_DEFAULT)) { 257a25f0a04SGreg Roach $this->setPassword($password); 258a25f0a04SGreg Roach } 259cbc1590aSGreg Roach 260a25f0a04SGreg Roach return true; 261a25f0a04SGreg Roach } else { 262a25f0a04SGreg Roach return false; 263a25f0a04SGreg Roach } 264a25f0a04SGreg Roach } 265a25f0a04SGreg Roach 266a25f0a04SGreg Roach /** 267*f7fb7d41SGreg Roach * Get a list of all managers. 268*f7fb7d41SGreg Roach * 269*f7fb7d41SGreg Roach * @return User[] 270*f7fb7d41SGreg Roach */ 271*f7fb7d41SGreg Roach public static function managers() { 272*f7fb7d41SGreg Roach $rows = Database::prepare( 273*f7fb7d41SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 274*f7fb7d41SGreg Roach " FROM `##user` JOIN `##user_gedcom_setting` USING (user_id)" . 275*f7fb7d41SGreg Roach " WHERE setting_name = 'canedit' AND setting_value='admin'" . 276*f7fb7d41SGreg Roach " GROUP BY user_id, real_name" . 277*f7fb7d41SGreg Roach " ORDER BY real_name" 278*f7fb7d41SGreg Roach )->fetchAll(); 279*f7fb7d41SGreg Roach 280*f7fb7d41SGreg Roach return array_map(function($row) { return new static($row); }, $rows); 281*f7fb7d41SGreg Roach } 282*f7fb7d41SGreg Roach 283*f7fb7d41SGreg Roach /** 284*f7fb7d41SGreg Roach * Get a list of all moderators. 285*f7fb7d41SGreg Roach * 286*f7fb7d41SGreg Roach * @return User[] 287*f7fb7d41SGreg Roach */ 288*f7fb7d41SGreg Roach public static function moderators() { 289*f7fb7d41SGreg Roach $rows = Database::prepare( 290*f7fb7d41SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 291*f7fb7d41SGreg Roach " FROM `##user` JOIN `##user_gedcom_setting` USING (user_id)" . 292*f7fb7d41SGreg Roach " WHERE setting_name = 'canedit' AND setting_value='accept'" . 293*f7fb7d41SGreg Roach " GROUP BY user_id, real_name" . 294*f7fb7d41SGreg Roach " ORDER BY real_name" 295*f7fb7d41SGreg Roach )->fetchAll(); 296*f7fb7d41SGreg Roach 297*f7fb7d41SGreg Roach return array_map(function($row) { return new static($row); }, $rows); 298*f7fb7d41SGreg Roach } 299*f7fb7d41SGreg Roach 300*f7fb7d41SGreg Roach /** 301*f7fb7d41SGreg Roach * Get a list of all verified users. 302*f7fb7d41SGreg Roach * 303*f7fb7d41SGreg Roach * @return User[] 304*f7fb7d41SGreg Roach */ 305*f7fb7d41SGreg Roach public static function unapproved() { 306*f7fb7d41SGreg Roach $rows = Database::prepare( 307*f7fb7d41SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 308*f7fb7d41SGreg Roach " FROM `##user` JOIN `##user_setting` USING (user_id)" . 309*f7fb7d41SGreg Roach " WHERE setting_name = 'verified_by_admin' AND setting_value = '0'" . 310*f7fb7d41SGreg Roach " ORDER BY real_name" 311*f7fb7d41SGreg Roach )->fetchAll(); 312*f7fb7d41SGreg Roach 313*f7fb7d41SGreg Roach return array_map(function($row) { return new static($row); }, $rows); 314*f7fb7d41SGreg Roach } 315*f7fb7d41SGreg Roach 316*f7fb7d41SGreg Roach /** 317*f7fb7d41SGreg Roach * Get a list of all verified users. 318*f7fb7d41SGreg Roach * 319*f7fb7d41SGreg Roach * @return User[] 320*f7fb7d41SGreg Roach */ 321*f7fb7d41SGreg Roach public static function unverified() { 322*f7fb7d41SGreg Roach $rows = Database::prepare( 323*f7fb7d41SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 324*f7fb7d41SGreg Roach " FROM `##user` JOIN `##user_setting` USING (user_id)" . 325*f7fb7d41SGreg Roach " WHERE setting_name = 'verified' AND setting_value = '0'" . 326*f7fb7d41SGreg Roach " ORDER BY real_name" 327*f7fb7d41SGreg Roach )->fetchAll(); 328*f7fb7d41SGreg Roach 329*f7fb7d41SGreg Roach return array_map(function($row) { return new static($row); }, $rows); 330*f7fb7d41SGreg Roach } 331*f7fb7d41SGreg Roach 332*f7fb7d41SGreg Roach /** 333*f7fb7d41SGreg Roach * Get a list of all users who are currently logged in. 334*f7fb7d41SGreg Roach * 335*f7fb7d41SGreg Roach * @return User[] 336*f7fb7d41SGreg Roach */ 337*f7fb7d41SGreg Roach public static function allLoggedIn() { 338*f7fb7d41SGreg Roach $rows = Database::prepare( 339*f7fb7d41SGreg Roach "SELECT SQL_NO_CACHE DISTINCT user_id, user_name, real_name, email" . 340*f7fb7d41SGreg Roach " FROM `##user`" . 341*f7fb7d41SGreg Roach " JOIN `##session` USING (user_id)" 342*f7fb7d41SGreg Roach )->fetchAll(); 343*f7fb7d41SGreg Roach 344*f7fb7d41SGreg Roach return array_map(function($row) { return new static($row); }, $rows); 345*f7fb7d41SGreg Roach } 346*f7fb7d41SGreg Roach 347*f7fb7d41SGreg Roach /** 348a25f0a04SGreg Roach * Get the numeric ID for this user. 349a25f0a04SGreg Roach * 350a25f0a04SGreg Roach * @return string 351a25f0a04SGreg Roach */ 352a25f0a04SGreg Roach public function getUserId() { 353a25f0a04SGreg Roach return $this->user_id; 354a25f0a04SGreg Roach } 355a25f0a04SGreg Roach 356a25f0a04SGreg Roach /** 357a25f0a04SGreg Roach * Get the login name for this user. 358a25f0a04SGreg Roach * 359a25f0a04SGreg Roach * @return string 360a25f0a04SGreg Roach */ 361a25f0a04SGreg Roach public function getUserName() { 362a25f0a04SGreg Roach return $this->user_name; 363a25f0a04SGreg Roach } 364a25f0a04SGreg Roach 365a25f0a04SGreg Roach /** 366a25f0a04SGreg Roach * Set the login name for this user. 367a25f0a04SGreg Roach * 368a25f0a04SGreg Roach * @param string $user_name 369a25f0a04SGreg Roach * 370a25f0a04SGreg Roach * @return $this 371a25f0a04SGreg Roach */ 372a25f0a04SGreg Roach public function setUserName($user_name) { 373a25f0a04SGreg Roach if ($this->user_name !== $user_name) { 374a25f0a04SGreg Roach $this->user_name = $user_name; 375a25f0a04SGreg Roach Database::prepare( 376a25f0a04SGreg Roach "UPDATE `##user` SET user_name = ? WHERE user_id = ?" 37713abd6f3SGreg Roach )->execute([$user_name, $this->user_id]); 378a25f0a04SGreg Roach } 379a25f0a04SGreg Roach 380a25f0a04SGreg Roach return $this; 381a25f0a04SGreg Roach } 382a25f0a04SGreg Roach 383a25f0a04SGreg Roach /** 384a25f0a04SGreg Roach * Get the real name of this user. 385a25f0a04SGreg Roach * 386a25f0a04SGreg Roach * @return string 387a25f0a04SGreg Roach */ 388a25f0a04SGreg Roach public function getRealName() { 389a25f0a04SGreg Roach return $this->real_name; 390a25f0a04SGreg Roach } 391a25f0a04SGreg Roach 392a25f0a04SGreg Roach /** 393524c0fabSGreg Roach * Get the real name of this user, for display on screen. 394524c0fabSGreg Roach * 395524c0fabSGreg Roach * @return string 396524c0fabSGreg Roach */ 397524c0fabSGreg Roach public function getRealNameHtml() { 398cc5ab399SGreg Roach return '<span dir="auto">' . Html::escape($this->real_name) . '</span>'; 399524c0fabSGreg Roach } 400524c0fabSGreg Roach 401524c0fabSGreg Roach /** 402a25f0a04SGreg Roach * Set the real name of this user. 403a25f0a04SGreg Roach * 404a25f0a04SGreg Roach * @param string $real_name 405a25f0a04SGreg Roach * 406a25f0a04SGreg Roach * @return User 407a25f0a04SGreg Roach */ 408a25f0a04SGreg Roach public function setRealName($real_name) { 409a25f0a04SGreg Roach if ($this->real_name !== $real_name) { 410a25f0a04SGreg Roach $this->real_name = $real_name; 411a25f0a04SGreg Roach Database::prepare( 412a25f0a04SGreg Roach "UPDATE `##user` SET real_name = ? WHERE user_id = ?" 41313abd6f3SGreg Roach )->execute([$real_name, $this->user_id]); 414a25f0a04SGreg Roach } 415a25f0a04SGreg Roach 416a25f0a04SGreg Roach return $this; 417a25f0a04SGreg Roach } 418a25f0a04SGreg Roach 419a25f0a04SGreg Roach /** 420a25f0a04SGreg Roach * Get the email address of this user. 421a25f0a04SGreg Roach * 422a25f0a04SGreg Roach * @return string 423a25f0a04SGreg Roach */ 424a25f0a04SGreg Roach public function getEmail() { 425a25f0a04SGreg Roach return $this->email; 426a25f0a04SGreg Roach } 427a25f0a04SGreg Roach 428a25f0a04SGreg Roach /** 429a25f0a04SGreg Roach * Set the email address of this user. 430a25f0a04SGreg Roach * 431a25f0a04SGreg Roach * @param string $email 432a25f0a04SGreg Roach * 433a25f0a04SGreg Roach * @return User 434a25f0a04SGreg Roach */ 435a25f0a04SGreg Roach public function setEmail($email) { 436a25f0a04SGreg Roach if ($this->email !== $email) { 437a25f0a04SGreg Roach $this->email = $email; 438a25f0a04SGreg Roach Database::prepare( 439a25f0a04SGreg Roach "UPDATE `##user` SET email = ? WHERE user_id = ?" 44013abd6f3SGreg Roach )->execute([$email, $this->user_id]); 441a25f0a04SGreg Roach } 442a25f0a04SGreg Roach 443a25f0a04SGreg Roach return $this; 444a25f0a04SGreg Roach } 445a25f0a04SGreg Roach 446a25f0a04SGreg Roach /** 447a25f0a04SGreg Roach * Set the password of this user. 448a25f0a04SGreg Roach * 449a25f0a04SGreg Roach * @param string $password 450a25f0a04SGreg Roach * 451a25f0a04SGreg Roach * @return User 452a25f0a04SGreg Roach */ 453a25f0a04SGreg Roach public function setPassword($password) { 454a25f0a04SGreg Roach Database::prepare( 455015c99a2SGreg Roach "UPDATE `##user` SET password = :password WHERE user_id = :user_id" 456015c99a2SGreg Roach )->execute([ 457015c99a2SGreg Roach 'password' => password_hash($password, PASSWORD_DEFAULT), 458015c99a2SGreg Roach 'user_id' => $this->user_id, 459015c99a2SGreg Roach ]); 460a25f0a04SGreg Roach 461a25f0a04SGreg Roach return $this; 462a25f0a04SGreg Roach } 463a25f0a04SGreg Roach 464a25f0a04SGreg Roach /** 465a25f0a04SGreg Roach * Fetch a user option/setting from the wt_user_setting table. 466a25f0a04SGreg Roach * 467a25f0a04SGreg Roach * Since we'll fetch several settings for each user, and since there aren’t 468a25f0a04SGreg Roach * that many of them, fetch them all in one database query 469a25f0a04SGreg Roach * 470a25f0a04SGreg Roach * @param string $setting_name 47115d603e7SGreg Roach * @param string $default 472a25f0a04SGreg Roach * 47315d603e7SGreg Roach * @return string 474a25f0a04SGreg Roach */ 47515d603e7SGreg Roach public function getPreference($setting_name, $default = '') { 47615d603e7SGreg Roach if (empty($this->preferences) && $this->user_id !== null) { 477a25f0a04SGreg Roach $this->preferences = Database::prepare( 47815d603e7SGreg Roach "SELECT SQL_CACHE setting_name, setting_value" . 47915d603e7SGreg Roach " FROM `##user_setting`" . 48015d603e7SGreg Roach " WHERE user_id = :user_id" 48115d603e7SGreg Roach )->execute([ 48215d603e7SGreg Roach 'user_id' => $this->user_id, 48315d603e7SGreg Roach ])->fetchAssoc(); 484a25f0a04SGreg Roach } 485a25f0a04SGreg Roach 48615d603e7SGreg Roach if (!array_key_exists($setting_name, $this->preferences)) { 48715d603e7SGreg Roach $this->preferences[$setting_name] = $default; 488a25f0a04SGreg Roach } 48915d603e7SGreg Roach 49015d603e7SGreg Roach return $this->preferences[$setting_name]; 491a25f0a04SGreg Roach } 492a25f0a04SGreg Roach 493a25f0a04SGreg Roach /** 494a25f0a04SGreg Roach * Update a setting for the user. 495a25f0a04SGreg Roach * 496a25f0a04SGreg Roach * @param string $setting_name 497a25f0a04SGreg Roach * @param string $setting_value 498a25f0a04SGreg Roach * 499a25f0a04SGreg Roach * @return User 500a25f0a04SGreg Roach */ 501a25f0a04SGreg Roach public function setPreference($setting_name, $setting_value) { 502a25f0a04SGreg Roach if ($this->user_id && $this->getPreference($setting_name) !== $setting_value) { 503a25f0a04SGreg Roach Database::prepare("REPLACE INTO `##user_setting` (user_id, setting_name, setting_value) VALUES (?, ?, LEFT(?, 255))") 50413abd6f3SGreg Roach ->execute([$this->user_id, $setting_name, $setting_value]); 50515d603e7SGreg Roach 506a25f0a04SGreg Roach $this->preferences[$setting_name] = $setting_value; 507a25f0a04SGreg Roach } 508a25f0a04SGreg Roach 509a25f0a04SGreg Roach return $this; 510a25f0a04SGreg Roach } 511a25f0a04SGreg Roach} 512