1*a25f0a04SGreg Roach<?php 2*a25f0a04SGreg Roachnamespace Webtrees; 3*a25f0a04SGreg Roach 4*a25f0a04SGreg Roach/** 5*a25f0a04SGreg Roach * webtrees: online genealogy 6*a25f0a04SGreg Roach * Copyright (C) 2015 webtrees development team 7*a25f0a04SGreg Roach * This program is free software: you can redistribute it and/or modify 8*a25f0a04SGreg Roach * it under the terms of the GNU General Public License as published by 9*a25f0a04SGreg Roach * the Free Software Foundation, either version 3 of the License, or 10*a25f0a04SGreg Roach * (at your option) any later version. 11*a25f0a04SGreg Roach * This program is distributed in the hope that it will be useful, 12*a25f0a04SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*a25f0a04SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*a25f0a04SGreg Roach * GNU General Public License for more details. 15*a25f0a04SGreg Roach * You should have received a copy of the GNU General Public License 16*a25f0a04SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 17*a25f0a04SGreg Roach */ 18*a25f0a04SGreg Roach 19*a25f0a04SGreg Roach/** 20*a25f0a04SGreg Roach * Class User - Provide an interface to the wt_user table. 21*a25f0a04SGreg Roach */ 22*a25f0a04SGreg Roachclass User { 23*a25f0a04SGreg Roach /** @var string The primary key of this user. */ 24*a25f0a04SGreg Roach private $user_id; 25*a25f0a04SGreg Roach 26*a25f0a04SGreg Roach /** @var string The login name of this user. */ 27*a25f0a04SGreg Roach private $user_name; 28*a25f0a04SGreg Roach 29*a25f0a04SGreg Roach /** @var string The real (display) name of this user. */ 30*a25f0a04SGreg Roach private $real_name; 31*a25f0a04SGreg Roach 32*a25f0a04SGreg Roach /** @var string The email address of this user. */ 33*a25f0a04SGreg Roach private $email; 34*a25f0a04SGreg Roach 35*a25f0a04SGreg Roach /** @var array Cached copy of the wt_user_setting table. */ 36*a25f0a04SGreg Roach private $preferences; 37*a25f0a04SGreg Roach 38*a25f0a04SGreg Roach /** @var User[] Only fetch users from the database once. */ 39*a25f0a04SGreg Roach private static $cache = array(); 40*a25f0a04SGreg Roach 41*a25f0a04SGreg Roach /** 42*a25f0a04SGreg Roach * Find the user with a specified user_id. 43*a25f0a04SGreg Roach * 44*a25f0a04SGreg Roach * @param integer|null $user_id 45*a25f0a04SGreg Roach * 46*a25f0a04SGreg Roach * @return User|null 47*a25f0a04SGreg Roach */ 48*a25f0a04SGreg Roach public static function find($user_id) { 49*a25f0a04SGreg Roach if (!array_key_exists($user_id, self::$cache)) { 50*a25f0a04SGreg Roach $row = Database::prepare( 51*a25f0a04SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email FROM `##user` WHERE user_id = ?" 52*a25f0a04SGreg Roach )->execute(array($user_id))->fetchOneRow(); 53*a25f0a04SGreg Roach if ($row) { 54*a25f0a04SGreg Roach self::$cache[$user_id] = new User($row); 55*a25f0a04SGreg Roach } else { 56*a25f0a04SGreg Roach self::$cache[$user_id] = null; 57*a25f0a04SGreg Roach } 58*a25f0a04SGreg Roach } 59*a25f0a04SGreg Roach 60*a25f0a04SGreg Roach return self::$cache[$user_id]; 61*a25f0a04SGreg Roach } 62*a25f0a04SGreg Roach 63*a25f0a04SGreg Roach /** 64*a25f0a04SGreg Roach * Find the user with a specified user_id. 65*a25f0a04SGreg Roach * 66*a25f0a04SGreg Roach * @param string $identifier 67*a25f0a04SGreg Roach * 68*a25f0a04SGreg Roach * @return User|null 69*a25f0a04SGreg Roach */ 70*a25f0a04SGreg Roach public static function findByIdentifier($identifier) { 71*a25f0a04SGreg Roach $user_id = Database::prepare( 72*a25f0a04SGreg Roach "SELECT SQL_CACHE user_id FROM `##user` WHERE ? IN (user_name, email)" 73*a25f0a04SGreg Roach )->execute(array($identifier))->fetchOne(); 74*a25f0a04SGreg Roach 75*a25f0a04SGreg Roach return self::find($user_id); 76*a25f0a04SGreg Roach } 77*a25f0a04SGreg Roach 78*a25f0a04SGreg Roach /** 79*a25f0a04SGreg Roach * Find the user with a specified genealogy record. 80*a25f0a04SGreg Roach * 81*a25f0a04SGreg Roach * @param Tree $tree 82*a25f0a04SGreg Roach * @param Individual $individual 83*a25f0a04SGreg Roach * 84*a25f0a04SGreg Roach * @return User|null 85*a25f0a04SGreg Roach */ 86*a25f0a04SGreg Roach public static function findByGenealogyRecord(Tree $tree, Individual $individual) { 87*a25f0a04SGreg Roach $user_id = Database::prepare( 88*a25f0a04SGreg Roach "SELECT SQL_CACHE user_id" . 89*a25f0a04SGreg Roach " FROM `##user_gedcom_setting`" . 90*a25f0a04SGreg Roach " WHERE gedcom_id = ? AND setting_name = 'gedcomid' AND setting_value = ?" 91*a25f0a04SGreg Roach )->execute(array($tree->id(), $individual->getXref()))->fetchOne(); 92*a25f0a04SGreg Roach 93*a25f0a04SGreg Roach return self::find($user_id); 94*a25f0a04SGreg Roach } 95*a25f0a04SGreg Roach 96*a25f0a04SGreg Roach /** 97*a25f0a04SGreg Roach * Find the latest user to register. 98*a25f0a04SGreg Roach * 99*a25f0a04SGreg Roach * @return User|null 100*a25f0a04SGreg Roach */ 101*a25f0a04SGreg Roach public static function findLatestToRegister() { 102*a25f0a04SGreg Roach $user_id = Database::prepare( 103*a25f0a04SGreg Roach "SELECT SQL_CACHE u.user_id" . 104*a25f0a04SGreg Roach " FROM `##user` u" . 105*a25f0a04SGreg Roach " LEFT JOIN `##user_setting` us ON (u.user_id=us.user_id AND us.setting_name='reg_timestamp') " . 106*a25f0a04SGreg Roach " ORDER BY us.setting_value DESC LIMIT 1" 107*a25f0a04SGreg Roach )->execute()->fetchOne(); 108*a25f0a04SGreg Roach 109*a25f0a04SGreg Roach return self::find($user_id); 110*a25f0a04SGreg Roach } 111*a25f0a04SGreg Roach 112*a25f0a04SGreg Roach /** 113*a25f0a04SGreg Roach * Create a new user. 114*a25f0a04SGreg Roach * 115*a25f0a04SGreg Roach * The calling code needs to check for duplicates identifiers before calling 116*a25f0a04SGreg Roach * this function. 117*a25f0a04SGreg Roach * 118*a25f0a04SGreg Roach * @param string $user_name 119*a25f0a04SGreg Roach * @param string $real_name 120*a25f0a04SGreg Roach * @param string $email 121*a25f0a04SGreg Roach * @param string $password 122*a25f0a04SGreg Roach * 123*a25f0a04SGreg Roach * @return User 124*a25f0a04SGreg Roach */ 125*a25f0a04SGreg Roach public static function create($user_name, $real_name, $email, $password) { 126*a25f0a04SGreg Roach Database::prepare( 127*a25f0a04SGreg Roach "INSERT INTO `##user` (user_name, real_name, email, password) VALUES (:user_name, :real_name, :email, :password)" 128*a25f0a04SGreg Roach )->execute(array( 129*a25f0a04SGreg Roach 'user_name' => $user_name, 130*a25f0a04SGreg Roach 'real_name' => $real_name, 131*a25f0a04SGreg Roach 'email' => $email, 132*a25f0a04SGreg Roach 'password' => password_hash($password, PASSWORD_DEFAULT), 133*a25f0a04SGreg Roach )); 134*a25f0a04SGreg Roach 135*a25f0a04SGreg Roach // Set default blocks for this user 136*a25f0a04SGreg Roach $user = User::findByIdentifier($user_name); 137*a25f0a04SGreg Roach Database::prepare( 138*a25f0a04SGreg Roach "INSERT INTO `##block` (`user_id`, `location`, `block_order`, `module_name`)" . 139*a25f0a04SGreg Roach " SELECT :user_id , `location`, `block_order`, `module_name` FROM `##block` WHERE `user_id` = -1" 140*a25f0a04SGreg Roach )->execute(array('user_id' => $user->getUserId())); 141*a25f0a04SGreg Roach return $user; 142*a25f0a04SGreg Roach } 143*a25f0a04SGreg Roach 144*a25f0a04SGreg Roach /** 145*a25f0a04SGreg Roach * Get a count of all users. 146*a25f0a04SGreg Roach * 147*a25f0a04SGreg Roach * @return integer 148*a25f0a04SGreg Roach */ 149*a25f0a04SGreg Roach public static function count() { 150*a25f0a04SGreg Roach return (int) Database::prepare( 151*a25f0a04SGreg Roach "SELECT SQL_CACHE COUNT(*)" . 152*a25f0a04SGreg Roach " FROM `##user`" . 153*a25f0a04SGreg Roach " WHERE user_id > 0" 154*a25f0a04SGreg Roach )->fetchOne(); 155*a25f0a04SGreg Roach } 156*a25f0a04SGreg Roach 157*a25f0a04SGreg Roach /** 158*a25f0a04SGreg Roach * Get a list of all users. 159*a25f0a04SGreg Roach * 160*a25f0a04SGreg Roach * @return User[] 161*a25f0a04SGreg Roach */ 162*a25f0a04SGreg Roach public static function all() { 163*a25f0a04SGreg Roach $users = array(); 164*a25f0a04SGreg Roach 165*a25f0a04SGreg Roach $rows = Database::prepare( 166*a25f0a04SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 167*a25f0a04SGreg Roach " FROM `##user`" . 168*a25f0a04SGreg Roach " WHERE user_id > 0" . 169*a25f0a04SGreg Roach " ORDER BY user_name" 170*a25f0a04SGreg Roach )->fetchAll(); 171*a25f0a04SGreg Roach 172*a25f0a04SGreg Roach foreach ($rows as $row) { 173*a25f0a04SGreg Roach $users[] = new User($row); 174*a25f0a04SGreg Roach } 175*a25f0a04SGreg Roach 176*a25f0a04SGreg Roach return $users; 177*a25f0a04SGreg Roach } 178*a25f0a04SGreg Roach 179*a25f0a04SGreg Roach /** 180*a25f0a04SGreg Roach * Get a list of all administrators. 181*a25f0a04SGreg Roach * 182*a25f0a04SGreg Roach * @return User[] 183*a25f0a04SGreg Roach */ 184*a25f0a04SGreg Roach public static function allAdmins() { 185*a25f0a04SGreg Roach $rows = Database::prepare( 186*a25f0a04SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 187*a25f0a04SGreg Roach " FROM `##user`" . 188*a25f0a04SGreg Roach " JOIN `##user_setting` USING (user_id)" . 189*a25f0a04SGreg Roach " WHERE user_id > 0" . 190*a25f0a04SGreg Roach " AND setting_name = 'canadmin'" . 191*a25f0a04SGreg Roach " AND setting_value = '1'" 192*a25f0a04SGreg Roach )->fetchAll(); 193*a25f0a04SGreg Roach 194*a25f0a04SGreg Roach $users = array(); 195*a25f0a04SGreg Roach foreach ($rows as $row) { 196*a25f0a04SGreg Roach $users[] = new User($row); 197*a25f0a04SGreg Roach } 198*a25f0a04SGreg Roach 199*a25f0a04SGreg Roach return $users; 200*a25f0a04SGreg Roach } 201*a25f0a04SGreg Roach 202*a25f0a04SGreg Roach /** 203*a25f0a04SGreg Roach * Get a list of all verified uses. 204*a25f0a04SGreg Roach * 205*a25f0a04SGreg Roach * @return User[] 206*a25f0a04SGreg Roach */ 207*a25f0a04SGreg Roach public static function allVerified() { 208*a25f0a04SGreg Roach $rows = Database::prepare( 209*a25f0a04SGreg Roach "SELECT SQL_CACHE user_id, user_name, real_name, email" . 210*a25f0a04SGreg Roach " FROM `##user`" . 211*a25f0a04SGreg Roach " JOIN `##user_setting` USING (user_id)" . 212*a25f0a04SGreg Roach " WHERE user_id > 0" . 213*a25f0a04SGreg Roach " AND setting_name = 'verified'" . 214*a25f0a04SGreg Roach " AND setting_value = '1'" 215*a25f0a04SGreg Roach )->fetchAll(); 216*a25f0a04SGreg Roach 217*a25f0a04SGreg Roach $users = array(); 218*a25f0a04SGreg Roach foreach ($rows as $row) { 219*a25f0a04SGreg Roach $users[] = new User($row); 220*a25f0a04SGreg Roach } 221*a25f0a04SGreg Roach 222*a25f0a04SGreg Roach return $users; 223*a25f0a04SGreg Roach } 224*a25f0a04SGreg Roach 225*a25f0a04SGreg Roach /** 226*a25f0a04SGreg Roach * Get a list of all users who are currently logged in. 227*a25f0a04SGreg Roach * 228*a25f0a04SGreg Roach * @return User[] 229*a25f0a04SGreg Roach */ 230*a25f0a04SGreg Roach public static function allLoggedIn() { 231*a25f0a04SGreg Roach $rows = Database::prepare( 232*a25f0a04SGreg Roach "SELECT SQL_NO_CACHE DISTINCT user_id, user_name, real_name, email" . 233*a25f0a04SGreg Roach " FROM `##user`" . 234*a25f0a04SGreg Roach " JOIN `##session` USING (user_id)" 235*a25f0a04SGreg Roach )->fetchAll(); 236*a25f0a04SGreg Roach 237*a25f0a04SGreg Roach $users = array(); 238*a25f0a04SGreg Roach foreach ($rows as $row) { 239*a25f0a04SGreg Roach $users[] = new User($row); 240*a25f0a04SGreg Roach } 241*a25f0a04SGreg Roach 242*a25f0a04SGreg Roach return $users; 243*a25f0a04SGreg Roach } 244*a25f0a04SGreg Roach 245*a25f0a04SGreg Roach /** 246*a25f0a04SGreg Roach * Create a new user object from a row in the database. 247*a25f0a04SGreg Roach * 248*a25f0a04SGreg Roach * @param \stdclass $user A row from the wt_user table 249*a25f0a04SGreg Roach */ 250*a25f0a04SGreg Roach public function __construct(\stdClass $user) { 251*a25f0a04SGreg Roach $this->user_id = $user->user_id; 252*a25f0a04SGreg Roach $this->user_name = $user->user_name; 253*a25f0a04SGreg Roach $this->real_name = $user->real_name; 254*a25f0a04SGreg Roach $this->email = $user->email; 255*a25f0a04SGreg Roach } 256*a25f0a04SGreg Roach 257*a25f0a04SGreg Roach /** 258*a25f0a04SGreg Roach * Delete a user 259*a25f0a04SGreg Roach */ 260*a25f0a04SGreg Roach function delete() { 261*a25f0a04SGreg Roach // Don't delete the logs. 262*a25f0a04SGreg Roach Database::prepare("UPDATE `##log` SET user_id=NULL WHERE user_id =?")->execute(array($this->user_id)); 263*a25f0a04SGreg Roach // Take over the user’s pending changes. (What else could we do with them?) 264*a25f0a04SGreg Roach Database::prepare("DELETE FROM `##change` WHERE user_id=? AND status='accepted'")->execute(array($this->user_id)); 265*a25f0a04SGreg Roach Database::prepare("UPDATE `##change` SET user_id=? WHERE user_id=?")->execute(array($this->user_id, $this->user_id)); 266*a25f0a04SGreg Roach Database::prepare("DELETE `##block_setting` FROM `##block_setting` JOIN `##block` USING (block_id) WHERE user_id=?")->execute(array($this->user_id)); 267*a25f0a04SGreg Roach Database::prepare("DELETE FROM `##block` WHERE user_id=?")->execute(array($this->user_id)); 268*a25f0a04SGreg Roach Database::prepare("DELETE FROM `##user_gedcom_setting` WHERE user_id=?")->execute(array($this->user_id)); 269*a25f0a04SGreg Roach Database::prepare("DELETE FROM `##gedcom_setting` WHERE setting_value=? AND setting_name in ('CONTACT_USER_ID', 'WEBMASTER_USER_ID')")->execute(array($this->user_id)); 270*a25f0a04SGreg Roach Database::prepare("DELETE FROM `##user_setting` WHERE user_id=?")->execute(array($this->user_id)); 271*a25f0a04SGreg Roach Database::prepare("DELETE FROM `##message` WHERE user_id=?")->execute(array($this->user_id)); 272*a25f0a04SGreg Roach Database::prepare("DELETE FROM `##user` WHERE user_id=?")->execute(array($this->user_id)); 273*a25f0a04SGreg Roach } 274*a25f0a04SGreg Roach 275*a25f0a04SGreg Roach /** Validate a supplied password 276*a25f0a04SGreg Roach * 277*a25f0a04SGreg Roach * @param string $password 278*a25f0a04SGreg Roach * 279*a25f0a04SGreg Roach * @return boolean 280*a25f0a04SGreg Roach */ 281*a25f0a04SGreg Roach public function checkPassword($password) { 282*a25f0a04SGreg Roach $password_hash = Database::prepare( 283*a25f0a04SGreg Roach "SELECT password FROM `##user` WHERE user_id = ?" 284*a25f0a04SGreg Roach )->execute(array($this->user_id))->fetchOne(); 285*a25f0a04SGreg Roach 286*a25f0a04SGreg Roach if (password_verify($password, $password_hash)) { 287*a25f0a04SGreg Roach if (password_needs_rehash($password_hash, PASSWORD_DEFAULT)) { 288*a25f0a04SGreg Roach $this->setPassword($password); 289*a25f0a04SGreg Roach } 290*a25f0a04SGreg Roach return true; 291*a25f0a04SGreg Roach } else { 292*a25f0a04SGreg Roach return false; 293*a25f0a04SGreg Roach } 294*a25f0a04SGreg Roach } 295*a25f0a04SGreg Roach 296*a25f0a04SGreg Roach /** 297*a25f0a04SGreg Roach * Get the numeric ID for this user. 298*a25f0a04SGreg Roach * 299*a25f0a04SGreg Roach * @return string 300*a25f0a04SGreg Roach */ 301*a25f0a04SGreg Roach public function getUserId() { 302*a25f0a04SGreg Roach return $this->user_id; 303*a25f0a04SGreg Roach } 304*a25f0a04SGreg Roach 305*a25f0a04SGreg Roach /** 306*a25f0a04SGreg Roach * Get the login name for this user. 307*a25f0a04SGreg Roach * 308*a25f0a04SGreg Roach * @return string 309*a25f0a04SGreg Roach */ 310*a25f0a04SGreg Roach public function getUserName() { 311*a25f0a04SGreg Roach return $this->user_name; 312*a25f0a04SGreg Roach } 313*a25f0a04SGreg Roach 314*a25f0a04SGreg Roach /** 315*a25f0a04SGreg Roach * Set the login name for this user. 316*a25f0a04SGreg Roach * 317*a25f0a04SGreg Roach * @param string $user_name 318*a25f0a04SGreg Roach * 319*a25f0a04SGreg Roach * @return $this 320*a25f0a04SGreg Roach */ 321*a25f0a04SGreg Roach public function setUserName($user_name) { 322*a25f0a04SGreg Roach if ($this->user_name !== $user_name) { 323*a25f0a04SGreg Roach $this->user_name = $user_name; 324*a25f0a04SGreg Roach Database::prepare( 325*a25f0a04SGreg Roach "UPDATE `##user` SET user_name = ? WHERE user_id = ?" 326*a25f0a04SGreg Roach )->execute(array($user_name, $this->user_id)); 327*a25f0a04SGreg Roach } 328*a25f0a04SGreg Roach 329*a25f0a04SGreg Roach return $this; 330*a25f0a04SGreg Roach } 331*a25f0a04SGreg Roach 332*a25f0a04SGreg Roach /** 333*a25f0a04SGreg Roach * Get the real name of this user. 334*a25f0a04SGreg Roach * 335*a25f0a04SGreg Roach * @return string 336*a25f0a04SGreg Roach */ 337*a25f0a04SGreg Roach public function getRealName() { 338*a25f0a04SGreg Roach return $this->real_name; 339*a25f0a04SGreg Roach } 340*a25f0a04SGreg Roach 341*a25f0a04SGreg Roach /** 342*a25f0a04SGreg Roach * Set the real name of this user. 343*a25f0a04SGreg Roach * 344*a25f0a04SGreg Roach * @param string $real_name 345*a25f0a04SGreg Roach * 346*a25f0a04SGreg Roach * @return User 347*a25f0a04SGreg Roach */ 348*a25f0a04SGreg Roach public function setRealName($real_name) { 349*a25f0a04SGreg Roach if ($this->real_name !== $real_name) { 350*a25f0a04SGreg Roach $this->real_name = $real_name; 351*a25f0a04SGreg Roach Database::prepare( 352*a25f0a04SGreg Roach "UPDATE `##user` SET real_name = ? WHERE user_id = ?" 353*a25f0a04SGreg Roach )->execute(array($real_name, $this->user_id)); 354*a25f0a04SGreg Roach } 355*a25f0a04SGreg Roach 356*a25f0a04SGreg Roach return $this; 357*a25f0a04SGreg Roach } 358*a25f0a04SGreg Roach 359*a25f0a04SGreg Roach /** 360*a25f0a04SGreg Roach * Get the email address of this user. 361*a25f0a04SGreg Roach * 362*a25f0a04SGreg Roach * @return string 363*a25f0a04SGreg Roach */ 364*a25f0a04SGreg Roach public function getEmail() { 365*a25f0a04SGreg Roach return $this->email; 366*a25f0a04SGreg Roach } 367*a25f0a04SGreg Roach 368*a25f0a04SGreg Roach /** 369*a25f0a04SGreg Roach * Set the email address of this user. 370*a25f0a04SGreg Roach * 371*a25f0a04SGreg Roach * @param string $email 372*a25f0a04SGreg Roach * 373*a25f0a04SGreg Roach * @return User 374*a25f0a04SGreg Roach */ 375*a25f0a04SGreg Roach public function setEmail($email) { 376*a25f0a04SGreg Roach if ($this->email !== $email) { 377*a25f0a04SGreg Roach $this->email = $email; 378*a25f0a04SGreg Roach Database::prepare( 379*a25f0a04SGreg Roach "UPDATE `##user` SET email = ? WHERE user_id = ?" 380*a25f0a04SGreg Roach )->execute(array($email, $this->user_id)); 381*a25f0a04SGreg Roach } 382*a25f0a04SGreg Roach 383*a25f0a04SGreg Roach return $this; 384*a25f0a04SGreg Roach } 385*a25f0a04SGreg Roach 386*a25f0a04SGreg Roach /** 387*a25f0a04SGreg Roach * Set the password of this user. 388*a25f0a04SGreg Roach * 389*a25f0a04SGreg Roach * @param string $password 390*a25f0a04SGreg Roach * 391*a25f0a04SGreg Roach * @return User 392*a25f0a04SGreg Roach */ 393*a25f0a04SGreg Roach public function setPassword($password) { 394*a25f0a04SGreg Roach Database::prepare( 395*a25f0a04SGreg Roach "UPDATE `##user` SET password = ? WHERE user_id = ?" 396*a25f0a04SGreg Roach )->execute(array(password_hash($password, PASSWORD_DEFAULT), $this->user_id)); 397*a25f0a04SGreg Roach 398*a25f0a04SGreg Roach return $this; 399*a25f0a04SGreg Roach } 400*a25f0a04SGreg Roach 401*a25f0a04SGreg Roach /** 402*a25f0a04SGreg Roach * Fetch a user option/setting from the wt_user_setting table. 403*a25f0a04SGreg Roach * 404*a25f0a04SGreg Roach * Since we'll fetch several settings for each user, and since there aren’t 405*a25f0a04SGreg Roach * that many of them, fetch them all in one database query 406*a25f0a04SGreg Roach * 407*a25f0a04SGreg Roach * @param string $setting_name 408*a25f0a04SGreg Roach * @param string|null $default 409*a25f0a04SGreg Roach * 410*a25f0a04SGreg Roach * @return string|null 411*a25f0a04SGreg Roach */ 412*a25f0a04SGreg Roach public function getPreference($setting_name, $default = null) { 413*a25f0a04SGreg Roach if ($this->preferences === null) { 414*a25f0a04SGreg Roach if ($this->user_id) { 415*a25f0a04SGreg Roach $this->preferences = Database::prepare( 416*a25f0a04SGreg Roach "SELECT SQL_CACHE setting_name, setting_value FROM `##user_setting` WHERE user_id = ?" 417*a25f0a04SGreg Roach )->execute(array($this->user_id))->fetchAssoc(); 418*a25f0a04SGreg Roach } else { 419*a25f0a04SGreg Roach // Not logged in? We have no preferences. 420*a25f0a04SGreg Roach $this->preferences = array(); 421*a25f0a04SGreg Roach } 422*a25f0a04SGreg Roach } 423*a25f0a04SGreg Roach 424*a25f0a04SGreg Roach if (array_key_exists($setting_name, $this->preferences)) { 425*a25f0a04SGreg Roach return $this->preferences[$setting_name]; 426*a25f0a04SGreg Roach } else { 427*a25f0a04SGreg Roach return $default; 428*a25f0a04SGreg Roach } 429*a25f0a04SGreg Roach } 430*a25f0a04SGreg Roach 431*a25f0a04SGreg Roach /** 432*a25f0a04SGreg Roach * Update a setting for the user. 433*a25f0a04SGreg Roach * 434*a25f0a04SGreg Roach * @param string $setting_name 435*a25f0a04SGreg Roach * @param string $setting_value 436*a25f0a04SGreg Roach * 437*a25f0a04SGreg Roach * @return User 438*a25f0a04SGreg Roach */ 439*a25f0a04SGreg Roach public function setPreference($setting_name, $setting_value) { 440*a25f0a04SGreg Roach if ($this->user_id && $this->getPreference($setting_name) !== $setting_value) { 441*a25f0a04SGreg Roach Database::prepare("REPLACE INTO `##user_setting` (user_id, setting_name, setting_value) VALUES (?, ?, LEFT(?, 255))") 442*a25f0a04SGreg Roach ->execute(array($this->user_id, $setting_name, $setting_value)); 443*a25f0a04SGreg Roach $this->preferences[$setting_name] = $setting_value; 444*a25f0a04SGreg Roach } 445*a25f0a04SGreg Roach 446*a25f0a04SGreg Roach return $this; 447*a25f0a04SGreg Roach } 448*a25f0a04SGreg Roach 449*a25f0a04SGreg Roach /** 450*a25f0a04SGreg Roach * Delete a setting for the user. 451*a25f0a04SGreg Roach * 452*a25f0a04SGreg Roach * @param string $setting_name 453*a25f0a04SGreg Roach * 454*a25f0a04SGreg Roach * @return User 455*a25f0a04SGreg Roach */ 456*a25f0a04SGreg Roach public function deletePreference($setting_name) { 457*a25f0a04SGreg Roach if ($this->user_id && $this->getPreference($setting_name) !== null) { 458*a25f0a04SGreg Roach Database::prepare("DELETE FROM `##user_setting` WHERE user_id = ? AND setting_name = ?") 459*a25f0a04SGreg Roach ->execute(array($this->user_id, $setting_name)); 460*a25f0a04SGreg Roach unset($this->preferences[$setting_name]); 461*a25f0a04SGreg Roach } 462*a25f0a04SGreg Roach 463*a25f0a04SGreg Roach return $this; 464*a25f0a04SGreg Roach } 465*a25f0a04SGreg Roach} 466