DisplayBundle/Manager/TreeManager.php
<?php
namespace OpenOrchestra\DisplayBundle\Manager;
use OpenOrchestra\ModelInterface\Model\ReadNodeInterface;
/**
* Class TreeManager
*/
class TreeManager
{
/**
* @param array $nodes
*
* @return array
*/
public function generateTree($nodes)
{
$superRoot = count(array_filter($nodes, function (ReadNodeInterface $node) {
return '-' == $node->getParentId();
}))? '-': 'root';
$list = array();
$list[$superRoot] = array();
foreach ($nodes as $node) {
if ($superRoot !== $node->getParentId() && $this->parentInList($node->getParentId(), $nodes)) {
$list[$node->getParentId()][] = $node;
continue;
}
$list[$superRoot][] = $node;
}
$tree = $this->createTree($list[$superRoot], $list);
return $tree;
}
/**
* @param array|ReadNodeInterface $nodes
* @param array $list
*
* @return array
*/
protected function createTree($nodes, $list)
{
$tree = array();
if (is_array($nodes)) {
foreach ($nodes as $node) {
$position = $this->getNodePosition($node, $tree);
$tree[$position] = array('node' => $node, 'child' => $this->getChildren($node, $list));
}
$tree = $this->sortArray($tree);
} elseif (!empty($nodes)) {
$tree = array('node' => $nodes, 'child' => $this->getChildren($nodes, $list));
}
return $tree;
}
/**
* @param ReadNodeInterface $node
* @param array $list
*
* @return array
*/
protected function getChildren(ReadNodeInterface $node, $list)
{
$children = array();
if (!empty($list[$node->getNodeId()]) && is_array($list[$node->getNodeId()])) {
foreach ($list[$node->getNodeId()] as $child) {
$position = $this->getNodePosition($child, $children);
$children[$position] = $this->createTree($child, $list);
}
}
$children = $this->sortArray($children);
return $children;
}
/**
* @param string $parentId
* @param array $list
*
* @return bool
*/
protected function parentInList($parentId, $list)
{
foreach ($list as $node) {
if ($parentId === $node->getNodeId()) {
return true;
}
}
return false;
}
/**
* @param ReadNodeInterface $node
* @param array $tree
*
* @return mixed
*/
protected function getNodePosition(ReadNodeInterface $node, $tree)
{
$position = $node->getOrder();
while (array_key_exists($position, $tree)) {
$position++;
}
return $position;
}
/**
* @param array $tree
*
* @return mixed
*/
protected function sortArray($tree)
{
if (!empty($tree)) {
ksort($tree);
}
return $tree;
}
}