|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* This file contains a standard way of displaying side/drop down menus. |
|
5
|
|
|
* |
|
6
|
|
|
* @package ElkArte Forum |
|
7
|
|
|
* @copyright ElkArte Forum contributors |
|
8
|
|
|
* @license BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file) |
|
9
|
|
|
* |
|
10
|
|
|
* This file contains code covered by: |
|
11
|
|
|
* copyright: 2011 Simple Machines (http://www.simplemachines.org) |
|
12
|
|
|
* |
|
13
|
|
|
* @version 2.0 dev |
|
14
|
|
|
* |
|
15
|
|
|
*/ |
|
16
|
|
|
|
|
17
|
|
|
use ElkArte\User; |
|
18
|
|
|
|
|
19
|
|
|
/** |
|
20
|
|
|
* Create a menu. |
|
21
|
|
|
* |
|
22
|
|
|
* @param mixed[] $menuData the menu array |
|
23
|
|
|
* - Possible indexes: |
|
24
|
|
|
* - Menu name with named indexes as follows: |
|
25
|
|
|
* - string $title => Section title |
|
26
|
|
|
* - bool $enabled => Is the section enabled / shown |
|
27
|
|
|
* - array $areas => Array of areas within this menu section, see below |
|
28
|
|
|
* - array $permission => Permission required to access the whole section |
|
29
|
|
|
* |
|
30
|
|
|
* - $areas sub array from above, named indexes as follows: |
|
31
|
|
|
* - array $permission => Array of permissions to determine who can access this area |
|
32
|
|
|
* - string $label => Optional text string for link (Otherwise $txt[$index] will be used) |
|
33
|
|
|
* - string $controller => Name of controller required for this area |
|
34
|
|
|
* - string $function => Method in controller to call when area is selected |
|
35
|
|
|
* - string $icon => File name of an icon to use on the menu, if using a class set as transparent.png |
|
36
|
|
|
* - string $class => CSS class name to apply to the icon img, used to apply a sprite icon |
|
37
|
|
|
* - string $custom_url => URL to call for this menu item |
|
38
|
|
|
* - bool $enabled => Should this area even be enabled / accessible? |
|
39
|
|
|
* - bool $hidden => If the area is visible in the menu |
|
40
|
|
|
* - string $select => If set, references another area |
|
41
|
|
|
* - array $subsections => Array of subsections for this menu area, see below |
|
42
|
|
|
* |
|
43
|
|
|
* - $subsections sub array from $areas above, unnamed indexes interpreted as follows, single named index 'enabled' |
|
44
|
|
|
* - string 0 => Label for this subsection |
|
45
|
|
|
* - array 1 => Array of permissions to check for this subsection. |
|
46
|
|
|
* - bool 2 => Is this the default subaction - if not set for any will default to first... |
|
47
|
|
|
* - bool enabled => Enabled or not |
|
48
|
|
|
* - array active => Set the button active for other subsections. |
|
49
|
|
|
* - string url => Custom url for the subsection |
|
50
|
|
|
* @param mixed[] $menuOptions an array of options that can be used to override some default behaviours. |
|
51
|
|
|
* - Possible indexes: |
|
52
|
|
|
* - action => overrides the default action |
|
53
|
|
|
* - current_area => overrides the current area |
|
54
|
|
|
* - extra_url_parameters => an array or pairs or parameters to be added to the url |
|
55
|
|
|
* - disable_url_session_check => (boolean) if true the session var/id are omitted from the url |
|
56
|
|
|
* - base_url => an alternative base url |
|
57
|
|
|
* - menu_type => alternative menu types? |
|
58
|
|
|
* - can_toggle_drop_down => (boolean) if the menu can "toggle" |
|
59
|
|
|
* - template_name => an alternative template to load (instead of Generic) |
|
60
|
|
|
* - layer_name => alternative layer name for the menu |
|
61
|
|
|
* - hook => hook name to call integrate_ . 'hook name' . '_areas' |
|
62
|
|
|
* - default_include_dir => directory to include for function support |
|
63
|
|
|
* @return mixed[]|false |
|
|
|
|
|
|
64
|
|
|
*/ |
|
65
|
14 |
|
function createMenu($menuData, $menuOptions = array()) |
|
66
|
|
|
{ |
|
67
|
14 |
|
global $context, $settings, $options, $txt, $scripturl; |
|
68
|
|
|
|
|
69
|
|
|
$_req = \ElkArte\HttpReq::instance(); |
|
70
|
14 |
|
|
|
71
|
|
|
// Work out where we should get our images from. |
|
72
|
|
|
$context['menu_image_path'] = file_exists($settings['theme_dir'] . '/images/admin/change_menu.png') ? $settings['images_url'] . '/admin' : $settings['default_images_url'] . '/admin'; |
|
73
|
14 |
|
|
|
74
|
|
|
// Every menu gets a unique ID, these are shown in first in, first out order. |
|
75
|
|
|
$context['max_menu_id'] = isset($context['max_menu_id']) ? $context['max_menu_id'] + 1 : 1; |
|
76
|
14 |
|
|
|
77
|
14 |
|
// This will be all the data for this menu - and we'll make a shortcut to it to aid readability here. |
|
78
|
|
|
$context['menu_data_' . $context['max_menu_id']] = array(); |
|
79
|
|
|
$menu_context = &$context['menu_data_' . $context['max_menu_id']]; |
|
80
|
14 |
|
|
|
81
|
14 |
|
// Allow extend *any* menu with a single hook |
|
82
|
|
|
if (!empty($menuOptions['hook'])) |
|
83
|
|
|
call_integration_hook('integrate_' . $menuOptions['hook'] . '_areas', array(&$menuData, &$menuOptions)); |
|
84
|
14 |
|
|
|
85
|
|
|
// What is the general action of this menu (i.e. $scripturl?action=XXXX. |
|
86
|
|
|
$menu_context['current_action'] = isset($menuOptions['action']) ? $menuOptions['action'] : $context['current_action']; |
|
87
|
14 |
|
|
|
88
|
4 |
|
// What is the current area selected? |
|
89
|
|
|
if (isset($menuOptions['current_area']) || isset($_req->query->area)) |
|
90
|
|
|
$menu_context['current_area'] = isset($menuOptions['current_area']) ? $menuOptions['current_area'] : $_req->query->area; |
|
91
|
14 |
|
|
|
92
|
14 |
|
// Build a list of additional parameters that should go in the URL. |
|
93
|
12 |
|
$menu_context['extra_parameters'] = ''; |
|
94
|
12 |
|
if (!empty($menuOptions['extra_url_parameters'])) |
|
95
|
|
|
foreach ($menuOptions['extra_url_parameters'] as $key => $value) |
|
96
|
|
|
$menu_context['extra_parameters'] .= ';' . $key . '=' . $value; |
|
97
|
14 |
|
|
|
98
|
12 |
|
// Only include the session ID in the URL if it's strictly necessary. |
|
99
|
|
|
if (empty($menuOptions['disable_url_session_check'])) |
|
100
|
14 |
|
$menu_context['extra_parameters'] .= ';' . $context['session_var'] . '=' . $context['session_id']; |
|
101
|
|
|
|
|
102
|
14 |
|
$include_data = array(); |
|
103
|
|
|
// This is necessary only in profile (at least for the core), but we do it always because it's easier |
|
104
|
|
|
$permission_set = !empty($context['user']['is_owner']) ? 'own' : 'any'; |
|
105
|
14 |
|
|
|
106
|
|
|
// Now setup the context correctly. |
|
107
|
|
|
foreach ($menuData as $section_id => $section) |
|
108
|
14 |
|
{ |
|
109
|
8 |
|
// Is this enabled? |
|
110
|
|
|
if ((isset($section['enabled']) && $section['enabled'] == false)) |
|
111
|
14 |
|
continue; |
|
112
|
|
|
// Has permission check? |
|
113
|
|
View Code Duplication |
if (isset($section['permission'])) |
|
114
|
12 |
|
{ |
|
115
|
|
|
// The profile menu has slightly different permissions |
|
116
|
|
|
if (is_array($section['permission']) && isset($section['permission']['own'], $section['permission']['any'])) |
|
117
|
|
|
{ |
|
118
|
|
|
if (empty($section['permission'][$permission_set]) || !allowedTo($section['permission'][$permission_set])) |
|
119
|
12 |
|
continue; |
|
120
|
|
|
} |
|
121
|
|
|
elseif (!allowedTo($section['permission'])) |
|
122
|
|
|
continue; |
|
123
|
|
|
} |
|
124
|
14 |
|
|
|
125
|
|
|
// Now we cycle through the sections to pick the right area. |
|
126
|
|
|
foreach ($section['areas'] as $area_id => $area) |
|
127
|
14 |
|
{ |
|
128
|
|
|
// Can we do this? |
|
129
|
|
|
if (!isset($area['enabled']) || $area['enabled'] !== false) |
|
130
|
14 |
|
{ |
|
131
|
|
|
// Has permission check? |
|
132
|
|
View Code Duplication |
if (!empty($area['permission'])) |
|
133
|
14 |
|
{ |
|
134
|
|
|
// The profile menu has slightly different permissions |
|
135
|
2 |
|
if (is_array($area['permission']) && isset($area['permission']['own'], $area['permission']['any'])) |
|
136
|
2 |
|
{ |
|
137
|
|
|
if (empty($area['permission'][$permission_set]) || !allowedTo($area['permission'][$permission_set])) |
|
138
|
12 |
|
continue; |
|
139
|
2 |
|
} |
|
140
|
|
|
elseif (!allowedTo($area['permission'])) |
|
141
|
|
|
continue; |
|
142
|
|
|
} |
|
143
|
14 |
|
|
|
144
|
|
|
// Add it to the context... if it has some form of name! |
|
145
|
|
|
if (isset($area['label']) || (isset($txt[$area_id]) && !isset($area['select']))) |
|
146
|
14 |
|
{ |
|
147
|
|
|
// We may want to include a file, let's find out the path |
|
148
|
|
|
if (!empty($area['file'])) |
|
149
|
|
|
$area['file'] = (!empty($area['dir']) ? $area['dir'] : (!empty($menuOptions['default_include_dir']) ? $menuOptions['default_include_dir'] : CONTROLLERDIR)) . '/' . $area['file']; |
|
150
|
14 |
|
|
|
151
|
|
|
// If we haven't got an area then the first valid one is our choice. |
|
152
|
10 |
|
if (!isset($menu_context['current_area'])) |
|
153
|
10 |
|
{ |
|
154
|
|
|
$menu_context['current_area'] = $area_id; |
|
155
|
|
|
$include_data = $area; |
|
156
|
|
|
} |
|
157
|
14 |
|
|
|
158
|
|
|
// If this is hidden from view don't do the rest. |
|
159
|
|
|
if (empty($area['hidden'])) |
|
160
|
14 |
|
{ |
|
161
|
|
|
// First time this section? |
|
162
|
14 |
|
if (!isset($menu_context['sections'][$section_id])) |
|
163
|
|
|
{ |
|
164
|
|
|
if (isset($menuOptions['counters'], $section['counter']) && !empty($menuOptions['counters'][$section['counter']])) |
|
165
|
14 |
|
$section['title'] .= sprintf($settings['menu_numeric_notice'][0], $menuOptions['counters'][$section['counter']]); |
|
166
|
|
|
|
|
167
|
|
|
$menu_context['sections'][$section_id]['title'] = $section['title']; |
|
168
|
14 |
|
} |
|
169
|
14 |
|
|
|
170
|
|
|
$menu_context['sections'][$section_id]['areas'][$area_id] = array('label' => isset($area['label']) ? $area['label'] : $txt[$area_id]); |
|
171
|
|
View Code Duplication |
if (isset($menuOptions['counters'], $area['counter']) && !empty($menuOptions['counters'][$area['counter']])) |
|
172
|
|
|
$menu_context['sections'][$section_id]['areas'][$area_id]['label'] .= sprintf($settings['menu_numeric_notice'][1], $menuOptions['counters'][$area['counter']]); |
|
173
|
14 |
|
|
|
174
|
|
|
// We'll need the ID as well... |
|
175
|
|
|
$menu_context['sections'][$section_id]['id'] = $section_id; |
|
176
|
14 |
|
|
|
177
|
4 |
|
// Does it have a custom URL? |
|
178
|
|
View Code Duplication |
if (isset($area['custom_url'])) |
|
179
|
|
|
$menu_context['sections'][$section_id]['areas'][$area_id]['url'] = $area['custom_url']; |
|
180
|
14 |
|
|
|
181
|
12 |
|
// Does this area have its own icon? |
|
182
|
|
|
if (isset($area['icon'])) |
|
183
|
2 |
|
$menu_context['sections'][$section_id]['areas'][$area_id]['icon'] = '<img ' . (isset($area['class']) ? 'class="' . $area['class'] . '" ' : 'style="background: none"') . ' src="' . $context['menu_image_path'] . '/' . $area['icon'] . '" alt="" /> '; |
|
184
|
|
|
else |
|
185
|
|
|
$menu_context['sections'][$section_id]['areas'][$area_id]['icon'] = ''; |
|
186
|
14 |
|
|
|
187
|
|
|
// Did it have subsections? |
|
188
|
14 |
|
if (!empty($area['subsections'])) |
|
189
|
14 |
|
{ |
|
190
|
14 |
|
$menu_context['sections'][$section_id]['areas'][$area_id]['subsections'] = array(); |
|
191
|
|
|
$first_sa = $last_sa = null; |
|
192
|
14 |
|
foreach ($area['subsections'] as $sa => $sub) |
|
193
|
|
|
{ |
|
194
|
14 |
|
if ((empty($sub[1]) || allowedTo($sub[1])) && (!isset($sub['enabled']) || !empty($sub['enabled']))) |
|
195
|
14 |
|
{ |
|
196
|
|
|
if ($first_sa === null) |
|
197
|
14 |
|
$first_sa = $sa; |
|
198
|
14 |
|
|
|
199
|
|
|
$menu_context['sections'][$section_id]['areas'][$area_id]['subsections'][$sa] = array('label' => $sub[0]); |
|
200
|
|
View Code Duplication |
if (isset($menuOptions['counters'], $sub['counter']) && !empty($menuOptions['counters'][$sub['counter']])) |
|
201
|
|
|
$menu_context['sections'][$section_id]['areas'][$area_id]['subsections'][$sa]['label'] .= sprintf($settings['menu_numeric_notice'][2], $menuOptions['counters'][$sub['counter']]); |
|
202
|
14 |
|
|
|
203
|
12 |
|
// Custom URL? |
|
204
|
|
View Code Duplication |
if (isset($sub['url'])) |
|
205
|
|
|
$menu_context['sections'][$section_id]['areas'][$area_id]['subsections'][$sa]['url'] = $sub['url']; |
|
206
|
14 |
|
|
|
207
|
|
|
// A bit complicated - but is this set? |
|
208
|
|
|
if ($menu_context['current_area'] == $area_id) |
|
209
|
2 |
|
{ |
|
210
|
|
|
// Save which is the first... |
|
211
|
|
|
if (empty($first_sa)) |
|
212
|
|
|
$first_sa = $sa; |
|
213
|
2 |
|
|
|
214
|
|
|
// Is this the current subsection? |
|
215
|
|
|
if (isset($_req->query->sa) && $_req->query->sa == $sa) |
|
216
|
2 |
|
$menu_context['current_subsection'] = $sa; |
|
217
|
|
|
|
|
218
|
|
|
elseif (isset($sub['active']) && isset($_req->query->sa) && in_array($_req->query->sa, $sub['active'])) |
|
219
|
|
|
$menu_context['current_subsection'] = $sa; |
|
220
|
2 |
|
|
|
221
|
|
|
// Otherwise is it the default? |
|
222
|
|
|
elseif (!isset($menu_context['current_subsection']) && !empty($sub[2])) |
|
223
|
|
|
$menu_context['current_subsection'] = $sa; |
|
224
|
|
|
} |
|
225
|
14 |
|
|
|
226
|
|
|
// Let's assume this is the last, for now. |
|
227
|
|
|
$last_sa = $sa; |
|
228
|
|
|
} |
|
229
|
14 |
|
// Mark it as disabled... |
|
230
|
|
|
else |
|
231
|
|
|
$menu_context['sections'][$section_id]['areas'][$area_id]['subsections'][$sa]['disabled'] = true; |
|
232
|
|
|
} |
|
233
|
14 |
|
|
|
234
|
|
|
// Set which one is first, last and selected in the group. |
|
235
|
14 |
|
if (!empty($menu_context['sections'][$section_id]['areas'][$area_id]['subsections'])) |
|
236
|
14 |
|
{ |
|
237
|
|
|
$menu_context['sections'][$section_id]['areas'][$area_id]['subsections'][$context['right_to_left'] ? $last_sa : $first_sa]['is_first'] = true; |
|
238
|
14 |
|
$menu_context['sections'][$section_id]['areas'][$area_id]['subsections'][$context['right_to_left'] ? $first_sa : $last_sa]['is_last'] = true; |
|
239
|
2 |
|
|
|
240
|
|
|
if ($menu_context['current_area'] == $area_id && !isset($menu_context['current_subsection'])) |
|
241
|
|
|
$menu_context['current_subsection'] = $first_sa; |
|
242
|
|
|
} |
|
243
|
|
|
} |
|
244
|
|
|
} |
|
245
|
|
|
} |
|
246
|
|
|
|
|
247
|
14 |
|
// Is this the current section? |
|
248
|
|
|
// @todo why $found_section is not initialized outside one of the loops? (Not sure which one lol) |
|
249
|
|
|
if ($menu_context['current_area'] == $area_id && empty($found_section)) |
|
250
|
14 |
|
{ |
|
251
|
|
|
// Only do this once? |
|
252
|
|
|
$found_section = true; |
|
253
|
14 |
|
|
|
254
|
|
|
// Update the context if required - as we can have areas pretending to be others. ;) |
|
255
|
14 |
|
$menu_context['current_section'] = $section_id; |
|
256
|
|
|
// @todo 'select' seems useless |
|
257
|
|
|
$menu_context['current_area'] = isset($area['select']) ? $area['select'] : $area_id; |
|
258
|
14 |
|
|
|
259
|
|
|
// This will be the data we return. |
|
260
|
|
|
$include_data = $area; |
|
261
|
14 |
|
} |
|
262
|
|
|
// Make sure we have something in case it's an invalid area. |
|
263
|
4 |
|
elseif (empty($found_section) && empty($include_data)) |
|
264
|
4 |
|
{ |
|
265
|
9 |
|
$menu_context['current_section'] = $section_id; |
|
266
|
|
|
$backup_area = isset($area['select']) ? $area['select'] : $area_id; |
|
267
|
|
|
$include_data = $area; |
|
268
|
|
|
} |
|
269
|
|
|
} |
|
270
|
|
|
} |
|
271
|
14 |
|
} |
|
272
|
|
|
|
|
273
|
|
|
if (!isset($context['current_subaction']) && isset($menu_context['current_subsection'])) |
|
274
|
|
|
{ |
|
275
|
|
|
$context['current_subaction'] = $menu_context['current_subsection']; |
|
276
|
|
|
} |
|
277
|
14 |
|
|
|
278
|
|
|
// Should we use a custom base url, or use the default? |
|
279
|
|
|
$menu_context['base_url'] = isset($menuOptions['base_url']) ? $menuOptions['base_url'] : $scripturl . '?action=' . $menu_context['current_action']; |
|
280
|
14 |
|
|
|
281
|
|
|
// If there are sections quickly goes through all the sections to check if the base menu has an url |
|
282
|
14 |
|
if (!empty($menu_context['current_section'])) |
|
283
|
14 |
|
{ |
|
284
|
14 |
|
$menu_context['sections'][$menu_context['current_section']]['selected'] = true; |
|
285
|
|
|
$menu_context['sections'][$menu_context['current_section']]['areas'][$menu_context['current_area']]['selected'] = true; |
|
286
|
|
|
if (!empty($menu_context['sections'][$menu_context['current_section']]['areas'][$menu_context['current_area']]['subsections'][$context['current_subaction']])) |
|
287
|
14 |
|
$menu_context['sections'][$menu_context['current_section']]['areas'][$menu_context['current_area']]['subsections'][$context['current_subaction']]['selected'] = true; |
|
288
|
14 |
|
|
|
289
|
|
|
foreach ($menu_context['sections'] as $section_id => $section) |
|
290
|
14 |
|
foreach ($section['areas'] as $area_id => $area) |
|
291
|
|
|
{ |
|
292
|
14 |
|
if (!isset($menu_context['sections'][$section_id]['url'])) |
|
293
|
14 |
|
{ |
|
294
|
|
|
$menu_context['sections'][$section_id]['url'] = isset($area['url']) ? $area['url'] : $menu_context['base_url'] . ';area=' . $area_id; |
|
295
|
|
|
break; |
|
296
|
|
|
} |
|
297
|
|
|
} |
|
298
|
|
|
} |
|
299
|
14 |
|
|
|
300
|
|
|
// If we didn't find the area we were looking for go to a default one. |
|
301
|
|
|
if (isset($backup_area) && empty($found_section)) |
|
302
|
|
|
$menu_context['current_area'] = $backup_area; |
|
303
|
14 |
|
|
|
304
|
|
|
// If still no data then return - nothing to show! |
|
305
|
|
|
if (empty($menu_context['sections'])) |
|
306
|
|
|
{ |
|
307
|
|
|
// Never happened! |
|
308
|
|
|
$context['max_menu_id']--; |
|
309
|
|
|
if ($context['max_menu_id'] == 0) |
|
310
|
|
|
unset($context['max_menu_id']); |
|
311
|
|
|
|
|
312
|
|
|
return false; |
|
313
|
|
|
} |
|
314
|
14 |
|
|
|
315
|
|
|
// What type of menu is this? |
|
316
|
14 |
|
if (empty($menuOptions['menu_type'])) |
|
317
|
14 |
|
{ |
|
318
|
|
|
$menuOptions['menu_type'] = '_' . (empty($options['use_sidebar_menu']) ? 'dropdown' : 'sidebar'); |
|
319
|
|
|
$menu_context['can_toggle_drop_down'] = User::$info->is_guest === false && isset($settings['theme_version']) && $settings['theme_version'] >= 2.0; |
|
|
|
|
|
|
320
|
|
|
} |
|
321
|
|
|
else |
|
322
|
|
|
$menu_context['can_toggle_drop_down'] = !empty($menuOptions['can_toggle_drop_down']); |
|
323
|
14 |
|
|
|
324
|
14 |
|
// Almost there - load the template and add to the template layers. |
|
325
|
14 |
|
theme()->getTemplates()->load(isset($menuOptions['template_name']) ? $menuOptions['template_name'] : 'GenericMenu'); |
|
326
|
|
|
$menu_context['layer_name'] = (isset($menuOptions['layer_name']) ? $menuOptions['layer_name'] : 'generic_menu') . $menuOptions['menu_type']; |
|
327
|
|
|
theme()->getLayers()->add($menu_context['layer_name']); |
|
328
|
14 |
|
|
|
329
|
|
|
// Check we had something - for sanity sake. |
|
330
|
|
|
if (empty($include_data)) |
|
331
|
|
|
return false; |
|
332
|
|
|
|
|
333
|
14 |
|
// Finally - return information on the selected item. |
|
334
|
14 |
|
$include_data += array( |
|
335
|
14 |
|
'current_action' => $menu_context['current_action'], |
|
336
|
14 |
|
'current_area' => $menu_context['current_area'], |
|
337
|
|
|
'current_section' => $menu_context['current_section'], |
|
338
|
|
|
'current_subsection' => !empty($menu_context['current_subsection']) ? $menu_context['current_subsection'] : '', |
|
339
|
14 |
|
); |
|
340
|
|
|
|
|
341
|
|
|
return $include_data; |
|
342
|
|
|
} |
|
343
|
|
|
|
|
344
|
|
|
/** |
|
345
|
|
|
* Delete a menu. |
|
346
|
|
|
* |
|
347
|
|
|
* @param string $menu_id = 'last' |
|
348
|
|
|
* @return false|null |
|
349
|
|
|
*/ |
|
350
|
10 |
|
function destroyMenu($menu_id = 'last') |
|
351
|
|
|
{ |
|
352
|
10 |
|
global $context; |
|
353
|
10 |
|
|
|
354
|
|
|
$menu_name = $menu_id == 'last' && isset($context['max_menu_id']) && isset($context['menu_data_' . $context['max_menu_id']]) ? 'menu_data_' . $context['max_menu_id'] : 'menu_data_' . $menu_id; |
|
355
|
|
|
if (!isset($context[$menu_name])) |
|
356
|
10 |
|
return false; |
|
357
|
|
|
|
|
358
|
10 |
|
theme()->getLayers()->remove($context[$menu_name]['layer_name']); |
|
359
|
10 |
|
|
|
360
|
|
|
unset($context[$menu_name]); |
|
361
|
|
|
} |
|
362
|
|
|
|
|
363
|
|
|
/** |
|
364
|
|
|
* Call the function or method for the selected menu item. |
|
365
|
|
|
* $selectedMenu is the array of menu information, with the format as retrieved from createMenu() |
|
366
|
|
|
* |
|
367
|
|
|
* If $selectedMenu['controller'] is set, then it is a class, and $selectedMenu['function'] will be a method of it. |
|
368
|
|
|
* If it is not set, then $selectedMenu['function'] is simply a function to call. |
|
369
|
|
|
* |
|
370
|
|
|
* @param array|string $selectedMenu |
|
371
|
|
|
*/ |
|
372
|
|
|
function callMenu($selectedMenu) |
|
373
|
|
|
{ |
|
374
|
|
|
// We use only $selectedMenu['function'] and |
|
375
|
2 |
|
// $selectedMenu['controller'] if the latter is set. |
|
376
|
|
|
|
|
377
|
|
View Code Duplication |
if (!empty($selectedMenu['controller'])) |
|
378
|
|
|
{ |
|
379
|
2 |
|
// 'controller' => '\\ElkArte\\AdminController\\ManageAttachments' |
|
380
|
2 |
|
// 'function' => 'action_avatars' |
|
381
|
|
|
$controller = new $selectedMenu['controller'](new \ElkArte\EventManager()); |
|
382
|
|
|
$controller->setUser(User::$info); |
|
383
|
2 |
|
|
|
384
|
|
|
// always set up the environment |
|
385
|
2 |
|
$controller->pre_dispatch(); |
|
386
|
|
|
// and go! |
|
387
|
|
|
$controller->{$selectedMenu['function']}(); |
|
388
|
|
|
} |
|
389
|
|
|
else |
|
390
|
|
|
{ |
|
391
|
|
|
// a single function name... call it over! |
|
392
|
2 |
|
$selectedMenu['function'](); |
|
393
|
|
|
} |
|
394
|
|
|
} |
|
395
|
|
|
|
|
396
|
|
|
/** |
|
397
|
|
|
* Loads up all the default menu entries available. |
|
398
|
|
|
* |
|
399
|
|
|
* @return array |
|
|
|
|
|
|
400
|
|
|
*/ |
|
401
|
|
|
function loadDefaultMenuButtons() |
|
402
|
|
|
{ |
|
403
|
|
|
global $scripturl, $txt, $context, $modSettings; |
|
404
|
|
|
|
|
405
|
|
|
$buttons = array( |
|
406
|
|
|
'home' => array( |
|
407
|
|
|
'title' => $txt['community'], |
|
408
|
|
|
'href' => getUrl('home', []), |
|
409
|
|
|
'data-icon' => 'i-home', |
|
410
|
|
|
'show' => true, |
|
411
|
|
|
'sub_buttons' => array( |
|
412
|
|
|
'help' => array( |
|
413
|
|
|
'title' => $txt['help'], |
|
414
|
|
|
'href' => getUrl('action', ['action' => 'help']), |
|
415
|
|
|
'show' => true, |
|
416
|
|
|
), |
|
417
|
|
|
'search' => array( |
|
418
|
|
|
'title' => $txt['search'], |
|
419
|
|
|
'href' => getUrl('action', ['action' => 'search']), |
|
420
|
|
|
'show' => $context['allow_search'], |
|
421
|
|
|
), |
|
422
|
|
|
'calendar' => array( |
|
423
|
|
|
'title' => $txt['calendar'], |
|
424
|
|
|
'href' => getUrl('action', ['action' => 'calendar']), |
|
425
|
|
|
'show' => $context['allow_calendar'], |
|
426
|
|
|
), |
|
427
|
|
|
'memberlist' => array( |
|
428
|
|
|
'title' => $txt['members_title'], |
|
429
|
|
|
'href' => getUrl('action', ['action' => 'memberlist']), |
|
430
|
|
|
'show' => $context['allow_memberlist'], |
|
431
|
|
|
), |
|
432
|
|
|
'recent' => array( |
|
433
|
|
|
'title' => $txt['recent_posts'], |
|
434
|
|
|
'href' => getUrl('action', ['action' => 'recent']), |
|
435
|
|
|
'show' => true, |
|
436
|
|
|
), |
|
437
|
|
|
'like_stats' => array( |
|
438
|
|
|
'title' => $txt['like_post_stats'], |
|
439
|
|
|
'href' => getUrl('action', ['action' => 'likes', 'sa' => 'likestats']), |
|
440
|
|
|
'show' => !empty($modSettings['likes_enabled']) && allowedTo('like_posts_stats'), |
|
441
|
|
|
), |
|
442
|
|
|
'contact' => array( |
|
443
|
|
|
'title' => $txt['contact'], |
|
444
|
|
|
'href' => getUrl('action', ['action' => 'register', 'sa' => 'contact']), |
|
445
|
|
|
'show' => User::$info->is_guest && !empty($modSettings['enable_contactform']) && $modSettings['enable_contactform'] == 'menu', |
|
|
|
|
|
|
446
|
|
|
), |
|
447
|
|
|
), |
|
448
|
|
|
) |
|
449
|
|
|
); |
|
450
|
|
|
|
|
451
|
|
|
// Will change title correctly if user is either a mod or an admin. |
|
452
|
|
|
// Button highlighting works properly too (see current action stuffz). |
|
453
|
|
|
if ($context['allow_admin']) |
|
454
|
|
|
{ |
|
455
|
|
|
$buttons['admin'] = array( |
|
456
|
|
|
'title' => $context['current_action'] !== 'moderate' ? $txt['admin'] : $txt['moderate'], |
|
457
|
|
|
'counter' => 'grand_total', |
|
458
|
|
|
'href' => $scripturl . '?action=admin', |
|
459
|
|
|
'data-icon' => 'i-cog', |
|
460
|
|
|
'show' => true, |
|
461
|
|
|
'sub_buttons' => array( |
|
462
|
|
|
'admin_center' => array( |
|
463
|
|
|
'title' => $txt['admin_center'], |
|
464
|
|
|
'href' => $scripturl . '?action=admin', |
|
465
|
|
|
'show' => $context['allow_admin'], |
|
466
|
|
|
), |
|
467
|
|
|
'featuresettings' => array( |
|
468
|
|
|
'title' => $txt['modSettings_title'], |
|
469
|
|
|
'href' => $scripturl . '?action=admin;area=featuresettings', |
|
470
|
|
|
'show' => allowedTo('admin_forum'), |
|
471
|
|
|
), |
|
472
|
|
|
'packages' => array( |
|
473
|
|
|
'title' => $txt['package'], |
|
474
|
|
|
'href' => $scripturl . '?action=admin;area=packages', |
|
475
|
|
|
'show' => allowedTo('admin_forum'), |
|
476
|
|
|
), |
|
477
|
|
|
'permissions' => array( |
|
478
|
|
|
'title' => $txt['edit_permissions'], |
|
479
|
|
|
'href' => $scripturl . '?action=admin;area=permissions', |
|
480
|
|
|
'show' => allowedTo('manage_permissions'), |
|
481
|
|
|
), |
|
482
|
|
|
'errorlog' => array( |
|
483
|
|
|
'title' => $txt['errlog'], |
|
484
|
|
|
'href' => $scripturl . '?action=admin;area=logs;sa=errorlog;desc', |
|
485
|
|
|
'show' => allowedTo('admin_forum') && !empty($modSettings['enableErrorLogging']), |
|
486
|
|
|
), |
|
487
|
|
|
'moderate_sub' => array( |
|
488
|
|
|
'title' => $txt['moderate'], |
|
489
|
|
|
'counter' => 'grand_total', |
|
490
|
|
|
'href' => $scripturl . '?action=moderate', |
|
491
|
|
|
'show' => $context['allow_moderation_center'], |
|
492
|
|
|
'sub_buttons' => array( |
|
493
|
|
|
'reports' => array( |
|
494
|
|
|
'title' => $txt['mc_reported_posts'], |
|
495
|
|
|
'counter' => 'reports', |
|
496
|
|
|
'href' => $scripturl . '?action=moderate;area=reports', |
|
497
|
|
|
'show' => !empty(User::$info->mod_cache) && User::$info->mod_cache['bq'] != '0=1', |
|
|
|
|
|
|
498
|
|
|
), |
|
499
|
|
|
'modlog' => array( |
|
500
|
|
|
'title' => $txt['modlog_view'], |
|
501
|
|
|
'href' => $scripturl . '?action=moderate;area=modlog', |
|
502
|
|
|
'show' => !empty($modSettings['modlog_enabled']) && !empty(User::$info->mod_cache) && User::$info->mod_cache['bq'] != '0=1', |
|
|
|
|
|
|
503
|
|
|
), |
|
504
|
|
|
'attachments' => array( |
|
505
|
|
|
'title' => $txt['mc_unapproved_attachments'], |
|
506
|
|
|
'counter' => 'attachments', |
|
507
|
|
|
'href' => $scripturl . '?action=moderate;area=attachmod;sa=attachments', |
|
508
|
|
|
'show' => $modSettings['postmod_active'] && !empty(User::$info->mod_cache['ap']), |
|
|
|
|
|
|
509
|
|
|
), |
|
510
|
|
|
'poststopics' => array( |
|
511
|
|
|
'title' => $txt['mc_unapproved_poststopics'], |
|
512
|
|
|
'counter' => 'postmod', |
|
513
|
|
|
'href' => $scripturl . '?action=moderate;area=postmod;sa=posts', |
|
514
|
|
|
'show' => $modSettings['postmod_active'] && !empty(User::$info->mod_cache['ap']), |
|
|
|
|
|
|
515
|
|
|
), |
|
516
|
|
|
'postbyemail' => array( |
|
517
|
|
|
'title' => $txt['mc_emailerror'], |
|
518
|
|
|
'counter' => 'emailmod', |
|
519
|
|
|
'href' => $scripturl . '?action=admin;area=maillist;sa=emaillist', |
|
520
|
|
|
'show' => !empty($modSettings['maillist_enabled']) && allowedTo('approve_emails'), |
|
521
|
|
|
), |
|
522
|
|
|
), |
|
523
|
|
|
), |
|
524
|
|
|
), |
|
525
|
|
|
); |
|
526
|
|
|
} |
|
527
|
|
|
else |
|
528
|
|
|
{ |
|
529
|
|
|
$buttons['admin'] = array( |
|
530
|
|
|
'title' => $txt['moderate'], |
|
531
|
|
|
'counter' => 'grand_total', |
|
532
|
|
|
'href' => $scripturl . '?action=moderate', |
|
533
|
|
|
'data-icon' => 'i-cog', |
|
534
|
|
|
'show' => $context['allow_moderation_center'], |
|
535
|
|
|
'sub_buttons' => array( |
|
536
|
|
|
'reports' => array( |
|
537
|
|
|
'title' => $txt['mc_reported_posts'], |
|
538
|
|
|
'counter' => 'reports', |
|
539
|
|
|
'href' => $scripturl . '?action=moderate;area=reports', |
|
540
|
|
|
'show' => !empty(User::$info->mod_cache) && User::$info->mod_cache['bq'] != '0=1', |
|
|
|
|
|
|
541
|
|
|
), |
|
542
|
|
|
'modlog' => array( |
|
543
|
|
|
'title' => $txt['modlog_view'], |
|
544
|
|
|
'href' => $scripturl . '?action=moderate;area=modlog', |
|
545
|
|
|
'show' => !empty($modSettings['modlog_enabled']) && !empty(User::$info->mod_cache) && User::$info->mod_cache['bq'] != '0=1', |
|
|
|
|
|
|
546
|
|
|
), |
|
547
|
|
|
'attachments' => array( |
|
548
|
|
|
'title' => $txt['mc_unapproved_attachments'], |
|
549
|
|
|
'counter' => 'attachments', |
|
550
|
|
|
'href' => $scripturl . '?action=moderate;area=attachmod;sa=attachments', |
|
551
|
|
|
'show' => $modSettings['postmod_active'] && !empty(User::$info->mod_cache['ap']), |
|
|
|
|
|
|
552
|
|
|
), |
|
553
|
|
|
'poststopics' => array( |
|
554
|
|
|
'title' => $txt['mc_unapproved_poststopics'], |
|
555
|
|
|
'counter' => 'postmod', |
|
556
|
|
|
'href' => $scripturl . '?action=moderate;area=postmod;sa=posts', |
|
557
|
|
|
'show' => $modSettings['postmod_active'] && !empty(User::$info->mod_cache['ap']), |
|
|
|
|
|
|
558
|
|
|
), |
|
559
|
|
|
'postbyemail' => array( |
|
560
|
|
|
'title' => $txt['mc_emailerror'], |
|
561
|
|
|
'counter' => 'emailmod', |
|
562
|
|
|
'href' => $scripturl . '?action=admin;area=maillist;sa=emaillist', |
|
563
|
|
|
'show' => !empty($modSettings['maillist_enabled']) && allowedTo('approve_emails'), |
|
564
|
|
|
), |
|
565
|
|
|
), |
|
566
|
|
|
); |
|
567
|
|
|
} |
|
568
|
|
|
|
|
569
|
|
|
$buttons += array( |
|
570
|
|
|
'profile' => array( |
|
571
|
|
|
'title' => !empty($modSettings['displayMemberNames']) ? User::$info->name : $txt['account_short'], |
|
|
|
|
|
|
572
|
|
|
'href' => getUrl('profile', ['action' => 'profile', 'u' => User::$info->id, 'name' => User::$info->name]), |
|
|
|
|
|
|
573
|
|
|
'data-icon' => 'i-account', |
|
574
|
|
|
'show' => $context['allow_edit_profile'], |
|
575
|
|
|
'sub_buttons' => array( |
|
576
|
|
|
'account' => array( |
|
577
|
|
|
'title' => $txt['account'], |
|
578
|
|
|
'href' => getUrl('profile', ['action' => 'profile', 'area' => 'account', 'u' => User::$info->id, 'name' => User::$info->name]), |
|
|
|
|
|
|
579
|
|
|
'show' => allowedTo(array('profile_identity_any', 'profile_identity_own', 'manage_membergroups')), |
|
580
|
|
|
), |
|
581
|
|
|
'drafts' => array( |
|
582
|
|
|
'title' => $txt['mydrafts'], |
|
583
|
|
|
'href' => getUrl('profile', ['action' => 'profile', 'area' => 'showdrafts', 'u' => User::$info->id, 'name' => User::$info->name]), |
|
|
|
|
|
|
584
|
|
|
'show' => !empty($modSettings['drafts_enabled']) && !empty($modSettings['drafts_post_enabled']) && allowedTo('post_draft'), |
|
585
|
|
|
), |
|
586
|
|
|
'forumprofile' => array( |
|
587
|
|
|
'title' => $txt['forumprofile'], |
|
588
|
|
|
'href' => getUrl('profile', ['action' => 'profile', 'area' => 'forumprofile', 'u' => User::$info->id, 'name' => User::$info->name]), |
|
|
|
|
|
|
589
|
|
|
'show' => allowedTo(array('profile_extra_any', 'profile_extra_own')), |
|
590
|
|
|
), |
|
591
|
|
|
'theme' => array( |
|
592
|
|
|
'title' => $txt['theme'], |
|
593
|
|
|
'href' => getUrl('profile', ['action' => 'profile', 'area' => 'theme', 'u' => User::$info->id, 'name' => User::$info->name]), |
|
|
|
|
|
|
594
|
|
|
'show' => allowedTo(array('profile_extra_any', 'profile_extra_own', 'profile_extra_any')), |
|
595
|
|
|
), |
|
596
|
|
|
'logout' => array( |
|
597
|
|
|
'title' => $txt['logout'], |
|
598
|
|
|
'href' => getUrl('action', ['action' => 'logout']), |
|
599
|
|
|
'show' => User::$info->is_guest === false, |
|
|
|
|
|
|
600
|
|
|
), |
|
601
|
|
|
), |
|
602
|
|
|
), |
|
603
|
|
|
// @todo Look at doing something here, to provide instant access to inbox when using click menus. |
|
604
|
|
|
// @todo A small pop-up anchor seems like the obvious way to handle it. ;) |
|
605
|
|
|
'pm' => array( |
|
606
|
|
|
'title' => $txt['pm_short'], |
|
607
|
|
|
'counter' => 'unread_messages', |
|
608
|
|
|
'href' => getUrl('action', ['action' => 'pm']), |
|
609
|
|
|
'data-icon' => ($context['user']['unread_messages'] ? 'i-envelope' : 'i-envelope-blank'), |
|
610
|
|
|
'show' => $context['allow_pm'], |
|
611
|
|
|
'sub_buttons' => array( |
|
612
|
|
|
'pm_read' => array( |
|
613
|
|
|
'title' => $txt['pm_menu_read'], |
|
614
|
|
|
'href' => getUrl('action', ['action' => 'pm']), |
|
615
|
|
|
'show' => allowedTo('pm_read'), |
|
616
|
|
|
), |
|
617
|
|
|
'pm_send' => array( |
|
618
|
|
|
'title' => $txt['pm_menu_send'], |
|
619
|
|
|
'href' => getUrl('action', ['action' => 'pm', 'sa' => 'send']), |
|
620
|
|
|
'show' => allowedTo('pm_send'), |
|
621
|
|
|
), |
|
622
|
|
|
), |
|
623
|
|
|
), |
|
624
|
|
|
'mentions' => array( |
|
625
|
|
|
'title' => $txt['mention'], |
|
626
|
|
|
'counter' => 'mentions', |
|
627
|
|
|
'href' => getUrl('action', ['action' => 'mentions']), |
|
628
|
|
|
'data-icon' => ($context['user']['mentions'] ? 'i-bell' : 'i-bell-blank'), |
|
629
|
|
|
'show' => User::$info->is_guest === false && !empty($modSettings['mentions_enabled']), |
|
|
|
|
|
|
630
|
|
|
), |
|
631
|
|
|
// The old language string made no sense, and was too long. |
|
632
|
|
|
// "New posts" is better, because there are probably a pile |
|
633
|
|
|
// of old unread posts, and they wont be reached from this button. |
|
634
|
|
|
'unread' => array( |
|
635
|
|
|
'title' => $txt['view_unread_category'], |
|
636
|
|
|
'href' => getUrl('action', ['action' => 'unread']), |
|
637
|
|
|
'data-icon' => 'i-comments', |
|
638
|
|
|
'show' => User::$info->is_guest === false, |
|
|
|
|
|
|
639
|
|
|
), |
|
640
|
|
|
// The old language string made no sense, and was too long. |
|
641
|
|
|
// "New replies" is better, because there are "updated topics" |
|
642
|
|
|
// that the user has never posted in and doesn't care about. |
|
643
|
|
|
'unreadreplies' => array( |
|
644
|
|
|
'title' => $txt['view_replies_category'], |
|
645
|
|
|
'href' => getUrl('action', ['action' => 'unreadreplies']), |
|
646
|
|
|
'data-icon' => 'i-comments-blank', |
|
647
|
|
|
'show' => User::$info->is_guest === false, |
|
|
|
|
|
|
648
|
|
|
), |
|
649
|
|
|
'login' => array( |
|
650
|
|
|
'title' => $txt['login'], |
|
651
|
|
|
'href' => getUrl('action', ['action' => 'login']), |
|
652
|
|
|
'data-icon' => 'i-sign-in', |
|
653
|
|
|
'show' => User::$info->is_guest, |
|
|
|
|
|
|
654
|
|
|
), |
|
655
|
|
|
|
|
656
|
|
|
'register' => array( |
|
657
|
|
|
'title' => $txt['register'], |
|
658
|
|
|
'href' => getUrl('action', ['action' => 'register']), |
|
659
|
|
|
'data-icon' => 'i-register', |
|
660
|
|
|
'show' => User::$info->is_guest && $context['can_register'], |
|
|
|
|
|
|
661
|
|
|
), |
|
662
|
|
|
); |
|
663
|
|
|
|
|
664
|
|
|
return $buttons; |
|
665
|
|
|
} |
|
666
|
|
|
|
This check compares the return type specified in the
@returnannotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.