Neos.ContentRepository/Classes/Domain/Repository/NodeDataRepository.php
public function setNewIndex(NodeData $node, $position, NodeInterface $referenceNode = null)
    {
        $parentPath = $node->getParentPath();

        switch ($position) {
            case self::POSITION_BEFORE:
                if ($referenceNode === null) {
                    throw new \InvalidArgumentException('The reference node must be specified for POSITION_BEFORE.', 1317198857);
                }
                $referenceIndex = $referenceNode->getIndex();
                $nextLowerIndex = $this->findNextLowerIndex($parentPath, $referenceIndex);
                if ($nextLowerIndex === null) {
                    // FIXME: $nextLowerIndex returns 0 and not NULL in case no lower index is found. So this case seems to be
                    // never executed. We need to check that again!
                    $newIndex = (integer)round($referenceIndex / 2);
                } elseif ($nextLowerIndex < ($referenceIndex - 1)) {
                    // there is free space left between $referenceNode and preceding sibling.
                    $newIndex = (integer)round($nextLowerIndex + (($referenceIndex - $nextLowerIndex) / 2));
                } else {
                    // there is no free space left between $referenceNode and following sibling -> we have to make room!
                    $this->openIndexSpace($parentPath, $referenceIndex);
                    $referenceIndex = $referenceNode->getIndex();
                    $nextLowerIndex = $this->findNextLowerIndex($parentPath, $referenceIndex);
                    if ($nextLowerIndex === null) {
                        $newIndex = (integer)round($referenceIndex / 2);
                    } else {
                        $newIndex = (integer)round($nextLowerIndex + (($referenceIndex - $nextLowerIndex) / 2));
                    }
                }
                break;
            case self::POSITION_AFTER:
                if ($referenceNode === null) {
                    throw new \InvalidArgumentException('The reference node must be specified for POSITION_AFTER.', 1317198858);
                }
                $referenceIndex = $referenceNode->getIndex();
                $nextHigherIndex = $this->findNextHigherIndex($parentPath, $referenceIndex);
                if ($nextHigherIndex === null) {
                    // $referenceNode is last node, so we can safely add an index at the end by incrementing the reference index.
                    $newIndex = $referenceIndex + 100;
                    $this->setHighestIndexInParentPath($parentPath, $newIndex);
                } elseif ($nextHigherIndex > ($referenceIndex + 1)) {
                    // $referenceNode is not last node, but there is free space left between $referenceNode and following sibling.
                    $newIndex = (integer)round($referenceIndex + (($nextHigherIndex - $referenceIndex) / 2));
                } else {
                    // $referenceNode is not last node, and no free space is left -> we have to make room after the reference node!
                    $this->openIndexSpace($parentPath, $referenceIndex + 1);
                    $nextHigherIndex = $this->findNextHigherIndex($parentPath, $referenceIndex);
                    if ($nextHigherIndex === null) {
                        $newIndex = $referenceIndex + 100;
                        $this->setHighestIndexInParentPath($parentPath, $newIndex);
                    } else {
                        $newIndex = (integer)round($referenceIndex + (($nextHigherIndex - $referenceIndex) / 2));
                    }
                }
                break;
            case self::POSITION_LAST:
                $nextFreeIndex = $this->findNextFreeIndexInParentPath($parentPath);
                $newIndex = $nextFreeIndex;
                break;
            default:
                throw new \InvalidArgumentException('Invalid position for new node index given.', 1329729088);
        }

        $node->setIndex($newIndex);
    }
public function setNewIndex(NodeData $node, $position, NodeInterface $referenceNode = null)
    {
        $parentPath = $node->getParentPath();

        switch ($position) {
            case self::POSITION_BEFORE:
                if ($referenceNode === null) {
                    throw new \InvalidArgumentException('The reference node must be specified for POSITION_BEFORE.', 1317198857);
                }
                $referenceIndex = $referenceNode->getIndex();
                $nextLowerIndex = $this->findNextLowerIndex($parentPath, $referenceIndex);
                if ($nextLowerIndex === null) {
                    // FIXME: $nextLowerIndex returns 0 and not NULL in case no lower index is found. So this case seems to be
                    // never executed. We need to check that again!
                    $newIndex = (integer)round($referenceIndex / 2);
                } elseif ($nextLowerIndex < ($referenceIndex - 1)) {
                    // there is free space left between $referenceNode and preceding sibling.
                    $newIndex = (integer)round($nextLowerIndex + (($referenceIndex - $nextLowerIndex) / 2));
                } else {
                    // there is no free space left between $referenceNode and following sibling -> we have to make room!
                    $this->openIndexSpace($parentPath, $referenceIndex);
                    $referenceIndex = $referenceNode->getIndex();
                    $nextLowerIndex = $this->findNextLowerIndex($parentPath, $referenceIndex);
                    if ($nextLowerIndex === null) {
                        $newIndex = (integer)round($referenceIndex / 2);
                    } else {
                        $newIndex = (integer)round($nextLowerIndex + (($referenceIndex - $nextLowerIndex) / 2));
                    }
                }
                break;
            case self::POSITION_AFTER:
                if ($referenceNode === null) {
                    throw new \InvalidArgumentException('The reference node must be specified for POSITION_AFTER.', 1317198858);
                }
                $referenceIndex = $referenceNode->getIndex();
                $nextHigherIndex = $this->findNextHigherIndex($parentPath, $referenceIndex);
                if ($nextHigherIndex === null) {
                    // $referenceNode is last node, so we can safely add an index at the end by incrementing the reference index.
                    $newIndex = $referenceIndex + 100;
                    $this->setHighestIndexInParentPath($parentPath, $newIndex);
                } elseif ($nextHigherIndex > ($referenceIndex + 1)) {
                    // $referenceNode is not last node, but there is free space left between $referenceNode and following sibling.
                    $newIndex = (integer)round($referenceIndex + (($nextHigherIndex - $referenceIndex) / 2));
                } else {
                    // $referenceNode is not last node, and no free space is left -> we have to make room after the reference node!
                    $this->openIndexSpace($parentPath, $referenceIndex + 1);
                    $nextHigherIndex = $this->findNextHigherIndex($parentPath, $referenceIndex);
                    if ($nextHigherIndex === null) {
                        $newIndex = $referenceIndex + 100;
                        $this->setHighestIndexInParentPath($parentPath, $newIndex);
                    } else {
                        $newIndex = (integer)round($referenceIndex + (($nextHigherIndex - $referenceIndex) / 2));
                    }
                }
                break;
            case self::POSITION_LAST:
                $nextFreeIndex = $this->findNextFreeIndexInParentPath($parentPath);
                $newIndex = $nextFreeIndex;
                break;
            default:
                throw new \InvalidArgumentException('Invalid position for new node index given.', 1329729088);
        }

        $node->setIndex($newIndex);
    }
public function setNewIndex ( NodeData $ node , $ position , NodeInterface $ referenceNode = null ) { $ parentPath = $ node -> getParentPath ( ) ; switch ( $ position ) { case self :: POSITION_BEFORE : if ( $ referenceNode === null ) { throw new \ InvalidArgumentException ( 'The reference node must be specified for POSITION_BEFORE.' , 1317198857 ) ; } $ referenceIndex = $ referenceNode -> getIndex ( ) ; $ nextLowerIndex = $ this -> findNextLowerIndex ( $ parentPath , $ referenceIndex ) ; if ( $ nextLowerIndex === null ) { // FIXME: $nextLowerIndex returns 0 and not NULL in case no lower index is found. So this case seems to be // never executed. We need to check that again! $ newIndex = ( integer ) round ( $ referenceIndex / 2 ) ; } elseif ( $ nextLowerIndex < ( $ referenceIndex - 1 ) ) { // there is free space left between $referenceNode and preceding sibling. $ newIndex = ( integer ) round ( $ nextLowerIndex + ( ( $ referenceIndex - $ nextLowerIndex ) / 2 ) ) ; } else { // there is no free space left between $referenceNode and following sibling -> we have to make room! $ this -> openIndexSpace ( $ parentPath , $ referenceIndex ) ; $ referenceIndex = $ referenceNode -> getIndex ( ) ; $ nextLowerIndex = $ this -> findNextLowerIndex ( $ parentPath , $ referenceIndex ) ; if ( $ nextLowerIndex === null ) { $ newIndex = ( integer ) round ( $ referenceIndex / 2 ) ; } else { $ newIndex = ( integer ) round ( $ nextLowerIndex + ( ( $ referenceIndex - $ nextLowerIndex ) / 2 ) ) ; } } break ; case self :: POSITION_AFTER : if ( $ referenceNode === null ) { throw new \ InvalidArgumentException ( 'The reference node must be specified for POSITION_AFTER.' , 1317198858 ) ; } $ referenceIndex = $ referenceNode -> getIndex ( ) ; $ nextHigherIndex = $ this -> findNextHigherIndex ( $ parentPath , $ referenceIndex ) ; if ( $ nextHigherIndex === null ) { // $referenceNode is last node, so we can safely add an index at the end by incrementing the reference index. $ newIndex = $ referenceIndex + 100 ; $ this -> setHighestIndexInParentPath ( $ parentPath , $ newIndex ) ; } elseif ( $ nextHigherIndex > ( $ referenceIndex + 1 ) ) { // $referenceNode is not last node, but there is free space left between $referenceNode and following sibling. $ newIndex = ( integer ) round ( $ referenceIndex + ( ( $ nextHigherIndex - $ referenceIndex ) / 2 ) ) ; } else { // $referenceNode is not last node, and no free space is left -> we have to make room after the reference node! $ this -> openIndexSpace ( $ parentPath , $ referenceIndex + 1 ) ; $ nextHigherIndex = $ this -> findNextHigherIndex ( $ parentPath , $ referenceIndex ) ; if ( $ nextHigherIndex === null ) { $ newIndex = $ referenceIndex + 100 ; $ this -> setHighestIndexInParentPath ( $ parentPath , $ newIndex ) ; } else { $ newIndex = ( integer ) round ( $ referenceIndex + ( ( $ nextHigherIndex - $ referenceIndex ) / 2 ) ) ; } } break ; case self :: POSITION_LAST : $ nextFreeIndex = $ this -> findNextFreeIndexInParentPath ( $ parentPath ) ; $ newIndex = $ nextFreeIndex ; break ; default : throw new \ InvalidArgumentException ( 'Invalid position for new node index given.' , 1329729088 ) ; } $ node -> setIndex ( $ newIndex ) ; }
Assigns an index to the given node which reflects the specified position.
If the position is "before" or "after", an index will be chosen which makes
the given node the previous or next node of the given reference node.
If the position "last" is specified, an index higher than any existing index
will be chosen.

If no free index is available between two nodes (for "before" and "after"),
the whole index of the current node level will be renumbered.

@param NodeData $node The node to set the new index for
@param integer $position The position the new index should reflect, must be one of the POSITION_* constants
@param NodeInterface $referenceNode The reference node. Mandatory for POSITION_BEFORE and POSITION_AFTER
@return void
@throws \InvalidArgumentException
Assigns an index to the given node which reflects the specified position . If the position is before or after an index will be chosen which makes the given node the previous or next node of the given reference node . If the position last is specified an index higher than any existing index will be chosen .