/** * @desc make exist- and recursioncheck before moving Items */ public function checkRecursion() { $model = new AuthItemChild(); // climb up moveTo tree and search for moveFrom Item. $source = $this->moveFrom; $target = $this->moveTo; //quick precheck if moving items are nowhere in the Tree if (!$model->findByAttributes(array('child' => $source)) && !$model->findByAttributes(array('parent' => $source))) { $this->rekursionCheck = true; return true; } /* * this is a bit tricky, cause we can not search by child in top level * so we have to switch searching one last time by parent if no more items are found with searching by child */ $column = 'child'; $currentItem = $target; $depth = 0; $depthLimit = $this->rekursionCheckDepthLimit; while (true) { $result = $model->findAllByAttributes(array("{$column}" => $currentItem)); if (!count($result) && $column == 'parent') { // nothing found in child column // this switch should never entered with $column == 'parent' $this->rekursionCheck = true; return true; } elseif (!count($result)) { // top Level Items can't be detected via child, so we make last search again in column parent $column = 'parent'; continue; } // check parents if they are same with source foreach ($result as $row) { if ($row->parent == $source) { $this->rekursionCheck = false; return false; } } // last top level Item was checked if ($column == 'parent') { $this->rekursionCheck = true; return true; } $currentItem = $row->parent; if ($depth++ >= $depthLimit) { throw new CHttpException("CheckRecursion Error: Depthlimit of {$depthLimit} parents executed"); } } return $this->rekursionCheck; }
/** * * @desc */ public function actionMove() { $this->checkAccess('RbacViewer', true); if (!empty($_POST)) { $this->checkAccess('RbacEditor', true); $from = isset($_POST['moveFromItem']) ? $_POST['moveFromItem'] : null; $to = isset($_POST['moveToItem']) ? $_POST['moveToItem'] : null; // check only if parent is protected if (in_array($to, $this->protectedItems)) { if (in_array($from, $this->protectedItems)) { $this->messageErrors[] = "Sorry, Item is protected by Controller"; $this->actionIndex(); } } if (!$from || !$to || $from == $to) { $this->messageErrors[] = "Please select Parent- and Childitem and care that they are not same."; $this->actionIndex(); } // default validate $model = new AuthItemChild(); $model->attributes = array('child' => $from, 'parent' => $to); if (!$model->validate()) { $this->messageErrors[] = "Post validation Error. Please mail Siteadmin if this Error returns."; $this->actionIndex(); } // check if branch already exists if ($model->findByAttributes(array('child' => $from, 'parent' => $to)) !== null) { $this->messageErrors[] = "Create Brunch Error: Brunch already exists."; $this->actionIndex(); } // Items exist? $model = new AuthItem(); if (!count($model->findByAttributes(array('name' => $from))) || !count($model->findByAttributes(array('name' => $to)))) { $this->messageErrors[] = "Check Items exists Error. Please mail Siteadmin if this Error returns."; $this->actionIndex(); } // make recursioncheck and move Items $model = new RBACTree(); $model->moveFrom = $from; $model->moveTo = $to; if ($model->checkRecursion()) { $model->moveItem(); $this->messageSuccess[] = "Item {$from} successfull moved to {$to}."; } else { $this->messageErrors[] = "Can't move Selection cause that will produce a Recursion.\n\t\t\t\t<br>If you can't see producing a Recursion, it may help to eject Item before moving it."; $this->actionIndex(); } } $this->actionIndex(); }