3 namespace wcf\system\menu
;
5 use wcf\system\event\EventHandler
;
6 use wcf\system\SingletonFactory
;
10 * Basis class for a tree menu.
13 * @copyright 2001-2019 WoltLab GmbH
14 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
16 abstract class TreeMenu
extends SingletonFactory
19 * list of visible menu items
20 * @var ITreeMenuItem[]
22 public $menuItemList = [];
25 * list of the names of the active menu items
28 public $activeMenuItems = [];
31 * list of all menu items
32 * @var ITreeMenuItem[][]
39 protected function init()
41 // get menu items from cache
45 $this->checkMenuItems();
47 // remove items without children
48 $this->removeEmptyItems();
50 // build plain menu item list
51 $this->buildMenuItemList();
54 EventHandler
::getInstance()->fireAction($this, 'init');
58 * Loads cached menu items.
60 protected function loadCache()
62 // call loadCache event
63 EventHandler
::getInstance()->fireAction($this, 'loadCache');
65 $this->menuItems
= [];
69 * Checks the options and permissions of given menu item.
71 * @param ITreeMenuItem $item
74 protected function checkMenuItem(ITreeMenuItem
$item)
76 // check the options of this item
77 $hasEnabledOption = true;
78 if (!empty($item->options
)) {
79 $hasEnabledOption = false;
80 $options = \
explode(',', \
strtoupper($item->options
));
81 foreach ($options as $option) {
82 if (\
defined($option) && \
constant($option)) {
83 $hasEnabledOption = true;
88 if (!$hasEnabledOption) {
92 // check the permission of this item for the active user
93 $hasPermission = true;
94 if (!empty($item->permissions
)) {
95 $hasPermission = false;
96 $permissions = \
explode(',', $item->permissions
);
97 foreach ($permissions as $permission) {
98 if (WCF
::getSession()->getPermission($permission)) {
99 $hasPermission = true;
104 if (!$hasPermission) {
112 * Checks the options and permissions of the menu items.
114 * @param string $parentMenuItem
116 protected function checkMenuItems($parentMenuItem = '')
118 if (!isset($this->menuItems
[$parentMenuItem])) {
122 foreach ($this->menuItems
[$parentMenuItem] as $key => $item) {
123 if ($this->checkMenuItem($item)) {
125 $this->checkMenuItems($item->menuItem
);
128 unset($this->menuItems
[$parentMenuItem][$key]);
134 * Removes items without children.
136 * @param string $parentMenuItem
138 protected function removeEmptyItems($parentMenuItem = '')
140 if (!isset($this->menuItems
[$parentMenuItem])) {
144 foreach ($this->menuItems
[$parentMenuItem] as $key => $item) {
145 $this->removeEmptyItems($item->menuItem
);
147 empty($item->menuItemLink
)
148 && empty($item->menuItemController
)
149 && (!isset($this->menuItems
[$item->menuItem
]) ||
empty($this->menuItems
[$item->menuItem
]))
152 unset($this->menuItems
[$parentMenuItem][$key]);
158 * Builds a plain menu item list.
160 * @param string $parentMenuItem
162 protected function buildMenuItemList($parentMenuItem = '')
164 if (!isset($this->menuItems
[$parentMenuItem])) {
168 foreach ($this->menuItems
[$parentMenuItem] as $item) {
169 $this->menuItemList
[$item->menuItem
] = $item;
170 $this->buildMenuItemList($item->menuItem
);
175 * Sets the active menu item.
176 * This should be done before the menu.tpl template calls the function getMenu().
178 * This function should be used in each script which uses a template that includes the menu.tpl.
180 * @param string $menuItem name of the active menu item
182 public function setActiveMenuItem($menuItem)
184 $newActiveMenuItems = [];
185 while (isset($this->menuItemList
[$menuItem])) {
186 $newActiveMenuItems[] = $menuItem;
187 $menuItem = $this->menuItemList
[$menuItem]->parentMenuItem
;
189 if ($menuItem && !isset($this->menuItemList
[$menuItem])) {
194 if (!empty($newActiveMenuItems)) {
195 $this->activeMenuItems
= $newActiveMenuItems;
200 * Returns a list of the active menu items.
204 public function getActiveMenuItems()
206 return $this->activeMenuItems
;
210 * Returns the active menu item.
213 * @return string|null
215 public function getActiveMenuItem($level = 0)
217 if ($level < \
count($this->activeMenuItems
)) {
218 return $this->activeMenuItems
[\
count($this->activeMenuItems
) - ($level +
1)];
225 * Returns the list of menu items.
227 * @param string $parentMenuItem
230 public function getMenuItems($parentMenuItem = null)
232 if ($parentMenuItem === null) {
233 return $this->menuItems
;
235 if (isset($this->menuItems
[$parentMenuItem])) {
236 return $this->menuItems
[$parentMenuItem];