xref: /plugin/combo/ComboStrap/PathTreeNode.php (revision 70bbd7f1f72440223cc13f3495efdcb2b0a11514)
104fd306cSNickeau<?php
204fd306cSNickeau
304fd306cSNickeaunamespace ComboStrap;
404fd306cSNickeau
504fd306cSNickeauclass PathTreeNode extends TreeNode
604fd306cSNickeau{
704fd306cSNickeau
804fd306cSNickeau
904fd306cSNickeau    const CANONICAL = "path-tree";
1004fd306cSNickeau
1104fd306cSNickeau    private Path $path;
1204fd306cSNickeau
1304fd306cSNickeau    public function __construct(?Path $path)
1404fd306cSNickeau    {
1504fd306cSNickeau        $this->path = $path;
1604fd306cSNickeau    }
1704fd306cSNickeau
1804fd306cSNickeau    /**
1904fd306cSNickeau     * Build the tree from the file systems with the {@link FileSystems::getChildren()}
2004fd306cSNickeau     * function
2104fd306cSNickeau     */
2204fd306cSNickeau    public static function buildTreeViaFileSystemChildren(Path $rootSpace = null): PathTreeNode
2304fd306cSNickeau    {
2404fd306cSNickeau        $root = PathTreeNode::createPathTreeNodeFromPath($rootSpace);
2504fd306cSNickeau        self::buildTreeFromFileSystemRecursively($root);
2604fd306cSNickeau        return $root;
2704fd306cSNickeau    }
2804fd306cSNickeau
2904fd306cSNickeau    /**
3004fd306cSNickeau     * Build the tree from the file systems with the {@link FileSystems::getChildren()}
3104fd306cSNickeau     * function
3204fd306cSNickeau     *
3304fd306cSNickeau     * @param PathTreeNode $parentPathTreeNode
3404fd306cSNickeau     * @return void
3504fd306cSNickeau     */
3604fd306cSNickeau    public static function buildTreeFromFileSystemRecursively(PathTreeNode $parentPathTreeNode)
3704fd306cSNickeau    {
3804fd306cSNickeau        $parentPath = $parentPathTreeNode->getPath();
3904fd306cSNickeau        $childrenPath = FileSystems::getChildren($parentPath);
4004fd306cSNickeau        foreach ($childrenPath as $childPath) {
4104fd306cSNickeau            $childTreeNode = PathTreeNode::createPathTreeNodeFromPath($childPath);
4204fd306cSNickeau            try {
4304fd306cSNickeau                $parentPathTreeNode->appendChild($childTreeNode);
4404fd306cSNickeau            } catch (ExceptionBadState $e) {
4504fd306cSNickeau                throw new ExceptionRuntimeInternal("We shouldn't add the node two times. ", self::CANONICAL, 1, $e);
4604fd306cSNickeau            }
4704fd306cSNickeau            if (FileSystems::isDirectory($childPath)) {
4804fd306cSNickeau                self::buildTreeFromFileSystemRecursively($childTreeNode);
4904fd306cSNickeau            }
5004fd306cSNickeau        }
5104fd306cSNickeau    }
5204fd306cSNickeau
5304fd306cSNickeau
5404fd306cSNickeau    private static function createPathTreeNodeFromPath(Path $path): PathTreeNode
5504fd306cSNickeau    {
5604fd306cSNickeau        return new PathTreeNode($path);
5704fd306cSNickeau    }
5804fd306cSNickeau
5904fd306cSNickeau    /**
6004fd306cSNickeau     * Build the tree from a array of ids. The build is done via the {@link Path::getParent()}
6104fd306cSNickeau     * @param array $ids
6204fd306cSNickeau     * @return TreeNode
6304fd306cSNickeau     */
6404fd306cSNickeau    public static function buildTreeViaParentPath(array $ids): TreeNode
6504fd306cSNickeau    {
6604fd306cSNickeau
6704fd306cSNickeau        $rootNode = null;
6804fd306cSNickeau        /**
6904fd306cSNickeau         * @var PathTreeNode[]
7004fd306cSNickeau         */
7104fd306cSNickeau        $nodeByIds = [];
7204fd306cSNickeau        foreach ($ids as $id) {
7304fd306cSNickeau            $path = WikiPath::createMarkupPathFromId($id);
74*70bbd7f1Sgerardnico            $actualNode = $nodeByIds[$path->getWikiId()] ?? null;
7504fd306cSNickeau            if ($actualNode === null) {
7604fd306cSNickeau                $actualNode = PathTreeNode::createPathTreeNodeFromPath($path);
7704fd306cSNickeau                $nodeByIds[$path->getWikiId()] = $actualNode;
7804fd306cSNickeau            }
7904fd306cSNickeau            while (true) {
8004fd306cSNickeau                try {
8104fd306cSNickeau                    /**
8204fd306cSNickeau                     * @var WikiPath $parentPath
8304fd306cSNickeau                     */
8404fd306cSNickeau                    $parentPath = $actualNode->getPath()->getParent();
85*70bbd7f1Sgerardnico                    $parentPathNode = $nodeByIds[$parentPath->getWikiId()] ?? null;
8604fd306cSNickeau                    if ($parentPathNode === null) {
8704fd306cSNickeau                        $parentPathNode = PathTreeNode::createPathTreeNodeFromPath($parentPath);
8804fd306cSNickeau                        $nodeByIds[$parentPath->getWikiId()] = $parentPathNode;
8904fd306cSNickeau                    }
9004fd306cSNickeau                    $parentPathNode->appendChild($actualNode);
9104fd306cSNickeau
9204fd306cSNickeau                    // Loop
9304fd306cSNickeau                    $actualNode = $parentPathNode;
9404fd306cSNickeau                } catch (ExceptionNotFound $e) {
9504fd306cSNickeau                    break;
9604fd306cSNickeau                }
9704fd306cSNickeau            }
9804fd306cSNickeau            if ($rootNode === null) {
9904fd306cSNickeau                $rootNode = $actualNode;
10004fd306cSNickeau            }
10104fd306cSNickeau
10204fd306cSNickeau        }
10304fd306cSNickeau        return $rootNode;
10404fd306cSNickeau    }
10504fd306cSNickeau
10604fd306cSNickeau    public function getPath(): Path
10704fd306cSNickeau    {
10804fd306cSNickeau        return $this->path;
10904fd306cSNickeau    }
11004fd306cSNickeau
11104fd306cSNickeau    function getTreeIdentifier(): string
11204fd306cSNickeau    {
11304fd306cSNickeau        return $this->path->toAbsoluteId();
11404fd306cSNickeau    }
11504fd306cSNickeau
11604fd306cSNickeau
11704fd306cSNickeau}
118