[ Index ]

PHP Cross Reference of ACL Module

title

Body

[close]

/models/ -> AclObject.php (source)

   1  <?php
   2  
   3  /*

   4   * To change this template, choose Tools | Templates

   5   * and open the template in the editor.

   6   */
   7  
   8  /**

   9   * AclObject Interface File

  10   * This is the base interfasce for AclObjects defining the most basic operations 

  11   *

  12   * @author dispy <dispyfree@googlemail.com>

  13   * @package acl.base

  14   * @license LGPLv2

  15   */
  16  abstract class AclObject extends CActiveRecord{
  17      
  18       /**

  19        * Joins the given object (now called: group)

  20        * @param mixed $obj

  21        * @return boolean

  22        */
  23       abstract public function join($obj);
  24       
  25       /**

  26        * Callback being executed before every join

  27        * Usage of this method allows common behavior for several strategies 

  28        * with respect to object transformations and a secure environment

  29        * @param AclObject $obj 

  30        */
  31       protected function beforeJoin(&$obj){
  32           $this->assureSafety($obj);
  33       }
  34       
  35       /**

  36        * Callback being executed before every leave

  37        * Usage of this method allows common behavior for several strategies 

  38        * with respect to object transformations and a secure environment

  39        * @param AclObject $obj 

  40        */
  41       protected function beforeLeave(&$obj){
  42           $this->assureSafety($obj);
  43       }
  44       
  45       /**

  46        * Callback being executed before every childhood-check

  47        * Usage of this method allows common behavior for several strategies 

  48        * with respect to object transformations and a secure environment

  49        * @param AclObject $obj 

  50        */
  51       protected function beforeIs(&$obj){
  52           $this->assureSafety($obj);
  53       }
  54       
  55       /**

  56        * Leaves the given group

  57        * @param mixed $obj

  58        * @return boolean

  59        */
  60       abstract public function leave($obj);
  61       
  62       /**

  63        * Checks whether this object is somehow a child of the given object

  64        * @param mixed $obj

  65        * @return boolean

  66        */
  67       abstract public function is($obj);
  68       
  69       /**

  70       * Returns all of the AclNodes of this object which do not have a parent yet

  71       *

  72       * @access public

  73       * @param  AclObject object

  74       * @return array[AclNode]

  75       */
  76      abstract public function getFreeNodes();
  77      
  78      /**

  79       * Fetches and returns positions of all nodes of this object 

  80       * which denote them

  81       * In this case, it's really easy because we've done that anyway :)

  82       * @return array[string] 

  83       */
  84      abstract public function fetchComprisedPositions();
  85      
  86      /**

  87       * Builds a single SQL-statement comprising all given positions and their parents

  88       * This SQL-statement will match all those rows being located above the given positions including themselves

  89       * @param array $positions All positions to include in our statement

  90       * @param string $type aco/aro

  91       * @param string $table the table comprising the map between objects and permissions

  92       * @return string the finished SQL-statement

  93       */
  94      abstract public function addPositionCheck($positions, $type, $table = 't');
  95      
  96      /**

  97        * Creates a new node of this collection

  98        * This new node will be a children of the given AclNode 

  99        * @param AclNode $parent  parent of the new node, if NULL, it has no parent

 100        * @return AclNode the new node

 101        */
 102       abstract protected function createNode($parent = NULL);
 103       
 104       /**

 105       * Returns all of the (direct) AclNodes whose parent AclNode is a node of this 

 106       * AclObject. 

 107       * 

 108       * If the $child AclObject is specified, only nodes having the given AclObject

 109       * as owner will be returned.

 110       *

 111       * @access public

 112       * @param  AclObject child

 113       * @param  Integer

 114       * @return array[AclNode]

 115       */
 116      abstract public function getDirectChildNodes(AclObject $child = NULL);
 117      
 118      /**

 119       * Returns all of the (direct) AclNodes whose child AclNode is a node of this 

 120       * AclObject. 

 121       * 

 122       * If the $child AclObject is specified, only nodes having the given AclObject

 123       * as owner will be returned.

 124       *

 125       * @access public

 126       * @param  AclObject child

 127       * @param  Integer

 128       * @return array[AclNode]

 129       */
 130      abstract public function getDirectParentNodes(AclObject $parent = NULL);
 131      
 132      /**

 133       * Fetches all child-objects and returns them in an array

 134       * @return array[AclObject] the child-objects 

 135       */
 136      public function getChildObjects(){
 137          $childNodes = $this->getDirectChildNodes(NULL);
 138          $objects = array();
 139          
 140          $type = Util::getDataBaseType($this);
 141          foreach($childNodes as $node){
 142              $obj = $node->{$type};
 143              //Why this way? Several nodes may be associated to the same object

 144              $objects[$obj->id] = $obj;
 145          }
 146          
 147          return $objects;
 148      }
 149      
 150      /**

 151       * Fetches all parent-objects and returns them in an array

 152       * @return array[AclObject] the parent-objects 

 153       */
 154      public function getParentObjects(){
 155          $parentNodes = $this->getDirectParentNodes(NULL);
 156          $objects = array();
 157          
 158          $type = Util::getDataBaseType($this);
 159          foreach($parentNodes as $node){
 160              $obj = $node->{$type};
 161              //Why this way? Several nodes may be associated to the same object

 162              $objects[$obj->id] = $obj;
 163          }
 164          
 165          return $objects;
 166      }
 167       
 168      /**

 169       * Just a convenient wrapper to loadObjects

 170       * @param mixed $identifier The Identifier denoting the associated row in the ACL-system. 

 171       * @param string $model - the class-Name of the expected object (Aro or Aco)

 172       */
 173      public static function loadObjectStatic($identifier, $model){
 174          return self::loadObjectsStatic($identifier, $model, true);
 175      }
 176      
 177       /**

 178       * Just a convenient wrapper to loadObjects

 179       * @param mixed $identifier The Identifier denoting the associated row in the ACL-system. 

 180       * @param string $model - the class-Name of the expected object (Aro or Aco)

 181       */
 182      public function loadObject($identifier, $model = NULL){
 183          if(!$model)
 184              $model = get_class($this);
 185          return self::loadObjectsStatic($identifier, $model, true);
 186      }
 187      
 188      /**

 189       * Just a convenient wrapper to loadObjects

 190       * @param mixed $identifier The Identifier denoting the associated row in the ACL-system. 

 191       * @param string $model - the class-Name of the expected object (Aro or Aco)

 192       */
 193      public function loadObjects($identifier, $model = NULL, $onlyFirst = true){
 194          if(!$model)
 195              $model = get_class($this);
 196          return self::loadObjects($identifier, $model, $onlyFirst);
 197      }
 198      
 199      
 200      /**

 201       * This method is used to load Objects (either Aco or Aro) using convenient identifiers. 

 202       * 

 203       * @param mixed $identifier The Identifier denoting the associated row in the ACL-system. 

 204       * Supported identifiers:

 205       * 1)   Array syntax: array('model' => 'MyModel', 'foreign_key' => myId)

 206       *          e.g.: model => User, foreign_key => the ID of the user (presumably AUTO_INCREMENT INT from the user row)

 207       * 2)   alias syntax: "MyAlias"

 208       *          e.g.: "Visitors", "Admins", "Authors"

 209       * 3)   direct syntax: pass your object derived from CActiveRecord directly

 210       *          e.g.: loadObject(User::model()->find(....))

 211       *          This will be automatically resolved to the first syntax. 

 212       *          Please be aware that auto-creation of associated ACL-objects only happens if the strict-mode is disabled 

 213       *          So if you pass a new object which has no corresponding aco/aro-row, this will lead to an exception if the strict-mode is

 214       *          enabled.

 215       * 4)   Of course, you can pass the finished object directly. As many methods call this method without check, this is natural.

 216       * 

 217       * @param string $model - the class-Name of the expected object (Aro or Aco)

 218       * @param boolean $onlyFirst    Determines whether to fetch only the first matching object, or all of them. 

 219       * @return type 

 220       */
 221      public static function loadObjectsStatic($identifier, $model = NULL, $onlyFirst = true){
 222  
 223          //There are several ways to define the object in question

 224          if(is_string($model)){
 225              $class = Strategy::getClass($model);
 226              $model = new $class();
 227          }
 228          
 229          if($onlyFirst)
 230                  $method = 'find';
 231              else
 232                  $method = 'findAll';
 233              
 234          //An alias is being used

 235          if(is_string($identifier)){
 236              
 237              $objects = $model->$method('alias=:alias', array('alias' => $identifier));
 238              
 239              if(!$objects){
 240                  if(Strategy::get('strictMode')){
 241                      throw new Exception('Unknown alias for ACL-ObjectCollection');
 242                  }
 243                  else{
 244                      $obj = new $model;
 245                      $obj->alias   = $identifier;
 246                      $obj->save();
 247                      
 248                      $objects = $onlyFirst ? $obj : array($obj);
 249                 }
 250              }
 251              
 252          }
 253          
 254          //The object is searched by its model

 255          elseif(
 256                  is_array($identifier) && 
 257                  (isset($identifier['foreign_key']) && isset($identifier['model']))
 258              ){
 259                  
 260              $objects = $model->$method('foreign_key = :foreign_key AND model = :model', 
 261                      array(':foreign_key' => $identifier['foreign_key'], ':model' => $identifier['model']));
 262              if(!$objects){
 263                  if(Strategy::get('strictMode')){
 264                      throw new Exception('Unknown foreign key and/or model for ACL-ObjectCollection');
 265                  }
 266                  else{
 267                      $obj = new $model;
 268                      $obj->foreign_key   = $identifier['foreign_key'];
 269                      $obj->model         = $identifier['model'];
 270                      $obj->save();
 271                      
 272                      $objects = $onlyFirst ? $obj : array($obj);
 273                  }
 274                  
 275              }
 276          }
 277          
 278          //The object is passed directly - do not do anything

 279          elseif(is_a($identifier, "AclObject") || (
 280                  is_a($identifier, "HiddenClass") 
 281                  && is_subclass_of($identifier->pretends(), "Aclobject")
 282          )){
 283              $objects = $identifier;
 284          }
 285          elseif(is_a($identifier, "CActiveRecord")){
 286              return self::loadObjectsStatic( array('model' => get_class($identifier), 'foreign_key' => $identifier->id), $model, $onlyFirst);
 287          }
 288          else{
 289              throw new Exception('Unknown ACL-Object specification');
 290          }
 291          
 292          return $objects;   
 293      }
 294      
 295      /**

 296       * This method returns all AclNodes being associated with this

 297       *

 298       * @access public

 299       * @param  AclObject object

 300       * @return array[AclNode]

 301       */
 302      public function getNodes(){
 303          $class = Util::getNodeNameOfObject($this);
 304          
 305          return $class::model()->findAll('collection_id = :id', array(':id' => $this->id));
 306      }
 307      
 308      /**

 309        * Processes post-saving tasks 

 310        */
 311       public function afterSave(){
 312           parent::afterSave();
 313           
 314           //If we're new here, we also need a new node for the permissions :)

 315           if($this->isNewRecord){
 316               $this->createNode();
 317           }
 318       }
 319       
 320       /**

 321        * Loads the associated object, if possible, and returns it

 322        * @return mixed   NULL or a child of CActiveREcord

 323        */
 324       public function getAssociatedObject(){
 325           if(is_subclass_of($this->model, "CActiveRecord")){
 326               $model = $this->model;
 327               return $model::model()->findByPk($this->foreign_key);
 328           }
 329           return NULL;
 330       }
 331       
 332       /**

 333        * Reassures that all passed objects have been saved

 334        */
 335       protected function assureSaved(){
 336           $args = func_get_args();
 337           foreach($args as $arg){
 338               if(is_object($arg) && is_a($arg, "CActiveRecord") && $arg->getIsNewRecord()){
 339                       if(!$arg->save())
 340                           throw new RuntimeException('Unable to save object');
 341               }
 342           }
 343       }
 344       
 345       /**

 346        * Assures that:

 347        * - the object is of a proper class

 348        * - all involved objects have been saved before they interact

 349        * @param AclObject $obj 

 350        */
 351       protected function assureSafety(&$obj){
 352           $obj = $this->loadObject($obj);
 353           //Assure that objects have been saved

 354           $this->assureSaved($this, $obj);
 355       }
 356      
 357       
 358       
 359  }
 360  
 361  ?>


Generated: Sun Jul 1 19:24:45 2012 Cross-referenced by PHPXref 0.7.1