ACL Extension  0.3
 All Data Structures Namespaces Files Functions Variables
PmAclObject.php
Go to the documentation of this file.
1 <?php
2 
12 class PmAclObject extends AclObject{
13 
14 
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 
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 
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 ? 'REGEX' : '=';
63 
64  return $destination['table'].'.'.$destination['field'].'_path'
65  .' '.$method.' '.$pathExpression;
66  }
67 
74  public function fetchComprisedPositions(){
75  return $this->getPaths();
76  }
77 
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 
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 
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 
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 
204  public function 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 
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 
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 
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 ?>