args =& $args; } /** * @return array */ public function getActiveBranch() { return $this->active_branch; } /** * @return int */ public function getCurrentNodeId() { return $this->current_node; } /** * @return RokMenuNodeTree */ public function getMenuTree() { if (null == $this->menu) { $this->menu = new RokMenuNodeTree(); $this->populateMenuTree(); } return $this->menu; } /** * @return void */ protected function populateMenuTree() { $nodes = $this->getMenuItems(); $this->createMenuTree($nodes, $this->args['maxdepth']); } /** * Takes the menu item nodes and puts them into a tree structure * @param $nodes * @param $maxdepth * @return bool|RokMenuNodeTree */ protected function createMenuTree(&$nodes, $maxdepth) { // TODO: move maxdepth to higher processing level? if (!empty($nodes)) { // Build Menu Tree root down (orphan proof - child might have lower id than parent) $ids = array(); $ids[0] = true; $unresolved = array(); // pop the first item until the array is empty if there is any item if (is_array($nodes)) { while (count($nodes) && !is_null($node = array_shift($nodes))) { if (!$this->menu->addNode($node)) { if (!array_key_exists($node->getId(), $unresolved) || $unresolved[$node->getId()] < $maxdepth) { array_push($nodes, $node); if (!isset($unresolved[$node->getId()])) $unresolved[$node->getId()] = 1; else $unresolved[$node->getId()]++; } } } } } } /** * @param $nodeList * @return void */ protected function populateActiveBranch($nodeList) { // setup children array to find parents and children $children = array(); $list = array(); foreach ($nodeList as $node) { $thisref = &$children[$node->getId()]; $thisref['parent_id'] = $node->getParent(); if ($node->getParent() == 0) { $list[$node->getId()] = &$thisref; } else { $children[$node->getParent()]['children'][] = $node->getId(); } } // Find active branch if ($this->current_node != 0) { if (array_key_exists($this->current_node, $nodeList)) { $parent_id = $children[$this->current_node]['parent_id']; while ($parent_id != 0) { $this->active_branch[$parent_id] = $nodeList[$parent_id]; $parent_id = $children[$parent_id]['parent_id']; } $this->active_branch = array_reverse($this->active_branch, true); $this->active_branch[$this->current_node] = $nodeList[$this->current_node]; } } } /** * This platform specific function should be implemented to get the menu nodes and return them in a RokMenuNodeTree. * @abstract * @return array of RokMenuNode objects */ protected abstract function getMenuItems(); }