[ Index ]

PHP Cross Reference of MantisBT

title

Body

[close]

/core/ -> user_api.php (source)

   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 API
  19   *
  20   * @package CoreAPI
  21   * @subpackage UserAPI
  22   * @copyright Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
  23   * @copyright Copyright (C) 2002 - 2011  MantisBT Team - mantisbt-dev@lists.sourceforge.net
  24   * @link http://www.mantisbt.org
  25   *
  26   * @uses access_api.php
  27   * @uses authentication_api.php
  28   * @uses config_api.php
  29   * @uses constant_inc.php
  30   * @uses database_api.php
  31   * @uses email_api.php
  32   * @uses error_api.php
  33   * @uses filter_api.php
  34   * @uses helper_api.php
  35   * @uses lang_api.php
  36   * @uses ldap_api.php
  37   * @uses project_api.php
  38   * @uses project_hierarchy_api.php
  39   * @uses string_api.php
  40   * @uses user_pref_api.php
  41   * @uses utility_api.php
  42   */
  43  
  44  require_api( 'access_api.php' );
  45  require_api( 'authentication_api.php' );
  46  require_api( 'config_api.php' );
  47  require_api( 'constant_inc.php' );
  48  require_api( 'database_api.php' );
  49  require_api( 'email_api.php' );
  50  require_api( 'error_api.php' );
  51  require_api( 'filter_api.php' );
  52  require_api( 'helper_api.php' );
  53  require_api( 'lang_api.php' );
  54  require_api( 'ldap_api.php' );
  55  require_api( 'project_api.php' );
  56  require_api( 'project_hierarchy_api.php' );
  57  require_api( 'string_api.php' );
  58  require_api( 'user_pref_api.php' );
  59  require_api( 'utility_api.php' );
  60  
  61  # ===================================
  62  # Caching
  63  # ===================================
  64  # ########################################
  65  # SECURITY NOTE: cache globals are initialized here to prevent them
  66  #   being spoofed if register_globals is turned on
  67  
  68  $g_cache_user = array();
  69  
  70  # --------------------
  71  # Cache a user row if necessary and return the cached copy
  72  #  If the second parameter is true (default), trigger an error
  73  #  if the user can't be found.  If the second parameter is
  74  #  false, return false if the user can't be found.
  75  function user_cache_row( $p_user_id, $p_trigger_errors = true ) {
  76      global $g_cache_user;
  77  
  78      if( isset( $g_cache_user[$p_user_id] ) ) {
  79          return $g_cache_user[$p_user_id];
  80      }
  81  
  82      $t_user_table = db_get_table( 'user' );
  83  
  84      $query = "SELECT *
  85                    FROM $t_user_table
  86                    WHERE id=" . db_param();
  87      $result = db_query_bound( $query, Array( $p_user_id ) );
  88  
  89      if( 0 == db_num_rows( $result ) ) {
  90          $g_cache_user[$p_user_id] = false;
  91  
  92          if( $p_trigger_errors ) {
  93              error_parameters( (integer)$p_user_id );
  94              trigger_error( ERROR_USER_BY_ID_NOT_FOUND, ERROR );
  95          }
  96  
  97          return false;
  98      }
  99  
 100      $row = db_fetch_array( $result );
 101  
 102      $g_cache_user[$p_user_id] = $row;
 103  
 104      return $row;
 105  }
 106  
 107  function user_cache_array_rows( $p_user_id_array ) {
 108      global $g_cache_user;
 109      $c_user_id_array = array();
 110  
 111      foreach( $p_user_id_array as $t_user_id ) {
 112          if( !isset( $g_cache_user[(int) $t_user_id] ) ) {
 113              $c_user_id_array[] = (int) $t_user_id;
 114          }
 115      }
 116  
 117      if( empty( $c_user_id_array ) ) {
 118          return;
 119      }
 120  
 121      $t_user_table = db_get_table( 'user' );
 122  
 123      $query = "SELECT *
 124                    FROM $t_user_table
 125                    WHERE id IN (" . implode( ',', $c_user_id_array ) . ')';
 126      $result = db_query_bound( $query );
 127  
 128      while( $row = db_fetch_array( $result ) ) {
 129          $g_cache_user[(int) $row['id']] = $row;
 130      }
 131      return;
 132  }
 133  
 134  # --------------------
 135  # Cache an object as a bug.
 136  function user_cache_database_result( $p_user_database_result ) {
 137      global $g_cache_user;
 138  
 139      if( isset( $g_cache_user[$p_user_database_result['id']] ) ) {
 140          return $g_cache_user[$p_user_database_result['id']];
 141      }
 142  
 143      $g_cache_user[$p_user_database_result['id']] = $p_user_database_result;
 144  }
 145  
 146  # --------------------
 147  # Clear the user cache (or just the given id if specified)
 148  function user_clear_cache( $p_user_id = null ) {
 149      global $g_cache_user;
 150  
 151      if( null === $p_user_id ) {
 152          $g_cache_user = array();
 153      } else {
 154          unset( $g_cache_user[$p_user_id] );
 155      }
 156  
 157      return true;
 158  }
 159  
 160  function user_update_cache( $p_user_id, $p_field, $p_value ) {
 161      global $g_cache_user;
 162  
 163      if( isset( $g_cache_user[$p_user_id] ) && isset( $g_cache_user[$p_user_id][$p_field] ) ) {
 164          $g_cache_user[$p_user_id][$p_field] = $p_value;
 165      } else {
 166          user_clear_cache( $p_user_id );
 167      }
 168  }
 169  
 170  function user_search_cache( $p_field, $p_value ) {
 171      global $g_cache_user;
 172      if( isset( $g_cache_user ) ) {
 173          foreach( $g_cache_user as $t_user ) {
 174              if( $t_user[$p_field] == $p_value ) {
 175                  return $t_user;
 176              }
 177          }
 178      }
 179      return false;
 180  }
 181  
 182  # ===================================
 183  # Boolean queries and ensures
 184  # ===================================
 185  # --------------------
 186  # check to see if user exists by id
 187  # return true if it does, false otherwise
 188  #
 189  # Use user_cache_row() to benefit from caching if called multiple times
 190  #  and because if the user does exist the data may well be wanted
 191  function user_exists( $p_user_id ) {
 192      $row = user_cache_row( $p_user_id, false );
 193  
 194      if( false === $row ) {
 195          return false;
 196      } else {
 197          return true;
 198      }
 199  }
 200  
 201  # --------------------
 202  # check to see if project exists by id
 203  # if it doesn't exist then error
 204  #  otherwise let execution continue undisturbed
 205  function user_ensure_exists( $p_user_id ) {
 206      $c_user_id = (integer)$p_user_id;
 207  
 208      if ( !user_exists( $c_user_id ) ) {
 209          error_parameters( $c_user_id );
 210          trigger_error( ERROR_USER_BY_ID_NOT_FOUND, ERROR );
 211      }
 212  }
 213  
 214  # --------------------
 215  # return true if the username is unique, false if there is already a user
 216  #  with that username
 217  function user_is_name_unique( $p_username ) {
 218      $t_user_table = db_get_table( 'user' );
 219  
 220      $query = "SELECT username
 221                  FROM $t_user_table
 222                  WHERE username=" . db_param();
 223      $result = db_query_bound( $query, Array( $p_username ), 1 );
 224  
 225      if( db_num_rows( $result ) > 0 ) {
 226          return false;
 227      } else {
 228          return true;
 229      }
 230  }
 231  
 232  # --------------------
 233  # Check if the username is unique and trigger an ERROR if it isn't
 234  function user_ensure_name_unique( $p_username ) {
 235      if( !user_is_name_unique( $p_username ) ) {
 236          trigger_error( ERROR_USER_NAME_NOT_UNIQUE, ERROR );
 237      }
 238  }
 239  
 240  # --------------------
 241  # Check if the realname is a valid username (does not account for uniqueness)
 242  # Return 0 if it is invalid, The number of matches + 1
 243  function user_is_realname_unique( $p_username, $p_realname ) {
 244      if( is_blank( $p_realname ) ) {
 245          # don't bother checking if realname is blank
 246          return 1;
 247      }
 248  
 249      $p_username = trim( $p_username );
 250      $p_realname = trim( $p_realname );
 251  
 252      # allow realname to match username
 253      $t_count = 0;
 254      if( $p_realname <> $p_username ) {
 255          # check realname does not match an existing username
 256          #  but allow it to match the current user
 257          $t_target_user = user_get_id_by_name( $p_username );
 258          $t_other_user = user_get_id_by_name( $p_realname );
 259          if( ( 0 != $t_other_user ) && ( $t_target_user != $t_other_user ) ) {
 260              return 0;
 261          }
 262  
 263          # check to see if the realname is unique
 264          $t_user_table = db_get_table( 'user' );
 265          $query = "SELECT id
 266                  FROM $t_user_table
 267                  WHERE realname=" . db_param();
 268          $result = db_query_bound( $query, Array( $p_realname ) );
 269          $t_count = db_num_rows( $result );
 270  
 271          if( $t_count > 0 ) {
 272              # set flags for non-unique realnames
 273              if( config_get( 'differentiate_duplicates' ) ) {
 274                  for( $i = 0;$i < $t_count;$i++ ) {
 275                      $t_user_id = db_result( $result, $i );
 276                      user_set_field( $t_user_id, 'duplicate_realname', ON );
 277                  }
 278              }
 279          }
 280      }
 281      return $t_count + 1;
 282  }
 283  
 284  # --------------------
 285  # Check if the realname is a unique
 286  # Trigger an error if the username is not valid
 287  function user_ensure_realname_unique( $p_username, $p_realname ) {
 288      if( 1 > user_is_realname_unique( $p_username, $p_realname ) ) {
 289          trigger_error( ERROR_USER_REAL_MATCH_USER, ERROR );
 290      }
 291  }
 292  
 293  # --------------------
 294  # Check if the username is a valid username (does not account for uniqueness)
 295  #  realname can match
 296  # Return true if it is, false otherwise
 297  function user_is_name_valid( $p_username ) {
 298  
 299      # The DB field is hard-coded. USERLEN should not be modified.
 300      if( utf8_strlen( $p_username ) > USERLEN ) {
 301          return false;
 302      }
 303  
 304      # username must consist of at least one character
 305      if( is_blank( $p_username ) ) {
 306          return false;
 307      }
 308  
 309      # Only allow a basic set of characters
 310      if( 0 == preg_match( config_get( 'user_login_valid_regex' ), $p_username ) ) {
 311          return false;
 312      }
 313  
 314      # We have a valid username
 315      return true;
 316  }
 317  
 318  # --------------------
 319  # Check if the username is a valid username (does not account for uniqueness)
 320  # Trigger an error if the username is not valid
 321  function user_ensure_name_valid( $p_username ) {
 322      if( !user_is_name_valid( $p_username ) ) {
 323          trigger_error( ERROR_USER_NAME_INVALID, ERROR );
 324      }
 325  }
 326  
 327  # --------------------
 328  # return whether user is monitoring bug for the user id and bug id
 329  function user_is_monitoring_bug( $p_user_id, $p_bug_id ) {
 330      $c_user_id = db_prepare_int( $p_user_id );
 331      $c_bug_id = db_prepare_int( $p_bug_id );
 332  
 333      $t_bug_monitor_table = db_get_table( 'bug_monitor' );
 334  
 335      $query = "SELECT COUNT(*)
 336                    FROM $t_bug_monitor_table
 337                    WHERE user_id=" . db_param() . " AND bug_id=" . db_param();
 338  
 339      $result = db_query_bound( $query, Array( $c_user_id, $c_bug_id ) );
 340  
 341      if( 0 == db_result( $result ) ) {
 342          return false;
 343      } else {
 344          return true;
 345      }
 346  }
 347  
 348  # --------------------
 349  # return true if the user has access of ADMINISTRATOR or higher, false otherwise
 350  function user_is_administrator( $p_user_id ) {
 351      $t_access_level = user_get_field( $p_user_id, 'access_level' );
 352  
 353      if( $t_access_level >= config_get_global( 'admin_site_threshold' ) ) {
 354          return true;
 355      } else {
 356          return false;
 357      }
 358  }
 359  
 360  /*
 361   * Check if a user has a protected user account.
 362   * Protected user accounts cannot be updated without manage_user_threshold
 363   * permission. If the user ID supplied is that of the anonymous user, this
 364   * function will always return true. The anonymous user account is always
 365   * considered to be protected.
 366   *
 367   * @param int $p_user_id
 368   * @return true: user is protected; false: user is not protected.
 369   * @access public
 370   */
 371  function user_is_protected( $p_user_id ) {
 372      if( user_is_anonymous( $p_user_id ) || ON == user_get_field( $p_user_id, 'protected' ) ) {
 373          return true;
 374      }
 375      return false;
 376  }
 377  
 378  /*
 379   * Check if a user is the anonymous user account.
 380   * When anonymous logins are disabled this function will always return false.
 381   *
 382   * @param int $p_user_id
 383   * @return true: user is the anonymous user; false: user is not the anonymous user.
 384   * @access public
 385   */
 386  function user_is_anonymous( $p_user_id ) {
 387      if( ON == config_get( 'allow_anonymous_login' ) && user_get_field( $p_user_id, 'username' ) == config_get( 'anonymous_account' ) ) {
 388          return true;
 389      }
 390      return false;
 391  }
 392  
 393  # --------------------
 394  # Trigger an ERROR if the user account is protected
 395  function user_ensure_unprotected( $p_user_id ) {
 396      if( user_is_protected( $p_user_id ) ) {
 397          trigger_error( ERROR_PROTECTED_ACCOUNT, ERROR );
 398      }
 399  }
 400  
 401  # --------------------
 402  # return true is the user account is enabled, false otherwise
 403  function user_is_enabled( $p_user_id ) {
 404      if( ON == user_get_field( $p_user_id, 'enabled' ) ) {
 405          return true;
 406      } else {
 407          return false;
 408      }
 409  }
 410  
 411  # --------------------
 412  # count the number of users at or greater than a specific level
 413  function user_count_level( $p_level = ANYBODY ) {
 414      $t_level = db_prepare_int( $p_level );
 415      $t_user_table = db_get_table( 'user' );
 416      $query = "SELECT COUNT(id) FROM $t_user_table WHERE access_level>=" . db_param();
 417      $result = db_query_bound( $query, Array( $t_level ) );
 418  
 419      # Get the list of connected users
 420      $t_users = db_result( $result );
 421  
 422      return $t_users;
 423  }
 424  
 425  # --------------------
 426  # Return an array of user ids that are logged in.
 427  # A user is considered logged in if the last visit timestamp is within the
 428  # specified session duration.
 429  # If the session duration is 0, then no users will be returned.
 430  function user_get_logged_in_user_ids( $p_session_duration_in_minutes ) {
 431      $t_session_duration_in_minutes = (integer) $p_session_duration_in_minutes;
 432  
 433      # if session duration is 0, then there is no logged in users.
 434      if( $t_session_duration_in_minutes == 0 ) {
 435          return array();
 436      }
 437  
 438      # Generate timestamp
 439      $t_last_timestamp_threshold = mktime( date( 'H' ), date( 'i' ) - 1 * $t_session_duration_in_minutes, date( 's' ), date( 'm' ), date( 'd' ), date( 'Y' ) );
 440  
 441      $t_user_table = db_get_table( 'user' );
 442  
 443      # Execute query
 444      $query = 'SELECT id FROM ' . $t_user_table . ' WHERE last_visit > ' . db_param();
 445      $result = db_query_bound( $query, array( $c_last_timestamp_threshold ), 1 );
 446  
 447      # Get the list of connected users
 448      $t_users_connected = array();
 449      while( $row = db_fetch_array( $result ) ) {
 450          $t_users_connected[] = $row['id'];
 451      }
 452  
 453      return $t_users_connected;
 454  }
 455  
 456  # ===================================
 457  # Creation / Deletion / Updating
 458  # ===================================
 459  # --------------------
 460  # Create a user.
 461  # returns false if error, the generated cookie string if ok
 462  function user_create( $p_username, $p_password, $p_email = '',
 463      $p_access_level = null, $p_protected = false, $p_enabled = true,
 464      $p_realname = '', $p_admin_name = '' ) {
 465      if( null === $p_access_level ) {
 466          $p_access_level = config_get( 'default_new_account_access_level' );
 467      }
 468  
 469      $t_password = auth_process_plain_password( $p_password );
 470  
 471      $c_access_level = db_prepare_int( $p_access_level );
 472      $c_protected = db_prepare_bool( $p_protected );
 473      $c_enabled = db_prepare_bool( $p_enabled );
 474  
 475      user_ensure_name_valid( $p_username );
 476      user_ensure_name_unique( $p_username );
 477      user_ensure_realname_unique( $p_username, $p_realname );
 478      email_ensure_valid( $p_email );
 479  
 480      $t_seed = $p_email . $p_username;
 481      $t_cookie_string = auth_generate_unique_cookie_string( $t_seed );
 482      $t_user_table = db_get_table( 'user' );
 483  
 484      $query = "INSERT INTO $t_user_table
 485                      ( username, email, password, date_created, last_visit,
 486                       enabled, access_level, login_count, cookie_string, realname )
 487                    VALUES
 488                      ( " . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param()  . ",
 489                       " . db_param() . ',' . db_param() . ',' . db_param() . ',' . db_param() . ', ' . db_param() . ')';
 490      db_query_bound( $query, Array( $p_username, $p_email, $t_password, db_now(), db_now(), $c_enabled, $c_access_level, 0, $t_cookie_string, $p_realname ) );
 491  
 492      # Create preferences for the user
 493      $t_user_id = db_insert_id( $t_user_table );
 494  
 495      # Users are added with protected set to FALSE in order to be able to update
 496      # preferences.  Now set the real value of protected.
 497      if( $c_protected ) {
 498          user_set_field( $t_user_id, 'protected', 1 );
 499      }
 500  
 501      # Send notification email
 502      if( !is_blank( $p_email ) ) {
 503          $t_confirm_hash = auth_generate_confirm_hash( $t_user_id );
 504          email_signup( $t_user_id, $p_password, $t_confirm_hash, $p_admin_name );
 505      }
 506  
 507      return $t_cookie_string;
 508  }
 509  
 510  # --------------------
 511  # Signup a user.
 512  # If the use_ldap_email config option is on then tries to find email using
 513  # ldap. $p_email may be empty, but the user wont get any emails.
 514  # returns false if error, the generated cookie string if ok
 515  function user_signup( $p_username, $p_email = null ) {
 516      if( null === $p_email ) {
 517          $p_email = '';
 518  
 519          # @@@ I think the ldap_email stuff is a bit borked
 520          #  Where is it being set?  When is it being used?
 521          #  Shouldn't we override an email that is passed in here?
 522          #  If the user doesn't exist in ldap, is the account created?
 523          #  If so, there password won't get set anywhere...  (etc)
 524          #  RJF: I was going to check for the existence of an LDAP email.
 525          #  however, since we can't create an LDAP account at the moment,
 526          #  and we don't know the user password in advance, we may not be able
 527          #  to retrieve it anyway.
 528          #  I'll re-enable this once a plan has been properly formulated for LDAP
 529          #  account management and creation.
 530          /*            $t_email = '';
 531                      if ( ON == config_get( 'use_ldap_email' ) ) {
 532                          $t_email = ldap_email_from_username( $p_username );
 533                      }
 534  
 535                      if ( !is_blank( $t_email ) ) {
 536                          $p_email = $t_email;
 537                      }
 538          */
 539      }
 540  
 541      $p_email = trim( $p_email );
 542  
 543      $t_seed = $p_email . $p_username;
 544  
 545      # Create random password
 546      $t_password = auth_generate_random_password( $t_seed );
 547  
 548      return user_create( $p_username, $t_password, $p_email );
 549  }
 550  
 551  # --------------------
 552  # delete project-specific user access levels.
 553  # returns true when successfully deleted
 554  function user_delete_project_specific_access_levels( $p_user_id ) {
 555      $c_user_id = db_prepare_int( $p_user_id );
 556  
 557      user_ensure_unprotected( $p_user_id );
 558  
 559      $t_project_user_list_table = db_get_table( 'project_user_list' );
 560  
 561      $query = "DELETE FROM $t_project_user_list_table
 562                    WHERE user_id=" . db_param();
 563      db_query_bound( $query, Array( $c_user_id ) );
 564  
 565      user_clear_cache( $p_user_id );
 566  
 567      return true;
 568  }
 569  
 570  # --------------------
 571  # delete profiles for the specified user
 572  # returns true when successfully deleted
 573  function user_delete_profiles( $p_user_id ) {
 574      $c_user_id = db_prepare_int( $p_user_id );
 575  
 576      user_ensure_unprotected( $p_user_id );
 577  
 578      $t_user_profile_table = db_get_table( 'user_profile' );
 579  
 580      # Remove associated profiles
 581      $query = "DELETE FROM $t_user_profile_table
 582                    WHERE user_id=" . db_param();
 583      db_query_bound( $query, Array( $c_user_id ) );
 584  
 585      user_clear_cache( $p_user_id );
 586  
 587      return true;
 588  }
 589  
 590  # --------------------
 591  # delete a user account (account, profiles, preferences, project-specific access levels)
 592  # returns true when the account was successfully deleted
 593  function user_delete( $p_user_id ) {
 594      $c_user_id = db_prepare_int( $p_user_id );
 595      $t_user_table = db_get_table( 'user' );
 596  
 597      user_ensure_unprotected( $p_user_id );
 598  
 599      # Remove associated profiles
 600      user_delete_profiles( $p_user_id );
 601  
 602      # Remove associated preferences
 603      user_pref_delete_all( $p_user_id );
 604  
 605      # Remove project specific access levels
 606      user_delete_project_specific_access_levels( $p_user_id );
 607  
 608      # unset non-unique realname flags if necessary
 609      if( config_get( 'differentiate_duplicates' ) ) {
 610          $c_realname = user_get_field( $p_user_id, 'realname' );
 611          $query = "SELECT id
 612                      FROM $t_user_table
 613                      WHERE realname=" . db_param();
 614          $result = db_query_bound( $query, Array( $c_realname ) );
 615          $t_count = db_num_rows( $result );
 616  
 617          if( $t_count == 2 ) {
 618  
 619              # unset flags if there are now only 2 unique names
 620              for( $i = 0;$i < $t_count;$i++ ) {
 621                  $t_user_id = db_result( $result, $i );
 622                  user_set_field( $t_user_id, 'duplicate_realname', OFF );
 623              }
 624          }
 625      }
 626  
 627      user_clear_cache( $p_user_id );
 628  
 629      # Remove account
 630      $query = "DELETE FROM $t_user_table
 631                    WHERE id=" . db_param();
 632      db_query_bound( $query, Array( $c_user_id ) );
 633  
 634      return true;
 635  }
 636  
 637  # ===================================
 638  # Data Access
 639  # ===================================
 640  # --------------------
 641  # get a user id from a username
 642  #  return false if the username does not exist
 643  function user_get_id_by_name( $p_username ) {
 644      global $g_cache_user;
 645      if( $t_user = user_search_cache( 'username', $p_username ) ) {
 646          return $t_user['id'];
 647      }
 648  
 649      $t_user_table = db_get_table( 'user' );
 650  
 651      $query = "SELECT *
 652                    FROM $t_user_table
 653                    WHERE username=" . db_param();
 654      $result = db_query_bound( $query, Array( $p_username ) );
 655  
 656      if( 0 == db_num_rows( $result ) ) {
 657          return false;
 658      } else {
 659          $row = db_fetch_array( $result );
 660          user_cache_database_result( $row );
 661          return $row['id'];
 662      }
 663  }
 664  
 665  # Get a user id from an email address
 666  function user_get_id_by_email( $p_email ) {
 667      global $g_cache_user;
 668      if( $t_user = user_search_cache( 'email', $p_email ) ) {
 669          return $t_user['id'];
 670      }
 671  
 672      $t_user_table = db_get_table( 'user' );
 673  
 674      $query = "SELECT *
 675                    FROM $t_user_table
 676                    WHERE email=" . db_param();
 677      $result = db_query_bound( $query, Array( $p_email ) );
 678  
 679      if( 0 == db_num_rows( $result ) ) {
 680          return false;
 681      } else {
 682          $row = db_fetch_array( $result );
 683          user_cache_database_result( $row );
 684          return $row['id'];
 685      }
 686  }
 687  
 688  # Get a user id from their real name
 689  function user_get_id_by_realname( $p_realname ) {
 690      global $g_cache_user;
 691      if( $t_user = user_search_cache( 'realname', $p_realname ) ) {
 692          return $t_user['id'];
 693      }
 694  
 695      $t_user_table = db_get_table( 'user' );
 696  
 697      $query = "SELECT *
 698                    FROM $t_user_table
 699                    WHERE realname=" . db_param();
 700      $result = db_query_bound( $query, Array( $p_realname ) );
 701  
 702      if( 0 == db_num_rows( $result ) ) {
 703          return false;
 704      } else {
 705          $row = db_fetch_array( $result );
 706          user_cache_database_result( $row );
 707          return $row['id'];
 708      }
 709  }
 710  
 711  # --------------------
 712  # return all data associated with a particular user name
 713  #  return false if the username does not exist
 714  function user_get_row_by_name( $p_username ) {
 715      $t_user_id = user_get_id_by_name( $p_username );
 716  
 717      if( false === $t_user_id ) {
 718          return false;
 719      }
 720  
 721      $row = user_get_row( $t_user_id );
 722  
 723      return $row;
 724  }
 725  
 726  # --------------------
 727  # return a user row
 728  function user_get_row( $p_user_id ) {
 729      return user_cache_row( $p_user_id );
 730  }
 731  
 732  # --------------------
 733  # return the specified user field for the user id
 734  function user_get_field( $p_user_id, $p_field_name ) {
 735      if( NO_USER == $p_user_id ) {
 736          trigger_error( 'user_get_field() for NO_USER', WARNING );
 737          return '@null@';
 738      }
 739  
 740      $row = user_get_row( $p_user_id );
 741  
 742      if( isset( $row[$p_field_name] ) ) {
 743          return $row[$p_field_name];
 744      } else {
 745          error_parameters( $p_field_name );
 746          trigger_error( ERROR_DB_FIELD_NOT_FOUND, WARNING );
 747          return '';
 748      }
 749  }
 750  
 751  # --------------------
 752  # lookup the user's email in LDAP or the db as appropriate
 753  function user_get_email( $p_user_id ) {
 754      $t_email = '';
 755      if( ON == config_get( 'use_ldap_email' ) ) {
 756          $t_email = ldap_email( $p_user_id );
 757      }
 758      if( is_blank( $t_email ) ) {
 759          $t_email = user_get_field( $p_user_id, 'email' );
 760      }
 761      return $t_email;
 762  }
 763  
 764  # --------------------
 765  # lookup the user's realname
 766  function user_get_realname( $p_user_id ) {
 767      $t_realname = '';
 768  
 769      if ( ON == config_get( 'use_ldap_realname' ) ) {
 770          $t_realname = ldap_realname( $p_user_id );
 771      }
 772  
 773      if ( is_blank( $t_realname ) ) {
 774          $t_realname = user_get_field( $p_user_id, 'realname' );
 775      }
 776  
 777      return $t_realname;
 778  }
 779  
 780  # --------------------
 781  # return the username or a string "user<id>" if the user does not exist
 782  # if $g_show_realname is set and real name is not empty, return it instead
 783  function user_get_name( $p_user_id ) {
 784      $row = user_cache_row( $p_user_id, false );
 785  
 786      if( false == $row ) {
 787          return lang_get( 'prefix_for_deleted_users' ) . (int) $p_user_id;
 788      } else {
 789          if( ON == config_get( 'show_realname' ) ) {
 790              if( is_blank( $row['realname'] ) ) {
 791                  return $row['username'];
 792              } else {
 793                  if( isset( $row['duplicate_realname'] ) && ( ON == $row['duplicate_realname'] ) ) {
 794                      return $row['realname'] . ' (' . $row['username'] . ')';
 795                  } else {
 796                      return $row['realname'];
 797                  }
 798              }
 799          } else {
 800              return $row['username'];
 801          }
 802      }
 803  }
 804  
 805  /**
 806  * Return the user avatar image URL
 807  * in this first implementation, only gravatar.com avatars are supported
 808  * @return array|bool an array( URL, width, height ) or false when the given user has no avatar
 809  */
 810  function user_get_avatar( $p_user_id, $p_size = 80 ) {
 811      $t_email = utf8_strtolower( user_get_email( $p_user_id ) );
 812      if( is_blank( $t_email ) ) {
 813          $t_result = false;
 814      } else {
 815          $t_default_image = config_get( 'default_avatar' );
 816          $t_size = $p_size;
 817  
 818          $t_use_ssl = false;
 819          if( isset( $_SERVER['HTTPS'] ) && ( utf8_strtolower( $_SERVER['HTTPS'] ) != 'off' ) ) {
 820              $t_use_ssl = true;
 821          }
 822  
 823          if( !$t_use_ssl ) {
 824              $t_gravatar_domain = 'http://www.gravatar.com/';
 825          } else {
 826              $t_gravatar_domain = 'https://secure.gravatar.com/';
 827          }
 828  
 829          $t_avatar_url = $t_gravatar_domain . 'avatar/' . md5( $t_email ) . '?default=' . urlencode( $t_default_image ) . '&size=' . $t_size . '&rating=G';
 830          $t_result = array(
 831              $t_avatar_url,
 832              $t_size,
 833              $t_size,
 834          );
 835      }
 836  
 837      return $t_result;
 838  }
 839  
 840  # --------------------
 841  # return the user's access level
 842  #  account for private project and the project user lists
 843  function user_get_access_level( $p_user_id, $p_project_id = ALL_PROJECTS ) {
 844      $t_access_level = user_get_field( $p_user_id, 'access_level' );
 845  
 846      if( user_is_administrator( $p_user_id ) ) {
 847          return $t_access_level;
 848      }
 849  
 850      $t_project_access_level = project_get_local_user_access_level( $p_project_id, $p_user_id );
 851  
 852      if( false === $t_project_access_level ) {
 853          return $t_access_level;
 854      } else {
 855          return $t_project_access_level;
 856      }
 857  }
 858  
 859  $g_user_accessible_projects_cache = null;
 860  
 861  # --------------------
 862  # retun an array of project IDs to which the user has access
 863  function user_get_accessible_projects( $p_user_id, $p_show_disabled = false ) {
 864      global $g_user_accessible_projects_cache;
 865  
 866      if( null !== $g_user_accessible_projects_cache && auth_get_current_user_id() == $p_user_id && false == $p_show_disabled ) {
 867          return $g_user_accessible_projects_cache;
 868      }
 869  
 870      if( access_has_global_level( config_get( 'private_project_threshold' ), $p_user_id ) ) {
 871          $t_projects = project_hierarchy_get_subprojects( ALL_PROJECTS, $p_show_disabled );
 872      } else {
 873          $t_project_table = db_get_table( 'project' );
 874          $t_project_user_list_table = db_get_table( 'project_user_list' );
 875          $t_project_hierarchy_table = db_get_table( 'project_hierarchy' );
 876  
 877          $t_public = VS_PUBLIC;
 878          $t_private = VS_PRIVATE;
 879  
 880          $result = null;
 881  
 882          $query = "SELECT p.id, p.name, ph.parent_id
 883                            FROM $t_project_table p
 884                            LEFT JOIN $t_project_user_list_table u
 885                              ON p.id=u.project_id AND u.user_id=" . db_param() . "
 886                            LEFT JOIN $t_project_hierarchy_table ph
 887                              ON ph.child_id = p.id
 888                            WHERE " . ( $p_show_disabled ? '' : ( 'p.enabled = ' . db_param() . ' AND ' ) ) . "
 889                              ( p.view_state=" . db_param() . "
 890                                  OR (p.view_state=" . db_param() . "
 891                                      AND
 892                                      u.user_id=" . db_param() . " )
 893                              )
 894                ORDER BY p.name";
 895          $result = db_query_bound( $query, ( $p_show_disabled ? Array( $p_user_id, $t_public, $t_private, $p_user_id ) : Array( $p_user_id, true, $t_public, $t_private, $p_user_id ) ) );
 896  
 897          $row_count = db_num_rows( $result );
 898  
 899          $t_projects = array();
 900  
 901          for( $i = 0;$i < $row_count;$i++ ) {
 902              $row = db_fetch_array( $result );
 903  
 904              $t_projects[(int)$row['id']] = ( $row['parent_id'] === NULL ) ? 0 : (int)$row['parent_id'];
 905          }
 906  
 907          # prune out children where the parents are already listed. Make the list
 908          #  first, then prune to avoid pruning a parent before the child is found.
 909          $t_prune = array();
 910          foreach( $t_projects as $t_id => $t_parent ) {
 911              if(( $t_parent !== 0 ) && isset( $t_projects[$t_parent] ) ) {
 912                  $t_prune[] = $t_id;
 913              }
 914          }
 915          foreach( $t_prune as $t_id ) {
 916              unset( $t_projects[$t_id] );
 917          }
 918          $t_projects = array_keys( $t_projects );
 919      }
 920  
 921      if( auth_get_current_user_id() == $p_user_id ) {
 922          $g_user_accessible_projects_cache = $t_projects;
 923      }
 924  
 925      return $t_projects;
 926  }
 927  
 928  $g_user_accessible_subprojects_cache = null;
 929  
 930  # --------------------
 931  # retun an array of subproject IDs of a certain project to which the user has access
 932  function user_get_accessible_subprojects( $p_user_id, $p_project_id, $p_show_disabled = false ) {
 933      global $g_user_accessible_subprojects_cache;
 934  
 935      if( null !== $g_user_accessible_subprojects_cache && auth_get_current_user_id() == $p_user_id && false == $p_show_disabled ) {
 936          if( isset( $g_user_accessible_subprojects_cache[$p_project_id] ) ) {
 937              return $g_user_accessible_subprojects_cache[$p_project_id];
 938          } else {
 939              return Array();
 940          }
 941      }
 942  
 943      $t_project_table = db_get_table( 'project' );
 944      $t_project_user_list_table = db_get_table( 'project_user_list' );
 945      $t_project_hierarchy_table = db_get_table( 'project_hierarchy' );
 946  
 947      $t_public = VS_PUBLIC;
 948      $t_private = VS_PRIVATE;
 949  
 950      if( access_has_global_level( config_get( 'private_project_threshold' ), $p_user_id ) ) {
 951          $t_enabled_clause = $p_show_disabled ? '' : 'p.enabled = ' . db_param() . ' AND';
 952          $query = "SELECT DISTINCT p.id, p.name, ph.parent_id
 953                        FROM $t_project_table p
 954                        LEFT JOIN $t_project_hierarchy_table ph
 955                          ON ph.child_id = p.id
 956                        WHERE $t_enabled_clause
 957                             ph.parent_id IS NOT NULL
 958                        ORDER BY p.name";
 959          $result = db_query_bound( $query, ( $p_show_disabled ? null : Array( true ) ) );
 960      } else {
 961          $query = "SELECT DISTINCT p.id, p.name, ph.parent_id
 962                        FROM $t_project_table p
 963                        LEFT JOIN $t_project_user_list_table u
 964                          ON p.id = u.project_id AND u.user_id=" . db_param() . "
 965                        LEFT JOIN $t_project_hierarchy_table ph
 966                          ON ph.child_id = p.id
 967                        WHERE " . ( $p_show_disabled ? '' : ( 'p.enabled = ' . db_param() . ' AND ' ) ) . '
 968                            ph.parent_id IS NOT NULL AND
 969                          ( p.view_state=' . db_param() . '
 970                              OR (p.view_state=' . db_param() . '
 971                                  AND
 972                                  u.user_id=' . db_param() . ' )
 973                          )
 974                        ORDER BY p.name';
 975          $result = db_query_bound( $query, ( $p_show_disabled ? Array( $p_user_id, $t_public, $t_private, $p_user_id ) : Array( $p_user_id, 1, $t_public, $t_private, $p_user_id ) ) );
 976      }
 977  
 978      $row_count = db_num_rows( $result );
 979  
 980      $t_projects = array();
 981  
 982      for( $i = 0;$i < $row_count;$i++ ) {
 983          $row = db_fetch_array( $result );
 984  
 985          if( !isset( $t_projects[(int)$row['parent_id']] ) ) {
 986              $t_projects[(int)$row['parent_id']] = array();
 987          }
 988  
 989          array_push( $t_projects[(int)$row['parent_id']], (int)$row['id'] );
 990      }
 991  
 992      if( auth_get_current_user_id() == $p_user_id ) {
 993          $g_user_accessible_subprojects_cache = $t_projects;
 994      }
 995  
 996      if( !isset( $t_projects[(int)$p_project_id] ) ) {
 997          $t_projects[(int)$p_project_id] = array();
 998      }
 999  
1000      return $t_projects[(int)$p_project_id];
1001  }
1002  
1003  # --------------------
1004  function user_get_all_accessible_subprojects( $p_user_id, $p_project_id ) {
1005      /** @todo (thraxisp) Should all top level projects be a sub-project of ALL_PROJECTS implicitly?
1006       *  affects how news and some summaries are generated
1007       */
1008      $t_todo = user_get_accessible_subprojects( $p_user_id, $p_project_id );
1009      $t_subprojects = Array();
1010  
1011      while( $t_todo ) {
1012          $t_elem = (int)array_shift( $t_todo );
1013          if( !in_array( $t_elem, $t_subprojects ) ) {
1014              array_push( $t_subprojects, $t_elem );
1015              $t_todo = array_merge( $t_todo, user_get_accessible_subprojects( $p_user_id, $t_elem ) );
1016          }
1017      }
1018  
1019      return $t_subprojects;
1020  }
1021  
1022  function user_get_all_accessible_projects( $p_user_id, $p_project_id ) {
1023      if( ALL_PROJECTS == $p_project_id ) {
1024          $t_topprojects = $t_project_ids = user_get_accessible_projects( $p_user_id );
1025          foreach( $t_topprojects as $t_project ) {
1026              $t_project_ids = array_merge( $t_project_ids, user_get_all_accessible_subprojects( $p_user_id, $t_project ) );
1027          }
1028  
1029          $t_project_ids = array_unique( $t_project_ids );
1030      } else {
1031          access_ensure_project_level( VIEWER, $p_project_id );
1032          $t_project_ids = user_get_all_accessible_subprojects( $p_user_id, $p_project_id );
1033          array_unshift( $t_project_ids, $p_project_id );
1034      }
1035  
1036      return $t_project_ids;
1037  }
1038  
1039  /**
1040   * Get a list of projects the specified user is assigned to.
1041   * @param int $p_user_id
1042   * @return array An array of projects by project id the specified user is assigned to.
1043   *        The array contains the id, name, view state, and project access level for the user.
1044   */
1045  function user_get_assigned_projects( $p_user_id ) {
1046      $t_mantis_project_user_list_table = db_get_table( 'project_user_list' );
1047      $t_mantis_project_table = db_get_table( 'project' );
1048  
1049      $t_query = "SELECT DISTINCT p.id, p.name, p.view_state, u.access_level
1050                  FROM $t_mantis_project_table p
1051                  LEFT JOIN $t_mantis_project_user_list_table u
1052                  ON p.id=u.project_id
1053                  WHERE p.enabled = '1' AND
1054                      u.user_id=" . db_param() . "
1055                  ORDER BY p.name";
1056      $t_result = db_query_bound( $t_query, array( $p_user_id ) );
1057      $category_count = db_num_rows( $t_result );
1058      $t_projects = array();
1059      for( $i = 0;$i < $category_count;$i++ ) {
1060          $t_row = db_fetch_array( $t_result );
1061          $t_project_id = $t_row['id'];
1062          $t_projects[$t_project_id] = $t_row;
1063      }
1064      return $t_projects;
1065  }
1066  
1067  /**
1068   * List of users that are NOT in the specified project and that are enabled
1069   * if no project is specified use the current project
1070   * also exclude any administrators
1071   *    @param int $p_project_id
1072   *    @return array List of users not assigned to the specified project
1073   */
1074  function user_get_unassigned_by_project_id( $p_project_id = null ) {
1075      $t_mantis_project_user_list_table = db_get_table( 'project_user_list' );
1076      $t_mantis_user_table = db_get_table( 'user' );
1077  
1078      if( null === $p_project_id ) {
1079          $p_project_id = helper_get_current_project();
1080      }
1081  
1082      $t_adm = config_get_global( 'admin_site_threshold' );
1083      $t_query = "SELECT DISTINCT u.id, u.username, u.realname
1084                  FROM $t_mantis_user_table u
1085                  LEFT JOIN $t_mantis_project_user_list_table p
1086                  ON p.user_id=u.id AND p.project_id=" . db_param() . "
1087                  WHERE u.access_level<" . db_param() . " AND
1088                      u.enabled = " . db_param() . " AND
1089                      p.user_id IS NULL
1090                  ORDER BY u.realname, u.username";
1091      $t_result = db_query_bound( $t_query, Array( $p_project_id, $t_adm, true ) );
1092      $t_display = array();
1093      $t_sort = array();
1094      $t_users = array();
1095      $t_show_realname = ( ON == config_get( 'show_realname' ) );
1096      $t_sort_by_last_name = ( ON == config_get( 'sort_by_last_name' ) );
1097      $t_user_count = db_num_rows( $t_result );
1098      while( $t_row = db_fetch_array( $t_result ) ) {
1099          $t_users[] = $t_row['id'];
1100          $t_user_name = string_attribute( $t_row['username'] );
1101          $t_sort_name = $t_user_name;
1102          if(( isset( $t_row['realname'] ) ) && ( $t_row['realname'] <> '' ) && $t_show_realname ) {
1103              $t_user_name = string_attribute( $t_row['realname'] );
1104              if( $t_sort_by_last_name ) {
1105                  $t_sort_name_bits = explode( ' ', utf8_strtolower( $t_user_name ), 2 );
1106                  $t_sort_name = ( isset( $t_sort_name_bits[1] ) ? $t_sort_name_bits[1] . ', ' : '' ) . $t_sort_name_bits[0];
1107              } else {
1108                  $t_sort_name = utf8_strtolower( $t_user_name );
1109              }
1110          }
1111          $t_display[] = $t_user_name;
1112          $t_sort[] = $t_sort_name;
1113      }
1114      array_multisort( $t_sort, SORT_ASC, SORT_STRING, $t_users, $t_display );
1115      $t_count = count( $t_sort );
1116      $t_user_list = array();
1117      for( $i = 0;$i < $t_count; $i++ ) {
1118          $t_user_list[$t_users[$i]] = $t_display[$i];
1119      }
1120      return $t_user_list;
1121  }
1122  
1123  # --------------------
1124  # return the number of open assigned bugs to a user in a project
1125  function user_get_assigned_open_bug_count( $p_user_id, $p_project_id = ALL_PROJECTS ) {
1126      $t_bug_table = db_get_table( 'bug' );
1127  
1128      $t_where_prj = helper_project_specific_where( $p_project_id, $p_user_id ) . ' AND';
1129  
1130      $t_resolved = config_get( 'bug_resolved_status_threshold' );
1131  
1132      $query = "SELECT COUNT(*)
1133                    FROM $t_bug_table
1134                    WHERE $t_where_prj
1135                            status<'$t_resolved' AND
1136                            handler_id=" . db_param();
1137      $result = db_query_bound( $query, Array( $p_user_id ) );
1138  
1139      return db_result( $result );
1140  }
1141  
1142  # --------------------
1143  # return the number of open reported bugs by a user in a project
1144  function user_get_reported_open_bug_count( $p_user_id, $p_project_id = ALL_PROJECTS ) {
1145      $t_bug_table = db_get_table( 'bug' );
1146  
1147      $t_where_prj = helper_project_specific_where( $p_project_id, $p_user_id ) . ' AND';
1148  
1149      $t_resolved = config_get( 'bug_resolved_status_threshold' );
1150  
1151      $query = "SELECT COUNT(*)
1152                    FROM $t_bug_table
1153                    WHERE $t_where_prj
1154                            status<'$t_resolved' AND
1155                            reporter_id=" . db_param();
1156      $result = db_query_bound( $query, Array( $p_user_id ) );
1157  
1158      return db_result( $result );
1159  }
1160  
1161  # --------------------
1162  # return a profile row
1163  function user_get_profile_row( $p_user_id, $p_profile_id ) {
1164      $c_user_id = db_prepare_int( $p_user_id );
1165      $c_profile_id = db_prepare_int( $p_profile_id );
1166  
1167      $t_user_profile_table = db_get_table( 'user_profile' );
1168  
1169      $query = "SELECT *
1170                    FROM $t_user_profile_table
1171                    WHERE id=" . db_param() . " AND
1172                            user_id=" . db_param();
1173      $result = db_query_bound( $query, Array( $c_profile_id, $c_user_id ) );
1174  
1175      if( 0 == db_num_rows( $result ) ) {
1176          trigger_error( ERROR_USER_PROFILE_NOT_FOUND, ERROR );
1177      }
1178  
1179      $row = db_fetch_array( $result );
1180  
1181      return $row;
1182  }
1183  
1184  # --------------------
1185  # Get failed login attempts
1186  function user_is_login_request_allowed( $p_user_id ) {
1187      $t_max_failed_login_count = config_get( 'max_failed_login_count' );
1188      $t_failed_login_count = user_get_field( $p_user_id, 'failed_login_count' );
1189      return( $t_failed_login_count < $t_max_failed_login_count || OFF == $t_max_failed_login_count );
1190  }
1191  
1192  # --------------------
1193  # Get 'lost password' in progress attempts
1194  function user_is_lost_password_request_allowed( $p_user_id ) {
1195      if( OFF == config_get( 'lost_password_feature' ) ) {
1196          return false;
1197      }
1198      $t_max_lost_password_in_progress_count = config_get( 'max_lost_password_in_progress_count' );
1199      $t_lost_password_in_progress_count = user_get_field( $p_user_id, 'lost_password_request_count' );
1200      return( $t_lost_password_in_progress_count < $t_max_lost_password_in_progress_count || OFF == $t_max_lost_password_in_progress_count );
1201  }
1202  
1203  # --------------------
1204  # return the bug filter parameters for the specified user
1205  function user_get_bug_filter( $p_user_id, $p_project_id = null ) {
1206      if( null === $p_project_id ) {
1207          $t_project_id = helper_get_current_project();
1208      } else {
1209          $t_project_id = $p_project_id;
1210      }
1211  
1212      $t_view_all_cookie_id = filter_db_get_project_current( $t_project_id, $p_user_id );
1213      $t_view_all_cookie = filter_db_get_filter( $t_view_all_cookie_id, $p_user_id );
1214      $t_cookie_detail = explode( '#', $t_view_all_cookie, 2 );
1215  
1216      if( !isset( $t_cookie_detail[1] ) ) {
1217          return false;
1218      }
1219  
1220      $t_filter = unserialize( $t_cookie_detail[1] );
1221  
1222      $t_filter = filter_ensure_valid_filter( $t_filter );
1223  
1224      return $t_filter;
1225  }
1226  
1227  # ===================================
1228  # Data Modification
1229  # ===================================
1230  # --------------------
1231  # Update the last_visited field to be now
1232  function user_update_last_visit( $p_user_id ) {
1233      $c_user_id = db_prepare_int( $p_user_id );
1234      $c_value = db_now();
1235  
1236      $t_user_table = db_get_table( 'user' );
1237  
1238      $query = "UPDATE $t_user_table
1239                    SET last_visit= " . db_param() . "
1240                    WHERE id=" . db_param();
1241  
1242      db_query_bound( $query, Array( $c_value, $c_user_id ) );
1243  
1244      user_update_cache( $p_user_id, 'last_visit', $c_value );
1245  
1246      # db_query errors on failure so:
1247      return true;
1248  }
1249  
1250  # --------------------
1251  # Increment the number of times the user has logegd in
1252  # This function is only called from the login.php script
1253  function user_increment_login_count( $p_user_id ) {
1254      $t_user_table = db_get_table( 'user' );
1255  
1256      $query = "UPDATE $t_user_table
1257                  SET login_count=login_count+1
1258                  WHERE id=" . db_param();
1259  
1260      db_query_bound( $query, Array( $p_user_id ) );
1261  
1262      user_clear_cache( $p_user_id );
1263  
1264      # db_query errors on failure so:
1265      return true;
1266  }
1267  
1268  # --------------------
1269  # Reset to zero the failed login attempts
1270  function user_reset_failed_login_count_to_zero( $p_user_id ) {
1271      $t_user_table = db_get_table( 'user' );
1272  
1273      $query = "UPDATE $t_user_table
1274                  SET failed_login_count=0
1275                  WHERE id=" . db_param();
1276      db_query_bound( $query, Array( $p_user_id ) );
1277  
1278      user_clear_cache( $p_user_id );
1279  
1280      return true;
1281  }
1282  
1283  # --------------------
1284  # Increment the failed login count by 1
1285  function user_increment_failed_login_count( $p_user_id ) {
1286      $t_user_table = db_get_table( 'user' );
1287  
1288      $query = "UPDATE $t_user_table
1289                  SET failed_login_count=failed_login_count+1
1290                  WHERE id=" . db_param();
1291      db_query_bound( $query, Array( $p_user_id ) );
1292  
1293      user_clear_cache( $p_user_id );
1294  
1295      return true;
1296  }
1297  
1298  # --------------------
1299  # Reset to zero the 'lost password' in progress attempts
1300  function user_reset_lost_password_in_progress_count_to_zero( $p_user_id ) {
1301      $t_user_table = db_get_table( 'user' );
1302  
1303      $query = "UPDATE $t_user_table
1304                  SET lost_password_request_count=0
1305                  WHERE id=" . db_param();
1306      db_query_bound( $query, Array( $p_user_id ) );
1307  
1308      user_clear_cache( $p_user_id );
1309  
1310      return true;
1311  }
1312  
1313  # --------------------
1314  # Increment the failed login count by 1
1315  function user_increment_lost_password_in_progress_count( $p_user_id ) {
1316      $t_user_table = db_get_table( 'user' );
1317  
1318      $query = "UPDATE $t_user_table
1319                  SET lost_password_request_count=lost_password_request_count+1
1320                  WHERE id=" . db_param();
1321      db_query_bound( $query, Array( $p_user_id ) );
1322  
1323      user_clear_cache( $p_user_id );
1324  
1325      return true;
1326  }
1327  
1328  # --------------------
1329  # Set a user field
1330  function user_set_field( $p_user_id, $p_field_name, $p_field_value ) {
1331      $c_user_id = db_prepare_int( $p_user_id );
1332      $c_field_name = db_prepare_string( $p_field_name );
1333  
1334      if( $p_field_name != 'protected' ) {
1335          user_ensure_unprotected( $p_user_id );
1336      }
1337  
1338      $t_user_table = db_get_table( 'user' );
1339  
1340      $query = 'UPDATE ' . $t_user_table .
1341               ' SET ' . $c_field_name . '=' . db_param() .
1342               ' WHERE id=' . db_param();
1343  
1344      db_query_bound( $query, Array( $p_field_value, $c_user_id ) );
1345  
1346      user_clear_cache( $p_user_id );
1347  
1348      # db_query errors on failure so:
1349      return true;
1350  }
1351  
1352  # --------------------
1353  # Set the user's default project
1354  function user_set_default_project( $p_user_id, $p_project_id ) {
1355      return user_pref_set_pref( $p_user_id, 'default_project', (int) $p_project_id );
1356  }
1357  
1358  # --------------------
1359  # Set the user's password to the given string, encoded as appropriate
1360  function user_set_password( $p_user_id, $p_password, $p_allow_protected = false ) {
1361      if( !$p_allow_protected ) {
1362          user_ensure_unprotected( $p_user_id );
1363      }
1364  
1365      $t_email = user_get_field( $p_user_id, 'email' );
1366      $t_username = user_get_field( $p_user_id, 'username' );
1367  
1368      # When the password is changed, invalidate the cookie to expire sessions that
1369      # may be active on all browsers.
1370      $t_seed = $t_email . $t_username;
1371      $c_cookie_string = auth_generate_unique_cookie_string( $t_seed );
1372  
1373      $c_user_id = db_prepare_int( $p_user_id );
1374      $c_password = auth_process_plain_password( $p_password );
1375      $c_user_table = db_get_table( 'user' );
1376  
1377      $query = "UPDATE $c_user_table
1378                    SET password=" . db_param() . ",
1379                    cookie_string=" . db_param() . "
1380                    WHERE id=" . db_param();
1381      db_query_bound( $query, Array( $c_password, $c_cookie_string, $c_user_id ) );
1382  
1383      # db_query errors on failure so:
1384      return true;
1385  }
1386  
1387  # --------------------
1388  # Set the user's email to the given string after checking that it is a valid email
1389  function user_set_email( $p_user_id, $p_email ) {
1390      email_ensure_valid( $p_email );
1391  
1392      return user_set_field( $p_user_id, 'email', $p_email );
1393  }
1394  
1395  # --------------------
1396  # Set the user's realname to the given string after checking validity
1397  function user_set_realname( $p_user_id, $p_realname ) {
1398      return user_set_field( $p_user_id, 'realname', $p_realname );
1399  }
1400  
1401  # --------------------
1402  # Set the user's username to the given string after checking that it is valid
1403  function user_set_name( $p_user_id, $p_username ) {
1404      user_ensure_name_valid( $p_username );
1405      user_ensure_name_unique( $p_username );
1406  
1407      return user_set_field( $p_user_id, 'username', $p_username );
1408  }
1409  
1410  # --------------------
1411  # Reset the user's password
1412  #  Take into account the 'send_reset_password' setting
1413  #   - if it is ON, generate a random password and send an email
1414  #      (unless the second parameter is false)
1415  #   - if it is OFF, set the password to blank
1416  #  Return false if the user is protected, true if the password was
1417  #   successfully reset
1418  function user_reset_password( $p_user_id, $p_send_email = true ) {
1419      $t_protected = user_get_field( $p_user_id, 'protected' );
1420  
1421      # Go with random password and email it to the user
1422      if( ON == $t_protected ) {
1423          return false;
1424      }
1425  
1426      # @@@ do we want to force blank password instead of random if
1427      #      email notifications are turned off?
1428      #     How would we indicate that we had done this with a return value?
1429      #     Should we just have two functions? (user_reset_password_random()
1430      #     and user_reset_password() )?
1431      if(( ON == config_get( 'send_reset_password' ) ) && ( ON == config_get( 'enable_email_notification' ) ) ) {
1432  
1433          # Create random password
1434          $t_email = user_get_field( $p_user_id, 'email' );
1435          $t_password = auth_generate_random_password( $t_email );
1436          $t_password2 = auth_process_plain_password( $t_password );
1437  
1438          user_set_field( $p_user_id, 'password', $t_password2 );
1439  
1440          # Send notification email
1441          if( $p_send_email ) {
1442              $t_confirm_hash = auth_generate_confirm_hash( $p_user_id );
1443              email_send_confirm_hash_url( $p_user_id, $t_confirm_hash );
1444          }
1445      } else {
1446  
1447          # use blank password, no emailing
1448          $t_password = auth_process_plain_password( '' );
1449          user_set_field( $p_user_id, 'password', $t_password );
1450  
1451          # reset the failed login count because in this mode there is no emailing
1452          user_reset_failed_login_count_to_zero( $p_user_id );
1453      }
1454  
1455      return true;
1456  }


Generated: Thu Jul 28 15:48:31 2011 Cross-referenced by PHPXref 0.7