[ Index ] |
PHP Cross Reference of ACL Module |
[Summary view] [Print] [Text view]
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 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Jul 1 19:24:45 2012 | Cross-referenced by PHPXref 0.7.1 |