Buduje drzewo rekurencyjnie
@param array $tree
@param array $parents
@param array $orderedCategories
@param CmsCategoryRecord|null $parentCategory
509122
private function _buildTree(array &$tree, array $parents, array $orderedCategories, CmsCategoryRecord $parentCategory = null)
    {
        //uzupełnienie rodziców
        if ($parentCategory !== null) {
            $parents[$parentCategory->id] = $parentCategory;
        } else {
            $parentCategory = new CmsCategoryRecord;
            $parentCategory->id = null;
        }
        /* @var $categoryRecord CmsCategoryRecord */
        foreach ($orderedCategories as $key => $categoryRecord) {
            //niezgodny rodzic
            if ($categoryRecord->parentId != $parentCategory->id) {
                continue;
            }
            //dodawanie do płaskiej listy
            $this->_flatCategories[$categoryRecord->id] = $categoryRecord;
            //usuwanie wykorzystanego rekordu kategorii
            unset($orderedCategories[$key]);
            //zapis do drzewa
            $tree[$categoryRecord->id] = [];
            $tree[$categoryRecord->id]['record'] = $categoryRecord->setOption('parents', $parents);
            $tree[$categoryRecord->id]['children'] = [];
            //zejście rekurencyjne do dzieci
            $this->_buildTree($tree[$categoryRecord->id]['children'], $parents, $orderedCategories, $categoryRecord);
        }
    }
623102
private function _redirectAfterEdit(\Cms\Orm\CmsCategoryRecord $category)
    {
        //referer
        $referer = $this->_getReferrer();
        //jeśli istnieje referer
        if ($referer) {
            $this->getResponse()->redirectToUrl($referer);
        }
        //przekierowanie na stronę frontową kategorii jeśli wskazana
        if ($category) {
            $this->getResponse()->redirectToUrl($category->getUrl());
        }
        $this->getResponse()->redirect('cmsAdmin', 'category', 'tree');
    }
1191344
protected function _rebuildChildren($parentId)
    {
        $i = 0;
        //iteracja po dzieciach
        foreach ($this->_getChildren($parentId) as $categoryRecord) {
            //wyznaczanie kolejności
            $categoryRecord->order = $i++;
            $categoryRecord->setOption('block-ordering', true);
            //zapis dziecka
            $categoryRecord->save();
            //zejście rekurencyjne
            $this->_rebuildChildren($categoryRecord->id);
        }
    }
696899
public function getRoot($parentNodeCategory = null, $recursionLevel = 3)
    {
        if ($parentNodeCategory === null) {
            if ($this->getCurrentCategoryId()) {
                $this->getRootByIds([$this->getCurrentCategoryId()]);
            }
        }

        return parent::getRoot($parentNodeCategory, $recursionLevel);
    }
231930
function getTree($gets,$category='fid',$order='id desc')
	{
		$gets['order'] = $category . ',' . $order;
		$list = $this->gets($gets);
		foreach ($list as $li)
		{
			if ($li[$category] == 0)
			{
				$new[$li[$this->primary]] = $li;
			}
			else
			{
				$new[$li[$category]]['child'][$li[$this->primary]] = $li;
			}
		}
		return $new;
	}
1127928
public function getParentClasses(string $class, array $parents = [])
    {
        $strParent = get_parent_class($class);

        if ($strParent) {
            $parents[] = $strParent;

            $parents = $this->getParentClasses($strParent, $parents);
        }

        return $parents;
    }
799129
protected function createNavItems(array $treeItems, NavItem $parent = null)
    {
        /** @var NavItem[] $navItems */
        $navItems = [];

        foreach ($treeItems as $treeItem) {
            if ($treeItem->isAsset) {
                continue;
            }

            $nav = $this->createNavItem($treeItem, $parent);
            if ($nav === null) {
                continue;
            }

            if (!isset($navItems[$nav->relUrl]) || !$navItems[$nav->relUrl]->children) {
                $navItems[$nav->relUrl] = $nav;
            }
        }

        return array_values($navItems);
    }
563195
protected function _getChildren($parentId, $activeOnly = false)
    {
        //inicjalizacja zapytania
        $query = (new CmsCategoryQuery)
            ->whereParentId()->equals($parentId)
            ->joinLeft('cms_category_type')->on('cms_category_type_id')
            ->orderAscOrder()
            ->orderAscId();
        //tylko aktywne
        if ($activeOnly) {
            $query->whereStatus()->equals(self::STATUS_ACTIVE);
        }
        //zwrot w postaci tablicy rekordów
        return $query->find()->toObjectArray();
    }
1040896
protected function sortChildrenByPosition($parent, $childrenPropertyPath)
    {
        $collection = $this->getPropertyAccessor()->getValue($parent, $childrenPropertyPath);

        if ($collection instanceOf PersistentCollection) {
            /** @var PersistentCollection $collection */
            if (false === $collection->isInitialized()) {
                $collection->initialize();
            }
            $collection = $collection->unwrap();
        }

        if (!$collection instanceOf ArrayCollection) {
            throw new \InvalidArgumentException('Expected ArrayCollection.');
        }

        /** @var ArrayCollection $collection */
        $iterator = $collection->getIterator();
        $iterator->uasort(function (SortableInterface $a, SortableInterface $b) {
            return
                ($a->getPosition() == $b->getPosition()) ? 0 :
                    ($a->getPosition() < $b->getPosition()) ? -1 : 1;
        });

        $collection->clear();
        foreach ($iterator as $key => $item) {
            $collection->set($key, $item);
        }
    }
461703
protected function _reOrder($parent_id, $left, array $order = []) {
        $parent = $this->getConfig('parentField');
        $repo = $this->getRepository();
        $pk = $repo->getPrimaryKey();
        $right = $left + 1;

        // Get children and sort
        $children = $repo->select()
            ->where($parent, $parent_id)
            ->orderBy($order)
            ->all();

        foreach ($children as $child) {
            $right = $this->_reOrder($child[$pk], $right, $order);
        }

        // Update parent node
        if ($parent_id) {
            $this->_moveNode(function(Query $query) use ($pk, $parent_id) {
                $query->where($pk, $parent_id);
            }, [
                $this->getConfig('leftField') => $left,
                $this->getConfig('rightField') => $right
            ]);
        }

        return $right + 1;
    }
720764
private function _setupActive(&$tree, $params)
    {
        //domyślnie zakładamy, że gałąź jest nieaktywna
        $branchActive = false;
        //iteracja po drzewie
        foreach ($tree as $key => $item) {
            //aktywność tylko jeśli istnieje request
            if (true === $active = isset($item['request'])) {
                //iteracja po requescie w danym itemie
                foreach ($item['request'] as $name => $param) {
                    //jeśli brak zmiennej w parametrach, lub różne
                    if (!isset($params[$name]) || $params[$name] != $param) {
                        //nieaktywny
                        $active = false;
                        break;
                    }
                }
            }
            $tree[$key]['active'] = $active;
            //jeśli aktywny - ustawiamy aktywność gałęzi, jeśli nie - bez zmian
            $branchActive = $active ? true : $branchActive;
            //jeśli element posiada dzieci
            if (isset($item['children'])) {
                //zejście rekurencyjne
                $branch = $this->_setupActive($item['children'], $params);
                $tree[$key]['children'] = $branch['tree'];
                //jeśli gałąź aktywna - aktywacja, jeśli nie - bez zmian
                $tree[$key]['active'] = $branch['active'] ? true : $tree[$key]['active'];
            }
            //optymalizacja wydajności
            if ($tree[$key]['active']) {
                unset($item['children']);
                $branchActive = true;
            }
        }
        //zwrot gałęzi z określeniem czy aktywna
        return ['tree' => $tree, 'active' => $branchActive];
    }
103721
private function _buildFlatTree($prefix, array &$flatTree, array $categories, $categoryTypeKey)
    {
        //iteracja po kategoriach
        foreach ($categories as $id => $leaf) {
            if (null === $categoryTypeKey || $leaf['record']->getJoined('cms_category_type')->key === $categoryTypeKey) {
                //dodanie rekordu z prefixem i nazwą
                $flatTree[$id] = ltrim($prefix . ' > ' . $leaf['record']->name, ' >');
            }
            //zejście rekurencyjne
            $this->_buildFlatTree($prefix . ' > ' . $leaf['record']->name, $flatTree, $leaf['children'], $categoryTypeKey);
        }
    }
1045118
public function setParentInstance(SiteTree $parent)
    {
        $this->parentInstance = $parent;
        
        $this->setStyleIDFrom($parent);
        
        return $this;
    }
993895
public function initializeNode($parentId, $language, $siteId, $order = 0)
    {
        /** @var NodeInterface $node */
        $node = new $this->nodeClass();
        $node->setSiteId($siteId);
        $node->setLanguage($language);
        $node->setMaxAge(NodeInterface::MAX_AGE);
        $node->setParentId($parentId);
        $node->setOrder($order);
        $node->setVersion($this->uniqueIdGenerator->generateUniqueId());
        $node->setCreatedBy($this->tokenStorage->getToken()->getUser()->getUsername());

        $parentNode = $this->nodeRepository->findInLastVersion($parentId, $language, $siteId);
        $status = $this->statusRepository->findOneByInitial();
        $node->setStatus($status);
        $nodeType = NodeInterface::TYPE_DEFAULT;
        if ($parentNode instanceof NodeInterface) {
            $nodeType = $parentNode->getNodeType();
            $node->setPath($parentNode->getPath());
        } else {
            $node->setNodeId(NodeInterface::ROOT_NODE_ID);
        }
        $node->setNodeType($nodeType);

        return $node;
    }
1158778
public void setParents(java.util.Collection<String> parents) {
        if (parents == null) {
            this.parents = null;
            return;
        }

        this.parents = new java.util.ArrayList<String>(parents);
    }
523915
private function buildTree(?string $parentId, array $categories): array
    {
        $mapped = [];
        foreach ($categories as $key => $category) {
            if ($category->getParentId() !== $parentId) {
                continue;
            }

            unset($categories[$key]);

            $item = clone $this->treeItem;
            $item->setCategory($category);
            $item->setChildren(
                $this->buildTree($category->getId(), $categories)
            );

            $mapped[$category->getId()] = $item;
        }

        return $mapped;
    }
350881
protected function insertParents($entity, array $path, array $parents)
    {
        $propertyName = reset($path);
        $propertyValue = Core::get()->getObjectService()->getObjectProperty($entity, $propertyName);

        if (1 === count($path)) {
            if (is_object($propertyValue)
                && Core::get()->getParentsUtility()->classUsesParentsTrait($propertyValue)
            ) {
                /** @var ParentsTrait $propertyValue */
                $propertyValue->attachParents($this->filterParents($parents));
            }
        } else {
            if (is_object($propertyValue)) {
                $parents[] = $propertyValue;
            }

            array_shift($path);
            $this->insertParents($propertyValue, $path, $parents);
        }
    }