File: D:/HostingSpaces/SBogers10/centrum8a.komma.pro/app/KommaApp/Kms/Core/Tree/Tree.php
<?php
namespace App\KommaApp\Kms\Core\Tree;
class Tree
{
protected $index = [];
protected $tree = [];
protected $nodes;
/**
* @param array $data
* @return $this
*/
public function make(array $data)
{
$this->nodes = $data;
$root = $this->createRoot();
foreach($this->nodes as $key => &$node)
{
$this->tree[] = $this->findChildren($node, $key);
if($this->nodeIsLastLeaf($node,$root))
{
return $this;
}
};
return $this;
}
public function getTree()
{
return $this->tree;
}
public function getIndex()
{
return $this->index;
}
/**
* @return TreeNode
*/
public function getEntityById($id)
{
if(isset($id) && isset($this->getIndex()[$id])) return $this->getIndex()[$id];
return $this->tree[0];
}
/**
* @param $entityId
* @param $entityTree
* @return int
*/
public function findNodeLevel($entityId, $entityTree)
{
$level = 0;
if(isset($entityTree['index']) && $index = $entityTree['index'])
{
$level++;
// Get rid of the index
unset($entityTree['index']);
$entity = $index[$entityId];
while($entity = $entity->parent)
{
$level++;
}
}
return $level;
}
/**
* @return object
*/
protected function createRoot()
{
// Create ghost root
$largestRgt = 0;
foreach($this->nodes as $node)
{
if($node->rgt > $largestRgt) $largestRgt = $node->rgt;
}
return (object) ['rgt' => $largestRgt + 1];
}
/**
* @param TreeNode $node
* @param $key
* @param null $parent
* @return array
*/
protected function findChildren($node, $key, &$parent = null)
{
$entity = new TreeNode($node, $parent);
$this->index[$node->id] = $entity;
for($i = $key+1; $i < count($this->nodes); $i++ )
{
if(isset($this->index[$this->nodes[$i]->id])){
continue; // don't process if node is already processed
}
$childNode = $this->nodes[$i];
if($this->nodeHasChildren($childNode))
{
$this->index[$childNode->id] = $this->findChildren($childNode, $i, $entity);
$entity->addChildNode($this->index[$childNode->id]);
}
else
{
$this->index[$childNode->id] = new TreeNode($childNode, $entity);
$entity->addChildNode($this->index[$childNode->id]);
}
if($this->nodeIsLastLeaf($childNode,$node))
{
return $entity;
}
}
return $entity;
}
/**
* @param $node
* @param $parent
* @return bool
*/
protected function nodeIsLastLeaf($node, $parent)
{
if(isset($parent->rgt) && $node->lft)
{
return $node->rgt == ($parent->rgt - 1);
}
return false;
}
/**
* @param $node
* @return bool
*/
protected function nodeHasChildren($node)
{
if(isset($node->lft) && $node->rgt)
{
return ($node->lft + 1) != $node->rgt;
}
return false;
}
public function removeFromIndex($id){
if(isset($this->index[$id])){
foreach($this->index[$id]->getChildren() as $child)
{
$this->removeFromIndex($child->node->id);
}
unset($this->index[$id]);
}
}
}