PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.1.13
Adminify – White Label, Admin Menu Editor, Login Customizer v4.1.13
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.13, at Inc/Modules/MenuEditor/MenuEditor.php

1,915 lines 83.6 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 * Find menu settings for a given slug.
404 * Some plugins (e.g. Yoast SEO) register different top-level menu slugs
405 * depending on user capabilities. The admin sees slug 'wpseo_dashboard'
406 * but the editor sees 'wpseo_tools'. This method handles that mismatch
407 * by falling back to checking if the slug appears as a submenu key.
408 *
409 * @param string $slug The menu slug to look up.
410 * @return array|null The matching settings array, or null if not found.
411 */
412 public function find_menu_settings_by_slug( $slug ) {
413 // Direct match
414 if ( isset( $this->menu_settings[$slug] ) ) {
415 return $this->menu_settings[$slug];
416 }
417 // Fallback: check if this slug is a submenu of any saved parent menu
418 if ( is_array( $this->menu_settings ) ) {
419 foreach ( $this->menu_settings as $parent_slug => $parent_settings ) {
420 if ( !is_array( $parent_settings ) || !isset( $parent_settings['submenu'] ) || !is_array( $parent_settings['submenu'] ) ) {
421 continue;
422 }
423 if ( isset( $parent_settings['submenu'][$slug] ) ) {
424 return $parent_settings;
425 }
426 }
427 }
428 return null;
429 }
430
431 /**
432 * Get menu items
433 *
434 * @param [type] $parent_file
435 *
436 * @return void
437 */
438 public function set_menu( $parent_file ) {
439 global $menu, $submenu;
440 $this->menu = $this->sort_menu_settings( $menu );
441 $this->submenu = $this->sort_sub_menu_settings( $this->menu, $submenu );
442 return $parent_file;
443 }
444
445 /**
446 * Sorts Menu's for Option settings
447 */
448 public function sort_menu_settings( $thismenu ) {
449 $menu_settings = $this->menu_settings;
450 $tempmenu = [];
451 foreach ( $thismenu as $key => $current_menu_item ) {
452 if ( $current_menu_item[4] === "wp-menu-separator" ) {
453 unset($thismenu[$key]);
454 continue;
455 }
456 if ( !current_user_can( 'administrator' ) && $current_menu_item[2] === 'vc-welcome' ) {
457 unset($thismenu[$key]);
458 continue;
459 }
460 $next_menu_item = next( $thismenu );
461 $optiongroup = [];
462 $order = $key;
463 $separator = 0;
464 $external_link = 0;
465 $icon = null;
466 $hidden_for = [];
467 if ( !empty( $next_menu_item ) && strpos( $next_menu_item[2], 'separator' ) !== false ) {
468 $separator = 1;
469 }
470 if ( is_array( $menu_settings ) ) {
471 // Direct slug match first, then fallback for dynamic-slug plugins (e.g. Yoast SEO)
472 if ( isset( $menu_settings[$current_menu_item[2]] ) ) {
473 $optiongroup = $menu_settings[$current_menu_item[2]];
474 } else {
475 $fallback = $this->find_menu_settings_by_slug( $current_menu_item[2] );
476 if ( $fallback !== null ) {
477 $optiongroup = $fallback;
478 }
479 }
480 if ( !empty( $optiongroup ) ) {
481 if ( isset( $optiongroup['order'] ) ) {
482 $order = $optiongroup['order'];
483 }
484 if ( isset( $optiongroup['separator'] ) ) {
485 $separator = $optiongroup['separator'];
486 }
487 if ( isset( $optiongroup['external_link'] ) ) {
488 $external_link = $optiongroup['external_link'];
489 }
490 if ( !empty( $optiongroup['icon'] ) ) {
491 $icon = $optiongroup['icon'];
492 }
493 if ( !empty( $optiongroup['hidden_for'] ) ) {
494 $hidden_for = $optiongroup['hidden_for'];
495 }
496 }
497 }
498 $current_menu_item['order'] = $order;
499 $current_menu_item['hidden_for'] = $hidden_for;
500 $current_menu_item['separator'] = $separator;
501 $current_menu_item['external_link'] = $external_link;
502 // if (empty($this->options['admin_ui'])) {
503 if ( $icon !== null ) {
504 if ( strpos( $icon, 'dashicons ' ) !== false ) {
505 $menu_icon = str_replace( 'dashicons ', '', $icon );
506 $current_menu_item[6] = $menu_icon;
507 } else {
508 if ( strpos( $icon, ',' ) !== false ) {
509 $menu_icon = explode( ',', $icon )[1];
510 } else {
511 $menu_icon = 'dashicons-adminify- ' . $icon;
512 }
513 $current_menu_item[6] = $menu_icon;
514 }
515 }
516 if ( $separator == 1 ) {
517 $current_menu_item[4] = $current_menu_item[4] . ' adminify-menu-separator';
518 }
519 // }
520 array_push( $tempmenu, $current_menu_item );
521 if ( isset( $menu_settings[$current_menu_item[2]] ) ) {
522 unset($menu_settings[$current_menu_item[2]]);
523 }
524 }
525 if ( is_array( $menu_settings ) && !array_key_exists( 0, $menu_settings ) ) {
526 foreach ( $menu_settings as $key => $menu_s ) {
527 // Skip if $menu_s is not an array
528 if ( !is_array( $menu_s ) ) {
529 continue;
530 }
531 // Ensure required keys exist with defaults
532 $menu_s = wp_parse_args( $menu_s, [
533 'name' => '',
534 'link' => '',
535 'icon' => '',
536 'order' => 0,
537 'separator' => 0,
538 'external_link' => 0,
539 'hidden_for' => [],
540 ] );
541 $new_array = [
542 $menu_s['name'],
543 'read',
544 ( !empty( $menu_s['link'] ) ? $menu_s['link'] : '' ),
545 '',
546 'menu-top menu-icon-custom',
547 $key,
548 ( !empty( $menu_s['icon'] ) ? $menu_s['icon'] : '' ),
549 'order' => $menu_s['order'],
550 'separator' => ( !empty( $menu_s['separator'] ) ? $menu_s['separator'] : 0 ),
551 'external_link' => ( !empty( $menu_s['external_link'] ) ? $menu_s['external_link'] : 0 ),
552 'hidden_for' => ( !empty( $menu_s['hidden_for'] ) ? $menu_s['hidden_for'] : [] )
553 ];
554 // if (empty($this->options['admin_ui'])) {
555 if ( strpos( $menu_s['icon'], 'dashicons ' ) !== false ) {
556 $menu_icon = str_replace( 'dashicons ', '', $menu_s['icon'] );
557 } else {
558 if ( empty( $menu_s['icon'] ) || strpos( $menu_s['icon'], ',' ) !== false ) {
559 if ( empty( $menu_s['icon'] ) ) {
560 $menu_icon = WP_ADMINIFY_ASSETS_IMAGE . 'logos/menu-icon.svg';
561 } else {
562 $menu_icon = explode( ',', $menu_s['icon'] )[1];
563 }
564 } else {
565 $menu_icon = 'dashicons-adminify- ' . $menu_s['icon'];
566 }
567 }
568 if ( !empty( $menu_s['separator'] ) && $menu_s['separator'] == 1 ) {
569 $new_array[4] = $new_array[4] . ' adminify-menu-separator';
570 }
571 // if (!empty($menu_s['external_link']) && $menu_s['external_link'] == 1) {
572 // $new_array[4] = $new_array[4] . ' adminify-menu-external_link';
573 // }
574 $new_array[6] = $menu_icon;
575 // }
576 array_push( $tempmenu, $new_array );
577 }
578 }
579 return $this->sort_array( $tempmenu );
580 }
581
582 /**
583 * usort function for menu arrays
584 */
585 public function sort_array_helper( $a, $b ) {
586 $result = 0;
587 if ( !isset( $a['order'] ) ) {
588 return $result;
589 }
590 if ( $a['order'] > $b['order'] ) {
591 $result = 1;
592 } elseif ( $a['order'] < $b['order'] ) {
593 $result = -1;
594 }
595 return $result;
596 }
597
598 /**
599 * Sorts arrays by key 'order'
600 */
601 public function sort_array( $tosort ) {
602 usort( $tosort, [$this, 'sort_array_helper'] );
603 return $tosort;
604 }
605
606 /**
607 * Sorts Sub Menu for settings
608 *
609 * @since 1.4
610 */
611 public function sort_sub_menu_settings( $themenu, $thesubmenu ) {
612 $menu_settings = $this->menu_settings;
613 $tempsubmenu = [];
614 foreach ( $themenu as $current_menu_item ) {
615 $optiongroup = [];
616 $submenu_items = [];
617 if ( isset( $thesubmenu[$current_menu_item[2]] ) ) {
618 $submenuitems = $thesubmenu[$current_menu_item[2]];
619 foreach ( $submenuitems as $key => $subitem ) {
620 $subitem['order'] = $key;
621 if ( is_array( $menu_settings ) && isset( $menu_settings[$current_menu_item[2]] ) && isset( $menu_settings[$current_menu_item[2]]['submenu'] ) ) {
622 $submenugroup = $menu_settings[$current_menu_item[2]]['submenu'];
623 if ( isset( $submenugroup[$subitem[2]] ) ) {
624 $itemoptions = $submenugroup[$subitem[2]];
625 if ( isset( $itemoptions['order'] ) ) {
626 $subitem['order'] = $itemoptions['order'];
627 }
628 }
629 }
630 array_push( $submenu_items, $subitem );
631 }
632 $submenu_items = $this->sort_array( $submenu_items );
633 $tempsubmenu[$current_menu_item[2]] = $submenu_items;
634 }
635 }
636 if ( is_array( $menu_settings ) ) {
637 $tmp_menu = [];
638 foreach ( $menu_settings as $key => $menu_s ) {
639 if ( isset( $menu_s['submenu'] ) && is_array( $menu_s['submenu'] ) ) {
640 $tmp_sub_menu = [];
641 $i = 0;
642 foreach ( $menu_s['submenu'] as $k => $sub_menu ) {
643 if ( strpos( $k, 'adminify-custom-submenu' ) === false ) {
644 continue;
645 }
646 $order = ( $sub_menu['order'] ? $sub_menu['order'] : $i );
647 $new_array = [
648 ( $sub_menu['name'] ? $sub_menu['name'] : '' ),
649 'read',
650 ( $sub_menu['link'] ? $sub_menu['link'] : '' ),
651 'order' => $order,
652 'key' => $k,
653 'hidden_for' => ( isset( $sub_menu['hidden_for'] ) ? $sub_menu['hidden_for'] : [] )
654 ];
655 // processing submenu array
656 $tmp_sub_menu[$order] = $new_array;
657 $i++;
658 }
659 if ( !empty( $tmp_sub_menu ) ) {
660 // adding submenu into temp variable
661 $tmp_menu[$key] = $tmp_sub_menu;
662 }
663 }
664 }
665 if ( !empty( $tmp_menu ) ) {
666 $tempsubmenu = array_merge_recursive( $tempsubmenu, $tmp_menu );
667 }
668 foreach ( $tempsubmenu as $m_k => $m_menu ) {
669 $tempsubmenu[$m_k] = $this->sort_array( $tempsubmenu[$m_k] );
670 }
671 }
672 return $tempsubmenu;
673 }
674
675 /**
676 * Applies menu settings
677 */
678 public function apply_menu( $parent_file ) {
679 // Not applicable for Network Admin
680 if ( is_multisite() && is_network_admin() ) {
681 return;
682 }
683 global $menu, $submenu;
684 $tempmenu = [];
685 $tempsub = [];
686 $submenu = $this->sort_sub_menu_settings( $menu, $submenu );
687 if ( $this->menu && is_array( $this->menu ) ) {
688 foreach ( $this->menu as $key => $menu_item ) {
689 if ( empty( $menu_item[2] ) ) {
690 continue;
691 }
692 if ( strpos( $menu_item[2], 'separator' ) !== false && !$menu_item[0] ) {
693 // Build Separator
694 $newitem = $this->apply_separator_settings( $menu_item, $key );
695 if ( $newitem ) {
696 array_push( $tempmenu, $newitem );
697 }
698 } else {
699 // Build Top Level
700 $newitem = $this->apply_top_level_settings( $menu_item, $key );
701 if ( $newitem ) {
702 array_push( $tempmenu, $newitem );
703 // Menu Editor Custom Separator
704 if ( !empty( $newitem['separator'] ) ) {
705 $separator_order = $this->menu[$key]['order'];
706 $empty_separator = array(
707 0 => '',
708 1 => 'read',
709 2 => 'separator_' . rand( 200, 1000 ) * 1000,
710 3 => '',
711 4 => 'wp-menu-separator',
712 'order' => $separator_order + 0.5,
713 );
714 array_push( $tempmenu, $empty_separator );
715 }
716 $parent_key = $newitem[2];
717 if ( strpos( $newitem[5], 'adminify-custom-menu-' ) !== false ) {
718 $parent_key = $newitem[5];
719 }
720 if ( isset( $this->submenu[$parent_key] ) ) {
721 $subitem = $this->apply_sub_level_settings( $this->submenu[$parent_key], $parent_key );
722 if ( $subitem ) {
723 $tempsub[$newitem[2]] = $this->apply_sub_level_settings( $this->submenu[$parent_key], $parent_key );
724 }
725 }
726 }
727 }
728 }
729 }
730 $submenu = $tempsub;
731 $menu = $this->sort_array( $tempmenu );
732 return $parent_file;
733 }
734
735 /**
736 * Applies sub level menu item settings
737 *
738 * @return $tempsub | false
739 *
740 * @since 1.4
741 */
742 public function apply_sub_level_settings( $subitems, $parentname ) {
743 if ( !is_array( $this->menu_settings ) ) {
744 return $subitems;
745 }
746 if ( !isset( $this->menu_settings[$parentname]['submenu'] ) ) {
747 return $subitems;
748 }
749 $submenu_settings = $this->menu_settings[$parentname]['submenu'];
750 $tempsub = [];
751 foreach ( $subitems as $current_menu_item ) {
752 $sub_level = apply_filters( 'adminify/menu_editor', [
753 'sub_level' => false,
754 ] );
755 if ( !empty( $sub_level['sub_level'] ) ) {
756 if ( empty( $current_menu_item[0] ) || $current_menu_item[2] === 'wp-adminify-settings-pricing' ) {
757 continue;
758 }
759 }
760 $name = '';
761 $link = '';
762 $disabled_for = [];
763 $optiongroup = [];
764 // NO SETTINGS
765 if ( isset( $submenu_settings[$current_menu_item[2]] ) ) {
766 $optiongroup = $submenu_settings[$current_menu_item[2]];
767 if ( isset( $optiongroup['name'] ) ) {
768 $name = $optiongroup['name'];
769 if ( $name != '' ) {
770 $current_menu_item[0] = $name;
771 }
772 }
773 if ( isset( $optiongroup['link'] ) ) {
774 $link = $optiongroup['link'];
775 if ( $link != '' ) {
776 $current_menu_item[2] = $link;
777 $current_menu_item['link'] = $link;
778 }
779 }
780 if ( isset( $optiongroup['external_link'] ) ) {
781 $external_link = $optiongroup['external_link'];
782 }
783 if ( isset( $optiongroup['hidden_for'] ) ) {
784 $disabled_for = $optiongroup['hidden_for'];
785 if ( $this->is_hidden( $disabled_for ) ) {
786 $current_menu_item['hidden_for'] = true;
787 continue;
788 }
789 }
790 }
791 $custom_menu = ( isset( $current_menu_item['key'] ) ? $current_menu_item['key'] : '' );
792 if ( strpos( $custom_menu, 'adminify-custom-submenu-' ) !== false ) {
793 if ( isset( $submenu_settings[$current_menu_item['key']]['hidden_for'] ) ) {
794 $disabled_for = $submenu_settings[$current_menu_item['key']]['hidden_for'];
795 }
796 if ( isset( $submenu_settings[$current_menu_item['key']]['external_link'] ) ) {
797 $external_link = $submenu_settings[$current_menu_item['key']]['external_link'];
798 }
799 if ( $this->is_hidden( $disabled_for ) ) {
800 $current_menu_item['hidden_for'] = true;
801 continue;
802 }
803 }
804 array_push( $tempsub, $current_menu_item );
805 }
806 if ( count( $tempsub ) < 1 ) {
807 return false;
808 } else {
809 return $tempsub;
810 }
811 }
812
813 /**
814 * Applies top level menu item settings
815 *
816 * @since 1.4
817 */
818 public function apply_top_level_settings( $current_menu_item, $key ) {
819 $name = '';
820 $link = '';
821 $icon = '';
822 $disabled_for = [];
823 $optiongroup = [];
824 $order = $key;
825 if ( is_array( $this->menu_settings ) ) {
826 // Direct slug match first, then fallback for dynamic-slug plugins (e.g. Yoast SEO)
827 if ( isset( $this->menu_settings[$current_menu_item[2]] ) ) {
828 $optiongroup = $this->menu_settings[$current_menu_item[2]];
829 } else {
830 $fallback = $this->find_menu_settings_by_slug( $current_menu_item[2] );
831 if ( $fallback !== null ) {
832 $optiongroup = $fallback;
833 }
834 }
835 if ( !empty( $optiongroup ) ) {
836 if ( isset( $optiongroup['name'] ) ) {
837 $name = $optiongroup['name'];
838 if ( $name != '' ) {
839 $current_menu_item[0] = $name;
840 }
841 }
842 if ( isset( $optiongroup['link'] ) ) {
843 $link = $optiongroup['link'];
844 if ( $link != '' ) {
845 $current_menu_item[2] = $link;
846 $current_menu_item['link'] = $link;
847 }
848 }
849 if ( isset( $optiongroup['external_link'] ) ) {
850 $external_link = ( $optiongroup['external_link'] ? $optiongroup['external_link'] : '' );
851 }
852 if ( isset( $optiongroup['icon'] ) ) {
853 $icon = $optiongroup['icon'];
854 if ( $icon != '' ) {
855 $current_menu_item['icon'] = $icon;
856 }
857 }
858 if ( isset( $optiongroup['order'] ) ) {
859 $order = $optiongroup['order'];
860 }
861 if ( isset( $optiongroup['hidden_for'] ) ) {
862 $disabled_for = $optiongroup['hidden_for'];
863 if ( $this->is_hidden( $disabled_for ) ) {
864 $current_menu_item['hidden_for'] = true;
865 } else {
866 $current_menu_item['hidden_for'] = false;
867 }
868 }
869 }
870 $custom_menu = ( isset( $current_menu_item[5] ) ? $current_menu_item[5] : '' );
871 if ( strpos( $custom_menu, 'adminify-custom-menu-' ) !== false ) {
872 if ( isset( $this->menu_settings[$current_menu_item[5]]['hidden_for'] ) && !empty( $this->menu_settings[$current_menu_item[5]]['hidden_for'] ) ) {
873 $disabled_for = $this->menu_settings[$current_menu_item[5]]['hidden_for'];
874 if ( $this->is_hidden( $disabled_for ) ) {
875 $current_menu_item['hidden_for'] = true;
876 }
877 }
878 if ( isset( $this->menu_settings[$current_menu_item[5]]['external_link'] ) ) {
879 $external_link = $this->menu_settings[$current_menu_item[5]]['external_link'];
880 }
881 }
882 }
883 $current_menu_item['order'] = $order;
884 // Check hidden_for: boolean true means hide, array means check via is_hidden
885 if ( isset( $current_menu_item['hidden_for'] ) ) {
886 if ( $current_menu_item['hidden_for'] === true ) {
887 return false;
888 } elseif ( is_array( $current_menu_item['hidden_for'] ) && !empty( $current_menu_item['hidden_for'] ) ) {
889 // Fallback: hidden_for is still an array (settings lookup may have missed it)
890 if ( $this->is_hidden( $current_menu_item['hidden_for'] ) ) {
891 return false;
892 }
893 }
894 return $current_menu_item;
895 } else {
896 return $current_menu_item;
897 }
898 }
899
900 /**
901 * Hidden for method
902 *
903 * @param [type] $disabled_for
904 *
905 * @return boolean
906 */
907 public function is_hidden( $disabled_for ) {
908 if ( !is_array( $disabled_for ) ) {
909 return false;
910 }
911 $current_user = wp_get_current_user();
912 $current_roles = $current_user->roles;
913 $all_roles = wp_roles()->get_names();
914 foreach ( $current_roles as $current_role ) {
915 if ( isset( $all_roles[$current_role] ) && in_array( $all_roles[$current_role], $disabled_for ) ) {
916 return true;
917 }
918 }
919 // Normalize disabled_for array
920 $disabled_for_arr = [];
921 foreach ( $disabled_for as $v ) {
922 $disabled_for_arr[] = jlt_adminify_sluggify_with_underscores( $v );
923 }
924 $slugify_user_login = jlt_adminify_sluggify_with_underscores( $current_user->user_login );
925 // Check Username
926 if ( in_array( $current_user->user_login, $disabled_for_arr ) || in_array( $slugify_user_login, $disabled_for_arr ) ) {
927 return true;
928 }
929 // Check User Roles and Capabilities
930 foreach ( $current_roles as $role ) {
931 $role_obj = get_role( $role );
932 if ( !$role_obj ) {
933 continue;
934 }
935 // Check if role slug is in disabled array
936 if ( in_array( $role, $disabled_for_arr ) ) {
937 return true;
938 }
939 // Check if role display name is in disabled array
940 if ( isset( $disabled_for_arr[$role] ) && (in_array( $all_roles[$role], $disabled_for ) || in_array( strtolower( $all_roles[$role] ), array_map( 'strtolower', $disabled_for ) )) ) {
941 return true;
942 }
943 // Check for custom roles
944 foreach ( $disabled_for as $disabled_item ) {
945 // Convert role names to match WordPress format
946 $disabled_role = str_replace( ' ', '_', strtolower( $disabled_item ) );
947 if ( $role === $disabled_role ) {
948 return true;
949 }
950 }
951 }
952 // Handle Super Admin specially
953 if ( is_super_admin( $current_user->ID ) ) {
954 if ( in_array( 'Super Admin', $disabled_for_arr ) || in_array( 'super_admin', $disabled_for_arr ) || in_array( 'administrator', $disabled_for_arr ) ) {
955 return true;
956 }
957 // Super admin sees everything by default unless explicitly disabled
958 return false;
959 }
960 // Special check for user ID 1 (default admin)
961 if ( $current_user->ID === 1 ) {
962 if ( in_array( 'Super Admin', $disabled_for_arr ) || in_array( 'super_admin', $disabled_for_arr ) || in_array( 'administrator', $disabled_for_arr ) ) {
963 return true;
964 }
965 return false;
966 }
967 return false;
968 }
969
970 /**
971 * Applies separator menu item settings
972 *
973 * @since 1.0.0
974 */
975 public function apply_separator_settings( $current_menu_item, $key ) {
976 $name = '';
977 $disabled_for = [];
978 $optiongroup = [];
979 $order = $key;
980 if ( is_array( $this->menu_settings ) ) {
981 if ( isset( $this->menu_settings[$current_menu_item[2]] ) ) {
982 $optiongroup = $this->menu_settings[$current_menu_item[2]];
983 if ( isset( $optiongroup['name'] ) ) {
984 $name = $optiongroup['name'];
985 if ( $name != '' ) {
986 $current_menu_item['name'] = $name;
987 }
988 }
989 if ( isset( $optiongroup['order'] ) ) {
990 $order = $optiongroup['order'];
991 }
992 if ( isset( $optiongroup['hidden_for'] ) ) {
993 $disabled_for = $optiongroup['hidden_for'];
994 if ( $this->is_hidden( $disabled_for ) ) {
995 $current_menu_item['hidden_for'] = true;
996 }
997 }
998 }
999 }
1000 $current_menu_item['order'] = $order;
1001 if ( isset( $current_menu_item['hidden_for'] ) ) {
1002 if ( $current_menu_item['hidden_for'] == true ) {
1003 return false;
1004 } else {
1005 return $current_menu_item;
1006 }
1007 } else {
1008 return $current_menu_item;
1009 }
1010 }
1011
1012 public function get_saved_sub_menu() {
1013 $menu_settings = $this->menu_settings;
1014 $menu = $this->menu;
1015 $submenu = $this->submenu;
1016 if ( is_array( $menu_settings ) && !array_key_exists( 0, $menu_settings ) ) {
1017 foreach ( $menu as $menu_item ) {
1018 if ( isset( $menu_settings[$menu_item[2]] ) ) {
1019 unset($menu_settings[$menu_item[2]]);
1020 }
1021 }
1022 $tmp_menu = [];
1023 foreach ( $menu_settings as $key => $menu_s ) {
1024 if ( isset( $menu_s['submenu'] ) && is_array( $menu_s['submenu'] ) ) {
1025 $tmp_sub_menu = [];
1026 $i = 0;
1027 foreach ( $menu_s['submenu'] as $k => $sub_menu ) {
1028 $new_array = [
1029 $sub_menu['name'],
1030 'read',
1031 $sub_menu['link'],
1032 'order' => $i
1033 ];
1034 $tmp_sub_menu[$i] = $new_array;
1035 $i++;
1036 }
1037 if ( !empty( $tmp_sub_menu ) ) {
1038 $tmp_menu[$key] = $tmp_sub_menu;
1039 }
1040 }
1041 }
1042 if ( !empty( $tmp_menu ) ) {
1043 $submenu = $submenu + $tmp_menu;
1044 }
1045 }
1046 return $submenu;
1047 }
1048
1049 /**
1050 * Render Menu Editor
1051 */
1052 public function render_menu_editor() {
1053 global $wp_roles;
1054 $this->roles = $wp_roles->roles;
1055 if ( $this->menu && is_array( $this->menu ) ) {
1056 foreach ( $this->menu as $menu_item ) {
1057 $next_menu_item = next( $this->menu );
1058 if ( strpos( $menu_item[2], 'separator' ) !== false && !$menu_item[0] ) {
1059 // Render Separator
1060 // $this->render_menu_separator($menu_item);
1061 } else {
1062 // Render Top Level menu
1063 $this->render_top_level_menu_item(
1064 $this->menu,
1065 $menu_item,
1066 $this->submenu,
1067 $next_menu_item
1068 );
1069 }
1070 }
1071 $this->render_add_new_menu_item();
1072 }
1073 }
1074
1075 public function get_icon( $value, $default ) {
1076 if ( empty( $value ) ) {
1077 return $default;
1078 }
1079 return $value;
1080 }
1081
1082 /**
1083 * Generate User Rules Select box
1084 */
1085 public function generate_user_rules_select_field( $menu_id, $disabled_for, $menu_type = 'menu' ) {
1086 ob_start();
1087 ?>
1088 <select class="adminify-menu-settings adminify-user-role-select <?php
1089 echo esc_attr( $menu_type );
1090 ?>_setting" name="hidden_for" id="<?php
1091 echo esc_attr( $menu_id );
1092 ?>-user-role-types" multiple>
1093 <optgroup label="<?php
1094 esc_attr_e( 'Roles', 'adminify' );
1095 ?>">
1096 <?php
1097 foreach ( $this->roles as $role ) {
1098 $rolename = $role['name'];
1099 if ( 'administrator' == strtolower( $rolename ) ) {
1100 continue;
1101 }
1102 $sel = '';
1103 if ( in_array( $rolename, $disabled_for ) ) {
1104 $sel = 'selected';
1105 }
1106 ?>
1107 <option value="<?php
1108 echo esc_attr( $rolename );
1109 ?>" <?php
1110 echo esc_attr( $sel );
1111 ?>><?php
1112 echo esc_html( $rolename );
1113 ?></option>
1114 <?php
1115 }
1116 ?>
1117 </optgroup>
1118
1119 <optgroup label="<?php
1120 esc_attr_e( 'Users', 'adminify' );
1121 ?>" class="adminify-users-optgroup">
1122 <?php
1123 // Only include pre-selected users in HTML (AJAX will populate dropdown)
1124 foreach ( $disabled_for as $item ) {
1125 // Check if this is a user (not a role)
1126 $is_role = false;
1127 foreach ( $this->roles as $role ) {
1128 if ( $role['name'] === $item ) {
1129 $is_role = true;
1130 break;
1131 }
1132 }
1133 if ( !$is_role ) {
1134 $user = get_user_by( 'login', $item );
1135 if ( $user ) {
1136 ?>
1137 <option value="<?php
1138 echo esc_attr( $user->user_login );
1139 ?>" selected><?php
1140 echo esc_html( $user->user_login . ' (' . $user->display_name . ')' );
1141 ?></option>
1142 <?php
1143 }
1144 }
1145 }
1146 ?>
1147 </optgroup>
1148 </select>
1149 <?php
1150 return ob_get_clean();
1151 }
1152
1153 /**
1154 * Render Top Level menu Item
1155 *
1156 * @return void
1157 */
1158 public function render_top_level_menu_item(
1159 $master_menu,
1160 $current_menu_item,
1161 $master_sub_menu,
1162 $next_menu_item
1163 ) {
1164 if ( empty( $current_menu_item[2] ) ) {
1165 return;
1166 }
1167 // $disabled_for = '';
1168 $menu_id = preg_replace( '/[^A-Za-z0-9 ]/', '', $current_menu_item[5] );
1169 $name = '';
1170 $link = '';
1171 $external_link = '';
1172 $icon = '';
1173 $separator = '';
1174 $disabled_for = [];
1175 $optiongroup = [];
1176 $menu_options = $this->menu_settings;
1177 if ( !empty( $next_menu_item ) && strpos( $next_menu_item[2], 'separator' ) !== false ) {
1178 $separator = 1;
1179 }
1180 if ( is_array( $menu_options ) ) {
1181 if ( isset( $menu_options[$current_menu_item[2]] ) ) {
1182 $optiongroup = $menu_options[$current_menu_item[2]];
1183 if ( isset( $optiongroup['name'] ) ) {
1184 $name = $optiongroup['name'];
1185 }
1186 if ( isset( $optiongroup['link'] ) ) {
1187 $link = $optiongroup['link'];
1188 }
1189 if ( isset( $optiongroup['icon'] ) ) {
1190 $icon = $optiongroup['icon'];
1191 }
1192 if ( isset( $optiongroup['hidden_for'] ) ) {
1193 $disabled_for = $optiongroup['hidden_for'];
1194 }
1195 if ( isset( $optiongroup['separator'] ) ) {
1196 $separator = $optiongroup['separator'];
1197 }
1198 if ( isset( $optiongroup['external_link'] ) ) {
1199 $external_link = $optiongroup['external_link'];
1200 }
1201 }
1202 }
1203 $name_attr = $current_menu_item[2];
1204 if ( strpos( $current_menu_item[5], 'adminify-custom-menu-' ) !== false ) {
1205 $name_attr = $current_menu_item[5];
1206 $name = $current_menu_item[0];
1207 $link = $current_menu_item[2];
1208 if ( isset( $menu_options[$current_menu_item[5]]['hidden_for'] ) ) {
1209 $disabled_for = $menu_options[$current_menu_item[5]]['hidden_for'];
1210 }
1211 if ( isset( $menu_options[$current_menu_item[5]] ) ) {
1212 $optiongroup = $menu_options[$current_menu_item[5]];
1213 }
1214 if ( isset( $menu_options[$current_menu_item[5]]['icon'] ) ) {
1215 $icon = $menu_options[$current_menu_item[5]]['icon'];
1216 }
1217 if ( isset( $current_menu_item['separator'] ) ) {
1218 $separator = $current_menu_item['separator'];
1219 }
1220 if ( isset( $current_menu_item['external_link'] ) ) {
1221 $external_link = $current_menu_item['external_link'];
1222 }
1223 }
1224 if ( !is_array( $disabled_for ) ) {
1225 $disabled_for = [];
1226 }
1227 // LIST OF AVAILABLE MENU ICONS
1228 $icons = [
1229 'dashicons-admin-multisite' => 'dashicons dashicons-admin-multisite',
1230 'dashicons-dashboard' => 'dashicons dashicons-dashboard',
1231 'dashicons-admin-post' => 'dashicons dashicons-admin-post',
1232 'dashicons-database' => 'dashicons dashicons-database',
1233 'dashicons-admin-media' => 'dashicons dashicons-admin-media',
1234 'dashicons-admin-page' => 'dashicons dashicons-admin-page',
1235 'dashicons-admin-comments' => 'dashicons dashicons-admin-comments',
1236 'dashicons-admin-appearance' => 'dashicons dashicons-admin-appearance',
1237 'dashicons-admin-plugins' => 'dashicons dashicons-admin-plugins',
1238 'dashicons-admin-users' => 'dashicons dashicons-admin-users',
1239 'dashicons-admin-tools' => 'dashicons dashicons-admin-tools',
1240 'dashicons-chart-bar' => 'dashicons dashicons-chart-bar',
1241 'dashicons-admin-settings' => 'dashicons dashicons-admin-settings',
1242 ];
1243 $default_icons = ( isset( $current_menu_item ) ? $current_menu_item[6] : 'dashicons dashicons-external' );
1244 ?>
1245 <div class="accordion adminify_menu_item" name="<?php
1246 echo esc_attr( $name_attr );
1247 ?>" id="wp-adminify-top-menu-<?php
1248 echo esc_attr( $menu_id );
1249 ?>">
1250 <input type="number" class="top_level_order" value="" style="display:none;">
1251 <a class="menu-editor-title accordion-button adminify-flex adminify-flex-center adminify-gap-2" href="#">
1252 <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">
1253 <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" />
1254 <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" />
1255 <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" />
1256 <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" />
1257 <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" />
1258 <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" />
1259 <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" />
1260 <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" />
1261 <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" />
1262 </svg>
1263 <?php
1264 echo wp_kses_post( preg_replace( '/\\<span.*?>.*?\\<\\/span><\\/span>/s', '', $current_menu_item[0] ) );
1265 ?>
1266 </a>
1267
1268 <div class="accordion-body adminify_top_level_settings">
1269 <div class="tabs tabbable">
1270 <ul class="adminify-flex adminify-flex-center adminify-m-0 nav nav-tabs">
1271 <li class="nav-item active">
1272 <a class="nav-link is-clickable active" href="#tab-<?php
1273 echo esc_attr( $menu_id );
1274 ?>-1">
1275 <?php
1276 esc_html_e( 'Settings', 'adminify' );
1277 ?>
1278 </a>
1279 </li>
1280 <li class="nav-item" role="presentation">
1281 <a class="nav-link is-clickable" href="#tab-<?php
1282 echo esc_attr( $menu_id );
1283 ?>-2">
1284 <?php
1285 esc_html_e( 'Submenu', 'adminify' );
1286 ?>
1287 </a>
1288 </li>
1289 </ul>
1290 </div>
1291
1292 <div class="tab-content tab-panel panel adminify-p-4">
1293 <div id="tab-<?php
1294 echo esc_attr( $menu_id );
1295 ?>-1" class="tab-pane">
1296 <div class="menu-editor-form">
1297 <div class="columns">
1298 <div class="column">
1299 <label for="<?php
1300 echo esc_attr( $current_menu_item[2] );
1301 ?>">
1302 <?php
1303 esc_html_e( 'Rename as', 'adminify' );
1304 ?>
1305 </label>
1306 <input class="menu_setting" type="text" name="name" data-top-menu-id="<?php
1307 echo esc_attr( $menu_id );
1308 ?>" placeholder="<?php
1309 echo esc_attr( $current_menu_item[0] );
1310 ?>" value='<?php
1311 echo esc_attr( $name );
1312 ?>' />
1313 </div>
1314 <div class="column">
1315 <label for="<?php
1316 echo esc_attr( $current_menu_item[2] );
1317 ?>">
1318 <?php
1319 esc_html_e( 'Hidden For Roles or Users', 'adminify' );
1320 ?>
1321 </label>
1322
1323 <div class="select is-small">
1324
1325 <?php
1326 echo $this->generate_user_rules_select_field( $menu_id, $disabled_for );
1327 ?>
1328
1329 </div>
1330 </div>
1331 </div>
1332
1333 <div class="columns">
1334 <!-- <div class="column">
1335 <label for="">
1336 <?php
1337 esc_html_e( 'Change Link', 'adminify' );
1338 ?>
1339 </label>
1340 <input class="menu_setting" name="link" type="url" placeholder="<?php
1341 esc_html_e( 'New link', 'adminify' );
1342 ?>" value="<?php
1343 echo esc_attr( ( $name_attr != ltrim( $link, '#' ) ? $link : '' ) );
1344 ?>" onchange="checkForLinkTarget(this)" >
1345
1346 <label for="external_link-<?php
1347 echo esc_attr( $name_attr );
1348 ?>">
1349 <?php
1350 esc_html_e( 'New Window?', 'adminify' );
1351 ?>
1352 <input class="menu_setting" id="external_link-<?php
1353 echo esc_attr( $name_attr );
1354 ?>" name="external_link" type="checkbox" value="0" <?php
1355 checked( (int) $external_link, 1 );
1356 ?> disabled>
1357
1358 </label>
1359 <script>
1360 function checkForLinkTarget(inputField) {
1361 var checkbox = inputField.closest('.column').querySelector('input[type="checkbox"]');
1362
1363 if (inputField.value.trim() !== "") {
1364 checkbox.disabled = false; // Enable checkbox if input is not empty
1365 } else {
1366 checkbox.disabled = true; // Disable checkbox if input is empty
1367 }
1368 }
1369 </script>
1370 </div> -->
1371
1372 <div class="column">
1373 <label for="">
1374 <?php
1375 esc_html_e( 'Change Link', 'adminify' );
1376 ?>
1377 </label>
1378 <input class="menu_setting" name="link" type="url"
1379 placeholder="<?php
1380 esc_html_e( 'New link', 'adminify' );
1381 ?>"
1382 value="<?php
1383 echo esc_attr( ( $name_attr != ltrim( $link, '#' ) ? $link : '' ) );
1384 ?>"
1385 oninput="checkForLinkTarget(this)">
1386 <div class="new-tab-settings" style="padding-top: 10px;">
1387 <label for="external_link-<?php
1388 echo esc_attr( $name_attr );
1389 ?>" style="display: flex; align-items: center; gap: 8px;">
1390
1391 <input class="menu_setting" id="external_link-<?php
1392 echo esc_attr( $name_attr );
1393 ?>"
1394 name="external_link" type="checkbox" value="1"
1395 <?php
1396 checked( (int) $external_link, 1 );
1397 ?> disabled style="margin-top: 0;" >
1398 <span><?php
1399 esc_html_e( 'New Window?', 'adminify' );
1400 ?></span>
1401 </label>
1402 </div>
1403
1404 <script>
1405 // Function to validate URL
1406 function isValidURL(url) {
1407 // Allow absolute URLs (with http:// or https://)
1408 var absolutePattern = /^(https?:\/\/)[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}.*$/;
1409
1410 // Allow relative URLs (starting with "/")
1411 var relativePattern = /^\/[a-zA-Z0-9-_\/]+$/;
1412
1413 return absolutePattern.test(url) || relativePattern.test(url);
1414 }
1415
1416
1417 function checkForLinkTarget(inputField) {
1418 var checkbox = inputField.closest('.column').querySelector('input[type="checkbox"]');
1419
1420 if (isValidURL(inputField.value.trim())) {
1421 checkbox.disabled = false; // Enable if URL is valid
1422 } else {
1423 checkbox.disabled = true; // Disable if invalid
1424 checkbox.checked = false; // Also uncheck if disabled
1425 }
1426 }
1427
1428 // Run on page load
1429 document.addEventListener("DOMContentLoaded", function() {
1430 document.querySelectorAll('.column input[name="link"]').forEach(function(inputField) {
1431 checkForLinkTarget(inputField);
1432 });
1433 });
1434 </script>
1435 </div>
1436
1437 <div class="column">
1438 <label for="">
1439 <?php
1440 esc_html_e( 'Set Custom Icon', 'adminify' );
1441 ?>
1442 </label>
1443 <div class="icon-picker-wrap wp-adminify-menu-icon-picker adminify-icon-picker-input icon-select-button is-clickable is-pulled-left">
1444 <ul class="icon-picker">
1445 <li class="icon-none" title="None"><i class="dashicons dashicons-dismiss"></i></li>
1446 <li class="select-icon <?php
1447 echo ( !empty( $icon ) && preg_match( '/http(s?)\\:\\/\\//i', $icon ) || empty( $icon ) && empty( $icons[$default_icons] ) ? 'custom-icon' : '' );
1448 ?>" title="Icon Library">
1449 <?php
1450 if ( !empty( $icon ) ) {
1451 if ( preg_match( '/http(s?)\\:\\/\\//i', $icon ) ) {
1452 $image = explode( ',', $icon );
1453 echo '<i class=""><img width="24" height="24" src=' . esc_url( $image[1] ) . ' ></i>';
1454 } else {
1455 ?>
1456 <i class="<?php
1457 echo esc_attr( $this->get_icon( esc_attr( $icon ), '' ) );
1458 ?>"></i>
1459 <?php
1460 }
1461 } else {
1462 $adminify_icon = WP_ADMINIFY_ASSETS_IMAGE . 'logos/menu-icon.svg';
1463 if ( empty( $icons[$default_icons] ) ) {
1464 echo '<i class=""><img width="24" height="24" src=' . esc_url( $adminify_icon ) . ' ></i>';
1465 } else {
1466 ?>
1467 <i class="<?php
1468 echo wp_kses_post( $this->get_icon( esc_attr( $icon ), $icons[$default_icons] ) );
1469 ?>"></i>
1470 <?php
1471 }
1472 }
1473 ?>
1474
1475 </li>
1476 <input type="hidden" class="menu_setting" name="icon" value="<?php
1477 echo esc_attr( $icon );
1478 ?>">
1479 </ul>
1480 </div>
1481 </div>
1482 </div>
1483 <div class='columns'>
1484 <?php
1485 $upgrade_pro = '';
1486 $separator_name_attr = '';
1487 $upgrade_pro = 'upgrade-pro';
1488 $separator_name_attr = Utils::adminify_upgrade_pro( 'Add Separator' );
1489 ?>
1490
1491 <div class='column <?php
1492 echo esc_attr( $upgrade_pro );
1493 ?>'>
1494 <label for="seperator-<?php
1495 echo esc_attr( $name_attr );
1496 ?>">
1497 <?php
1498 $separator_content = apply_filters( 'adminify/menu_editor/add_separator', $separator_name_attr, $separator );
1499 // Apply the filter
1500 echo $separator_content;
1501 ?>
1502 </label>
1503 </div>
1504 </div>
1505 </div>
1506 <?php
1507 if ( strpos( $current_menu_item[5], 'adminify-custom-menu-' ) !== false ) {
1508 ?>
1509 <div class="remove-add-new-menu"><span data-id="<?php
1510 echo esc_attr( $current_menu_item[5] );
1511 ?>"><i class="icon-close"></i> Delete</span></div>
1512 <?php
1513 }
1514 ?>
1515 </div>
1516 <div id="tab-<?php
1517 echo esc_attr( $menu_id );
1518 ?>-2" class="tab-pane tab-pane--submenu">
1519 <?php
1520 // Sub Menu Items Check
1521 $link = $current_menu_item[2];
1522 if ( isset( $master_sub_menu[$name_attr] ) && is_array( $master_sub_menu[$name_attr] ) ) {
1523 foreach ( $master_sub_menu[$name_attr] as $sub_menu_item ) {
1524 $this->build_sub_menu_item( $sub_menu_item, $optiongroup, $name_attr );
1525 }
1526 } else {
1527 ?>
1528 <span><?php
1529 esc_html_e( 'No sub menu items', 'adminify' );
1530 ?></span>
1531 <?php
1532 }
1533 $this->render_add_new_menu_item( true );
1534 // true for submenu item
1535 ?>
1536
1537 </div>
1538 </div>
1539
1540 </div>
1541 </div>
1542
1543 <?php
1544 }
1545
1546 public function render_menu_separator( $current_menu_item ) {
1547 $disabled_for = [];
1548 $name = '';
1549 $menu_id = preg_replace( '/[^A-Za-z0-9 ]/', '', $current_menu_item[2] );
1550 $menu_options = $this->menu_settings;
1551 if ( is_array( $menu_options ) ) {
1552 if ( isset( $menu_options[$current_menu_item[2]] ) ) {
1553 $optiongroup = $menu_options[$current_menu_item[2]];
1554 if ( isset( $optiongroup['name'] ) ) {
1555 $name = $optiongroup['name'];
1556 }
1557 if ( isset( $optiongroup['hidden_for'] ) ) {
1558 $disabled_for = $optiongroup['hidden_for'];
1559 }
1560 }
1561 }
1562 if ( !is_array( $disabled_for ) ) {
1563 $disabled_for = [];
1564 }
1565 ?>
1566 <div class="accordion adminify_menu_item" name="<?php
1567 echo esc_attr( $current_menu_item[2] );
1568 ?>" id="<?php
1569 echo esc_attr( $menu_id );
1570 ?>">
1571 <input type="number" class="top_level_order" value="" style="display:none;">
1572 <a class="menu-editor-title accordion-button p-4" href="#">
1573 <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">
1574 <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" />
1575 <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" />
1576 <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" />
1577 <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" />
1578 <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" />
1579 <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" />
1580 <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" />
1581 <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" />
1582 <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" />
1583 </svg>
1584 <?php
1585 esc_html_e( 'Separator', 'adminify' );
1586 ?>
1587 </a>
1588
1589 <div class="accordion-body adminify_top_level_settings">
1590 <div class="tab-content tab-panel panel p-4">
1591 <div class="menu-editor-form">
1592 <div class="columns">
1593 <div class="column">
1594 <label for=""><?php
1595 esc_html_e( 'Rename as', 'adminify' );
1596 ?></label>
1597 <input class="menu_setting" type="text" name="name" placeholder="<?php
1598 esc_html_e( 'New Name', 'adminify' );
1599 ?>" value="<?php
1600 echo esc_attr( $name );
1601 ?>">
1602 </div>
1603 <div class="column">
1604 <label for=""><?php
1605 esc_html_e( 'Hidden For Roles or Users', 'adminify' );
1606 ?></label>
1607
1608 <div class="select is-small">
1609 <?php
1610 echo $this->generate_user_rules_select_field( $menu_id, $disabled_for );
1611 ?>
1612 </div>
1613 </div>
1614 </div>
1615 </div>
1616
1617 </div>
1618 </div>
1619 </div>
1620
1621 <?php
1622 }
1623
1624 public function build_sub_menu_item( $current_menu_item, $optiongroup, $name_attr ) {
1625 $name = '';
1626 $link = '';
1627 $icon = '';
1628 $external_link = '';
1629 $disabled_for = [];
1630 $suboptiongroup = [];
1631 $menu_options = $this->menu_settings;
1632 if ( isset( $optiongroup['submenu'] ) ) {
1633 if ( isset( $optiongroup['submenu'][$current_menu_item[2]] ) ) {
1634 $suboptiongroup = $optiongroup['submenu'][$current_menu_item[2]];
1635 if ( isset( $suboptiongroup['name'] ) ) {
1636 $name = $suboptiongroup['name'];
1637 }
1638 if ( isset( $suboptiongroup['link'] ) ) {
1639 $link = $suboptiongroup['link'];
1640 }
1641 if ( isset( $suboptiongroup['external_link'] ) ) {
1642 $external_link = $suboptiongroup['external_link'];
1643 }
1644 if ( isset( $suboptiongroup['icon'] ) ) {
1645 $icon = $suboptiongroup['icon'];
1646 }
1647 if ( isset( $suboptiongroup['hidden_for'] ) ) {
1648 $disabled_for = $suboptiongroup['hidden_for'];
1649 }
1650 }
1651 }
1652 $sub_menu_name_attr = $current_menu_item[2];
1653 if ( isset( $current_menu_item['key'] ) ) {
1654 $sub_menu_name_attr = $current_menu_item['key'];
1655 }
1656 if ( strpos( $sub_menu_name_attr, 'adminify-custom-submenu-' ) !== false ) {
1657 $name = $current_menu_item[0];
1658 $link = $current_menu_item[2];
1659 if ( isset( $optiongroup['submenu'][$sub_menu_name_attr]['hidden_for'] ) ) {
1660 $disabled_for = $optiongroup['submenu'][$sub_menu_name_attr]['hidden_for'];
1661 }
1662 if ( isset( $optiongroup['submenu'][$sub_menu_name_attr]['icon'] ) ) {
1663 $icon = $optiongroup['submenu'][$sub_menu_name_attr]['icon'];
1664 }
1665 if ( isset( $optiongroup['submenu'][$sub_menu_name_attr]['external_link'] ) ) {
1666 $external_link = $optiongroup['submenu'][$sub_menu_name_attr]['external_link'];
1667 }
1668 }
1669 if ( !is_array( $disabled_for ) ) {
1670 $disabled_for = [];
1671 }
1672 $menu_id = preg_replace( '/[^A-Za-z0-9 ]/', '', $sub_menu_name_attr );
1673 ?>
1674 <div class="accordion adminify_sub_menu_item" name="<?php
1675 echo esc_attr( $sub_menu_name_attr );
1676 ?>" id="wp-adminify-sub-menu-<?php
1677 echo esc_attr( $menu_id );
1678 ?>">
1679 <input type="number" class="top_level_order" value="" style="display:none;">
1680 <a class="menu-editor-title accordion-button adminify-flex adminify-flex-center adminify-gap-2" href="#">
1681 <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">
1682 <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" />
1683 <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" />
1684 <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" />
1685 <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" />
1686 <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" />
1687 <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" />
1688 <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" />
1689 <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" />
1690 <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" />
1691 </svg>
1692 <?php
1693 if ( !empty( $current_menu_item[0] ) ) {
1694 echo wp_kses_post( preg_replace( '/\\<span.*?>.*?\\<\\/span><\\/span>/s', '', $current_menu_item[0] ) );
1695 }
1696 ?>
1697 </a>
1698
1699 <div class="accordion-body">
1700 <div class="tab-content tab-panel panel p-4">
1701 <div class="tab-pane">
1702 <div class="menu-editor-form">
1703 <div class="columns">
1704 <div class="column">
1705 <label for=""><?php
1706 esc_html_e( 'Rename as', 'adminify' );
1707 ?></label>
1708 <input class="sub_menu_setting" type="text" data-sub-menu-id="<?php
1709 echo esc_attr( $menu_id );
1710 ?>" name="name" placeholder="<?php
1711 esc_html_e( 'New Menu name...', 'adminify' );
1712 ?>" value="<?php
1713 echo esc_attr( $name );
1714 ?>">
1715 </div>
1716 <div class="column">
1717 <label for=""><?php
1718 esc_html_e( 'Hidden For Roles or Users', 'adminify' );
1719 ?></label>
1720
1721 <div class="select is-small">
1722 <?php
1723 echo $this->generate_user_rules_select_field( $menu_id, $disabled_for, 'sub_menu' );
1724 ?>
1725 </div>
1726 </div>
1727 </div>
1728 <div class="columns">
1729 <div class="column">
1730 <label for=""><?php
1731 esc_html_e( 'Change Link', 'adminify' );
1732 ?></label>
1733 <input class="sub_menu_setting" name="link" type="url" placeholder="New link" value="<?php
1734 echo esc_attr( ( $sub_menu_name_attr != ltrim( $link, '#' ) ? $link : '' ) );
1735 ?>" onchange="checkForLinkTarget(this)" >
1736
1737 <label for="external_link-<?php
1738 echo esc_attr( $sub_menu_name_attr );
1739 ?>">
1740 <?php
1741 esc_html_e( 'New Window?', 'adminify' );
1742 ?>
1743 <input class="sub_menu_setting" id="external_link-<?php
1744 echo esc_attr( $sub_menu_name_attr );
1745 ?>" name="external_link" type="checkbox" value="0" <?php
1746 checked( (int) $external_link, 1 );
1747 ?>disabled />
1748
1749 </label>
1750 </div>
1751 <div class="column">
1752 <label for="" style="margin-top:25px">
1753 <?php
1754 esc_html_e( 'Custom Icon is not allowed for Submenu', 'adminify' );
1755 ?>
1756 </label>
1757 </div>
1758 </div>
1759 </div>
1760 <?php
1761 if ( strpos( $sub_menu_name_attr, 'adminify-custom-submenu-' ) !== false ) {
1762 ?>
1763 <div class="remove-add-new-menu"><span data-id="<?php
1764 echo esc_attr( $sub_menu_name_attr );
1765 ?>"><i class="icon-close"></i> Delete</span></div>
1766 <?php
1767 }
1768 ?>
1769 </div>
1770 </div>
1771 </div>
1772 </div>
1773
1774 <?php
1775 }
1776
1777 /**
1778 * Add New Menu Item.
1779 */
1780 public function render_add_new_menu_item( $submenu = false ) {
1781 $add_item = apply_filters( 'adminify/menu_editor', [
1782 'upgrade_pro' => Utils::adminify_upgrade_pro( ' ' ),
1783 'upgrade_class' => 'upgrade-pro',
1784 ] );
1785 ?>
1786 <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
1787 echo esc_attr( ( $submenu ? 'submenu' : '' ) );
1788 ?> <?php
1789 echo Utils::wp_kses_custom( $add_item['upgrade_class'] );
1790 ?>">
1791 <div class="inner-text">
1792 <i class="dashicons dashicons-plus-alt"></i>
1793 <span class="title"><?php
1794 esc_html_e( 'Add Item', 'adminify' );
1795 ?></span>
1796 </div>
1797 <?php
1798 echo Utils::wp_kses_custom( $add_item['upgrade_pro'] );
1799 ?>
1800 </div>
1801 <?php
1802 }
1803
1804 /**
1805 * Menu Editor Header
1806 *
1807 * @return void
1808 */
1809 public static function render_menu_editor_header() {
1810 ?>
1811
1812 <div class="adminify-flex adminify-flex-center adminify-justify-between">
1813 <div class="adminify-menu-editor-help-urls adminify-flex adminify-flex-center adminify-gap-2">
1814 <?php
1815 echo Utils::adminfiy_help_urls(
1816 __( 'Menu Editor', 'adminify' ),
1817 'https://wpadminify.com/kb/wordpress-dashboard-menu-editor/',
1818 'https://www.youtube.com/playlist?list=PLqpMw0NsHXV-EKj9Xm1DMGa6FGniHHly8',
1819 'https://www.facebook.com/groups/jeweltheme',
1820 \WPAdminify\Inc\Admin\AdminSettings::support_url()
1821 );
1822 ?>
1823 </div>
1824
1825
1826 <div class="wp-adminify--page--title--actions adminify-flex adminify-flex-center adminify-gap-2">
1827
1828 <button class="adminify-btn adminify-btn-outline-primary adminify_menu_save_settings">
1829 <?php
1830 esc_html_e( 'Save', 'adminify' );
1831 ?>
1832 </button>
1833
1834 <div class="adminify-dropdown">
1835 <div class="adminify-dropdown-trigger">
1836 <button class="adminify-btn adminify-btn-outline-primary" aria-haspopup="true" aria-controls="dropdown-menu">
1837 <svg class="icon" width="16" height="12" viewBox="0 0 16 12" fill="none" xmlns="http://www.w3.org/2000/svg">
1838 <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" />
1839 </svg>
1840 </button>
1841 </div>
1842 <div class="adminify-dropdown-menu" id="dropdown-menu" role="menu">
1843 <div class="adminify-dropdown-content adminify-flex adminify-flex-col adminify-gap-2">
1844 <a href="#" class="adminify-dropdown-item adminify_export_menu_settings">
1845 <?php
1846 esc_html_e( 'Export menu', 'adminify' );
1847 ?>
1848 </a>
1849 <input accept=".json" type="file" single="" id="adminify_import_menu" class="hidden">
1850 <a href="#" class="adminify-dropdown-item adminify_import_menu_settings">
1851 <?php
1852 esc_html_e( 'Import menu', 'adminify' );
1853 ?>
1854 </a>
1855 <a href="#" class="adminify-dropdown-item adminify_reset_menu_settings">
1856 <?php
1857 esc_html_e( 'Reset menu', 'adminify' );
1858 ?>
1859 </a>
1860 </div>
1861 </div>
1862 </div>
1863 </div>
1864 </div>
1865
1866 <div class="adminify-text-wrap">
1867 <p><?php
1868 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' );
1869 ?></p>
1870 <p class="adminify-flex adminify-flex-center adminify-gap-1">
1871 <svg class="" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
1872 <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" />
1873 <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" />
1874 <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" />
1875 </svg>
1876
1877 <?php
1878 esc_html_e( 'If you have WP Adminify Menu Module disabled, icons and label dividers won\'t change.', 'adminify' );
1879 ?>
1880
1881 </p>
1882 </div>
1883
1884
1885 <?php
1886 }
1887
1888 public function jltwp_adminify_menu_editor_contents() {
1889 ?>
1890
1891 <div class="wrap">
1892 <div class="wp-adminify--menu--editor--container">
1893
1894 <!-- <div id="adminify-data-saved-message"></div> -->
1895
1896 <?php
1897 //self::render_menu_editor_header();
1898 ?>
1899
1900 <div class="wp-adminify--menu--editor--settings adminify-flex adminify-flex-col adminify-gap-4">
1901 <div class="wp-adminify-menu-editor-loader"></div>
1902 <?php
1903 $this->render_menu_editor();
1904 ?>
1905 </div>
1906
1907 </div>
1908 </div>
1909 <a href="#" id="adminify_download_settings" style="display: none;" ?></a>
1910 <?php
1911 }
1912
1913 }
1914
1915 }