* @license PHP License * @package WB * @subpackage content */ /** * Datasource Tree Menu Renderer * * @version 0.2.1 * @package WB * @subpackage content */ class WBDatasource_TreeMenuRenderer extends WBStdClass { /** * Current Config * * - menu main menu id * - tmpl name of template file to load for displaying menus * - treemenu tree menu sub class, if any * - children list of automated child trees */ protected $config = array( 'tmpl' => 'default', 'menu' => '', 'treemenu' => '', 'children' => array(), 'withparent' => 0, 'tmplDir' => 'MenuMaker/Renderer' ); /** * Tree Datasource * @var WBDatasource_TreeMenu */ private $treeMenu = null; /** * Template Engine * @var patTemplate */ private $tmpl; /** * Current User * * @var WBUser_Auth */ private $user; /** * URL Id of current URI * @param string */ private $currentUrlId = 0; /** * Has class list * @param array */ private $hasClass = array(); /** * Constructor * * Parameter: * * * @param array $parameter */ public function __construct( $parameter = array() ) { $this->tmpl = WBClass::create('patTemplate'); $this->tmpl->setRoot('template'); WBClass::load('WBUser'); $this->user = WBUser::getCurrent(); } /** * Gerneral Configuration Method * * The $config array will existing default configuration parameter * * @param array $config */ public function setConfig($config = array()) { if (!is_array($config) || empty($config)) { return; } $this->config = array_merge($this->config, $config); // set null as default if (empty($this->config['menu'])) { $this->config['menu'] = null; } // slashes at tmplDir $this->config['tmplDir'] = trim($this->config['tmplDir'], '/'); } /** * Add Globald Template Vars * * @see patTemplate::addGlobalVars() * @param array * @param string * @return bool */ public function addGlobalVars($vars, $prefix = '') { return $this->tmpl->addGlobalVars($vars, $prefix); } /** * Set Current URI * * Set path to figure out URL id. Usually pass current's request location * * @param string URI path */ public function setCurrentURI($uri) { $this->initTreeMenu(); $this->currentUrlId = $this->treeMenu->getUrlId($uri); } private function initTreeMenu() { if ($this->treeMenu) { return; } $treeMenu = 'WBDatasource_TreeMenu'; if (!empty($this->config['treemenu'])) { $treeMenu .= '_' . $this->config['treemenu']; } $this->treeMenu = WBClass::Create($treeMenu); $this->treeMenu->setRoot($this->config['menu']); $this->treeMenu->useChildTrees($this->config['children']); } public function render() { $this->tmpl->readTemplatesFromInput($this->config['tmplDir'] . '/' . $this->config['tmpl'] . '.tmpl'); // prepare hasClass $this->hasClass = array(); if ($this->tmpl->exists('hasclass')) { $hasClass = trim($this->tmpl->getParsedTemplate('hasclass')); $hasClass = str_replace("\n", " ", $hasClass); $hasClass = array_map('trim', explode(' ', $hasClass)); foreach ($hasClass as $has) { if (!empty($has)) { $this->hasClass[] = $has; } } } $this->initTreeMenu(); $current = $this->treeMenu->getMenuCurrent($this->currentUrlId); $current['current'] = 'yes'; $this->injectHasClass($current); if (0 < $this->config['withparent']) { $parents = $this->treeMenu->getMenuParents($current); } else { $parents = array($this->treeMenu->getMenuNode($this->config['menu'])); } $menu = ''; $cacheable = true; for ($i = count($parents) - 1; $i >= 0; --$i) { $current['level'] = $i; // either use levelX and levelX_item or leveldefault and leveldefault_item $no = $i; if (!$this->tmpl->exists('level' . $no)) { $no = 'default'; } // child records $children = $this->treeMenu->getMenuChildren($parents[$i]); $parents[$i]['children_count'] = count($children); // apply authorisation settings foreach ($children as &$child) { $this->injectHasClass($child); $child['children_count'] = count($this->treeMenu->getMenuChildren($child)); if ($child['urlid'] == $this->currentUrlId || $child['id'] == $current['id']) { $child['status'] = 'selected'; } // check group permissions if (!empty($child['requiregroup'])) { $cacheable = false; if (!$this->user->isInGroup($child['requiregroup'], true)) { $child['status'] = 'grouprequired'; } continue; } // check user login permissions switch ($child['requireuser']) { case 'user': $cacheable = false; if (!$this->user->isAuthenticated()) { $child['status'] = 'userrequired'; } break; case 'anonymous': $cacheable = false; if ($this->user->isAuthenticated()) { $child['status'] = 'userdenied'; } break; case 'anybody': default: break; } } // add stuff to template ... $this->tmpl->addVar('level' . $no, 'children', $menu); $this->tmpl->addVars('level' . $no, $current); $this->tmpl->addVars('level' . $no, $current, 'parent_'); $this->tmpl->addRows('level' . $no . '_item', $children); // ... render template and prepare for next step - one level up. $menu = $this->tmpl->getParsedTemplate('level' . $no); $this->tmpl->clearTemplate('level' . $no); $this->tmpl->clearTemplate('level' . $no . '_item'); $current = $parents[$i]; } $this->tmpl->addGlobalVar('menu', trim($menu)); } public function getHtml() { return $this->tmpl->getParsedTemplate('snippet'); } /** * Has Class Feature * * Tell if menu item has class * @param array */ private function injectHasClass(&$item) { if (empty($item['class'])) { $item['class'] = ''; } $clazz = explode(' ', $item['class']); foreach ($this->hasClass as $has) { if (empty($has)) { continue; } $item['has_class_' . $has] = 0; if (in_array($has, $clazz)) { $item['has_class_' . $has] = 1; } } } }