eZ Publish  [4.0]
ezpolicy.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Definition of eZPolicy class
00004 //
00005 // Created on: <16-Aug-2002 16:34:41 sp>
00006 //
00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00008 // SOFTWARE NAME: eZ Publish
00009 // SOFTWARE RELEASE: 4.0.x
00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
00011 // SOFTWARE LICENSE: GNU General Public License v2.0
00012 // NOTICE: >
00013 //   This program is free software; you can redistribute it and/or
00014 //   modify it under the terms of version 2.0  of the GNU General
00015 //   Public License as published by the Free Software Foundation.
00016 //
00017 //   This program is distributed in the hope that it will be useful,
00018 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 //   GNU General Public License for more details.
00021 //
00022 //   You should have received a copy of version 2.0 of the GNU General
00023 //   Public License along with this program; if not, write to the Free
00024 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00025 //   MA 02110-1301, USA.
00026 //
00027 //
00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00029 //
00030 
00031 /*! \file ezpolicy.php
00032 */
00033 
00034 /*!
00035   \class eZPolicy ezpolicy.php
00036   \ingroup eZRole
00037   \brief Defines a policy in the permission system
00038 
00039 */
00040 
00041 //include_once( 'kernel/classes/ezpolicylimitation.php' );
00042 //include_once( 'kernel/classes/ezrole.php' );
00043 
00044 class eZPolicy extends eZPersistentObject
00045 {
00046     /*!
00047      Constructor
00048     */
00049     function eZPolicy( $row )
00050     {
00051           $this->eZPersistentObject( $row );
00052           $this->NodeID = 0;
00053     }
00054 
00055     static function definition()
00056     {
00057         return array( 'fields' => array( 'id' => array( 'name' => 'ID',
00058                                                         'datatype' => 'integer',
00059                                                         'default' => 0,
00060                                                         'required' => true ),
00061                                          'role_id' => array( 'name' => 'RoleID',
00062                                                              'datatype' => 'integer',
00063                                                              'default' => 0,
00064                                                              'required' => true,
00065                                                              'foreign_class' => 'eZRole',
00066                                                              'foreign_attribute' => 'id',
00067                                                              'multiplicity' => '1..*' ),
00068                                          'module_name' => array( 'name' => 'ModuleName',
00069                                                                  'datatype' => 'string',
00070                                                                  'default' => '',
00071                                                                  'required' => true ),
00072                                          'function_name' => array( 'name' => 'FunctionName',
00073                                                                    'datatype' => 'string',
00074                                                                    'default' => '',
00075                                                                    'required' => true ) ),
00076                       'keys' => array( 'id' ),
00077                       'function_attributes' => array( 'limitations' => 'limitationList',
00078                                                       'role' => 'role',
00079                                                       'limit_identifier' => 'limitIdentifier',
00080                                                       'limit_value' => 'limitValue',
00081                                                       'user_role_id' => 'userRoleID' ),
00082                       'increment_key' => 'id',
00083                       'sort' => array( 'id' => 'asc' ),
00084                       'class_name' => 'eZPolicy',
00085                       'name' => 'ezpolicy' );
00086     }
00087 
00088     function limitIdentifier()
00089     {
00090         return $this->LimitIdentifier;
00091     }
00092 
00093     function limitValue()
00094     {
00095         return $this->LimitValue;
00096     }
00097 
00098     function userRoleID()
00099     {
00100         return $this->UserRoleID;
00101     }
00102 
00103     /*!
00104      \reimp
00105     */
00106     function setAttribute( $attr, $val )
00107     {
00108         switch( $attr )
00109         {
00110             case 'limit_identifier':
00111             {
00112                 if ( !$this->LimitIdentifier )
00113                 {
00114                     $this->LimitIdentifier = $val;
00115                 }
00116             } break;
00117 
00118             case 'limit_value':
00119             {
00120                 if ( !$this->LimitValue )
00121                 {
00122                     $this->LimitValue = $val;
00123                 }
00124             } break;
00125             case 'user_role_id':
00126             {
00127                 if ( !$this->UserRoleID )
00128                 {
00129                     $this->UserRoleID = $val;
00130                 }
00131             } break;
00132 
00133             default:
00134             {
00135                 eZPersistentObject::setAttribute( $attr, $val );
00136             } break;
00137         }
00138     }
00139 
00140     /*!
00141      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00142      the calls within a db transaction; thus within db->begin and db->commit.
00143      */
00144     static function createNew( $roleID , $params = array() )
00145     {
00146         $policy = new eZPolicy( array( 'id' => null ) );
00147         $policy->setAttribute( 'role_id', $roleID );
00148         if ( array_key_exists( 'ModuleName', $params ))
00149         {
00150             $policy->setAttribute( 'module_name', $params['ModuleName'] );
00151         }
00152         if ( array_key_exists( 'FunctionName', $params ))
00153         {
00154             $policy->setAttribute( 'function_name', $params['FunctionName'] );
00155         }
00156         $policy->store();
00157 
00158         return $policy;
00159     }
00160 
00161     /*!
00162      \static
00163      Creates a new policy assigned to the role identified by ID \a $roleID  and returns it.
00164      \note The policy is not stored.
00165      \param $module Which module to give access to or \c true to give access to all modules.
00166      \param $function Which function to give access to or \c true to give access to all functions.
00167      \param $limitations An associative array with limitations and their values, use an empty array for no limitations.
00168     */
00169     static function create( $roleID, $module, $function )
00170     {
00171         if ( $module === true )
00172             $module = '*';
00173         if ( $function === true )
00174             $function = '*';
00175         $row = array( 'id' => null,
00176                       'role_id' => $roleID,
00177                       'module_name' => $module,
00178                       'function_name' => $function );
00179         $policy = new eZPolicy( $row );
00180         return $policy;
00181     }
00182 
00183     /*!
00184      Appends a new policy limitation to the current policy and returns it.
00185      \note The limitation and it's values will be stored to the database before returning.
00186      \param $identifier The identifier for the limitation, e.g. \c 'Class'
00187      \param $values Array of values to store for limitation.
00188      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00189      the calls within a db transaction; thus within db->begin and db->commit.
00190     */
00191     function appendLimitation( $identifier, $values )
00192     {
00193         //include_once( 'kernel/classes/ezpolicylimitation.php' );
00194         //include_once( 'kernel/classes/ezpolicylimitationvalue.php' );
00195         $limitation = eZPolicyLimitation::create( $this->ID, $identifier );
00196 
00197         $db = eZDB::instance();
00198         $db->begin();
00199         $limitation->store();
00200         $limitationID = $limitation->attribute( 'id' );
00201         $limitations = array();
00202         foreach ( $values as $value )
00203         {
00204             $limitationValue = eZPolicyLimitationValue::create( $limitationID, $value );
00205             $limitationValue->store();
00206             if ( isset( $limitation->Values ) )
00207             {
00208                 $limitation->Values[] = $limitationValue;
00209             }
00210         }
00211         $db->commit();
00212 
00213         if ( isset( $this->Limitations ) )
00214         {
00215             $this->Limitations[] = $limitation;
00216         }
00217         return $limitation;
00218     }
00219 
00220     /*!
00221      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00222      the calls within a db transaction; thus within db->begin and db->commit.
00223      */
00224     function copy( $roleID )
00225     {
00226         $params = array();
00227         $params['ModuleName'] = $this->attribute( 'module_name' );
00228         $params['FunctionName'] = $this->attribute( 'function_name' );
00229 
00230         $db = eZDB::instance();
00231         $db->begin();
00232         $newPolicy = eZPolicy::createNew( $roleID, $params  );
00233         foreach ( $this->attribute( 'limitations' ) as $limitation )
00234         {
00235             $limitation->copy( $newPolicy->attribute( 'id' ) );
00236         }
00237         $db->commit();
00238     }
00239 
00240     /*!
00241      \sa removeThis
00242     */
00243     static function removeByID( $id )
00244     {
00245         $policy = eZPolicy::fetch( $id );
00246         if ( !$policy )
00247         {
00248             return null;
00249         }
00250         $policy->removeThis();
00251     }
00252 
00253     /*!
00254      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00255      the calls within a db transaction; thus within db->begin and db->commit.
00256      */
00257     function removeThis( $id = false )
00258     {
00259         //include_once( 'lib/ezdb/classes/ezdb.php' );
00260         $db = eZDB::instance();
00261         $db->begin();
00262         foreach ( $this->attribute( 'limitations' ) as $limitation )
00263         {
00264             $limitation->removeThis();
00265         }
00266         $db->query( "DELETE FROM ezpolicy
00267                      WHERE id='" . $db->escapeString( $this->attribute( 'id' ) ) . "'" );
00268         $db->commit();
00269     }
00270 
00271     /*!
00272      Generate access array from this policy.
00273 
00274      return access array
00275     */
00276     function accessArray( $ignoreLimitIdentifier = false )
00277     {
00278         $limitations = $this->limitationList( true, $ignoreLimitIdentifier );
00279         if ( $this->Disabled === true )
00280         {
00281             return array();
00282         }
00283 
00284         if ( !$limitations )
00285         {
00286             return array( $this->attribute( 'module_name' ) => array ( $this->attribute( 'function_name' ) => array( '*' => '*' ) ) );
00287         }
00288 
00289         $limitArray = array();
00290 
00291         foreach( array_keys( $limitations ) as $limitKey )
00292         {
00293             $limitArray = array_merge_recursive( $limitArray, $limitations[$limitKey]->limitArray() );
00294         }
00295 
00296         $policyName = 'p_' . $this->attribute( 'id' ) . ( isset($this->UserRoleID) ? ( '_' . $this->UserRoleID ) : '' );
00297 
00298         return array( $this->attribute( 'module_name' ) => array ( $this->attribute( 'function_name' ) => array( $policyName => $limitArray ) ) );
00299     }
00300 
00301     /*!
00302      Fetch limitation array()
00303 
00304      \param use limitation cache, true by default.
00305     */
00306     function limitationList( $useCache = true, $ignoreLimitIdentifier = false )
00307     {
00308         if ( !isset( $this->Limitations ) || !$useCache )
00309         {
00310 
00311             $limitations = eZPersistentObject::fetchObjectList( eZPolicyLimitation::definition(),
00312                                                                  null, array( 'policy_id' => $this->attribute( 'id') ), null, null,
00313                                                                  true );
00314 
00315             eZDebugSetting::writeDebug( 'kernel-policy-limitation', $limitations, "before policy limitations " . $this->ID );
00316             eZDebugSetting::writeDebug( 'kernel-policy-limitation', $this, "policy itself before before limitations check"  );
00317 
00318             if ( $ignoreLimitIdentifier === false  && isset( $this->LimitIdentifier ) && $this->LimitIdentifier )
00319             {
00320                 $limitIdentifier =  $this->attribute( 'limit_identifier' );
00321                 $limitValue = $this->attribute( 'limit_value' );
00322                 $limitationTouched = false;
00323                 $checkEmptyLimitation = true;
00324                 foreach ( $limitations as $limitation )
00325                 {
00326                     if ( $limitation->attribute( 'identifier' ) == $limitIdentifier )
00327                     {
00328                         if ( $limitIdentifier == 'Subtree' )
00329                         {
00330                             $limitationTouched = true;
00331 
00332                             $values = $limitation->attribute( 'values' );
00333 
00334                             foreach ( $values as $limitationValue )
00335                             {
00336                                 $value = $limitationValue->attribute( 'value' );
00337                                 if ( strpos( $value, $limitValue ) === 0 )
00338                                 {
00339                                     $checkEmptyLimitation = false;
00340                                     eZDebugSetting::writeDebug( 'kernel-policy-limitation', $value,
00341                                                                 "Limitationvalue has been left in the limitation [limitValue=$limitValue]" );
00342                                 }
00343                                 else if ( strpos( $limitValue, $value ) === 0 )
00344                                 {
00345                                     $checkEmptyLimitation = false;
00346                                     $limitationValue->setAttribute( 'value', $limitValue );
00347                                     eZDebugSetting::writeDebug(  'kernel-policy-limitation',
00348                                                                  $value,
00349                                                                  "Limitationvalue has been exchanged to the value from cond assignment [limitValue=$limitValue]" );
00350                                 }
00351                                 else
00352                                 {
00353                                     eZDebugSetting::writeDebug(  'kernel-policy-limitation',  $value,
00354                                                                  "Limitationvalue has been removed from limitation [limitValue=$limitValue]" );
00355                                     //exlude limitation value from limitation..
00356                                     unset( $limitationValue );
00357                                 }
00358                             }
00359                             if ( $checkEmptyLimitation )
00360                             {
00361                                 eZDebugSetting::writeDebug( 'kernel-policy-limitation', $this, 'The policy has been disabled' );
00362                                 $this->Disabled = true;
00363                                 $this->Limitations = array();
00364                                 return $this->Limitations;
00365                             }
00366                         }
00367                     }
00368                 }
00369 
00370                 if ( !$limitationTouched )
00371                 {
00372                     $policyLimitation = new eZPolicyLimitation( array ( 'id' => -1,
00373                                                                         'policy_id' => $this->attribute( 'id' ),
00374                                                                         'identifier' => $this->attribute( 'limit_identifier' ) ) );
00375                     $policyLimitation->setAttribute( 'limit_value', $this->attribute( 'limit_value' ) );
00376 
00377                     $limitations[] = $policyLimitation;
00378                 }
00379             }
00380             eZDebugSetting::writeDebug( 'kernel-policy-limitation', $limitations, "policy limitations " . $this->ID );
00381 
00382             $this->Limitations = $limitations;
00383         }
00384         return $this->Limitations;
00385     }
00386 
00387     function role()
00388     {
00389         if ( $this->ID )
00390         {
00391             return eZPersistentObject::fetchObject( eZRole::definition(),
00392                                                     null, array( 'id' => $this->RoleID ), true );
00393         }
00394 
00395         return false;
00396     }
00397 
00398     static function fetch( $policyID )
00399     {
00400         return eZPersistentObject::fetchObject( eZPolicy::definition(),
00401                                                 null, array('id' => $policyID ), true);
00402     }
00403 
00404     // Used for assign based limitations.
00405     public $Disabled = false;
00406     public $LimitValue;
00407     public $LimitIdentifier;
00408     public $UserRoleID;
00409 
00410 }
00411 
00412 ?>