PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.0.5.4
Adminify – White Label, Admin Menu Editor, Login Customizer v4.0.5.4
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 -265 4.2.204.0.5.4 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'] ) ) {
@@ -568,9 +421,9 @@
568 421 $menu_icon = str_replace( 'dashicons ', '', $menu_s['icon'] );
569 422 } else {
570 423 if ( empty( $menu_s['icon'] ) || strpos( $menu_s['icon'], ',' ) !== false ) {
571 424 if ( empty( $menu_s['icon'] ) ) {
572 - $menu_icon = PXLBSADMINIFY_ASSETS_IMAGE . 'logos/menu-icon.svg';
425 + $menu_icon = WP_ADMINIFY_ASSETS_IMAGE . 'logos/menu-icon.svg';
573 426 } else {
574 427 $menu_icon = explode( ',', $menu_s['icon'] )[1];
575 428 }
576 429 } else {
@@ -717,9 +570,9 @@
717 570 $separator_order = $this->menu[$key]['order'];
718 571 $empty_separator = array(
719 572 0 => '',
720 573 1 => 'read',
721 - 2 => 'separator_' . wp_rand( 200, 1000 ) * 1000,
574 + 2 => 'separator_' . rand( 200, 1000 ) * 1000,
722 575 3 => '',
723 576 4 => 'wp-menu-separator',
724 577 'order' => $separator_order + 0.5,
725 578 );
@@ -760,9 +613,9 @@
760 613 }
761 614 $submenu_settings = $this->menu_settings[$parentname]['submenu'];
762 615 $tempsub = [];
763 616 foreach ( $subitems as $current_menu_item ) {
764 - $sub_level = apply_filters( 'pxlbsadminify/menu_editor', [
617 + $sub_level = apply_filters( 'adminify/menu_editor', [
765 618 'sub_level' => false,
766 619 ] );
767 620 if ( !empty( $sub_level['sub_level'] ) ) {
768 621 if ( empty( $current_menu_item[0] ) || $current_menu_item[2] === 'wp-adminify-settings-pricing' ) {
@@ -834,18 +687,10 @@
834 687 $disabled_for = [];
835 688 $optiongroup = [];
836 689 $order = $key;
837 690 if ( is_array( $this->menu_settings ) ) {
838 - // Direct slug match first, then fallback for dynamic-slug plugins (e.g. Yoast SEO)
839 691 if ( isset( $this->menu_settings[$current_menu_item[2]] ) ) {
840 692 $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 693 if ( isset( $optiongroup['name'] ) ) {
849 694 $name = $optiongroup['name'];
850 695 if ( $name != '' ) {
851 696 $current_menu_item[0] = $name;
@@ -892,19 +737,14 @@
892 737 }
893 738 }
894 739 }
895 740 $current_menu_item['order'] = $order;
896 - // Check hidden_for: boolean true means hide, array means check via is_hidden
897 741 if ( isset( $current_menu_item['hidden_for'] ) ) {
898 742 if ( $current_menu_item['hidden_for'] === true ) {
899 743 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 - }
744 + } else {
745 + return $current_menu_item;
905 746 }
906 - return $current_menu_item;
907 747 } else {
908 748 return $current_menu_item;
909 749 }
910 750 }
@@ -930,11 +770,11 @@
930 770 }
931 771 // Normalize disabled_for array
932 772 $disabled_for_arr = [];
933 773 foreach ( $disabled_for as $v ) {
934 - $disabled_for_arr[] = Utils::sluggify_with_underscores( $v );
774 + $disabled_for_arr[] = jlt_adminify_sluggify_with_underscores( $v );
935 775 }
936 - $slugify_user_login = Utils::sluggify_with_underscores( $current_user->user_login );
776 + $slugify_user_login = jlt_adminify_sluggify_with_underscores( $current_user->user_login );
937 777 // Check Username
938 778 if ( in_array( $current_user->user_login, $disabled_for_arr ) || in_array( $slugify_user_login, $disabled_for_arr ) ) {
939 779 return true;
940 780 }
@@ -1062,8 +902,10 @@
1062 902 * Render Menu Editor
1063 903 */
1064 904 public function render_menu_editor() {
1065 905 global $wp_roles;
906 + $users = get_users();
907 + $this->users = $users;
1066 908 $this->roles = $wp_roles->roles;
1067 909 if ( $this->menu && is_array( $this->menu ) ) {
1068 910 foreach ( $this->menu as $menu_item ) {
1069 911 $next_menu_item = next( $this->menu );
@@ -1080,8 +922,25 @@
1080 922 );
1081 923 }
1082 924 }
1083 925 $this->render_add_new_menu_item();
926 + ?>
927 + <script>
928 + jQuery(function($) {
929 +
930 + $('.adminify-menu-settings').tokenize2({
931 + placeholder: '<?php
932 + esc_html_e( 'Select roles or users', 'adminify' );
933 + ?>'
934 + });
935 +
936 + $('.adminify-menu-settings').on('tokenize:select', function() {
937 + $(this).tokenize2().trigger('tokenize:search', [$(this).tokenize2().input.val()]);
938 + });
939 +
940 + });
941 + </script>
942 + <?php
1084 943 }
1085 944 }
1086 945
1087 946 public function get_icon( $value, $default ) {
@@ -1096,17 +955,27 @@
1096 955 */
1097 956 public function generate_user_rules_select_field( $menu_id, $disabled_for, $menu_type = 'menu' ) {
1098 957 ob_start();
1099 958 ?>
1100 - <select class="adminify-menu-settings adminify-user-role-select <?php
1101 - echo esc_attr( $menu_type );
959 + <select class="adminify-menu-settings <?php
960 + echo $menu_type;
1102 961 ?>_setting" name="hidden_for" id="<?php
1103 962 echo esc_attr( $menu_id );
1104 963 ?>-user-role-types" multiple>
1105 - <optgroup label="<?php
1106 - esc_attr_e( 'Roles', 'adminify' );
1107 - ?>">
1108 964 <?php
965 + $sel = '';
966 + // if (in_array('Super Admin', $disabled_for)) {
967 + // $sel = 'selected';
968 + // }
969 + ?>
970 +
971 + <!-- <option value="Super Admin" <?php
972 + // echo esc_attr($sel);
973 + ?>><?php
974 + // esc_html_e('Super Admin', 'adminify');
975 + ?></option> -->
976 +
977 + <?php
1109 978 foreach ( $this->roles as $role ) {
1110 979 $rolename = $role['name'];
1111 980 if ( 'administrator' == strtolower( $rolename ) ) {
1112 981 continue;
@@ -1124,40 +993,26 @@
1124 993 echo esc_html( $rolename );
1125 994 ?></option>
1126 995 <?php
1127 996 }
1128 - ?>
1129 - </optgroup>
1130 -
1131 - <optgroup label="<?php
1132 - esc_attr_e( 'Users', 'adminify' );
1133 - ?>" class="adminify-users-optgroup">
997 + foreach ( $this->users as $user ) {
998 + $username = $user->display_name;
999 + $user_login = $user->user_login;
1000 + $sel = '';
1001 + if ( in_array( $user_login, $disabled_for ) ) {
1002 + $sel = 'selected';
1003 + }
1004 + ?>
1005 + <option value="<?php
1006 + echo wp_kses_post( $user_login );
1007 + ?>" <?php
1008 + echo esc_attr( $sel );
1009 + ?>><?php
1010 + echo wp_kses_post( $user_login );
1011 + ?></option>
1134 1012 <?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 1013 }
1158 1014 ?>
1159 - </optgroup>
1160 1015 </select>
1161 1016 <?php
1162 1017 return ob_get_clean();
1163 1018 }
@@ -1327,9 +1182,9 @@
1327 1182 <label for="<?php
1328 1183 echo esc_attr( $current_menu_item[2] );
1329 1184 ?>">
1330 1185 <?php
1331 - esc_html_e( 'Hidden For Roles or Users', 'adminify' );
1186 + esc_html_e( 'Hidden For Rules', 'adminify' );
1332 1187 ?>
1333 1188 </label>
1334 1189
1335 1190 <div class="select is-small">
@@ -1334,9 +1189,8 @@
1334 1189
1335 1190 <div class="select is-small">
1336 1191
1337 1192 <?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 1193 echo $this->generate_user_rules_select_field( $menu_id, $disabled_for );
1340 1194 ?>
1341 1195
1342 1196 </div>
@@ -1462,9 +1316,9 @@
1462 1316 <?php
1463 1317 if ( !empty( $icon ) ) {
1464 1318 if ( preg_match( '/http(s?)\\:\\/\\//i', $icon ) ) {
1465 1319 $image = explode( ',', $icon );
1466 - echo '<i class=""><img width="24" height="24" src=' . esc_url( $image[1] ) . ' ></i>';
1320 + echo '<i class=""><img src=' . esc_url( $image[1] ) . ' ></i>';
1467 1321 } else {
1468 1322 ?>
1469 1323 <i class="<?php
1470 1324 echo esc_attr( $this->get_icon( esc_attr( $icon ), '' ) );
@@ -1471,11 +1325,11 @@
1471 1325 ?>"></i>
1472 1326 <?php
1473 1327 }
1474 1328 } else {
1475 - $adminify_icon = PXLBSADMINIFY_ASSETS_IMAGE . 'logos/menu-icon.svg';
1329 + $adminify_icon = WP_ADMINIFY_ASSETS_IMAGE . 'logos/menu-icon.svg';
1476 1330 if ( empty( $icons[$default_icons] ) ) {
1477 - echo '<i class=""><img width="24" height="24" src=' . esc_url( $adminify_icon ) . ' ></i>';
1331 + echo '<i class=""><img src=' . esc_url( $adminify_icon ) . ' ></i>';
1478 1332 } else {
1479 1333 ?>
1480 1334 <i class="<?php
1481 1335 echo wp_kses_post( $this->get_icon( esc_attr( $icon ), $icons[$default_icons] ) );
@@ -1497,9 +1351,9 @@
1497 1351 <?php
1498 1352 $upgrade_pro = '';
1499 1353 $separator_name_attr = '';
1500 1354 $upgrade_pro = 'upgrade-pro';
1501 - $separator_name_attr = Utils::upgrade_pro_notice( 'Add Separator' );
1355 + $separator_name_attr = Utils::adminify_upgrade_pro( 'Add Separator' );
1502 1356 ?>
1503 1357
1504 1358 <div class='column <?php
1505 1359 echo esc_attr( $upgrade_pro );
@@ -1507,11 +1361,11 @@
1507 1361 <label for="seperator-<?php
1508 1362 echo esc_attr( $name_attr );
1509 1363 ?>">
1510 1364 <?php
1511 - $separator_content = apply_filters( 'pxlbsadminify/menu_editor/add_separator', $separator_name_attr, $separator );
1365 + $separator_content = apply_filters( 'adminify/menu_editor/add_separator', $separator_name_attr, $separator );
1512 1366 // Apply the filter
1513 - echo wp_kses_post( $separator_content || "" );
1367 + echo $separator_content;
1514 1368 ?>
1515 1369 </label>
1516 1370 </div>
1517 1371 </div>
@@ -1614,16 +1468,36 @@
1614 1468 ?>">
1615 1469 </div>
1616 1470 <div class="column">
1617 1471 <label for=""><?php
1618 - esc_html_e( 'Hidden For Roles or Users', 'adminify' );
1472 + esc_html_e( 'Hidden For Rules', 'adminify' );
1619 1473 ?></label>
1620 1474
1621 1475 <div class="select is-small">
1622 1476 <?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 1477 echo $this->generate_user_rules_select_field( $menu_id, $disabled_for );
1625 1478 ?>
1479 +
1480 + <script>
1481 + jQuery('#<?php
1482 + echo esc_attr( $menu_id );
1483 + ?> #<?php
1484 + echo esc_attr( $menu_id );
1485 + ?>-user-role-types').tokenize2({
1486 + placeholder: '<?php
1487 + esc_html_e( 'Select roles or users', 'adminify' );
1488 + ?>'
1489 + });
1490 + jQuery(document).ready(function($) {
1491 + $('#<?php
1492 + echo esc_attr( $menu_id );
1493 + ?> #<?php
1494 + echo esc_attr( $menu_id );
1495 + ?>-user-role-types').on('tokenize:select', function(container) {
1496 + $(this).tokenize2().trigger('tokenize:search', [$(this).tokenize2().input.val()]);
1497 + });
1498 + })
1499 + </script>
1626 1500 </div>
1627 1501 </div>
1628 1502 </div>
1629 1503 </div>
@@ -1728,16 +1602,38 @@
1728 1602 ?>">
1729 1603 </div>
1730 1604 <div class="column">
1731 1605 <label for=""><?php
1732 - esc_html_e( 'Hidden For Roles or Users', 'adminify' );
1606 + esc_html_e( 'Hidden For Rules', 'adminify' );
1733 1607 ?></label>
1734 1608
1735 1609 <div class="select is-small">
1610 +
1736 1611 <?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 1612 echo $this->generate_user_rules_select_field( $menu_id, $disabled_for, 'sub_menu' );
1739 1613 ?>
1614 +
1615 + <script>
1616 + jQuery('#wp-adminify-sub-menu-<?php
1617 + echo esc_attr( $menu_id );
1618 + ?> #<?php
1619 + echo esc_attr( $menu_id );
1620 + ?>-user-role-types').tokenize2({
1621 + placeholder: '<?php
1622 + esc_html_e( 'Select roles or users', 'adminify' );
1623 + ?>'
1624 + });
1625 + jQuery(document).ready(function($) {
1626 + $('#wp-adminify-sub-menu-<?php
1627 + echo esc_attr( $menu_id );
1628 + ?> #<?php
1629 + echo esc_attr( $menu_id );
1630 + ?>-user-role-types').on('tokenize:select', function(container) {
1631 + $(this).tokenize2().trigger('tokenize:search', [$(this).tokenize2().input.val()]);
1632 + });
1633 + })
1634 + </script>
1635 +
1740 1636 </div>
1741 1637 </div>
1742 1638 </div>
1743 1639 <div class="columns">
@@ -1792,10 +1688,10 @@
1792 1688 /**
1793 1689 * Add New Menu Item.
1794 1690 */
1795 1691 public function render_add_new_menu_item( $submenu = false ) {
1796 - $add_item = apply_filters( 'pxlbsadminify/menu_editor', [
1797 - 'upgrade_pro' => Utils::upgrade_pro_notice( ' ' ),
1692 + $add_item = apply_filters( 'adminify/menu_editor', [
1693 + 'upgrade_pro' => Utils::adminify_upgrade_pro( ' ' ),
1798 1694 'upgrade_class' => 'upgrade-pro',
1799 1695 ] );
1800 1696 ?>
1801 1697 <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 +1696,9 @@
1800 1696 ?>
1801 1697 <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 1698 echo esc_attr( ( $submenu ? 'submenu' : '' ) );
1803 1699 ?> <?php
1804 - echo esc_attr( $add_item['upgrade_class'] );
1700 + echo Utils::wp_kses_custom( $add_item['upgrade_class'] );
1805 1701 ?>">
1806 1702 <div class="inner-text">
1807 1703 <i class="dashicons dashicons-plus-alt"></i>
1808 1704 <span class="title"><?php
@@ -1809,9 +1705,9 @@
1809 1705 esc_html_e( 'Add Item', 'adminify' );
1810 1706 ?></span>
1811 1707 </div>
1812 1708 <?php
1813 - echo wp_kses( $add_item['upgrade_pro'], Utils::kses_allowed_html() );
1709 + echo Utils::wp_kses_custom( $add_item['upgrade_pro'] );
1814 1710 ?>
1815 1711 </div>
1816 1712 <?php
1817 1713 }
@@ -1826,15 +1722,14 @@
1826 1722
1827 1723 <div class="adminify-flex adminify-flex-center adminify-justify-between">
1828 1724 <div class="adminify-menu-editor-help-urls adminify-flex adminify-flex-center adminify-gap-2">
1829 1725 <?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(
1726 + echo Utils::adminfiy_help_urls(
1832 1727 __( 'Menu Editor', 'adminify' ),
1833 1728 'https://wpadminify.com/kb/wordpress-dashboard-menu-editor/',
1834 1729 'https://www.youtube.com/playlist?list=PLqpMw0NsHXV-EKj9Xm1DMGa6FGniHHly8',
1835 1730 'https://www.facebook.com/groups/jeweltheme',
1836 - esc_url( \PXLBSAdminify\Inc\Admin\AdminSettings::support_url() )
1731 + \WPAdminify\Inc\Admin\AdminSettings::support_url()
1837 1732 );
1838 1733 ?>
1839 1734 </div>
1840 1735
@@ -1890,9 +1785,9 @@
1890 1785 <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 1786 </svg>
1892 1787
1893 1788 <?php
1894 - esc_html_e( 'If you have Adminify Menu Module disabled, icons and label dividers won\'t change.', 'adminify' );
1789 + esc_html_e( 'If you have WP Adminify Menu Module disabled, icons and label dividers won\'t change.', 'adminify' );
1895 1790 ?>
1896 1791
1897 1792 </p>
1898 1793 </div>
@@ -1900,9 +1795,9 @@
1900 1795
1901 1796 <?php
1902 1797 }
1903 1798
1904 - public function menu_editor_contents() {
1799 + public function jltwp_adminify_menu_editor_contents() {
1905 1800 ?>
1906 1801
1907 1802 <div class="wrap">
1908 1803 <div class="wp-adminify--menu--editor--container">