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 20b0b72ea4SGreg Roachuse stdClass; 2160bc3e3fSGreg Roach 22a25f0a04SGreg Roach/** 2376692c8bSGreg Roach * Provide an interface to the wt_user table. 24a25f0a04SGreg Roach */ 25c1010edaSGreg Roachclass User 26c1010edaSGreg 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 * 48b0b72ea4SGreg Roach * @param stdClass $user A row from the wt_user table 49f7fb7d41SGreg Roach */ 50c1010edaSGreg Roach public function __construct(stdClass $user) 51c1010edaSGreg 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 * The calling code needs to check for duplicates identifiers before calling 61f7fb7d41SGreg Roach * this function. 62f7fb7d41SGreg Roach * 63f7fb7d41SGreg Roach * @param string $user_name 64f7fb7d41SGreg Roach * @param string $real_name 65f7fb7d41SGreg Roach * @param string $email 66f7fb7d41SGreg Roach * @param string $password 67f7fb7d41SGreg Roach * 68f7fb7d41SGreg Roach * @return User 69f7fb7d41SGreg Roach */ 70c1010edaSGreg Roach public static function create($user_name, $real_name, $email, $password) 71c1010edaSGreg Roach { 72f7fb7d41SGreg Roach Database::prepare( 73f7fb7d41SGreg Roach "INSERT INTO `##user` (user_name, real_name, email, password) VALUES (:user_name, :real_name, :email, :password)" 74f7fb7d41SGreg Roach )->execute([ 75f7fb7d41SGreg Roach 'user_name' => $user_name, 76f7fb7d41SGreg Roach 'real_name' => $real_name, 77f7fb7d41SGreg Roach 'email' => $email, 78f7fb7d41SGreg Roach 'password' => password_hash($password, PASSWORD_DEFAULT), 79f7fb7d41SGreg Roach ]); 80f7fb7d41SGreg Roach 81f7fb7d41SGreg Roach // Set default blocks for this user 82f7fb7d41SGreg Roach $user = self::findByIdentifier($user_name); 83f7fb7d41SGreg Roach Database::prepare( 84f7fb7d41SGreg Roach "INSERT INTO `##block` (`user_id`, `location`, `block_order`, `module_name`)" . 85f7fb7d41SGreg Roach " SELECT :user_id , `location`, `block_order`, `module_name` FROM `##block` WHERE `user_id` = -1" 86fa4036e8SGreg Roach )->execute([ 87fa4036e8SGreg Roach 'user_id' => $user->getUserId(), 88fa4036e8SGreg Roach ]); 89f7fb7d41SGreg Roach 90f7fb7d41SGreg Roach return $user; 91f7fb7d41SGreg Roach } 92f7fb7d41SGreg Roach 93f7fb7d41SGreg Roach /** 94f7fb7d41SGreg Roach * Delete a user 95fa4036e8SGreg Roach * 96fa4036e8SGreg Roach * @return void 97f7fb7d41SGreg Roach */ 98c1010edaSGreg Roach public function delete() 99c1010edaSGreg Roach { 100f7fb7d41SGreg Roach // Don't delete the logs. 101f7fb7d41SGreg Roach Database::prepare("UPDATE `##log` SET user_id=NULL WHERE user_id =?")->execute([$this->user_id]); 102f7fb7d41SGreg Roach // Take over the user’s pending changes. (What else could we do with them?) 103f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##change` WHERE user_id=? AND status='rejected'")->execute([$this->user_id]); 104c1010edaSGreg Roach Database::prepare("UPDATE `##change` SET user_id=? WHERE user_id=?")->execute([ 105c1010edaSGreg Roach Auth::id(), 106c1010edaSGreg Roach $this->user_id, 107c1010edaSGreg Roach ]); 108f7fb7d41SGreg Roach Database::prepare("DELETE `##block_setting` FROM `##block_setting` JOIN `##block` USING (block_id) WHERE user_id=?")->execute([$this->user_id]); 109f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##block` WHERE user_id=?")->execute([$this->user_id]); 110f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##user_gedcom_setting` WHERE user_id=?")->execute([$this->user_id]); 1117ff5d33bSGreg 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]); 112f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##user_setting` WHERE user_id=?")->execute([$this->user_id]); 113f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##message` WHERE user_id=?")->execute([$this->user_id]); 114f7fb7d41SGreg Roach Database::prepare("DELETE FROM `##user` WHERE user_id=?")->execute([$this->user_id]); 115f7fb7d41SGreg Roach } 116f7fb7d41SGreg Roach 117f7fb7d41SGreg Roach /** 118a25f0a04SGreg Roach * Find the user with a specified user_id. 119a25f0a04SGreg Roach * 120cbc1590aSGreg Roach * @param int|null $user_id 121a25f0a04SGreg Roach * 122a25f0a04SGreg Roach * @return User|null 123a25f0a04SGreg Roach */ 124c1010edaSGreg Roach public static function find($user_id) 125c1010edaSGreg Roach { 126a25f0a04SGreg Roach if (!array_key_exists($user_id, self::$cache)) { 127a25f0a04SGreg Roach $row = Database::prepare( 128e5588fb0SGreg Roach "SELECT user_id, user_name, real_name, email FROM `##user` WHERE user_id = ?" 12913abd6f3SGreg Roach )->execute([$user_id])->fetchOneRow(); 130a25f0a04SGreg Roach if ($row) { 13106ef8e02SGreg Roach self::$cache[$user_id] = new self($row); 132a25f0a04SGreg Roach } else { 133a25f0a04SGreg Roach self::$cache[$user_id] = null; 134a25f0a04SGreg Roach } 135a25f0a04SGreg Roach } 136a25f0a04SGreg Roach 137a25f0a04SGreg Roach return self::$cache[$user_id]; 138a25f0a04SGreg Roach } 139a25f0a04SGreg Roach 140a25f0a04SGreg Roach /** 141a982a56eSGreg Roach * Find the user with a specified email address. 142a982a56eSGreg Roach * 143a982a56eSGreg Roach * @param string $email 144a982a56eSGreg Roach * 145a982a56eSGreg Roach * @return User|null 146a982a56eSGreg Roach */ 147c1010edaSGreg Roach public static function findByEmail($email) 148c1010edaSGreg Roach { 149fa4036e8SGreg Roach $user_id = (int) Database::prepare( 150e5588fb0SGreg Roach "SELECT user_id FROM `##user` WHERE email = :email" 15113abd6f3SGreg Roach )->execute([ 152a982a56eSGreg Roach 'email' => $email, 15313abd6f3SGreg Roach ])->fetchOne(); 154a982a56eSGreg Roach 155a982a56eSGreg Roach return self::find($user_id); 156a982a56eSGreg Roach } 157a982a56eSGreg Roach 158a982a56eSGreg Roach /** 159a982a56eSGreg Roach * Find the user with a specified user_name or email address. 160a25f0a04SGreg Roach * 161a25f0a04SGreg Roach * @param string $identifier 162a25f0a04SGreg Roach * 163a25f0a04SGreg Roach * @return User|null 164a25f0a04SGreg Roach */ 165c1010edaSGreg Roach public static function findByIdentifier($identifier) 166c1010edaSGreg Roach { 167fa4036e8SGreg Roach $user_id = (int) Database::prepare( 168e5588fb0SGreg Roach "SELECT user_id FROM `##user` WHERE ? IN (user_name, email)" 16913abd6f3SGreg Roach )->execute([$identifier])->fetchOne(); 170a25f0a04SGreg Roach 171a25f0a04SGreg Roach return self::find($user_id); 172a25f0a04SGreg Roach } 173a25f0a04SGreg Roach 174a25f0a04SGreg Roach /** 175a25f0a04SGreg Roach * Find the user with a specified genealogy record. 176a25f0a04SGreg Roach * 177a25f0a04SGreg Roach * @param Individual $individual 178a25f0a04SGreg Roach * 179a25f0a04SGreg Roach * @return User|null 180a25f0a04SGreg Roach */ 181c1010edaSGreg Roach public static function findByIndividual(Individual $individual) 182c1010edaSGreg Roach { 183fa4036e8SGreg Roach $user_id = (int) Database::prepare( 184e5588fb0SGreg Roach "SELECT user_id" . 185a25f0a04SGreg Roach " FROM `##user_gedcom_setting`" . 186a5adda01SGreg Roach " WHERE gedcom_id = :tree_id AND setting_name = 'gedcomid' AND setting_value = :xref" 18713abd6f3SGreg Roach )->execute([ 188a5adda01SGreg Roach 'tree_id' => $individual->getTree()->getTreeId(), 189cbc1590aSGreg Roach 'xref' => $individual->getXref(), 19013abd6f3SGreg Roach ])->fetchOne(); 191a25f0a04SGreg Roach 192a25f0a04SGreg Roach return self::find($user_id); 193a25f0a04SGreg Roach } 194a25f0a04SGreg Roach 195a25f0a04SGreg Roach /** 196f7fb7d41SGreg Roach * Find the user with a specified user_name. 197f7fb7d41SGreg Roach * 198f7fb7d41SGreg Roach * @param string $user_name 199f7fb7d41SGreg Roach * 200f7fb7d41SGreg Roach * @return User|null 201f7fb7d41SGreg Roach */ 202c1010edaSGreg Roach public static function findByUserName($user_name) 203c1010edaSGreg Roach { 204fa4036e8SGreg Roach $user_id = (int) Database::prepare( 205e5588fb0SGreg Roach "SELECT user_id FROM `##user` WHERE user_name = :user_name" 206f7fb7d41SGreg Roach )->execute([ 207f7fb7d41SGreg Roach 'user_name' => $user_name, 208f7fb7d41SGreg Roach ])->fetchOne(); 209f7fb7d41SGreg Roach 210f7fb7d41SGreg Roach return self::find($user_id); 211f7fb7d41SGreg Roach } 212f7fb7d41SGreg Roach 213f7fb7d41SGreg Roach /** 214a25f0a04SGreg Roach * Find the latest user to register. 215a25f0a04SGreg Roach * 216a25f0a04SGreg Roach * @return User|null 217a25f0a04SGreg Roach */ 218c1010edaSGreg Roach public static function findLatestToRegister() 219c1010edaSGreg Roach { 220fa4036e8SGreg Roach $user_id = (int) Database::prepare( 221e5588fb0SGreg Roach "SELECT u.user_id" . 222a25f0a04SGreg Roach " FROM `##user` u" . 223a25f0a04SGreg Roach " LEFT JOIN `##user_setting` us ON (u.user_id=us.user_id AND us.setting_name='reg_timestamp') " . 224a25f0a04SGreg Roach " ORDER BY us.setting_value DESC LIMIT 1" 225a25f0a04SGreg Roach )->execute()->fetchOne(); 226a25f0a04SGreg Roach 227a25f0a04SGreg Roach return self::find($user_id); 228a25f0a04SGreg Roach } 229a25f0a04SGreg Roach 230a25f0a04SGreg Roach /** 231a25f0a04SGreg Roach * Get a list of all users. 232a25f0a04SGreg Roach * 233a25f0a04SGreg Roach * @return User[] 234a25f0a04SGreg Roach */ 235fa4036e8SGreg Roach public static function all(): array 236c1010edaSGreg Roach { 237a25f0a04SGreg Roach $rows = Database::prepare( 238e5588fb0SGreg Roach "SELECT user_id, user_name, real_name, email" . 239a25f0a04SGreg Roach " FROM `##user`" . 240a25f0a04SGreg Roach " WHERE user_id > 0" . 241f7fb7d41SGreg Roach " ORDER BY real_name" 242a25f0a04SGreg Roach )->fetchAll(); 243a25f0a04SGreg Roach 244*59f2f229SGreg Roach return array_map(function (stdClass $row): User { 2458d68cabeSGreg Roach return new static($row); 2468d68cabeSGreg Roach }, $rows); 247a25f0a04SGreg Roach } 248a25f0a04SGreg Roach 249a25f0a04SGreg Roach /** 250a25f0a04SGreg Roach * Get a list of all administrators. 251a25f0a04SGreg Roach * 252a25f0a04SGreg Roach * @return User[] 253a25f0a04SGreg Roach */ 254fa4036e8SGreg Roach public static function administrators(): array 255c1010edaSGreg Roach { 256a25f0a04SGreg Roach $rows = Database::prepare( 257e5588fb0SGreg Roach "SELECT user_id, user_name, real_name, email" . 258a25f0a04SGreg Roach " FROM `##user`" . 259a25f0a04SGreg Roach " JOIN `##user_setting` USING (user_id)" . 260f7fb7d41SGreg Roach " WHERE user_id > 0 AND setting_name = 'canadmin' AND setting_value = '1'" . 261f7fb7d41SGreg Roach " ORDER BY real_name" 262a25f0a04SGreg Roach )->fetchAll(); 263a25f0a04SGreg Roach 264fa4036e8SGreg Roach return array_map(function (stdClass $row) { 2658d68cabeSGreg Roach return new static($row); 2668d68cabeSGreg Roach }, $rows); 267a25f0a04SGreg Roach } 268a25f0a04SGreg Roach 269fa4036e8SGreg Roach /** 270fa4036e8SGreg Roach * Validate a supplied password 271c1010edaSGreg Roach * 272a25f0a04SGreg Roach * @param string $password 273a25f0a04SGreg Roach * 274cbc1590aSGreg Roach * @return bool 275a25f0a04SGreg Roach */ 276fa4036e8SGreg Roach public function checkPassword(string $password): bool 277c1010edaSGreg Roach { 278a25f0a04SGreg Roach $password_hash = Database::prepare( 279a25f0a04SGreg Roach "SELECT password FROM `##user` WHERE user_id = ?" 28013abd6f3SGreg Roach )->execute([$this->user_id])->fetchOne(); 281a25f0a04SGreg Roach 282015c99a2SGreg Roach if (password_verify($password, $password_hash)) { 283015c99a2SGreg Roach if (password_needs_rehash($password_hash, PASSWORD_DEFAULT)) { 284a25f0a04SGreg Roach $this->setPassword($password); 285a25f0a04SGreg Roach } 286cbc1590aSGreg Roach 287a25f0a04SGreg Roach return true; 288a25f0a04SGreg Roach } else { 289a25f0a04SGreg Roach return false; 290a25f0a04SGreg Roach } 291a25f0a04SGreg Roach } 292a25f0a04SGreg Roach 293a25f0a04SGreg Roach /** 294f7fb7d41SGreg Roach * Get a list of all managers. 295f7fb7d41SGreg Roach * 296f7fb7d41SGreg Roach * @return User[] 297f7fb7d41SGreg Roach */ 298fa4036e8SGreg Roach public static function managers(): array 299c1010edaSGreg Roach { 300f7fb7d41SGreg Roach $rows = Database::prepare( 301e5588fb0SGreg Roach "SELECT user_id, user_name, real_name, email" . 302f7fb7d41SGreg Roach " FROM `##user` JOIN `##user_gedcom_setting` USING (user_id)" . 303f7fb7d41SGreg Roach " WHERE setting_name = 'canedit' AND setting_value='admin'" . 304f7fb7d41SGreg Roach " GROUP BY user_id, real_name" . 305f7fb7d41SGreg Roach " ORDER BY real_name" 306f7fb7d41SGreg Roach )->fetchAll(); 307f7fb7d41SGreg Roach 308*59f2f229SGreg Roach return array_map(function (stdClass $row): User { 3098d68cabeSGreg Roach return new static($row); 3108d68cabeSGreg Roach }, $rows); 311f7fb7d41SGreg Roach } 312f7fb7d41SGreg Roach 313f7fb7d41SGreg Roach /** 314f7fb7d41SGreg Roach * Get a list of all moderators. 315f7fb7d41SGreg Roach * 316f7fb7d41SGreg Roach * @return User[] 317f7fb7d41SGreg Roach */ 318fa4036e8SGreg Roach public static function moderators(): array 319c1010edaSGreg Roach { 320f7fb7d41SGreg Roach $rows = Database::prepare( 321e5588fb0SGreg Roach "SELECT user_id, user_name, real_name, email" . 322f7fb7d41SGreg Roach " FROM `##user` JOIN `##user_gedcom_setting` USING (user_id)" . 323f7fb7d41SGreg Roach " WHERE setting_name = 'canedit' AND setting_value='accept'" . 324f7fb7d41SGreg Roach " GROUP BY user_id, real_name" . 325f7fb7d41SGreg Roach " ORDER BY real_name" 326f7fb7d41SGreg Roach )->fetchAll(); 327f7fb7d41SGreg Roach 328*59f2f229SGreg Roach return array_map(function (stdClass $row): User { 3298d68cabeSGreg Roach return new static($row); 3308d68cabeSGreg Roach }, $rows); 331f7fb7d41SGreg Roach } 332f7fb7d41SGreg Roach 333f7fb7d41SGreg Roach /** 334f7fb7d41SGreg Roach * Get a list of all verified users. 335f7fb7d41SGreg Roach * 336f7fb7d41SGreg Roach * @return User[] 337f7fb7d41SGreg Roach */ 338fa4036e8SGreg Roach public static function unapproved(): array 339c1010edaSGreg Roach { 340f7fb7d41SGreg Roach $rows = Database::prepare( 341e5588fb0SGreg Roach "SELECT user_id, user_name, real_name, email" . 342f7fb7d41SGreg Roach " FROM `##user` JOIN `##user_setting` USING (user_id)" . 343f7fb7d41SGreg Roach " WHERE setting_name = 'verified_by_admin' AND setting_value = '0'" . 344f7fb7d41SGreg Roach " ORDER BY real_name" 345f7fb7d41SGreg Roach )->fetchAll(); 346f7fb7d41SGreg Roach 347*59f2f229SGreg Roach return array_map(function (stdClass $row): User { 3488d68cabeSGreg Roach return new static($row); 3498d68cabeSGreg Roach }, $rows); 350f7fb7d41SGreg Roach } 351f7fb7d41SGreg Roach 352f7fb7d41SGreg Roach /** 353f7fb7d41SGreg Roach * Get a list of all verified users. 354f7fb7d41SGreg Roach * 355f7fb7d41SGreg Roach * @return User[] 356f7fb7d41SGreg Roach */ 357fa4036e8SGreg Roach public static function unverified(): array 358c1010edaSGreg Roach { 359f7fb7d41SGreg Roach $rows = Database::prepare( 360e5588fb0SGreg Roach "SELECT user_id, user_name, real_name, email" . 361f7fb7d41SGreg Roach " FROM `##user` JOIN `##user_setting` USING (user_id)" . 362f7fb7d41SGreg Roach " WHERE setting_name = 'verified' AND setting_value = '0'" . 363f7fb7d41SGreg Roach " ORDER BY real_name" 364f7fb7d41SGreg Roach )->fetchAll(); 365f7fb7d41SGreg Roach 366*59f2f229SGreg Roach return array_map(function (stdClass $row): User { 3678d68cabeSGreg Roach return new static($row); 3688d68cabeSGreg Roach }, $rows); 369f7fb7d41SGreg Roach } 370f7fb7d41SGreg Roach 371f7fb7d41SGreg Roach /** 372f7fb7d41SGreg Roach * Get a list of all users who are currently logged in. 373f7fb7d41SGreg Roach * 374f7fb7d41SGreg Roach * @return User[] 375f7fb7d41SGreg Roach */ 376fa4036e8SGreg Roach public static function allLoggedIn(): array 377c1010edaSGreg Roach { 378f7fb7d41SGreg Roach $rows = Database::prepare( 379e5588fb0SGreg Roach "SELECT DISTINCT user_id, user_name, real_name, email" . 380f7fb7d41SGreg Roach " FROM `##user`" . 381f7fb7d41SGreg Roach " JOIN `##session` USING (user_id)" 382f7fb7d41SGreg Roach )->fetchAll(); 383f7fb7d41SGreg Roach 384*59f2f229SGreg Roach return array_map(function (stdClass $row): User { 3858d68cabeSGreg Roach return new static($row); 3868d68cabeSGreg Roach }, $rows); 387f7fb7d41SGreg Roach } 388f7fb7d41SGreg Roach 389f7fb7d41SGreg Roach /** 390a25f0a04SGreg Roach * Get the numeric ID for this user. 391a25f0a04SGreg Roach * 392c04dd3c1SGreg Roach * @return int 393a25f0a04SGreg Roach */ 394c1010edaSGreg Roach public function getUserId(): int 395c1010edaSGreg Roach { 396a25f0a04SGreg Roach return $this->user_id; 397a25f0a04SGreg Roach } 398a25f0a04SGreg Roach 399a25f0a04SGreg Roach /** 400a25f0a04SGreg Roach * Get the login name for this user. 401a25f0a04SGreg Roach * 402a25f0a04SGreg Roach * @return string 403a25f0a04SGreg Roach */ 404c1010edaSGreg Roach public function getUserName() 405c1010edaSGreg Roach { 406a25f0a04SGreg Roach return $this->user_name; 407a25f0a04SGreg Roach } 408a25f0a04SGreg Roach 409a25f0a04SGreg Roach /** 410a25f0a04SGreg Roach * Set the login name for this user. 411a25f0a04SGreg Roach * 412a25f0a04SGreg Roach * @param string $user_name 413a25f0a04SGreg Roach * 414a25f0a04SGreg Roach * @return $this 415a25f0a04SGreg Roach */ 416c1010edaSGreg Roach public function setUserName($user_name) 417c1010edaSGreg Roach { 418a25f0a04SGreg Roach if ($this->user_name !== $user_name) { 419a25f0a04SGreg Roach $this->user_name = $user_name; 420a25f0a04SGreg Roach Database::prepare( 421a25f0a04SGreg Roach "UPDATE `##user` SET user_name = ? WHERE user_id = ?" 422c1010edaSGreg Roach )->execute([ 423c1010edaSGreg Roach $user_name, 424c1010edaSGreg Roach $this->user_id, 425c1010edaSGreg Roach ]); 426a25f0a04SGreg Roach } 427a25f0a04SGreg Roach 428a25f0a04SGreg Roach return $this; 429a25f0a04SGreg Roach } 430a25f0a04SGreg Roach 431a25f0a04SGreg Roach /** 432a25f0a04SGreg Roach * Get the real name of this user. 433a25f0a04SGreg Roach * 434a25f0a04SGreg Roach * @return string 435a25f0a04SGreg Roach */ 436c1010edaSGreg Roach public function getRealName() 437c1010edaSGreg Roach { 438a25f0a04SGreg Roach return $this->real_name; 439a25f0a04SGreg Roach } 440a25f0a04SGreg Roach 441a25f0a04SGreg Roach /** 442a25f0a04SGreg Roach * Set the real name of this user. 443a25f0a04SGreg Roach * 444a25f0a04SGreg Roach * @param string $real_name 445a25f0a04SGreg Roach * 446a25f0a04SGreg Roach * @return User 447a25f0a04SGreg Roach */ 448c1010edaSGreg Roach public function setRealName($real_name) 449c1010edaSGreg Roach { 450a25f0a04SGreg Roach if ($this->real_name !== $real_name) { 451a25f0a04SGreg Roach $this->real_name = $real_name; 452a25f0a04SGreg Roach Database::prepare( 453a25f0a04SGreg Roach "UPDATE `##user` SET real_name = ? WHERE user_id = ?" 454c1010edaSGreg Roach )->execute([ 455c1010edaSGreg Roach $real_name, 456c1010edaSGreg Roach $this->user_id, 457c1010edaSGreg Roach ]); 458a25f0a04SGreg Roach } 459a25f0a04SGreg Roach 460a25f0a04SGreg Roach return $this; 461a25f0a04SGreg Roach } 462a25f0a04SGreg Roach 463a25f0a04SGreg Roach /** 464a25f0a04SGreg Roach * Get the email address of this user. 465a25f0a04SGreg Roach * 466a25f0a04SGreg Roach * @return string 467a25f0a04SGreg Roach */ 468c1010edaSGreg Roach public function getEmail() 469c1010edaSGreg Roach { 470a25f0a04SGreg Roach return $this->email; 471a25f0a04SGreg Roach } 472a25f0a04SGreg Roach 473a25f0a04SGreg Roach /** 474a25f0a04SGreg Roach * Set the email address of this user. 475a25f0a04SGreg Roach * 476a25f0a04SGreg Roach * @param string $email 477a25f0a04SGreg Roach * 478a25f0a04SGreg Roach * @return User 479a25f0a04SGreg Roach */ 480c1010edaSGreg Roach public function setEmail($email) 481c1010edaSGreg Roach { 482a25f0a04SGreg Roach if ($this->email !== $email) { 483a25f0a04SGreg Roach $this->email = $email; 484a25f0a04SGreg Roach Database::prepare( 485a25f0a04SGreg Roach "UPDATE `##user` SET email = ? WHERE user_id = ?" 486c1010edaSGreg Roach )->execute([ 487c1010edaSGreg Roach $email, 488c1010edaSGreg Roach $this->user_id, 489c1010edaSGreg Roach ]); 490a25f0a04SGreg Roach } 491a25f0a04SGreg Roach 492a25f0a04SGreg Roach return $this; 493a25f0a04SGreg Roach } 494a25f0a04SGreg Roach 495a25f0a04SGreg Roach /** 496a25f0a04SGreg Roach * Set the password of this user. 497a25f0a04SGreg Roach * 498a25f0a04SGreg Roach * @param string $password 499a25f0a04SGreg Roach * 500a25f0a04SGreg Roach * @return User 501a25f0a04SGreg Roach */ 502c1010edaSGreg Roach public function setPassword($password) 503c1010edaSGreg Roach { 504a25f0a04SGreg Roach Database::prepare( 505015c99a2SGreg Roach "UPDATE `##user` SET password = :password WHERE user_id = :user_id" 506015c99a2SGreg Roach )->execute([ 507015c99a2SGreg Roach 'password' => password_hash($password, PASSWORD_DEFAULT), 508015c99a2SGreg Roach 'user_id' => $this->user_id, 509015c99a2SGreg Roach ]); 510a25f0a04SGreg Roach 511a25f0a04SGreg Roach return $this; 512a25f0a04SGreg Roach } 513a25f0a04SGreg Roach 514a25f0a04SGreg Roach /** 515a25f0a04SGreg Roach * Fetch a user option/setting from the wt_user_setting table. 516a25f0a04SGreg Roach * Since we'll fetch several settings for each user, and since there aren’t 517a25f0a04SGreg Roach * that many of them, fetch them all in one database query 518a25f0a04SGreg Roach * 519a25f0a04SGreg Roach * @param string $setting_name 52015d603e7SGreg Roach * @param string $default 521a25f0a04SGreg Roach * 52215d603e7SGreg Roach * @return string 523a25f0a04SGreg Roach */ 524c1010edaSGreg Roach public function getPreference($setting_name, $default = '') 525c1010edaSGreg Roach { 526c04dd3c1SGreg Roach if (empty($this->preferences) && $this->user_id !== 0) { 527a25f0a04SGreg Roach $this->preferences = Database::prepare( 528e5588fb0SGreg Roach "SELECT setting_name, setting_value" . 52915d603e7SGreg Roach " FROM `##user_setting`" . 53015d603e7SGreg Roach " WHERE user_id = :user_id" 53115d603e7SGreg Roach )->execute([ 53215d603e7SGreg Roach 'user_id' => $this->user_id, 53315d603e7SGreg Roach ])->fetchAssoc(); 534a25f0a04SGreg Roach } 535a25f0a04SGreg Roach 53615d603e7SGreg Roach if (!array_key_exists($setting_name, $this->preferences)) { 53715d603e7SGreg Roach $this->preferences[$setting_name] = $default; 538a25f0a04SGreg Roach } 53915d603e7SGreg Roach 54015d603e7SGreg Roach return $this->preferences[$setting_name]; 541a25f0a04SGreg Roach } 542a25f0a04SGreg Roach 543a25f0a04SGreg Roach /** 544a25f0a04SGreg Roach * Update a setting for the user. 545a25f0a04SGreg Roach * 546a25f0a04SGreg Roach * @param string $setting_name 547a25f0a04SGreg Roach * @param string $setting_value 548a25f0a04SGreg Roach * 549a25f0a04SGreg Roach * @return User 550a25f0a04SGreg Roach */ 551c1010edaSGreg Roach public function setPreference($setting_name, $setting_value) 552c1010edaSGreg Roach { 553c04dd3c1SGreg Roach if ($this->user_id !== 0 && $this->getPreference($setting_name) !== $setting_value) { 554*59f2f229SGreg Roach Database::prepare( 555*59f2f229SGreg Roach "REPLACE INTO `##user_setting` (user_id, setting_name, setting_value) VALUES (?, ?, LEFT(?, 255))" 556*59f2f229SGreg Roach )->execute([ 557c1010edaSGreg Roach $this->user_id, 558c1010edaSGreg Roach $setting_name, 559c1010edaSGreg Roach $setting_value, 560c1010edaSGreg Roach ]); 56115d603e7SGreg Roach 562a25f0a04SGreg Roach $this->preferences[$setting_name] = $setting_value; 563a25f0a04SGreg Roach } 564a25f0a04SGreg Roach 565a25f0a04SGreg Roach return $this; 566a25f0a04SGreg Roach } 567a25f0a04SGreg Roach} 568