PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.0.11
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.0.11
6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 5.2.2 5.3 All 153 releases
mainwp / class / class-mainwp-menu.php

class-mainwp-menu.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.0.11, at class/class-mainwp-menu.php

1,485 lines 70.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Main Menu
4 *
5 * Build & Render MainWP Main Menu.
6 *
7 * @package MainWP/Dashboard
8 */
9
10 namespace MainWP\Dashboard;
11
12 // Exit if accessed directly.
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 /**
18 * Class MainWP_Menu
19 *
20 * @package MainWP\Dashboard
21 */
22 class MainWP_Menu { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
23
24 /**
25 * Method get_class_name()
26 *
27 * Get Class Name.
28 *
29 * @return object
30 */
31 public static function get_class_name() {
32 return __CLASS__;
33 }
34
35 /**
36 * Method get_instance().
37 */
38 public static function get_instance() {
39 return new self();
40 }
41
42 /**
43 * MainWP_Menu constructor.
44 *
45 * Run each time the class is called.
46 * Define MainWP Main Menu Items.
47 */
48 public function __construct() {
49
50 /**
51 * MainWP Disable Menus items array.
52 *
53 * @global object
54 */
55 global $_mainwp_disable_menus_items;
56
57 // Init disable menu items, default is false.
58 // Use the MainWP Hook 'mainwp_main_menu_disable_menu_items' to disable menu items.
59 if ( null === $_mainwp_disable_menus_items ) {
60 $_mainwp_disable_menus_items = array(
61 // Compatible with old hooks.
62 'level_1' => array(
63 'not_set_this_level' => true,
64 ),
65 'level_2' => array(
66 // 'mainwp_tab' - Do not hide this menu.
67 'UpdatesManage' => false,
68 'managesites' => false,
69 'ManageClients' => false,
70 'ManageGroups' => false,
71 'PostBulkManage' => false,
72 'PageBulkManage' => false,
73 'ThemesManage' => false,
74 'PluginsManage' => false,
75 'UserBulkManage' => false,
76 'ManageBackups' => false,
77 'Settings' => false,
78 'Extensions' => false,
79 'ServerInformation' => false,
80 ),
81 // Compatible with old hooks.
82 'level_3' => array(),
83 );
84 }
85 }
86
87 /**
88 * Method init_mainwp_menus()
89 *
90 * Init MainWP menus.
91 *
92 * @uses \MainWP\Dashboard\MainWP_System_Utility::is_admin()
93 * @uses \MainWP\Dashboard\MainWP_Updates::init_menu()
94 * @uses \MainWP\Dashboard\MainWP_Manage_Sites::init_menu()
95 * @uses \MainWP\Dashboard\MainWP_Post::init_menu()
96 * @uses \MainWP\Dashboard\MainWP_Page::init_menu()
97 * @uses \MainWP\Dashboard\MainWP_Themes::init_menu()
98 * @uses \MainWP\Dashboard\MainWP_Plugins::init_menu()
99 * @uses \MainWP\Dashboard\MainWP_User::init_menu()
100 * @uses \MainWP\Dashboard\MainWP_Manage_Backups::init_menu()
101 * @uses \MainWP\Dashboard\MainWP_Manage_Groups::init_menu()
102 * @uses \MainWP\Dashboard\MainWP_Monitoring::init_menu()
103 * @uses \MainWP\Dashboard\MainWP_Settings::init_menu()
104 * @uses \MainWP\Dashboard\MainWP_Extensions::init_menu()
105 * @uses \MainWP\Dashboard\MainWP_Bulk_Update_Admin_Passwords::init_menu()
106 */
107 public static function init_mainwp_menus() { // phpcs:ignore -- NOSONAR - complex method. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
108 if ( MainWP_System_Utility::is_admin() ) {
109
110 $menus_items = array();
111
112 // Manage Sites.
113 $menus_items[] = array(
114 'slug' => 'managesites',
115 'menu_level' => 2,
116 'menu_rights' => array(
117 'dashboard' => array(
118 'add_sites',
119 'edit_sites',
120 'delete_sites',
121 'access_individual_dashboard',
122 'access_wpadmin_on_child_sites',
123 'manage_security_issues',
124 'test_connection',
125 'manage_groups',
126 'manage_uptime_monitoring',
127 ),
128 ),
129 'init_menu_callback' => array( MainWP_Manage_Sites::class, 'init_menu' ),
130 'leftbar_order' => 1,
131 );
132
133 // Manage Clients.
134 $menus_items[] = array(
135 'slug' => 'ManageClients',
136 'menu_level' => 2,
137 'menu_rights' => array(
138 'dashboard' => array(
139 'manage_clients',
140 ),
141 ),
142 'init_menu_callback' => array( MainWP_Client::class, 'init_menu' ),
143 'leftbar_order' => 2,
144 );
145
146 // Manage Tags.
147 $menus_items[] = array(
148 'slug' => 'ManageGroups',
149 'menu_level' => 2,
150 'menu_rights' => array(
151 'dashboard' => array(
152 'manage_groups',
153 ),
154 ),
155 'init_menu_callback' => array( MainWP_Manage_Groups::class, 'init_menu' ),
156 );
157
158 // Manage Updates.
159 $menus_items[] = array(
160 'slug' => 'UpdatesManage',
161 'menu_level' => 2,
162 'menu_rights' => array(
163 'dashboard' => array(
164 'update_wordpress',
165 'update_plugins',
166 'update_themes',
167 'update_translations',
168 'ignore_unignore_updates',
169 'trust_untrust_updates',
170 ),
171 ),
172 'init_menu_callback' => array( MainWP_Updates::class, 'init_menu' ),
173 );
174
175 // Manage Plugins.
176 $menus_items[] = array(
177 'slug' => 'PluginsManage',
178 'menu_level' => 2,
179 'menu_rights' => array(
180 'dashboard' => array(
181 'install_plugins',
182 'delete_plugins',
183 'activate_deactivate_plugins',
184 ),
185 ),
186 'init_menu_callback' => array( MainWP_Plugins::class, 'init_menu' ),
187 );
188
189 // Manage Themes.
190 $menus_items[] = array(
191 'slug' => 'ThemesManage',
192 'menu_level' => 2,
193 'menu_rights' => array(
194 'dashboard' => array(
195 'install_themes',
196 'delete_themes',
197 'activate_deactivate_themes',
198 ),
199 ),
200 'init_menu_callback' => array( MainWP_Themes::class, 'init_menu' ),
201 );
202
203 // Manage Users.
204 $menus_items[] = array(
205 'slug' => 'UserBulkManage',
206 'menu_level' => 2,
207 'menu_rights' => array(
208 'dashboard' => array(
209 'manage_users',
210 ),
211 ),
212 'init_menu_callback' => array( MainWP_User::class, 'init_menu' ),
213 );
214
215 // Manage Posts.
216 $menus_items[] = array(
217 'slug' => 'PostBulkManage',
218 'menu_level' => 2,
219 'menu_rights' => array(
220 'dashboard' => array(
221 'manage_posts',
222 ),
223 ),
224 'init_menu_callback' => array( MainWP_Post::class, 'init_menu' ),
225 );
226
227 // Manage Pages.
228 $menus_items[] = array(
229 'slug' => 'PageBulkManage',
230 'menu_level' => 2,
231 'menu_rights' => array(
232 'dashboard' => array(
233 'manage_pages',
234 ),
235 ),
236 'init_menu_callback' => array( MainWP_Page::class, 'init_menu' ),
237 );
238
239 // Manage Backups.
240 $menus_items[] = array(
241 'slug' => 'ManageBackups',
242 'menu_level' => 2,
243 'menu_rights' => true,
244 'init_menu_callback' => array( MainWP_Manage_Backups::class, 'init_menu' ),
245 );
246
247 // Manage Settings.
248 $menus_items[] = array(
249 'slug' => 'Settings',
250 'menu_level' => 2,
251 'menu_rights' => array(
252 'dashboard' => array(
253 'manage_dashboard_settings',
254 ),
255 ),
256 'init_menu_callback' => array( MainWP_Settings::class, 'init_menu' ),
257 'leftbar_order' => 5,
258 );
259
260 // Manage RESTAPI.
261 $menus_items[] = array(
262 'slug' => 'RESTAPI',
263 'menu_level' => 2,
264 'menu_rights' => true,
265 'init_menu_callback' => array( MainWP_Rest_Api_Page::class, 'init_menu' ),
266 'leftbar_order' => 4,
267 );
268
269 // Manage Extensions.
270 $menus_items[] = array(
271 'slug' => 'Extensions',
272 'menu_level' => 2,
273 'menu_rights' => true,
274 'init_menu_callback' => array( MainWP_Extensions::class, 'init_menu' ),
275 'leftbar_order' => 3,
276 );
277
278 // Manage Admin Passwords.
279 $menus_items[] = array(
280 'slug' => 'UpdateAdminPasswords',
281 'menu_level' => 2,
282 'menu_rights' => array(
283 'dashboard' => array(
284 'manage_users',
285 ),
286 ),
287 'init_menu_callback' => array( MainWP_Bulk_Update_Admin_Passwords::class, 'init_menu' ),
288 );
289
290 // Password Policy Settings.
291 $menus_items[] = array(
292 'slug' => 'PasswordPolicy',
293 'menu_level' => 2,
294 'menu_rights' => array(
295 'dashboard' => array(
296 'manage_users',
297 ),
298 ),
299 'init_menu_callback' => array( MainWP_Password_Policy_Settings::class, 'init_menu' ),
300 );
301
302 // Monitoring Sites.
303 $menus_items[] = array(
304 'slug' => 'MonitoringSites',
305 'menu_level' => 3,
306 'menu_rights' => true,
307 'init_menu_callback' => array( MainWP_Monitoring::class, 'init_menu' ),
308 );
309
310 static::init_mainwp_menu_items( $menus_items, 'first' ); // do NOT change 'first', it related other hooks.
311
312 /**
313 * Action: mainwp_admin_menu
314 *
315 * Hooks main navigation menu items.
316 *
317 * @since 4.0
318 */
319 do_action( 'mainwp_admin_menu' ); // to compatible.
320
321 $menus_items_low = array();
322
323 // Manage Admin Passwords.
324 $menus_items_low[] = array(
325 'slug' => 'ServerInformation',
326 'menu_level' => 2,
327 'menu_rights' => array(
328 'dashboard' => array(
329 'see_server_information',
330 ),
331 ),
332 'init_menu_callback' => array( MainWP_Server_Information::class, 'init_menu' ),
333 'leftbar_order' => 6,
334 );
335
336 static::init_mainwp_menu_items( $menus_items_low, 'second' );
337
338 }
339 }
340
341 /**
342 * Method init_mainwp_menu_items()
343 *
344 * Init MainWP menus.
345 *
346 * @param array $menus_items menus items.
347 * @param string $part menus part.
348 */
349 public static function init_mainwp_menu_items( $menus_items, $part ) { //phpcs:ignore -- NOSONAR - complex method.
350 if ( ! is_array( $menus_items ) ) {
351 return;
352 }
353
354 $menus_items = apply_filters( 'mainwp_init_primary_menu_items', $menus_items, $part );
355
356 MainWP_Utility::array_sort_existed_keys( $menus_items, 'leftbar_order' );
357
358 foreach ( $menus_items as $item ) {
359 if ( ! is_array( $item ) ) {
360 continue;
361 }
362
363 $empty_level = true;
364
365 if ( ! empty( $item['slug'] ) && ! empty( $item['menu_level'] ) && ! empty( $item['init_menu_callback'] ) ) {
366 $empty_level = false;
367 }
368
369 if ( ! $empty_level && ! static::is_disable_menu_item( intval( $item['menu_level'] ), $item['slug'] ) && is_callable( $item['init_menu_callback'] ) ) {
370 $accessable = false;
371 if ( isset( $item['menu_rights'] ) ) {
372 $item_rights = $item['menu_rights'];
373 if ( is_array( $item_rights ) && ! empty( $item_rights ) ) {
374 foreach ( $item_rights as $group_right => $rights ) {
375 if ( is_array( $rights ) ) {
376 foreach ( $rights as $func_right ) {
377 if ( \mainwp_current_user_can( $group_right, $func_right ) ) {
378 $accessable = true;
379 break;
380 }
381 }
382 }
383 if ( $accessable ) {
384 break;
385 }
386 }
387 } elseif ( true === $item['menu_rights'] ) {
388 $accessable = true;
389 }
390 }
391
392 if ( $accessable ) {
393 call_user_func( $item['init_menu_callback'] );
394 }
395 }
396 }
397 }
398
399 /**
400 * Method set_menu_active_slugs
401 *
402 * @param string $item Menu item.
403 * @param string $active Menu active slug.
404 */
405 public static function set_menu_active_slugs( $item, $active ) {
406 global $_mainwp_menu_active_slugs;
407 if ( ! is_array( $_mainwp_menu_active_slugs ) ) {
408 $_mainwp_menu_active_slugs = array();
409 }
410 $_mainwp_menu_active_slugs[ $item ] = $active;
411 }
412
413
414 /**
415 * Method init_subpages_left_menu
416 *
417 * Build left menu subpages array.
418 *
419 * @param array $subPages Array of SubPages.
420 * @param array $initSubpage Initial SubPage Array.
421 * @param string $parentKey Parent Menu Slug.
422 * @param mixed $slug SubPage Slug.
423 */
424 public static function init_subpages_left_menu( $subPages, &$initSubpage, $parentKey, $slug ) { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR - complexity.
425
426 if ( ! is_array( $subPages ) ) {
427 $subPages = array();
428 }
429
430 global $_mainwp_menu_active_slugs;
431
432 $subPages = apply_filters( 'mainwp_subpages_left_menu', $subPages, $initSubpage, $parentKey, $slug );
433
434 foreach ( $subPages as $subPage ) {
435 if ( ! isset( $subPage['menu_hidden'] ) || ( isset( $subPage['menu_hidden'] ) && empty( $subPage['menu_hidden'] ) ) ) {
436 $sub_slug = isset( $subPage['slug'] ) ? $subPage['slug'] : '';
437 $_item = array(
438 'title' => isset( $subPage['title'] ) ? $subPage['title'] : '',
439 'parent_key' => $parentKey,
440 'href' => 'admin.php?page=' . $slug . $sub_slug,
441 'slug' => $slug . $sub_slug,
442 'right' => '',
443 );
444
445 if ( ! empty( $subPage['before_title'] ) ) {
446 $item['before_title'] = $subPage['before_title'];
447 }
448
449 // To support check right to open menu for sometime.
450 if ( isset( $subPage['item_slug'] ) ) {
451 $_item['item_slug'] = $subPage['item_slug'];
452 }
453
454 if ( isset( $subPage['href'] ) && ! empty( $subPage['href'] ) ) { // override href.
455 $_item['href'] = $subPage['href'];
456 }
457
458 $initSubpage[] = $_item;
459 } elseif ( isset( $subPage['slug'] ) ) {
460 $_mainwp_menu_active_slugs[ $slug . $subPage['slug'] ] = $parentKey; // to fix.
461 }
462 }
463 }
464
465 /**
466 * Method is_disable_menu_item
467 *
468 * Check if $_mainwp_disable_menus_items contains any menu items to hide.
469 *
470 * @param string $level The level the menu item is on.
471 * @param array|string $item The menu items meta data.
472 *
473 * @return bool True|False, default is False.
474 */
475 public static function is_disable_menu_item( $level, $item ) {
476
477 /**
478 * MainWP Disable Menus items array.
479 *
480 * @global object
481 */
482 global $_mainwp_disable_menus_items;
483 $disabled = false;
484 $_level = 'level_' . $level;
485 if ( is_array( $_mainwp_disable_menus_items ) && isset( $_mainwp_disable_menus_items[ $_level ] ) && isset( $_mainwp_disable_menus_items[ $_level ][ $item ] ) ) {
486 $disabled = $_mainwp_disable_menus_items[ $_level ][ $item ];
487 }
488 $disabled = apply_filters( 'mainwp_is_disable_menu_item', $disabled, $level, $item );
489 $_mainwp_disable_menus_items[ $_level ][ $item ] = $disabled;
490 return $disabled;
491 }
492
493 /**
494 * Method add_left_menu
495 *
496 * Build Top Level Menu
497 *
498 * @param array $params Menu Item parameters.
499 * @param integer $level Menu Item Level 1 or 2.
500 *
501 * @return array $mainwp_leftmenu[] | $mainwp_sub_leftmenu[].
502 */
503 public static function add_left_menu( $params = array(), $level = 1 ) { //phpcs:ignore -- NOSONAR - complex method.
504
505 if ( empty( $params ) ) {
506 return;
507 }
508
509 if ( ! empty( $params['menu_hidden'] ) ) {
510 return;
511 }
512
513 $level = (int) $level;
514
515 if ( 1 !== $level && 2 !== $level && 0 !== $level ) {
516 $level = 1;
517 }
518
519 $title = $params['title'];
520 $before_title = ! empty( $params['before_title'] ) ? $params['before_title'] : '';
521
522 $slug = isset( $params['slug'] ) ? $params['slug'] : '';
523 $href = isset( $params['href'] ) ? $params['href'] : '';
524 $right = isset( $params['right'] ) ? $params['right'] : '';
525 $id = isset( $params['id'] ) ? $params['id'] : '';
526 $level_cls = 'left-menu-item-level-' . $level;
527
528 if ( ! MainWP_Cache_Warm_Helper::is_excluded_warm_cache_pages() ) {
529 $level_cls .= ' mainwp-js-prefetch ';
530 }
531
532 $icon = isset( $params['icon'] ) ? $params['icon'] : '';
533 $leftsub_order = isset( $params['leftsub_order'] ) ? $params['leftsub_order'] : '';
534 $leftsub_order_level2 = isset( $params['leftsub_order_level2'] ) ? $params['leftsub_order_level2'] : '';
535 $ext_state = isset( $params['ext_status'] ) && ( 'activated' === $params['ext_status'] || 'inactive' === $params['ext_status'] ) ? $params['ext_status'] : '';
536 $parent_key = isset( $params['parent_key'] ) ? $params['parent_key'] : '';
537 $others = array( 'level_class' => $level_cls );
538
539 $others['classes_item'] = '';
540 if ( ! empty( $params['classes_item'] ) ) {
541 if ( is_array( $params['classes_item'] ) ) {
542 $others['classes_item'] = implode( ' ', $params['classes_item'] );
543 } elseif ( is_string( $params['classes_item'] ) ) {
544 $others['classes_item'] = $params['classes_item'];
545 }
546 }
547
548 $excluded_warm_cached_page = MainWP_Cache_Warm_Helper::is_excluded_warm_cache_pages();
549
550 /**
551 * Menu excluded warm cache item.
552 *
553 * @since 5.5.
554 */
555 if ( ! apply_filters( 'mainwp_menu_excluded_warm_cache_item', $excluded_warm_cached_page, $params ) ) {
556 $others['classes_item'] .= ' mainwp-js-prefetch ';
557 }
558
559 if ( isset( $params['active_params'] ) ) {
560 $others['active_params'] = $params['active_params'];
561 }
562 if ( ! empty( $params['item_class'] ) ) {
563 $others['item_class'] = $params['item_class'];
564 }
565
566 /**
567 * MainWP Left Menu, Sub Menu & Active menu slugs.
568 *
569 * @global object $mainwp_leftmenu
570 * @global object $mainwp_sub_leftmenu
571 * @global object $_mainwp_menu_active_slugs
572 */
573 global $mainwp_leftmenu, $mainwp_sub_leftmenu, $_mainwp_menu_active_slugs;
574
575 if ( ! is_array( $mainwp_leftmenu ) ) {
576 $mainwp_leftmenu = array();
577 }
578
579 if ( ! isset( $mainwp_leftmenu['mainwp_tab'] ) ) {
580 $mainwp_leftmenu['mainwp_tab'] = array(); // to compatible with old hooks.
581 }
582
583 if ( ! is_array( $_mainwp_menu_active_slugs ) ) {
584 $_mainwp_menu_active_slugs = array();
585 }
586
587 $active_path = false;
588
589 if ( isset( $params['active_path'] ) && is_array( $params['active_path'] ) && ! empty( $params['active_path'] ) ) {
590 $active_path = $params['active_path'];
591 reset( $active_path );
592 $item = key( $active_path );
593 $active = current( $active_path );
594 $_mainwp_menu_active_slugs['leftbar'][ $item ] = $active;
595 $_mainwp_menu_active_slugs['parent_slug'][ $item ] = $parent_key;
596 }
597
598 if ( 0 === $level ) {
599 $parent_key = 'mainwp_tab'; // forced value.
600 $mainwp_leftmenu['leftbar'][] = array( $title, $slug, $href, $id, $icon, $level_cls );
601 } elseif ( 1 === $level ) {
602
603 if ( empty( $parent_key ) ) {
604 $parent_key = 'mainwp_tab'; // forced value.
605 }
606
607 if ( 'mainwp_tab' === $parent_key ) {
608 $mainwp_leftmenu[ $parent_key ][] = array( $title, $slug, $href, $id, $level_cls );
609 } else {
610 $mainwp_sub_leftmenu['leftbar'][ $parent_key ][] = array( $title, $slug, $href, $id, $leftsub_order, $ext_state, $active_path, $level_cls );
611
612 if ( ! empty( $slug ) ) {
613 $_mainwp_menu_active_slugs['leftbar'][ $slug ] = $parent_key; // to get active menu.
614 }
615 }
616 } else {
617 if ( empty( $parent_key ) ) {
618 $parent_key = 'mainwp_tab'; // forced value.
619 }
620 $mainwp_sub_leftmenu[ $parent_key ][] = array( $title, $href, $right, $id, $slug, $leftsub_order_level2, $ext_state, $active_path, $before_title, $others );
621 }
622
623 if ( ! empty( $slug ) ) {
624 $no_submenu = ! empty( $params['nosubmenu'] ) ? true : false;
625 if ( $no_submenu ) {
626 $_mainwp_menu_active_slugs[ $slug ] = $slug; // to get active menu.
627 } else {
628 $_mainwp_menu_active_slugs[ $slug ] = $parent_key; // to get active menu.
629 }
630 }
631 }
632
633 /**
634 * Method render_left_menu
635 *
636 * Build Top Level Main Menu HTML & Render.
637 */
638 public static function render_left_menu() { // phpcs:ignore -- NOSONAR -Current complexity is the only way to achieve desired results, pull request solutions appreciated.
639
640 /**
641 * MainWP Left Menu, Sub Menu & Active menu slugs.
642 *
643 * @global object $mainwp_leftmenu
644 * @global object $mainwp_sub_leftmenu
645 * @global object $_mainwp_menu_active_slugs
646 */
647 global $mainwp_leftmenu, $mainwp_sub_leftmenu, $_mainwp_menu_active_slugs, $plugin_page;
648
649 /**
650 * Filter: mainwp_main_menu
651 *
652 * Filters main navigation menu items
653 *
654 * @since 4.0
655 */
656 $mainwp_leftmenu = apply_filters( 'mainwp_main_menu', $mainwp_leftmenu );
657 $bar_leftmenu = isset( $mainwp_leftmenu['leftbar'] ) ? $mainwp_leftmenu['leftbar'] : array();
658
659 /**
660 * Filter: mainwp_main_menu_submenu
661 *
662 * Filters main navigation subt-menu items
663 *
664 * @since 4.0
665 */
666
667 $mainwp_sub_leftmenu = apply_filters( 'mainwp_main_menu_submenu', $mainwp_sub_leftmenu );
668 $sub_bar_leftmenu = isset( $mainwp_sub_leftmenu['leftbar'] ) ? $mainwp_sub_leftmenu['leftbar'] : array();
669
670 if ( is_array( $mainwp_sub_leftmenu ) && ! empty( $mainwp_sub_leftmenu['Extensions'] ) ) {
671 $add_on_items = $mainwp_sub_leftmenu['Extensions'];
672
673 $head = array_shift( $add_on_items );
674 // sort the rest by first element.
675 usort(
676 $add_on_items,
677 function ( $a, $b ) {
678 return strcmp( (string) $a[0], (string) $b[0] );
679 }
680 );
681 // put the head back.
682 array_unshift( $add_on_items, $head );
683
684 $mainwp_sub_leftmenu['Extensions'] = $add_on_items;
685 }
686
687 $version = get_option( 'mainwp_plugin_version' );
688
689 ?>
690 <?php
691 /**
692 * Action: before_mainwp_menu
693 *
694 * Fires before the main navigation element.
695 *
696 * @since 4.0
697 */
698 do_action( 'before_mainwp_menu' );
699 ?>
700 <div id="mainwp-main-navigation-container">
701 <div id="mainwp-first-level-navigation">
702 <div id="mainwp-first-level-navigation-menu" class="ui vertical labeled inverted icon tiny menu">
703 <?php
704
705 $bar_item_actived_key = '';
706 if ( is_array( $_mainwp_menu_active_slugs ) && isset( $_mainwp_menu_active_slugs[ $plugin_page ] ) ) {
707 $menu_item_actived_key = $_mainwp_menu_active_slugs[ $plugin_page ];
708 if ( isset( $_mainwp_menu_active_slugs['leftbar'] ) && is_array( $_mainwp_menu_active_slugs['leftbar'] ) && isset( $_mainwp_menu_active_slugs['leftbar'][ $menu_item_actived_key ] ) ) {
709 $bar_item_actived_key = $_mainwp_menu_active_slugs['leftbar'][ $menu_item_actived_key ];
710 }
711 }
712
713 $bar_item_active = null;
714
715 $sites_count = MainWP_DB::instance()->get_websites_count();
716 if ( empty( $sites_count ) ) {
717 ?>
718 <a style="background: #FFD300 !important;" id="leftbar-item-quick-setup" title="<?php esc_html_e( 'Quick Setup', 'mainwp' ); ?>" class="item" href="admin.php?page=mainwp-setup">
719 <i class="magic large icon"></i><span class="ui small text"><?php esc_html_e( 'Quick Setup', 'mainwp' ); ?></span>
720 </a>
721 <?php
722 }
723
724 if ( is_array( $bar_leftmenu ) && ! empty( $bar_leftmenu ) ) {
725 foreach ( $bar_leftmenu as $item ) {
726 $title = wptexturize( $item[0] );
727 $item_key = $item[1];
728 $href = $item[2];
729 $item_id = isset( $item[3] ) ? $item[3] : '';
730 $item_icon = isset( $item[4] ) ? $item[4] : '';
731 $level_cls = isset( $item[5] ) ? $item[5] : '';
732
733 $has_sub = true;
734 if ( ! isset( $mainwp_sub_leftmenu[ $item_key ] ) || empty( $mainwp_sub_leftmenu[ $item_key ] ) ) {
735 $has_sub = false;
736 }
737 $active_item = '';
738
739 if ( empty( $bar_item_actived_key ) ) {
740 if ( isset( $_mainwp_menu_active_slugs['leftbar'][ $plugin_page ] ) ) {
741 if ( $item_key === $_mainwp_menu_active_slugs['leftbar'][ $plugin_page ] ) {
742 $bar_item_actived_key = $item_key;
743 }
744 } elseif ( isset( $_mainwp_menu_active_slugs[ $plugin_page ] ) ) {
745 if ( $item_key === $_mainwp_menu_active_slugs[ $plugin_page ] ) {
746 $bar_item_actived_key = $item_key;
747 }
748 }
749 }
750
751 if ( ! empty( $bar_item_actived_key ) && $item_key === $bar_item_actived_key ) {
752 $active_item = 'active';
753 $bar_item_active = $item;
754 }
755
756 $id_attr = ! empty( $item_id ) ? 'id="' . esc_html( $item_id ) . '"' : '';
757
758 $item_cls = $level_cls . ' ' . $active_item;
759
760 // phpcs:disable WordPress.Security.EscapeOutput
761 echo '<a ' . $id_attr . ' title="' . esc_html( $title ) . '" class="item ' . esc_attr( $item_cls ) . "\" href=\"$href\">";
762 echo ! empty( $item_icon ) ? $item_icon : '<i class="th large icon"></i>';
763 echo '<span class="ui small text">' . esc_html( $title ) . '</span>';
764 echo '</a>';
765 // phpcs:enable
766 }
767 }
768 ?>
769 </div>
770 <?php
771 $all_updates = wp_get_update_data();
772 $go_back_wpadmin_url = admin_url( 'index.php' );
773
774 $link = array(
775 'url' => $go_back_wpadmin_url,
776 'text' => esc_html__( 'WP Admin', 'mainwp' ),
777 'tip' => esc_html__( 'Click to go back to the site WP Admin area.', 'mainwp' ),
778 );
779 /**
780 * Filter: mainwp_go_back_wpadmin_link
781 *
782 * Filters URL for the Go to WP Admin button in Main navigation.
783 *
784 * @since 4.0
785 */
786 $go_back_link = apply_filters( 'mainwp_go_back_wpadmin_link', $link );
787
788 if ( false !== $go_back_link && is_array( $go_back_link ) ) {
789 if ( isset( $go_back_link['url'] ) ) {
790 $link['url'] = $go_back_link['url'];
791 }
792 if ( isset( $go_back_link['text'] ) ) {
793 $link['text'] = $go_back_link['text'];
794 }
795 if ( isset( $go_back_link['tip'] ) ) {
796 $link['tip'] = $go_back_link['tip'];
797 }
798 }
799 ?>
800 <div id="mainwp-support-menu">
801 <a class="mainwp-help-menu-item-open" id="mainwp-help-menu-item" title="<?php esc_attr_e( 'Support', 'mainwp' ); ?>" href="#">
802 <i class="question circle outline icon"></i><br/>
803 <span class="ui small text"><?php esc_html_e( 'Support', 'mainwp' ); ?></span>
804 </a>
805 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp_support_popup' ) ) : ?>
806 <span class="ui mainwp-help-popup popup" style="width: 200px !important;">
807 <em data-emoji=":ring_buoy:" class="large"></em>
808 <h4 class="ui large header"><?php esc_html_e( 'Feeling stuck?', 'mainwp' ); ?></h4>
809 <p><?php esc_html_e( 'Help is just a click away.', 'mainwp' ); ?></p>
810 <a class="ui mini green button mainwp-notice-dismiss" notice-id="mainwp_support_popup" href="#"><?php esc_html_e( 'Thanks!', 'mainwp' ); ?></a>
811 </span>
812 <script>
813 jQuery(document).ready(function() {
814 jQuery('.mainwp-help-menu-item-open').popup({
815 popup : jQuery('.mainwp-help-popup'),
816 delay : { show: 2000 },
817 distanceAway : 10,
818 closable: false,
819 position : 'top left',
820 }).popup('show');
821
822 jQuery('.mainwp-help-popup .mainwp-notice-dismiss').on('click', function (e) {
823 jQuery('.mainwp-help-popup').removeClass('visible').addClass('hidden').hide();
824
825 });
826 });
827 </script>
828 <?php endif; ?>
829 </div>
830 <div id="mainwp-first-level-navigation-version-label">
831 <?php if ( is_array( $all_updates ) && isset( $all_updates['counts']['total'] ) && 0 < $all_updates['counts']['total'] ) : ?>
832 <a class="ui tiny red fluid centered pulse looping transition label" id="mainwp-dashboard-update-available" data-inverted="" data-position="left center" data-tooltip="<?php esc_attr_e( 'Your MainWP Dashboard sites needs your attention. Please check the available updates', 'mainwp' ); ?>" aria-label="<?php esc_attr_e( 'Your MainWP Dashboard sites needs your attention. Please check the available updates', 'mainwp' ); ?>" href="update-core.php">
833 <i class="exclamation triangle icon" style="color:#fff"></i> <?php esc_html_e( 'Update Dashboard Site', 'mainwp' ); ?>
834 </a>
835 <?php endif; ?>
836 <div id="mainwp-version-label" class="ui tiny green fluid centered label"><?php echo esc_html( $version ); ?></div>
837 </div>
838 </div>
839 <div id="mainwp-divider-handle">
840 <div id="mainwp-collapse-second-level-navigation" aria-label="<?php esc_attr_e( 'Collapse menu.', 'mainwp' ); ?>">
841 <i class="double angle left small icon"></i>
842 </div>
843 </div>
844 <div id="mainwp-second-level-navigation">
845 <div id="mainwp-main-menu" class="mainwp-main-navigation-menu ui inverted vertical accordion menu">
846 <?php
847 $bar_active_item_key = '';
848
849 $set_actived = false;
850
851 if ( ! empty( $bar_item_active ) ) {
852 $item = $bar_item_active;
853 $title = wptexturize( $item[0] );
854 $item_key = $item[1];
855 $item_id = isset( $item[3] ) ? $item[3] : '';
856 $level_cls = isset( $item[5] ) ? $item[5] : '';
857
858 $bar_active_item_key = $item_key;
859
860 $has_sub = true;
861 if ( ! isset( $mainwp_sub_leftmenu[ $item_key ] ) || empty( $mainwp_sub_leftmenu[ $item_key ] ) ) {
862 $has_sub = false;
863 }
864 $active_item = '';
865
866 if ( ! $set_actived && isset( $_mainwp_menu_active_slugs['parent_slug'][ $plugin_page ] ) && $item_key === $_mainwp_menu_active_slugs['parent_slug'][ $plugin_page ] ) {
867 $active_item = 'active';
868 $set_actived = true;
869 }
870
871 // to fix active menu.
872 if ( ! $set_actived && isset( $_mainwp_menu_active_slugs[ $plugin_page ] ) && $item_key === $_mainwp_menu_active_slugs[ $plugin_page ] ) {
873 $active_item = 'active';
874 $set_actived = true;
875 }
876
877 $id_attr = ! empty( $item_id ) ? 'id="' . esc_html( $item_id ) . '"' : '';
878
879 // phpcs:disable WordPress.Security.EscapeOutput
880 if ( $has_sub ) {
881 echo '<div ' . $id_attr . " class=\"item $active_item " . esc_attr( $level_cls ) . ' ">';
882 echo "<a class=\"title with-sub $active_item\" href=\"javascript:void(0)\">$title <i class=\"dropdown icon\"></i></a>";
883 echo "<div class=\"content menu $active_item\">";
884 static::render_sub_item( $item_key );
885 echo '</div>';
886 echo '</div>';
887 } else {
888 echo '<div ' . $id_attr . ' class="item ' . esc_attr( $level_cls ) . '">';
889 echo "<a class='title $active_item' href=\"javascript:void(0)\">$title</a>";
890 echo '</div>';
891 }
892 // phpcs:enable
893
894 if ( is_array( $sub_bar_leftmenu ) && ! empty( $bar_active_item_key ) && isset( $sub_bar_leftmenu[ $bar_active_item_key ] ) && is_array( $sub_bar_leftmenu[ $bar_active_item_key ] ) ) {
895 $sub_bar_leftmenu_active_items = $sub_bar_leftmenu[ $bar_active_item_key ];
896 MainWP_Utility::array_sort_existed_keys( $sub_bar_leftmenu_active_items, 4 ); //phpcs:ignore Squiz.PHP.CommentedOutCode.Found -- 4 => 'leftsub_order'.
897 $set_actived = false;
898 foreach ( $sub_bar_leftmenu_active_items as $item ) {
899
900 if ( empty( $item ) || ! is_array( $item ) ) {
901 continue;
902 }
903
904 $title = wptexturize( $item[0] );
905 $item_key = $item[1];
906
907 $has_sub = true;
908 if ( ! isset( $mainwp_sub_leftmenu[ $item_key ] ) || empty( $mainwp_sub_leftmenu[ $item_key ] ) ) {
909 $has_sub = false;
910 }
911
912 $href = $item[2];
913 $item_id = isset( $item[3] ) ? $item[3] : '';
914 $ext_state = isset( $item[5] ) ? $item[5] : '';
915 $level_cls = isset( $item[7] ) ? $item[7] : '';
916
917 $item_classes = 'inactive' === $ext_state ? 'extension-inactive' : '';
918
919 $active_item = '';
920
921 if ( ! $set_actived && isset( $_mainwp_menu_active_slugs['parent_slug'][ $plugin_page ] ) && $item_key === $_mainwp_menu_active_slugs['parent_slug'][ $plugin_page ] ) {
922 $active_item = 'active';
923 $set_actived = true;
924 }
925
926 // to fix active menu.
927 if ( ! $set_actived && isset( $_mainwp_menu_active_slugs[ $plugin_page ] ) && $item_key === $_mainwp_menu_active_slugs[ $plugin_page ] ) {
928 $active_item = 'active';
929 $set_actived = true;
930 }
931
932 $id_attr = ! empty( $item_id ) ? 'id="' . esc_html( $item_id ) . '"' : '';
933
934 $hide_item = '';
935 if ( 'admin.php?page=ManageApiBackups' === $href ) {
936 $hide_item = ' style="display:none"';
937 }
938
939 if ( ! empty( $level_cls ) ) {
940 $item_classes = $item_classes . ' ' . $level_cls;
941 }
942
943 // phpcs:disable WordPress.Security.EscapeOutput
944 if ( $has_sub ) {
945 echo '<div ' . $id_attr . " class=\"item $active_item $item_classes\">";
946 echo "<a class=\"title with-sub $active_item\" href=\"javascript:void(0)\">$title <i class=\"dropdown icon\"></i></a>";
947 echo "<div class=\"content menu $active_item\">";
948 static::render_sub_item( $item_key );
949 echo '</div>';
950 echo '</div>';
951 } else {
952 echo '<div ' . $id_attr . $hide_item . " class=\"item $active_item $item_classes\">";
953 echo "<a class='title $active_item' href=\"javascript:void(0)\">$title</a>";
954 echo '</div>';
955 }
956 // phpcs:enable
957 }
958 }
959 }
960 ?>
961 </div>
962 </div>
963 </div>
964
965 <?php
966 /**
967 * Action: after_mainwp_menu
968 *
969 * Fires after the main navigation element.
970 *
971 * @since 4.0
972 */
973 do_action( 'after_mainwp_menu' );
974 ?>
975 <script type="text/javascript">
976
977 jQuery( document ).ready( function () {
978
979 setTimeout(() => {
980 jQuery('#mainwp-dashboard-update-available').removeClass('looping');
981 }, 1500);
982
983 let mainwp_left_bar_showhide_init = function(){
984 if(jQuery('body').hasClass('mainwp-hidden-second-level-navigation')){
985 return; // hide always.
986 }
987 if(jQuery('body').hasClass('toplevel_page_mainwp_tab')){
988 return; // hide always.
989 }
990 let lbar = jQuery( '#mainwp-collapse-second-level-navigation' );
991 let show = ( typeof mainwp_ui_state_load !== 'undefined' ) && 0 != mainwp_ui_state_load( 'showmenu' );
992 mainwp_left_bar_showhide( lbar, show);
993 }
994 mainwp_left_bar_showhide = function( lbar, show ){
995 if ( show ) {
996 jQuery( '#mainwp-second-level-navigation' ).show();
997 jQuery( '.mainwp-content-wrap' ).css( "margin-left", "272px" );
998 //jQuery( '#mainwp-screenshots-sites' ).css( "margin-left", "272px" );
999 jQuery( '#mainwp-main-navigation-container' ).css( "width", "272px" );
1000 jQuery( lbar ).find( '.icon' ).removeClass( 'right' );
1001 jQuery( lbar ).find( '.icon' ).addClass( 'left' );
1002 jQuery( lbar ).parent('#mainwp-divider-handle').css( "left", "200px" );
1003 jQuery( lbar ).removeClass( 'collapsed' );
1004 if( ( typeof mainwp_ui_state_save !== 'undefined' ) ) {
1005 mainwp_ui_state_save( 'showmenu', 1 );
1006 }
1007 } else {
1008 jQuery( '#mainwp-second-level-navigation' ).hide();
1009 jQuery( '.mainwp-content-wrap' ).css( "margin-left", "72px" );
1010 //jQuery( '#mainwp-screenshots-sites' ).css( "margin-left", "72px" );
1011 jQuery( '#mainwp-main-navigation-container' ).css( "width", "72px" );
1012 jQuery( lbar ).find( '.icon' ).removeClass( 'left' );
1013 jQuery( lbar ).find( '.icon' ).addClass( 'right' );
1014 jQuery( lbar ).parent('#mainwp-divider-handle').css( "left", "0px" );
1015 jQuery( lbar ).addClass( 'collapsed' );
1016 jQuery( '#mainwp-top-header' ).css( "width", "100%" );
1017 if( ( typeof mainwp_ui_state_save !== 'undefined' ) ) {
1018 mainwp_ui_state_save( 'showmenu', 0 );
1019 }
1020 }
1021 }
1022
1023 jQuery( '#mainwp-collapse-second-level-navigation' ).on( 'click', function() {
1024 let show = jQuery( this ).hasClass( 'collapsed' ) ? true : false;
1025 mainwp_left_bar_showhide( this, show);
1026 return false;
1027 } );
1028 mainwp_left_bar_showhide_init();
1029
1030 // click on menu with-sub icon.
1031 jQuery( '#mainwp-main-navigation-container .mainwp-main-navigation-menu a.title.with-sub .icon' ).on( "click", function ( event ) {
1032 let pr = jQuery( this ).closest( '.item' );
1033 let title = jQuery( this ).closest( '.title' );
1034 let active = jQuery( title ).hasClass( 'active' );
1035
1036 // remove current active.
1037 mainwp_menu_collapse();
1038
1039 // if current menu item are not active then set it active.
1040 if ( !active ) {
1041 jQuery( title ).addClass( 'active' );
1042 jQuery( pr ).find('.content.menu').addClass( 'active' );
1043 pr.addClass('active');
1044 }
1045 return false;
1046 } );
1047
1048 jQuery( '#mainwp-main-navigation-container .mainwp-main-navigation-menu a.title.with-sub' ).on( "click", function ( event ) {
1049 let pr = jQuery( this ).closest( '.item' );
1050 let active = jQuery( this ).hasClass( 'active' );
1051
1052 // remove current active.
1053 mainwp_menu_collapse();
1054
1055 // set active before go to the page.
1056 if ( !active ) {
1057 jQuery( this ).addClass( 'active' );
1058 jQuery( pr ).find('.content.menu').addClass( 'active' );
1059 pr.addClass('active');
1060 }
1061 } );
1062
1063 mainwp_menu_collapse = function() {
1064 // remove current active.
1065 jQuery( '#mainwp-main-navigation-container .mainwp-main-navigation-menu a.title.active').removeClass('active');
1066 jQuery( '#mainwp-main-navigation-container .mainwp-main-navigation-menu .item').removeClass('active');
1067 jQuery( '#mainwp-main-navigation-container .mainwp-main-navigation-menu .content.menu.active').removeClass('active');
1068 };
1069
1070 jQuery( '#mainwp-main-mobile-navigation-container .accordion.menu' ).accordion();
1071
1072 } );
1073 </script>
1074 <?php
1075 }
1076
1077 /**
1078 * Method render_mobile_menu
1079 *
1080 * Renders the mobile menu.
1081 */
1082 public static function render_mobile_menu() { // phpcs:ignore -- NOSONAR -Current complexity is the only way to achieve desired results, pull request solutions appreciated.
1083 $mainwp_show_language_updates = get_option( 'mainwp_show_language_updates', 1 );
1084 ?>
1085 <div id="mainwp-overlay"></div>
1086 <div id="mainwp-main-mobile-navigation-container" class="mainwp-main-mobile-navigation-container ui top fullscreen flyout">
1087 <div class="mainwp-nav-menu scrolling content">
1088 <?php
1089 /**
1090 * Action: before_mainwp_menu
1091 *
1092 * Fires before the main navigation element.
1093 *
1094 * @since 4.0
1095 */
1096 do_action( 'before_mainwp_menu' );
1097 ?>
1098
1099 <div id="mainwp-main-menu-mobile" class="mainwp-main-navigation-menu test-menu ui inverted vertical accordion menu">
1100 <div class="item"><a href="admin.php?page=mainwp_tab"><i class="th icon"></i> <?php esc_html_e( 'Operations', 'mainwp' ); ?></a></div>
1101
1102 <div class="item">
1103 <div class="title"><a href="admin.php?page=managesites" class="with-sub"><i class="globe left floated icon"></i> <?php esc_html_e( 'Sites', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1104 <div class="content menu" id="mainwp-sites-mobile-menu-item">
1105 <div class="item">
1106 <div class="title"><a href="admin.php?page=managesites"><?php esc_html_e( 'Sites', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1107 <div class="content menu">
1108 <a class="item" href="admin.php?page=managesites"><?php esc_html_e( 'Manage Sites', 'mainwp' ); ?></a>
1109 <a class="item" href="admin.php?page=managesites&do=new"><?php esc_html_e( 'Add New Site', 'mainwp' ); ?></a>
1110 <a class="item" href="admin.php?page=managesites&do=bulknew"><?php esc_html_e( 'Import Sites', 'mainwp' ); ?></a>
1111 <a class="item" href="admin.php?page=MonitoringSites"><?php esc_html_e( 'Monitoring', 'mainwp' ); ?></a>
1112 </div>
1113 </div>
1114 <div class="item">
1115 <div class="title"><a class="" href="admin.php?page=ManageGroups"><?php esc_html_e( 'Tags', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1116 <div class="content menu">
1117 <a class="item" href="admin.php?page=ManageGroups"><?php esc_html_e( 'Manage Tags', 'mainwp' ); ?></a>
1118 </div>
1119 </div>
1120 <div class="item">
1121 <div class="title"><a href="admin.php?page=UpdatesManage"><?php esc_html_e( 'Updates', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1122 <div class="content menu">
1123 <a class="item" href="admin.php?page=UpdatesManage&tab=plugins-updates"><?php esc_html_e( 'Plugin Updates', 'mainwp' ); ?></a>
1124 <a class="item" href="admin.php?page=UpdatesManage&tab=themes-updates"><?php esc_html_e( 'Theme Updates', 'mainwp' ); ?></a>
1125 <a class="item" href="admin.php?page=UpdatesManage&tab=wordpress-updates"><?php esc_html_e( 'WordPress Updates', 'mainwp' ); ?></a>
1126 <?php if ( $mainwp_show_language_updates ) : ?>
1127 <a class="item" href="admin.php?page=UpdatesManage&tab=translations-updates"><?php esc_html_e( 'Translation Plugins', 'mainwp' ); ?></a>
1128 <?php endif; ?>
1129 <a class="item" href="admin.php?page=PluginsAbandoned"><?php esc_html_e( 'Abandoned Plugins', 'mainwp' ); ?></a>
1130 <a class="item" href="admin.php?page=ThemesAbandoned"><?php esc_html_e( 'Abandoned Themes', 'mainwp' ); ?></a>
1131 </div>
1132 </div>
1133 <div class="item">
1134 <div class="title"><a href="admin.php?page=PluginsManage"><?php esc_html_e( 'Plugins', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1135 <div class="content menu">
1136 <a class="item" href="admin.php?page=PluginsManage"><?php esc_html_e( 'Manage Plugins', 'mainwp' ); ?></a>
1137 <a class="item" href="admin.php?page=PluginsInstall"><?php esc_html_e( 'Install', 'mainwp' ); ?></a>
1138 <a class="item" href="admin.php?page=PluginsAutoUpdate"><?php esc_html_e( 'Advanced Auto Updates', 'mainwp' ); ?></a>
1139 <a class="item" href="admin.php?page=PluginsIgnore"><?php esc_html_e( 'Ignored Updates', 'mainwp' ); ?></a>
1140 <a class="item" href="admin.php?page=PluginsIgnoredAbandoned"><?php esc_html_e( 'Ignored Abandoned', 'mainwp' ); ?></a>
1141 </div>
1142 </div>
1143 <div class="item">
1144 <div class="title"><a href="admin.php?page=ThemesManage"><?php esc_html_e( 'Themes', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1145 <div class="content menu">
1146 <a class="item" href="admin.php?page=ThemesManage"><?php esc_html_e( 'Manage Themes', 'mainwp' ); ?></a>
1147 <a class="item" href="admin.php?page=ThemesInstall"><?php esc_html_e( 'Install', 'mainwp' ); ?></a>
1148 <a class="item" href="admin.php?page=ThemesAutoUpdate"><?php esc_html_e( 'Advanced Auto Updates', 'mainwp' ); ?></a>
1149 <a class="item" href="admin.php?page=ThemesIgnore"><?php esc_html_e( 'Ignored Updates', 'mainwp' ); ?></a>
1150 <a class="item" href="admin.php?page=ThemesIgnoredAbandoned"><?php esc_html_e( 'Ignored Abandoned', 'mainwp' ); ?></a>
1151 </div>
1152 </div>
1153 <div class="item">
1154 <div class="title"><a href="admin.php?page=UserBulkManage"><?php esc_html_e( 'Users', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1155 <div class="content menu">
1156 <a class="item" href="admin.php?page=UserBulkManage"><?php esc_html_e( 'Manage Users', 'mainwp' ); ?></a>
1157 <a class="item" href="admin.php?page=UserBulkAdd"><?php esc_html_e( 'Add New User', 'mainwp' ); ?></a>
1158 <a class="item" href="admin.php?page=BulkImportUsers"><?php esc_html_e( 'Import Users', 'mainwp' ); ?></a>
1159 <a class="item" href="admin.php?page=UpdateAdminPasswords"><?php esc_html_e( 'Admin Passwords', 'mainwp' ); ?></a>
1160 </div>
1161 </div>
1162 <div class="item">
1163 <div class="title"><a href="admin.php?page=PostBulkManage"><?php esc_html_e( 'Posts', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1164 <div class="content menu">
1165 <a class="item" href="admin.php?page=PostBulkManage"><?php esc_html_e( 'Manage Posts', 'mainwp' ); ?></a>
1166 <a class="item" href="admin.php?page=PostBulkAdd"><?php esc_html_e( 'Add New Post', 'mainwp' ); ?></a>
1167 </div>
1168 </div>
1169 <div class="item">
1170 <div class="title"><a href="admin.php?page=PageBulkManage"><?php esc_html_e( 'Pages', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1171 <div class="content menu">
1172 <a class="item" href="admin.php?page=PageBulkManage"><?php esc_html_e( 'Manage Pages', 'mainwp' ); ?></a>
1173 <a class="item" href="admin.php?page=PageBulkAdd"><?php esc_html_e( 'Add New Page', 'mainwp' ); ?></a>
1174 </div>
1175 </div>
1176 <div class="item">
1177 <div class="title"><a href="admin.php?page=ManageApiBackups"><?php esc_html_e( 'Backups', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1178 <div class="content menu">
1179 <a class="item" href="admin.php?page=ManageApiBackups"><?php esc_html_e( 'Backups', 'mainwp' ); ?></a>
1180 </div>
1181 </div>
1182 </div>
1183 </div>
1184
1185 <div class="item">
1186 <div class="title"><a href="admin.php?page=ManageClients" class="with-sub"><i class="users icon"></i> <?php esc_html_e( 'Clients', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1187 <div class="content menu">
1188 <a class="item" href="admin.php?page=ManageClients"><?php esc_html_e( 'Clients', 'mainwp' ); ?></a>
1189 <a class="item" href="admin.php?page=ClientAddNew"><?php esc_html_e( 'Add Client', 'mainwp' ); ?></a>
1190 <a class="item" href="admin.php?page=ClientAddField"><?php esc_html_e( 'Client Fields', 'mainwp' ); ?></a>
1191 </div>
1192 </div>
1193
1194 <div class="item">
1195 <div class="title"><a href="admin.php?page=ManageCostTracker" class="with-sub"><i class="dollar sign icon"></i> <?php esc_html_e( 'Cost Tracker', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1196 <div class="content menu">
1197 <a class="item" href="admin.php?page=CostSummary"><?php esc_html_e( 'Cost Summary', 'mainwp' ); ?></a>
1198 <a class="item" href="admin.php?page=ManageCostTracker"><?php esc_html_e( 'Manage Costs', 'mainwp' ); ?></a>
1199 <a class="item" href="admin.php?page=CostTrackerAdd"><?php esc_html_e( 'Add Cost', 'mainwp' ); ?></a>
1200 </div>
1201 </div>
1202
1203 <div class="item">
1204 <div class="title"><a href="admin.php?page=InsightsOverview" class="with-sub"><i class="chart pie icon"></i> <?php esc_html_e( 'Insights', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1205 <div class="content menu">
1206 <a class="item" href="admin.php?page=InsightsOverview"><?php esc_html_e( 'Insights', 'mainwp' ); ?></a>
1207 </div>
1208 </div>
1209
1210 <div class="item">
1211 <div class="title"><a href="admin.php?page=Extensions" class=""><i class="box icon"></i> <?php esc_html_e( 'Add-ons', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1212 <div class="content menu">
1213 <a class="item" href="admin.php?page=Extensions"><?php esc_html_e( 'Manage Add-ons', 'mainwp' ); ?></a>
1214 </div>
1215 </div>
1216
1217 <div class="item">
1218 <div class="title"><a href="admin.php?page=RESTAPI" class="with-sub"><i class="key icon"></i> <?php esc_html_e( 'REST API', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1219 <div class="content menu">
1220 <a class="item" href="admin.php?page=RESTAPI"><?php esc_html_e( 'Manage API Keys', 'mainwp' ); ?></a>
1221 <a class="item" href="admin.php?page=AddApiKeys"><?php esc_html_e( 'Add API Keys', 'mainwp' ); ?></a>
1222 <a class="item" href="admin.php?page=ApplicationPasswords"><?php esc_html_e( 'Application Passwords', 'mainwp' ); ?></a>
1223 </div>
1224 </div>
1225
1226 <div class="item">
1227 <div class="title"><a href="admin.php?page=Settings" class="with-sub"><i class="cog icon"></i> <?php esc_html_e( 'Settings', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1228 <div class="content menu">
1229 <a class="item" href="admin.php?page=Settings"><?php esc_html_e( 'General Settings', 'mainwp' ); ?></a>
1230 <a class="item" href="admin.php?page=SettingsAdvanced"><?php esc_html_e( 'Advanced Settings', 'mainwp' ); ?></a>
1231 <a class="item" href="admin.php?page=MonitoringSettings"><?php esc_html_e( 'Monitoring Settings', 'mainwp' ); ?></a>
1232 <a class="item" href="admin.php?page=SettingsEmail"><?php esc_html_e( 'Email Settings', 'mainwp' ); ?></a>
1233 <a class="item" href="admin.php?page=MainWPTools"><?php esc_html_e( 'Tools', 'mainwp' ); ?></a>
1234 </div>
1235 </div>
1236
1237 <div class="item">
1238 <div class="title"><a href="admin.php?page=ServerInformation" class="with-sub"><i class="info circle icon"></i> <?php esc_html_e( 'Info', 'mainwp' ); ?></a><i class="dropdown icon"></i></div>
1239 <div class="content menu">
1240 <a class="item" href="admin.php?page=ServerInformation"><?php esc_html_e( 'Server', 'mainwp' ); ?></a>
1241 <a class="item" href="admin.php?page=ServerInformationCron"><?php esc_html_e( 'Cron Schedules', 'mainwp' ); ?></a>
1242 <a class="item" href="admin.php?page=ErrorLog"><?php esc_html_e( 'Error Log', 'mainwp' ); ?></a>
1243 <a class="item" href="admin.php?page=ActionLogs"><?php esc_html_e( 'Custom Event Monitor', 'mainwp' ); ?></a>
1244 <a class="item" href="admin.php?page=PluginPrivacy"><?php esc_html_e( 'Plugin Privacy', 'mainwp' ); ?></a>
1245 </div>
1246 </div>
1247 </div>
1248 <?php
1249 /**
1250 * Action: after_mainwp_menu
1251 *
1252 * Fires after the main navigation element.
1253 *
1254 * @since 4.0
1255 */
1256 do_action( 'after_mainwp_menu' );
1257 ?>
1258 </div>
1259 <div class="actions">
1260 <?php
1261 $go_back_wpadmin_url = admin_url( 'index.php' );
1262
1263 $link = array(
1264 'url' => $go_back_wpadmin_url,
1265 'text' => esc_html__( 'WP Admin', 'mainwp' ),
1266 'tip' => esc_html__( 'Click to go back to the site WP Admin area.', 'mainwp' ),
1267 );
1268
1269 /**
1270 * Filter: mainwp_go_back_wpadmin_link
1271 *
1272 * Filters URL for the Go to WP Admin button in Main navigation.
1273 *
1274 * @since 4.0
1275 */
1276 $go_back_link = apply_filters( 'mainwp_go_back_wpadmin_link', $link );
1277
1278 if ( false !== $go_back_link ) {
1279 if ( is_array( $go_back_link ) ) {
1280 if ( isset( $go_back_link['url'] ) ) {
1281 $link['url'] = $go_back_link['url'];
1282 }
1283 if ( isset( $go_back_link['text'] ) ) {
1284 $link['text'] = $go_back_link['text'];
1285 }
1286 if ( isset( $go_back_link['tip'] ) ) {
1287 $link['tip'] = $go_back_link['tip'];
1288 }
1289 }
1290 }
1291 ?>
1292 <div class="ui three column grid">
1293 <div class="column">
1294 <a href="<?php echo esc_url( $link['url'] ); ?>" class="ui mini basic fluid button small text"><i class="icon wordpress"></i> <?php echo esc_html( $link['text'] ); ?></a><?php //phpcs:ignore -- to avoid auto fix icon wordpress. ?>
1295 </div>
1296 <div class="column">
1297 <a id="mainwp-help-menu-item-mobile" class="ui mini basic fluid button" href="#"><i class="question circle icon"></i> <?php esc_html_e( 'Help', 'mainwp' ); ?></a><?php //NOSONAR -- ignore double ID, elements not rendered at the same time. ?>
1298 </div>
1299 <div class="column item-wp-admin">
1300 <a class="ui mini basic fluid button" href="<?php echo esc_url_raw( wp_logout_url() ); ?>"><i class="sign out icon"></i> <?php esc_html_e( 'Log Out', 'mainwp' ); ?></a>
1301 </div>
1302 </div>
1303 </div>
1304 </div>
1305 <?php
1306 }
1307
1308 /**
1309 * Method render_sub_item
1310 *
1311 * Grabs all submenu items and attatches to Main Menu.
1312 *
1313 * @param mixed $parent_key The parent key.
1314 */
1315 public static function render_sub_item( $parent_key ) { //phpcs:ignore -- NOSONAR - complex method.
1316 if ( empty( $parent_key ) ) {
1317 return;
1318 }
1319
1320 /**
1321 * MainWP Left Menu.
1322 *
1323 * @global object $mainwp_sub_leftmenu
1324 */
1325 global $mainwp_sub_leftmenu;
1326
1327 $submenu_items = $mainwp_sub_leftmenu[ $parent_key ];
1328
1329 if ( ! is_array( $submenu_items ) || empty( $submenu_items ) ) {
1330 return;
1331 }
1332
1333 global $plugin_page;
1334
1335 $set_actived = false;
1336
1337 MainWP_Utility::array_sort_existed_keys( $submenu_items, 5 ); //phpcs:ignore Squiz.PHP.CommentedOutCode.Found -- 5 => 'leftsub_order_level2'.
1338
1339 $idx = 0;
1340 $fix_douplicate_ids = array();
1341
1342 foreach ( $submenu_items as $sub_item ) {
1343 $title = $sub_item[0];
1344 $href = $sub_item[1];
1345 $right = $sub_item[2];
1346 $id = isset( $sub_item[3] ) ? $sub_item[3] : '';
1347 $slug = isset( $sub_item[4] ) ? $sub_item[4] : '';
1348 $ext_state = isset( $sub_item[6] ) ? $sub_item[6] : '';
1349 $active_path = isset( $sub_item[7] ) ? $sub_item[7] : '';
1350 $before_title = isset( $sub_item[8] ) ? $sub_item[8] : '';
1351 $others = isset( $sub_item[9] ) ? $sub_item[9] : array();
1352
1353 if ( ! is_array( $others ) ) {
1354 $others = array();
1355 }
1356
1357 $item_classes = 'inactive' === $ext_state ? 'extension-inactive' : '';
1358
1359 if ( ! empty( $others['item_class'] ) ) {
1360 $item_classes .= ' ' . $others['item_class'];
1361 }
1362
1363 $_blank = false;
1364 if ( '_blank' === $id ) {
1365 $_blank = true;
1366 }
1367
1368 $level2_active = false;
1369
1370 if ( ! $set_actived ) {
1371 $level2_active = static::is_level2_menu_item_active( $href ) ? true : false;
1372 if ( is_array( $active_path ) && ! empty( $active_path ) ) {
1373 foreach ( $active_path as $item => $value ) {
1374 if ( $item === $plugin_page ) {
1375 $level2_active = true;
1376 break;
1377 }
1378 }
1379 }
1380 // hard fix managesite menu items active status.
1381 //phpcs:disable WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1382 if ( false !== strpos( $href, 'admin.php?page=managesites' ) ) {
1383 $page_name = isset( $_GET['page'] ) ? wp_unslash( $_GET['page'] ) : '';
1384 $level2_active = false;
1385
1386 if ( isset( $_GET['do'] ) && 'new' === $_GET['do'] && false !== strpos( $href, 'admin.php?page=managesites&do=new' ) ) {
1387 $level2_active = true;
1388 }
1389
1390 if ( ! $level2_active && isset( $_GET['do'] ) && 'bulknew' === $_GET['do'] && ( false !== strpos( $href, 'admin.php?page=managesites&do=bulknew' ) || 'managesites-addnew' === $id ) ) {
1391 $level2_active = true;
1392 }
1393
1394 if ( ! $level2_active && ! isset( $_GET['do'] ) && 'InsightsManage' !== $page_name && 'Extensions-Mainwp-Clone-Extension' !== $page_name && 'managesites-root' === $id ) {
1395 $level2_active = true;
1396 }
1397 }
1398
1399 if ( ! $level2_active && ! empty( $others['active_params'] ) && is_array( $others['active_params'] ) ) {
1400 foreach ( $others['active_params'] as $name => $value ) {
1401 if ( isset( $_GET[ $name ] ) && wp_unslash( $_GET[ $name ] ) === $value ) {
1402 $level2_active = true;
1403 break;
1404 }
1405 }
1406 }
1407
1408 //phpcs:enable WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1409 if ( $level2_active ) {
1410 $set_actived = true;
1411 }
1412 }
1413
1414 $right_group = 'dashboard';
1415 if ( ! empty( $right ) && strpos( $right, 'extension_' ) === 0 ) {
1416 $right_group = 'extension';
1417 $right = str_replace( 'extension_', '', $right );
1418 }
1419
1420 if ( ! empty( $others['level_class'] ) ) {
1421 $item_classes = $item_classes . ' ' . $others['level_class'];
1422 }
1423
1424 if ( ! empty( $others['classes_item'] ) ) {
1425 $item_classes = $item_classes . ' ' . $others['classes_item'];
1426 }
1427
1428 if ( empty( $right ) || ( ! empty( $right ) && \mainwp_current_user_can( $right_group, $right ) ) ) {
1429 $menu_itemid = $slug; // compatible.
1430 $menu_itemid = 'managesites' === $slug && ! empty( $id ) ? $id : $menu_itemid;
1431
1432 // Fix duplicate ID issue caused by empty id="" (kept for backward compatibility).
1433 if ( empty( $menu_itemid ) ) {
1434 $menu_itemid = ! empty( $title ) ? sanitize_title( $title ) : 'left-menu-item';
1435 $menu_itemid = 'left-menu-item-' . hash( 'crc32b', $menu_itemid . '-' . $idx );
1436 }
1437
1438 // Fix duplicate ID issue caused by same id in multiple extensions.
1439 if ( ! empty( $fix_douplicate_ids ) && in_array( $menu_itemid, $fix_douplicate_ids ) ) {
1440 $menu_itemid = $menu_itemid . '-' . $idx;
1441 }
1442 $fix_douplicate_ids[] = $menu_itemid;
1443
1444 ?>
1445 <a class="item <?php echo $level2_active ? 'active level-two-active' : ''; ?> <?php echo esc_attr( $item_classes ); ?>" href="<?php echo esc_url( $href ); ?>" id="<?php echo esc_attr( $menu_itemid ); ?>" <?php echo $_blank ? 'target="_blank"' : ''; ?>>
1446 <?php echo $before_title . $title; //phpcs:ignore -- requires escaped. ?>
1447 </a>
1448 <?php
1449 }
1450 ++$idx;
1451 }
1452 }
1453
1454
1455 /**
1456 * Method is_level2_menu_item_active().
1457 *
1458 * Check if menu item level 2 is active.
1459 *
1460 * @param mixed $href The href value.
1461 */
1462 public static function is_level2_menu_item_active( $href ) {
1463 $current_path = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
1464 $san_path = $current_path;
1465
1466 if ( 0 === stripos( $san_path, '/wp-admin/' ) ) {
1467 $san_path = str_replace( '/wp-admin/', '', $san_path );
1468 }
1469
1470 $orther = '';
1471 if ( 0 === stripos( $san_path, $href ) ) {
1472 $orther = str_replace( $href, '', $san_path );
1473 }
1474
1475 if ( ! empty( $orther ) && '&' === substr( $orther, 0, 1 ) ) { // cheat: start by &, it is addition params string.
1476 $san_path = str_replace( $orther, '', $san_path ); // remove other path of uri.
1477 }
1478
1479 $san_path = MainWP_Utility::sanitize_attr_slug( $san_path );
1480 $san_href = MainWP_Utility::sanitize_attr_slug( $href );
1481
1482 return $san_path === $san_href;
1483 }
1484 }
1485