1 | <?php |
||
2 | |||
3 | /** |
||
4 | * @package Ultimate Menu mod |
||
5 | * @version 1.0.4 |
||
6 | * @author John Rayes <[email protected]> |
||
7 | * @copyright Copyright (c) 2014, John Rayes |
||
8 | * @license http://opensource.org/licenses/MIT MIT |
||
9 | */ |
||
10 | |||
11 | if (!defined('SMF')) |
||
12 | die('Hacking attempt...'); |
||
13 | |||
14 | function Menu() |
||
15 | { |
||
16 | global $context, $txt; |
||
17 | |||
18 | loadTemplate('ManageUltimateMenu'); |
||
19 | |||
20 | $subActions = array( |
||
21 | 'manmenu' => 'ManageUltimateMenu', |
||
22 | 'addbutton' => 'PrepareContext', |
||
23 | 'savebutton' => 'SaveButton', |
||
24 | ); |
||
25 | |||
26 | // Default to sub action 'manmenu' |
||
27 | if (!isset($_GET['sa']) || !isset($subActions[$_GET['sa']])) |
||
28 | $_GET['sa'] = 'manmenu'; |
||
29 | |||
30 | // Have you got the proper permissions? |
||
31 | isAllowedTo('admin_forum'); |
||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||
32 | |||
33 | $context['page_title'] = $txt['admin_menu_title']; |
||
34 | |||
35 | // Load up all the tabs... |
||
36 | $context[$context['admin_menu_name']]['tab_data'] = array( |
||
37 | 'title' => &$txt['admin_menu'], |
||
38 | 'description' => $txt['admin_menu_desc'], |
||
39 | 'tabs' => array( |
||
40 | 'manmenu' => array( |
||
41 | 'description' => $txt['admin_manage_menu_desc'], |
||
42 | ), |
||
43 | 'addbutton' => array( |
||
44 | 'description' => $txt['admin_menu_add_button_desc'], |
||
45 | ), |
||
46 | ), |
||
47 | ); |
||
48 | |||
49 | // Call the right function for this sub-acton. |
||
50 | $subActions[$_GET['sa']](); |
||
51 | |||
52 | } |
||
53 | |||
54 | function ManageUltimateMenu() |
||
55 | { |
||
56 | global $context, $txt, $modSettings, $scripturl, $sourcedir, $smcFunc; |
||
57 | |||
58 | // Get rid of all of em! |
||
59 | if (!empty($_POST['removeAll'])) |
||
60 | { |
||
61 | checkSession(); |
||
62 | |||
63 | $smcFunc['db_query']('truncate_table', ' |
||
64 | TRUNCATE {db_prefix}um_menu'); |
||
65 | |||
66 | rebuild_um_menu(); |
||
67 | redirectexit('action=admin;area=umen'); |
||
68 | } |
||
69 | |||
70 | // User pressed the 'remove selection button'. |
||
71 | if (!empty($_POST['removeButtons']) && !empty($_POST['remove']) && is_array($_POST['remove'])) |
||
72 | { |
||
73 | checkSession(); |
||
74 | |||
75 | // Make sure every entry is a proper integer. |
||
76 | foreach ($_POST['remove'] as $index => $page_id) |
||
77 | $_POST['remove'][(int) $index] = (int) $page_id; |
||
78 | |||
79 | // Delete the page! |
||
80 | $smcFunc['db_query']('', ' |
||
81 | DELETE FROM {db_prefix}um_menu |
||
82 | WHERE id_button IN ({array_int:button_list})', |
||
83 | array( |
||
84 | 'button_list' => $_POST['remove'], |
||
85 | ) |
||
86 | ); |
||
87 | rebuild_um_menu(); |
||
88 | redirectexit('action=admin;area=umen'); |
||
89 | } |
||
90 | |||
91 | // Changing the status? |
||
92 | if (isset($_POST['save'])) |
||
93 | { |
||
94 | checkSession(); |
||
95 | foreach (total_getMenu() as $item) |
||
96 | { |
||
97 | $status = !empty($_POST['status'][$item['id_button']]) ? 'active' : 'inactive'; |
||
98 | if ($status != $item['status']) |
||
99 | $smcFunc['db_query']('', ' |
||
100 | UPDATE {db_prefix}um_menu |
||
101 | SET status = {string:status} |
||
102 | WHERE id_button = {int:item}', |
||
103 | array( |
||
104 | 'status' => $status, |
||
105 | 'item' => $item['id_button'], |
||
106 | ) |
||
107 | ); |
||
108 | } |
||
109 | rebuild_um_menu(); |
||
110 | redirectexit('action=admin;area=umen'); |
||
111 | } |
||
112 | |||
113 | // New item? |
||
114 | if (isset($_POST['new'])) |
||
115 | redirectexit('action=admin;area=umen;sa=addbutton'); |
||
116 | |||
117 | loadLanguage('ManageBoards'); |
||
118 | |||
119 | // Our options for our list. |
||
120 | $listOptions = array( |
||
121 | 'id' => 'menu_list', |
||
122 | 'items_per_page' => 20, |
||
123 | 'base_href' => $scripturl . '?action=admin;area=umen;sa=manmenu', |
||
124 | 'default_sort_col' => 'id_button', |
||
125 | 'default_sort_dir' => 'desc', |
||
126 | 'get_items' => array( |
||
127 | 'function' => 'list_getMenu', |
||
128 | ), |
||
129 | 'get_count' => array( |
||
130 | 'function' => 'list_getNumButtons', |
||
131 | ), |
||
132 | 'no_items_label' => $txt['um_menu_no_buttons'], |
||
133 | 'columns' => array( |
||
134 | 'id_button' => array( |
||
135 | 'header' => array( |
||
136 | 'value' => $txt['um_menu_button_id'], |
||
137 | ), |
||
138 | 'data' => array( |
||
139 | 'db' => 'id_button', |
||
140 | 'class' => 'centertext', |
||
141 | ), |
||
142 | 'sort' => array( |
||
143 | 'default' => 'men.id_button', |
||
144 | 'reverse' => 'men.id_button DESC', |
||
145 | ), |
||
146 | ), |
||
147 | 'name' => array( |
||
148 | 'header' => array( |
||
149 | 'value' => $txt['um_menu_button_name'], |
||
150 | ), |
||
151 | 'data' => array( |
||
152 | 'db_htmlsafe' => 'name', |
||
153 | 'class' => 'centertext', |
||
154 | ), |
||
155 | 'sort' => array( |
||
156 | 'default' => 'men.name', |
||
157 | 'reverse' => 'men.name DESC', |
||
158 | ), |
||
159 | ), |
||
160 | 'type' => array( |
||
161 | 'header' => array( |
||
162 | 'value' => $txt['um_menu_button_type'], |
||
163 | ), |
||
164 | 'data' => array( |
||
165 | 'function' => function($rowData) use ($txt) |
||
166 | { |
||
167 | return $txt[$rowData['type'] . '_link']; |
||
168 | }, |
||
169 | 'class' => 'centertext', |
||
170 | ), |
||
171 | 'sort' => array( |
||
172 | 'default' => 'men.type', |
||
173 | 'reverse' => 'men.type DESC', |
||
174 | ), |
||
175 | ), |
||
176 | 'poition' => array( |
||
177 | 'header' => array( |
||
178 | 'value' => $txt['um_menu_button_position'], |
||
179 | ), |
||
180 | 'data' => array( |
||
181 | 'function' => function($rowData) use ($txt) |
||
182 | { |
||
183 | return $txt['mboards_order_' . $rowData['position']] . ' ' . ucwords($rowData['parent']); |
||
184 | }, |
||
185 | 'class' => 'centertext', |
||
186 | ), |
||
187 | 'sort' => array( |
||
188 | 'default' => 'men.position', |
||
189 | 'reverse' => 'men.position DESC', |
||
190 | ), |
||
191 | ), |
||
192 | 'link' => array( |
||
193 | 'header' => array( |
||
194 | 'value' => $txt['um_menu_button_link'], |
||
195 | ), |
||
196 | 'data' => array( |
||
197 | 'db_htmlsafe' => 'link', |
||
198 | 'class' => 'centertext', |
||
199 | ), |
||
200 | 'sort' => array( |
||
201 | 'default' => 'men.link', |
||
202 | 'reverse' => 'men.link DESC', |
||
203 | ), |
||
204 | ), |
||
205 | 'status' => array( |
||
206 | 'header' => array( |
||
207 | 'value' => $txt['um_menu_button_active'], |
||
208 | ), |
||
209 | 'data' => array( |
||
210 | 'function' => function($rowData) use ($txt) |
||
211 | { |
||
212 | $isChecked = $rowData['status'] == 'inactive' ? '' : ' checked="checked"'; |
||
213 | return sprintf('<span>%3$s</span> <input type="checkbox" name="status[%1$s]" id="status_%1$s" value="%1$s"%2$s />', $rowData['id_button'], $isChecked, $txt[$rowData['status']], $rowData['status']); |
||
214 | }, |
||
215 | 'class' => 'centertext', |
||
216 | ), |
||
217 | 'sort' => array( |
||
218 | 'default' => 'men.status', |
||
219 | 'reverse' => 'men.status DESC', |
||
220 | ), |
||
221 | ), |
||
222 | 'actions' => array( |
||
223 | 'header' => array( |
||
224 | 'value' => $txt['um_menu_actions'], |
||
225 | ), |
||
226 | 'data' => array( |
||
227 | 'sprintf' => array( |
||
228 | 'format' => '<a href="' . $scripturl . '?action=admin;area=umen;sa=addbutton;edit;in=%1$d">' . $txt['modify'] . '</a>', |
||
229 | 'params' => array( |
||
230 | 'id_button' => false, |
||
231 | ), |
||
232 | ), |
||
233 | 'class' => 'centertext', |
||
234 | ), |
||
235 | ), |
||
236 | 'check' => array( |
||
237 | 'header' => array( |
||
238 | 'value' => '<input type="checkbox" onclick="invertAll(this, this.form);" class="input_check" />', |
||
239 | ), |
||
240 | 'data' => array( |
||
241 | 'sprintf' => array( |
||
242 | 'format' => '<input type="checkbox" name="remove[]" value="%1$d" class="input_check" />', |
||
243 | 'params' => array( |
||
244 | 'id_button' => false, |
||
245 | ), |
||
246 | ), |
||
247 | 'class' => 'centertext', |
||
248 | ), |
||
249 | ), |
||
250 | ), |
||
251 | 'form' => array( |
||
252 | 'href' => $scripturl . '?action=admin;area=umen;sa=manmenu', |
||
253 | ), |
||
254 | 'additional_rows' => array( |
||
255 | array( |
||
256 | 'position' => 'below_table_data', |
||
257 | 'value' => ' |
||
258 | <input type="submit" name="removeButtons" value="' . $txt['um_menu_remove_selected'] . '" onclick="return confirm(\'' . $txt['um_menu_remove_confirm'] . '\');" class="button_submit" /> |
||
259 | <input type="submit" name="removeAll" value="' . $txt['um_menu_remove_all'] . '" onclick="return confirm(\'' . $txt['um_menu_remove_all_confirm'] . '\');" class="button_submit" /> |
||
260 | <input type="submit" name="new" value="' . $txt['um_admin_add_button'] . '" class="button_submit" /> |
||
261 | <input type="submit" name="save" value="' . $txt['save'] . '" class="button_submit" />', |
||
262 | 'class' => 'righttext', |
||
263 | ), |
||
264 | ), |
||
265 | ); |
||
266 | |||
267 | require_once($sourcedir . '/Subs-List.php'); |
||
268 | createList($listOptions); |
||
269 | |||
270 | $context['sub_template'] = 'show_list'; |
||
271 | $context['default_list'] = 'menu_list'; |
||
272 | } |
||
273 | |||
274 | function SaveButton() |
||
275 | { |
||
276 | global $context, $smcFunc, $txt, $sourcedir; |
||
277 | |||
278 | // It's expected to be present. |
||
279 | $context['user']['unread_messages'] = 0; |
||
280 | |||
281 | // Load SMF's default menu context |
||
282 | setupMenuContext(); |
||
283 | |||
284 | if (isset($_REQUEST['submit'])) |
||
285 | { |
||
286 | $post_errors = array(); |
||
287 | $required_fields = array( |
||
288 | 'name', |
||
289 | 'link', |
||
290 | 'parent', |
||
291 | ); |
||
292 | |||
293 | // Make sure we grab all of the content |
||
294 | $id = isset($_REQUEST['in']) ? (int) $_REQUEST['in'] : 0; |
||
295 | $name = isset($_REQUEST['name']) ? $_REQUEST['name'] : ''; |
||
296 | $position = isset($_REQUEST['position']) ? $_REQUEST['position'] : 'before'; |
||
297 | $type = isset($_REQUEST['type']) ? $_REQUEST['type'] : 'forum'; |
||
298 | $link = isset($_REQUEST['link']) ? $_REQUEST['link'] : ''; |
||
299 | $permissions = isset($_REQUEST['permissions']) ? implode(',', array_intersect($_REQUEST['permissions'], array_keys(list_groups(-3, 1)))) : '1'; |
||
300 | $status = isset($_REQUEST['status']) ? $_REQUEST['status'] : 'active'; |
||
301 | $parent = isset($_REQUEST['parent']) ? $_REQUEST['parent'] : 'home'; |
||
302 | $target = isset($_REQUEST['target']) ? $_REQUEST['target'] : '_self'; |
||
303 | |||
304 | // These fields are required! |
||
305 | foreach ($required_fields as $required_field) |
||
306 | if ($_POST[$required_field] == '') |
||
307 | $post_errors[$required_field] = 'um_menu_empty_' . $required_field; |
||
308 | |||
309 | // Stop making numeric names! |
||
310 | if (is_numeric($name)) |
||
311 | $post_errors['name'] = 'um_menu_numeric'; |
||
312 | |||
313 | // Let's make sure you're not trying to make a name that's already taken. |
||
314 | $request = $smcFunc['db_query']('', ' |
||
315 | SELECT id_button |
||
316 | FROM {db_prefix}um_menu |
||
317 | WHERE name = {string:name} |
||
318 | AND id_button != {int:id}', |
||
319 | array( |
||
320 | 'name' => $name, |
||
321 | 'id' => $id, |
||
322 | ) |
||
323 | ); |
||
324 | |||
325 | $check = $smcFunc['db_num_rows']($request); |
||
326 | |||
327 | $smcFunc['db_free_result']($request); |
||
328 | |||
329 | if ($check > 0) |
||
330 | $post_errors['name'] = 'um_menu_mysql'; |
||
331 | |||
332 | if (empty($post_errors)) |
||
333 | { |
||
334 | // I see you made it to the final stage, my young padawan. |
||
335 | if (!empty($id)) |
||
336 | $smcFunc['db_query']('',' |
||
337 | UPDATE {db_prefix}um_menu |
||
338 | SET name = {string:name}, type = {string:type}, target = {string:target}, position = {string:position}, link = {string:link}, status = {string:status}, permissions = {string:permissions}, parent = {string:parent} |
||
339 | WHERE id_button = {int:id}', |
||
340 | array( |
||
341 | 'id' => $id, |
||
342 | 'name' => $name, |
||
343 | 'type' => $type, |
||
344 | 'target' => $target, |
||
345 | 'position' => $position, |
||
346 | 'link' => $link, |
||
347 | 'status' => $status, |
||
348 | 'permissions' => $permissions, |
||
349 | 'parent' => $parent, |
||
350 | ) |
||
351 | ); |
||
352 | else |
||
353 | $smcFunc['db_insert']('insert', |
||
354 | '{db_prefix}um_menu', |
||
355 | array( |
||
356 | 'slug' => 'string', 'name' => 'string', 'type' => 'string', 'target' => 'string', 'position' => 'string', 'link' => 'string', 'status' => 'string', 'permissions' => 'string', 'parent' => 'string', |
||
357 | ), |
||
358 | array( |
||
359 | md5($name) . '-' . time(), $name, $type, $target, $position, $link, $status, $permissions, $parent, |
||
360 | ), |
||
361 | array('id_button') |
||
362 | ); |
||
363 | |||
364 | rebuild_um_menu(); |
||
365 | |||
366 | // Before we leave, we must clear the cache. See, SMF |
||
367 | // caches its menu at level 2 or higher. |
||
368 | clean_cache('menu_buttons'); |
||
369 | |||
370 | redirectexit('action=admin;area=umen'); |
||
371 | } |
||
372 | else |
||
373 | { |
||
374 | $context['post_error'] = $post_errors; |
||
375 | $context['error_title'] = empty($id) ? 'um_menu_errors_create' : 'um_menu_errors_modify'; |
||
376 | |||
377 | $context['button_data'] = array( |
||
378 | 'name' => $name, |
||
379 | 'type' => $type, |
||
380 | 'target' => $target, |
||
381 | 'position' => $position, |
||
382 | 'link' => $link, |
||
383 | 'parent' => $parent, |
||
384 | 'permissions' => list_groups($permissions, 1), |
||
385 | 'status' => $status, |
||
386 | 'id' => $id, |
||
387 | ); |
||
388 | |||
389 | $context['page_title'] = $txt['um_menu_edit_title']; |
||
390 | } |
||
391 | } |
||
392 | } |
||
393 | /** |
||
394 | * Prepares theme context for the template. |
||
395 | * |
||
396 | * @since 1.0 |
||
397 | */ |
||
398 | function PrepareContext() |
||
399 | { |
||
400 | global $context, $smcFunc, $txt, $sourcedir; |
||
401 | |||
402 | // It's expected to be present. |
||
403 | $context['user']['unread_messages'] = 0; |
||
404 | |||
405 | // Load SMF's default menu context |
||
406 | setupMenuContext(); |
||
407 | |||
408 | if (isset($_GET['in'])) |
||
409 | { |
||
410 | $request = $smcFunc['db_query']('', ' |
||
411 | SELECT name, target, type, position, link, status, permissions, parent |
||
412 | FROM {db_prefix}um_menu |
||
413 | WHERE id_button = {int:button} |
||
414 | LIMIT 1', |
||
415 | array( |
||
416 | 'button' => (int) $_GET['in'], |
||
417 | ) |
||
418 | ); |
||
419 | |||
420 | $row = $smcFunc['db_fetch_assoc']($request); |
||
421 | |||
422 | $context['button_data'] = array( |
||
423 | 'id' => $_GET['in'], |
||
424 | 'name' => $row['name'], |
||
425 | 'target' => $row['target'], |
||
426 | 'type' => $row['type'], |
||
427 | 'position' => $row['position'], |
||
428 | 'permissions' => list_groups($row['permissions'], 1), |
||
429 | 'link' => $row['link'], |
||
430 | 'status' => $row['status'], |
||
431 | 'parent' => $row['parent'], |
||
432 | ); |
||
433 | } |
||
434 | else |
||
435 | { |
||
436 | $context['button_data'] = array( |
||
437 | 'name' => '', |
||
438 | 'link' => '', |
||
439 | 'target' => '_self', |
||
440 | 'type' => 'forum', |
||
441 | 'position' => 'before', |
||
442 | 'status' => '1', |
||
443 | 'permissions' => list_groups('-3', 1), |
||
444 | 'parent' => 'home', |
||
445 | 'id' => 0, |
||
446 | ); |
||
447 | |||
448 | $context['page_title'] = $txt['um_menu_add_title']; |
||
449 | } |
||
450 | } |
||
451 | |||
452 | function total_getMenu() |
||
453 | { |
||
454 | global $smcFunc; |
||
455 | |||
456 | $request = $smcFunc['db_query']('', ' |
||
457 | SELECT id_button, name, target, type, position, link, status, permissions, parent |
||
458 | FROM {db_prefix}um_menu'); |
||
459 | |||
460 | $um_menu = array(); |
||
461 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
462 | $um_menu[] = $row; |
||
463 | |||
464 | return $um_menu; |
||
465 | } |
||
466 | |||
467 | function list_getMenu($start, $items_per_page, $sort) |
||
468 | { |
||
469 | global $smcFunc; |
||
470 | |||
471 | $request = $smcFunc['db_query']('', ' |
||
472 | SELECT id_button, name, target, type, position, link, status, permissions, parent |
||
473 | FROM {db_prefix}um_menu AS men |
||
474 | ORDER BY {raw:sort} |
||
475 | LIMIT {int:offset}, {int:limit}', |
||
476 | array( |
||
477 | 'sort' => $sort, |
||
478 | 'offset' => $start, |
||
479 | 'limit' => $items_per_page, |
||
480 | ) |
||
481 | ); |
||
482 | |||
483 | $um_menu = array(); |
||
484 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
485 | $um_menu[] = $row; |
||
486 | |||
487 | return $um_menu; |
||
488 | } |
||
489 | |||
490 | function list_getNumButtons() |
||
491 | { |
||
492 | global $smcFunc; |
||
493 | |||
494 | $request = $smcFunc['db_query']('', ' |
||
495 | SELECT COUNT(*) |
||
496 | FROM {db_prefix}um_menu'); |
||
497 | |||
498 | list ($numButtons) = $smcFunc['db_fetch_row']($request); |
||
499 | $smcFunc['db_free_result']($request); |
||
500 | |||
501 | return $numButtons; |
||
502 | } |
||
503 | |||
504 | function rebuild_um_menu() |
||
505 | { |
||
506 | global $smcFunc; |
||
507 | |||
508 | $request = $smcFunc['db_query']('', ' |
||
509 | SELECT * |
||
510 | FROM {db_prefix}um_menu'); |
||
511 | |||
512 | $db_buttons = array(); |
||
513 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
514 | $db_buttons[$row['id_button']] = $row; |
||
515 | |||
516 | $smcFunc['db_free_result']($request); |
||
517 | updateSettings( |
||
518 | array( |
||
519 | 'um_menu' => serialize($db_buttons), |
||
520 | ) |
||
521 | ); |
||
522 | } |
||
523 | |||
524 | ?> |
||
0 ignored issues
–
show
It is not recommended to use PHP's closing tag
?> in files other than templates.
Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore. A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever. ![]() |