Move node

@param int $sourceNode
@param string $position
@param int $relatedNode
@return array hash
960289
public function moveNode( $sourceNode, $position, $relatedNode )
    {
        $sourceNode = (int) $sourceNode;
        $sourceRoot = $this->getMapper()
                           ->findRootOf( $sourceNode );

        if ( empty( $sourceRoot ) ||
             ! $sourceRoot->isEditable() )
        {
            return array(
                'sourceNode'    => null,
                'position'      => $position,
                'relatedNode'   => $relatedNode,
                'success'       => false,
            );
        }

        $relatedNode = (int) $relatedNode;
        $relatedRoot = $this->getMapper()
                            ->findRootOf( $relatedNode );

        if ( empty( $relatedRoot ) ||
             ! $relatedRoot->isEditable() )
        {
            return array(
                'sourceNode'    => $sourceNode,
                'position'      => $position,
                'relatedNode'   => null,
                'success'       => false,
            );
        }

        $success = $this->getMapper()
                        ->moveNode( $sourceNode,
                                    strtolower( $position ),
                                    $relatedNode );

        return array(
            'sourceNode'    => $sourceNode,
            'position'      => $position,
            'relatedNode'   => $relatedNode,
            'success'       => (bool) $success,
        );
    }
68318
public function moveToParent($movedNode, $newParent, $position=null)
    {

        $this->callBeforeListeners('move', [$movedNode, $newParent, $position]);

        $this->model()->placeAt($movedNode, $newParent, $position);

        if (!$position) {
            $this->model()->makeChildOf($movedNode, $newParent);
        } else {
            $this->model()->placeAt($movedNode, $newParent, $position);
        }

        $this->callAfterListeners('move', [$movedNode, $newParent, $position]);

        return $this;
    }
1048805
public function moveAsNextSiblingOf(NodeInterface $afterNode)
	{
		$pos = $afterNode->getRightValue() + 1;
		$level = $afterNode->getLevel();
		$this->move($pos, $level);

		return $this;
	}
348715
protected function reorder($oldPosition = null, $position = null, $siblings = [])
    {
        if (null === $oldPosition || null === $position || true === empty($siblings)) {
            return ['error' => Yii::t('jstw', 'Invalid data provided!')];
        }
        $nodeId = $siblings[$position];
        $class = $this->className;
        if ($oldPosition > $position) {
            //change next
            $nodeOperator = '-';
            $siblingsOperator = '+';
            $workWith = array_slice($siblings, $position, $oldPosition - $position + 1);
        } else if ($oldPosition < $position) {
            //change previous
            $nodeOperator = '+';
            $siblingsOperator = '-';
            $workWith = array_slice($siblings, $oldPosition, $position - $oldPosition + 1);
        } else {
            return true;
        }
        if (true === empty($workWith)) {
            return ['error' => Yii::t('jstw', 'Invalid data provided!')];
        }
        $lr = $workWithLr = $this->getLr($workWith);
        if (true === empty($lr)) {
            return ['error' => Yii::t('jstw', 'Invalid data provided!')];
        }
        unset($workWithLr[$nodeId]);
        $lft = array_column($workWithLr, $this->leftAttribute);
        $lft = min($lft);
        $rgt = array_column($workWithLr, $this->rightAttribute);
        $rgt = max($rgt);
        $nodeCondition = [
            'and',
            ['>=', $this->leftAttribute, $lft],
            ['<=', $this->rightAttribute, $rgt]
        ];
        $this->applyRootCondition($nodeCondition);
        $nodeDelta = $this->getCount($nodeCondition);
        $nodeDelta *= 2;
        $siblingsCondition = [
            'and',
            ['>=', $this->leftAttribute, $lr[$nodeId][$this->leftAttribute]],
            ['<=', $this->rightAttribute, $lr[$nodeId][$this->rightAttribute]]
        ];
        $this->applyRootCondition($siblingsCondition);
        $nodeChildren = $this->getChildIds($siblingsCondition);
        $siblingsDelta = count($nodeChildren) * 2;
        $db = Yii::$app->getDb();
        $transaction = $db->beginTransaction();
        try {
            //updating necessary node siblings
            $db->createCommand()->update(
                $class::tableName(),
                [
                    $this->leftAttribute => new Expression($this->leftAttribute . sprintf('%s%d', $siblingsOperator, $siblingsDelta)),
                    $this->rightAttribute => new Expression($this->rightAttribute . sprintf('%s%d', $siblingsOperator, $siblingsDelta)),
                ],
                $nodeCondition
            )->execute();
            //updating node
            $db->createCommand()->update(
                $class::tableName(),
                [
                    $this->leftAttribute => new Expression($this->leftAttribute . sprintf('%s%d', $nodeOperator, $nodeDelta)),
                    $this->rightAttribute => new Expression($this->rightAttribute . sprintf('%s%d', $nodeOperator, $nodeDelta)),
                ],
                ['id' => $nodeChildren]
            )->execute();
            $transaction->commit();
        } catch (\Exception $e) {
            $transaction->rollBack();
            return ['error' => $e->getMessage()];
        }
        return true;
    }
126306
public function match($node, $position, $items)
    {
        return Dom::searchNode($node, $this->_items) === false;
    }
49652
public function moveSubtree(array $sourceTagData, array $destinationParentTagData = null)
    {
        $query = $this->handler->createSelectQuery();
        $query
            ->select(
                $this->handler->quoteColumn('id'),
                $this->handler->quoteColumn('parent_id'),
                $this->handler->quoteColumn('main_tag_id'),
                $this->handler->quoteColumn('path_string')
            )
            ->from($this->handler->quoteTable('eztags'))
            ->where(
                $query->expr->lOr(
                    $query->expr->like(
                        $this->handler->quoteColumn('path_string'),
                        $query->bindValue($sourceTagData['path_string'] . '%', null, PDO::PARAM_STR)
                    ),
                    $query->expr->eq(
                        $this->handler->quoteColumn('main_tag_id'),
                        $query->bindValue($sourceTagData['id'], null, PDO::PARAM_INT)
                    )
                )
            );

        $statement = $query->prepare();
        $statement->execute();

        $rows = $statement->fetchAll(PDO::FETCH_ASSOC);

        $oldParentPathString = implode('/', array_slice(explode('/', $sourceTagData['path_string']), 0, -2)) . '/';
        foreach ($rows as $row) {
            // Prefixing ensures correct replacement when there is no parent
            $newPathString = str_replace(
                'prefix' . $oldParentPathString,
                $destinationParentTagData ?
                    $destinationParentTagData['path_string'] :
                    '/',
                'prefix' . $row['path_string']
            );

            $newParentId = $row['parent_id'];
            if ($row['path_string'] === $sourceTagData['path_string'] || (int) $row['main_tag_id'] === (int) $sourceTagData['id']) {
                $newParentId = (int) implode('', array_slice(explode('/', $newPathString), -3, 1));
            }

            $newDepth = mb_substr_count($newPathString, '/') - 1;

            $query = $this->handler->createUpdateQuery();
            $query
                ->update($this->handler->quoteTable('eztags'))
                ->set(
                    $this->handler->quoteColumn('path_string'),
                    $query->bindValue($newPathString, null, PDO::PARAM_STR)
                )->set(
                    $this->handler->quoteColumn('depth'),
                    $query->bindValue($newDepth, null, PDO::PARAM_INT)
                )->set(
                    $this->handler->quoteColumn('modified'),
                    $query->bindValue(time(), null, PDO::PARAM_INT)
                )->set(
                    $this->handler->quoteColumn('parent_id'),
                    $query->bindValue($newParentId, null, PDO::PARAM_INT)
                )->where(
                    $query->expr->eq(
                        $this->handler->quoteColumn('id'),
                        $query->bindValue($row['id'], null, PDO::PARAM_INT)
                    )
                );

            $query->prepare()->execute();
        }
    }
1106203
protected function move($position = null, $siblings = [], $oldParentId)
    {
        $class = $this->className;
        if (null === $oldParent = $class::findOne($oldParentId)) {
            return ['error' => Yii::t('jstw', "Old parent with id '{id}' not found!", ['id' => $oldParentId])];
        }
        $nodeCountCondition = [
            'and',
            ['>=', $this->leftAttribute, $this->node{$this->leftAttribute}],
            ['<=', $this->rightAttribute, $this->node{$this->rightAttribute}]
        ];
        $this->applyRootCondition($nodeCountCondition);
        $nodeChildren = $this->getChildIds($nodeCountCondition);
        $siblingsDelta = count($nodeChildren) * 2;
        if ($position == 0) {
            $compareRight = $this->parent->{$this->leftAttribute} + 1;
        } else {
            if (false === isset($siblings[$position - 1])) {
                return ['error' => Yii::t('jstw', 'New previous sibling does not exist')];
            }
            $newPrevSiblingId = $siblings[$position - 1];
            $newPrevSiblingData = $this->getLr($newPrevSiblingId);
            $compareRight = $newPrevSiblingData[$newPrevSiblingId][$this->rightAttribute];
        }
        if ($this->node->{$this->leftAttribute} > $compareRight) {
            //move node up
            if ($position == 0) {
                $leftFrom = $compareRight;
            } else {
                $leftFrom = $compareRight + 1;
            }
            $rightTo = $this->node->{$this->leftAttribute};
            $nodeDelta = $this->node->{$this->leftAttribute} - $leftFrom;
            $nodeOperator = '-';
            $parentOperator = $siblingsOperator = '+';
            $newParentUpdateField = $this->rightAttribute;
            $oldParentUpdateField = $this->leftAttribute;
        } else if ($this->node->{$this->leftAttribute} < $compareRight) {
            //move node down
            $leftFrom = $this->node->{$this->rightAttribute};
            if ($position == 0) {
                $rightTo = $compareRight - 1;
            } else {
                $rightTo = $compareRight;
            }
            $nodeOperator = '+';
            $parentOperator = $siblingsOperator = '-';
            $nodeDelta = $rightTo - $siblingsDelta + 1 - $this->node->{$this->leftAttribute};
            $newParentUpdateField = $this->leftAttribute;
            $oldParentUpdateField = $this->rightAttribute;
        } else {
            return ['error' => Yii::t('jstw', 'There are two nodes with same "left" value. This should not be.')];
        }
        $siblingsCondition = [
            'and',
            ['>=', $this->leftAttribute, $leftFrom],
            ['<=', $this->rightAttribute, $rightTo]
        ];
        $this->applyRootCondition($siblingsCondition);
        $db = Yii::$app->getDb();
        $transaction = $db->beginTransaction();
        $oldParentDepth = $oldParent->{$this->depthAttribute};
        $newParentDepth = $this->parent->{$this->depthAttribute};
        if ($newParentDepth < $oldParentDepth) {
            $depthOperator = '-';
            $depthDelta = $oldParentDepth - $newParentDepth;
        } else {
            $depthOperator = '+';
            $depthDelta = $newParentDepth - $oldParentDepth;
        }
        $commonParentsCondition = [
            'and',
            ['<', $this->leftAttribute, $leftFrom],
            ['>', $this->rightAttribute, $rightTo]
        ];
        $this->applyRootCondition($commonParentsCondition);
        $commonParentsIds = $class::find()->select('id')->where($commonParentsCondition)->column();
        $commonCondition = [
            ['!=', $this->depthAttribute, 0],
            ['not in', 'id', $commonParentsIds],
        ];
        $this->applyRootCondition($commonCondition);
        $newParentCondition = array_merge([
            'and',
            ['<=', $this->leftAttribute, $this->parent->{$this->leftAttribute}],
            ['>=', $this->rightAttribute, $this->parent->{$this->rightAttribute}],
        ], $commonCondition);
        $oldParentsCondition = array_merge([
            'and',
            ['<', $this->leftAttribute, $this->node->{$this->leftAttribute}],
            ['>', $this->rightAttribute, $this->node->{$this->rightAttribute}],
        ], $commonCondition);
        try {
            //updating necessary node siblings
            $db->createCommand()->update(
                $class::tableName(),
                [
                    $this->leftAttribute => new Expression($this->leftAttribute . sprintf('%s%d', $siblingsOperator, $siblingsDelta)),
                    $this->rightAttribute => new Expression($this->rightAttribute . sprintf('%s%d', $siblingsOperator, $siblingsDelta)),
                ],
                $siblingsCondition
            )->execute();
            //updating old parents
            $db->createCommand()->update(
                $class::tableName(),
                [
                    //down - right
                    $oldParentUpdateField => new Expression($oldParentUpdateField . sprintf('%s%d', $parentOperator, $siblingsDelta)),
                ],
                $oldParentsCondition
            )->execute();
            //updating new parents
            $db->createCommand()->update(
                $class::tableName(),
                [
                    //down - left
                    $newParentUpdateField => new Expression($newParentUpdateField . sprintf('%s%d', $parentOperator, $siblingsDelta)),
                ],
                $newParentCondition
            )->execute();
            //updating node with children
            $db->createCommand()->update(
                $class::tableName(),
                [
                    $this->leftAttribute => new Expression($this->leftAttribute . sprintf('%s%d', $nodeOperator, $nodeDelta)),
                    $this->rightAttribute => new Expression($this->rightAttribute . sprintf('%s%d', $nodeOperator, $nodeDelta)),
                    $this->depthAttribute => new Expression($this->depthAttribute . sprintf('%s%d', $depthOperator, $depthDelta)),
                ],
                ['id' => $nodeChildren]
            )->execute();
            $transaction->commit();
        } catch (\Exception $e) {
            $transaction->rollBack();
            return ['error' => $e->getMessage()];
        }
        return true;
    }
37328
final protected function shiftLeftFromPos($position)
    {
        $cnt = parent::count();
        if ($position < 1 || $position >= $cnt) {
            throw new \OutOfBoundsException('position to shift from must be in range 1..Length-1');
        }
        for ($i = $position; $i < $cnt; $i++) {
            $this->items[$i - 1] = $this->items[$i];
        }
    }
1335853
protected function moveNode(Node\NodeInterface $item, $moveLeft, $moveRight, $moveLevel)
	{
//		$newLeft = $item->getLeftValue() + (int) $moveLeft;
//		$newRight = $item->getRightValue() + (int) $moveRight;
//		$newLevel = $item->getLevel() + (int) $moveLevel;
//
// Call original local move method for items not in the database yet
		parent::moveNode($item, $moveLeft, $moveRight, $moveLevel);

// In case of entity update, make the new nested set values to be ignored
		$insert = $this->entityManager->getUnitOfWork()->isScheduledForInsert($item);
		if ( ! $insert) {
			$oid = spl_object_hash($item);
			$this->entityManager->getUnitOfWork()->setOriginalEntityProperty($oid, 'level', $item->getLevel());
			$this->entityManager->getUnitOfWork()->setOriginalEntityProperty($oid, 'right', $item->getRightValue());
			$this->entityManager->getUnitOfWork()->setOriginalEntityProperty($oid, 'left', $item->getLeftValue());
		}

//
//		if ($insert) {
//			// Call original local move method for items not in the database yet
//			parent::moveNode($item, $moveLeft, $moveRight, $moveLevel);
//		} else {
//			// Refresh so additional UPDATE-s are not executed on the server
//			$this->entityManager->refresh($item);
//		}
//		// Double check the values, should not happen
//		if ($item->getLeftValue() != $newLeft) {
//			$item->setLeftValue($newLeft);
//		}
//		if ($item->getRightValue() != $newRight) {
//			$item->setRightValue($newRight);
//		}
//		if ($item->getLevel() != $newLevel) {
//			$item->setLevel($newLevel);
//		}
	}
709065
protected function doSetSportId(Position $model, $relatedId) {
		if ($model->getSportId() !== $relatedId) {
			$model->setSportId($relatedId);

			return true;
		}

		return false;
	}
398592
public function beforeNodeMove(NodeInterface $movedNode, NodeInterface $referenceNode, $moveOperation)
    {
        if (!$this->eventEmittingService->isEnabled()) {
            return;
        }

        $this->currentlyMoving += 1;

        /* @var $nodeEvent NodeEvent */
        $nodeEvent = $this->eventEmittingService->emit(self::NODE_MOVE, [
            'referenceNode' => $referenceNode->getContextPath(),
            'moveOperation' => $moveOperation
        ], NodeEvent::class);
        $nodeEvent->setNode($movedNode);
        $this->eventEmittingService->pushContext();
    }
662926
public function moveToPosition(array $conditions, int $originalPosition, int $position, bool $allowOutOfRange = false): int
    {
        $nextPosition = $this->getNextPosition($conditions);

        if ($position < 0) {
            throw new BadStateException('position', 'Position cannot be negative.');
        }

        if (!$allowOutOfRange && $position >= $nextPosition) {
            throw new BadStateException('position', 'Position is out of range.');
        }

        if ($position > $originalPosition) {
            $this->decrementPositions(
                $conditions,
                $originalPosition + 1,
                $position
            );
        } elseif ($position < $originalPosition) {
            $this->incrementPositions(
                $conditions,
                $position,
                $originalPosition - 1
            );
        }

        return $position;
    }
47019
public function moveAction(Request $request)
    {
        $id = $request->get('id');
        $targetId = $request->get('target');

        $treeManager = $this->get('phlexible_tree.tree_manager');
        $tree = $treeManager->getByNodeId($id);
        $node = $tree->get($id);

        $targetTree = $treeManager->getByNodeId($targetId);
        $targetNode = $tree->get($targetId);

        if ($id === $targetId) {
            return new ResultResponse(false, 'source_id === target_id');
        }

        $tree->move($node, $targetNode, $this->getUser()->getId());

        return new ResultResponse(true, 'Element moved.', ['id' => $id, 'parent_id' => $targetId]);
    }
647926
function move( $newParentNodeID, $nodeID = 0 )
    {
        if ( $nodeID == 0 )
        {
            $node = $this;
            $nodeID = $node->attribute( 'node_id' );
        }
        else
        {
            $node = eZContentObjectTreeNode::fetch( $nodeID );
        }

        $oldPath = $node->attribute( 'path_string' );
        $oldParentNodeID = $node->attribute( 'parent_node_id' );
        $newParentNodeID =(int) $newParentNodeID;
        if ( $oldParentNodeID != $newParentNodeID )
        {
            $node->updateAndStoreModified();
            // Who moves which content should be logged.
            $object = $node->object();
            eZAudit::writeAudit( 'content-move', array( 'Node ID' => $node->attribute( 'node_id' ),
                                                        'Old parent node ID' => $oldParentNodeID, 'New parent node ID' => $newParentNodeID,
                                                        'Object ID' => $object->attribute( 'id' ), 'Content Name' => $object->attribute( 'name' ),
                                                        'Comment' => 'Moved the node to the given node: eZContentObjectTreeNode::move()' ) );

            $newParentNode = eZContentObjectTreeNode::fetch( $newParentNodeID );
            $newParentPath = $newParentNode->attribute( 'path_string' );
            $newParentDepth = $newParentNode->attribute( 'depth' );
            $newPath = $newParentPath . $nodeID;
            $oldDepth = $node->attribute( 'depth' );

            $oldPathLength = strlen( $oldPath );
            $moveQuery = "UPDATE
                                 ezcontentobject_tree
                          SET
                                 parent_node_id = $newParentNodeID
                          WHERE
                                 node_id = $nodeID";
            $db = eZDB::instance();
            $subStringString = $db->subString( 'path_string', $oldPathLength );
            $newPathString   = $db->concatString( array( "'$newPath'", $subStringString ) );
            $moveQuery1 = "UPDATE
                                 ezcontentobject_tree
                           SET
                                 path_identification_string = " .
                                 $db->concatString(
                                     array(
                                         "'" . $db->escapeString( $newParentNode->PathIdentificationString ) . "'",
                                         $db->subString(
                                             "path_identification_string",
                                             mb_strlen( $node->PathIdentificationString ) + 1
                                         )
                                     )
                                 ) . ",
                                 path_string = $newPathString,
                                 depth = depth + $newParentDepth - $oldDepth + 1
                           WHERE
                                 path_string LIKE '$oldPath%'";
            $db->begin();
            $db->query( $moveQuery );
            $db->query( $moveQuery1 );

            /// role system clean up
            // Clean up policies and limitations

            $expireRoleCache = false;

            $limitationsToFix = eZPolicyLimitation::findByType( 'SubTree', $node->attribute( 'path_string' ), false );
            if ( count( $limitationsToFix ) > 0 )
            {
                $limitationIDString = $db->generateSQLINStatement( $limitationsToFix, 'limitation_id' );
                $subStringString =  $db->subString( 'value', $oldPathLength );
                $newValue = $db->concatString( array( "'$newPath'", $subStringString ) );

                $query = "UPDATE
                                ezpolicy_limitation_value
                          SET
                                value = $newValue
                          WHERE
                                value LIKE '$oldPath%' AND $limitationIDString";

                $db->query( $query );

                $expireRoleCache = true;
            }

            // clean up limitations on role assignment level
            $countRows = $db->arrayQuery( "SELECT COUNT(*) AS row_count FROM ezuser_role WHERE limit_identifier='Subtree' AND limit_value LIKE '$oldPath%'" );
            $assignmentsToFixCount = $countRows[0]['row_count'];

            if ( $assignmentsToFixCount > 0 )
            {
                $subStringString =  $db->subString( 'limit_value', $oldPathLength );
                $newValue = $db->concatString( array( "'$newPath'", $subStringString ) );

                $db->query( "UPDATE
                                ezuser_role
                             SET
                                limit_value = $newValue
                             WHERE
                                limit_identifier='Subtree' AND limit_value LIKE '$oldPath%'"
                          );

               $expireRoleCache = true;
           }

            if ( $expireRoleCache )
            {
                eZRole::expireCache();
            }

            // Update "is_invisible" node attribute.
            $newNode = eZContentObjectTreeNode::fetch( $nodeID );
            eZContentObjectTreeNode::updateNodeVisibility( $newNode, $newParentNode );
            $db->commit();
        }
    }
1058360
public function setPosition($position = self::POSITION_RIGHT) {
		if (!in_array($position,self::$_positionXLref)) {
			return false;
		}

		$this->_position = $position;
		return true;
	}
24440
private function internalMoveBlock(PersistenceBlock $block, PersistenceBlock $targetBlock, string $placeholder, int $position): PersistenceBlock
    {
        return $this->transaction(
            function () use ($block, $targetBlock, $placeholder, $position): PersistenceBlock {
                if ($block->parentId === $targetBlock->id && $block->placeholder === $placeholder) {
                    return $this->blockHandler->moveBlockToPosition($block, $position);
                }

                return $this->blockHandler->moveBlock(
                    $block,
                    $targetBlock,
                    $placeholder,
                    $position
                );
            }
        );
    }
832426
function move(node, stayWithin, directionIsNext) {
  if (directionIsNext) {
    return NodeTraversal.next(node, stayWithin);
  } else {
    if (node === stayWithin) {
      return null;
    }
    return NodeTraversal.previous(node, null);
  }
}