[ Index ]

PHP Cross Reference of ACL Module

title

Body

[close]

/components/strategies/nestedSet/pathMaterialization/models/ -> PmAclObject.php (source)

   1  <?php
   2  
   3  /**

   4   * The specialization of the general AclObject.

   5   * This class implements the path-materialization-specific/optimized position- 

   6   * and rights-operations

   7   *

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

   9   * @license LGPLv2

  10   * @package acl.strategies.nestedSet.pathMaterialiization

  11   */
  12  class PmAclObject extends AclObject{
  13      
  14      
  15      /**

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

  17       *

  18       * @access public

  19       * @param  AclObject object

  20       * @return array[AclNode]

  21       */
  22      public function getFreeNodes(){
  23          $class = Util::getNodeNameOfObject($this);
  24       
  25          return $class::findAll('collection_id = :id AND path =""', array(':id' => $this->id));
  26      }
  27      
  28      
  29       /**

  30        * Fetches all Paths of the nodes of this object 

  31        * @return array[string] the paths of the nodes 

  32        */
  33       public function getPaths(){
  34          $nodeClass = Util::getNodeNameOfObject($this);
  35          $nodes = $nodeClass::model()->findAll('collection_id = :id', array(':id' => $this->id));
  36          $paths = array();
  37          
  38          foreach($nodes as $node){
  39              $paths[] = PmPathManager::appendToPath($node->path, $node->id);
  40          }
  41          unset($nodes);
  42          
  43          return $paths;
  44       }
  45       
  46      /**

  47       * Builds (string) condition which matches all destinations, which are children

  48       * of source

  49       * field should be either aco or aro

  50       * @param array $source array('field' => '', 'table' => '')

  51       * @param array $destination array('field' => '', 'table' => '')

  52       * @param boolean   $disableInheritance if set to true, no inheritance will be used, that means no node will acquire the rights of it's parent

  53       */ 
  54      public static function buildTreeQueryCondition($source, $destination, $disableInheritance = false){
  55          $source['field'] = 'path';
  56          $sourcePrefix = $source['table'].'.'.$source['field'];
  57          
  58          $pathExpression = 'CONCAT("^", '.$sourcePrefix.', '
  59                      .$source['table'].'.id, '
  60                  .' "'.PmPathManager::getSeparator().'")';
  61          
  62          $method = !$disableInheritance ? 'REGEXP' : '=';
  63          
  64          return $destination['table'].'.'.$destination['field'].'_path'
  65                  .' '.$method.' '.$pathExpression;
  66      }
  67       
  68       /**

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

  70       * which denote them

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

  72       * @return array[string] 

  73       */
  74      public function fetchComprisedPositions(){
  75          return $this->getPaths();
  76      }
  77      
  78       /**

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

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

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

  82       * @param string $type aco/aro

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

  84       * @return string the finished SQL-statement

  85       */
  86      public function addPositionCheck($positions, $type, $table = 't'){
  87          //Positions == paths in this case

  88          $preparedConditions = ' ( ';
  89          
  90          foreach($positions as $key =>$position){
  91              if($key > 0)
  92                  $preparedConditions .= ' OR ';
  93              $preparedConditions .= sprintf( " ( '%s' REGEXP CONCAT('^', %s.%s_path ))",
  94                      $position, $table, $type);
  95          }
  96          
  97          $preparedConditions .= ' ) ';
  98          
  99          return $preparedConditions;
 100      }
 101       
 102       /**

 103        * Creates a new node of this collection

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

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

 106        * @return AclNode the new node

 107        */
 108       protected function createNode($parent = NULL){
 109           
 110           $class = Util::getNodeNameOfObject($this);
 111            //First, create the node itself and place it in the tree

 112          $node = new $class();
 113          $node->collection_id = $this->id;
 114          
 115          if($parent !== NULL)
 116              $node->path = PmPathManager::appendToPath($parent->path, $parent->id);
 117          else
 118              $node->path = PmPathManager::getSeparator();
 119  
 120          
 121          if(!$node->save())
 122              throw new RuntimeException('Unable to create Node');
 123          
 124          return $node;
 125       }
 126       
 127       /**

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

 129       * AclObject. 

 130       * 

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

 132       * as owner will be returned.

 133       *

 134       * @access public

 135       * @param  AclObject child

 136       * @param  Integer

 137       * @return array[AclNode]

 138       */
 139      public function getDirectChildNodes(AclObject $child = NULL){
 140          $nodeName   = Util::getNodeNameOfObject($this);
 141          $type       = Util::getDataBaseType($this);
 142          
 143          //It's easy: fetch all nodes and get the paths their childs will have

 144          $nodes = $this->getNOdes();
 145          $resPaths = array();
 146          
 147          foreach($nodes as $node){
 148              $resPaths[] = PmPathManager::appendToPath($node->path, $node->id);
 149          }
 150  
 151          $condition = Util::generateInStatement($resPaths);
 152          $params = array();
 153          
 154          if($child !== NULL){
 155              $condition .= ' AND t.collection_id = :id ';
 156              $params[':id'] = $parent->id;
 157          }
 158          
 159          return $nodeName::model()->with($type)->findAll(' t.path '.$condition);
 160      }
 161      
 162      /**

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

 164       * AclObject. 

 165       * 

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

 167       * as owner will be returned.

 168       *

 169       * @access public

 170       * @param  AclObject child

 171       * @param  Integer

 172       * @return array[AclNode]

 173       */
 174      public function getDirectParentNodes(AclObject $parent = NULL){
 175          $nodeName   = Util::getNodeNameOfObject($this);
 176          $type       = Util::getDataBaseType($this);
 177          
 178          //This time it's easy: fetch all paths and search only by the IDs

 179          $paths = $this->getPaths();
 180          $ids = array();
 181          foreach($paths as $path){
 182              //We have to apply it twice - the getPaths() returns full paths

 183              $info = PmPathManager::getParentPath($path);
 184              $info  = PmPathManager::getParentPath($info['path']);
 185              //If it has a parent ^^

 186              if($info['id'])
 187                  $ids[] = $info['id'];
 188          }
 189  
 190          $condition = Util::generateInStatement($ids);
 191          $params = array();
 192          
 193          if($parent !== NULL){
 194              $condition .= ' AND collection_id = :id ';
 195              $params[':id'] = $parent->id;
 196          }
 197          
 198          return $nodeName::model()->with($type)->findAll(' t.id '.$condition);
 199      }
 200       
 201       /**

 202        * Processes post-deletion tasks 

 203        */
 204       public function beforeDelete(){ 
 205           parent::beforeDelete();
 206           
 207           //Delete all associated AclNodes

 208          $class = Util::getNodeNameOfObject($this);
 209          $paths = $this->getPaths();
 210          
 211          //Now, deletes nodes including their subnodes

 212          $condition = PmPathManager::buildMultiplePathCondition("path", $paths);
 213          $num = $class::model()->deleteAll($condition);
 214          
 215          if($num === false)
 216              throw new RuntimeException('Unable to delete all nodes of '.$this->id);
 217          
 218          //Finally, delete all associated permissions

 219          if(PmPermission::deleteByObject($this, $paths) === false)
 220                  throw new RuntimeException('Unable to delete associated permissions of '.$this->id);
 221          
 222          return $num !== false;
 223       }
 224       
 225       /**

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

 227        * @param mixed $obj

 228        * @return boolean

 229        */
 230       public function join($obj){
 231           parent::beforeJoin($obj);
 232           
 233           //Get all nodes of the object

 234           $objNodes = $obj->getNodes();
 235           
 236           $transaction = Yii::app()->db->beginTransaction();
 237           try{
 238              foreach($objNodes as $objNode){
 239                  $this->createNode($objNode);
 240              }
 241              $transaction->commit();
 242           }
 243           catch(Exception $e){
 244               $transaction->rollback();
 245               throw $e;
 246           }
 247           
 248           return true;
 249       }
 250       
 251       /**

 252        * Leaves the given group

 253        * @param mixed $obj

 254        * @return boolean

 255        */
 256       public function leave($obj){
 257           parent::beforeLeave($obj);
 258           
 259           //Get all nodes of the object

 260           $paths = $obj->getPaths();
 261           $nodeClass = Util::getNodeNameOfObject($this);
 262  
 263           //We only want to leave usign the DIRECT child-nodes of this collection

 264           $oneLevelCondition = 'path = ":path"';
 265           $pathCondition = PmPathManager::buildMultiplePathCondition('path', $paths, $oneLevelCondition);
 266           
 267           $transaction = Yii::app()->db->beginTransaction();
 268           try{
 269              $nodes = $nodeClass::model()->findAll('collection_id = :id AND '.$pathCondition,
 270                   array(':id' => $this->id));
 271              
 272              foreach($nodes as $node){
 273                  if(!$node->delete())
 274                      throw new RuntimeException('Unable to delete node');
 275              }
 276              $transaction->commit();
 277              return true;
 278           }
 279           catch(Exception $e){
 280               $transaction->rollback();
 281               throw $e;
 282           }
 283       }
 284       
 285       /**

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

 287        * @param mixed $obj

 288        * @return boolean

 289        */
 290       public function is($obj){
 291           parent::beforeIs($obj);
 292           
 293          //Get all nodes of the object

 294           $paths = $obj->getPaths();
 295           $nodeClass = Util::getNodeNameOfObject($this);
 296  
 297           //We only want to leave usign the DIRECT child-nodes of this collection

 298           $pathCondition = PmPathManager::buildMultiplePathCondition('path', $paths);
 299           
 300           return $nodeClass::model()->find('collection_id = :id  AND'.$pathCondition,
 301                   array(':id' => $this->id)) !== NULL;
 302       }
 303  }
 304  
 305  ?>


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