Neos\ContentRepository\Domain\Repository\NodeDataRepository::setNewIndex PHP Метод

setNewIndex() публичный Метод

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.
public setNewIndex ( NodeData $node, integer $position, Neos\ContentRepository\Domain\Model\NodeInterface $referenceNode = null ) : void
$node Neos\ContentRepository\Domain\Model\NodeData The node to set the new index for
$position integer The position the new index should reflect, must be one of the POSITION_* constants
$referenceNode Neos\ContentRepository\Domain\Model\NodeInterface The reference node. Mandatory for POSITION_BEFORE and POSITION_AFTER
Результат void
    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 = (int) round($referenceIndex / 2);
                } elseif ($nextLowerIndex < $referenceIndex - 1) {
                    // there is free space left between $referenceNode and preceding sibling.
                    $newIndex = (int) 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 = (int) round($referenceIndex / 2);
                    } else {
                        $newIndex = (int) 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 = (int) 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 = (int) 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);
    }

Usage Example

Пример #1
0
 /**
  * Moves this node into the given node
  *
  * @param NodeInterface $referenceNode
  * @param string $newName
  * @throws NodeConstraintException
  * @throws NodeException
  * @throws NodeExistsException
  * @api
  */
 public function moveInto(NodeInterface $referenceNode, $newName = null)
 {
     if ($referenceNode === $this || $referenceNode === $this->getParent()) {
         return;
     }
     if ($this->getPath() === '/') {
         throw new NodeException('The root node cannot be moved.', 1346769001);
     }
     if ($referenceNode !== $this->getParent() && $referenceNode->getNode($this->getName()) !== null) {
         throw new NodeExistsException('Node with path "' . $this->getName() . '" already exists.', 1292503470);
     }
     if (!$referenceNode->willChildNodeBeAutoCreated($this->getName()) && !$referenceNode->isNodeTypeAllowedAsChildNode($this->getNodeType())) {
         throw new NodeConstraintException('Cannot move ' . $this->__toString() . ' into ' . $referenceNode->__toString(), 1404648124);
     }
     $name = $newName !== null ? $newName : $this->getName();
     $this->emitBeforeNodeMove($this, $referenceNode, NodeDataRepository::POSITION_LAST);
     $this->setPath(NodePaths::addNodePathSegment($referenceNode->getPath(), $name));
     $this->nodeDataRepository->persistEntities();
     $this->nodeDataRepository->setNewIndex($this->nodeData, NodeDataRepository::POSITION_LAST);
     $this->context->getFirstLevelNodeCache()->flush();
     $this->emitAfterNodeMove($this, $referenceNode, NodeDataRepository::POSITION_LAST);
     $this->emitNodeUpdated($this);
 }