* @license PHP License * @package WB * @subpackage content */ /** * Datasource Tree Menu * * Acces to tree menu itms * * @version 0.2.0 * @package WB * @subpackage content */ class WBDatasource_TreeMenu extends WBStdClass { /** * Tree datasource object * @var WBDatasource_Tree */ private $tree; /** * URL dictionary * @var WBDictionary_URL */ protected $url; /** * Id of root item * @var string */ private $rootId = null; /** * List of child trees * @var array WBDatasource_TreeMenu_Child */ private $childTrees = array(); /** * Map URLIDs to child trees * @var WBDatasource_TreeMenu_Child */ private $childTreeMap = array(); /** * constructor * * */ public function __construct() { $params = array( 'treetable' => 'menu', 'alphalength' => 4, ); $this->tree = WBClass::create('WBDatasource_Tree', $params); $this->url = WBClass::create('WBDictionary_URL'); } /** * Inject cache parameter * * Cache parameters are used to create a unique cache id. * Implement this function to add custom parameters for caching. * * It is recommended to prefix custom parameter with a namespace plus colon. * * @param array $params */ public function addCacheIdParams(&$params) { } /** * Use list of child-trees * * @param array $list */ public function useChildTrees($list) { if (!is_array($list) || empty($list)) { return; } foreach ($list as $l) { $obj = WBClass::create('WBDatasource_TreeMenu_Child_' . $l); $this->childTrees[] = $obj; } } /** * Set root id * * Use menu root * * @param string $id */ public function setRoot($id) { $this->tree->get($id); $this->rootId = $id; } /** * Get current root id * * @return string */ protected function getRootId() { return $this->rootId; } /** * Get URL id of current page * * Auxilliary method, can be overwritten * * @param string $uri * @return string $urlid */ public function getUrlId($uri) { $this->url->addWord($uri); return $this->url->getId(); } /** * Get selected menu record * * @param string $urlid * @return array curren node */ public function getMenuCurrent($urlid) { // find current URL in menu $clause = array(); $clause[] = array( 'field' => 'urlid', 'value' => $urlid ); $current = $this->tree->getChildren($this->rootId, 0, array(), $clause); $childCurrent = $this->getMenuCurrentChild($urlid); if (empty($current)) { $current = $childCurrent; // if nothing matches load at least the menu if (empty($current)) { $current = $this->tree->get($this->rootId); } } else { $current = $current[0]; } $this->injectUrl($current); return $current; } private function getMenuCurrentChild($urlid) { $url = clone $this->url; $url->load($urlid); if (empty($this->childTrees)) { return array(); } foreach ($this->childTrees as $ct) { if (!$ct->checkUrl($url->getWord())) { continue; } return $ct->getNode($url->getId(), $url->getWord()); break; } return array(); } /** * Get ancestors * * Receive list of parents from menu tree. Auxilliary method can be overwritten * * @param array $current node * @return array */ public function getMenuParents($current) { $childish = array(); foreach ($this->childTrees as $ct) { if ($ct->checkUrl($current['url'])) { $childish = $ct->getParents($current); break; } } // load ascending parents if (empty($childish)) { $parents = $this->tree->getParent($current['id'], 0); } else { $clause = array(); $clause[] = array( 'field' => 'urlid', 'value' => $childish[0]['urlid'] ); array_pop($childish); $tmp = $this->tree->getChildren($this->rootId, 0, array(), $clause); $childish[0] = $tmp[0]; $parents = $this->tree->getParent($tmp[0]['id'], 0); $parents = array_merge($parents, $childish); } $parents[] = $current; foreach ($parents as &$node) { $this->injectUrl($node); } return $parents; } /** * Get direct offspring of parent node * * Receive children from menu tree * * @param array $parent node * @return array */ public function getMenuChildren($parent) { foreach ($this->childTrees as $ct) { if ($ct->checkUrl($parent['url'])) { return $ct->getChildren($parent['url']); } } $children = $this->tree->getChildren($parent['id']); foreach ($children as &$node) { $this->injectUrl($node); } return $children; } /** * Select menu node by id * * @param string $id * @return array */ public function getMenuNode($id) { $node = $this->tree->get($id); $this->injectUrl($node); return $node; } /** * Inject URL into node * * Locate URL-id and set "url" either to [[SERVICE_HTML]] * or the actual URL of the Dictionary_URL item * * @param array $node */ private function injectUrl(&$node) { if (isset($node['url']) && !empty($node['url'])) { return; } if (0 == $node['urlid']) { $node['url'] = '[[SERVICE_HTML]]'; return; } $this->url->load($node['urlid']); $node['url'] = $this->url->getWord(); } }