b2evolution PHP Cross Reference Blogging Systems

Source: /inc/users/model/_usercache.class.php - 371 lines - 10359 bytes - Summary - Text - Print

Description: This file implements the UserCache class. This file is part of the evoCore framework - {@link http://evocore.net/} See also {@link http://sourceforge.net/projects/evocms/}.

   1  <?php
   2  /**
   3   * This file implements the UserCache class.
   4   *
   5   * This file is part of the evoCore framework - {@link http://evocore.net/}
   6   * See also {@link http://sourceforge.net/projects/evocms/}.
   7   *
   8   * @copyright (c)2003-2014 by Francois Planque - {@link http://fplanque.com/}
   9   * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.
  10   *
  11   * {@internal License choice
  12   * - If you have received this file as part of a package, please find the license.txt file in
  13   *   the same folder or the closest folder above for complete license terms.
  14   * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
  15   *   then you must choose one of the following licenses before using the file:
  16   *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
  17   *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
  18   * }}
  19   *
  20   * {@internal Open Source relicensing agreement:
  21   * Daniel HAHLER grants Francois PLANQUE the right to license
  22   * Daniel HAHLER's contributions to this file and the b2evolution project
  23   * under any OSI approved OSS license (http://www.opensource.org/licenses/).
  24   * }}
  25   *
  26   * @package evocore
  27   *
  28   * {@internal Below is a list of authors who have contributed to design/coding of this file: }}
  29   * @author fplanque: Francois PLANQUE
  30   * @author blueyed: Daniel HAHLER
  31   *
  32   * @version $Id: _usercache.class.php 6136 2014-03-08 07:59:48Z manuel $
  33   */
  34  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  35  
  36  load_class( '_core/model/dataobjects/_dataobjectcache.class.php', 'DataObjectCache' );
  37  
  38  /**
  39   * Blog Cache Class
  40   *
  41   * @package evocore
  42   */
  43  class UserCache extends DataObjectCache
  44  {
  45      /**
  46       * Cache for login -> User object reference. "login" is transformed to lowercase.
  47       * @access private
  48       * @var array
  49       */
  50      var $cache_login = array();
  51  
  52  
  53      /**
  54       * Remember special cache loads.
  55       * @access protected
  56       */
  57      var $alreadyCached = array();
  58  
  59  
  60      /**
  61       * Constructor
  62       */
  63  	function UserCache()
  64      {
  65          parent::DataObjectCache( 'User', false, 'T_users', 'user_', 'user_ID', NULL, '',
  66              /* TRANS: "None" select option */ T_('No user') );
  67      }
  68  
  69      /* this is for debugging only:
  70      function & get_by_ID( $req_ID, $halt_on_error = true )
  71      {
  72          $obj = parent::get_by_ID( $req_ID, $halt_on_error );
  73              pre_dump($obj);
  74          return $obj;
  75      }
  76      */
  77  
  78  
  79      /**
  80       * Get a user object by login.
  81       *
  82       * Does not halt on error.
  83       *
  84       * @param string user login
  85       * @param boolean force to run db query to get user by the given login.
  86       *        !IMPORTANT! Set this to false only if it's sure that this user was already loaded if it exists on DB!
  87       *
  88       * @return false|User Reference to the user object or false if not found
  89       */
  90      function & get_by_login( $login, $force_db_check = true )
  91      {
  92          // Make sure we have a lowercase login:
  93          // We want all logins to be lowercase to guarantee uniqueness regardless of the database case handling for UNIQUE indexes.
  94          $login = evo_strtolower( $login );
  95  
  96          if( !( $force_db_check || isset( $this->cache_login[$login] ) ) )
  97          { // force db check is false and this login is not set in the cache it means that user with the given login doesn't exists
  98              $this->cache_login[$login] = false;
  99          }
 100  
 101          if( !isset( $this->cache_login[$login] ) )
 102          {
 103              global $DB;
 104  
 105              if( $row = $DB->get_row( "
 106                      SELECT *
 107                        FROM T_users
 108                       WHERE user_login = '".$DB->escape($login)."'", 0, 0, 'Get User login' ) )
 109              {
 110                  $this->add( new User( $row ) );
 111              }
 112              else
 113              {
 114                  $this->cache_login[$login] = false;
 115              }
 116          }
 117  
 118          return $this->cache_login[$login];
 119      }
 120  
 121  
 122      /**
 123       * Get a user object by login, only if password matches.
 124       *
 125       * @param string Login
 126       * @param string Password
 127       * @param boolean Password is MD5()'ed
 128       * @return false|User
 129       */
 130      function & get_by_loginAndPwd( $login, $pass, $pass_is_md5 = true )
 131      {
 132          if( !($User =& $this->get_by_login( $login )) )
 133          {
 134              return false;
 135          }
 136  
 137          if( !$pass_is_md5 )
 138          {
 139              $pass = md5($pass);
 140          }
 141  
 142          if( $User->pass != $pass )
 143          {
 144              return false;
 145          }
 146  
 147          return $User;
 148      }
 149  
 150  
 151      /**
 152       * Get a user object by email and password
 153       * If multiple accounts match, give priority to:
 154       *  -accounts that are activated over non activated accounts
 155       *  -accounts that were used more recently than others
 156       *
 157       * @param string email address
 158       * @param string md5 hashed password
 159       * @param string hashed password - If this is set, it means we need to check the hasshed password instead of the md5 password
 160       * @param string password salt
 161       * @return false|array false if user with this email not exists, array( $User, $exists_more ) pair otherwise
 162       */
 163  	function get_by_emailAndPwd( $email, $pass_md5, $pwd_hashed = NULL, $pwd_salt = NULL )
 164      {
 165          global $DB;
 166  
 167          // Get all users with matching email address
 168          $result = $DB->get_results('SELECT * FROM T_users
 169                      WHERE LOWER(user_email) = '.$DB->quote( evo_strtolower($email) ).'
 170                      ORDER BY user_lastseen_ts DESC, user_status ASC');
 171  
 172          if( empty( $result ) )
 173          { // user was not found with the given email address
 174              return false;
 175          }
 176  
 177          // check if exists more user with the same email address
 178          $exists_more = ( count( $result ) > 1 );
 179          $index = -1;
 180          $first_matched_index = false;
 181          // iterate through the result list
 182          foreach( $result as $row )
 183          {
 184              $index++;
 185              if( empty( $pwd_hashed ) )
 186              {
 187                  if( $row->user_pass != $pass_md5 )
 188                  { // password doesn't match
 189                      continue;
 190                  }
 191              }
 192              elseif( sha1($row->user_pass.$pwd_salt) != $pwd_hashed )
 193              { // password doesn't match
 194                  continue;
 195              }
 196              // a user with matched password was found
 197              $first_matched_index = $index;
 198              if( ( $row->user_status == 'activated' ) || ( $row->user_status == 'autoactivated' ) )
 199              { // an activated user was found, break from the iteration
 200                  $User = new User( $row );
 201                  break;
 202              }
 203              if( ( !isset( $first_notclosed_User ) ) && ( $row->user_status != 'closed' ) )
 204              {
 205                  $first_notclosed_User = new User( $row );
 206              }
 207          }
 208  
 209          if( !isset( $User ) )
 210          { // There is no activated user with the given email and password
 211              if( isset( $first_notclosed_User ) )
 212              { // Get first not closed user with the given email and password
 213                  $User = $first_notclosed_User;
 214              }
 215              elseif( $first_matched_index !== false )
 216              { // There is only closed user with the given email and password
 217                  $User = new User( $result[$first_matched_index] );
 218              }
 219              else
 220              { // No matched user was found
 221                  return false;
 222              }
 223          }
 224  
 225          // Add user to the cache and return result
 226          $this->add( $User );
 227          return array( & $User, $exists_more );
 228      }
 229  
 230  
 231      /**
 232       * Overload parent's function to also maintain the login cache.
 233       *
 234       * @param User
 235       * @return boolean
 236       */
 237  	function add( & $Obj )
 238      {
 239          if( parent::add( $Obj ) )
 240          {
 241              $this->cache_login[ evo_strtolower($Obj->login) ] = & $Obj;
 242  
 243              return true;
 244          }
 245  
 246          return false;
 247      }
 248  
 249  
 250      /**
 251       * Load members of a given blog
 252       *
 253       * @todo make a UNION query when we upgrade to MySQL 4
 254       * @param integer Blog ID to load members for
 255       * @param integer Limit, 0 - for unlimit
 256       */
 257  	function load_blogmembers( $blog_ID, $limit = 0 )
 258      {
 259          global $DB, $Debuglog;
 260  
 261          if( isset( $this->alreadyCached['blogmembers'] ) && isset( $this->alreadyCached['blogmembers'][$blog_ID] ) )
 262          {
 263              $Debuglog->add( "Already loaded <strong>$this->objtype(Blog #$blog_ID members)</strong> into cache", 'dataobjects' );
 264              return false;
 265          }
 266  
 267          // Clear previous users to get only the members of this blog
 268          $this->clear();
 269  
 270          // Remember this special load:
 271          $this->alreadyCached['blogmembers'][$blog_ID] = true;
 272  
 273          $Debuglog->add( "Loading <strong>$this->objtype(Blog #$blog_ID members)</strong> into cache", 'dataobjects' );
 274  
 275          // Get users which are members of the blog:
 276          $user_perms_SQL = new SQL();
 277          $user_perms_SQL->SELECT( 'T_users.*' );
 278          $user_perms_SQL->FROM( 'T_users' );
 279          $user_perms_SQL->FROM_add( 'INNER JOIN T_coll_user_perms ON user_ID = bloguser_user_ID' );
 280          $user_perms_SQL->WHERE( 'bloguser_blog_ID = '.$DB->quote( $blog_ID ) );
 281          $user_perms_SQL->WHERE_and( 'bloguser_ismember <> 0' );
 282  
 283          // Get users which groups are members of the blog:
 284          $group_perms_SQL = new SQL();
 285          $group_perms_SQL->SELECT( 'T_users.*' );
 286          $group_perms_SQL->FROM( 'T_users' );
 287          $group_perms_SQL->FROM_add( 'INNER JOIN T_coll_group_perms ON user_grp_ID = bloggroup_group_ID' );
 288          $group_perms_SQL->WHERE( 'bloggroup_blog_ID = '.$DB->quote( $blog_ID ) );
 289          $group_perms_SQL->WHERE_and( 'bloggroup_ismember <> 0' );
 290  
 291          // Union two sql queries to execute one query and save an order as one list
 292          $users_sql = '( '.$user_perms_SQL->get().' )'
 293              .' UNION '
 294              .'( '.$group_perms_SQL->get().' )'
 295              .' ORDER BY user_login';
 296          if( $limit > 0 )
 297          { // Limit the users
 298              $users_sql .= ' LIMIT '.$limit;
 299          }
 300  
 301          $users = $DB->get_results( $users_sql );
 302          foreach( $users as $row )
 303          {
 304              if( !isset($this->cache[$row->user_ID]) )
 305              { // Save reinstatiating User if it's already been added
 306                  $this->add( new User( $row ) );
 307              }
 308          }
 309  
 310          return true;
 311      }
 312  
 313  
 314      /**
 315       * Loads cache with blog memeber, then display form option list with cache contents
 316       *
 317       * Optionally, also adds default choice to the cache.
 318       *
 319       * @param integer blog ID or 0 for ALL
 320       * @param integer selected ID
 321       * @param boolean provide a choice for "none" with ID 0
 322       * @param boolean make sur the current default user is part of the choices
 323       */
 324  	function get_blog_member_option_list( $blog_ID, $default = 0, $allow_none = false, $always_load_default = false )
 325      {
 326          if( $blog_ID )
 327          { // Load requested blog members:
 328              $this->load_blogmembers( $blog_ID );
 329  
 330              // Make sure current user is in list:
 331              if( $default && $always_load_default )
 332              {
 333                  // echo '<option>getting default';
 334                  $this->get_by_ID( $default );
 335              }
 336          }
 337          else
 338          { // No blog specified: load ALL members:
 339              $this->load_all();
 340          }
 341  
 342          return parent::get_option_list( $default, $allow_none, 'get_preferred_name' );
 343      }
 344  
 345  
 346      /**
 347       * Clear our caches.
 348       */
 349  	function clear( $keep_shadow = false )
 350      {
 351          $this->alreadyCached = array();
 352          $this->cache_login = array();
 353  
 354          return parent::clear($keep_shadow);
 355      }
 356  
 357      /**
 358       * Handle our login cache.
 359       */
 360  	function remove_by_ID( $req_ID )
 361      {
 362          if( isset($this->cache[$req_ID]) )
 363          {
 364              $Obj = & $this->cache[$req_ID];
 365              unset( $this->cache_login[ evo_strtolower($Obj->login) ] );
 366          }
 367          parent::remove_by_ID($req_ID);
 368      }
 369  }
 370  
 371  ?>

title

Description

title

Description

title

Description

title

title

Body