Пример #1
0
 /**
  * Moves the given item to another location
  *
  * @param string      $id        The id or alias of the layout item to be moved
  * @param string|null $parentId  The id or alias of a parent item the specified item is moved to
  *                               If this parameter is null only the order of the item is changed
  * @param string|null $siblingId The id or alias of an item which should be nearest neighbor
  * @param bool        $prepend   Determines whether the moving item should be located before or after
  *                               the specified sibling item
  *
  * @throws Exception\InvalidArgumentException if the id is empty
  * @throws Exception\ItemNotFoundException if the layout item, parent item or sibling item does not exist
  * @throws Exception\LogicException if the layout item cannot be moved by other reasons
  *
  * @SuppressWarnings(PHPMD.NPathComplexity)
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  */
 public function move($id, $parentId = null, $siblingId = null, $prepend = false)
 {
     $id = $this->validateAndResolveId($id);
     if ($parentId) {
         $parentId = $this->resolveId($parentId);
         if (!isset($this->items[$parentId])) {
             throw new Exception\ItemNotFoundException(sprintf('The "%s" parent item does not exist.', $parentId));
         }
         if ($parentId === $id) {
             throw new Exception\LogicException('The parent item cannot be the same as the moving item.');
         }
     }
     if ($siblingId) {
         $siblingId = $this->resolveId($siblingId);
         if (!isset($this->items[$siblingId])) {
             throw new Exception\ItemNotFoundException(sprintf('The "%s" sibling item does not exist.', $siblingId));
         }
         if ($siblingId === $id) {
             throw new Exception\LogicException('The sibling item cannot be the same as the moving item.');
         }
     }
     if (!$parentId && !$siblingId) {
         throw new Exception\LogicException('At least one parent or sibling item must be specified.');
     }
     $path = $this->items[$id][self::PATH];
     if (!$parentId) {
         $parentPath = array_slice($path, 0, -1);
     } else {
         if ($siblingId && $siblingId === $parentId) {
             throw new Exception\LogicException('The sibling item cannot be the same as the parent item.');
         }
         $parentPath = $this->items[$parentId][self::PATH];
         if (strpos(implode('/', $parentPath) . '/', implode('/', $path) . '/') === 0) {
             throw new Exception\LogicException(sprintf('The parent item (path: %s) cannot be a child of the moving item (path: %s).', implode('/', $parentPath), implode('/', $path)));
         }
     }
     // update hierarchy
     $hierarchy = $this->hierarchy->get($path);
     $this->hierarchy->remove($path);
     $this->hierarchy->add($parentPath, $id, $siblingId, $prepend, $hierarchy);
     if ($parentId) {
         // build the new path
         $newPath = $parentPath;
         $newPath[] = $id;
         // update the path of the moving item
         $this->items[$id][self::PATH] = $newPath;
         // update the path for all children
         $prevPathLength = count($path);
         $iterator = $this->getHierarchyIterator($id);
         foreach ($iterator as $childId) {
             $this->items[$childId][self::PATH] = array_merge($newPath, array_slice($this->items[$childId][self::PATH], $prevPathLength));
         }
     }
 }