Commit | Line | Data |
---|---|---|
158bd3ca | 1 | <?php |
a9229942 | 2 | |
158bd3ca | 3 | namespace wcf\system\menu; |
a9229942 | 4 | |
158bd3ca TD |
5 | use wcf\system\event\EventHandler; |
6 | use wcf\system\SingletonFactory; | |
7 | use wcf\system\WCF; | |
158bd3ca TD |
8 | |
9 | /** | |
10 | * Basis class for a tree menu. | |
a9229942 TD |
11 | * |
12 | * @author Marcel Werk | |
13 | * @copyright 2001-2019 WoltLab GmbH | |
14 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> | |
158bd3ca | 15 | */ |
a9229942 TD |
16 | abstract class TreeMenu extends SingletonFactory |
17 | { | |
18 | /** | |
19 | * list of visible menu items | |
20 | * @var ITreeMenuItem[] | |
21 | */ | |
22 | public $menuItemList = []; | |
23 | ||
24 | /** | |
25 | * list of the names of the active menu items | |
26 | * @var string[] | |
27 | */ | |
28 | public $activeMenuItems = []; | |
29 | ||
30 | /** | |
31 | * list of all menu items | |
32 | * @var ITreeMenuItem[][] | |
33 | */ | |
34 | public $menuItems; | |
35 | ||
36 | /** | |
37 | * @inheritDoc | |
38 | */ | |
39 | protected function init() | |
40 | { | |
41 | // get menu items from cache | |
42 | $this->loadCache(); | |
43 | ||
44 | // check menu items | |
45 | $this->checkMenuItems(); | |
46 | ||
47 | // remove items without children | |
48 | $this->removeEmptyItems(); | |
49 | ||
50 | // build plain menu item list | |
51 | $this->buildMenuItemList(); | |
52 | ||
53 | // call init event | |
54 | EventHandler::getInstance()->fireAction($this, 'init'); | |
55 | } | |
56 | ||
57 | /** | |
58 | * Loads cached menu items. | |
59 | */ | |
60 | protected function loadCache() | |
61 | { | |
62 | // call loadCache event | |
63 | EventHandler::getInstance()->fireAction($this, 'loadCache'); | |
64 | ||
65 | $this->menuItems = []; | |
66 | } | |
67 | ||
68 | /** | |
69 | * Checks the options and permissions of given menu item. | |
70 | * | |
71 | * @param ITreeMenuItem $item | |
72 | * @return bool | |
73 | */ | |
74 | protected function checkMenuItem(ITreeMenuItem $item) | |
75 | { | |
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; | |
84 | break; | |
85 | } | |
86 | } | |
87 | } | |
88 | if (!$hasEnabledOption) { | |
89 | return false; | |
90 | } | |
91 | ||
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; | |
100 | break; | |
101 | } | |
102 | } | |
103 | } | |
104 | if (!$hasPermission) { | |
105 | return false; | |
106 | } | |
107 | ||
108 | return true; | |
109 | } | |
110 | ||
111 | /** | |
112 | * Checks the options and permissions of the menu items. | |
113 | * | |
114 | * @param string $parentMenuItem | |
115 | */ | |
116 | protected function checkMenuItems($parentMenuItem = '') | |
117 | { | |
118 | if (!isset($this->menuItems[$parentMenuItem])) { | |
119 | return; | |
120 | } | |
121 | ||
122 | foreach ($this->menuItems[$parentMenuItem] as $key => $item) { | |
123 | if ($this->checkMenuItem($item)) { | |
124 | // check children | |
125 | $this->checkMenuItems($item->menuItem); | |
126 | } else { | |
127 | // remove this item | |
128 | unset($this->menuItems[$parentMenuItem][$key]); | |
129 | } | |
130 | } | |
131 | } | |
132 | ||
133 | /** | |
134 | * Removes items without children. | |
135 | * | |
136 | * @param string $parentMenuItem | |
137 | */ | |
138 | protected function removeEmptyItems($parentMenuItem = '') | |
139 | { | |
140 | if (!isset($this->menuItems[$parentMenuItem])) { | |
141 | return; | |
142 | } | |
143 | ||
144 | foreach ($this->menuItems[$parentMenuItem] as $key => $item) { | |
145 | $this->removeEmptyItems($item->menuItem); | |
146 | if ( | |
147 | empty($item->menuItemLink) | |
148 | && empty($item->menuItemController) | |
149 | && (!isset($this->menuItems[$item->menuItem]) || empty($this->menuItems[$item->menuItem])) | |
150 | ) { | |
151 | // remove this item | |
152 | unset($this->menuItems[$parentMenuItem][$key]); | |
153 | } | |
154 | } | |
155 | } | |
156 | ||
157 | /** | |
158 | * Builds a plain menu item list. | |
159 | * | |
160 | * @param string $parentMenuItem | |
161 | */ | |
162 | protected function buildMenuItemList($parentMenuItem = '') | |
163 | { | |
164 | if (!isset($this->menuItems[$parentMenuItem])) { | |
165 | return; | |
166 | } | |
167 | ||
168 | foreach ($this->menuItems[$parentMenuItem] as $item) { | |
169 | $this->menuItemList[$item->menuItem] = $item; | |
170 | $this->buildMenuItemList($item->menuItem); | |
171 | } | |
172 | } | |
173 | ||
174 | /** | |
175 | * Sets the active menu item. | |
176 | * This should be done before the menu.tpl template calls the function getMenu(). | |
177 | * | |
178 | * This function should be used in each script which uses a template that includes the menu.tpl. | |
179 | * | |
180 | * @param string $menuItem name of the active menu item | |
181 | */ | |
182 | public function setActiveMenuItem($menuItem) | |
183 | { | |
184 | $newActiveMenuItems = []; | |
185 | while (isset($this->menuItemList[$menuItem])) { | |
186 | $newActiveMenuItems[] = $menuItem; | |
187 | $menuItem = $this->menuItemList[$menuItem]->parentMenuItem; | |
188 | ||
189 | if ($menuItem && !isset($this->menuItemList[$menuItem])) { | |
190 | return; | |
191 | } | |
192 | } | |
193 | ||
194 | if (!empty($newActiveMenuItems)) { | |
195 | $this->activeMenuItems = $newActiveMenuItems; | |
196 | } | |
197 | } | |
198 | ||
199 | /** | |
200 | * Returns a list of the active menu items. | |
201 | * | |
202 | * @return array | |
203 | */ | |
204 | public function getActiveMenuItems() | |
205 | { | |
206 | return $this->activeMenuItems; | |
207 | } | |
208 | ||
209 | /** | |
210 | * Returns the active menu item. | |
211 | * | |
212 | * @param int $level | |
5227ebc7 | 213 | * @return string|null |
a9229942 TD |
214 | */ |
215 | public function getActiveMenuItem($level = 0) | |
216 | { | |
217 | if ($level < \count($this->activeMenuItems)) { | |
218 | return $this->activeMenuItems[\count($this->activeMenuItems) - ($level + 1)]; | |
219 | } | |
5227ebc7 MS |
220 | |
221 | return null; | |
a9229942 TD |
222 | } |
223 | ||
224 | /** | |
225 | * Returns the list of menu items. | |
226 | * | |
227 | * @param string $parentMenuItem | |
228 | * @return array | |
229 | */ | |
230 | public function getMenuItems($parentMenuItem = null) | |
231 | { | |
232 | if ($parentMenuItem === null) { | |
233 | return $this->menuItems; | |
234 | } | |
235 | if (isset($this->menuItems[$parentMenuItem])) { | |
236 | return $this->menuItems[$parentMenuItem]; | |
237 | } | |
238 | ||
239 | return []; | |
240 | } | |
dcb3a44c | 241 | } |