Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- class Node implements \IteratorAggregate
- {
- public $id = 0;
- public $pid = 0;
- public $pos = 0;
- //public $data = null;
- protected $parent = null;
- protected $children = [];
- public function __construct($id, $pid, $pos, $data)
- {
- $this->id = $id;
- $this->pid = $pid;
- $this->pos = $pos;
- //$this->data = $data;
- }
- public static function createBranch(&$parents, $children)
- {
- $tree = array();
- foreach ($children as $child) {
- if (isset($parents[$child->id])) {
- $child->setChildren(self::createBranch($parents, $parents[$child->id]));
- }
- $tree[$child->id] = $child;
- }
- return $tree;
- }
- public static function createTreeObject(array $array, $rootID = 0, $fieldID = 'id', $fieldPID = 'pid', $fieldPos = 'pos')
- {
- $parents = array();
- foreach ($array as $element) {
- $node = new static($element->$fieldID, $element->$fieldPID, $element->$fieldPos, $element);
- $nodes[$node->id] = $node;
- $parents[$node->pid][$node->id] = $node;
- }
- if ($rootID > 0) {
- $root = $nodes[$rootID];
- } else {
- $root = new static(0, 0, 1, 0);
- }
- $root->setChildren(self::createBranch($parents, $parents[$rootID]));
- return $root;
- }
- public function debug()
- {
- $count = 1;
- $this->printDebugTree($count, 0);
- }
- public function debugSelf()
- {
- echo 'nod - id:'.intval($this->id);
- echo ' - pid:'.intval($this->pid);
- echo ' - pos:'.intval($this->pos);
- echo ' ---- p:'.($this->getParent()?'t':'f');
- echo ' c:'.count($this->getChildren());
- echo ' o:'.count($this->getDescendants());
- echo ' a:'.count($this->getAncestors());
- echo PHP_EOL;
- }
- public function getAncestor($id)
- {
- $node = $this;
- do {
- $parent = $node->getParent();
- if ($parent and $parent->id == $id) {
- return $parent;
- }
- $node = $parent;
- } while ($parent);
- return null;
- }
- public function getAncestorRecursive($id)
- {
- $parent = $this->getParent();
- }
- public function getAncestors()
- {
- $ancestors = [];
- $this->getAncestorsRecursive($ancestors);
- return $ancestors;
- }
- protected function getAncestorsRecursive(&$ancestors)
- {
- $parent = $this->getParent();
- if ($parent) {
- $ancestors[$parent->pos] = $parent;
- $parent->getAncestorsRecursive($ancestors);
- }
- }
- public function getBrother($id)
- {
- $parent = $this->getParent();
- return $parent?$parent->getChild($id):null;
- }
- public function getChild($id)
- {
- if (isset($this->children[$id])) {
- return $this->children[$id];
- }
- return null;
- }
- public function getChildren()
- {
- return $this->children;
- }
- public function getDescendant($id)
- {
- if (isset($this->children[$id])) {
- return $this->children[$id];
- }
- foreach($this->children as $child) {
- $result = $child->getDescendant($id);
- if ($result) {
- return $result;
- }
- }
- return null;
- }
- public function getDepth()
- {
- $depth = 0;
- $node = $this;
- while ($node = $node->getParent()) {
- $depth++;
- }
- return $depth;
- }
- public function getDepthMax()
- {
- $max = 0;
- return $this->getDepthMaxRecursive(0, $max);
- }
- protected function getDepthMaxRecursive($depth, &$max)
- {
- if ($depth > $max) {
- $max = $depth;
- }
- foreach ($this->children as $child) {
- $child->getDepthMaxRecursive($depth+1, $max);
- }
- return $max;
- }
- public function getDepthRelative($id)
- {
- $depth = 0;
- $node = $this;
- while ($node = $node->getParent()) {
- $depth++;
- if ($node->id == $id) {
- return $depth;
- }
- }
- $depth = 0;
- $node = $this->getDescendant($id);
- while ($node and $node = $node->getParent()) {
- $depth--;
- if ($node->id == $this->id) {
- return $depth;
- }
- }
- return $this->getBrother($id) ? 0 : null;
- }
- public function getIterator()
- {
- return new \ArrayIterator($this->children);
- }
- public function getDescendants()
- {
- $descendants = [];
- $this->getDescendantsRecursive($descendants);
- return $descendants;
- }
- protected function getDescendantsRecursive(&$descendants)
- {
- foreach ($this->children as $child) {
- $descendants[$child->pos] = $child;
- $child->getDescendantsRecursive($descendants);
- }
- }
- public function getParent()
- {
- return $this->parent;
- }
- public function getRoot()
- {
- $node = $this;
- do {
- if ($node and $node->isRoot()) {
- return $node;
- }
- $node = $node->getParent();
- } while ($node);
- return null;
- }
- public function getSiblings()
- {
- $parent = $this->getParent();
- return $parent?$parent->getChilden():null;
- }
- public function isChildren($id)
- {
- $root = $this->getRoot();
- $node = $root->getDescendant($id);
- if ($node) {
- return array_key_exists($this->id, $node->getChildren());
- }
- return null;
- }
- public function isDescendant($id)
- {
- return array_key_exists($id, $this->getAncestors());
- }
- public function isRoot()
- {
- return $this->getParent()?false:true;
- }
- protected function printDebugTree(&$count, $level)
- {
- echo sprintf('%03d', $count).' ';
- if ($level > 0 ) {
- echo implode(' ', array_fill(0, $level, '---')).' ';
- }
- $this->debugSelf();
- foreach ($this->getChildren() as $child) {
- $count += 1;
- $child->printDebugTree($count, $level + 1);
- }
- }
- protected function setChildren($tree)
- {
- $this->children = $tree;
- foreach ($this->children as $child) {
- $child->setParent($this);
- }
- return true;
- }
- protected function setParent(self $parent)
- {
- $this->parent = $parent;
- return true;
- }
- }
- class Record
- {
- public $id = 0;
- public $pid = 0;
- public $name = 0;
- }
- class PageNode extends Node
- {
- public $name = '';
- }
- /* Recursive branch extrusion */
- function createBranch(&$parents, $children) {
- $tree = array();
- foreach ($children as $child) {
- if (isset($parents[$child['id']])) {
- $child['children'] = createBranch($parents, $parents[$child['id']]);
- }
- $tree[] = $child;
- }
- return $tree;
- }
- /* Initialization */
- function createTree($flat, $root = 0) {
- $parents = array();
- foreach ($flat as $a) {
- $parents[$a['parent']][] = $a;
- }
- return createBranch($parents, $parents[$root]);
- }
- function r($id, $p, $n)
- {
- return array('id' => $id, 'parent'=>$p, 'name'=>$n);
- }
- function r2($id, $p, $pos, $n)
- {
- $r = new Record();
- $r->id = $id;
- $r->pid = $p;
- $r->pos = $pos;
- $r->name = $n;
- return $r;
- }
- $p = array(
- r( 1, 0, 'strona_1'),
- r( 2, 0, 'strona_2'),
- r( 3, 0, 'strona_3'),
- r( 4, 2, 'strona_4'),
- r( 5, 2, 'strona_5'),
- r( 6, 2, 'strona_6'),
- r( 7, 4, 'strona_7'),
- r( 8, 4, 'strona_8'),
- r( 9, 8, 'strona_9'),
- r(10, 8, 'strona_10'),
- r(11, 1, 'strona_11'),
- r(12, 3, 'strona_12'),
- r(13, 3, 'strona_13'),
- r(14, 3, 'strona_14'),
- r(15, 12, 'strona_15'),
- r(16, 12, 'strona_16'),
- r(17, 16, 'strona_17'),
- r(18, 10, 'strona_18'),
- r(19, 10, 'strona_19'),
- r(20, 19, 'strona_20'),
- r(21, 8, 'strona_21'),
- );
- $p2 = array(
- r2( 1, 0, 1, 'strona_1'),
- r2( 2, 0, 2, 'strona_2'),
- r2( 3, 0, 3, 'strona_3'),
- r2( 4, 2, 1, 'strona_4'),
- r2( 5, 2, 2, 'strona_5'),
- r2( 6, 2, 3, 'strona_6'),
- r2( 7, 4, 1, 'strona_7'),
- r2( 8, 4, 2, 'strona_8'),
- r2( 9, 8, 1, 'strona_9'),
- r2(10, 8, 2, 'strona_10'),
- r2(11, 1, 1, 'strona_11'),
- r2(12, 3, 3, 'strona_12'),
- r2(13, 3, 2, 'strona_13'),
- r2(14, 3, 1, 'strona_14'),
- r2(15, 12, 1, 'strona_15'),
- r2(16, 12, 1, 'strona_16'),
- r2(17, 16, 1, 'strona_17'),
- r2(18, 10, 1, 'strona_18'),
- r2(19, 10, 2, 'strona_19'),
- r2(20, 19, 1, 'strona_20'),
- r2(21, 8, 3, 'strona_21'),
- r2(28, 19, 2, 'strona_22'),
- r2(23, 19, 3, 'strona_22'),
- );
- echo '$g = Node::createTreeObject($p, 0):'.PHP_EOL;
- $g = Node::createTreeObject($p2, 0);
- $g->debug();
- echo PHP_EOL.'$f = Node::createTreeObject($p, 4):'.PHP_EOL;
- $f = Node::createTreeObject($p2, 4);
- $f->debug();
- echo PHP_EOL.'foreach($f as $c) { $c->debug(); }:'.PHP_EOL;
- foreach($f as $c) { $c->debug(); }
- echo PHP_EOL.'$f->getChild(8):'.PHP_EOL;
- $f->getChild(8)->debug();
- echo PHP_EOL.'$g->getDescendant(10):'.PHP_EOL;
- $g->getDescendant(10)->debug();
- echo PHP_EOL.'$g->getDescendant(10)->getDepth():'.PHP_EOL;
- var_dump($g->getDescendant(10)->getDepth());
- echo PHP_EOL.'$g->getDescendant(2)->getDepthMax():'.PHP_EOL;
- var_dump($g->getDescendant(4)->getDepthMax());
- echo PHP_EOL.'$g->getDescendant(20)->getDepthRelative(8):'.PHP_EOL;
- var_dump($g->getDescendant(20)->getDepthRelative(8));
- echo PHP_EOL.'$g->getDescendant(8)->getDepthRelative(20):'.PHP_EOL;
- var_dump($g->getDescendant(8)->getDepthRelative(20));
- echo PHP_EOL.'$g->getDescendant(7)->getDepthRelative(8):'.PHP_EOL;
- var_dump($g->getDescendant(7)->getDepthRelative(8));
- echo PHP_EOL.'$g->getDescendant(10)->getAncestor(2)->debugSelf():'.PHP_EOL;
- $g->getDescendant(10)->getAncestor(2)->debugSelf();
- echo PHP_EOL.'$g->getDescendant(10)->getParent()->getParent()->debugSelf():'.PHP_EOL;
- $g->getDescendant(10)->getParent()->getParent()->debugSelf();
- echo PHP_EOL.'$g->isRoot():'.PHP_EOL;
- var_dump($g->isRoot());
- echo PHP_EOL.'$g->getDescendant(10)->isDescendant(4):'.PHP_EOL;
- var_dump($g->getDescendant(10)->isDescendant(4));
- echo PHP_EOL.'$g->getDescendant(8)->isChildren(4):'.PHP_EOL;
- var_dump($g->getDescendant(8)->isChildren(4));
- echo PHP_EOL.'foreach($g->getDescendant(3)>getDescendants() as $c) { $c->debugSelf(); }:'.PHP_EOL;
- foreach($g->getDescendant(3)->getDescendants() as $c) { $c->debugSelf(); }
- echo PHP_EOL.'foreach($g->getDescendant(20)->getAncestors() as $c) { $c->debugSelf(); }:'.PHP_EOL;
- foreach($g->getDescendant(20)->getAncestors() as $c) { $c->debugSelf(); }
- echo PHP_EOL.'----------------------------------------------------------------------------'.PHP_EOL;
- /*
- Node or null $n->getChild($id); # zwróć dziecko o id
- array $n->getChildren(); # zwróć wszystkie dzieci
- Node or null $n->getDescendant($id); # zwróć potomka o id
- array $n->getDescendants(); # zwróć wszyskich potomków
- Node or null $n->getParent(); # zwróć rodzica
- Node or null $n->getAncestor($id); # zwróć przodka o id
- array $n->getAncestors(); # zwróć wszystkich przodków
- Node $n->getRoot(); # zwróć korzeń drzewa
- Node or null $n->getBrother($id); # zwróć brata o id
- array $n->getSiblings(); # zwróć wszelkie rodzeństwo
- unsigned int $n->getDepth(); # zwróć zagłębienie względem korzenia
- unsigned int $n->getDepthMax(); # zwróć maksymalne zagłębienie względem węzła
- signed int $n->getDepthRelative($id); # zwróć zagłębienie względem węzła o id
- bool $n->isRoot($id); # Czy węzeł $n jest korzeniem?
- bool $n->isDescendant($id); # Czy węzeł $n jest potomkiem węzła o id?
- bool $n->isChildren($id); # Czy węzeł $n jest dzieckiem węzła o id?
- */
Advertisement
Add Comment
Please, Sign In to add comment