159 lines
4.2 KiB
PHP
159 lines
4.2 KiB
PHP
<?php
|
|
/**
|
|
* @version $Id: AbstractRokMenuProvider.php 4585 2012-10-27 01:44:54Z btowles $
|
|
* @author RocketTheme http://www.rockettheme.com
|
|
* @copyright Copyright (C) 2007 - 2013 RocketTheme, LLC
|
|
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
|
|
*/
|
|
|
|
require_once(dirname(__FILE__) . '/RokMenuProvider.php');
|
|
|
|
|
|
/**
|
|
* The base class for all data providers for menus
|
|
*/
|
|
abstract class AbstractRokMenuProvider implements RokMenuProvider
|
|
{
|
|
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $args = array();
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $active_branch = array();
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
protected $current_node = 0;
|
|
|
|
/**
|
|
* @var RokMenuNodeTree
|
|
*/
|
|
protected $menu;
|
|
|
|
/**
|
|
* @param $args
|
|
* @return void
|
|
*/
|
|
public function __construct(&$args)
|
|
{
|
|
$this->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();
|
|
}
|
|
|