/** * Runs the SQL query associated with the update of the indexes affected * by the move operation. * * @return int */ public function updateStructure() { list($a, $b, $c, $d) = $this->boundaries(); // select the rows between the leftmost & the rightmost boundaries and apply a lock $this->applyLockBetween($a, $d); $connection = $this->node->getConnection(); $grammar = $connection->getQueryGrammar(); $currentId = (int) $this->node->getKey(); $parentId = (int) $this->parentId(); $leftColumn = $this->node->getLeftColumnName(); $rightColumn = $this->node->getRightColumnName(); $parentColumn = $this->node->getParentColumnName(); $wrappedLeft = $grammar->wrap($leftColumn); $wrappedRight = $grammar->wrap($rightColumn); $wrappedParent = $grammar->wrap($parentColumn); $wrappedId = $grammar->wrap($this->node->getKeyName()); $lftSql = "CASE\n WHEN {$wrappedLeft} BETWEEN {$a} AND {$b} THEN {$wrappedLeft} + {$d} - {$b}\n WHEN {$wrappedLeft} BETWEEN {$c} AND {$d} THEN {$wrappedLeft} + {$a} - {$c}\n ELSE {$wrappedLeft} END"; $rgtSql = "CASE\n WHEN {$wrappedRight} BETWEEN {$a} AND {$b} THEN {$wrappedRight} + {$d} - {$b}\n WHEN {$wrappedRight} BETWEEN {$c} AND {$d} THEN {$wrappedRight} + {$a} - {$c}\n ELSE {$wrappedRight} END"; $parentSql = "CASE\n WHEN {$wrappedId} = {$currentId} THEN {$parentId}\n ELSE {$wrappedParent} END"; $updateConditions = array($leftColumn => $connection->raw($lftSql), $rightColumn => $connection->raw($rgtSql), $parentColumn => $connection->raw($parentSql)); if ($this->node->timestamps) { $updateConditions[$this->node->getUpdatedAtColumn()] = $this->node->freshTimestamp(); } return $this->node->newNestedSetQuery()->where(function ($query) use($leftColumn, $rightColumn, $a, $d) { $query->whereBetween($leftColumn, array($a, $d))->orWhereBetween($rightColumn, array($a, $d)); })->update($updateConditions); }
/** * Flattens an array to contain 'id', 'lft', 'rgt', 'depth', 'parent_id' as a valid tree * @param $nestableArray * @param mixed $parent_id * @param int $depth * @param int $bound * @return array */ public function flattenNestable($nodeList, $parent_id = null, $depth = 0, &$bound = 0) { $nodes = array(); foreach ($nodeList as $node) { $lft = ++$bound; $children = array_get($node, $this->childrenKeyName, []); if (!empty($children)) { $children = $this->flattenNestable($children, array_get($node, $this->node->getKeyName()), $depth + 1, $bound); } $rgt = ++$bound; $nodes[] = array($this->node->getKeyName() => array_get($node, $this->node->getKeyName()), $this->node->getParentColumnName() => $parent_id, $this->node->getDepthColumnName() => $depth, $this->node->getLeftColumnName() => $lft, $this->node->getRightColumnName() => $rgt); $nodes = array_merge($nodes, $children); } return $nodes; }