1*04fd306cSNickeau<?php 2*04fd306cSNickeau 3*04fd306cSNickeaunamespace ComboStrap; 4*04fd306cSNickeau 5*04fd306cSNickeauclass PathTreeNode extends TreeNode 6*04fd306cSNickeau{ 7*04fd306cSNickeau 8*04fd306cSNickeau 9*04fd306cSNickeau const CANONICAL = "path-tree"; 10*04fd306cSNickeau 11*04fd306cSNickeau private Path $path; 12*04fd306cSNickeau 13*04fd306cSNickeau public function __construct(?Path $path) 14*04fd306cSNickeau { 15*04fd306cSNickeau $this->path = $path; 16*04fd306cSNickeau } 17*04fd306cSNickeau 18*04fd306cSNickeau /** 19*04fd306cSNickeau * Build the tree from the file systems with the {@link FileSystems::getChildren()} 20*04fd306cSNickeau * function 21*04fd306cSNickeau */ 22*04fd306cSNickeau public static function buildTreeViaFileSystemChildren(Path $rootSpace = null): PathTreeNode 23*04fd306cSNickeau { 24*04fd306cSNickeau $root = PathTreeNode::createPathTreeNodeFromPath($rootSpace); 25*04fd306cSNickeau self::buildTreeFromFileSystemRecursively($root); 26*04fd306cSNickeau return $root; 27*04fd306cSNickeau } 28*04fd306cSNickeau 29*04fd306cSNickeau /** 30*04fd306cSNickeau * Build the tree from the file systems with the {@link FileSystems::getChildren()} 31*04fd306cSNickeau * function 32*04fd306cSNickeau * 33*04fd306cSNickeau * @param PathTreeNode $parentPathTreeNode 34*04fd306cSNickeau * @return void 35*04fd306cSNickeau */ 36*04fd306cSNickeau public static function buildTreeFromFileSystemRecursively(PathTreeNode $parentPathTreeNode) 37*04fd306cSNickeau { 38*04fd306cSNickeau $parentPath = $parentPathTreeNode->getPath(); 39*04fd306cSNickeau $childrenPath = FileSystems::getChildren($parentPath); 40*04fd306cSNickeau foreach ($childrenPath as $childPath) { 41*04fd306cSNickeau $childTreeNode = PathTreeNode::createPathTreeNodeFromPath($childPath); 42*04fd306cSNickeau try { 43*04fd306cSNickeau $parentPathTreeNode->appendChild($childTreeNode); 44*04fd306cSNickeau } catch (ExceptionBadState $e) { 45*04fd306cSNickeau throw new ExceptionRuntimeInternal("We shouldn't add the node two times. ", self::CANONICAL, 1, $e); 46*04fd306cSNickeau } 47*04fd306cSNickeau if (FileSystems::isDirectory($childPath)) { 48*04fd306cSNickeau self::buildTreeFromFileSystemRecursively($childTreeNode); 49*04fd306cSNickeau } 50*04fd306cSNickeau } 51*04fd306cSNickeau } 52*04fd306cSNickeau 53*04fd306cSNickeau 54*04fd306cSNickeau private static function createPathTreeNodeFromPath(Path $path): PathTreeNode 55*04fd306cSNickeau { 56*04fd306cSNickeau return new PathTreeNode($path); 57*04fd306cSNickeau } 58*04fd306cSNickeau 59*04fd306cSNickeau /** 60*04fd306cSNickeau * Build the tree from a array of ids. The build is done via the {@link Path::getParent()} 61*04fd306cSNickeau * @param array $ids 62*04fd306cSNickeau * @return TreeNode 63*04fd306cSNickeau */ 64*04fd306cSNickeau public static function buildTreeViaParentPath(array $ids): TreeNode 65*04fd306cSNickeau { 66*04fd306cSNickeau 67*04fd306cSNickeau $rootNode = null; 68*04fd306cSNickeau /** 69*04fd306cSNickeau * @var PathTreeNode[] 70*04fd306cSNickeau */ 71*04fd306cSNickeau $nodeByIds = []; 72*04fd306cSNickeau foreach ($ids as $id) { 73*04fd306cSNickeau $path = WikiPath::createMarkupPathFromId($id); 74*04fd306cSNickeau $actualNode = $nodeByIds[$path->getWikiId()]; 75*04fd306cSNickeau if ($actualNode === null) { 76*04fd306cSNickeau $actualNode = PathTreeNode::createPathTreeNodeFromPath($path); 77*04fd306cSNickeau $nodeByIds[$path->getWikiId()] = $actualNode; 78*04fd306cSNickeau } 79*04fd306cSNickeau while (true) { 80*04fd306cSNickeau try { 81*04fd306cSNickeau /** 82*04fd306cSNickeau * @var WikiPath $parentPath 83*04fd306cSNickeau */ 84*04fd306cSNickeau $parentPath = $actualNode->getPath()->getParent(); 85*04fd306cSNickeau $parentPathNode = $nodeByIds[$parentPath->getWikiId()]; 86*04fd306cSNickeau if ($parentPathNode === null) { 87*04fd306cSNickeau $parentPathNode = PathTreeNode::createPathTreeNodeFromPath($parentPath); 88*04fd306cSNickeau $nodeByIds[$parentPath->getWikiId()] = $parentPathNode; 89*04fd306cSNickeau } 90*04fd306cSNickeau $parentPathNode->appendChild($actualNode); 91*04fd306cSNickeau 92*04fd306cSNickeau // Loop 93*04fd306cSNickeau $actualNode = $parentPathNode; 94*04fd306cSNickeau } catch (ExceptionNotFound $e) { 95*04fd306cSNickeau break; 96*04fd306cSNickeau } 97*04fd306cSNickeau } 98*04fd306cSNickeau if ($rootNode === null) { 99*04fd306cSNickeau $rootNode = $actualNode; 100*04fd306cSNickeau } 101*04fd306cSNickeau 102*04fd306cSNickeau } 103*04fd306cSNickeau return $rootNode; 104*04fd306cSNickeau } 105*04fd306cSNickeau 106*04fd306cSNickeau public function getPath(): Path 107*04fd306cSNickeau { 108*04fd306cSNickeau return $this->path; 109*04fd306cSNickeau } 110*04fd306cSNickeau 111*04fd306cSNickeau function getTreeIdentifier(): string 112*04fd306cSNickeau { 113*04fd306cSNickeau return $this->path->toAbsoluteId(); 114*04fd306cSNickeau } 115*04fd306cSNickeau 116*04fd306cSNickeau 117*04fd306cSNickeau} 118