1<?php 2# MantisBT - A PHP based bugtracking system 3 4# MantisBT is free software: you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation, either version 2 of the License, or 7# (at your option) any later version. 8# 9# MantisBT is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with MantisBT. If not, see <http://www.gnu.org/licenses/>. 16 17/** 18 * User Preferences API 19 * 20 * @package CoreAPI 21 * @subpackage UserPreferencesAPI 22 * @copyright Copyright 2000 - 2002 Kenzaburo Ito - kenito@300baud.org 23 * @copyright Copyright 2002 MantisBT Team - mantisbt-dev@lists.sourceforge.net 24 * @link http://www.mantisbt.org 25 * 26 * @uses authentication_api.php 27 * @uses config_api.php 28 * @uses constant_inc.php 29 * @uses database_api.php 30 * @uses error_api.php 31 * @uses lang_api.php 32 * @uses user_api.php 33 * @uses utility_api.php 34 */ 35 36require_api( 'authentication_api.php' ); 37require_api( 'config_api.php' ); 38require_api( 'constant_inc.php' ); 39require_api( 'database_api.php' ); 40require_api( 'error_api.php' ); 41require_api( 'lang_api.php' ); 42require_api( 'user_api.php' ); 43require_api( 'utility_api.php' ); 44 45/** 46 * Preference Structure Definition 47 */ 48class UserPreferences { 49 /** 50 * Default Profile 51 */ 52 protected $default_profile = null; 53 54 /** 55 * Default Project for user 56 */ 57 protected $default_project = null; 58 59 /** 60 * Automatic Refresh delay 61 */ 62 protected $refresh_delay = null; 63 64 /** 65 * Automatic Redirect delay 66 */ 67 protected $redirect_delay = null; 68 69 /** 70 * Bugnote order - oldest/newest first 71 */ 72 protected $bugnote_order = null; 73 74 /** 75 * Receive email on new bugs 76 */ 77 protected $email_on_new = null; 78 79 /** 80 * Receive email on assigned bugs 81 */ 82 protected $email_on_assigned = null; 83 84 /** 85 * Receive email on feedback 86 */ 87 protected $email_on_feedback = null; 88 89 /** 90 * Receive email on resolved bugs 91 */ 92 protected $email_on_resolved = null; 93 94 /** 95 * Receive email on closed bugs 96 */ 97 protected $email_on_closed = null; 98 99 /** 100 * Receive email on reopened bugs 101 */ 102 protected $email_on_reopened = null; 103 104 /** 105 * Receive email on new bugnote 106 */ 107 protected $email_on_bugnote = null; 108 109 /** 110 * Receive email on bug status change 111 */ 112 protected $email_on_status = null; 113 114 /** 115 * Receive email on bug priority change 116 */ 117 protected $email_on_priority = null; 118 119 /** 120 * Minimum Severity on which to trigger email if set to receive 121 */ 122 protected $email_on_new_min_severity = null; 123 124 /** 125 * Minimum Severity on which to trigger email if set to receive 126 */ 127 protected $email_on_assigned_min_severity = null; 128 129 /** 130 * Minimum Severity on which to trigger email if set to receive 131 */ 132 protected $email_on_feedback_min_severity = null; 133 134 /** 135 * Minimum Severity on which to trigger email if set to receive 136 */ 137 protected $email_on_resolved_min_severity = null; 138 139 /** 140 * Minimum Severity on which to trigger email if set to receive 141 */ 142 protected $email_on_closed_min_severity = null; 143 144 /** 145 * Minimum Severity on which to trigger email if set to receive 146 */ 147 protected $email_on_reopened_min_severity = null; 148 149 /** 150 * Minimum Severity on which to trigger email if set to receive 151 */ 152 protected $email_on_bugnote_min_severity = null; 153 154 /** 155 * Minimum Severity on which to trigger email if set to receive 156 */ 157 protected $email_on_status_min_severity = null; 158 159 /** 160 * Minimum Severity on which to trigger email if set to receive 161 */ 162 protected $email_on_priority_min_severity = null; 163 164 /** 165 * Number of bug notes to include in generated emails 166 */ 167 protected $email_bugnote_limit = null; 168 169 /** 170 * Users language preference 171 */ 172 protected $language = null; 173 174 /** 175 * User Timezone 176 */ 177 protected $timezone = null; 178 179 /** 180 * User id 181 */ 182 private $pref_user_id; 183 184 /** 185 * Project ID 186 */ 187 private $pref_project_id; 188 189 /** 190 * Default Values - Config Field Mappings 191 */ 192 private static $_default_mapping = array( 193 'default_profile' => array( 'default_profile', 'int' ), 194 'default_project' => array( 'default_project', 'int' ), 195 'refresh_delay' => array( 'default_refresh_delay', 'int' ), 196 'redirect_delay' => array( 'default_redirect_delay', 'int' ), 197 'bugnote_order' => array( 'default_bugnote_order', 'string' ), 198 'email_on_new' => array( 'default_email_on_new', 'int' ), 199 'email_on_assigned' => array( 'default_email_on_assigned', 'int' ), 200 'email_on_feedback' => array( 'default_email_on_feedback', 'int' ), 201 'email_on_resolved' => array( 'default_email_on_resolved', 'int' ), 202 'email_on_closed' => array( 'default_email_on_closed', 'int' ), 203 'email_on_reopened' => array( 'default_email_on_reopened', 'int' ), 204 'email_on_bugnote' => array( 'default_email_on_bugnote', 'int' ), 205 'email_on_status' => array( 'default_email_on_status', 'int' ), 206 'email_on_priority' => array( 'default_email_on_priority', 'int' ), 207 'email_on_new_min_severity' => array( 'default_email_on_new_minimum_severity', 'int' ), 208 'email_on_assigned_min_severity' => array( 'default_email_on_assigned_minimum_severity', 'int' ), 209 'email_on_feedback_min_severity' => array( 'default_email_on_feedback_minimum_severity', 'int' ), 210 'email_on_resolved_min_severity' => array( 'default_email_on_resolved_minimum_severity', 'int' ), 211 'email_on_closed_min_severity' => array( 'default_email_on_closed_minimum_severity', 'int' ), 212 'email_on_reopened_min_severity' => array( 'default_email_on_reopened_minimum_severity', 'int' ), 213 'email_on_bugnote_min_severity' => array( 'default_email_on_bugnote_minimum_severity', 'int' ), 214 'email_on_status_min_severity' => array( 'default_email_on_status_minimum_severity', 'int' ), 215 'email_on_priority_min_severity' => array( 'default_email_on_priority_minimum_severity', 'int' ), 216 'email_bugnote_limit' => array( 'default_email_bugnote_limit', 'int' ), 217 'language' => array( 'default_language', 'string' ), 218 'timezone' => array( 'default_timezone', 'string' ), 219 ); 220 221 /** 222 * Constructor 223 * @param integer $p_user_id A valid user identifier. 224 * @param integer $p_project_id A valid project identifier. 225 */ 226 function __construct( $p_user_id, $p_project_id ) { 227 $this->default_profile = 0; 228 $this->default_project = ALL_PROJECTS; 229 230 $this->pref_user_id = (int)$p_user_id; 231 $this->pref_project_id = (int)$p_project_id; 232 } 233 234 /** 235 * Overloaded function 236 * @param string $p_name The Property name to set. 237 * @param string $p_value A value to set the property to. 238 * @return void 239 * @access private 240 */ 241 public function __set( $p_name, $p_value ) { 242 switch( $p_name ) { 243 case 'timezone': 244 if( $p_value == '' ) { 245 $p_value = null; 246 } 247 } 248 $this->$p_name = $p_value; 249 } 250 251 /** 252 * Overloaded function 253 * @param string $p_string Property name. 254 * @access private 255 * @return mixed 256 */ 257 public function __get( $p_string ) { 258 if( is_null( $this->$p_string ) ) { 259 $this->$p_string = config_get( self::$_default_mapping[$p_string][0], null, $this->pref_user_id, $this->pref_project_id ); 260 } 261 switch( self::$_default_mapping[$p_string][1] ) { 262 case 'int': 263 return (int)($this->$p_string); 264 default: 265 return $this->$p_string; 266 } 267 } 268 269 /** 270 * Public Get() function 271 * @param string $p_string Property to get. 272 * @return mixed 273 */ 274 function Get( $p_string ) { 275 if( is_null( $this->$p_string ) ) { 276 $this->$p_string = config_get( self::$_default_mapping[$p_string][0], null, $this->pref_user_id, $this->pref_project_id ); 277 } 278 return $this->$p_string; 279 } 280} 281 282$g_cache_user_pref = array(); 283$g_cache_current_user_pref = array(); 284 285/** 286 * Cache a user preferences row if necessary and return the cached copy. 287 * If preferences can't be found, will trigger an error if $p_trigger_errors is 288 * true (default), or return false otherwise 289 * @param integer $p_user_id A valid user identifier. 290 * @param integer $p_project_id A valid project identifier. 291 * @param boolean $p_trigger_errors Whether to trigger error on failure. 292 * @return boolean|array 293 */ 294function user_pref_cache_row( $p_user_id, $p_project_id = ALL_PROJECTS, $p_trigger_errors = true ) { 295 global $g_cache_user_pref; 296 297 if( !isset( $g_cache_user_pref[(int)$p_user_id][(int)$p_project_id] ) ) { 298 user_pref_cache_array_rows( array( $p_user_id ), $p_project_id ); 299 } 300 301 $t_row = $g_cache_user_pref[(int)$p_user_id][(int)$p_project_id]; 302 if( false === $t_row && $p_trigger_errors ) { 303 trigger_error( ERROR_USER_PREFS_NOT_FOUND, ERROR ); 304 } 305 return $t_row; 306} 307 308/** 309 * Cache user preferences for a set of users 310 * @param array $p_user_id_array An array of valid user identifiers. 311 * @param integer $p_project_id A valid project identifier. 312 * @return void 313 */ 314function user_pref_cache_array_rows( array $p_user_id_array, $p_project_id = ALL_PROJECTS ) { 315 global $g_cache_user_pref; 316 $c_user_id_array = array(); 317 318 # identify the user ids that are not cached already. 319 foreach( $p_user_id_array as $t_user_id ) { 320 if( !isset( $g_cache_user_pref[(int)$t_user_id][(int)$p_project_id] ) ) { 321 $c_user_id_array[(int)$t_user_id] = (int)$t_user_id; 322 } 323 } 324 325 # if all users are already cached, then return 326 if( empty( $c_user_id_array ) ) { 327 return; 328 } 329 330 $t_query = new DbQuery( 'SELECT * FROM {user_pref} WHERE user_id IN :user_array AND project_id = :project_id' ); 331 $t_query->bind( 'user_array', $c_user_id_array ); 332 $t_query->bind( 'project_id', (int)$p_project_id ); 333 334 $t_result = $t_query->fetch_all(); 335 if( $t_result ) { 336 foreach( $t_result as $t_row ) { 337 $t_user_id = (int)$t_row['user_id']; 338 if( !isset( $g_cache_user_pref[$t_user_id] ) ) { 339 $g_cache_user_pref[$t_user_id] = array(); 340 } 341 $g_cache_user_pref[$t_user_id][(int)$p_project_id] = $t_row; 342 343 # remove found users from required set. 344 unset( $c_user_id_array[$t_user_id] ); 345 } 346 } 347 348 # cache users that are not found as false (i.e. negative cache) 349 foreach( $c_user_id_array as $t_user_id ) { 350 $g_cache_user_pref[(int)$t_user_id][(int)$p_project_id] = false; 351 } 352} 353 354/** 355 * Clear the user preferences cache (or just the given id if specified) 356 * @param integer $p_user_id A valid user identifier. 357 * @param integer $p_project_id A valid project identifier. 358 * @return boolean 359 */ 360function user_pref_clear_cache( $p_user_id = null, $p_project_id = null ) { 361 global $g_cache_user_pref; 362 363 if( null === $p_user_id ) { 364 $g_cache_user_pref = array(); 365 } else if( null === $p_project_id ) { 366 unset( $g_cache_user_pref[(int)$p_user_id] ); 367 } else { 368 unset( $g_cache_user_pref[(int)$p_user_id][(int)$p_project_id] ); 369 } 370 371 return true; 372} 373 374/** 375 * return true if the user has preferences assigned for the given project, 376 * false otherwise 377 * @param integer $p_user_id A valid user identifier. 378 * @param integer $p_project_id A valid project identifier. 379 * @return boolean 380 */ 381function user_pref_exists( $p_user_id, $p_project_id = ALL_PROJECTS ) { 382 if( false === user_pref_cache_row( $p_user_id, $p_project_id, false ) ) { 383 return false; 384 } else { 385 return true; 386 } 387} 388 389/** 390 * Backwards compatibility wrapper for user_pref_db_insert() 391 * @deprecated Use user_pref_db_insert() 392 */ 393function user_pref_insert( $p_user_id, $p_project_id, UserPreferences $p_prefs ) { 394 user_ensure_unprotected( $p_user_id ); 395 user_pref_db_insert( $p_user_id, $p_project_id, $p_prefs ); 396} 397 398/** 399 * perform an insert of a preference object into the DB 400 * @param integer $p_user_id A valid user identifier. 401 * @param integer $p_project_id A valid project identifier. 402 * @param UserPreferences $p_prefs A UserPrefences Object. 403 * @return boolean 404 */ 405function user_pref_db_insert( $p_user_id, $p_project_id, UserPreferences $p_prefs ) { 406 static $s_vars; 407 $c_user_id = (int)$p_user_id; 408 $c_project_id = (int)$p_project_id; 409 410 if( $s_vars == null ) { 411 $s_vars = getClassProperties( 'UserPreferences', 'protected' ); 412 } 413 414 $t_values = array(); 415 $t_values[] = $c_user_id; 416 $t_values[] = $c_project_id; 417 foreach( $s_vars as $t_var => $t_val ) { 418 array_push( $t_values, $p_prefs->Get( $t_var ) ); 419 } 420 421 $t_columns = 'user_id, project_id, ' . implode( ', ', array_keys( $s_vars ) ); 422 $t_query = new DBQuery( 'INSERT INTO {user_pref} (' . $t_columns . ') VALUES :values' ); 423 $t_query->bind( 'values', $t_values ); 424 $t_query->execute(); 425 426 return true; 427} 428 429/** 430 * Backwards compatibility wrapper for user_pref_db_update() 431 * @deprecated Use user_pref_db_update() 432 */ 433function user_pref_update( $p_user_id, $p_project_id, UserPreferences $p_prefs ) { 434 user_ensure_unprotected( $p_user_id ); 435 user_pref_db_update($p_user_id, $p_project_id, $p_prefs ); 436 user_pref_clear_cache( $p_user_id, $p_project_id ); 437} 438 439/** 440 * perform an update of a preference object into the DB 441 * @param integer $p_user_id A valid user identifier. 442 * @param integer $p_project_id A valid project identifier. 443 * @param UserPreferences $p_prefs A UserPrefences Object. 444 * @return void 445 */ 446function user_pref_db_update( $p_user_id, $p_project_id, UserPreferences $p_prefs ) { 447 static $s_vars; 448 449 if( $s_vars == null ) { 450 $s_vars = getClassProperties( 'UserPreferences', 'protected' ); 451 } 452 453 $t_pairs = array(); 454 foreach( $s_vars as $t_var => $t_val ) { 455 $t_pairs[] = "$t_var = :$t_var"; 456 $t_param[$t_var] = $p_prefs->$t_var; 457 } 458 459 $t_query = new DbQuery( 'UPDATE {user_pref} 460 SET ' . implode( ', ', $t_pairs ) . ' 461 WHERE user_id = :user_id AND project_id = :project_id' ); 462 $t_query->bind( $t_param ); 463 $t_query->bind( 'user_id', $p_user_id ); 464 $t_query->bind( 'project_id', $p_project_id ); 465 $t_query->execute(); 466} 467 468/** 469 * Backwards compatibility wrapper for user_pref_db_delete() 470 * @deprecated Use user_pref_db_delete() 471 */ 472function user_pref_delete( $p_user_id, $p_project_id = ALL_PROJECTS ) { 473 user_ensure_unprotected( $p_user_id ); 474 user_pref_db_delete( $p_user_id, $p_project_id ); 475 user_pref_clear_cache( $p_user_id, $p_project_id ); 476} 477 478/** 479 * delete a preferences row 480 * returns true if the preferences were successfully deleted 481 * @param integer $p_user_id A valid user identifier. 482 * @param integer $p_project_id A valid project identifier. 483 * @return void 484 */ 485function user_pref_db_delete( $p_user_id, $p_project_id ) { 486 $t_query = new DbQuery( 'DELETE FROM {user_pref}' 487 . ' WHERE user_id=:user_id AND project_id=:project_id' 488 ); 489 $t_query->bind( 'user_id', (int)$p_user_id ); 490 $t_query->bind( 'project_id', (int)$p_project_id ); 491 $t_query->execute(); 492} 493 494/** 495 * Backwards compatibility wrapper for user_pref_db_delete_user() 496 * @deprecated Use user_pref_db_delete_user() 497 */ 498function user_pref_delete_all( $p_user_id ) { 499 user_ensure_unprotected( $p_user_id ); 500 user_pref_db_delete_user( $p_user_id ); 501 user_pref_clear_cache( $p_user_id ); 502} 503 504/** 505 * delete all preferences for a user in all projects 506 * returns true if the prefs were successfully deleted 507 * 508 * It is far more efficient to delete them all in one query than to 509 * call user_pref_delete() for each one and the code is short so that's 510 * what we do 511 * @param integer $p_user_id A valid user identifier. 512 * @return void 513 */ 514function user_pref_db_delete_user( $p_user_id ) { 515 $t_query = new DbQuery( 'DELETE FROM {user_pref} WHERE user_id=:user_id' ); 516 $t_query->bind( 'user_id', (int)$p_user_id ); 517 $t_query->execute(); 518} 519 520/** 521 * Sets project default to ALL_PROJECTS. 522 * 523 * @param integer $p_project_id A valid project identifier. 524 * @param array $p_users A list of users (empty = all users). 525 * 526 * @return void 527 */ 528function user_pref_clear_project_default( $p_project_id, array $p_users = array() ) { 529 $t_query = new DbQuery( 'UPDATE {user_pref}' 530 . ' SET default_project = ' . ALL_PROJECTS 531 . ' WHERE default_project = :default' 532 ); 533 $t_query->bind( 'default', (int)$p_project_id ); 534 if( $p_users ) { 535 $t_query->append_sql( ' AND ' . $t_query->sql_in( 'user_id', 'users' ) ); 536 $t_query->bind( 'users', $p_users ); 537 } 538 $t_query->execute(); 539} 540 541/** 542 * Sets project default to ALL_PROJECTS if current default is not valid. 543 * 544 * When users are removed from a project, the ones having that project as 545 * default but who are no longer authorized to access it, need to have their 546 * now-invalid preference updated. 547 * 548 * @param integer $p_project_id A valid project identifier. 549 * @param array $p_users A list of users (empty = all users). 550 * 551 * @return void 552 */ 553function user_pref_clear_invalid_project_default( $p_project_id, array $p_users = array() ) { 554 # Get all users having the project as default 555 $t_query = new DbQuery( 'SELECT user_id FROM {user_pref} WHERE default_project = :default' ); 556 $t_query->bind( 'default', (int)$p_project_id ); 557 if( $p_users ) { 558 $t_query->append_sql( ' AND ' . $t_query->sql_in( 'user_id', 'users' ) ); 559 $t_query->bind( 'users', $p_users ); 560 } 561 $t_query->execute(); 562 563 $t_users_having_project_as_default = array_column( $t_query->fetch_all(), 'user_id' ); 564 565 # Users who can't access the project anymore must have the default cleared 566 $t_users_to_clear = array(); 567 foreach( $t_users_having_project_as_default as $t_id ) { 568 if( access_get_project_level( $p_project_id, $t_id ) == ANYBODY ) { 569 $t_users_to_clear[] = $t_id; 570 } 571 } 572 573 if( !empty( $t_users_to_clear ) ) { 574 user_pref_clear_project_default( $p_project_id, $t_users_to_clear ); 575 } 576} 577 578/** 579 * delete all preferences for a project for all users (part of deleting the project) 580 * returns true if the prefs were successfully deleted 581 * 582 * It is far more efficient to delete them all in one query than to 583 * call user_pref_delete() for each one and the code is short so that's what we do 584 * @param integer $p_project_id A valid project identifier. 585 * @return void 586 */ 587function user_pref_db_delete_project( $p_project_id ) { 588 $t_query = new DbQuery( 'DELETE FROM {user_pref} WHERE project_id=:project_id' ); 589 $t_query->bind( 'project_id', (int)$p_project_id ); 590 $t_query->execute(); 591} 592 593/** 594 * return the user's preferences in a UserPreferences object 595 * @param integer $p_user_id A valid user identifier. 596 * @param integer $p_project_id A valid project identifier. 597 * @return UserPreferences 598 */ 599function user_pref_get( $p_user_id, $p_project_id = ALL_PROJECTS ) { 600 static $s_vars; 601 global $g_cache_current_user_pref; 602 603 if( isset( $g_cache_current_user_pref[(int)$p_project_id] ) && 604 auth_is_user_authenticated() && 605 auth_get_current_user_id() == $p_user_id ) { 606 return $g_cache_current_user_pref[(int)$p_project_id]; 607 } 608 609 $t_prefs = new UserPreferences( $p_user_id, $p_project_id ); 610 611 $t_row = user_pref_cache_row( $p_user_id, $p_project_id, false ); 612 613 # If the user has no preferences for the given project 614 if( false === $t_row ) { 615 if( ALL_PROJECTS != $p_project_id ) { 616 # Try to get the prefs for ALL_PROJECTS (the defaults) 617 $t_row = user_pref_cache_row( $p_user_id, ALL_PROJECTS, false ); 618 } 619 620 # If $t_row is still false (the user doesn't have default preferences) 621 if( false === $t_row ) { 622 # We use an empty array 623 $t_row = array(); 624 } 625 } 626 627 if( $s_vars == null ) { 628 $s_vars = getClassProperties( 'UserPreferences', 'protected' ); 629 } 630 631 $t_row_keys = array_keys( $t_row ); 632 633 # Check each variable in the class 634 foreach( $s_vars as $t_var => $t_val ) { 635 # If we got a field from the DB with the same name 636 if( in_array( $t_var, $t_row_keys, true ) ) { 637 # Store that value in the object 638 $t_prefs->$t_var = $t_row[$t_var]; 639 } 640 } 641 if( auth_is_user_authenticated() && auth_get_current_user_id() == $p_user_id ) { 642 $g_cache_current_user_pref[(int)$p_project_id] = $t_prefs; 643 } 644 return $t_prefs; 645} 646 647/** 648 * Return the specified preference field for the user id 649 * If the preference can't be found try to return a defined default 650 * If that fails, trigger a WARNING and return '' 651 * @param integer $p_user_id A valid user identifier. 652 * @param string $p_pref_name A valid user preference name. 653 * @param integer $p_project_id A valid project identifier. 654 * @return string 655 */ 656function user_pref_get_pref( $p_user_id, $p_pref_name, $p_project_id = ALL_PROJECTS ) { 657 static $s_vars; 658 659 $t_prefs = user_pref_get( $p_user_id, $p_project_id ); 660 661 if( $s_vars == null ) { 662 $t_reflection = new ReflectionClass( 'UserPreferences' ); 663 $s_vars = $t_reflection->getDefaultProperties(); 664 } 665 666 if( in_array( $p_pref_name, array_keys( $s_vars ), true ) ) { 667 return $t_prefs->Get( $p_pref_name ); 668 } else { 669 error_parameters( $p_pref_name ); 670 trigger_error( ERROR_DB_FIELD_NOT_FOUND, WARNING ); 671 return ''; 672 } 673} 674 675/** 676 * returns user language 677 * @param integer $p_user_id A valid user identifier. 678 * @param integer $p_project_id A valid project identifier. 679 * @return string language name or null if invalid language specified 680 */ 681function user_pref_get_language( $p_user_id, $p_project_id = ALL_PROJECTS ) { 682 $t_prefs = user_pref_get( $p_user_id, $p_project_id ); 683 684 # ensure the language is a valid one 685 $t_lang = $t_prefs->language; 686 if( !lang_language_exists( $t_lang ) ) { 687 $t_lang = null; 688 } 689 return $t_lang; 690} 691 692/** 693 * Set a user preference 694 * 695 * By getting the preferences for the project first we deal fairly well with defaults. If there are currently no 696 * preferences for that project, the ALL_PROJECTS preferences will be returned so we end up storing a new set of 697 * preferences for the given project based on the preferences for ALL_PROJECTS. If there isn't even an entry for 698 * ALL_PROJECTS, we'd get returned a default UserPreferences object to modify. 699 * @param integer $p_user_id A valid user identifier. 700 * @param string $p_pref_name The name of the preference value to set. 701 * @param string $p_pref_value A preference value to set. 702 * @param integer $p_project_id A valid project identifier. 703 * @param boolean $p_check_protected Whether to perform a check to not allow modify protected users 704 * @return boolean 705 */ 706function user_pref_set_pref( $p_user_id, $p_pref_name, $p_pref_value, $p_project_id = ALL_PROJECTS, $p_check_protected = true ) { 707 $t_prefs = user_pref_get( $p_user_id, $p_project_id ); 708 709 if( $t_prefs->$p_pref_name != $p_pref_value ) { 710 $t_prefs->$p_pref_name = $p_pref_value; 711 user_pref_set( $p_user_id, $t_prefs, $p_project_id, $p_check_protected ); 712 } 713 714 return true; 715} 716 717/** 718 * Set the user's preferences for the project from the given preferences object 719 * Do the work by calling update or insert as appropriate 720 * @param integer $p_user_id A valid user identifier. 721 * @param UserPreferences $p_prefs A UserPreferences object containing settings to set. 722 * @param integer $p_project_id A valid project identifier. 723 * @param boolean $p_check_protected Whether to perform a check to not allow modify protected users 724 * @return void 725 */ 726function user_pref_set( $p_user_id, UserPreferences $p_prefs, $p_project_id = ALL_PROJECTS, $p_check_protected = true ) { 727 if( $p_check_protected ) { 728 user_ensure_unprotected( $p_user_id ); 729 } 730 if( user_pref_exists( $p_user_id, $p_project_id ) ) { 731 user_pref_db_update( $p_user_id, $p_project_id, $p_prefs ); 732 } else { 733 user_pref_db_insert( $p_user_id, $p_project_id, $p_prefs ); 734 } 735 user_pref_clear_cache( $p_user_id, $p_project_id ); 736} 737 738/** 739 * Delete the user's preferences row for the given project 740 * @param integer $p_user_id A valid user identifier. 741 * @param integer $p_project_id A valid project identifier. 742 * @param boolean $p_check_protected Whether to perform a check to not allow modify protected users 743 * @return void 744 */ 745function user_pref_reset( $p_user_id, $p_project_id = ALL_PROJECTS, $p_check_protected = true ) { 746 if( $p_check_protected ) { 747 user_ensure_unprotected( $p_user_id ); 748 } 749 if( user_pref_exists( $p_user_id, $p_project_id ) ) { 750 user_pref_db_delete( $p_user_id, $p_project_id ); 751 } 752 user_pref_clear_cache( $p_user_id, $p_project_id ); 753} 754