fork(1) download
  1. <?php
  2. class TreeElement
  3. {
  4. protected $nodeName;
  5. protected $childNodes=[];
  6. protected $parentNode;
  7.  
  8.  
  9. public function __construct($nodeName){
  10. $this->nodeName = $nodeName;
  11. }
  12.  
  13. public function getNodeName(){
  14. return $this->nodeName;
  15. }
  16.  
  17. public function findDescendant($name){
  18. foreach($this->childNodes as $child){
  19. if($child->getNodeName()==$name){
  20. return $child;
  21. }
  22. else{
  23. $desc = $child->findDescendant($name);
  24. if($desc && $desc->getNodeName()==$name){
  25. return $desc;
  26. }
  27. }
  28. }
  29. return null;
  30. }
  31.  
  32. public function countChildNodes(){
  33. return count($this->childNodes);
  34. }
  35.  
  36. public function countDescendants(){
  37. $descCount = 0;
  38. foreach ($this->childNodes as $child) {
  39. $descCount++;
  40. $descCount+= $child->countDescendants();
  41. }
  42. return $descCount;
  43. }
  44.  
  45.  
  46. public function addChild(TreeElement $child){
  47. if($this->getRootElement()->findDescendant($child->getNodeName())){
  48. return false;
  49.  
  50. }
  51. $this->childNodes[] = $child;
  52. $child->setParentNode($this);
  53. }
  54.  
  55. public function removeChild($node){
  56. foreach ($this->childNodes as $key => $child) {
  57. if($child === $node){
  58. unset($this->childNodes[$key]);
  59. }
  60. }
  61. }
  62.  
  63. public function isRoot(){
  64. if(!$this->parentNode){
  65. return true;
  66. }
  67. return false;
  68. }
  69.  
  70. public function getRootElement(){
  71. $currentNode = $this;
  72. while (!$currentNode->isRoot()){
  73. $currentNode = $currentNode->parentNode;
  74. };
  75. return $currentNode;
  76. }
  77.  
  78. public function getDepth(){
  79. $depth = 0;
  80. if($this->parentNode){
  81. $depth++;
  82. $depth+= $this->parentNode->getDepth();
  83. }
  84. return $depth;
  85. }
  86.  
  87. public function getChildNodes(){
  88. return $this->childNodes;
  89. }
  90.  
  91. public function setChildNodes($newNodes){
  92. $this->childNodes = [];
  93. foreach ($newNodes as $child) {
  94. $this->addChild($child);
  95. }
  96. }
  97.  
  98. public function getParentNode(){
  99. return $this->parentNode;
  100. }
  101.  
  102. public function setParentNode($node){
  103. $this->parentNode = $node;
  104. }
  105.  
  106. public function isDescendant($node){
  107. if($node->isAncestor($this)){
  108. return true;
  109. }
  110. return false;
  111. }
  112.  
  113. public function isAncestor($node){
  114. foreach ($this->childNodes as $child) {
  115. if($node===$child){
  116. return true;
  117. }
  118. elseif($child->isAncestor($node)){
  119. return true;
  120. }
  121. }
  122. return false;
  123. }
  124.  
  125. public function getNextSibling(){
  126. $parent = $this->parentNode;
  127. if(!$parent){
  128. return false;
  129. }
  130. $previous = NULL;
  131. foreach ($parent->getChildNodes() as $child) {
  132. if($previous==$this){
  133. return $child;
  134. }
  135. $previous = $child;
  136. }
  137. return false;
  138. }
  139.  
  140. public function getPreviousSibling(){
  141. $parent = $this->parentNode;
  142. $previous = NULL;
  143. if(!$parent){
  144. return false;
  145. }
  146. foreach ($parent->getChildNodes() as $child) {
  147. if($this == $child){
  148. return $previous;
  149. }
  150. $previous = $child;
  151. }
  152. return false;
  153. }
  154.  
  155. public function moveSibling($n){
  156. $parent = $this->parentNode;
  157. if(!$parent){
  158. return false;
  159. }
  160. $children = $parent->getChildNodes();
  161. foreach ($children as $key => $child) {
  162. if($child===$this){
  163. $element = array_splice($children, $key, 1);
  164. array_splice($children, $n, 0, $element);
  165. break;
  166. }
  167. }
  168. $parent->setChildNodes($children);
  169. }
  170.  
  171. public function moveNode($parent){
  172. if(!$this->parentNode){
  173. return false;
  174. }
  175. $this->parentNode->removeChild($this);
  176. $parent->addChild($this);
  177. }
  178.  
  179. public function displayAsCatalog(){
  180. $children = "";
  181. $depth = "";
  182. if($this->countDescendants()>0){
  183. $children = " (".$this->countDescendants().") ";
  184. }
  185.  
  186. for($i = 0; $i<$this->getDepth();$i++){
  187. $depth.="...";
  188. }
  189. echo $depth.$this->nodeName.$children."\n";
  190. foreach ($this->childNodes as $child) {
  191. $child->displayAsCatalog();
  192. }
  193. }
  194. }
  195.  
  196.  
  197. $tech = new TreeElement("Бытовая техника");
  198. $tech->addChild(new TreeElement('Телевизоры'));
  199. $televisors = $tech->findDescendant('Телевизоры');
  200. $televisors->addChild(new TreeElement('LCD-телевизоры'));
  201. $televisors->addChild(new TreeElement('Плазменные'));
  202. $tech->addChild(new TreeElement('Холодильники'));
  203. $refrigirators = $tech->findDescendant('Холодильники');
  204. $refrigirators->addChild(new TreeElement('Маленькие'));
  205. $refrigirators->addChild(new TreeElement('Средние'));
  206. $refrigirators->addChild(new TreeElement('Большие'));
  207. $tech->displayAsCatalog();
Success #stdin #stdout 0.02s 52472KB
stdin
Standard input is empty
stdout
Бытовая техника (7) 
...Телевизоры (2) 
......LCD-телевизоры
......Плазменные
...Холодильники (3) 
......Маленькие
......Средние
......Большие