Поведение дерева CakePHP удалить родительский узел, кроме детей - PullRequest
0 голосов
/ 06 февраля 2012

Можно ли удалить родительский узел из дерева, используя CakePHP Tree Behavior?? 1002 *. Например, у меня есть такой узел:

<Node A>
    - child 1 node A
    - child 2 node A
    - child 3 node A
    - <Node B> (which is also a child 4 of Node A)
        - child 1 node B
        - child 2 node B

Можно ли получить всех детей узла A (используя chidren () или любую другую функцию поведения дерева в cakePHP), но исключить узел, у которого есть дочерние элементы из результата (в нашем случае узел B)?

Есть идеи, пожалуйста?

Заранее спасибо

Ответы [ 4 ]

0 голосов
/ 18 мая 2016

вот код из моего проекта cakephp 2.x:

public function delete($id = null) {
        $this->ProductCategory->id = $id;
        if (!$this->ProductCategory->exists()) {
            throw new NotFoundException(__('Invalid product category'));
        }
        $this->request->allowMethod('post', 'delete');
        if ($this->ProductCategory->removeFromTree($id, TRUE)) {
            $this->Session->setFlash(__('The product category has been deleted.'));
        } else {
            $this->Session->setFlash(__('The product category could not be deleted. Please, try again.'));
        }
        return $this->redirect(array('action' => 'index'));
    }

Использование этого метода (например, removeFromTree ()) удалит или переместит узел, но сохранит его поддерево, которое будет перерисованона один уровень выше.Он предлагает больше контроля, чем удаление, что для модели, использующей поведение дерева, удалит указанный узел и все его дочерние элементы.

0 голосов
/ 06 февраля 2012

Что касается спецификаций, то для этого нет конкретного метода, поэтому вы должны создать свою собственную функцию для этого, используя children () и childCount (). Вот шаблон кода (я не использую Cake PHP):

$children = <call TreeBehavior children() method with $id = id of Node A and $direct = true>;
$children_without_children = array();
foreach ($children as $child) {
    if (<call TreeBehavior childCount() method with $id = $child->id and $direct = true> === 0) {
        $children_without_children[] = $child;
    }
}

Тогда $ children_without_children должен содержать то, что вы хотите.

0 голосов
/ 08 апреля 2012

Вы можете использовать этот код:

$this->Node->removeFromTree($id, true);
0 голосов
/ 06 февраля 2012

Вы можете, но вам нужно немного испачкать руки, потому что я не думаю, что поведение позволяет что-то подобное.

Ключ заключается в том, что все узлы, которые не имеют дочерних элементов, должны иметь значения left и right в последовательности. Вам нужно будет создать запрос, подобный следующему:

SELECT * FROM items WHERE left > (parent's left) AND right < (parent's right) AND right = left + 1 AND parent_id = (parent's ID)

Таким образом, мы просим, ​​чтобы все возвращаемые значения были дочерними для нашего родителя и чтобы их левые и правые значения были в последовательности, чего не будет, если у узла есть дочерние элементы.

...