PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.1.3
Adminify – White Label, Admin Menu Editor, Login Customizer v4.1.3
4.3.1 4.3.0 4.2.26 4.2.25 4.2.24 4.2.23 4.2.22 4.2.21 4.2.20 4.2.19 4.2.18 4.2.17 4.2.16 4.2.15 4.2.14 4.2.13 4.2.12 4.2.11 4.2.10 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 4.1.17 All 164 releases
adminify / Inc / Modules / MenuEditor / MenuEditor.php

MenuEditor.php in Adminify – White Label, Admin Menu Editor, Login Customizer 4.1.3, at Inc/Modules/MenuEditor/MenuEditor.php

1,865 lines 81.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPAdminify\Inc\Modules\MenuEditor;
4
5 use WPAdminify\Inc\Utils;
6 use WPAdminify\Inc\Admin\AdminSettings;
7 use WPAdminify\Inc\Modules\MenuEditor\MenuEditorAssets;
8 use WPAdminify\Inc\Admin\AdminSettingsModel;
9 use enshrined\svgSanitize\Sanitizer;
10 // no direct access allowed
11 if ( !defined( 'ABSPATH' ) ) {
12 exit;
13 }
14 /**
15 * WP Adminify
16 *
17 * @package WP Adminify: Menu Editor
18 *
19 * @author WP Adminify <support@wpadminify.com>
20 */
21 if ( !class_exists( 'MenuEditor' ) ) {
22 class MenuEditor extends MenuEditorModel {
23 public $url;
24
25 public $menu;
26
27 public $users;
28
29 public $roles;
30
31 public $submenu;
32
33 public $options = [];
34
35 public $menu_settings = [];
36
37 public static $instance;
38
39 public static function get_instance() {
40 if ( self::$instance === null ) {
41 self::$instance = new self();
42 }
43 return self::$instance;
44 }
45
46 public function __construct() {
47 $this->menu_settings = ( new MenuEditorOptions() )->get();
48 $this->options = (array) AdminSettings::get_instance()->get();
49 add_filter( 'upload_mimes', [$this, 'custom_icon_mime_types'] );
50 add_filter( 'wp_handle_upload_prefilter', [$this, 'sanitize_svg_file'] );
51 add_filter( 'admin_body_class', [$this, 'jltwp_adminify_menu_editor_body_class'] );
52 // add_filter('parent_file', [$this, 'set_menu'], 800);
53 // add_filter('parent_file', [$this, 'apply_menu'], 900);
54 // add_action('jltwp_adminify_modules_menu_editor_render', [$this, 'jltwp_adminify_modules_menu_editor_render']);
55 if ( apply_filters( 'enable_jltwp_adminify_menu_editor_render', true ) ) {
56 add_filter( 'parent_file', [$this, 'set_menu'], 800 );
57 add_filter( 'parent_file', [$this, 'apply_menu'], 900 );
58 }
59 add_action( 'wp_ajax_adminify_save_menu_settings', [$this, 'adminify_save_menu_settings'] );
60 add_action( 'wp_ajax_adminify_reset_menu_settings', [$this, 'adminify_reset_menu_settings'] );
61 add_action( 'wp_ajax_adminify_export_menu_settings', [$this, 'adminify_export_menu_settings'] );
62 add_action( 'wp_ajax_adminify_import_menu_settings', [$this, 'adminify_import_menu_settings'] );
63 add_action( 'wp_ajax_adminify_file_upload', [$this, 'adminify_file_upload_callback'] );
64 add_action( 'wp_ajax_adminify_load_custom_icons', [$this, 'adminify_load_custom_icons_callback'] );
65 add_action( 'wp_ajax_adminify_search_users', [$this, 'adminify_search_users_callback'] );
66 new MenuEditorAssets();
67 }
68
69 public function custom_icon_mime_types( $mimes ) {
70 if ( current_user_can( 'administrator' ) ) {
71 $mimes['svg'] = 'image/svg+xml';
72 }
73 return $mimes;
74 }
75
76 public function sanitize_svg_file( $file ) {
77 // Step 1: Validate File Type
78 $file_type = wp_check_filetype( $file['name'] );
79 // Ensure the file is an SVG
80 if ( $file_type['ext'] === 'svg' ) {
81 // Read the contents of the SVG file
82 $file_contents = file_get_contents( $file['tmp_name'] );
83 // Validate if it's an actual SVG by checking if it contains the <svg> tag
84 if ( strpos( $file_contents, '<svg' ) === false ) {
85 $file['error'] = 'Invalid SVG file';
86 return $file;
87 // Stop further processing if it's not a valid SVG
88 }
89 // Step 2: Sanitize the SVG File
90 $sanitizer = new Sanitizer();
91 $clean_svg = $sanitizer->sanitize( $file_contents );
92 if ( $clean_svg ) {
93 // Save the sanitized SVG back to the file
94 file_put_contents( $file['tmp_name'], $clean_svg );
95 } else {
96 $file['error'] = 'Failed to sanitize the SVG file';
97 }
98 }
99 return $file;
100 }
101
102 public function filter_attachment( $value ) {
103 // return $value->post_title == 'adminify-custom-icon';
104 return strpos( $value->guid, 'adminify-custom-icon' ) !== false;
105 }
106
107 public function adminify_load_custom_icons_callback() {
108 // Security check - verify nonce and capability
109 check_ajax_referer( 'adminify-menu-editor-security-nonce', 'security' );
110 if ( !current_user_can( 'manage_options' ) ) {
111 wp_send_json_error( array(
112 'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
113 ) );
114 }
115 $result['images'] = null;
116 $query = get_posts( [
117 'post_type' => 'attachment',
118 'numberposts' => -1,
119 ] );
120 $filtered = array_filter( $query, [$this, 'filter_attachment'] );
121 foreach ( $filtered as $key => $value ) {
122 $result['images'][$value->ID] = $value->guid;
123 }
124 echo wp_json_encode( $result );
125 die;
126 }
127
128 public function adminify_file_upload_callback() {
129 $result['status'] = false;
130 check_ajax_referer( 'adminify-menu-editor-security-nonce', 'security' );
131 if ( !current_user_can( 'manage_options' ) ) {
132 wp_send_json_error( array(
133 'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
134 ) );
135 }
136 $upload_dir = wp_upload_dir();
137 $targeted_dir = $upload_dir['basedir'] . '/adminify-custom-icons';
138 if ( !is_dir( $targeted_dir ) ) {
139 wp_mkdir_p( $targeted_dir );
140 }
141 add_filter( 'upload_dir', [$this, 'adminify_icon_custom_upload_dir'] );
142 $files = wp_kses_post_deep( wp_unslash( $_FILES['my_file_upload'] ) );
143 foreach ( $files['name'] as $key => $value ) {
144 if ( $files['name'][$key] ) {
145 $file = [
146 'name' => $files['name'][$key],
147 'type' => $files['type'][$key],
148 'tmp_name' => $files['tmp_name'][$key],
149 'error' => $files['error'][$key],
150 'size' => $files['size'][$key],
151 ];
152 $_FILES = [
153 'upload_file' => $file,
154 ];
155 $attachment_id = media_handle_upload( 'upload_file', 0 );
156 if ( is_wp_error( $attachment_id ) ) {
157 // There was an error uploading the image.
158 $result['status'] = false;
159 $result['message'] = __( 'Error uploading file.', 'adminify' );
160 } else {
161 // The image was uploaded successfully!
162 $result['status'] = true;
163 $result['message'] = __( 'File Uploaded successfully.', 'adminify' );
164 $result['images'][$attachment_id] = wp_get_attachment_url( $attachment_id );
165 }
166 }
167 }
168 remove_filter( 'upload_dir', [$this, 'adminify_icon_custom_upload_dir'] );
169 echo wp_json_encode( $result );
170 wp_die();
171 }
172
173 public function adminify_icon_custom_upload_dir( $dir_data ) {
174 // $dir_data already you might want to use
175 $custom_dir = 'adminify-custom-icons';
176 return [
177 'path' => $dir_data['basedir'] . '/' . $custom_dir,
178 'url' => $dir_data['baseurl'] . '/' . $custom_dir,
179 'subdir' => '/' . $custom_dir,
180 'basedir' => $dir_data['basedir'],
181 'baseurl' => $dir_data['baseurl'],
182 'error' => $dir_data['error'],
183 ];
184 }
185
186 /**
187 * AJAX callback to search users for Select2
188 * Uses 'fields' parameter for optimized database query performance
189 */
190 public function adminify_search_users_callback() {
191 check_ajax_referer( 'adminify-menu-editor-security-nonce', 'security' );
192 if ( !current_user_can( 'manage_options' ) ) {
193 wp_send_json_error( array(
194 'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
195 ) );
196 }
197 $search = ( isset( $_GET['search'] ) ? sanitize_text_field( wp_unslash( $_GET['search'] ) ) : '' );
198 // If no search term or less than 3 chars, return first 3 users
199 if ( strlen( $search ) < 3 ) {
200 $args = array(
201 'number' => 3,
202 'orderby' => 'ID',
203 'order' => 'DESC',
204 'fields' => array('ID', 'user_login', 'display_name'),
205 );
206 $users = get_users( $args );
207 $results = array();
208 foreach ( $users as $user ) {
209 $results[] = array(
210 'id' => $user->user_login,
211 'text' => $user->user_login . ' (' . $user->display_name . ')',
212 );
213 }
214 // Get total user count efficiently
215 $user_count = count_users();
216 $total_users = $user_count['total_users'];
217 wp_send_json( array(
218 'results' => $results,
219 'pagination' => array(
220 'more' => $total_users > 3,
221 ),
222 'total_users' => $total_users,
223 ) );
224 return;
225 }
226 // Search users when 3+ characters typed
227 $args = array(
228 'search' => '*' . $search . '*',
229 'search_columns' => array('user_login', 'user_email', 'display_name'),
230 'number' => 20,
231 'orderby' => 'display_name',
232 'order' => 'ASC',
233 'fields' => array('ID', 'user_login', 'display_name'),
234 );
235 $users = get_users( $args );
236 $results = array();
237 foreach ( $users as $user ) {
238 $results[] = array(
239 'id' => $user->user_login,
240 'text' => $user->user_login . ' (' . $user->display_name . ')',
241 );
242 }
243 wp_send_json( array(
244 'results' => $results,
245 'pagination' => array(
246 'more' => false,
247 ),
248 ) );
249 }
250
251 // Menu Editor Body Class
252 public function jltwp_adminify_menu_editor_body_class( $classes ) {
253 $classes .= ' adminify_menu_editor ';
254 return $classes;
255 }
256
257 /**
258 * Sanitises and strips tags of input from ajax
259 *
260 * @since 1.0.0
261 * @variables $values = item to clean (array or string)
262 */
263 public function clean_ajax_input( $values ) {
264 if ( is_array( $values ) ) {
265 foreach ( $values as $index => $in ) {
266 if ( is_array( $in ) ) {
267 $values[$index] = $this->clean_ajax_input( $in );
268 } else {
269 $values[$index] = strip_tags( $in );
270 }
271 }
272 } else {
273 $values = strip_tags( $values );
274 }
275 return $values;
276 }
277
278 /**
279 * Returns ajax error
280 *
281 * @since 1.4
282 * @variables $message = error message to send back to user (string)
283 */
284 public function ajax_error_message( $message ) {
285 $returndata = [];
286 $returndata['error'] = true;
287 $returndata['error_message'] = $message;
288 return json_encode( $returndata );
289 }
290
291 public function adminify_save_menu_settings() {
292 if ( defined( 'DOING_AJAX' ) && DOING_AJAX && check_ajax_referer( 'adminify-menu-editor-security-nonce', 'security' ) > 0 ) {
293 if ( !current_user_can( 'manage_options' ) ) {
294 wp_send_json_error( array(
295 'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
296 ) );
297 }
298 $options = wp_kses_post_deep( wp_unslash( $_POST['options'] ) );
299 $options = $this->clean_ajax_input( $options );
300 if ( $options == '' || !is_array( $options ) ) {
301 $message = __( 'No options supplied to save', 'adminify' );
302 echo Utils::wp_kses_custom( $this->ajax_error_message( $message ) );
303 die;
304 }
305 if ( is_array( $options ) ) {
306 update_option( $this->prefix, $options );
307 $returndata = [];
308 $returndata['success'] = true;
309 $returndata['message'] = __( 'Settings saved', 'adminify' );
310 echo json_encode( $returndata );
311 die;
312 } else {
313 $message = __( 'Something went wrong', 'adminify' );
314 echo Utils::wp_kses_custom( $this->ajax_error_message( $message ) );
315 die;
316 }
317 }
318 die;
319 }
320
321 /**
322 * Menu Editor Settings Reset
323 *
324 * @return void
325 */
326 public function adminify_reset_menu_settings() {
327 if ( defined( 'DOING_AJAX' ) && DOING_AJAX && check_ajax_referer( 'adminify-menu-editor-security-nonce', 'security' ) > 0 ) {
328 if ( !current_user_can( 'manage_options' ) ) {
329 wp_send_json_error( array(
330 'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
331 ) );
332 }
333 update_option( $this->prefix, [] );
334 $menu_editor_options = get_option( $this->prefix );
335 if ( !$menu_editor_options ) {
336 $returndata = [];
337 $returndata['success'] = true;
338 $returndata['message'] = __( 'Settings reset', 'adminify' );
339 echo json_encode( $returndata );
340 die;
341 } else {
342 $message = __( 'Something went wrong', 'adminify' );
343 echo Utils::wp_kses_custom( $this->ajax_error_message( $message ) );
344 die;
345 }
346 }
347 die;
348 }
349
350 /**
351 * Export Menu Editor Settings
352 *
353 * @return void
354 */
355 public function adminify_export_menu_settings() {
356 if ( defined( 'DOING_AJAX' ) && DOING_AJAX && check_ajax_referer( 'adminify-menu-editor-security-nonce', 'security' ) > 0 ) {
357 if ( !current_user_can( 'manage_options' ) ) {
358 wp_send_json_error( array(
359 'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
360 ) );
361 }
362 $menu_editor_options = get_option( $this->prefix );
363 echo json_encode( $menu_editor_options );
364 }
365 die;
366 }
367
368 /**
369 * Import Menu Editor Settings
370 *
371 * @since 1.0.0
372 */
373 public function adminify_import_menu_settings() {
374 if ( defined( 'DOING_AJAX' ) && DOING_AJAX && check_ajax_referer( 'adminify-menu-editor-security-nonce', 'security' ) > 0 ) {
375 if ( !current_user_can( 'manage_options' ) ) {
376 wp_send_json_error( array(
377 'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
378 ) );
379 }
380 $new_options = wp_kses_post_deep( $_POST['settings'] );
381 if ( $new_options == '' || !is_array( $new_options ) ) {
382 $message = __( 'No options supplied to save', 'adminify' );
383 echo Utils::wp_kses_custom( $this->ajax_error_message( $message ) );
384 die;
385 }
386 if ( is_array( $new_options ) ) {
387 update_option( $this->prefix, $new_options );
388 $returndata = [];
389 $returndata['success'] = true;
390 $returndata['message'] = __( 'Menu Imported', 'adminify' );
391 echo json_encode( $returndata );
392 die;
393 } else {
394 $message = __( 'Something went wrong', 'adminify' );
395 echo Utils::wp_kses_custom( $this->ajax_error_message( $message ) );
396 die;
397 }
398 }
399 die;
400 }
401
402 /**
403 * Get menu items
404 *
405 * @param [type] $parent_file
406 *
407 * @return void
408 */
409 public function set_menu( $parent_file ) {
410 global $menu, $submenu;
411 $this->menu = $this->sort_menu_settings( $menu );
412 $this->submenu = $this->sort_sub_menu_settings( $this->menu, $submenu );
413 return $parent_file;
414 }
415
416 /**
417 * Sorts Menu's for Option settings
418 */
419 public function sort_menu_settings( $thismenu ) {
420 $menu_settings = $this->menu_settings;
421 $tempmenu = [];
422 foreach ( $thismenu as $key => $current_menu_item ) {
423 if ( $current_menu_item[4] === "wp-menu-separator" ) {
424 unset($thismenu[$key]);
425 continue;
426 }
427 if ( !current_user_can( 'administrator' ) && $current_menu_item[2] === 'vc-welcome' ) {
428 unset($thismenu[$key]);
429 continue;
430 }
431 $next_menu_item = next( $thismenu );
432 $optiongroup = [];
433 $order = $key;
434 $separator = 0;
435 $external_link = 0;
436 $icon = null;
437 $hidden_for = [];
438 if ( !empty( $next_menu_item ) && strpos( $next_menu_item[2], 'separator' ) !== false ) {
439 $separator = 1;
440 }
441 if ( is_array( $menu_settings ) ) {
442 if ( isset( $menu_settings[$current_menu_item[2]] ) ) {
443 $optiongroup = $menu_settings[$current_menu_item[2]];
444 if ( isset( $optiongroup['order'] ) ) {
445 $order = $optiongroup['order'];
446 }
447 if ( isset( $optiongroup['separator'] ) ) {
448 $separator = $optiongroup['separator'];
449 }
450 if ( isset( $optiongroup['external_link'] ) ) {
451 $external_link = $optiongroup['external_link'];
452 }
453 if ( !empty( $optiongroup['icon'] ) ) {
454 $icon = $optiongroup['icon'];
455 }
456 if ( !empty( $optiongroup['hidden_for'] ) ) {
457 $hidden_for = $optiongroup['hidden_for'];
458 }
459 }
460 }
461 $current_menu_item['order'] = $order;
462 $current_menu_item['hidden_for'] = $hidden_for;
463 $current_menu_item['separator'] = $separator;
464 $current_menu_item['external_link'] = $external_link;
465 // if (empty($this->options['admin_ui'])) {
466 if ( $icon !== null ) {
467 if ( strpos( $icon, 'dashicons ' ) !== false ) {
468 $menu_icon = str_replace( 'dashicons ', '', $icon );
469 $current_menu_item[6] = $menu_icon;
470 } else {
471 if ( strpos( $icon, ',' ) !== false ) {
472 $menu_icon = explode( ',', $icon )[1];
473 } else {
474 $menu_icon = 'dashicons-adminify- ' . $icon;
475 }
476 $current_menu_item[6] = $menu_icon;
477 }
478 }
479 if ( $separator == 1 ) {
480 $current_menu_item[4] = $current_menu_item[4] . ' adminify-menu-separator';
481 }
482 // }
483 array_push( $tempmenu, $current_menu_item );
484 if ( isset( $menu_settings[$current_menu_item[2]] ) ) {
485 unset($menu_settings[$current_menu_item[2]]);
486 }
487 }
488 if ( is_array( $menu_settings ) && !array_key_exists( 0, $menu_settings ) ) {
489 foreach ( $menu_settings as $key => $menu_s ) {
490 // Skip if $menu_s is not an array
491 if ( !is_array( $menu_s ) ) {
492 continue;
493 }
494 // Ensure required keys exist with defaults
495 $menu_s = wp_parse_args( $menu_s, [
496 'name' => '',
497 'link' => '',
498 'icon' => '',
499 'order' => 0,
500 'separator' => 0,
501 'external_link' => 0,
502 'hidden_for' => [],
503 ] );
504 $new_array = [
505 $menu_s['name'],
506 'read',
507 ( !empty( $menu_s['link'] ) ? $menu_s['link'] : '' ),
508 '',
509 'menu-top menu-icon-custom',
510 $key,
511 ( !empty( $menu_s['icon'] ) ? $menu_s['icon'] : '' ),
512 'order' => $menu_s['order'],
513 'separator' => ( !empty( $menu_s['separator'] ) ? $menu_s['separator'] : 0 ),
514 'external_link' => ( !empty( $menu_s['external_link'] ) ? $menu_s['external_link'] : 0 ),
515 'hidden_for' => ( !empty( $menu_s['hidden_for'] ) ? $menu_s['hidden_for'] : [] )
516 ];
517 // if (empty($this->options['admin_ui'])) {
518 if ( strpos( $menu_s['icon'], 'dashicons ' ) !== false ) {
519 $menu_icon = str_replace( 'dashicons ', '', $menu_s['icon'] );
520 } else {
521 if ( empty( $menu_s['icon'] ) || strpos( $menu_s['icon'], ',' ) !== false ) {
522 if ( empty( $menu_s['icon'] ) ) {
523 $menu_icon = WP_ADMINIFY_ASSETS_IMAGE . 'logos/menu-icon.svg';
524 } else {
525 $menu_icon = explode( ',', $menu_s['icon'] )[1];
526 }
527 } else {
528 $menu_icon = 'dashicons-adminify- ' . $menu_s['icon'];
529 }
530 }
531 if ( !empty( $menu_s['separator'] ) && $menu_s['separator'] == 1 ) {
532 $new_array[4] = $new_array[4] . ' adminify-menu-separator';
533 }
534 // if (!empty($menu_s['external_link']) && $menu_s['external_link'] == 1) {
535 // $new_array[4] = $new_array[4] . ' adminify-menu-external_link';
536 // }
537 $new_array[6] = $menu_icon;
538 // }
539 array_push( $tempmenu, $new_array );
540 }
541 }
542 return $this->sort_array( $tempmenu );
543 }
544
545 /**
546 * usort function for menu arrays
547 */
548 public function sort_array_helper( $a, $b ) {
549 $result = 0;
550 if ( !isset( $a['order'] ) ) {
551 return $result;
552 }
553 if ( $a['order'] > $b['order'] ) {
554 $result = 1;
555 } elseif ( $a['order'] < $b['order'] ) {
556 $result = -1;
557 }
558 return $result;
559 }
560
561 /**
562 * Sorts arrays by key 'order'
563 */
564 public function sort_array( $tosort ) {
565 usort( $tosort, [$this, 'sort_array_helper'] );
566 return $tosort;
567 }
568
569 /**
570 * Sorts Sub Menu for settings
571 *
572 * @since 1.4
573 */
574 public function sort_sub_menu_settings( $themenu, $thesubmenu ) {
575 $menu_settings = $this->menu_settings;
576 $tempsubmenu = [];
577 foreach ( $themenu as $current_menu_item ) {
578 $optiongroup = [];
579 $submenu_items = [];
580 if ( isset( $thesubmenu[$current_menu_item[2]] ) ) {
581 $submenuitems = $thesubmenu[$current_menu_item[2]];
582 foreach ( $submenuitems as $key => $subitem ) {
583 $subitem['order'] = $key;
584 if ( is_array( $menu_settings ) && isset( $menu_settings[$current_menu_item[2]] ) && isset( $menu_settings[$current_menu_item[2]]['submenu'] ) ) {
585 $submenugroup = $menu_settings[$current_menu_item[2]]['submenu'];
586 if ( isset( $submenugroup[$subitem[2]] ) ) {
587 $itemoptions = $submenugroup[$subitem[2]];
588 if ( isset( $itemoptions['order'] ) ) {
589 $subitem['order'] = $itemoptions['order'];
590 }
591 }
592 }
593 array_push( $submenu_items, $subitem );
594 }
595 $submenu_items = $this->sort_array( $submenu_items );
596 $tempsubmenu[$current_menu_item[2]] = $submenu_items;
597 }
598 }
599 if ( is_array( $menu_settings ) ) {
600 $tmp_menu = [];
601 foreach ( $menu_settings as $key => $menu_s ) {
602 if ( isset( $menu_s['submenu'] ) && is_array( $menu_s['submenu'] ) ) {
603 $tmp_sub_menu = [];
604 $i = 0;
605 foreach ( $menu_s['submenu'] as $k => $sub_menu ) {
606 if ( strpos( $k, 'adminify-custom-submenu' ) === false ) {
607 continue;
608 }
609 $order = ( $sub_menu['order'] ? $sub_menu['order'] : $i );
610 $new_array = [
611 ( $sub_menu['name'] ? $sub_menu['name'] : '' ),
612 'read',
613 ( $sub_menu['link'] ? $sub_menu['link'] : '' ),
614 'order' => $order,
615 'key' => $k,
616 'hidden_for' => ( isset( $sub_menu['hidden_for'] ) ? $sub_menu['hidden_for'] : [] )
617 ];
618 // processing submenu array
619 $tmp_sub_menu[$order] = $new_array;
620 $i++;
621 }
622 if ( !empty( $tmp_sub_menu ) ) {
623 // adding submenu into temp variable
624 $tmp_menu[$key] = $tmp_sub_menu;
625 }
626 }
627 }
628 if ( !empty( $tmp_menu ) ) {
629 $tempsubmenu = array_merge_recursive( $tempsubmenu, $tmp_menu );
630 }
631 foreach ( $tempsubmenu as $m_k => $m_menu ) {
632 $tempsubmenu[$m_k] = $this->sort_array( $tempsubmenu[$m_k] );
633 }
634 }
635 return $tempsubmenu;
636 }
637
638 /**
639 * Applies menu settings
640 */
641 public function apply_menu( $parent_file ) {
642 // Not applicable for Network Admin
643 if ( is_multisite() && is_network_admin() ) {
644 return;
645 }
646 global $menu, $submenu;
647 $tempmenu = [];
648 $tempsub = [];
649 $submenu = $this->sort_sub_menu_settings( $menu, $submenu );
650 if ( $this->menu && is_array( $this->menu ) ) {
651 foreach ( $this->menu as $key => $menu_item ) {
652 if ( empty( $menu_item[2] ) ) {
653 continue;
654 }
655 if ( strpos( $menu_item[2], 'separator' ) !== false && !$menu_item[0] ) {
656 // Build Separator
657 $newitem = $this->apply_separator_settings( $menu_item, $key );
658 if ( $newitem ) {
659 array_push( $tempmenu, $newitem );
660 }
661 } else {
662 // Build Top Level
663 $newitem = $this->apply_top_level_settings( $menu_item, $key );
664 if ( $newitem ) {
665 array_push( $tempmenu, $newitem );
666 // Menu Editor Custom Separator
667 if ( !empty( $newitem['separator'] ) ) {
668 $separator_order = $this->menu[$key]['order'];
669 $empty_separator = array(
670 0 => '',
671 1 => 'read',
672 2 => 'separator_' . rand( 200, 1000 ) * 1000,
673 3 => '',
674 4 => 'wp-menu-separator',
675 'order' => $separator_order + 0.5,
676 );
677 array_push( $tempmenu, $empty_separator );
678 }
679 $parent_key = $newitem[2];
680 if ( strpos( $newitem[5], 'adminify-custom-menu-' ) !== false ) {
681 $parent_key = $newitem[5];
682 }
683 if ( isset( $this->submenu[$parent_key] ) ) {
684 $subitem = $this->apply_sub_level_settings( $this->submenu[$parent_key], $parent_key );
685 if ( $subitem ) {
686 $tempsub[$newitem[2]] = $this->apply_sub_level_settings( $this->submenu[$parent_key], $parent_key );
687 }
688 }
689 }
690 }
691 }
692 }
693 $submenu = $tempsub;
694 $menu = $this->sort_array( $tempmenu );
695 return $parent_file;
696 }
697
698 /**
699 * Applies sub level menu item settings
700 *
701 * @return $tempsub | false
702 *
703 * @since 1.4
704 */
705 public function apply_sub_level_settings( $subitems, $parentname ) {
706 if ( !is_array( $this->menu_settings ) ) {
707 return $subitems;
708 }
709 if ( !isset( $this->menu_settings[$parentname]['submenu'] ) ) {
710 return $subitems;
711 }
712 $submenu_settings = $this->menu_settings[$parentname]['submenu'];
713 $tempsub = [];
714 foreach ( $subitems as $current_menu_item ) {
715 $sub_level = apply_filters( 'adminify/menu_editor', [
716 'sub_level' => false,
717 ] );
718 if ( !empty( $sub_level['sub_level'] ) ) {
719 if ( empty( $current_menu_item[0] ) || $current_menu_item[2] === 'wp-adminify-settings-pricing' ) {
720 continue;
721 }
722 }
723 $name = '';
724 $link = '';
725 $disabled_for = [];
726 $optiongroup = [];
727 // NO SETTINGS
728 if ( isset( $submenu_settings[$current_menu_item[2]] ) ) {
729 $optiongroup = $submenu_settings[$current_menu_item[2]];
730 if ( isset( $optiongroup['name'] ) ) {
731 $name = $optiongroup['name'];
732 if ( $name != '' ) {
733 $current_menu_item[0] = $name;
734 }
735 }
736 if ( isset( $optiongroup['link'] ) ) {
737 $link = $optiongroup['link'];
738 if ( $link != '' ) {
739 $current_menu_item[2] = $link;
740 $current_menu_item['link'] = $link;
741 }
742 }
743 if ( isset( $optiongroup['external_link'] ) ) {
744 $external_link = $optiongroup['external_link'];
745 }
746 if ( isset( $optiongroup['hidden_for'] ) ) {
747 $disabled_for = $optiongroup['hidden_for'];
748 if ( $this->is_hidden( $disabled_for ) ) {
749 $current_menu_item['hidden_for'] = true;
750 continue;
751 }
752 }
753 }
754 $custom_menu = ( isset( $current_menu_item['key'] ) ? $current_menu_item['key'] : '' );
755 if ( strpos( $custom_menu, 'adminify-custom-submenu-' ) !== false ) {
756 if ( isset( $submenu_settings[$current_menu_item['key']]['hidden_for'] ) ) {
757 $disabled_for = $submenu_settings[$current_menu_item['key']]['hidden_for'];
758 }
759 if ( isset( $submenu_settings[$current_menu_item['key']]['external_link'] ) ) {
760 $external_link = $submenu_settings[$current_menu_item['key']]['external_link'];
761 }
762 if ( $this->is_hidden( $disabled_for ) ) {
763 $current_menu_item['hidden_for'] = true;
764 continue;
765 }
766 }
767 array_push( $tempsub, $current_menu_item );
768 }
769 if ( count( $tempsub ) < 1 ) {
770 return false;
771 } else {
772 return $tempsub;
773 }
774 }
775
776 /**
777 * Applies top level menu item settings
778 *
779 * @since 1.4
780 */
781 public function apply_top_level_settings( $current_menu_item, $key ) {
782 $name = '';
783 $link = '';
784 $icon = '';
785 $disabled_for = [];
786 $optiongroup = [];
787 $order = $key;
788 if ( is_array( $this->menu_settings ) ) {
789 if ( isset( $this->menu_settings[$current_menu_item[2]] ) ) {
790 $optiongroup = $this->menu_settings[$current_menu_item[2]];
791 if ( isset( $optiongroup['name'] ) ) {
792 $name = $optiongroup['name'];
793 if ( $name != '' ) {
794 $current_menu_item[0] = $name;
795 }
796 }
797 if ( isset( $optiongroup['link'] ) ) {
798 $link = $optiongroup['link'];
799 if ( $link != '' ) {
800 $current_menu_item[2] = $link;
801 $current_menu_item['link'] = $link;
802 }
803 }
804 if ( isset( $optiongroup['external_link'] ) ) {
805 $external_link = ( $optiongroup['external_link'] ? $optiongroup['external_link'] : '' );
806 }
807 if ( isset( $optiongroup['icon'] ) ) {
808 $icon = $optiongroup['icon'];
809 if ( $icon != '' ) {
810 $current_menu_item['icon'] = $icon;
811 }
812 }
813 if ( isset( $optiongroup['order'] ) ) {
814 $order = $optiongroup['order'];
815 }
816 if ( isset( $optiongroup['hidden_for'] ) ) {
817 $disabled_for = $optiongroup['hidden_for'];
818 if ( $this->is_hidden( $disabled_for ) ) {
819 $current_menu_item['hidden_for'] = true;
820 } else {
821 $current_menu_item['hidden_for'] = false;
822 }
823 }
824 }
825 $custom_menu = ( isset( $current_menu_item[5] ) ? $current_menu_item[5] : '' );
826 if ( strpos( $custom_menu, 'adminify-custom-menu-' ) !== false ) {
827 if ( isset( $this->menu_settings[$current_menu_item[5]]['hidden_for'] ) && !empty( $this->menu_settings[$current_menu_item[5]]['hidden_for'] ) ) {
828 $disabled_for = $this->menu_settings[$current_menu_item[5]]['hidden_for'];
829 if ( $this->is_hidden( $disabled_for ) ) {
830 $current_menu_item['hidden_for'] = true;
831 }
832 }
833 if ( isset( $this->menu_settings[$current_menu_item[5]]['external_link'] ) ) {
834 $external_link = $this->menu_settings[$current_menu_item[5]]['external_link'];
835 }
836 }
837 }
838 $current_menu_item['order'] = $order;
839 if ( isset( $current_menu_item['hidden_for'] ) ) {
840 if ( $current_menu_item['hidden_for'] === true ) {
841 return false;
842 } else {
843 return $current_menu_item;
844 }
845 } else {
846 return $current_menu_item;
847 }
848 }
849
850 /**
851 * Hidden for method
852 *
853 * @param [type] $disabled_for
854 *
855 * @return boolean
856 */
857 public function is_hidden( $disabled_for ) {
858 if ( !is_array( $disabled_for ) ) {
859 return false;
860 }
861 $current_user = wp_get_current_user();
862 $current_roles = $current_user->roles;
863 $all_roles = wp_roles()->get_names();
864 foreach ( $current_roles as $current_role ) {
865 if ( isset( $all_roles[$current_role] ) && in_array( $all_roles[$current_role], $disabled_for ) ) {
866 return true;
867 }
868 }
869 // Normalize disabled_for array
870 $disabled_for_arr = [];
871 foreach ( $disabled_for as $v ) {
872 $disabled_for_arr[] = jlt_adminify_sluggify_with_underscores( $v );
873 }
874 $slugify_user_login = jlt_adminify_sluggify_with_underscores( $current_user->user_login );
875 // Check Username
876 if ( in_array( $current_user->user_login, $disabled_for_arr ) || in_array( $slugify_user_login, $disabled_for_arr ) ) {
877 return true;
878 }
879 // Check User Roles and Capabilities
880 foreach ( $current_roles as $role ) {
881 $role_obj = get_role( $role );
882 if ( !$role_obj ) {
883 continue;
884 }
885 // Check if role slug is in disabled array
886 if ( in_array( $role, $disabled_for_arr ) ) {
887 return true;
888 }
889 // Check if role display name is in disabled array
890 if ( isset( $disabled_for_arr[$role] ) && (in_array( $all_roles[$role], $disabled_for ) || in_array( strtolower( $all_roles[$role] ), array_map( 'strtolower', $disabled_for ) )) ) {
891 return true;
892 }
893 // Check for custom roles
894 foreach ( $disabled_for as $disabled_item ) {
895 // Convert role names to match WordPress format
896 $disabled_role = str_replace( ' ', '_', strtolower( $disabled_item ) );
897 if ( $role === $disabled_role ) {
898 return true;
899 }
900 }
901 }
902 // Handle Super Admin specially
903 if ( is_super_admin( $current_user->ID ) ) {
904 if ( in_array( 'Super Admin', $disabled_for_arr ) || in_array( 'super_admin', $disabled_for_arr ) || in_array( 'administrator', $disabled_for_arr ) ) {
905 return true;
906 }
907 // Super admin sees everything by default unless explicitly disabled
908 return false;
909 }
910 // Special check for user ID 1 (default admin)
911 if ( $current_user->ID === 1 ) {
912 if ( in_array( 'Super Admin', $disabled_for_arr ) || in_array( 'super_admin', $disabled_for_arr ) || in_array( 'administrator', $disabled_for_arr ) ) {
913 return true;
914 }
915 return false;
916 }
917 return false;
918 }
919
920 /**
921 * Applies separator menu item settings
922 *
923 * @since 1.0.0
924 */
925 public function apply_separator_settings( $current_menu_item, $key ) {
926 $name = '';
927 $disabled_for = [];
928 $optiongroup = [];
929 $order = $key;
930 if ( is_array( $this->menu_settings ) ) {
931 if ( isset( $this->menu_settings[$current_menu_item[2]] ) ) {
932 $optiongroup = $this->menu_settings[$current_menu_item[2]];
933 if ( isset( $optiongroup['name'] ) ) {
934 $name = $optiongroup['name'];
935 if ( $name != '' ) {
936 $current_menu_item['name'] = $name;
937 }
938 }
939 if ( isset( $optiongroup['order'] ) ) {
940 $order = $optiongroup['order'];
941 }
942 if ( isset( $optiongroup['hidden_for'] ) ) {
943 $disabled_for = $optiongroup['hidden_for'];
944 if ( $this->is_hidden( $disabled_for ) ) {
945 $current_menu_item['hidden_for'] = true;
946 }
947 }
948 }
949 }
950 $current_menu_item['order'] = $order;
951 if ( isset( $current_menu_item['hidden_for'] ) ) {
952 if ( $current_menu_item['hidden_for'] == true ) {
953 return false;
954 } else {
955 return $current_menu_item;
956 }
957 } else {
958 return $current_menu_item;
959 }
960 }
961
962 public function get_saved_sub_menu() {
963 $menu_settings = $this->menu_settings;
964 $menu = $this->menu;
965 $submenu = $this->submenu;
966 if ( is_array( $menu_settings ) && !array_key_exists( 0, $menu_settings ) ) {
967 foreach ( $menu as $menu_item ) {
968 if ( isset( $menu_settings[$menu_item[2]] ) ) {
969 unset($menu_settings[$menu_item[2]]);
970 }
971 }
972 $tmp_menu = [];
973 foreach ( $menu_settings as $key => $menu_s ) {
974 if ( isset( $menu_s['submenu'] ) && is_array( $menu_s['submenu'] ) ) {
975 $tmp_sub_menu = [];
976 $i = 0;
977 foreach ( $menu_s['submenu'] as $k => $sub_menu ) {
978 $new_array = [
979 $sub_menu['name'],
980 'read',
981 $sub_menu['link'],
982 'order' => $i
983 ];
984 $tmp_sub_menu[$i] = $new_array;
985 $i++;
986 }
987 if ( !empty( $tmp_sub_menu ) ) {
988 $tmp_menu[$key] = $tmp_sub_menu;
989 }
990 }
991 }
992 if ( !empty( $tmp_menu ) ) {
993 $submenu = $submenu + $tmp_menu;
994 }
995 }
996 return $submenu;
997 }
998
999 /**
1000 * Render Menu Editor
1001 */
1002 public function render_menu_editor() {
1003 global $wp_roles;
1004 $this->roles = $wp_roles->roles;
1005 if ( $this->menu && is_array( $this->menu ) ) {
1006 foreach ( $this->menu as $menu_item ) {
1007 $next_menu_item = next( $this->menu );
1008 if ( strpos( $menu_item[2], 'separator' ) !== false && !$menu_item[0] ) {
1009 // Render Separator
1010 // $this->render_menu_separator($menu_item);
1011 } else {
1012 // Render Top Level menu
1013 $this->render_top_level_menu_item(
1014 $this->menu,
1015 $menu_item,
1016 $this->submenu,
1017 $next_menu_item
1018 );
1019 }
1020 }
1021 $this->render_add_new_menu_item();
1022 }
1023 }
1024
1025 public function get_icon( $value, $default ) {
1026 if ( empty( $value ) ) {
1027 return $default;
1028 }
1029 return $value;
1030 }
1031
1032 /**
1033 * Generate User Rules Select box
1034 */
1035 public function generate_user_rules_select_field( $menu_id, $disabled_for, $menu_type = 'menu' ) {
1036 ob_start();
1037 ?>
1038 <select class="adminify-menu-settings adminify-user-role-select <?php
1039 echo esc_attr( $menu_type );
1040 ?>_setting" name="hidden_for" id="<?php
1041 echo esc_attr( $menu_id );
1042 ?>-user-role-types" multiple>
1043 <optgroup label="<?php
1044 esc_attr_e( 'Roles', 'adminify' );
1045 ?>">
1046 <?php
1047 foreach ( $this->roles as $role ) {
1048 $rolename = $role['name'];
1049 if ( 'administrator' == strtolower( $rolename ) ) {
1050 continue;
1051 }
1052 $sel = '';
1053 if ( in_array( $rolename, $disabled_for ) ) {
1054 $sel = 'selected';
1055 }
1056 ?>
1057 <option value="<?php
1058 echo esc_attr( $rolename );
1059 ?>" <?php
1060 echo esc_attr( $sel );
1061 ?>><?php
1062 echo esc_html( $rolename );
1063 ?></option>
1064 <?php
1065 }
1066 ?>
1067 </optgroup>
1068
1069 <optgroup label="<?php
1070 esc_attr_e( 'Users', 'adminify' );
1071 ?>" class="adminify-users-optgroup">
1072 <?php
1073 // Only include pre-selected users in HTML (AJAX will populate dropdown)
1074 foreach ( $disabled_for as $item ) {
1075 // Check if this is a user (not a role)
1076 $is_role = false;
1077 foreach ( $this->roles as $role ) {
1078 if ( $role['name'] === $item ) {
1079 $is_role = true;
1080 break;
1081 }
1082 }
1083 if ( !$is_role ) {
1084 $user = get_user_by( 'login', $item );
1085 if ( $user ) {
1086 ?>
1087 <option value="<?php
1088 echo esc_attr( $user->user_login );
1089 ?>" selected><?php
1090 echo esc_html( $user->user_login . ' (' . $user->display_name . ')' );
1091 ?></option>
1092 <?php
1093 }
1094 }
1095 }
1096 ?>
1097 </optgroup>
1098 </select>
1099 <?php
1100 return ob_get_clean();
1101 }
1102
1103 /**
1104 * Render Top Level menu Item
1105 *
1106 * @return void
1107 */
1108 public function render_top_level_menu_item(
1109 $master_menu,
1110 $current_menu_item,
1111 $master_sub_menu,
1112 $next_menu_item
1113 ) {
1114 if ( empty( $current_menu_item[2] ) ) {
1115 return;
1116 }
1117 // $disabled_for = '';
1118 $menu_id = preg_replace( '/[^A-Za-z0-9 ]/', '', $current_menu_item[5] );
1119 $name = '';
1120 $link = '';
1121 $external_link = '';
1122 $icon = '';
1123 $separator = '';
1124 $disabled_for = [];
1125 $optiongroup = [];
1126 $menu_options = $this->menu_settings;
1127 if ( !empty( $next_menu_item ) && strpos( $next_menu_item[2], 'separator' ) !== false ) {
1128 $separator = 1;
1129 }
1130 if ( is_array( $menu_options ) ) {
1131 if ( isset( $menu_options[$current_menu_item[2]] ) ) {
1132 $optiongroup = $menu_options[$current_menu_item[2]];
1133 if ( isset( $optiongroup['name'] ) ) {
1134 $name = $optiongroup['name'];
1135 }
1136 if ( isset( $optiongroup['link'] ) ) {
1137 $link = $optiongroup['link'];
1138 }
1139 if ( isset( $optiongroup['icon'] ) ) {
1140 $icon = $optiongroup['icon'];
1141 }
1142 if ( isset( $optiongroup['hidden_for'] ) ) {
1143 $disabled_for = $optiongroup['hidden_for'];
1144 }
1145 if ( isset( $optiongroup['separator'] ) ) {
1146 $separator = $optiongroup['separator'];
1147 }
1148 if ( isset( $optiongroup['external_link'] ) ) {
1149 $external_link = $optiongroup['external_link'];
1150 }
1151 }
1152 }
1153 $name_attr = $current_menu_item[2];
1154 if ( strpos( $current_menu_item[5], 'adminify-custom-menu-' ) !== false ) {
1155 $name_attr = $current_menu_item[5];
1156 $name = $current_menu_item[0];
1157 $link = $current_menu_item[2];
1158 if ( isset( $menu_options[$current_menu_item[5]]['hidden_for'] ) ) {
1159 $disabled_for = $menu_options[$current_menu_item[5]]['hidden_for'];
1160 }
1161 if ( isset( $menu_options[$current_menu_item[5]] ) ) {
1162 $optiongroup = $menu_options[$current_menu_item[5]];
1163 }
1164 if ( isset( $menu_options[$current_menu_item[5]]['icon'] ) ) {
1165 $icon = $menu_options[$current_menu_item[5]]['icon'];
1166 }
1167 if ( isset( $current_menu_item['separator'] ) ) {
1168 $separator = $current_menu_item['separator'];
1169 }
1170 if ( isset( $current_menu_item['external_link'] ) ) {
1171 $external_link = $current_menu_item['external_link'];
1172 }
1173 }
1174 if ( !is_array( $disabled_for ) ) {
1175 $disabled_for = [];
1176 }
1177 // LIST OF AVAILABLE MENU ICONS
1178 $icons = [
1179 'dashicons-admin-multisite' => 'dashicons dashicons-admin-multisite',
1180 'dashicons-dashboard' => 'dashicons dashicons-dashboard',
1181 'dashicons-admin-post' => 'dashicons dashicons-admin-post',
1182 'dashicons-database' => 'dashicons dashicons-database',
1183 'dashicons-admin-media' => 'dashicons dashicons-admin-media',
1184 'dashicons-admin-page' => 'dashicons dashicons-admin-page',
1185 'dashicons-admin-comments' => 'dashicons dashicons-admin-comments',
1186 'dashicons-admin-appearance' => 'dashicons dashicons-admin-appearance',
1187 'dashicons-admin-plugins' => 'dashicons dashicons-admin-plugins',
1188 'dashicons-admin-users' => 'dashicons dashicons-admin-users',
1189 'dashicons-admin-tools' => 'dashicons dashicons-admin-tools',
1190 'dashicons-chart-bar' => 'dashicons dashicons-chart-bar',
1191 'dashicons-admin-settings' => 'dashicons dashicons-admin-settings',
1192 ];
1193 $default_icons = ( isset( $current_menu_item ) ? $current_menu_item[6] : 'dashicons dashicons-external' );
1194 ?>
1195 <div class="accordion adminify_menu_item" name="<?php
1196 echo esc_attr( $name_attr );
1197 ?>" id="wp-adminify-top-menu-<?php
1198 echo esc_attr( $menu_id );
1199 ?>">
1200 <input type="number" class="top_level_order" value="" style="display:none;">
1201 <a class="menu-editor-title accordion-button adminify-flex adminify-flex-center adminify-gap-2" href="#">
1202 <svg class="drag-icon is-pulled-left mr-2" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
1203 <path d="M12 14C13.1046 14 14 13.1046 14 12C14 10.8954 13.1046 10 12 10C10.8954 10 10 10.8954 10 12C10 13.1046 10.8954 14 12 14Z" fill="#4E4B66" fill-opacity="0.72" />
1204 <path d="M12 7C13.1046 7 14 6.10457 14 5C14 3.89543 13.1046 3 12 3C10.8954 3 10 3.89543 10 5C10 6.10457 10.8954 7 12 7Z" fill="#4E4B66" fill-opacity="0.72" />
1205 <path d="M12 21C13.1046 21 14 20.1046 14 19C14 17.8954 13.1046 17 12 17C10.8954 17 10 17.8954 10 19C10 20.1046 10.8954 21 12 21Z" fill="#4E4B66" fill-opacity="0.72" />
1206 <path d="M5 14C6.10457 14 7 13.1046 7 12C7 10.8954 6.10457 10 5 10C3.89543 10 3 10.8954 3 12C3 13.1046 3.89543 14 5 14Z" fill="#4E4B66" fill-opacity="0.72" />
1207 <path d="M5 7C6.10457 7 7 6.10457 7 5C7 3.89543 6.10457 3 5 3C3.89543 3 3 3.89543 3 5C3 6.10457 3.89543 7 5 7Z" fill="#4E4B66" fill-opacity="0.72" />
1208 <path d="M5 21C6.10457 21 7 20.1046 7 19C7 17.8954 6.10457 17 5 17C3.89543 17 3 17.8954 3 19C3 20.1046 3.89543 21 5 21Z" fill="#4E4B66" fill-opacity="0.72" />
1209 <path d="M19 14C20.1046 14 21 13.1046 21 12C21 10.8954 20.1046 10 19 10C17.8954 10 17 10.8954 17 12C17 13.1046 17.8954 14 19 14Z" fill="#4E4B66" fill-opacity="0.72" />
1210 <path d="M19 7C20.1046 7 21 6.10457 21 5C21 3.89543 20.1046 3 19 3C17.8954 3 17 3.89543 17 5C17 6.10457 17.8954 7 19 7Z" fill="#4E4B66" fill-opacity="0.72" />
1211 <path d="M19 21C20.1046 21 21 20.1046 21 19C21 17.8954 20.1046 17 19 17C17.8954 17 17 17.8954 17 19C17 20.1046 17.8954 21 19 21Z" fill="#4E4B66" fill-opacity="0.72" />
1212 </svg>
1213 <?php
1214 echo wp_kses_post( preg_replace( '/\\<span.*?>.*?\\<\\/span><\\/span>/s', '', $current_menu_item[0] ) );
1215 ?>
1216 </a>
1217
1218 <div class="accordion-body adminify_top_level_settings">
1219 <div class="tabs tabbable">
1220 <ul class="adminify-flex adminify-flex-center adminify-m-0 nav nav-tabs">
1221 <li class="nav-item active">
1222 <a class="nav-link is-clickable active" href="#tab-<?php
1223 echo esc_attr( $menu_id );
1224 ?>-1">
1225 <?php
1226 esc_html_e( 'Settings', 'adminify' );
1227 ?>
1228 </a>
1229 </li>
1230 <li class="nav-item" role="presentation">
1231 <a class="nav-link is-clickable" href="#tab-<?php
1232 echo esc_attr( $menu_id );
1233 ?>-2">
1234 <?php
1235 esc_html_e( 'Submenu', 'adminify' );
1236 ?>
1237 </a>
1238 </li>
1239 </ul>
1240 </div>
1241
1242 <div class="tab-content tab-panel panel adminify-p-4">
1243 <div id="tab-<?php
1244 echo esc_attr( $menu_id );
1245 ?>-1" class="tab-pane">
1246 <div class="menu-editor-form">
1247 <div class="columns">
1248 <div class="column">
1249 <label for="<?php
1250 echo esc_attr( $current_menu_item[2] );
1251 ?>">
1252 <?php
1253 esc_html_e( 'Rename as', 'adminify' );
1254 ?>
1255 </label>
1256 <input class="menu_setting" type="text" name="name" data-top-menu-id="<?php
1257 echo esc_attr( $menu_id );
1258 ?>" placeholder="<?php
1259 echo esc_attr( $current_menu_item[0] );
1260 ?>" value='<?php
1261 echo esc_attr( $name );
1262 ?>' />
1263 </div>
1264 <div class="column">
1265 <label for="<?php
1266 echo esc_attr( $current_menu_item[2] );
1267 ?>">
1268 <?php
1269 esc_html_e( 'Hidden For Roles or Users', 'adminify' );
1270 ?>
1271 </label>
1272
1273 <div class="select is-small">
1274
1275 <?php
1276 echo $this->generate_user_rules_select_field( $menu_id, $disabled_for );
1277 ?>
1278
1279 </div>
1280 </div>
1281 </div>
1282
1283 <div class="columns">
1284 <!-- <div class="column">
1285 <label for="">
1286 <?php
1287 esc_html_e( 'Change Link', 'adminify' );
1288 ?>
1289 </label>
1290 <input class="menu_setting" name="link" type="url" placeholder="<?php
1291 esc_html_e( 'New link', 'adminify' );
1292 ?>" value="<?php
1293 echo esc_attr( ( $name_attr != ltrim( $link, '#' ) ? $link : '' ) );
1294 ?>" onchange="checkForLinkTarget(this)" >
1295
1296 <label for="external_link-<?php
1297 echo esc_attr( $name_attr );
1298 ?>">
1299 <?php
1300 esc_html_e( 'New Window?', 'adminify' );
1301 ?>
1302 <input class="menu_setting" id="external_link-<?php
1303 echo esc_attr( $name_attr );
1304 ?>" name="external_link" type="checkbox" value="0" <?php
1305 checked( (int) $external_link, 1 );
1306 ?> disabled>
1307
1308 </label>
1309 <script>
1310 function checkForLinkTarget(inputField) {
1311 var checkbox = inputField.closest('.column').querySelector('input[type="checkbox"]');
1312
1313 if (inputField.value.trim() !== "") {
1314 checkbox.disabled = false; // Enable checkbox if input is not empty
1315 } else {
1316 checkbox.disabled = true; // Disable checkbox if input is empty
1317 }
1318 }
1319 </script>
1320 </div> -->
1321
1322 <div class="column">
1323 <label for="">
1324 <?php
1325 esc_html_e( 'Change Link', 'adminify' );
1326 ?>
1327 </label>
1328 <input class="menu_setting" name="link" type="url"
1329 placeholder="<?php
1330 esc_html_e( 'New link', 'adminify' );
1331 ?>"
1332 value="<?php
1333 echo esc_attr( ( $name_attr != ltrim( $link, '#' ) ? $link : '' ) );
1334 ?>"
1335 oninput="checkForLinkTarget(this)">
1336 <div class="new-tab-settings" style="padding-top: 10px;">
1337 <label for="external_link-<?php
1338 echo esc_attr( $name_attr );
1339 ?>" style="display: flex; align-items: center; gap: 8px;">
1340
1341 <input class="menu_setting" id="external_link-<?php
1342 echo esc_attr( $name_attr );
1343 ?>"
1344 name="external_link" type="checkbox" value="1"
1345 <?php
1346 checked( (int) $external_link, 1 );
1347 ?> disabled style="margin-top: 0;" >
1348 <span><?php
1349 esc_html_e( 'New Window?', 'adminify' );
1350 ?></span>
1351 </label>
1352 </div>
1353
1354 <script>
1355 // Function to validate URL
1356 function isValidURL(url) {
1357 // Allow absolute URLs (with http:// or https://)
1358 var absolutePattern = /^(https?:\/\/)[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}.*$/;
1359
1360 // Allow relative URLs (starting with "/")
1361 var relativePattern = /^\/[a-zA-Z0-9-_\/]+$/;
1362
1363 return absolutePattern.test(url) || relativePattern.test(url);
1364 }
1365
1366
1367 function checkForLinkTarget(inputField) {
1368 var checkbox = inputField.closest('.column').querySelector('input[type="checkbox"]');
1369
1370 if (isValidURL(inputField.value.trim())) {
1371 checkbox.disabled = false; // Enable if URL is valid
1372 } else {
1373 checkbox.disabled = true; // Disable if invalid
1374 checkbox.checked = false; // Also uncheck if disabled
1375 }
1376 }
1377
1378 // Run on page load
1379 document.addEventListener("DOMContentLoaded", function() {
1380 document.querySelectorAll('.column input[name="link"]').forEach(function(inputField) {
1381 checkForLinkTarget(inputField);
1382 });
1383 });
1384 </script>
1385 </div>
1386
1387 <div class="column">
1388 <label for="">
1389 <?php
1390 esc_html_e( 'Set Custom Icon', 'adminify' );
1391 ?>
1392 </label>
1393 <div class="icon-picker-wrap wp-adminify-menu-icon-picker adminify-icon-picker-input icon-select-button is-clickable is-pulled-left">
1394 <ul class="icon-picker">
1395 <li class="icon-none" title="None"><i class="dashicons dashicons-dismiss"></i></li>
1396 <li class="select-icon <?php
1397 echo ( !empty( $icon ) && preg_match( '/http(s?)\\:\\/\\//i', $icon ) || empty( $icon ) && empty( $icons[$default_icons] ) ? 'custom-icon' : '' );
1398 ?>" title="Icon Library">
1399 <?php
1400 if ( !empty( $icon ) ) {
1401 if ( preg_match( '/http(s?)\\:\\/\\//i', $icon ) ) {
1402 $image = explode( ',', $icon );
1403 echo '<i class=""><img width="24" height="24" src=' . esc_url( $image[1] ) . ' ></i>';
1404 } else {
1405 ?>
1406 <i class="<?php
1407 echo esc_attr( $this->get_icon( esc_attr( $icon ), '' ) );
1408 ?>"></i>
1409 <?php
1410 }
1411 } else {
1412 $adminify_icon = WP_ADMINIFY_ASSETS_IMAGE . 'logos/menu-icon.svg';
1413 if ( empty( $icons[$default_icons] ) ) {
1414 echo '<i class=""><img width="24" height="24" src=' . esc_url( $adminify_icon ) . ' ></i>';
1415 } else {
1416 ?>
1417 <i class="<?php
1418 echo wp_kses_post( $this->get_icon( esc_attr( $icon ), $icons[$default_icons] ) );
1419 ?>"></i>
1420 <?php
1421 }
1422 }
1423 ?>
1424
1425 </li>
1426 <input type="hidden" class="menu_setting" name="icon" value="<?php
1427 echo esc_attr( $icon );
1428 ?>">
1429 </ul>
1430 </div>
1431 </div>
1432 </div>
1433 <div class='columns'>
1434 <?php
1435 $upgrade_pro = '';
1436 $separator_name_attr = '';
1437 $upgrade_pro = 'upgrade-pro';
1438 $separator_name_attr = Utils::adminify_upgrade_pro( 'Add Separator' );
1439 ?>
1440
1441 <div class='column <?php
1442 echo esc_attr( $upgrade_pro );
1443 ?>'>
1444 <label for="seperator-<?php
1445 echo esc_attr( $name_attr );
1446 ?>">
1447 <?php
1448 $separator_content = apply_filters( 'adminify/menu_editor/add_separator', $separator_name_attr, $separator );
1449 // Apply the filter
1450 echo $separator_content;
1451 ?>
1452 </label>
1453 </div>
1454 </div>
1455 </div>
1456 <?php
1457 if ( strpos( $current_menu_item[5], 'adminify-custom-menu-' ) !== false ) {
1458 ?>
1459 <div class="remove-add-new-menu"><span data-id="<?php
1460 echo esc_attr( $current_menu_item[5] );
1461 ?>"><i class="icon-close"></i> Delete</span></div>
1462 <?php
1463 }
1464 ?>
1465 </div>
1466 <div id="tab-<?php
1467 echo esc_attr( $menu_id );
1468 ?>-2" class="tab-pane tab-pane--submenu">
1469 <?php
1470 // Sub Menu Items Check
1471 $link = $current_menu_item[2];
1472 if ( isset( $master_sub_menu[$name_attr] ) && is_array( $master_sub_menu[$name_attr] ) ) {
1473 foreach ( $master_sub_menu[$name_attr] as $sub_menu_item ) {
1474 $this->build_sub_menu_item( $sub_menu_item, $optiongroup, $name_attr );
1475 }
1476 } else {
1477 ?>
1478 <span><?php
1479 esc_html_e( 'No sub menu items', 'adminify' );
1480 ?></span>
1481 <?php
1482 }
1483 $this->render_add_new_menu_item( true );
1484 // true for submenu item
1485 ?>
1486
1487 </div>
1488 </div>
1489
1490 </div>
1491 </div>
1492
1493 <?php
1494 }
1495
1496 public function render_menu_separator( $current_menu_item ) {
1497 $disabled_for = [];
1498 $name = '';
1499 $menu_id = preg_replace( '/[^A-Za-z0-9 ]/', '', $current_menu_item[2] );
1500 $menu_options = $this->menu_settings;
1501 if ( is_array( $menu_options ) ) {
1502 if ( isset( $menu_options[$current_menu_item[2]] ) ) {
1503 $optiongroup = $menu_options[$current_menu_item[2]];
1504 if ( isset( $optiongroup['name'] ) ) {
1505 $name = $optiongroup['name'];
1506 }
1507 if ( isset( $optiongroup['hidden_for'] ) ) {
1508 $disabled_for = $optiongroup['hidden_for'];
1509 }
1510 }
1511 }
1512 if ( !is_array( $disabled_for ) ) {
1513 $disabled_for = [];
1514 }
1515 ?>
1516 <div class="accordion adminify_menu_item" name="<?php
1517 echo esc_attr( $current_menu_item[2] );
1518 ?>" id="<?php
1519 echo esc_attr( $menu_id );
1520 ?>">
1521 <input type="number" class="top_level_order" value="" style="display:none;">
1522 <a class="menu-editor-title accordion-button p-4" href="#">
1523 <svg class="drag-icon is-pulled-left mr-2" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
1524 <path d="M12 14C13.1046 14 14 13.1046 14 12C14 10.8954 13.1046 10 12 10C10.8954 10 10 10.8954 10 12C10 13.1046 10.8954 14 12 14Z" fill="#4E4B66" fill-opacity="0.72" />
1525 <path d="M12 7C13.1046 7 14 6.10457 14 5C14 3.89543 13.1046 3 12 3C10.8954 3 10 3.89543 10 5C10 6.10457 10.8954 7 12 7Z" fill="#4E4B66" fill-opacity="0.72" />
1526 <path d="M12 21C13.1046 21 14 20.1046 14 19C14 17.8954 13.1046 17 12 17C10.8954 17 10 17.8954 10 19C10 20.1046 10.8954 21 12 21Z" fill="#4E4B66" fill-opacity="0.72" />
1527 <path d="M5 14C6.10457 14 7 13.1046 7 12C7 10.8954 6.10457 10 5 10C3.89543 10 3 10.8954 3 12C3 13.1046 3.89543 14 5 14Z" fill="#4E4B66" fill-opacity="0.72" />
1528 <path d="M5 7C6.10457 7 7 6.10457 7 5C7 3.89543 6.10457 3 5 3C3.89543 3 3 3.89543 3 5C3 6.10457 3.89543 7 5 7Z" fill="#4E4B66" fill-opacity="0.72" />
1529 <path d="M5 21C6.10457 21 7 20.1046 7 19C7 17.8954 6.10457 17 5 17C3.89543 17 3 17.8954 3 19C3 20.1046 3.89543 21 5 21Z" fill="#4E4B66" fill-opacity="0.72" />
1530 <path d="M19 14C20.1046 14 21 13.1046 21 12C21 10.8954 20.1046 10 19 10C17.8954 10 17 10.8954 17 12C17 13.1046 17.8954 14 19 14Z" fill="#4E4B66" fill-opacity="0.72" />
1531 <path d="M19 7C20.1046 7 21 6.10457 21 5C21 3.89543 20.1046 3 19 3C17.8954 3 17 3.89543 17 5C17 6.10457 17.8954 7 19 7Z" fill="#4E4B66" fill-opacity="0.72" />
1532 <path d="M19 21C20.1046 21 21 20.1046 21 19C21 17.8954 20.1046 17 19 17C17.8954 17 17 17.8954 17 19C17 20.1046 17.8954 21 19 21Z" fill="#4E4B66" fill-opacity="0.72" />
1533 </svg>
1534 <?php
1535 esc_html_e( 'Separator', 'adminify' );
1536 ?>
1537 </a>
1538
1539 <div class="accordion-body adminify_top_level_settings">
1540 <div class="tab-content tab-panel panel p-4">
1541 <div class="menu-editor-form">
1542 <div class="columns">
1543 <div class="column">
1544 <label for=""><?php
1545 esc_html_e( 'Rename as', 'adminify' );
1546 ?></label>
1547 <input class="menu_setting" type="text" name="name" placeholder="<?php
1548 esc_html_e( 'New Name', 'adminify' );
1549 ?>" value="<?php
1550 echo esc_attr( $name );
1551 ?>">
1552 </div>
1553 <div class="column">
1554 <label for=""><?php
1555 esc_html_e( 'Hidden For Roles or Users', 'adminify' );
1556 ?></label>
1557
1558 <div class="select is-small">
1559 <?php
1560 echo $this->generate_user_rules_select_field( $menu_id, $disabled_for );
1561 ?>
1562 </div>
1563 </div>
1564 </div>
1565 </div>
1566
1567 </div>
1568 </div>
1569 </div>
1570
1571 <?php
1572 }
1573
1574 public function build_sub_menu_item( $current_menu_item, $optiongroup, $name_attr ) {
1575 $name = '';
1576 $link = '';
1577 $icon = '';
1578 $external_link = '';
1579 $disabled_for = [];
1580 $suboptiongroup = [];
1581 $menu_options = $this->menu_settings;
1582 if ( isset( $optiongroup['submenu'] ) ) {
1583 if ( isset( $optiongroup['submenu'][$current_menu_item[2]] ) ) {
1584 $suboptiongroup = $optiongroup['submenu'][$current_menu_item[2]];
1585 if ( isset( $suboptiongroup['name'] ) ) {
1586 $name = $suboptiongroup['name'];
1587 }
1588 if ( isset( $suboptiongroup['link'] ) ) {
1589 $link = $suboptiongroup['link'];
1590 }
1591 if ( isset( $suboptiongroup['external_link'] ) ) {
1592 $external_link = $suboptiongroup['external_link'];
1593 }
1594 if ( isset( $suboptiongroup['icon'] ) ) {
1595 $icon = $suboptiongroup['icon'];
1596 }
1597 if ( isset( $suboptiongroup['hidden_for'] ) ) {
1598 $disabled_for = $suboptiongroup['hidden_for'];
1599 }
1600 }
1601 }
1602 $sub_menu_name_attr = $current_menu_item[2];
1603 if ( isset( $current_menu_item['key'] ) ) {
1604 $sub_menu_name_attr = $current_menu_item['key'];
1605 }
1606 if ( strpos( $sub_menu_name_attr, 'adminify-custom-submenu-' ) !== false ) {
1607 $name = $current_menu_item[0];
1608 $link = $current_menu_item[2];
1609 if ( isset( $optiongroup['submenu'][$sub_menu_name_attr]['hidden_for'] ) ) {
1610 $disabled_for = $optiongroup['submenu'][$sub_menu_name_attr]['hidden_for'];
1611 }
1612 if ( isset( $optiongroup['submenu'][$sub_menu_name_attr]['icon'] ) ) {
1613 $icon = $optiongroup['submenu'][$sub_menu_name_attr]['icon'];
1614 }
1615 if ( isset( $optiongroup['submenu'][$sub_menu_name_attr]['external_link'] ) ) {
1616 $external_link = $optiongroup['submenu'][$sub_menu_name_attr]['external_link'];
1617 }
1618 }
1619 if ( !is_array( $disabled_for ) ) {
1620 $disabled_for = [];
1621 }
1622 $menu_id = preg_replace( '/[^A-Za-z0-9 ]/', '', $sub_menu_name_attr );
1623 ?>
1624 <div class="accordion adminify_sub_menu_item" name="<?php
1625 echo esc_attr( $sub_menu_name_attr );
1626 ?>" id="wp-adminify-sub-menu-<?php
1627 echo esc_attr( $menu_id );
1628 ?>">
1629 <input type="number" class="top_level_order" value="" style="display:none;">
1630 <a class="menu-editor-title accordion-button adminify-flex adminify-flex-center adminify-gap-2" href="#">
1631 <svg class="drag-icon is-pulled-left mr-2" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
1632 <path d="M12 14C13.1046 14 14 13.1046 14 12C14 10.8954 13.1046 10 12 10C10.8954 10 10 10.8954 10 12C10 13.1046 10.8954 14 12 14Z" fill="#4E4B66" fill-opacity="0.72" />
1633 <path d="M12 7C13.1046 7 14 6.10457 14 5C14 3.89543 13.1046 3 12 3C10.8954 3 10 3.89543 10 5C10 6.10457 10.8954 7 12 7Z" fill="#4E4B66" fill-opacity="0.72" />
1634 <path d="M12 21C13.1046 21 14 20.1046 14 19C14 17.8954 13.1046 17 12 17C10.8954 17 10 17.8954 10 19C10 20.1046 10.8954 21 12 21Z" fill="#4E4B66" fill-opacity="0.72" />
1635 <path d="M5 14C6.10457 14 7 13.1046 7 12C7 10.8954 6.10457 10 5 10C3.89543 10 3 10.8954 3 12C3 13.1046 3.89543 14 5 14Z" fill="#4E4B66" fill-opacity="0.72" />
1636 <path d="M5 7C6.10457 7 7 6.10457 7 5C7 3.89543 6.10457 3 5 3C3.89543 3 3 3.89543 3 5C3 6.10457 3.89543 7 5 7Z" fill="#4E4B66" fill-opacity="0.72" />
1637 <path d="M5 21C6.10457 21 7 20.1046 7 19C7 17.8954 6.10457 17 5 17C3.89543 17 3 17.8954 3 19C3 20.1046 3.89543 21 5 21Z" fill="#4E4B66" fill-opacity="0.72" />
1638 <path d="M19 14C20.1046 14 21 13.1046 21 12C21 10.8954 20.1046 10 19 10C17.8954 10 17 10.8954 17 12C17 13.1046 17.8954 14 19 14Z" fill="#4E4B66" fill-opacity="0.72" />
1639 <path d="M19 7C20.1046 7 21 6.10457 21 5C21 3.89543 20.1046 3 19 3C17.8954 3 17 3.89543 17 5C17 6.10457 17.8954 7 19 7Z" fill="#4E4B66" fill-opacity="0.72" />
1640 <path d="M19 21C20.1046 21 21 20.1046 21 19C21 17.8954 20.1046 17 19 17C17.8954 17 17 17.8954 17 19C17 20.1046 17.8954 21 19 21Z" fill="#4E4B66" fill-opacity="0.72" />
1641 </svg>
1642 <?php
1643 if ( !empty( $current_menu_item[0] ) ) {
1644 echo wp_kses_post( preg_replace( '/\\<span.*?>.*?\\<\\/span><\\/span>/s', '', $current_menu_item[0] ) );
1645 }
1646 ?>
1647 </a>
1648
1649 <div class="accordion-body">
1650 <div class="tab-content tab-panel panel p-4">
1651 <div class="tab-pane">
1652 <div class="menu-editor-form">
1653 <div class="columns">
1654 <div class="column">
1655 <label for=""><?php
1656 esc_html_e( 'Rename as', 'adminify' );
1657 ?></label>
1658 <input class="sub_menu_setting" type="text" data-sub-menu-id="<?php
1659 echo esc_attr( $menu_id );
1660 ?>" name="name" placeholder="<?php
1661 esc_html_e( 'New Menu name...', 'adminify' );
1662 ?>" value="<?php
1663 echo esc_attr( $name );
1664 ?>">
1665 </div>
1666 <div class="column">
1667 <label for=""><?php
1668 esc_html_e( 'Hidden For Roles or Users', 'adminify' );
1669 ?></label>
1670
1671 <div class="select is-small">
1672 <?php
1673 echo $this->generate_user_rules_select_field( $menu_id, $disabled_for, 'sub_menu' );
1674 ?>
1675 </div>
1676 </div>
1677 </div>
1678 <div class="columns">
1679 <div class="column">
1680 <label for=""><?php
1681 esc_html_e( 'Change Link', 'adminify' );
1682 ?></label>
1683 <input class="sub_menu_setting" name="link" type="url" placeholder="New link" value="<?php
1684 echo esc_attr( ( $sub_menu_name_attr != ltrim( $link, '#' ) ? $link : '' ) );
1685 ?>" onchange="checkForLinkTarget(this)" >
1686
1687 <label for="external_link-<?php
1688 echo esc_attr( $sub_menu_name_attr );
1689 ?>">
1690 <?php
1691 esc_html_e( 'New Window?', 'adminify' );
1692 ?>
1693 <input class="sub_menu_setting" id="external_link-<?php
1694 echo esc_attr( $sub_menu_name_attr );
1695 ?>" name="external_link" type="checkbox" value="0" <?php
1696 checked( (int) $external_link, 1 );
1697 ?>disabled />
1698
1699 </label>
1700 </div>
1701 <div class="column">
1702 <label for="" style="margin-top:25px">
1703 <?php
1704 esc_html_e( 'Custom Icon is not allowed for Submenu', 'adminify' );
1705 ?>
1706 </label>
1707 </div>
1708 </div>
1709 </div>
1710 <?php
1711 if ( strpos( $sub_menu_name_attr, 'adminify-custom-submenu-' ) !== false ) {
1712 ?>
1713 <div class="remove-add-new-menu"><span data-id="<?php
1714 echo esc_attr( $sub_menu_name_attr );
1715 ?>"><i class="icon-close"></i> Delete</span></div>
1716 <?php
1717 }
1718 ?>
1719 </div>
1720 </div>
1721 </div>
1722 </div>
1723
1724 <?php
1725 }
1726
1727 /**
1728 * Add New Menu Item.
1729 */
1730 public function render_add_new_menu_item( $submenu = false ) {
1731 $add_item = apply_filters( 'adminify/menu_editor', [
1732 'upgrade_pro' => Utils::adminify_upgrade_pro( ' ' ),
1733 'upgrade_class' => 'upgrade-pro',
1734 ] );
1735 ?>
1736 <div class="adminify-accordion adminify-add-new-menu-editor-item upgrade-pro adminify-field adminify-field-switcher adminify-depend-visible adminify-depend-on adminify-pro-notice <?php
1737 echo esc_attr( ( $submenu ? 'submenu' : '' ) );
1738 ?> <?php
1739 echo Utils::wp_kses_custom( $add_item['upgrade_class'] );
1740 ?>">
1741 <div class="inner-text">
1742 <i class="dashicons dashicons-plus-alt"></i>
1743 <span class="title"><?php
1744 esc_html_e( 'Add Item', 'adminify' );
1745 ?></span>
1746 </div>
1747 <?php
1748 echo Utils::wp_kses_custom( $add_item['upgrade_pro'] );
1749 ?>
1750 </div>
1751 <?php
1752 }
1753
1754 /**
1755 * Menu Editor Header
1756 *
1757 * @return void
1758 */
1759 public static function render_menu_editor_header() {
1760 ?>
1761
1762 <div class="adminify-flex adminify-flex-center adminify-justify-between">
1763 <div class="adminify-menu-editor-help-urls adminify-flex adminify-flex-center adminify-gap-2">
1764 <?php
1765 echo Utils::adminfiy_help_urls(
1766 __( 'Menu Editor', 'adminify' ),
1767 'https://wpadminify.com/kb/wordpress-dashboard-menu-editor/',
1768 'https://www.youtube.com/playlist?list=PLqpMw0NsHXV-EKj9Xm1DMGa6FGniHHly8',
1769 'https://www.facebook.com/groups/jeweltheme',
1770 \WPAdminify\Inc\Admin\AdminSettings::support_url()
1771 );
1772 ?>
1773 </div>
1774
1775
1776 <div class="wp-adminify--page--title--actions adminify-flex adminify-flex-center adminify-gap-2">
1777
1778 <button class="adminify-btn adminify-btn-outline-primary adminify_menu_save_settings">
1779 <?php
1780 esc_html_e( 'Save', 'adminify' );
1781 ?>
1782 </button>
1783
1784 <div class="adminify-dropdown">
1785 <div class="adminify-dropdown-trigger">
1786 <button class="adminify-btn adminify-btn-outline-primary" aria-haspopup="true" aria-controls="dropdown-menu">
1787 <svg class="icon" width="16" height="12" viewBox="0 0 16 12" fill="none" xmlns="http://www.w3.org/2000/svg">
1788 <path d="M5 12C3.63144 12.0007 2.43589 11.0751 2.09375 9.75H0.5V8.25H2.0945C2.48423 6.74059 3.96509 5.78119 5.50196 6.04243C7.03883 6.30366 8.11953 7.69847 7.98865 9.25188C7.85776 10.8053 6.55892 11.9996 5 12ZM5 7.5C4.18055 7.50083 3.51342 8.15914 3.50167 8.97851C3.48993 9.79788 4.13792 10.475 4.95702 10.4993C5.77611 10.5237 6.46312 9.88613 6.5 9.0675V9.3675V9C6.5 8.17158 5.82843 7.5 5 7.5ZM15.5 9.75H8.75V8.25H15.5V9.75ZM8.75 6C7.38172 6.00035 6.18657 5.07483 5.8445 3.75H0.5V2.25H5.8445C6.23423 0.740588 7.71509 -0.218809 9.25196 0.0424253C10.7888 0.30366 11.8695 1.69847 11.7386 3.25188C11.6078 4.80529 10.3089 5.99961 8.75 6ZM8.75 1.5C7.93055 1.50083 7.26342 2.15914 7.25167 2.97851C7.23993 3.79788 7.88792 4.47503 8.70702 4.49934C9.52611 4.52365 10.2131 3.88613 10.25 3.0675V3.3675V3C10.25 2.17158 9.57843 1.5 8.75 1.5ZM15.5 3.75H12.5V2.25H15.5V3.75Z" fill="#0347FF" />
1789 </svg>
1790 </button>
1791 </div>
1792 <div class="adminify-dropdown-menu" id="dropdown-menu" role="menu">
1793 <div class="adminify-dropdown-content adminify-flex adminify-flex-col adminify-gap-2">
1794 <a href="#" class="adminify-dropdown-item adminify_export_menu_settings">
1795 <?php
1796 esc_html_e( 'Export menu', 'adminify' );
1797 ?>
1798 </a>
1799 <input accept=".json" type="file" single="" id="adminify_import_menu" class="hidden">
1800 <a href="#" class="adminify-dropdown-item adminify_import_menu_settings">
1801 <?php
1802 esc_html_e( 'Import menu', 'adminify' );
1803 ?>
1804 </a>
1805 <a href="#" class="adminify-dropdown-item adminify_reset_menu_settings">
1806 <?php
1807 esc_html_e( 'Reset menu', 'adminify' );
1808 ?>
1809 </a>
1810 </div>
1811 </div>
1812 </div>
1813 </div>
1814 </div>
1815
1816 <div class="adminify-text-wrap">
1817 <p><?php
1818 esc_html_e( 'Edit each menu item\'s name, link, icon and visibility. Drag and drop to rearange the menu. Changes will take effect after page refresh.', 'adminify' );
1819 ?></p>
1820 <p class="adminify-flex adminify-flex-center adminify-gap-1">
1821 <svg class="" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
1822 <path d="M7.33398 7.32002C7.33398 7.14321 7.40422 6.97364 7.52925 6.84861C7.65427 6.72359 7.82384 6.65335 8.00065 6.65335C8.17746 6.65335 8.34703 6.72359 8.47206 6.84861C8.59708 6.97364 8.66732 7.14321 8.66732 7.32002V11.32C8.66732 11.4968 8.59708 11.6664 8.47206 11.7914C8.34703 11.9164 8.17746 11.9867 8.00065 11.9867C7.82384 11.9867 7.65427 11.9164 7.52925 11.7914C7.40422 11.6664 7.33398 11.4968 7.33398 11.32V7.32002Z" fill="#4E4B66" />
1823 <path d="M8.00065 4.034C7.82384 4.034 7.65427 4.10423 7.52925 4.22926C7.40422 4.35428 7.33398 4.52385 7.33398 4.70066C7.33398 4.87747 7.40422 5.04704 7.52925 5.17207C7.65427 5.29709 7.82384 5.36733 8.00065 5.36733C8.17746 5.36733 8.34703 5.29709 8.47206 5.17207C8.59708 5.04704 8.66732 4.87747 8.66732 4.70066C8.66732 4.52385 8.59708 4.35428 8.47206 4.22926C8.34703 4.10423 8.17746 4.034 8.00065 4.034Z" fill="#4E4B66" />
1824 <path fill-rule="evenodd" clip-rule="evenodd" d="M8.00065 1.33334C4.31865 1.33334 1.33398 4.31801 1.33398 8.00001C1.33398 11.682 4.31865 14.6667 8.00065 14.6667C11.6827 14.6667 14.6673 11.682 14.6673 8.00001C14.6673 4.31801 11.6827 1.33334 8.00065 1.33334ZM2.66732 8.00001C2.66732 9.4145 3.22922 10.7711 4.22942 11.7712C5.22961 12.7714 6.58616 13.3333 8.00065 13.3333C9.41514 13.3333 10.7717 12.7714 11.7719 11.7712C12.7721 10.7711 13.334 9.4145 13.334 8.00001C13.334 6.58552 12.7721 5.22897 11.7719 4.22877C10.7717 3.22858 9.41514 2.66668 8.00065 2.66668C6.58616 2.66668 5.22961 3.22858 4.22942 4.22877C3.22922 5.22897 2.66732 6.58552 2.66732 8.00001V8.00001Z" fill="#4E4B66" />
1825 </svg>
1826
1827 <?php
1828 esc_html_e( 'If you have WP Adminify Menu Module disabled, icons and label dividers won\'t change.', 'adminify' );
1829 ?>
1830
1831 </p>
1832 </div>
1833
1834
1835 <?php
1836 }
1837
1838 public function jltwp_adminify_menu_editor_contents() {
1839 ?>
1840
1841 <div class="wrap">
1842 <div class="wp-adminify--menu--editor--container">
1843
1844 <!-- <div id="adminify-data-saved-message"></div> -->
1845
1846 <?php
1847 //self::render_menu_editor_header();
1848 ?>
1849
1850 <div class="wp-adminify--menu--editor--settings adminify-flex adminify-flex-col adminify-gap-4">
1851 <div class="wp-adminify-menu-editor-loader"></div>
1852 <?php
1853 $this->render_menu_editor();
1854 ?>
1855 </div>
1856
1857 </div>
1858 </div>
1859 <a href="#" id="adminify_download_settings" style="display: none;" ?></a>
1860 <?php
1861 }
1862
1863 }
1864
1865 }