PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.0.4.6
Adminify – White Label, Admin Menu Editor, Login Customizer v4.0.4.6
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
← All changes | Inc/Modules/MenuEditor/MenuEditor.php +160 -279 4.2.214.0.4.6 View file →
@@ -1,11 +1,12 @@
1 1 <?php
2 2
3 -namespace PXLBSAdminify\Inc\Modules\MenuEditor;
3 +namespace WPAdminify\Inc\Modules\MenuEditor;
4 4
5 -use PXLBSAdminify\Inc\Utils;
6 -use PXLBSAdminify\Inc\Admin\AdminSettings;
7 -use PXLBSAdminify\Inc\Modules\MenuEditor\MenuEditorAssets;
5 +use WPAdminify\Inc\Utils;
6 +use WPAdminify\Inc\Admin\AdminSettings;
7 +use WPAdminify\Inc\Modules\MenuEditor\MenuEditorAssets;
8 +use WPAdminify\Inc\Admin\AdminSettingsModel;
8 9 use enshrined\svgSanitize\Sanitizer;
9 10 // no direct access allowed
10 11 if ( !defined( 'ABSPATH' ) ) {
11 12 exit;
@@ -46,23 +47,22 @@
46 47 $this->menu_settings = ( new MenuEditorOptions() )->get();
47 48 $this->options = (array) AdminSettings::get_instance()->get();
48 49 add_filter( 'upload_mimes', [$this, 'custom_icon_mime_types'] );
49 50 add_filter( 'wp_handle_upload_prefilter', [$this, 'sanitize_svg_file'] );
50 - add_filter( 'admin_body_class', [$this, 'menu_editor_body_class'] );
51 + add_filter( 'admin_body_class', [$this, 'jltwp_adminify_menu_editor_body_class'] );
51 52 // add_filter('parent_file', [$this, 'set_menu'], 800);
52 53 // add_filter('parent_file', [$this, 'apply_menu'], 900);
53 - // add_action('modules_menu_editor_render', [$this, 'modules_menu_editor_render']);
54 - if ( apply_filters( 'pxlbsadminify_enable_menu_editor_render', true ) ) {
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 ) ) {
55 56 add_filter( 'parent_file', [$this, 'set_menu'], 800 );
56 57 add_filter( 'parent_file', [$this, 'apply_menu'], 900 );
57 58 }
58 - add_action( 'wp_ajax_pxlbsadminify_save_menu_settings', [$this, 'save_menu_settings'] );
59 - add_action( 'wp_ajax_pxlbsadminify_reset_menu_settings', [$this, 'reset_menu_settings'] );
60 - add_action( 'wp_ajax_pxlbsadminify_export_menu_settings', [$this, 'export_menu_settings'] );
61 - add_action( 'wp_ajax_pxlbsadminify_import_menu_settings', [$this, 'import_menu_settings'] );
62 - add_action( 'wp_ajax_pxlbsadminify_file_upload', [$this, 'file_upload_callback'] );
63 - add_action( 'wp_ajax_pxlbsadminify_load_custom_icons', [$this, 'load_custom_icons_callback'] );
64 - add_action( 'wp_ajax_pxlbsadminify_search_users', [$this, 'search_users_callback'] );
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 65 new MenuEditorAssets();
66 66 }
67 67
68 68 public function custom_icon_mime_types( $mimes ) {
@@ -102,16 +102,9 @@
102 102 // return $value->post_title == 'adminify-custom-icon';
103 103 return strpos( $value->guid, 'adminify-custom-icon' ) !== false;
104 104 }
105 105
106 - public function load_custom_icons_callback() {
107 - // Security check - verify nonce and capability
108 - check_ajax_referer( 'pxlbsadminify-menu-editor-security-nonce', 'security' );
109 - if ( !current_user_can( 'manage_options' ) ) {
110 - wp_send_json_error( array(
111 - 'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
112 - ) );
113 - }
106 + public function adminify_load_custom_icons_callback() {
114 107 $result['images'] = null;
115 108 $query = get_posts( [
116 109 'post_type' => 'attachment',
117 110 'numberposts' => -1,
@@ -123,28 +116,17 @@
123 116 echo wp_json_encode( $result );
124 117 die;
125 118 }
126 119
127 - public function file_upload_callback() {
120 + public function adminify_file_upload_callback() {
128 121 $result['status'] = false;
129 - check_ajax_referer( 'pxlbsadminify-menu-editor-security-nonce', 'security' );
130 - if ( !current_user_can( 'manage_options' ) ) {
131 - wp_send_json_error( array(
132 - 'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
133 - ) );
134 - }
122 + check_ajax_referer( 'adminify-menu-editor-security-nonce', 'security' );
135 123 $upload_dir = wp_upload_dir();
136 124 $targeted_dir = $upload_dir['basedir'] . '/adminify-custom-icons';
137 125 if ( !is_dir( $targeted_dir ) ) {
138 126 wp_mkdir_p( $targeted_dir );
139 127 }
140 - add_filter( 'upload_dir', [$this, 'icon_custom_upload_dir'] );
141 - if ( !isset( $_FILES['my_file_upload'] ) ) {
142 - wp_send_json_error( array(
143 - 'message' => __( 'No file was uploaded.', 'adminify' ),
144 - ) );
145 - }
146 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- $_FILES is sanitized by the WP upload handler.
128 + add_filter( 'upload_dir', [$this, 'adminify_icon_custom_upload_dir'] );
147 129 $files = wp_kses_post_deep( wp_unslash( $_FILES['my_file_upload'] ) );
148 130 foreach ( $files['name'] as $key => $value ) {
149 131 if ( $files['name'][$key] ) {
150 132 $file = [
@@ -169,14 +151,14 @@
169 151 $result['images'][$attachment_id] = wp_get_attachment_url( $attachment_id );
170 152 }
171 153 }
172 154 }
173 - remove_filter( 'upload_dir', [$this, 'icon_custom_upload_dir'] );
155 + remove_filter( 'upload_dir', [$this, 'adminify_icon_custom_upload_dir'] );
174 156 echo wp_json_encode( $result );
175 157 wp_die();
176 158 }
177 159
178 - public function icon_custom_upload_dir( $dir_data ) {
160 + public function adminify_icon_custom_upload_dir( $dir_data ) {
179 161 // $dir_data already you might want to use
180 162 $custom_dir = 'adminify-custom-icons';
181 163 return [
182 164 'path' => $dir_data['basedir'] . '/' . $custom_dir,
@@ -187,75 +169,10 @@
187 169 'error' => $dir_data['error'],
188 170 ];
189 171 }
190 172
191 - /**
192 - * AJAX callback to search users for Select2
193 - * Uses 'fields' parameter for optimized database query performance
194 - */
195 - public function search_users_callback() {
196 - check_ajax_referer( 'pxlbsadminify-menu-editor-security-nonce', 'security' );
197 - if ( !current_user_can( 'manage_options' ) ) {
198 - wp_send_json_error( array(
199 - 'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
200 - ) );
201 - }
202 - $search = ( isset( $_GET['search'] ) ? sanitize_text_field( wp_unslash( $_GET['search'] ) ) : '' );
203 - // If no search term or less than 3 chars, return first 3 users
204 - if ( strlen( $search ) < 3 ) {
205 - $args = array(
206 - 'number' => 3,
207 - 'orderby' => 'ID',
208 - 'order' => 'DESC',
209 - 'fields' => array('ID', 'user_login', 'display_name'),
210 - );
211 - $users = get_users( $args );
212 - $results = array();
213 - foreach ( $users as $user ) {
214 - $results[] = array(
215 - 'id' => $user->user_login,
216 - 'text' => $user->user_login . ' (' . $user->display_name . ')',
217 - );
218 - }
219 - // Get total user count efficiently
220 - $user_count = count_users();
221 - $total_users = $user_count['total_users'];
222 - wp_send_json( array(
223 - 'results' => $results,
224 - 'pagination' => array(
225 - 'more' => $total_users > 3,
226 - ),
227 - 'total_users' => $total_users,
228 - ) );
229 - return;
230 - }
231 - // Search users when 3+ characters typed
232 - $args = array(
233 - 'search' => '*' . $search . '*',
234 - 'search_columns' => array('user_login', 'user_email', 'display_name'),
235 - 'number' => 20,
236 - 'orderby' => 'display_name',
237 - 'order' => 'ASC',
238 - 'fields' => array('ID', 'user_login', 'display_name'),
239 - );
240 - $users = get_users( $args );
241 - $results = array();
242 - foreach ( $users as $user ) {
243 - $results[] = array(
244 - 'id' => $user->user_login,
245 - 'text' => $user->user_login . ' (' . $user->display_name . ')',
246 - );
247 - }
248 - wp_send_json( array(
249 - 'results' => $results,
250 - 'pagination' => array(
251 - 'more' => false,
252 - ),
253 - ) );
254 - }
255 -
256 173 // Menu Editor Body Class
257 - public function menu_editor_body_class( $classes ) {
174 + public function jltwp_adminify_menu_editor_body_class( $classes ) {
258 175 $classes .= ' adminify_menu_editor ';
259 176 return $classes;
260 177 }
261 178
@@ -270,13 +187,13 @@
270 187 foreach ( $values as $index => $in ) {
271 188 if ( is_array( $in ) ) {
272 189 $values[$index] = $this->clean_ajax_input( $in );
273 190 } else {
274 - $values[$index] = wp_strip_all_tags( $in );
191 + $values[$index] = strip_tags( $in );
275 192 }
276 193 }
277 194 } else {
278 - $values = wp_strip_all_tags( $values );
195 + $values = strip_tags( $values );
279 196 }
280 197 return $values;
281 198 }
282 199
@@ -289,25 +206,18 @@
289 206 public function ajax_error_message( $message ) {
290 207 $returndata = [];
291 208 $returndata['error'] = true;
292 209 $returndata['error_message'] = $message;
293 - return wp_json_encode( $returndata );
210 + return json_encode( $returndata );
294 211 }
295 212
296 - public function save_menu_settings() {
297 - if ( defined( 'DOING_AJAX' ) && DOING_AJAX && check_ajax_referer( 'pxlbsadminify-menu-editor-security-nonce', 'security' ) > 0 ) {
298 - if ( !current_user_can( 'manage_options' ) ) {
299 - wp_send_json_error( array(
300 - 'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
301 - ) );
302 - }
303 - $options = ( isset( $_POST['options'] ) ? wp_kses_post_deep( wp_unslash( $_POST['options'] ) ) : '' );
304 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitized via wp_kses_post_deep() and clean_ajax_input() below.
213 + public function adminify_save_menu_settings() {
214 + if ( defined( 'DOING_AJAX' ) && DOING_AJAX && check_ajax_referer( 'adminify-menu-editor-security-nonce', 'security' ) > 0 ) {
215 + $options = wp_kses_post_deep( wp_unslash( $_POST['options'] ) );
305 216 $options = $this->clean_ajax_input( $options );
306 217 if ( $options == '' || !is_array( $options ) ) {
307 218 $message = __( 'No options supplied to save', 'adminify' );
308 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- kses_custom() is a wp_kses() wrapper; output already escaped.
309 - echo Utils::kses_custom( $this->ajax_error_message( $message ) );
219 + echo Utils::wp_kses_custom( $this->ajax_error_message( $message ) );
310 220 die;
311 221 }
312 222 if ( is_array( $options ) ) {
313 223 update_option( $this->prefix, $options );
@@ -313,14 +223,13 @@
313 223 update_option( $this->prefix, $options );
314 224 $returndata = [];
315 225 $returndata['success'] = true;
316 226 $returndata['message'] = __( 'Settings saved', 'adminify' );
317 - echo wp_json_encode( $returndata );
227 + echo json_encode( $returndata );
318 228 die;
319 229 } else {
320 230 $message = __( 'Something went wrong', 'adminify' );
321 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- kses_custom() is a wp_kses() wrapper; output already escaped.
322 - echo Utils::kses_custom( $this->ajax_error_message( $message ) );
231 + echo Utils::wp_kses_custom( $this->ajax_error_message( $message ) );
323 232 die;
324 233 }
325 234 }
326 235 die;
@@ -330,15 +239,10 @@
330 239 * Menu Editor Settings Reset
331 240 *
332 241 * @return void
333 242 */
334 - public function reset_menu_settings() {
335 - if ( defined( 'DOING_AJAX' ) && DOING_AJAX && check_ajax_referer( 'pxlbsadminify-menu-editor-security-nonce', 'security' ) > 0 ) {
336 - if ( !current_user_can( 'manage_options' ) ) {
337 - wp_send_json_error( array(
338 - 'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
339 - ) );
340 - }
243 + public function adminify_reset_menu_settings() {
244 + if ( defined( 'DOING_AJAX' ) && DOING_AJAX && check_ajax_referer( 'adminify-menu-editor-security-nonce', 'security' ) > 0 ) {
341 245 update_option( $this->prefix, [] );
342 246 $menu_editor_options = get_option( $this->prefix );
343 247 if ( !$menu_editor_options ) {
344 248 $returndata = [];
@@ -343,14 +247,13 @@
343 247 if ( !$menu_editor_options ) {
344 248 $returndata = [];
345 249 $returndata['success'] = true;
346 250 $returndata['message'] = __( 'Settings reset', 'adminify' );
347 - echo wp_json_encode( $returndata );
251 + echo json_encode( $returndata );
348 252 die;
349 253 } else {
350 254 $message = __( 'Something went wrong', 'adminify' );
351 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- kses_custom() is a wp_kses() wrapper; output already escaped.
352 - echo Utils::kses_custom( $this->ajax_error_message( $message ) );
255 + echo Utils::wp_kses_custom( $this->ajax_error_message( $message ) );
353 256 die;
354 257 }
355 258 }
356 259 die;
@@ -360,17 +263,12 @@
360 263 * Export Menu Editor Settings
361 264 *
362 265 * @return void
363 266 */
364 - public function export_menu_settings() {
365 - if ( defined( 'DOING_AJAX' ) && DOING_AJAX && check_ajax_referer( 'pxlbsadminify-menu-editor-security-nonce', 'security' ) > 0 ) {
366 - if ( !current_user_can( 'manage_options' ) ) {
367 - wp_send_json_error( array(
368 - 'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
369 - ) );
370 - }
267 + public function adminify_export_menu_settings() {
268 + if ( defined( 'DOING_AJAX' ) && DOING_AJAX && check_ajax_referer( 'adminify-menu-editor-security-nonce', 'security' ) > 0 ) {
371 269 $menu_editor_options = get_option( $this->prefix );
372 - echo wp_json_encode( $menu_editor_options );
270 + echo json_encode( $menu_editor_options );
373 271 }
374 272 die;
375 273 }
376 274
@@ -378,21 +276,14 @@
378 276 * Import Menu Editor Settings
379 277 *
380 278 * @since 1.0.0
381 279 */
382 - public function import_menu_settings() {
383 - if ( defined( 'DOING_AJAX' ) && DOING_AJAX && check_ajax_referer( 'pxlbsadminify-menu-editor-security-nonce', 'security' ) > 0 ) {
384 - if ( !current_user_can( 'manage_options' ) ) {
385 - wp_send_json_error( array(
386 - 'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
387 - ) );
388 - }
389 - $new_options = ( isset( $_POST['settings'] ) ? wp_kses_post_deep( wp_unslash( $_POST['settings'] ) ) : '' );
390 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitized via wp_kses_post_deep().
280 + public function adminify_import_menu_settings() {
281 + if ( defined( 'DOING_AJAX' ) && DOING_AJAX && check_ajax_referer( 'adminify-menu-editor-security-nonce', 'security' ) > 0 ) {
282 + $new_options = wp_kses_post_deep( $_POST['settings'] );
391 283 if ( $new_options == '' || !is_array( $new_options ) ) {
392 284 $message = __( 'No options supplied to save', 'adminify' );
393 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- kses_custom() is a wp_kses() wrapper; output already escaped.
394 - echo Utils::kses_custom( $this->ajax_error_message( $message ) );
285 + echo Utils::wp_kses_custom( $this->ajax_error_message( $message ) );
395 286 die;
396 287 }
397 288 if ( is_array( $new_options ) ) {
398 289 update_option( $this->prefix, $new_options );
@@ -398,14 +289,13 @@
398 289 update_option( $this->prefix, $new_options );
399 290 $returndata = [];
400 291 $returndata['success'] = true;
401 292 $returndata['message'] = __( 'Menu Imported', 'adminify' );
402 - echo wp_json_encode( $returndata );
293 + echo json_encode( $returndata );
403 294 die;
404 295 } else {
405 296 $message = __( 'Something went wrong', 'adminify' );
406 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- kses_custom() is a wp_kses() wrapper; output already escaped.
407 - echo Utils::kses_custom( $this->ajax_error_message( $message ) );
297 + echo Utils::wp_kses_custom( $this->ajax_error_message( $message ) );
408 298 die;
409 299 }
410 300 }
411 301 die;
@@ -411,37 +301,8 @@
411 301 die;
412 302 }
413 303
414 304 /**
415 - * Find menu settings for a given slug.
416 - * Some plugins (e.g. Yoast SEO) register different top-level menu slugs
417 - * depending on user capabilities. The admin sees slug 'wpseo_dashboard'
418 - * but the editor sees 'wpseo_tools'. This method handles that mismatch
419 - * by falling back to checking if the slug appears as a submenu key.
420 - *
421 - * @param string $slug The menu slug to look up.
422 - * @return array|null The matching settings array, or null if not found.
423 - */
424 - public function find_menu_settings_by_slug( $slug ) {
425 - // Direct match
426 - if ( isset( $this->menu_settings[$slug] ) ) {
427 - return $this->menu_settings[$slug];
428 - }
429 - // Fallback: check if this slug is a submenu of any saved parent menu
430 - if ( is_array( $this->menu_settings ) ) {
431 - foreach ( $this->menu_settings as $parent_slug => $parent_settings ) {
432 - if ( !is_array( $parent_settings ) || !isset( $parent_settings['submenu'] ) || !is_array( $parent_settings['submenu'] ) ) {
433 - continue;
434 - }
435 - if ( isset( $parent_settings['submenu'][$slug] ) ) {
436 - return $parent_settings;
437 - }
438 - }
439 - }
440 - return null;
441 - }
442 -
443 - /**
444 305 * Get menu items
445 306 *
446 307 * @param [type] $parent_file
447 308 *
@@ -479,18 +340,10 @@
479 340 if ( !empty( $next_menu_item ) && strpos( $next_menu_item[2], 'separator' ) !== false ) {
480 341 $separator = 1;
481 342 }
482 343 if ( is_array( $menu_settings ) ) {
483 - // Direct slug match first, then fallback for dynamic-slug plugins (e.g. Yoast SEO)
484 344 if ( isset( $menu_settings[$current_menu_item[2]] ) ) {
485 345 $optiongroup = $menu_settings[$current_menu_item[2]];
486 - } else {
487 - $fallback = $this->find_menu_settings_by_slug( $current_menu_item[2] );
488 - if ( $fallback !== null ) {
489 - $optiongroup = $fallback;
490 - }
491 - }
492 - if ( !empty( $optiongroup ) ) {
493 346 if ( isset( $optiongroup['order'] ) ) {
494 347 $order = $optiongroup['order'];
495 348 }
496 349 if ( isset( $optiongroup['separator'] ) ) {
@@ -535,22 +388,8 @@
535 388 }
536 389 }
537 390 if ( is_array( $menu_settings ) && !array_key_exists( 0, $menu_settings ) ) {
538 391 foreach ( $menu_settings as $key => $menu_s ) {
539 - // Skip if $menu_s is not an array
540 - if ( !is_array( $menu_s ) ) {
541 - continue;
542 - }
543 - // Ensure required keys exist with defaults
544 - $menu_s = wp_parse_args( $menu_s, [
545 - 'name' => '',
546 - 'link' => '',
547 - 'icon' => '',
548 - 'order' => 0,
549 - 'separator' => 0,
550 - 'external_link' => 0,
551 - 'hidden_for' => [],
552 - ] );
553 392 $new_array = [
554 393 $menu_s['name'],
555 394 'read',
556 395 ( !empty( $menu_s['link'] ) ? $menu_s['link'] : '' ),
@@ -568,9 +407,9 @@
568 407 $menu_icon = str_replace( 'dashicons ', '', $menu_s['icon'] );
569 408 } else {
570 409 if ( empty( $menu_s['icon'] ) || strpos( $menu_s['icon'], ',' ) !== false ) {
571 410 if ( empty( $menu_s['icon'] ) ) {
572 - $menu_icon = PXLBSADMINIFY_ASSETS_IMAGE . 'logos/menu-icon.svg';
411 + $menu_icon = WP_ADMINIFY_ASSETS_IMAGE . 'logos/menu-icon.svg';
573 412 } else {
574 413 $menu_icon = explode( ',', $menu_s['icon'] )[1];
575 414 }
576 415 } else {
@@ -717,9 +556,9 @@
717 556 $separator_order = $this->menu[$key]['order'];
718 557 $empty_separator = array(
719 558 0 => '',
720 559 1 => 'read',
721 - 2 => 'separator_' . wp_rand( 200, 1000 ) * 1000,
560 + 2 => 'separator_' . rand( 200, 1000 ) * 1000,
722 561 3 => '',
723 562 4 => 'wp-menu-separator',
724 563 'order' => $separator_order + 0.5,
725 564 );
@@ -760,9 +599,9 @@
760 599 }
761 600 $submenu_settings = $this->menu_settings[$parentname]['submenu'];
762 601 $tempsub = [];
763 602 foreach ( $subitems as $current_menu_item ) {
764 - $sub_level = apply_filters( 'pxlbsadminify/menu_editor', [
603 + $sub_level = apply_filters( 'adminify/menu_editor', [
765 604 'sub_level' => false,
766 605 ] );
767 606 if ( !empty( $sub_level['sub_level'] ) ) {
768 607 if ( empty( $current_menu_item[0] ) || $current_menu_item[2] === 'wp-adminify-settings-pricing' ) {
@@ -834,18 +673,10 @@
834 673 $disabled_for = [];
835 674 $optiongroup = [];
836 675 $order = $key;
837 676 if ( is_array( $this->menu_settings ) ) {
838 - // Direct slug match first, then fallback for dynamic-slug plugins (e.g. Yoast SEO)
839 677 if ( isset( $this->menu_settings[$current_menu_item[2]] ) ) {
840 678 $optiongroup = $this->menu_settings[$current_menu_item[2]];
841 - } else {
842 - $fallback = $this->find_menu_settings_by_slug( $current_menu_item[2] );
843 - if ( $fallback !== null ) {
844 - $optiongroup = $fallback;
845 - }
846 - }
847 - if ( !empty( $optiongroup ) ) {
848 679 if ( isset( $optiongroup['name'] ) ) {
849 680 $name = $optiongroup['name'];
850 681 if ( $name != '' ) {
851 682 $current_menu_item[0] = $name;
@@ -892,19 +723,14 @@
892 723 }
893 724 }
894 725 }
895 726 $current_menu_item['order'] = $order;
896 - // Check hidden_for: boolean true means hide, array means check via is_hidden
897 727 if ( isset( $current_menu_item['hidden_for'] ) ) {
898 728 if ( $current_menu_item['hidden_for'] === true ) {
899 729 return false;
900 - } elseif ( is_array( $current_menu_item['hidden_for'] ) && !empty( $current_menu_item['hidden_for'] ) ) {
901 - // Fallback: hidden_for is still an array (settings lookup may have missed it)
902 - if ( $this->is_hidden( $current_menu_item['hidden_for'] ) ) {
903 - return false;
904 - }
730 + } else {
731 + return $current_menu_item;
905 732 }
906 - return $current_menu_item;
907 733 } else {
908 734 return $current_menu_item;
909 735 }
910 736 }
@@ -930,11 +756,11 @@
930 756 }
931 757 // Normalize disabled_for array
932 758 $disabled_for_arr = [];
933 759 foreach ( $disabled_for as $v ) {
934 - $disabled_for_arr[] = Utils::sluggify_with_underscores( $v );
760 + $disabled_for_arr[] = jlt_adminify_sluggify_with_underscores( $v );
935 761 }
936 - $slugify_user_login = Utils::sluggify_with_underscores( $current_user->user_login );
762 + $slugify_user_login = jlt_adminify_sluggify_with_underscores( $current_user->user_login );
937 763 // Check Username
938 764 if ( in_array( $current_user->user_login, $disabled_for_arr ) || in_array( $slugify_user_login, $disabled_for_arr ) ) {
939 765 return true;
940 766 }
@@ -1062,8 +888,10 @@
1062 888 * Render Menu Editor
1063 889 */
1064 890 public function render_menu_editor() {
1065 891 global $wp_roles;
892 + $users = get_users();
893 + $this->users = $users;
1066 894 $this->roles = $wp_roles->roles;
1067 895 if ( $this->menu && is_array( $this->menu ) ) {
1068 896 foreach ( $this->menu as $menu_item ) {
1069 897 $next_menu_item = next( $this->menu );
@@ -1080,8 +908,25 @@
1080 908 );
1081 909 }
1082 910 }
1083 911 $this->render_add_new_menu_item();
912 + ?>
913 + <script>
914 + jQuery(function($) {
915 +
916 + $('.adminify-menu-settings').tokenize2({
917 + placeholder: '<?php
918 + esc_html_e( 'Select roles or users', 'adminify' );
919 + ?>'
920 + });
921 +
922 + $('.adminify-menu-settings').on('tokenize:select', function() {
923 + $(this).tokenize2().trigger('tokenize:search', [$(this).tokenize2().input.val()]);
924 + });
925 +
926 + });
927 + </script>
928 + <?php
1084 929 }
1085 930 }
1086 931
1087 932 public function get_icon( $value, $default ) {
@@ -1096,17 +941,27 @@
1096 941 */
1097 942 public function generate_user_rules_select_field( $menu_id, $disabled_for, $menu_type = 'menu' ) {
1098 943 ob_start();
1099 944 ?>
1100 - <select class="adminify-menu-settings adminify-user-role-select <?php
1101 - echo esc_attr( $menu_type );
945 + <select class="adminify-menu-settings <?php
946 + echo $menu_type;
1102 947 ?>_setting" name="hidden_for" id="<?php
1103 948 echo esc_attr( $menu_id );
1104 949 ?>-user-role-types" multiple>
1105 - <optgroup label="<?php
1106 - esc_attr_e( 'Roles', 'adminify' );
1107 - ?>">
1108 950 <?php
951 + $sel = '';
952 + // if (in_array('Super Admin', $disabled_for)) {
953 + // $sel = 'selected';
954 + // }
955 + ?>
956 +
957 + <!-- <option value="Super Admin" <?php
958 + // echo esc_attr($sel);
959 + ?>><?php
960 + // esc_html_e('Super Admin', 'adminify');
961 + ?></option> -->
962 +
963 + <?php
1109 964 foreach ( $this->roles as $role ) {
1110 965 $rolename = $role['name'];
1111 966 if ( 'administrator' == strtolower( $rolename ) ) {
1112 967 continue;
@@ -1124,40 +979,26 @@
1124 979 echo esc_html( $rolename );
1125 980 ?></option>
1126 981 <?php
1127 982 }
1128 - ?>
1129 - </optgroup>
1130 -
1131 - <optgroup label="<?php
1132 - esc_attr_e( 'Users', 'adminify' );
1133 - ?>" class="adminify-users-optgroup">
983 + foreach ( $this->users as $user ) {
984 + $username = $user->display_name;
985 + $user_login = $user->user_login;
986 + $sel = '';
987 + if ( in_array( $user_login, $disabled_for ) ) {
988 + $sel = 'selected';
989 + }
990 + ?>
991 + <option value="<?php
992 + echo wp_kses_post( $user_login );
993 + ?>" <?php
994 + echo esc_attr( $sel );
995 + ?>><?php
996 + echo wp_kses_post( $user_login );
997 + ?></option>
1134 998 <?php
1135 - // Only include pre-selected users in HTML (AJAX will populate dropdown)
1136 - foreach ( $disabled_for as $item ) {
1137 - // Check if this is a user (not a role)
1138 - $is_role = false;
1139 - foreach ( $this->roles as $role ) {
1140 - if ( $role['name'] === $item ) {
1141 - $is_role = true;
1142 - break;
1143 - }
1144 - }
1145 - if ( !$is_role ) {
1146 - $user = get_user_by( 'login', $item );
1147 - if ( $user ) {
1148 - ?>
1149 - <option value="<?php
1150 - echo esc_attr( $user->user_login );
1151 - ?>" selected><?php
1152 - echo esc_html( $user->user_login . ' (' . $user->display_name . ')' );
1153 - ?></option>
1154 - <?php
1155 - }
1156 - }
1157 999 }
1158 1000 ?>
1159 - </optgroup>
1160 1001 </select>
1161 1002 <?php
1162 1003 return ob_get_clean();
1163 1004 }
@@ -1327,9 +1168,9 @@
1327 1168 <label for="<?php
1328 1169 echo esc_attr( $current_menu_item[2] );
1329 1170 ?>">
1330 1171 <?php
1331 - esc_html_e( 'Hidden For Roles or Users', 'adminify' );
1172 + esc_html_e( 'Hidden For Rules', 'adminify' );
1332 1173 ?>
1333 1174 </label>
1334 1175
1335 1176 <div class="select is-small">
@@ -1334,9 +1175,8 @@
1334 1175
1335 1176 <div class="select is-small">
1336 1177
1337 1178 <?php
1338 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- generate_user_rules_select_field() returns a trusted <select> template with form inputs that wp_kses_post() would strip; values inside are escaped.
1339 1179 echo $this->generate_user_rules_select_field( $menu_id, $disabled_for );
1340 1180 ?>
1341 1181
1342 1182 </div>
@@ -1462,9 +1302,9 @@
1462 1302 <?php
1463 1303 if ( !empty( $icon ) ) {
1464 1304 if ( preg_match( '/http(s?)\\:\\/\\//i', $icon ) ) {
1465 1305 $image = explode( ',', $icon );
1466 - echo '<i class=""><img width="24" height="24" src=' . esc_url( $image[1] ) . ' ></i>';
1306 + echo '<i class=""><img src=' . esc_url( $image[1] ) . ' ></i>';
1467 1307 } else {
1468 1308 ?>
1469 1309 <i class="<?php
1470 1310 echo esc_attr( $this->get_icon( esc_attr( $icon ), '' ) );
@@ -1471,11 +1311,11 @@
1471 1311 ?>"></i>
1472 1312 <?php
1473 1313 }
1474 1314 } else {
1475 - $adminify_icon = PXLBSADMINIFY_ASSETS_IMAGE . 'logos/menu-icon.svg';
1315 + $adminify_icon = WP_ADMINIFY_ASSETS_IMAGE . 'logos/menu-icon.svg';
1476 1316 if ( empty( $icons[$default_icons] ) ) {
1477 - echo '<i class=""><img width="24" height="24" src=' . esc_url( $adminify_icon ) . ' ></i>';
1317 + echo '<i class=""><img src=' . esc_url( $adminify_icon ) . ' ></i>';
1478 1318 } else {
1479 1319 ?>
1480 1320 <i class="<?php
1481 1321 echo wp_kses_post( $this->get_icon( esc_attr( $icon ), $icons[$default_icons] ) );
@@ -1497,9 +1337,9 @@
1497 1337 <?php
1498 1338 $upgrade_pro = '';
1499 1339 $separator_name_attr = '';
1500 1340 $upgrade_pro = 'upgrade-pro';
1501 - $separator_name_attr = Utils::upgrade_pro_notice( 'Add Separator' );
1341 + $separator_name_attr = Utils::adminify_upgrade_pro( 'Add Separator' );
1502 1342 ?>
1503 1343
1504 1344 <div class='column <?php
1505 1345 echo esc_attr( $upgrade_pro );
@@ -1507,11 +1347,11 @@
1507 1347 <label for="seperator-<?php
1508 1348 echo esc_attr( $name_attr );
1509 1349 ?>">
1510 1350 <?php
1511 - $separator_content = apply_filters( 'pxlbsadminify/menu_editor/add_separator', $separator_name_attr, $separator );
1351 + $separator_content = apply_filters( 'adminify/menu_editor/add_separator', $separator_name_attr, $separator );
1512 1352 // Apply the filter
1513 - echo wp_kses_post( $separator_content || "" );
1353 + echo $separator_content;
1514 1354 ?>
1515 1355 </label>
1516 1356 </div>
1517 1357 </div>
@@ -1614,16 +1454,36 @@
1614 1454 ?>">
1615 1455 </div>
1616 1456 <div class="column">
1617 1457 <label for=""><?php
1618 - esc_html_e( 'Hidden For Roles or Users', 'adminify' );
1458 + esc_html_e( 'Hidden For Rules', 'adminify' );
1619 1459 ?></label>
1620 1460
1621 1461 <div class="select is-small">
1622 1462 <?php
1623 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- generate_user_rules_select_field() returns a trusted <select> template with form inputs that wp_kses_post() would strip; values inside are escaped.
1624 1463 echo $this->generate_user_rules_select_field( $menu_id, $disabled_for );
1625 1464 ?>
1465 +
1466 + <script>
1467 + jQuery('#<?php
1468 + echo esc_attr( $menu_id );
1469 + ?> #<?php
1470 + echo esc_attr( $menu_id );
1471 + ?>-user-role-types').tokenize2({
1472 + placeholder: '<?php
1473 + esc_html_e( 'Select roles or users', 'adminify' );
1474 + ?>'
1475 + });
1476 + jQuery(document).ready(function($) {
1477 + $('#<?php
1478 + echo esc_attr( $menu_id );
1479 + ?> #<?php
1480 + echo esc_attr( $menu_id );
1481 + ?>-user-role-types').on('tokenize:select', function(container) {
1482 + $(this).tokenize2().trigger('tokenize:search', [$(this).tokenize2().input.val()]);
1483 + });
1484 + })
1485 + </script>
1626 1486 </div>
1627 1487 </div>
1628 1488 </div>
1629 1489 </div>
@@ -1728,16 +1588,38 @@
1728 1588 ?>">
1729 1589 </div>
1730 1590 <div class="column">
1731 1591 <label for=""><?php
1732 - esc_html_e( 'Hidden For Roles or Users', 'adminify' );
1592 + esc_html_e( 'Hidden For Rules', 'adminify' );
1733 1593 ?></label>
1734 1594
1735 1595 <div class="select is-small">
1596 +
1736 1597 <?php
1737 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- generate_user_rules_select_field() returns a trusted <select> template with form inputs that wp_kses_post() would strip; values inside are escaped.
1738 1598 echo $this->generate_user_rules_select_field( $menu_id, $disabled_for, 'sub_menu' );
1739 1599 ?>
1600 +
1601 + <script>
1602 + jQuery('#wp-adminify-sub-menu-<?php
1603 + echo esc_attr( $menu_id );
1604 + ?> #<?php
1605 + echo esc_attr( $menu_id );
1606 + ?>-user-role-types').tokenize2({
1607 + placeholder: '<?php
1608 + esc_html_e( 'Select roles or users', 'adminify' );
1609 + ?>'
1610 + });
1611 + jQuery(document).ready(function($) {
1612 + $('#wp-adminify-sub-menu-<?php
1613 + echo esc_attr( $menu_id );
1614 + ?> #<?php
1615 + echo esc_attr( $menu_id );
1616 + ?>-user-role-types').on('tokenize:select', function(container) {
1617 + $(this).tokenize2().trigger('tokenize:search', [$(this).tokenize2().input.val()]);
1618 + });
1619 + })
1620 + </script>
1621 +
1740 1622 </div>
1741 1623 </div>
1742 1624 </div>
1743 1625 <div class="columns">
@@ -1792,10 +1674,10 @@
1792 1674 /**
1793 1675 * Add New Menu Item.
1794 1676 */
1795 1677 public function render_add_new_menu_item( $submenu = false ) {
1796 - $add_item = apply_filters( 'pxlbsadminify/menu_editor', [
1797 - 'upgrade_pro' => Utils::upgrade_pro_notice( ' ' ),
1678 + $add_item = apply_filters( 'adminify/menu_editor', [
1679 + 'upgrade_pro' => Utils::adminify_upgrade_pro( ' ' ),
1798 1680 'upgrade_class' => 'upgrade-pro',
1799 1681 ] );
1800 1682 ?>
1801 1683 <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
@@ -1800,9 +1682,9 @@
1800 1682 ?>
1801 1683 <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
1802 1684 echo esc_attr( ( $submenu ? 'submenu' : '' ) );
1803 1685 ?> <?php
1804 - echo esc_attr( $add_item['upgrade_class'] );
1686 + echo Utils::wp_kses_custom( $add_item['upgrade_class'] );
1805 1687 ?>">
1806 1688 <div class="inner-text">
1807 1689 <i class="dashicons dashicons-plus-alt"></i>
1808 1690 <span class="title"><?php
@@ -1809,9 +1691,9 @@
1809 1691 esc_html_e( 'Add Item', 'adminify' );
1810 1692 ?></span>
1811 1693 </div>
1812 1694 <?php
1813 - echo wp_kses( $add_item['upgrade_pro'], Utils::kses_allowed_html() );
1695 + echo Utils::wp_kses_custom( $add_item['upgrade_pro'] );
1814 1696 ?>
1815 1697 </div>
1816 1698 <?php
1817 1699 }
@@ -1826,15 +1708,14 @@
1826 1708
1827 1709 <div class="adminify-flex adminify-flex-center adminify-justify-between">
1828 1710 <div class="adminify-menu-editor-help-urls adminify-flex adminify-flex-center adminify-gap-2">
1829 1711 <?php
1830 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- help_urls() returns a trusted template containing inline SVG icons that wp_kses_post() would strip; URLs inside are passed through esc_url().
1831 - echo Utils::help_urls(
1712 + echo Utils::adminfiy_help_urls(
1832 1713 __( 'Menu Editor', 'adminify' ),
1833 1714 'https://wpadminify.com/kb/wordpress-dashboard-menu-editor/',
1834 1715 'https://www.youtube.com/playlist?list=PLqpMw0NsHXV-EKj9Xm1DMGa6FGniHHly8',
1835 1716 'https://www.facebook.com/groups/jeweltheme',
1836 - esc_url( \PXLBSAdminify\Inc\Admin\AdminSettings::support_url() )
1717 + \WPAdminify\Inc\Admin\AdminSettings::support_url()
1837 1718 );
1838 1719 ?>
1839 1720 </div>
1840 1721
@@ -1890,9 +1771,9 @@
1890 1771 <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" />
1891 1772 </svg>
1892 1773
1893 1774 <?php
1894 - esc_html_e( 'If you have Adminify Menu Module disabled, icons and label dividers won\'t change.', 'adminify' );
1775 + esc_html_e( 'If you have WP Adminify Menu Module disabled, icons and label dividers won\'t change.', 'adminify' );
1895 1776 ?>
1896 1777
1897 1778 </p>
1898 1779 </div>
@@ -1900,9 +1781,9 @@
1900 1781
1901 1782 <?php
1902 1783 }
1903 1784
1904 - public function menu_editor_contents() {
1785 + public function jltwp_adminify_menu_editor_contents() {
1905 1786 ?>
1906 1787
1907 1788 <div class="wrap">
1908 1789 <div class="wp-adminify--menu--editor--container">