FOF30\Model\TreeModel::moveToLeftOf PHP Method

moveToLeftOf() public method

Moves the current node (and its subtree) to the left of another node. The other node can be in a different position in the tree or even under a different root.
public moveToLeftOf ( TreeModel $siblingNode )
$siblingNode TreeModel
    public function moveToLeftOf(TreeModel $siblingNode)
    {
        // Sanity checks on current and sibling node position
        if ($this->lft >= $this->rgt) {
            throw new TreeInvalidLftRgtCurrent();
        }
        if ($siblingNode->lft >= $siblingNode->rgt) {
            throw new TreeInvalidLftRgtSibling();
        }
        $db = $this->getDbo();
        $left = $db->qn($this->getFieldAlias('lft'));
        $right = $db->qn($this->getFieldAlias('rgt'));
        // Get node metrics
        $myLeft = $this->lft;
        $myRight = $this->rgt;
        $myWidth = $myRight - $myLeft + 1;
        // Get parent metrics
        $sibLeft = $siblingNode->lft;
        // Start the transaction
        $db->transactionStart();
        try {
            // Temporary remove subtree being moved
            $query = $db->getQuery(true)->update($db->qn($this->tableName))->set("{$left} = " . $db->q(0) . " - {$left}")->set("{$right} = " . $db->q(0) . " - {$right}")->where($left . ' >= ' . $db->q($myLeft))->where($right . ' <= ' . $db->q($myRight));
            $db->setQuery($query)->execute();
            // Close hole left behind
            $query = $db->getQuery(true)->update($db->qn($this->tableName))->set($left . ' = ' . $left . ' - ' . $db->q($myWidth))->where($left . ' > ' . $db->q($myRight));
            $db->setQuery($query)->execute();
            $query = $db->getQuery(true)->update($db->qn($this->tableName))->set($right . ' = ' . $right . ' - ' . $db->q($myWidth))->where($right . ' > ' . $db->q($myRight));
            $db->setQuery($query)->execute();
            // Make a hole for the new items
            $newSibLeft = $sibLeft > $myRight ? $sibLeft - $myWidth : $sibLeft;
            $query = $db->getQuery(true)->update($db->qn($this->tableName))->set($right . ' = ' . $right . ' + ' . $db->q($myWidth))->where($right . ' >= ' . $db->q($newSibLeft));
            $db->setQuery($query)->execute();
            $query = $db->getQuery(true)->update($db->qn($this->tableName))->set($left . ' = ' . $left . ' + ' . $db->q($myWidth))->where($left . ' >= ' . $db->q($newSibLeft));
            $db->setQuery($query)->execute();
            // Move node and subnodes
            $moveRight = $newSibLeft - $myLeft;
            $query = $db->getQuery(true)->update($db->qn($this->tableName))->set($left . ' = ' . $db->q(0) . ' - ' . $left . ' + ' . $db->q($moveRight))->set($right . ' = ' . $db->q(0) . ' - ' . $right . ' + ' . $db->q($moveRight))->where($left . ' <= 0 - ' . $db->q($myLeft))->where($right . ' >= 0 - ' . $db->q($myRight));
            $db->setQuery($query)->execute();
            // Commit the transaction
            $db->transactionCommit();
        } catch (\Exception $e) {
            $db->transactionRollback();
            throw $e;
        }
        // Let's load the record again to fetch the new values for lft and rgt
        $this->findOrFail();
        return $this;
    }