[ Index ]
 

Code source de eZ Publish 3.9.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/kernel/classes/datatypes/ezuser/ -> ezuser.php (source)

   1  <?php
   2  //
   3  // Definition of eZUser class
   4  //
   5  // Created on: <10-Jun-2002 17:03:15 bf>
   6  //
   7  // SOFTWARE NAME: eZ publish
   8  // SOFTWARE RELEASE: 3.9.0
   9  // BUILD VERSION: 17785
  10  // COPYRIGHT NOTICE: Copyright (C) 1999-2006 eZ systems AS
  11  // SOFTWARE LICENSE: GNU General Public License v2.0
  12  // NOTICE: >
  13  //   This program is free software; you can redistribute it and/or
  14  //   modify it under the terms of version 2.0  of the GNU General
  15  //   Public License as published by the Free Software Foundation.
  16  //
  17  //   This program is distributed in the hope that it will be useful,
  18  //   but WITHOUT ANY WARRANTY; without even the implied warranty of
  19  //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20  //   GNU General Public License for more details.
  21  //
  22  //   You should have received a copy of version 2.0 of the GNU General
  23  //   Public License along with this program; if not, write to the Free
  24  //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  25  //   MA 02110-1301, USA.
  26  //
  27  //
  28  
  29  /*!
  30    \class eZUser ezuser.php
  31    \brief eZUser handles eZ publish user accounts
  32    \ingroup eZDatatype
  33  
  34  */
  35  
  36  include_once ( 'kernel/classes/ezpersistentobject.php' );
  37  include_once ( 'lib/ezutils/classes/ezhttptool.php' );
  38  include_once ( 'lib/ezfile/classes/ezdir.php' );
  39  include_once ( 'lib/ezutils/classes/ezsys.php' );
  40  
  41  $ini =& eZINI::instance();
  42  define( 'EZ_USER_ANONYMOUS_ID', (int)$ini->variable( 'UserSettings', 'AnonymousUserID' ) );
  43  
  44  /// MD5 of password
  45  define( 'EZ_USER_PASSWORD_HASH_MD5_PASSWORD', 1 );
  46  /// MD5 of user and password
  47  define( 'EZ_USER_PASSWORD_HASH_MD5_USER', 2 );
  48  /// MD5 of site, user and password
  49  define( 'EZ_USER_PASSWORD_HASH_MD5_SITE', 3 );
  50  /// Legacy support for mysql hashed passwords
  51  define( 'EZ_USER_PASSWORD_HASH_MYSQL', 4 );
  52  /// Passwords in plaintext, should not be used for real sites
  53  define( 'EZ_USER_PASSWORD_HASH_PLAINTEXT', 5 );
  54  
  55  /// Authenticate by matching the login field
  56  define( 'EZ_USER_AUTHENTICATE_LOGIN', 1 << 0 );
  57  /// Authenticate by matching the email field
  58  define( 'EZ_USER_AUTHENTICATE_EMAIL', 1 << 1 );
  59  
  60  define( 'EZ_USER_AUTHENTICATE_ALL', EZ_USER_AUTHENTICATE_LOGIN | EZ_USER_AUTHENTICATE_EMAIL );
  61  
  62  $GLOBALS['eZUserBuiltins'] = array( EZ_USER_ANONYMOUS_ID );
  63  
  64  class eZUser extends eZPersistentObject
  65  {
  66      function eZUser( $row )
  67      {
  68          $this->eZPersistentObject( $row );
  69          $this->OriginalPassword = false;
  70          $this->OriginalPasswordConfirm = false;
  71      }
  72  
  73      function definition()
  74      {
  75          return array( 'fields' => array( 'contentobject_id' => array( 'name' => 'ContentObjectID',
  76                                                                        'datatype' => 'integer',
  77                                                                        'default' => 0,
  78                                                                        'required' => true,
  79                                                                        'foreign_class' => 'eZContentObject',
  80                                                                        'foreign_attribute' => 'id',
  81                                                                        'multiplicity' => '0..1' ),
  82                                           'login' => array( 'name' => 'Login',
  83                                                             'datatype' => 'string',
  84                                                             'default' => '',
  85                                                             'required' => true ),
  86                                           'email' => array( 'name' => 'Email',
  87                                                             'datatype' => 'string',
  88                                                             'default' => '',
  89                                                             'required' => true ),
  90                                           'password_hash' => array( 'name' => 'PasswordHash',
  91                                                                     'datatype' => 'string',
  92                                                                     'default' => '',
  93                                                                     'required' => true ),
  94                                           'password_hash_type' => array( 'name' => 'PasswordHashType',
  95                                                                          'datatype' => 'integer',
  96                                                                          'default' => 1,
  97                                                                          'required' => true ) ),
  98                        'keys' => array( 'contentobject_id' ),
  99                        'function_attributes' => array( 'contentobject' => 'contentObject',
 100                                                        'groups' => 'groups',
 101                                                        'has_stored_login' => 'hasStoredLogin',
 102                                                        'original_password' => 'originalPassword',
 103                                                        'original_password_confirm' => 'originalPasswordConfirm',
 104                                                        'roles' => 'roles',
 105                                                        'role_id_list' => 'roleIDList',
 106                                                        'limited_assignment_value_list' => 'limitValueList',
 107                                                        'is_logged_in' => 'isLoggedIn',
 108                                                        'is_enabled' => 'isEnabled',
 109                                                        'is_locked' => 'isLocked',
 110                                                        'last_visit' => 'lastVisit',
 111                                                        'has_manage_locations' => 'hasManageLocations' ),
 112                        'relations' => array( 'contentobject_id' => array( 'class' => 'ezcontentobject',
 113                                                                           'field' => 'id' ) ),
 114                        'class_name' => 'eZUser',
 115                        'name' => 'ezuser' );
 116      }
 117  
 118      /*!
 119       \return a textual identifier for the hash type $id
 120      */
 121      function passwordHashTypeName( $id )
 122      {
 123          switch ( $id )
 124          {
 125              case EZ_USER_PASSWORD_HASH_MD5_PASSWORD:
 126              {
 127                  return 'md5_password';
 128              } break;
 129              case EZ_USER_PASSWORD_HASH_MD5_USER:
 130              {
 131                  return 'md5_user';
 132              } break;
 133              case EZ_USER_PASSWORD_HASH_MD5_SITE:
 134              {
 135                  return 'md5_site';
 136              } break;
 137              case EZ_USER_PASSWORD_HASH_MYSQL:
 138              {
 139                  return 'mysql';
 140              } break;
 141              case EZ_USER_PASSWORD_HASH_PLAINTEXT:
 142              {
 143                  return 'plaintext';
 144              } break;
 145          }
 146      }
 147  
 148      /*!
 149       \return the hash type for the textual identifier $identifier
 150      */
 151      function passwordHashTypeID( $identifier )
 152      {
 153          switch ( $identifier )
 154          {
 155              case 'md5_password':
 156              {
 157                  return EZ_USER_PASSWORD_HASH_MD5_PASSWORD;
 158              } break;
 159              default:
 160              case 'md5_user':
 161              {
 162                  return EZ_USER_PASSWORD_HASH_MD5_USER;
 163              } break;
 164              case 'md5_site':
 165              {
 166                  return EZ_USER_PASSWORD_HASH_MD5_SITE;
 167              } break;
 168              case 'mysql':
 169              {
 170                  return EZ_USER_PASSWORD_HASH_MYSQL;
 171              } break;
 172              case 'plaintext':
 173              {
 174                  return EZ_USER_PASSWORD_HASH_PLAINTEXT;
 175              } break;
 176          }
 177      }
 178  
 179      /*!
 180       Check if current user has "content/manage_locations" access
 181      */
 182      function &hasManageLocations()
 183      {
 184          $retValue = false;
 185          $accessResult = $this->hasAccessTo( 'content', 'manage_locations' );
 186          if ( $accessResult['accessWord'] != 'no' )
 187          {
 188              $retValue = true;
 189          }
 190  
 191          return $retValue;
 192      }
 193  
 194      function create( $contentObjectID )
 195      {
 196          $row = array(
 197              'contentobject_id' => $contentObjectID,
 198              'login' => null,
 199              'email' => null,
 200              'password_hash' => null,
 201              'password_hash_type' => null
 202              );
 203          return new eZUser( $row );
 204      }
 205  
 206      function store()
 207      {
 208          $this->Email = trim( $this->Email );
 209          include_once ( 'lib/ezutils/classes/ezexpiryhandler.php' );
 210          $handler =& eZExpiryHandler::instance();
 211          $handler->setTimestamp( 'user-info-cache', mktime() );
 212          $handler->setTimestamp( 'user-groups-cache', mktime() );
 213          $handler->setTimestamp( 'user-access-cache', mktime() );
 214          $handler->store();
 215          $userID = $this->attribute( 'contentobject_id' );
 216          // Clear memory cache
 217          unset( $GLOBALS['eZUserObject_' . $userID] );
 218          $GLOBALS['eZUserObject_' . $userID] =& $this;
 219          eZPersistentObject::store();
 220      }
 221  
 222      function &originalPassword()
 223      {
 224          return $this->OriginalPassword;
 225      }
 226  
 227      function setOriginalPassword( $password )
 228      {
 229          $this->OriginalPassword = $password;
 230      }
 231  
 232      function &originalPasswordConfirm()
 233      {
 234          return $this->OriginalPasswordConfirm;
 235      }
 236  
 237      function setOriginalPasswordConfirm( $password )
 238      {
 239          $this->OriginalPasswordConfirm = $password;
 240      }
 241  
 242      function &hasStoredLogin()
 243      {
 244          $db =& eZDB::instance();
 245          $contentObjectID = $this->attribute( 'contentobject_id' );
 246          $sql = "SELECT * FROM ezuser WHERE contentobject_id='$contentObjectID' AND LENGTH( login ) > 0";
 247          $rows = $db->arrayQuery( $sql );
 248          $hasStoredLogin = count( $rows ) > 0;
 249          return $hasStoredLogin;
 250      }
 251  
 252      /*!
 253       Fills in the \a $id, \a $login, \a $email and \a $password for the user
 254       and creates the proper password hash.
 255      */
 256      function setInformation( $id, $login, $email, $password, $passwordConfirm = false )
 257      {
 258          $this->setAttribute( "contentobject_id", $id );
 259          $this->setAttribute( "email", $email );
 260          $this->setAttribute( "login", $login );
 261          $ini =& eZINI::instance();
 262          $minPasswordLength = $ini->hasVariable( 'UserSettings', 'MinPasswordLength' ) ? $ini->variable( 'UserSettings', 'MinPasswordLength' ) : 3;
 263          if ( $password !== false and
 264               $password !== null and
 265               $password == $passwordConfirm and
 266               strlen( $password ) >= (int) $minPasswordLength ) // Cannot change login or password_hash without login and password
 267          {
 268              $this->setAttribute( "password_hash", eZUser::createHash( $login, $password, eZUser::site(),
 269                                                                        eZUser::hashType() ) );
 270              $this->setAttribute( "password_hash_type", eZUser::hashType() );
 271          }
 272          else
 273          {
 274              $this->setOriginalPassword( $password );
 275              $this->setOriginalPasswordConfirm( $passwordConfirm );
 276          }
 277      }
 278  
 279      function fetch( $id, $asObject = true )
 280      {
 281          return eZPersistentObject::fetchObject( eZUser::definition(),
 282                                                  null,
 283                                                  array( 'contentobject_id' => $id ),
 284                                                  $asObject );
 285      }
 286  
 287      function fetchByName( $login, $asObject = true )
 288      {
 289          return eZPersistentObject::fetchObject( eZUser::definition(),
 290                                                  null,
 291                                                  array( 'LOWER( login )' => strtolower( $login ) ),
 292                                                  $asObject );
 293      }
 294  
 295      function fetchByEmail( $email, $asObject = true )
 296      {
 297          return eZPersistentObject::fetchObject( eZUser::definition(),
 298                                                    null,
 299                                                    array( 'LOWER( email )' => strtolower( $email ) ),
 300                                                    $asObject );
 301      }
 302  
 303      /*!
 304       \static
 305       \return a list of the logged in users.
 306       \param $asObject If false it will return a list with only the names of the users as elements and user ID as key,
 307                        otherwise each entry is a eZUser object.
 308       \sa fetchLoggedInCount
 309      */
 310      function fetchLoggedInList( $asObject = false, $offset = false, $limit = false, $sortBy = false )
 311      {
 312          $db =& eZDB::instance();
 313          $time = mktime();
 314          $ini =& eZINI::instance();
 315          $activityTimeout = $ini->variable( 'Session', 'ActivityTimeout' );
 316          $sessionTimeout = $ini->variable( 'Session', 'SessionTimeout' );
 317          $time = $time + $sessionTimeout - $activityTimeout;
 318  
 319          $parameters = array();
 320          if ( $offset )
 321              $parameters['offset'] =(int) $offset;
 322          if ( $limit )
 323              $parameters['limit'] =(int) $limit;
 324          $sortText = '';
 325          if ( $asObject )
 326          {
 327              $selectArray = array( "distinct ezuser.*" );
 328          }
 329          else
 330          {
 331              $selectArray = array( "ezuser.contentobject_id as user_id", "ezcontentobject.name" );
 332          }
 333          if ( $sortBy !== false )
 334          {
 335              $sortElements = array();
 336              if ( !is_array( $sortBy ) )
 337              {
 338                  $sortBy = array( array( $sortBy, true ) );
 339              }
 340              else if ( !is_array( $sortBy[0] ) )
 341                  $sortBy = array( $sortBy );
 342              $sortColumns = array();
 343              foreach ( $sortBy as $sortElements )
 344              {
 345                  $sortColumn = $sortElements[0];
 346                  $sortOrder = $sortElements[1];
 347                  $orderText = $sortOrder ? 'asc' : 'desc';
 348                  switch ( $sortColumn )
 349                  {
 350                      case 'user_id':
 351                      {
 352                          $sortColumn = "ezuser.contentobject_id $orderText";
 353                      } break;
 354  
 355                      case 'login':
 356                      {
 357                          $sortColumn = "ezuser.login $orderText";
 358                      } break;
 359  
 360                      case 'activity':
 361                      {
 362                          $selectArray[] = "( ezsession.expiration_time -  " . ( $sessionTimeout - $activityTimeout ) . " ) AS activity";
 363                          $sortColumn = "activity $orderText";
 364                      } break;
 365  
 366                      case 'email':
 367                      {
 368                          $sortColumn = "ezuser.email $orderText";
 369                      } break;
 370  
 371                      default:
 372                      {
 373                          eZDebug::writeError( "Unkown sort column '$sortColumn'", 'eZUser::fetchLoggedInList' );
 374                          $sortColumn = false;
 375                      } break;
 376                  }
 377                  if ( $sortColumn )
 378                      $sortColumns[] = $sortColumn;
 379              }
 380              if ( count( $sortColumns ) > 0 )
 381                  $sortText = "ORDER BY " . implode( ', ', $sortColumns );
 382          }
 383          if ( $asObject )
 384          {
 385              $selectText = implode( ', ',  $selectArray );
 386              $sql = "SELECT $selectText
 387  FROM ezsession, ezuser
 388  WHERE ezsession.user_id != '" . EZ_USER_ANONYMOUS_ID . "' AND
 389        ezsession.expiration_time > '$time' AND
 390        ezuser.contentobject_id = ezsession.user_id
 391  $sortText";
 392              $rows = $db->arrayQuery( $sql, $parameters );
 393              $list = array();
 394              foreach ( $rows as $row )
 395              {
 396                  $list[] = new eZUser( $row );
 397              }
 398          }
 399          else
 400          {
 401              $selectText = implode( ', ',  $selectArray );
 402              $sql = "SELECT $selectText
 403  FROM ezsession, ezuser, ezcontentobject
 404  WHERE ezsession.user_id != '" . EZ_USER_ANONYMOUS_ID . "' AND
 405        ezsession.expiration_time > '$time' AND
 406        ezuser.contentobject_id = ezsession.user_id AND
 407        ezcontentobject.id = ezuser.contentobject_id
 408  $sortText";
 409              $rows = $db->arrayQuery( $sql, $parameters );
 410              $list = array();
 411              foreach ( $rows as $row )
 412              {
 413                  $list[$row['user_id']] = $row['name'];
 414              }
 415          }
 416          return $list;
 417      }
 418  
 419      /*!
 420       \return the number of logged in users in the system.
 421       \note The count will be cached for the current page if caching is allowed.
 422       \sa fetchAnonymousCount
 423      */
 424      function fetchLoggedInCount()
 425      {
 426          if ( isset( $GLOBALS['eZSiteBasics']['no-cache-adviced'] ) and
 427               !$GLOBALS['eZSiteBasics']['no-cache-adviced'] and
 428               isset( $GLOBALS['eZUserLoggedInCount'] ) )
 429              return $GLOBALS['eZUserLoggedInCount'];
 430          $db =& eZDB::instance();
 431          $time = mktime();
 432          $ini =& eZINI::instance();
 433          $activityTimeout = $ini->variable( 'Session', 'ActivityTimeout' );
 434          $sessionTimeout = $ini->variable( 'Session', 'SessionTimeout' );
 435          $time = $time + $sessionTimeout - $activityTimeout;
 436  
 437          $sql = "SELECT count( DISTINCT user_id ) as count
 438  FROM ezsession
 439  WHERE user_id != '" . EZ_USER_ANONYMOUS_ID . "' AND
 440        user_id > 0 AND
 441        expiration_time > '$time'";
 442          $rows = $db->arrayQuery( $sql );
 443          $count = ( count( $rows ) > 0 ) ? $rows[0]['count'] : 0;
 444          $GLOBALS['eZUserLoggedInCount'] = $count;
 445          return $count;
 446      }
 447  
 448      /*!
 449       \static
 450       \return the number of anonymous users in the system.
 451       \sa fetchLoggedInCount
 452      */
 453      function fetchAnonymousCount()
 454      {
 455          if ( isset( $GLOBALS['eZSiteBasics']['no-cache-adviced'] ) and
 456               !$GLOBALS['eZSiteBasics']['no-cache-adviced'] and
 457               isset( $GLOBALS['eZUserAnonymousCount'] ) )
 458              return $GLOBALS['eZUserAnonymousCount'];
 459          $db =& eZDB::instance();
 460          $time = mktime();
 461          $ini =& eZINI::instance();
 462          $activityTimeout = $ini->variable( 'Session', 'ActivityTimeout' );
 463          $sessionTimeout = $ini->variable( 'Session', 'SessionTimeout' );
 464          $time = $time + $sessionTimeout - $activityTimeout;
 465  
 466          $sql = "SELECT count( session_key ) as count
 467  FROM ezsession
 468  WHERE user_id = '" . EZ_USER_ANONYMOUS_ID . "' AND
 469        expiration_time > '$time'";
 470          $rows = $db->arrayQuery( $sql );
 471          $count = ( count( $rows ) > 0 ) ? $rows[0]['count'] : 0;
 472          $GLOBALS['eZUserAnonymousCount'] = $count;
 473          return $count;
 474      }
 475  
 476      /*!
 477       \static
 478       \return true if the user with ID $userID is currently logged into the system.
 479       \note The information will be cached for the current page if caching is allowed.
 480       \sa fetchLoggedInList
 481      */
 482      function isUserLoggedIn( $userID )
 483      {
 484          $userID = (int)$userID;
 485          if ( isset( $GLOBALS['eZSiteBasics']['no-cache-adviced'] ) and
 486               !$GLOBALS['eZSiteBasics']['no-cache-adviced'] and
 487               isset( $GLOBALS['eZUserLoggedInMap'][$userID] ) )
 488              return $GLOBALS['eZUserLoggedInMap'][$userID];
 489          $db =& eZDB::instance();
 490          $time = mktime();
 491          $ini =& eZINI::instance();
 492          $activityTimeout = $ini->variable( 'Session', 'ActivityTimeout' );
 493          $sessionTimeout = $ini->variable( 'Session', 'SessionTimeout' );
 494          $time = $time + $sessionTimeout - $activityTimeout;
 495  
 496          $sql = "SELECT DISTINCT user_id
 497  FROM ezsession
 498  WHERE user_id = '" . $userID . "' AND
 499        expiration_time > '$time'";
 500          $rows = $db->arrayQuery( $sql, array( 'limit' => 2 ) );
 501          $isLoggedIn = count( $rows ) > 0;
 502          $GLOBALS['eZUserLoggedInMap'][$userID] = $isLoggedIn;
 503          return $isLoggedIn;
 504      }
 505  
 506      /*!
 507       \static
 508       Removes any cached session information, this is:
 509       - logged in user count
 510       - anonymous user count
 511       - logged in user map
 512      */
 513      function clearSessionCache()
 514      {
 515          unset( $GLOBALS['eZUserLoggedInCount'] );
 516          unset( $GLOBALS['eZUserAnonymousCount'] );
 517          unset( $GLOBALS['eZUserLoggedInMap'] );
 518      }
 519  
 520      /*!
 521       \static
 522       Remove session data for user \a $userID.
 523      */
 524      function removeSessionData( $userID )
 525      {
 526          eZUser::clearSessionCache();
 527          $db =& eZDB::instance();
 528          $userID = (int)$userID;
 529          $db->query( 'DELETE FROM ezsession WHERE user_id = \'' . $userID . '\'' );
 530      }
 531  
 532      /*!
 533       Removes the user from the ezuser table.
 534       \note Will also remove any notifications and session related to the user.
 535      */
 536      function removeUser( $userID )
 537      {
 538          include_once ( 'kernel/classes/notification/handler/ezsubtree/ezsubtreenotificationrule.php' );
 539          include_once ( 'kernel/classes/datatypes/ezuser/ezusersetting.php' );
 540          include_once ( 'kernel/classes/datatypes/ezuser/ezuseraccountkey.php' );
 541          include_once ( 'kernel/classes/datatypes/ezuser/ezforgotpassword.php' );
 542  
 543          $user = eZUser::fetch( $userID );
 544          if ( $user )
 545          {
 546              eZUser::removeSessionData( $userID );
 547          }
 548  
 549          eZSubtreeNotificationRule::removeByUserID( $userID );
 550          eZUserSetting::remove( $userID );
 551          eZUserAccountKey::remove( $userID );
 552          eZForgotPassword::remove( $userID );
 553  
 554          eZPersistentObject::removeObject( eZUser::definition(),
 555                                            array( 'contentobject_id' => $userID ) );
 556      }
 557  
 558      /*!
 559       \return a list of valid and enabled users, the data returned is an array
 560               with ezcontentobject database data.
 561      */
 562      function fetchContentList()
 563      {
 564          $contentObjectStatus = EZ_CONTENT_OBJECT_STATUS_PUBLISHED;
 565          $query = "SELECT ezcontentobject.*
 566                    FROM ezuser, ezcontentobject, ezuser_setting
 567                    WHERE ezcontentobject.status = '$contentObjectStatus' AND
 568                          ezuser_setting.is_enabled = 1 AND
 569                          ezcontentobject.id = ezuser.contentobject_id AND
 570                          ezuser_setting.user_id = ezuser.contentobject_id";
 571          $db =& eZDB::instance();
 572          $rows = $db->arrayQuery( $query );
 573          return $rows;
 574      }
 575  
 576      /*!
 577       \static
 578       \return the default hash type which is specified in UserSettings/HashType in site.ini
 579      */
 580      function hashType()
 581      {
 582          include_once ( 'lib/ezutils/classes/ezini.php' );
 583          $ini =& eZINI::instance();
 584          $type = strtolower( $ini->variable( 'UserSettings', 'HashType' ) );
 585          if ( $type == 'md5_site' )
 586              return EZ_USER_PASSWORD_HASH_MD5_SITE;
 587          else if ( $type == 'md5_user' )
 588              return EZ_USER_PASSWORD_HASH_MD5_USER;
 589          else if ( $type == 'plaintext' )
 590              return EZ_USER_PASSWORD_HASH_PLAINTEXT;
 591          else
 592              return EZ_USER_PASSWORD_HASH_MD5_PASSWORD;
 593      }
 594  
 595      /*!
 596       \static
 597       \return the site name used in password hashing.
 598      */
 599      function site()
 600      {
 601          include_once ( 'lib/ezutils/classes/ezini.php' );
 602          $ini =& eZINI::instance();
 603          return $ini->variable( 'UserSettings', 'SiteName' );
 604      }
 605  
 606      /*!
 607       Fetches a builtin user and returns it, this helps avoid special cases where
 608       user is not logged in.
 609      */
 610      function &fetchBuiltin( $id )
 611      {
 612          if ( !in_array( $id, $GLOBALS['eZUserBuiltins'] ) )
 613              $id = EZ_USER_ANONYMOUS_ID;
 614          $builtinInstance =& $GLOBALS["eZUserBuilitinInstance-$id"];
 615          if ( get_class( $builtinInstance ) != 'ezuser' )
 616          {
 617              include_once ( 'lib/ezutils/classes/ezini.php' );
 618              $builtinInstance = eZUser::fetch( EZ_USER_ANONYMOUS_ID );
 619          }
 620          return $builtinInstance;
 621      }
 622  
 623  
 624      /*!
 625       \return the user id.
 626      */
 627      function id()
 628      {
 629          return $this->ContentObjectID;
 630      }
 631  
 632      /*!
 633       \return a bitfield which decides the authenticate methods.
 634      */
 635      function authenticationMatch()
 636      {
 637          include_once ( 'lib/ezutils/classes/ezini.php' );
 638          $ini =& eZINI::instance();
 639          $matchArray = $ini->variableArray( 'UserSettings', 'AuthenticateMatch' );
 640          $match = 0;
 641          foreach ( $matchArray as $matchItem )
 642          {
 643              switch ( $matchItem )
 644              {
 645                  case "login":
 646                  {
 647                      $match = ( $match | EZ_USER_AUTHENTICATE_LOGIN );
 648                  } break;
 649                  case "email":
 650                  {
 651                      $match = ( $match | EZ_USER_AUTHENTICATE_EMAIL );
 652                  } break;
 653              }
 654          }
 655          return $match;
 656      }
 657  
 658      /*!
 659       \return \c true if there can only be one instance of an email address on the site.
 660      */
 661      function requireUniqueEmail()
 662      {
 663          $ini =& eZINI::instance();
 664          return $ini->variable( 'UserSettings', 'RequireUniqueEmail' ) == 'true';
 665      }
 666  
 667      /*!
 668      \static
 669       Logs in the user if applied username and password is valid.
 670       \return The user object (eZContentObject) of the logged in user or \c false if it failed.
 671      */
 672      function &loginUser( $login, $password, $authenticationMatch = false )
 673      {
 674          include_once ( 'kernel/classes/ezcontentobject.php' );
 675  
 676          $http =& eZHTTPTool::instance();
 677          $db =& eZDB::instance();
 678  
 679          if ( $authenticationMatch === false )
 680              $authenticationMatch = eZUser::authenticationMatch();
 681  
 682          $loginEscaped = $db->escapeString( $login );
 683          $passwordEscaped = $db->escapeString( $password );
 684  
 685          $loginArray = array();
 686          if ( $authenticationMatch & EZ_USER_AUTHENTICATE_LOGIN )
 687              $loginArray[] = "login='$loginEscaped'";
 688          if ( $authenticationMatch & EZ_USER_AUTHENTICATE_EMAIL )
 689          {
 690              include_once ( 'lib/ezutils/classes/ezmail.php' );
 691              if ( eZMail::validate( $login ) )
 692              {
 693                  $loginArray[] = "email='$loginEscaped'";
 694              }
 695          }
 696          if ( count( $loginArray ) == 0 )
 697              $loginArray[] = "login='$loginEscaped'";
 698          $loginText = implode( ' OR ', $loginArray );
 699  
 700          $contentObjectStatus = EZ_CONTENT_OBJECT_STATUS_PUBLISHED;
 701  
 702          $ini =& eZINI::instance();
 703          $databaseImplementation = $ini->variable( 'DatabaseSettings', 'DatabaseImplementation' );
 704          // if mysql
 705          if ( $databaseImplementation == "ezmysql" )
 706          {
 707              $query = "SELECT contentobject_id, password_hash, password_hash_type, email, login
 708                        FROM ezuser, ezcontentobject
 709                        WHERE ( $loginText ) AND
 710                          ezcontentobject.status='$contentObjectStatus' AND
 711                          ezcontentobject.id=contentobject_id AND
 712                          ( ( password_hash_type!=4 ) OR
 713                            ( password_hash_type=4 AND ( $loginText ) AND password_hash=PASSWORD('$passwordEscaped') ) )";
 714          }
 715          else
 716          {
 717              $query = "SELECT contentobject_id, password_hash, password_hash_type, email, login
 718                        FROM ezuser, ezcontentobject
 719                        WHERE ( $loginText ) AND
 720                              ezcontentobject.status='$contentObjectStatus' AND
 721                              ezcontentobject.id=contentobject_id";
 722          }
 723  
 724          $users = $db->arrayQuery( $query );
 725          $exists = false;
 726          if ( $users !== false and count( $users ) >= 1 )
 727          {
 728              include_once ( 'lib/ezutils/classes/ezini.php' );
 729              $ini =& eZINI::instance();
 730              foreach ( array_keys( $users ) as $key )
 731              {
 732                  $userRow =& $users[$key];
 733                  $userID = $userRow['contentobject_id'];
 734                  $hashType = $userRow['password_hash_type'];
 735                  $hash = $userRow['password_hash'];
 736                  $exists = eZUser::authenticateHash( $userRow['login'], $password, eZUser::site(),
 737                                                      $hashType,
 738                                                      $hash );
 739  
 740                  // If hash type is MySql
 741                  if ( $hashType == EZ_USER_PASSWORD_HASH_MYSQL and $databaseImplementation == "ezmysql" )
 742                  {
 743                      $queryMysqlUser = "SELECT contentobject_id, password_hash, password_hash_type, email, login
 744                                FROM ezuser, ezcontentobject
 745                                WHERE ezcontentobject.status='$contentObjectStatus' AND
 746                                      password_hash_type=4 AND ( $loginText ) AND password_hash=PASSWORD('$passwordEscaped') ";
 747                      $mysqlUsers = $db->arrayQuery( $queryMysqlUser );
 748                      if ( count( $mysqlUsers ) >= 1 )
 749                          $exists = true;
 750  
 751                  }
 752  
 753                  eZDebugSetting::writeDebug( 'kernel-user', eZUser::createHash( $userRow['login'], $password, eZUser::site(),
 754                                                                                 $hashType ), "check hash" );
 755                  eZDebugSetting::writeDebug( 'kernel-user', $hash, "stored hash" );
 756                   // If current user has been disabled after a few failed login attempts.
 757                  $canLogin = eZUser::isEnabledAfterFailedLogin( $userID );
 758  
 759                  if ( $exists )
 760                  {
 761                      // We should store userID for warning message.
 762                      $GLOBALS['eZFailedLoginAttemptUserID'] = $userID;
 763  
 764                      include_once ( "kernel/classes/datatypes/ezuser/ezusersetting.php" );
 765                      $userSetting = eZUserSetting::fetch( $userID );
 766                      $isEnabled = $userSetting->attribute( "is_enabled" );
 767                      if ( $hashType != eZUser::hashType() and
 768                           strtolower( $ini->variable( 'UserSettings', 'UpdateHash' ) ) == 'true' )
 769                      {
 770                          $hashType = eZUser::hashType();
 771                          $hash = eZUser::createHash( $login, $password, eZUser::site(),
 772                                                      $hashType );
 773                          $db->query( "UPDATE ezuser SET password_hash='$hash', password_hash_type='$hashType' WHERE contentobject_id='$userID'" );
 774                      }
 775                      break;
 776                  }
 777              }
 778          }
 779          include_once ( "kernel/classes/ezaudit.php" );
 780          if ( $exists and $isEnabled and $canLogin )
 781          {
 782              $oldUserID = $contentObjectID = $http->sessionVariable( "eZUserLoggedInID" );
 783              eZDebugSetting::writeDebug( 'kernel-user', $userRow, 'user row' );
 784              $user = new eZUser( $userRow );
 785              eZDebugSetting::writeDebug( 'kernel-user', $user, 'user' );
 786              $userID = $user->attribute( 'contentobject_id' );
 787  
 788              // if audit is enabled logins should be looged
 789              eZAudit::writeAudit( 'user-login', array( 'User id' => $userID, 'User login' => $user->attribute( 'login' ) ) );
 790  
 791              eZUser::updateLastVisit( $userID );
 792              eZUser::setCurrentlyLoggedInUser( $user, $userID );
 793  
 794              // Reset number of failed login attempts
 795              eZUser::setFailedLoginAttempts( $userID, 0 );
 796  
 797              return $user;
 798          }
 799          else
 800          {
 801              // Failed login attempts should be looged
 802              $userIDAudit = isset( $userID ) ? $userID : 'null';
 803              eZAudit::writeAudit( 'user-failed-login', array( 'User id' => $userIDAudit, 'User login' => $loginEscaped,
 804                                                               'Comment' => 'Failed login attempt: eZUser::loginUser()' ) );
 805  
 806              // Increase number of failed login attempts.
 807              if ( isset( $userID ) )
 808                  eZUser::setFailedLoginAttempts( $userID );
 809  
 810              $user = false;
 811              return $user;
 812          }
 813      }
 814  
 815      /*!
 816       \static
 817       Checks if IP address of current user is in \a $ipList.
 818      */
 819      function isUserIPInList( $ipList )
 820      {
 821          $ipAddress = eZSys::serverVariable( 'REMOTE_ADDR', true );
 822          if ( $ipAddress )
 823          {
 824              $result = false;
 825              foreach( $ipList as $itemToMatch )
 826              {
 827                  if ( preg_match("/^(([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+))(\/([0-9]+)$|$)/", $itemToMatch, $matches ) )
 828                  {
 829                      if ( $matches[6] )
 830                      {
 831                          if ( eZDebug::isIPInNet( $ipAddress, $matches[1], $matches[7] ) )
 832                          {
 833                              $result = true;
 834                              break;
 835                          }
 836                      }
 837                      else
 838                      {
 839                          if ( $matches[1] == $ipAddress )
 840                          {
 841                              $result = true;
 842                              break;
 843                          }
 844                      }
 845                  }
 846              }
 847          }
 848          else
 849          {
 850              $result = (
 851                  in_array( 'commandline', $ipList ) &&
 852                  ( php_sapi_name() == 'cli' )
 853              );
 854          }
 855          return $result;
 856      }
 857  
 858      /*!
 859       \static
 860        Returns true if current user is trusted user.
 861      */
 862      function isTrusted()
 863      {
 864          $ini =& eZINI::instance();
 865  
 866          // Check if current user is trusted user.
 867          $trustedIPs = $ini->hasVariable( 'UserSettings', 'TrustedIPList' ) ? $ini->variable( 'UserSettings', 'TrustedIPList' ) : array();
 868  
 869          // Check if IP address of current user is in $trustedIPs array.
 870          $trustedUser = eZUser::isUserIPInList( $trustedIPs );
 871          if ( $trustedUser )
 872              return true;
 873  
 874          return false;
 875      }
 876  
 877      /*!
 878       \static
 879       Returns max number of failed login attempts.
 880      */
 881      function maxNumberOfFailedLogin()
 882      {
 883          $ini =& eZINI::instance();
 884  
 885          $maxNumberOfFailedLogin = $ini->hasVariable( 'UserSettings', 'MaxNumberOfFailedLogin' ) ? $ini->variable( 'UserSettings', 'MaxNumberOfFailedLogin' ) : '0';
 886          return $maxNumberOfFailedLogin;
 887      }
 888  
 889      /*
 890       \static
 891       Returns true if the user can login
 892       If user has number of failed login attempts more than eZUser::maxNumberOfFailedLogin()
 893       and user is not trusted
 894       the user will not be allowed to login.
 895      */
 896      function isEnabledAfterFailedLogin( $userID, $ignoreTrusted = false )
 897      {
 898          if ( !is_numeric( $userID ) )
 899              return true;
 900  
 901          $userObject = eZUser::fetch( $userID );
 902          if ( !$userObject )
 903              return true;
 904  
 905          $trustedUser = eZUser::isTrusted();
 906          // If user is trusted we should stop processing
 907          if ( $trustedUser and !$ignoreTrusted )
 908              return true;
 909  
 910          $maxNumberOfFailedLogin = eZUser::maxNumberOfFailedLogin();
 911  
 912          if ( $maxNumberOfFailedLogin == '0' )
 913              return true;
 914  
 915          $failedLoginAttempts = $userObject->failedLoginAttempts();
 916          if ( $failedLoginAttempts > $maxNumberOfFailedLogin )
 917              return false;
 918  
 919          return true;
 920      }
 921  
 922      /*!
 923       \protected
 924       Makes sure the user \a $user is set as the currently logged in user by
 925       updating the session and setting the necessary global variables.
 926  
 927       All login handlers should use this function to ensure that the process
 928       is executed properly.
 929      */
 930      function setCurrentlyLoggedInUser( &$user, $userID )
 931      {
 932          $http =& eZHTTPTool::instance();
 933  
 934          $GLOBALS["eZUserGlobalInstance_$userID"] =& $user;
 935          // Set/overwrite the global user, this will be accessed from
 936          // instance() when there is no ID passed to the function.
 937          $GLOBALS["eZUserGlobalInstance_"] =& $user;
 938          $http->setSessionVariable( 'eZUserLoggedInID', $userID );
 939          eZSessionRegenerate();
 940          $user->cleanup();
 941          eZSessionSetUserID( $userID );
 942      }
 943  
 944      /*!
 945       \virtual
 946       Used by login handler to clean up session variables
 947      */
 948      function sessionCleanup()
 949      {
 950      }
 951  
 952      /*!
 953       \static
 954       Cleans up any cache or session variables that are set.
 955       This at least called on login and logout but can be used other places
 956       where you must ensure that the cache user values are refetched.
 957       \param depricated
 958      */
 959      function cleanup()
 960      {
 961          $http =& eZHTTPTool::instance();
 962          $http->setSessionVariable( 'eZUserGroupsCache_Timestamp', false );
 963          $http->removeSessionVariable( 'eZUserGroupsCache' );
 964  
 965          $http->removeSessionVariable( 'eZUserInfoCache' );
 966  
 967          $http->removeSessionVariable( 'AccessArray' );
 968          $http->removeSessionVariable( 'CanInstantiateClassesCachedForUser' );
 969          $http->removeSessionVariable( 'CanInstantiateClassList' );
 970          $http->removeSessionVariable( 'ClassesCachedForUser' );
 971          $http->removeSessionVariable( 'eZRoleIDList' );
 972          $http->setSessionVariable( 'eZRoleIDList_Timestamp', 0 );
 973          $http->removeSessionVariable( 'eZRoleLimitationValueList' );
 974          $http->setSessionVariable( 'eZRoleLimitationValueList_Timestamp', 0 );
 975  
 976          // Note: This must be done more generic with an internal
 977          //       callback system.
 978          include_once ( 'kernel/classes/ezpreferences.php' );
 979          eZPreferences::sessionCleanup();
 980      }
 981  
 982      /*!
 983       \return logs in the current user object
 984      */
 985      function loginCurrent()
 986      {
 987          eZHTTPTool::setSessionVariable( 'eZUserLoggedInID', $this->ContentObjectID );
 988          eZSessionSetUserID( $this->ContentObjectID );
 989          $this->cleanup();
 990      }
 991  
 992      /*!
 993       \static
 994       Logs out the current user
 995      */
 996      function logoutCurrent()
 997      {
 998          $http =& eZHTTPTool::instance();
 999          $id = false;
1000          $GLOBALS["eZUserGlobalInstance_$id"] = false;
1001          $contentObjectID = $http->sessionVariable( "eZUserLoggedInID" );
1002          $newUserID = EZ_USER_ANONYMOUS_ID;
1003          $http->setSessionVariable( 'eZUserLoggedInID', $newUserID );
1004          eZSessionSetUserID( $newUserID );
1005          // Clear current basket if necessary
1006          $db =& eZDB::instance();
1007          $db->begin();
1008          include_once ( 'kernel/classes/ezbasket.php' );
1009          eZBasket::cleanupCurrentBasket();
1010          $db->commit();
1011  
1012          if ( $contentObjectID )
1013              eZUser::cleanup();
1014      }
1015  
1016      /*!
1017       Finds the user with the id \a $id and returns the unique instance of it.
1018       If the user instance is not created yet it tries to either fetch it from the
1019       database with eZUser::fetch(). If $id is false or the user was not found, the
1020       default user is returned. This is a site.ini setting under UserSettings:AnonymousUserID.
1021       The instance is then returned.
1022       If \a $id is false then the current user is fetched.
1023      */
1024      function &instance( $id = false )
1025      {
1026          $currentUser =& $GLOBALS["eZUserGlobalInstance_$id"];
1027          if ( get_class( $currentUser ) == 'ezuser' )
1028          {
1029              return $currentUser;
1030          }
1031  
1032          $http =& eZHTTPTool::instance();
1033          // If not specified get the current user
1034          if ( $id === false )
1035          {
1036              $id = $http->sessionVariable( 'eZUserLoggedInID' );
1037  
1038              if ( !is_numeric( $id ) )
1039              {
1040                  $id = EZ_USER_ANONYMOUS_ID;
1041                  $http->setSessionVariable( 'eZUserLoggedInID', $id );
1042                  eZSessionSetUserID( $id );
1043              }
1044          }
1045  
1046          $fetchFromDB = true;
1047  
1048          // Check session cache
1049          include_once ( 'lib/ezutils/classes/ezexpiryhandler.php' );
1050          $handler =& eZExpiryHandler::instance();
1051          $expiredTimeStamp = 0;
1052          if ( $handler->hasTimestamp( 'user-info-cache' ) )
1053              $expiredTimeStamp = $handler->timestamp( 'user-info-cache' );
1054  
1055          $userArrayTimestamp =& $http->sessionVariable( 'eZUserInfoCache_Timestamp' );
1056  
1057          if ( $userArrayTimestamp > $expiredTimeStamp )
1058          {
1059              $userInfo = array();
1060              if ( $http->hasSessionVariable( 'eZUserInfoCache' ) )
1061                  $userInfo =& $http->sessionVariable( 'eZUserInfoCache' );
1062  
1063              if ( isset( $userInfo[$id] ) )
1064              {
1065                  $userArray =& $userInfo[$id];
1066  
1067                  if ( is_numeric( $userArray['contentobject_id'] ) )
1068                  {
1069                      $currentUser = new eZUser( $userArray );
1070                      $fetchFromDB = false;
1071                  }
1072              }
1073          }
1074  
1075          if ( $fetchFromDB == true )
1076          {
1077              $currentUser = eZUser::fetch( $id );
1078  
1079              if ( $currentUser )
1080              {
1081                  $userInfo = array();
1082                  $userInfo[$id] = array( 'contentobject_id' => $currentUser->attribute( 'contentobject_id' ),
1083                                          'login' => $currentUser->attribute( 'login' ),
1084                                          'email' => $currentUser->attribute( 'email' ),
1085                                          'password_hash' => $currentUser->attribute( 'password_hash' ),
1086                                          'password_hash_type' => $currentUser->attribute( 'password_hash_type' )
1087                                          );
1088                  $http->setSessionVariable( 'eZUserInfoCache', $userInfo );
1089                  $http->setSessionVariable( 'eZUserInfoCache_Timestamp', mktime() );
1090              }
1091          }
1092  
1093          $ini =& eZINI::instance();
1094  
1095          // Check if the user is not logged in, and if a automatic single sign on plugin is enabled
1096          if ( is_object( $currentUser ) and !$currentUser->isLoggedIn() )
1097          {
1098              $ssoHandlerArray = $ini->variable( 'UserSettings', 'SingleSignOnHandlerArray' );
1099              if ( count( $ssoHandlerArray ) > 0 )
1100              {
1101                  $ssoUser = false;
1102                  foreach ( $ssoHandlerArray as $ssoHandler )
1103                  {
1104                      // Load handler
1105                      $handlerFile = 'kernel/classes/ssohandlers/ez' . strtolower( $ssoHandler ) . 'ssohandler.php';
1106                      if ( file_exists( $handlerFile ) )
1107                      {
1108                          include_once( $handlerFile );
1109                          $className = 'eZ' . $ssoHandler . 'SSOHandler';
1110                          $impl = new $className();
1111                          $ssoUser = $impl->handleSSOLogin();
1112                      }
1113                      else // check in extensions
1114                      {
1115                          include_once ( 'lib/ezutils/classes/ezextension.php' );
1116                          $ini =& eZINI::instance();
1117                          $extensionDirectories = $ini->variable( 'UserSettings', 'ExtensionDirectory' );
1118                          $directoryList = eZExtension::expandedPathList( $extensionDirectories, 'sso_handler' );
1119                          foreach( $directoryList as $directory )
1120                          {
1121                              $handlerFile = $directory . '/ez' . strtolower( $ssoHandler ) . 'ssohandler.php';
1122                              if ( file_exists( $handlerFile ) )
1123                              {
1124                                  include_once( $handlerFile );
1125                                  $className = 'eZ' . $ssoHandler . 'SSOHandler';
1126                                  $impl = new $className();
1127                                  $ssoUser = $impl->handleSSOLogin();
1128                              }
1129                          }
1130                      }
1131                  }
1132                  // If a user was found via SSO, then use it
1133                  if ( $ssoUser !== false )
1134                  {
1135                      $currentUser = $ssoUser;
1136  
1137                      $userInfo = array();
1138                      $userInfo[$id] = array( 'contentobject_id' => $currentUser->attribute( 'contentobject_id' ),
1139                                              'login' => $currentUser->attribute( 'login' ),
1140                                              'email' => $currentUser->attribute( 'email' ),
1141                                              'password_hash' => $currentUser->attribute( 'password_hash' ),
1142                                              'password_hash_type' => $currentUser->attribute( 'password_hash_type' )
1143                                              );
1144                      $http->setSessionVariable( 'eZUserInfoCache', $userInfo );
1145                      $http->setSessionVariable( 'eZUserInfoCache_Timestamp', mktime() );
1146                      $http->setSessionVariable( 'eZUserLoggedInID', $id );
1147                      eZSessionSetUserID( $currentUser->attribute( 'contentobject_id' ) );
1148  
1149                      eZUser::updateLastVisit( $currentUser->attribute( 'contentobject_id' ) );
1150                      eZUser::setCurrentlyLoggedInUser( $currentUser, $currentUser->attribute( 'contentobject_id' ) );
1151                      eZHTTPTool::redirect( eZSys::wwwDir() . eZSys::indexFile( false ) . eZSys::requestURI() );
1152  
1153                  }
1154              }
1155          }
1156  
1157          $anonymousUserID = $ini->variable( 'UserSettings', 'AnonymousUserID' );
1158          if ( $id <> $anonymousUserID )
1159          {
1160              $sessionInactivityTimeout = $ini->variable( 'Session', 'ActivityTimeout' );
1161              if ( !isset( $GLOBALS['eZSessionIdleTime'] ) )
1162              {
1163                  eZUser::updateLastVisit( $id );
1164              }
1165              else
1166              {
1167                  $sessionIdle = $GLOBALS['eZSessionIdleTime'];
1168                  if ( $sessionIdle > $sessionInactivityTimeout )
1169                  {
1170                      eZUser::updateLastVisit( $id );
1171                  }
1172              }
1173          }
1174  
1175          if ( !$currentUser )
1176          {
1177              $currentUser = eZUser::fetch( EZ_USER_ANONYMOUS_ID );
1178              eZDebug::writeWarning( 'User not found, returning anonymous' );
1179          }
1180  
1181          if ( !$currentUser )
1182          {
1183              $currentUser = new eZUser( array( 'id' => -1, 'login' => 'NoUser' ) );
1184  
1185              eZDebug::writeWarning( 'Anonymous user not found, returning NoUser' );
1186          }
1187  
1188          return $currentUser;
1189      }
1190  
1191      /*!
1192         Updates the user's last visit timestamp
1193      */
1194      function updateLastVisit( $userID )
1195      {
1196          if ( isset( $GLOBALS['eZUserUpdatedLastVisit'] ) )
1197              return;
1198          $db =& eZDB::instance();
1199          $userID = (int) $userID;
1200          $userVisitArray = $db->arrayQuery( "SELECT 1 FROM ezuservisit WHERE user_id=$userID" );
1201          $time = time();
1202  
1203          if ( count( $userVisitArray ) == 1 )
1204          {
1205              $db->query( "UPDATE ezuservisit SET last_visit_timestamp=current_visit_timestamp, current_visit_timestamp=$time WHERE user_id=$userID" );
1206          }
1207          else
1208          {
1209              $db->query( "INSERT INTO ezuservisit ( current_visit_timestamp, last_visit_timestamp, user_id ) VALUES ( $time, $time, $userID )" );
1210          }
1211          $GLOBALS['eZUserUpdatedLastVisit'] = true;
1212      }
1213  
1214      /*!
1215        Returns the last visit timestamp to the current user.
1216      */
1217      function &lastVisit()
1218      {
1219          $db =& eZDB::instance();
1220  
1221          $userVisitArray = $db->arrayQuery( "SELECT last_visit_timestamp FROM ezuservisit WHERE user_id=$this->ContentObjectID" );
1222          if ( count( $userVisitArray ) == 1 )
1223          {
1224              return $userVisitArray[0]['last_visit_timestamp'];
1225          }
1226          else
1227          {
1228              $retValue = time();
1229              return $retValue;
1230          }
1231      }
1232  
1233      /*!
1234         If \a $value is false will increase the user's number of failed login attempts
1235         otherwise failed_login_attempts will be updated by $value.
1236         \a $setByForce if true checking for trusting or max number of failed login attempts will be ignored.
1237      */
1238      function setFailedLoginAttempts( $userID, $value = false, $setByForce = false )
1239      {
1240          $trustedUser = eZUser::isTrusted();
1241          // If user is trusted we should stop processing
1242          if ( $trustedUser and !$setByForce )
1243              return true;
1244  
1245          $maxNumberOfFailedLogin = eZUser::maxNumberOfFailedLogin();
1246  
1247          if ( $maxNumberOfFailedLogin == '0' and !$setByForce )
1248              return true;
1249  
1250          $userID = (int) $userID;
1251          $userObject = eZUser::fetch( $userID );
1252          if ( !$userObject )
1253              return true;
1254  
1255          $isEnabled = $userObject->isEnabled();
1256          // If current user is disabled we should not continue
1257          if ( !$isEnabled and !$setByForce )
1258              return true;
1259  
1260          $db =& eZDB::instance();
1261          $db->begin();
1262  
1263          $userVisitArray = $db->arrayQuery( "SELECT 1 FROM ezuservisit WHERE user_id=$userID" );
1264          $time = time();
1265  
1266          if ( count( $userVisitArray ) == 1 )
1267          {
1268              if ( $value === false )
1269              {
1270                  $failedLoginAttempts = $userObject->failedLoginAttempts();
1271                  $failedLoginAttempts += 1;
1272              }
1273              else
1274                  $failedLoginAttempts = (int) $value;
1275  
1276              $db->query( "UPDATE ezuservisit SET failed_login_attempts=$failedLoginAttempts WHERE user_id=$userID" );
1277          }
1278          else
1279          {
1280              if ( $value === false )
1281              {
1282                  $failedLoginAttempts = 1;
1283              }
1284              else
1285                  $failedLoginAttempts = (int) $value;
1286  
1287              $db->query( "INSERT INTO ezuservisit ( failed_login_attempts, user_id ) VALUES ( $failedLoginAttempts, $userID )" );
1288          }
1289          $db->commit();
1290      }
1291  
1292      /*!
1293        Returns the current user's number of failed login attempts.
1294      */
1295      function failedLoginAttempts( $userID = false )
1296      {
1297          $db =& eZDB::instance();
1298  
1299          if ( $userID === false )
1300          {
1301              $contentObjectID = $this->attribute( 'contentobject_id' );
1302          }
1303          else
1304          {
1305              $contentObjectID = (int) $userID;
1306          }
1307  
1308          $userVisitArray = $db->arrayQuery( "SELECT failed_login_attempts FROM ezuservisit WHERE user_id=$contentObjectID" );
1309          if ( count( $userVisitArray ) == 1 )
1310          {
1311              return $userVisitArray[0]['failed_login_attempts'];
1312          }
1313          else
1314          {
1315              $retValue = 0;
1316              return $retValue;
1317          }
1318      }
1319  
1320      /*!
1321       \return \c true if the user is locked (is enabled after failed login) and can be logged on the site.
1322      */
1323      function &isLocked()
1324      {
1325          $userID = $this->attribute( 'contentobject_id' );
1326          $isNotLocked = eZUser::isEnabledAfterFailedLogin( $userID, true );
1327          $retValue = !$isNotLocked ? true : false;
1328          return $retValue;
1329      }
1330  
1331      /*!
1332       \return \c true if the user is enabled and can be used on the site.
1333      */
1334      function &isEnabled()
1335      {
1336          if ( $this == eZUser::currentUser() )
1337          {
1338              $retValue = true;
1339              return $retValue;
1340          }
1341  
1342          include_once ( "kernel/classes/datatypes/ezuser/ezusersetting.php" );
1343          $setting = eZUserSetting::fetch( $this->attribute( 'contentobject_id' ) );
1344          if ( $setting and !$setting->attribute( 'is_enabled' ) )
1345              $retValue = false;
1346          else
1347              $retValue = true;
1348          return $retValue;
1349      }
1350  
1351      /*!
1352       \return \c true if the user is the anonymous user.
1353      */
1354      function isAnonymous()
1355      {
1356          if ( $this->attribute( 'contentobject_id' ) != EZ_USER_ANONYMOUS_ID )
1357          {
1358              return false;
1359          }
1360          return true;
1361      }
1362  
1363      /*!
1364       \static
1365       Returns the currently logged in user.
1366      */
1367      function &currentUser()
1368      {
1369          $user =& eZUser::instance();
1370          return $user;
1371      }
1372  
1373      /*!
1374       \static
1375       Returns the ID of the currently logged in user.
1376      */
1377      function currentUserID()
1378      {
1379          $user =& eZUser::instance();
1380          if ( !$user )
1381              return 0;
1382          return $user->attribute( 'contentobject_id' );
1383      }
1384  
1385      /*!
1386       \static
1387       Creates a hash out of \a $user, \a $password and \a $site according to the type \a $type.
1388       \return true if the generated hash is equal to the supplied hash \a $hash.
1389      */
1390      function authenticateHash( $user, $password, $site, $type, $hash )
1391      {
1392          return eZUser::createHash( $user, $password, $site, $type ) == $hash;
1393      }
1394  
1395      /*!
1396       \static
1397       \return an array with characters which are allowed in password.
1398      */
1399      function passwordCharacterTable()
1400      {
1401          $table =& $GLOBALS['eZUserPasswordCharacterTable'];
1402          if ( isset( $table ) )
1403              return $table;
1404          $table = array_merge( range( 'a', 'z' ), range( 'A', 'Z' ), range( 0, 9 ) );
1405  
1406          $ini =& eZINI::instance();
1407          if ( $ini->variable( 'UserSettings', 'UseSpecialCharacters' ) == 'true' )
1408          {
1409              $specialCharacters = '!#%&{[]}+?;:*';
1410              $table = array_merge( $table, preg_split( '//', $specialCharacters, -1, PREG_SPLIT_NO_EMPTY ) );
1411          }
1412          // Remove some characters that are too similar visually
1413          $table = array_diff( $table, array( 'I', 'l', 'o', 'O', '0' ) );
1414          $tableTmp = $table;
1415          $table = array();
1416          foreach ( $tableTmp as $item )
1417          {
1418              $table[] = $item;
1419          }
1420          return $table;
1421      }
1422  
1423      /*!
1424       Checks if the supplied content object is a user object ( contains ezuser datatype )
1425  
1426       \param ContentObject
1427  
1428       \return true or false
1429      */
1430      function isUserObject( $contentObject )
1431      {
1432          if ( !$contentObject )
1433          {
1434              return false;
1435          }
1436  
1437          eZDataType::loadAndRegisterType( 'ezuser' );
1438  
1439          $contentClass = $contentObject->attribute( 'content_class' );
1440          $classAttributeList = $contentClass->fetchAttributes();
1441          foreach( $classAttributeList as $classAttribute )
1442          {
1443              if ( $classAttribute->attribute( 'data_type_string' ) == EZ_DATATYPESTRING_USER )
1444                  return true;
1445          }
1446  
1447          return false;
1448      }
1449  
1450      /*!
1451       \static
1452       Creates a password with number of characters equal to \a $passwordLength and returns it.
1453       If you want pass a value in \a $seed it will be used as basis for the password, if not
1454       it will use the current time value as seed.
1455       \note If \a $passwordLength exceeds 16 it will need to generate new seed for the remaining
1456             characters.
1457      */
1458      function createPassword( $passwordLength, $seed = false )
1459      {
1460          $chars = 0;
1461          $password = '';
1462          if ( $passwordLength < 1 )
1463              $passwordLength = 1;
1464          $decimal = 0;
1465          while ( $chars < $passwordLength )
1466          {
1467              if ( $seed == false )
1468                  $seed = mktime() . ":" . mt_rand();
1469              $text = md5( $seed );
1470              $characterTable = eZUser::passwordCharacterTable();
1471              $tableCount = count( $characterTable );
1472              for ( $i = 0; ( $chars < $passwordLength ) and $i < 32; ++$chars, $i += 2 )
1473              {
1474                  $decimal += hexdec( substr( $text, $i, 2 ) );
1475                  $index = ( $decimal % $tableCount );
1476                  $character = $characterTable[$index];
1477                  $password .= $character;
1478              }
1479              $seed = false;
1480          }
1481          return $password;
1482      }
1483  
1484      /*!
1485       \static
1486       Will create a hash of the given string. This is used to store the passwords in the database.
1487      */
1488      function createHash( $user, $password, $site, $type )
1489      {
1490          $str = '';
1491  //         eZDebugSetting::writeDebug( 'kernel-user', "'$user' '$password' '$site'", "ezuser($type)" );
1492          if( $type == EZ_USER_PASSWORD_HASH_MD5_USER )
1493          {
1494              $str = md5( "$user\n$password" );
1495          }
1496          else if ( $type == EZ_USER_PASSWORD_HASH_MD5_SITE )
1497          {
1498              $str = md5( "$user\n$password\n$site" );
1499          }
1500          else if ( $type == EZ_USER_PASSWORD_HASH_MYSQL )
1501          {
1502              // Do some MySQL stuff here
1503          }
1504          else if ( $type == EZ_USER_PASSWORD_HASH_PLAINTEXT )
1505          {
1506              $str = $password;
1507          }
1508          else // EZ_USER_PASSWORD_HASH_MD5_PASSWORD
1509          {
1510              $str = md5( $password );
1511          }
1512          eZDebugSetting::writeDebug( 'kernel-user', $str, "ezuser($type)" );
1513          return $str;
1514      }
1515  
1516      /*!
1517       Check if user has got access to the specified module and function
1518  
1519       \param module name
1520       \param funtion name
1521  
1522       \return Array containg result.
1523               Array elements : 'accessWord', yes - access allowed
1524                                              no - access denied
1525                                              limited - access array describing access included
1526                                'policies', array containing the policy limitations
1527                                'accessList', array describing missing access rights
1528      */
1529      function hasAccessTo( $module, $function = false )
1530      {
1531          $accessArray = null;
1532          $ini =& eZINI::instance();
1533          $userID = $this->attribute( 'contentobject_id' );
1534          if ( $ini->variable( 'RoleSettings', 'EnableCaching' ) == 'true' )
1535          {
1536              $http =& eZHTTPTool::instance();
1537              if ( $http->hasSessionVariable( 'AccessArray' ) )
1538              {
1539                  $expiredTimeStamp = 0;
1540                  include_once ( 'lib/ezutils/classes/ezexpiryhandler.php' );
1541                  $handler =& eZExpiryHandler::instance();
1542                  if ( $handler->hasTimestamp( 'user-access-cache' ) )
1543                  {
1544                      $expiredTimeStamp = $handler->timestamp( 'user-access-cache' );
1545                  }
1546                  $userAccessTimestamp = $http->sessionVariable( 'AccessArrayTimestamp' );
1547                  if ( $userAccessTimestamp > $expiredTimeStamp )
1548                  {
1549                      $accessArray = $http->sessionVariable( 'AccessArray' );
1550                  }
1551              }
1552          }
1553  
1554          if ( $accessArray == null )
1555          {
1556              /* Figure out when the last update was done */
1557              $expiredTimestamp = 0;
1558              include_once ( 'lib/ezutils/classes/ezexpiryhandler.php' );
1559              $handler =& eZExpiryHandler::instance();
1560              if ( $handler->hasTimestamp( 'user-access-cache' ) )
1561              {
1562                  $expiredTimestamp = $handler->timestamp( 'user-access-cache' );
1563              }
1564  
1565              $cacheFilePath = eZUser::getCacheFilename( $userID );
1566  
1567              // VS-DBFILE
1568  
1569              if ( $cacheFilePath !== false )
1570              {
1571                  require_once ( 'kernel/classes/ezclusterfilehandler.php' );
1572                  $cacheFile = eZClusterFileHandler::instance( $cacheFilePath );
1573  
1574                  if( $cacheFile->exists() && $cacheFile->mtime() > $expiredTimestamp )
1575                  {
1576                      $cacheFile->fetch();
1577                      $accessArray = include( $cacheFilePath );
1578                      $cacheFile->deleteLocal();
1579                  }
1580              }
1581          }
1582  
1583          if ( $accessArray == null )
1584          {
1585              include_once ( 'kernel/classes/ezrole.php' );
1586              $accessArray =& eZRole::accessArrayByUserID( array_merge( $this->groups(), array( $userID ) ) );
1587  
1588              if ( !isset( $cacheFilePath ) )
1589                  $cacheFilePath = eZUser::getCacheFilename( $userID );
1590  
1591              if ( $cacheFilePath )
1592              {
1593                  // VS-DBFILE
1594  
1595                  if ( !isset( $cacheFile ) )
1596                  {
1597                      require_once ( 'kernel/classes/ezclusterfilehandler.php' );
1598                      $cacheFile = eZClusterFileHandler::instance( $cacheFilePath );
1599                  }
1600  
1601                  $fileContents = "<?php\n\treturn ". var_export( $accessArray, true ) . ";\n?>\n";
1602                  $cacheFile->storeContents( $fileContents, 'user-info-cache', 'php' );
1603              }
1604          }
1605  
1606          $access = 'no';
1607          $functionArray = array();
1608          if ( isset( $accessArray['*'] ) )
1609          {
1610              if ( isset( $accessArray['*']['*'] ) )
1611              {
1612                  $functionArray = $accessArray['*']['*'];
1613              }
1614              if ( $function === false )
1615              {
1616                  foreach( array_keys( $accessArray['*'] ) as $key )
1617                  {
1618                      $functionArray = array_merge_recursive( $functionArray, $accessArray['*'][$key] );
1619                  }
1620              }
1621              elseif ( isset( $accessArray['*'][$function] ) )
1622              {
1623                  $functionArray = array_merge_recursive( $functionArray, $accessArray['*'][$function] );
1624              }
1625  
1626          }
1627          if ( isset( $accessArray[$module] ) )
1628          {
1629              if ( isset( $accessArray[$module]['*'] ) )
1630              {
1631                  $functionArray = array_merge_recursive( $functionArray, $accessArray[$module]['*'] );
1632              }
1633              if ( $function === false )
1634              {
1635                  foreach( array_keys( $accessArray[$module] ) as $key )
1636                  {
1637                      if ( $functionArray !== $accessArray[$module][$key] )
1638                          $functionArray = array_merge_recursive( $functionArray, $accessArray[$module][$key] );
1639                  }
1640              }
1641              elseif ( isset( $accessArray[$module][$function] ) )
1642              {
1643                  if ( $functionArray !== $accessArray[$module][$function] )
1644                      $functionArray = array_merge_recursive( $functionArray, $accessArray[$module][$function] );
1645              }
1646          }
1647  
1648          if ( !$functionArray )
1649          {
1650              $accessList = array(
1651                  'FunctionRequired' => array ( 'Module' => $module,
1652                                                'Function' => $function,
1653                                                'ClassID' => '',
1654                                                'MainNodeID' => '' ),
1655                  'PolicyList' => array() );
1656              return array( 'accessWord' => 'no',
1657                            'accessList' => $accessList );
1658          }
1659  
1660          if ( isset( $functionArray['*'] ) && ( $functionArray['*'] == '*' || in_array( '*',  $functionArray['*'] ) ) )
1661          {
1662              return array( 'accessWord' => 'yes' );
1663          }
1664  
1665          return array( 'accessWord' => 'limited', 'policies' => $functionArray );
1666      }
1667  
1668      /*!
1669       \return an array of roles which the user is assigned to
1670      */
1671      function &roles()
1672      {
1673          include_once ( 'kernel/classes/ezrole.php' );
1674          $groups = $this->attribute( 'groups' );
1675          $groups[] = $this->attribute( 'contentobject_id' );
1676          $roles = eZRole::fetchByUser( $groups );
1677          return $roles;
1678      }
1679  
1680      /*!
1681       \return an array of role ids which the user is assigned to
1682      */
1683      function &roleIDList()
1684      {
1685          $http =& eZHTTPTool::instance();
1686  
1687          // If the user object is not the currently logged in user we cannot use the session cache
1688          $useCache = ( $this->ContentObjectID == $http->sessionVariable( 'eZUserLoggedInID' ) );
1689  
1690          if ( $useCache )
1691          {
1692              include_once ( 'lib/ezutils/classes/ezexpiryhandler.php' );
1693              $handler =& eZExpiryHandler::instance();
1694              $expiredTimeStamp = 0;
1695              $roleIDListTimestamp =& $http->sessionVariable( 'eZRoleIDList_Timestamp' );
1696              if ( $handler->hasTimestamp( 'user-info-cache' ) )
1697                  $expiredTimeStamp = $handler->timestamp( 'user-info-cache' );
1698  
1699              if ( $roleIDListTimestamp > $expiredTimeStamp )
1700              {
1701                  if ( $http->hasSessionVariable( 'eZRoleIDList' ) )
1702                  {
1703                      return $http->sessionVariable( 'eZRoleIDList' );
1704                  }
1705              }
1706          }
1707  
1708          include_once ( 'kernel/classes/ezrole.php' );
1709          $groups = $this->attribute( 'groups' );
1710          $groups[] = $this->attribute( 'contentobject_id' );
1711          $roleList = eZRole::fetchIDListByUser( $groups );
1712  
1713          if ( $useCache )
1714          {
1715              $http->setSessionVariable( 'eZRoleIDList', $roleList );
1716              $http->setSessionVariable( 'eZRoleIDList_Timestamp', mktime() );
1717          }
1718          return $roleList;
1719      }
1720  
1721      /*!
1722       \return an array of limited assignments
1723      */
1724      function limitList()
1725      {
1726          $groups = $this->groups( false );
1727          $groups[] = $this->attribute( 'contentobject_id' );
1728          $groups = implode( ', ', $groups );
1729  
1730          $db =& eZDB::instance();
1731  
1732          $limitationsArray = $db->arrayQuery( "SELECT DISTINCT limit_identifier, limit_value
1733                                                FROM ezuser_role
1734                                                WHERE contentobject_id IN ( $groups )" );
1735  
1736          return $limitationsArray;
1737      }
1738  
1739      /*!
1740       \return an array of values of limited assignments
1741      */
1742      function &limitValueList()
1743      {
1744          $limitValueList = array();
1745  
1746          $http =& eZHTTPTool::instance();
1747  
1748          // If the user object is not the currently logged in user we cannot use the session cache
1749          $useCache = ( $this->ContentObjectID == $http->sessionVariable( 'eZUserLoggedInID' ) );
1750  
1751          if ( $useCache )
1752          {
1753              include_once ( 'lib/ezutils/classes/ezexpiryhandler.php' );
1754              $handler =& eZExpiryHandler::instance();
1755              $expiredTimeStamp = 0;
1756              $roleLimitationValueListTimeStamp =& $http->sessionVariable( 'eZRoleLimitationValueList_Timestamp' );
1757              if ( $handler->hasTimestamp( 'user-info-cache' ) )
1758                  $expiredTimeStamp = $handler->timestamp( 'user-info-cache' );
1759  
1760              if ( $roleLimitationValueListTimeStamp > $expiredTimeStamp && $http->hasSessionVariable( 'eZRoleLimitationValueList' ) )
1761              {
1762                  return $http->sessionVariable( 'eZRoleLimitationValueList' );
1763              }
1764          }
1765  
1766          $limitList = $this->limitList();
1767          foreach ( $limitList as $limit )
1768              $limitValueList[] = $limit['limit_value'];
1769  
1770          if ( $useCache )
1771          {
1772              $http->setSessionVariable( 'eZRoleLimitationValueList', $limitValueList );
1773              $http->setSessionVariable( 'eZRoleLimitationValueList_Timestamp', mktime() );
1774          }
1775  
1776          return $limitValueList;
1777      }
1778  
1779      function &contentObject()
1780      {
1781          if ( isset( $this->ContentObjectID ) and $this->ContentObjectID )
1782          {
1783              include_once ( 'kernel/classes/ezcontentobject.php' );
1784              $object =& eZContentObject::fetch( $this->ContentObjectID );
1785          }
1786          else
1787              $object = null;
1788          return $object;
1789      }
1790  
1791      /*!
1792       Returns true if it's a real user which is logged in. False if the user
1793       is the default user or the fallback buildtin user.
1794      */
1795      function &isLoggedIn()
1796      {
1797          $return = true;
1798          if ( $this->ContentObjectID == EZ_USER_ANONYMOUS_ID or
1799               $this->ContentObjectID == -1 )
1800          {
1801              $return = false;
1802          }
1803          return $return;
1804      }
1805  
1806      /*!
1807       \return an array of id's with all the groups the user belongs to.
1808      */
1809      function &groups( $asObject = false, $userID = false )
1810      {
1811          $db =& eZDB::instance();
1812          $http =& eZHTTPTool::instance();
1813  
1814          if ( $asObject == true )
1815          {
1816              $this->Groups = array();
1817              if ( !isset( $this->GroupsAsObjects ) )
1818              {
1819                  include_once ( 'kernel/classes/ezcontentobject.php' );
1820  
1821                  if ( $userID )
1822                  {
1823                      $contentobjectID = (int) $userID;
1824                  }
1825                  else
1826                  {
1827                      $contentobjectID = $this->attribute( 'contentobject_id' );
1828                  }
1829                  $userGroups = $db->arrayQuery( "SELECT d.*, c.path_string
1830                                                  FROM ezcontentobject_tree  b,
1831                                                       ezcontentobject_tree  c,
1832                                                       ezcontentobject d
1833                                                  WHERE b.contentobject_id='$contentobjectID' AND
1834                                                        b.parent_node_id = c.node_id AND
1835                                                        d.id = c.contentobject_id
1836                                                  ORDER BY c.contentobject_id  ");
1837                  $userGroupArray = array();
1838                  $pathArray = array();
1839                  foreach ( $userGroups as $group )
1840                  {
1841                      $pathItems = explode( '/', $group["path_string"] );
1842                      array_pop( $pathItems );
1843                      array_pop( $pathItems );
1844                      foreach ( $pathItems as $pathItem )
1845                      {
1846                          if ( $pathItem != '' && $pathItem > 1 )
1847                              $pathArray[] = $pathItem;
1848                      }
1849                      $userGroupArray[] = new eZContentObject( $group );
1850                  }
1851                  $pathArray = array_unique( $pathArray );
1852  
1853                  if ( count( $pathArray ) != 0 )
1854                  {
1855                      $extraGroups = $db->arrayQuery( "SELECT d.*
1856                                                  FROM ezcontentobject_tree  c,
1857                                                       ezcontentobject d
1858                                                  WHERE c.node_id in ( " . implode( ', ', $pathArray ) . " ) AND
1859                                                        d.id = c.contentobject_id
1860                                                  ORDER BY c.contentobject_id  ");
1861                      foreach ( $extraGroups as $group )
1862                      {
1863                          $userGroupArray[] = new eZContentObject( $group );
1864                      }
1865                  }
1866  
1867                  $this->GroupsAsObjects =& $userGroupArray;
1868              }
1869              return $this->GroupsAsObjects;
1870          }
1871          else
1872          {
1873              if ( !isset( $this->Groups ) )
1874              {
1875                  // If the user object is not the currently logged in user we cannot use the session cache
1876                  $useCache = ( $this->ContentObjectID == $http->sessionVariable( 'eZUserLoggedInID' ) );
1877  
1878                  if ( $useCache )
1879                  {
1880                      $userGroupTimestamp =& $http->sessionVariable( 'eZUserGroupsCache_Timestamp' );
1881  
1882                      include_once ( 'lib/ezutils/classes/ezexpiryhandler.php' );
1883                      $handler =& eZExpiryHandler::instance();
1884                      $expiredTimeStamp = 0;
1885                      if ( $handler->hasTimestamp( 'user-info-cache' ) )
1886                          $expiredTimeStamp = $handler->timestamp( 'user-info-cache' );
1887  
1888                      if ( $userGroupTimestamp > $expiredTimeStamp )
1889                      {
1890                          if ( $http->hasSessionVariable( 'eZUserGroupsCache' ) )
1891                          {
1892                              $this->Groups =& $http->sessionVariable( 'eZUserGroupsCache' );
1893                              return $this->Groups;
1894                          }
1895                      }
1896                  }
1897  
1898                  if ( $userID )
1899                  {
1900                      $contentobjectID = $userID;
1901                  }
1902                  else
1903                  {
1904                      $contentobjectID = $this->attribute( 'contentobject_id' );
1905                  }
1906  
1907                  $userGroups = false;
1908  
1909                  $userGroups = $db->arrayQuery( "SELECT  c.contentobject_id as id,c.path_string
1910                                                  FROM ezcontentobject_tree  b,
1911                                                       ezcontentobject_tree  c
1912                                                  WHERE b.contentobject_id='$contentobjectID' AND
1913                                                        b.parent_node_id = c.node_id
1914                                                  ORDER BY c.contentobject_id  ");
1915                  $userGroupArray = array();
1916  
1917                  $pathArray = array();
1918                  foreach ( $userGroups as $group )
1919                  {
1920                      $pathItems = explode( '/', $group["path_string"] );
1921                      array_pop( $pathItems );
1922                      array_pop( $pathItems );
1923                      foreach ( $pathItems as $pathItem )
1924                      {
1925                          if ( $pathItem != '' && $pathItem > 1 )
1926                              $pathArray[] = $pathItem;
1927                      }
1928                      $userGroupArray[] = $group['id'];
1929                  }
1930  
1931                  if ( count( $pathArray ) > 0 )
1932                  {
1933                      $pathArray = array_unique ($pathArray);
1934                      $extraGroups = $db->arrayQuery( "SELECT c.contentobject_id as id
1935                                                      FROM ezcontentobject_tree  c,
1936                                                           ezcontentobject d
1937                                                      WHERE c.node_id in ( " . implode( ', ', $pathArray ) . " ) AND
1938                                                            d.id = c.contentobject_id
1939                                                      ORDER BY c.contentobject_id  ");
1940                      foreach ( $extraGroups as $group )
1941                      {
1942                          $userGroupArray[] = $group['id'];
1943                      }
1944                  }
1945  
1946                  if ( $useCache )
1947                  {
1948                      $http->setSessionVariable( 'eZUserGroupsCache', $userGroupArray );
1949                      $http->setSessionVariable( 'eZUserGroupsCache_Timestamp', mktime() );
1950                  }
1951                  $this->Groups =& $userGroupArray;
1952              }
1953              return $this->Groups;
1954          }
1955      }
1956  
1957      /*!
1958       Checks if user is logged in, if not and the site requires user login for access
1959       a module redirect is returned.
1960  
1961       \return null, user login not required.
1962      */
1963      function checkUser( &$siteBasics, &$uri )
1964      {
1965          $ini =& eZINI::instance();
1966          $http =& eZHTTPTool::instance();
1967          $check = array( "module" => "user",
1968                          "function" => "login" );
1969          if ( $http->hasSessionVariable( "eZUserLoggedInID" ) and
1970               $http->sessionVariable( "eZUserLoggedInID" ) != '' and
1971               $http->sessionVariable( "eZUserLoggedInID" ) != $ini->variable( 'UserSettings', 'AnonymousUserID' ) )
1972          {
1973              include_once ( "kernel/classes/datatypes/ezuser/ezuser.php" );
1974              $currentUser =& eZUser::currentUser();
1975              if ( !$currentUser->isEnabled() )
1976              {
1977                  eZUser::logoutCurrent();
1978                  $currentUser =& eZUser::currentUser();
1979              }
1980              else
1981              {
1982                  return null;
1983              }
1984          }
1985  
1986          $moduleName = $uri->element();
1987          $viewName = $uri->element( 1 );
1988          $anonymousAccessList = $ini->variable( "SiteAccessSettings", "AnonymousAccessList" );
1989          foreach ( $anonymousAccessList as $anonymousAccess )
1990          {
1991              $elements = explode( '/', $anonymousAccess );
1992              if ( count( $elements ) == 1 )
1993              {
1994                  if ( $moduleName == $elements[0] )
1995                  {
1996                      return null;
1997                  }
1998              }
1999              else
2000              {
2001                  if ( $moduleName == $elements[0] and
2002                       $viewName == $elements[1] )
2003                  {
2004                      return null;
2005                  }
2006              }
2007          }
2008  
2009          return $check;
2010      }
2011  
2012      /*!
2013       Funtion performed before user login info is collected.
2014       It's optional to implement this function in new login handler.
2015  
2016       \return @see eZUserLoginHandler::checkUser()
2017      */
2018      function preCollectUserInfo()
2019      {
2020          return array( 'module' => 'user', 'function' => 'login' );
2021      }
2022  
2023      /*!
2024       Function performed after user login info has been collected.
2025       Store login data as array:
2026       array( 'login' => <username>,
2027              'password' = <password> )
2028       to session variable EZ_LOGIN_HANDLER_USER_INFO for automatic processing of login data.
2029  
2030       \return @see eZUserLoginHandler::checkUser()
2031       */
2032      function postCollectUserInfo()
2033      {
2034          return true;
2035      }
2036  
2037      /*!
2038       Check if login handler require special login URI
2039  
2040       \return Special login uri. If false, use system standard login uri.
2041      */
2042      function loginURI()
2043      {
2044          return false;
2045      }
2046  
2047      /*!
2048       Check if login handler require forced login at user check.
2049  
2050       \return true if force login on user check, false if not.
2051      */
2052      function forceLogin()
2053      {
2054          return false;
2055      }
2056  
2057      /*!
2058       Creates the cache path if it doesn't exist, and returns the cache
2059       directory. The $id parameter is used to create multi-level directory names
2060       \static
2061       \return filename of the cachefile
2062      */
2063      function getCacheDir( $id = 0 )
2064      {
2065          $sys =& eZSys::instance();
2066          $dir = $sys->cacheDirectory() . '/user-info' . eZDir::createMultilevelPath( $id, 2 );
2067  
2068          if ( !is_dir( $dir ) )
2069          {
2070              eZDir::mkdir( $dir, false, true );
2071              // var_dump("MADE DIRECTORY $dir");
2072          }
2073          return $dir;
2074      }
2075  
2076      function cleanupCache()
2077      {
2078          include_once ( 'lib/ezutils/classes/ezexpiryhandler.php' );
2079          $handler =& eZExpiryHandler::instance();
2080          $handler->setTimestamp( 'user-access-cache', time() );
2081          $handler->setTimestamp( 'user-info-cache', mktime() );
2082          $handler->store();
2083      }
2084  
2085      /*!
2086       Returns the filename for a cache file with user information
2087       \static
2088       \return filename of the cachefile, or false when the user should not be cached
2089      */
2090      function getCacheFilename( $id )
2091      {
2092          $ini =& eZINI::instance();
2093          $cacheUserPolicies = $ini->variable( 'RoleSettings', 'UserPolicyCache' );
2094          if ( $cacheUserPolicies == 'enabled' )
2095          {
2096              // var_dump("BUILD FILENAME FOR $id");
2097              return eZUser::getCacheDir( $id ). '/user-'. $id . '.cache.php';
2098          }
2099          else if ( $cacheUserPolicies != 'disabled' )
2100          {
2101              $cachableIDs = split( ',', $cacheUserPolicies );
2102              if ( in_array( $id, $cachableIDs ) )
2103              {
2104                  // var_dump("BUILD FILENAME FOR $id");
2105                  return eZUser::getCacheDir( $id ). '/user-'. $id . '.cache.php';
2106              }
2107          }
2108          // var_dump("NO CACHE FOR $id");
2109          return false;
2110      }
2111  
2112      function fetchUserClassList( $asObject = false, $fields = false )
2113      {
2114          // Get names of user classes
2115          if ( !$asObject and
2116               is_array( $fields ) and
2117               count( $fields ) > 0 )
2118          {
2119              $fieldsFilter = '';
2120              $i = 0;
2121              foreach ( $fields as $fieldName )
2122              {
2123                  if ( $i > 0 )
2124                      $fieldsFilter .= ', ';
2125                  $fieldsFilter .= 'ezcontentclass.' . $fieldName;
2126                  $i++;
2127              }
2128          }
2129          else
2130          {
2131              $fieldsFilter = 'ezcontentclass.*';
2132          }
2133          $db =& eZDB::instance();
2134          $userClasses = $db->arrayQuery( "SELECT $fieldsFilter
2135                                           FROM ezcontentclass, ezcontentclass_attribute
2136                                           WHERE ezcontentclass.id = ezcontentclass_attribute.contentclass_id AND
2137                                                 ezcontentclass.version = " . EZ_CLASS_VERSION_STATUS_DEFINED ." AND
2138                                                 ezcontentclass_attribute.version = 0 AND
2139                                                 ezcontentclass_attribute.data_type_string = 'ezuser'" );
2140  
2141          return eZPersistentObject::handleRows( $userClasses, "eZContentClass", $asObject );
2142      }
2143  
2144      function fetchUserClassNames()
2145      {
2146          $userClassNames = array();
2147          $userClasses = eZUser::fetchUserClassList( false, array( 'identifier' ) );
2148          foreach ( $userClasses as $class )
2149          {
2150              $userClassNames[] = $class[ 'identifier' ];
2151          }
2152          return $userClassNames;
2153      }
2154  
2155      function fetchUserGroupClassNames()
2156      {
2157          // Get names of user classes
2158          $userClassNames = array();
2159          $userClasses = eZUser::fetchUserClassList( false, array( 'identifier' ) );
2160          foreach ( $userClasses as $class )
2161          {
2162              $userClassNames[] = $class[ 'identifier' ];
2163          }
2164  
2165          // Get names of all allowed content-classes for the Users subtree
2166          $contentIni =& eZINI::instance( "content.ini" );
2167          $userGroupClassNames = array();
2168          if ( $contentIni->hasVariable( 'ClassGroupIDs', 'Users' ) and
2169               is_numeric( $usersClassGroupID = $contentIni->variable( 'ClassGroupIDs', 'Users' ) ) and
2170               count( $usersClassList = eZContentClassClassGroup::fetchClassList( EZ_CLASS_VERSION_STATUS_DEFINED, $usersClassGroupID ) ) > 0 )
2171          {
2172              foreach ( $usersClassList as $userClass )
2173              {
2174                  $userGroupClassNames[] = $userClass->attribute( 'identifier' );
2175              }
2176          }
2177  
2178          // Get names of user-group classes
2179          $groupClassNames = array_diff( $userGroupClassNames, $userClassNames );
2180          return $groupClassNames;
2181      }
2182  
2183      /// \privatesection
2184      var $Login;
2185      var $Email;
2186      var $PasswordHash;
2187      var $PasswordHashType;
2188      var $Groups;
2189      var $OriginalPassword;
2190      var $OriginalPasswordConfirm;
2191  }
2192  
2193  ?>


Généré le : Sat Feb 24 10:30:04 2007 par Balluche grâce à PHPXref 0.7