* @license PHP License * @package WB * @subpackage db */ WBClass::load('WBUser'); /** * Menu Digger * * @version 0.1.0 * @package WB * @subpackage menu */ class WBDatasource_MenuDigger extends WBStdClass { /** * Tree Menu to dig * @var WBDatasource_TreeMenu */ private $treeMenu; /** * URL Dict * @var WBDictionary_URL */ private $url; /** * List of URLs to ignore * @var array */ private $ignore = array(); /** * maximum levels to dig down * @var int */ private $maxLevel = -1; /** * List of callback listener * * @var array */ private $listener = array(); /** * user object * @var WBUser_Auth */ protected $user; /** * Set tree menu object * * Dependecy injection * @param WBDatasource_TreeMenu $treeMenu */ public function setTreeMenu($treeMenu) { $this->treeMenu = $treeMenu; } /** * Set id of root menu item * * Select menu item * * @param string $id */ public function setRoot($id) { $this->treeMenu->setRoot($id); } /** * Set list of URLs to ignore * * In case the URLs match, they will be ignored. Also, all child-URLs will * be ignored. * * E.g: $list = array('http://wombat.exit0.net/foo', 'http://wombat.exit0.net/bar'); * Ignored URLs * - http://wombat.exit0.net/foo * - http://wombat.exit0.net/bar * - http://wombat.exit0.net/fooblah * - http://wombat.exit0.net/foo/something * - ... * * @param array $list */ public function ignore($list) { $this->ignore = $list; } /** * Set levels to dig * * Levels in tree menu to dig down. Set to -1 for unlimited * * @param int $level */ public function setMaxLevel($level = -1) { $this->maxLevel = $level; } /** * Add listener for menu entries * * @param WBDatasource_MenuDigger_Listener $listener */ public function addListener($listener) { $this->listener[] = $listener; } /** * Start digging * * Inform listener and load children of root menu */ public function dig() { $this->init(); $url = $this->treeMenu->getUrlId(''); $base = $this->treeMenu->getMenuCurrent($url); foreach ($this->listener as $l) { $l->onStart($base); } $children = $this->treeMenu->getMenuChildren($base); foreach ($children as $child) { $this->digDeeper($child, 1); } foreach ($this->listener as $l) { $l->onEnd($base); } } /** * Recursie digging * * Check level, call listener for item and dig deeper into item's children * * @param array $item * @param int $level */ private function digDeeper($item, $level) { // reached max level? if (0 < $this->maxLevel && $this->maxLevel < $level) { return; } // simply ignore invalid URLs if (0 == $item['urlid']) { if (0 < $level) { return; } } else { $urlid = $this->treeMenu->getUrlId($item['url']); if (empty($urlid)) { return; } foreach ($this->ignore as $ig) { if (strncmp($ig, $item['url'], strlen($ig)) == 0) { return; } } } $this->addStatus($item); $children = $this->treeMenu->getMenuChildren($item); foreach ($this->listener as $l) { $l->onDigStart($level, $item, $children); } if (0 == count($children)) { foreach ($this->listener as $l) { $l->onDigEnd($level, $item, $children); } return; } foreach ($children as $child) { $this->digDeeper($child, $level + 1); } foreach ($this->listener as $l) { $l->onDigEnd($level, $item, $children); } } /** * Add permission status to menu item * * Check user's grants for this menu item * * @param array $item */ private function addStatus(&$item) { $item['satus'] = ''; if (!empty($item['requiregroup']) && !$this->user->isInGroup($item['requiregroup'], true)) { $item['status'] = 'grouprequired'; return; } switch ($item['requireuser']) { case 'user': if (!$this->user->isAuthenticated()) { $item['status'] = 'userrequired'; } break; case 'anonymous': if ($this->user->isAuthenticated()) { $item['status'] = 'userdenied'; } break; case 'anybody': default: break; } } /** * Make sure tree menu exists * * Instantiate tree menu and URL dictionary, of not done already */ private function init() { if (!$this->treeMenu) { $this->treeMenu = WBClass::create('WBDatasource_TreeMenu'); } if (!$this->url) { $this->url = WBClass::create('WBDictionary_URL'); } if (!$this->user) { $this->user = WBUser::getCurrent(); } } }