Phalcon\Mvc\Model\Behavior\NestedSet::moveNode PHP Method

moveNode() private method

private moveNode ( Phalcon\Mvc\ModelInterface $target, integer $key, integer $levelUp ) : boolean
$target Phalcon\Mvc\ModelInterface
$key integer
$levelUp integer
return boolean
    private function moveNode(ModelInterface $target, $key, $levelUp)
    {
        $owner = $this->getOwner();
        if ($this->getIsNewRecord()) {
            throw new Exception('The node should not be new record.');
        }
        if ($this->getIsDeletedRecord()) {
            throw new Exception('The node should not be deleted.');
        }
        if ($target->getIsDeletedRecord()) {
            throw new Exception('The target node should not be deleted.');
        }
        if ($owner == $target) {
            throw new Exception('The target node should not be self.');
        }
        if ($target->isDescendantOf($owner)) {
            throw new Exception('The target node should not be descendant.');
        }
        if (!$levelUp && $target->isRoot()) {
            throw new Exception('The target node should not be root.');
        }
        $this->db->begin();
        $left = $owner->{$this->leftAttribute};
        $right = $owner->{$this->rightAttribute};
        $levelDelta = $target->{$this->levelAttribute} - $owner->{$this->levelAttribute} + $levelUp;
        if ($this->hasManyRoots && $owner->{$this->rootAttribute} !== $target->{$this->rootAttribute}) {
            $this->ignoreEvent = true;
            // 1. Rebuild the target tree
            foreach ([$this->leftAttribute, $this->rightAttribute] as $attribute) {
                $condition = join(' AND ', [$attribute . '>=' . $key, $this->rootAttribute . '=' . $target->{$this->rootAttribute}]);
                foreach ($target::find($condition) as $i) {
                    $delta = $right - $left + 1;
                    /** @var ModelInterface $i */
                    if (!$i->update([$attribute => $i->{$attribute} + $delta])) {
                        $this->db->rollback();
                        $this->ignoreEvent = false;
                        return false;
                    }
                }
            }
            $delta = $key - $left;
            // 2. Rebuild the owner's tree of children (owner sub-tree)
            $condition = $this->leftAttribute . '>=' . $left . ' AND ';
            $condition .= $this->rightAttribute . '<=' . $right . ' AND ';
            $condition .= $this->rootAttribute . '=' . $owner->{$this->rootAttribute};
            foreach ($owner::find($condition) as $i) {
                $arr = [$this->leftAttribute => $i->{$this->leftAttribute} + $delta, $this->rightAttribute => $i->{$this->rightAttribute} + $delta, $this->levelAttribute => $i->{$this->levelAttribute} + $levelDelta, $this->rootAttribute => $target->{$this->rootAttribute}];
                if ($i->update($arr) == false) {
                    $this->db->rollback();
                    $this->ignoreEvent = false;
                    return false;
                }
            }
            // 3. Rebuild the owner tree
            $this->shiftLeftRight($right + 1, $left - $right - 1, $owner);
            $this->ignoreEvent = false;
            $this->db->commit();
        } else {
            $delta = $right - $left + 1;
            $this->ignoreEvent = true;
            $this->shiftLeftRight($key, $delta);
            if ($left >= $key) {
                $left += $delta;
                $right += $delta;
            }
            $condition = $this->leftAttribute . '>=' . $left . ' AND ' . $this->rightAttribute . '<=' . $right;
            if ($this->hasManyRoots) {
                $condition .= ' AND ' . $this->rootAttribute . '=' . $owner->{$this->rootAttribute};
            }
            foreach ($owner::find($condition) as $i) {
                if ($i->update([$this->levelAttribute => $i->{$this->levelAttribute} + $levelDelta]) == false) {
                    $this->db->rollback();
                    $this->ignoreEvent = false;
                    return false;
                }
            }
            foreach ([$this->leftAttribute, $this->rightAttribute] as $attribute) {
                $condition = $attribute . '>=' . $left . ' AND ' . $attribute . '<=' . $right;
                if ($this->hasManyRoots) {
                    $condition .= ' AND ' . $this->rootAttribute . '=' . $owner->{$this->rootAttribute};
                }
                foreach ($owner::find($condition) as $i) {
                    if ($i->update([$attribute => $i->{$attribute} + $key - $left]) == false) {
                        $this->db->rollback();
                        $this->ignoreEvent = false;
                        return false;
                    }
                }
            }
            $this->shiftLeftRight($right + 1, -$delta);
            $this->ignoreEvent = false;
            $this->ignoreEvent = false;
            $this->db->commit();
        }
        return true;
    }