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