PluginProbe
Admin and Site Enhancements (ASE) / 8.2.3
Admin and Site Enhancements (ASE) v8.2.3
9.1.1 9.1.0 9.0.2 9.0.1 9.0.0 8.9.2 8.9.1 8.9.0 8.8.8 8.8.7 8.8.6 8.8.5 8.8.4 8.8.3 8.8.2 8.8.1 8.8.0 8.7.3 8.7.2 8.7.1 8.2.1 8.2.2 8.2.3 8.3.0 8.3.1 All 273 releases
admin-site-enhancements / classes / class-admin-menu-organizer.php
class-admin-menu-organizer.php
483 lines 19.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace ASENHA\Classes;
4
5 /**
6 * Class for Admin Menu Organizer module
7 *
8 * @since 6.9.5
9 */
10 class Admin_Menu_Organizer {
11 /**
12 * Make the "Collapse Menu" toggler sticky at the bottom of the admin menu
13 *
14 * @since 8.2.3
15 */
16 public function make_collapse_menu_item_sticky() {
17 ?>
18 <style>
19 #adminmenu #collapse-menu {
20 position: sticky;
21 bottom: 0;
22 background: #1d2327;
23 z-index: 100;
24 box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.2);
25 border-top: 1px solid #3c4349;
26 }
27 #adminmenuwrap {
28 display: flex;
29 flex-direction: column;
30 height: 100%;
31 }
32 #adminmenu {
33 display: flex;
34 flex-direction: column;
35 flex: 1;
36 margin: 12px 0 0;
37 }
38 .folded #adminmenu #collapse-menu {
39 position: sticky;
40 bottom: 0;
41 background: #1d2327;
42 }
43 </style>
44 <?php
45 }
46
47 /**
48 * Add Admin Menu item under Settings menu
49 *
50 * @since 7.8.5
51 */
52 public function add_menu_item() {
53 add_submenu_page(
54 'options-general.php',
55 // Parent page/menu
56 __( 'Admin Menu Settings', 'admin-site-enhancements' ),
57 // Browser tab/window title
58 __( 'Admin Menu', 'admin-site-enhancements' ),
59 // Sube menu title
60 'manage_options',
61 // Minimal user capabililty
62 'admin-menu-organizer',
63 // Page slug. Shows up in URL.
64 array($this, 'add_admin_menu_settings_page')
65 );
66 }
67
68 /**
69 * Create settings page for Admin Menu
70 *
71 * @since 7.8.5
72 */
73 public function add_admin_menu_settings_page() {
74 $render_field = new Settings_Fields_Render();
75 ?>
76 <div class="wrap admin-menu-organizer">
77 <h1 class="wp-heading-inline"><?php
78 echo __( 'Admin Menu Organizer', 'admin-site-enhancements' );
79 ?></h1>
80 <div class="admin-menu-organizer-main">
81 <div class="admin-menu-sortables-wrapper">
82 <?php
83 $render_field->render_sortable_menu();
84 ?>
85 </div>
86 <div class="admin-menu-actions">
87 <button id="amo-save-changes" class="button button-primary button-large"><?php
88 echo __( 'Save Changes', 'admin-site-enhancements' );
89 ?></button>
90 <div class="asenha-saving-changes" style="display:none;"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="#2271b1" d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z" opacity=".25"/><path fill="#2271b1" d="M12,4a8,8,0,0,1,7.89,6.7A1.53,1.53,0,0,0,21.38,12h0a1.5,1.5,0,0,0,1.48-1.75,11,11,0,0,0-21.72,0A1.5,1.5,0,0,0,2.62,12h0a1.53,1.53,0,0,0,1.49-1.3A8,8,0,0,1,12,4Z"><animateTransform attributeName="transform" dur="0.75s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></svg></div>
91 <div class="asenha-changes-saved" style="display:none;"><svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24"><path fill="seagreen" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10s10-4.48 10-10S17.52 2 12 2zM9.29 16.29L5.7 12.7a.996.996 0 1 1 1.41-1.41L10 14.17l6.88-6.88a.996.996 0 1 1 1.41 1.41l-7.59 7.59a.996.996 0 0 1-1.41 0z"/></svg></div>
92 </div>
93 </div>
94 </div>
95 <?php
96 }
97
98 /**
99 * Render custom menu order
100 *
101 * @param $menu_order array an ordered array of menu items
102 * @link https://developer.wordpress.org/reference/hooks/menu_order/
103 * @since 2.0.0
104 */
105 public function render_custom_menu_order( $menu_order ) {
106 global $menu;
107 $options_extra = get_option( ASENHA_SLUG_U . '_extra', array() );
108 $options = ( isset( $options_extra['admin_menu'] ) ? $options_extra['admin_menu'] : array() );
109 // Get current menu order. We're not using the default $menu_order which uses index.php, edit.php as array values.
110 $current_menu_order = array();
111 foreach ( $menu as $menu_key => $menu_info ) {
112 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
113 $menu_item_id = $menu_info[2];
114 } else {
115 $menu_item_id = $menu_info[5];
116 }
117 $current_menu_order[] = array($menu_item_id, $menu_info[2]);
118 }
119 // Get custom menu order
120 $custom_menu_order = $options['custom_menu_order'];
121 // comma separated
122 $custom_menu_order = explode( ",", $custom_menu_order );
123 // array of menu ID, e.g. menu-dashboard
124 // Return menu order for rendering
125 $rendered_menu_order = array();
126 // Render menu based on items saved in custom menu order
127 foreach ( $custom_menu_order as $custom_menu_item_id ) {
128 foreach ( $current_menu_order as $current_menu_item_id => $current_menu_item ) {
129 if ( $custom_menu_item_id == $current_menu_item[0] ) {
130 $rendered_menu_order[] = $current_menu_item[1];
131 }
132 }
133 }
134 // Add items from current menu not already part of custom menu order, e.g. new plugin activated and adds new menu item
135 foreach ( $current_menu_order as $current_menu_item_id => $current_menu_item ) {
136 if ( !in_array( $current_menu_item[0], $custom_menu_order ) ) {
137 $rendered_menu_order[] = $current_menu_item[1];
138 }
139 }
140 return $rendered_menu_order;
141 }
142
143 /**
144 * Apply custom menu item titles
145 *
146 * @since 2.9.0
147 */
148 public function apply_custom_menu_item_titles() {
149 global $menu;
150 $options_extra = get_option( ASENHA_SLUG_U . '_extra', array() );
151 $options = ( isset( $options_extra['admin_menu'] ) ? $options_extra['admin_menu'] : array() );
152 // Get custom menu item titles
153 $custom_menu_titles = $options['custom_menu_titles'];
154 $custom_menu_titles = explode( ',', $custom_menu_titles );
155 foreach ( $menu as $menu_key => $menu_info ) {
156 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
157 $menu_item_id = $menu_info[2];
158 } else {
159 $menu_item_id = $menu_info[5];
160 }
161 // Get defaul/custom menu item title
162 foreach ( $custom_menu_titles as $custom_menu_title ) {
163 // At this point, $custom_menu_title value looks like toplevel_page_snippets__Code Snippets
164 $custom_menu_title = explode( '__', $custom_menu_title );
165 if ( $custom_menu_title[0] == $menu_item_id ) {
166 $menu_item_title = $custom_menu_title[1];
167 // e.g. Code Snippets
168 break;
169 // stop foreach loop so $menu_item_title is not overwritten in the next iteration
170 } else {
171 $menu_item_title = $menu_info[0];
172 }
173 }
174 $menu[$menu_key][0] = $menu_item_title;
175 }
176 }
177
178 /**
179 * Apply custom menu item titles
180 *
181 * @since 7.9.7
182 */
183 public function apply_custom_title_for_posts_menu() {
184 global $wp_post_types;
185 $options_extra = get_option( ASENHA_SLUG_U . '_extra', array() );
186 $admin_menu_options = ( isset( $options_extra['admin_menu'] ) ? $options_extra['admin_menu'] : array() );
187 // $admin_menu_organizer = new ASENHA\Classes\Admin_Menu_Organizer();
188 // For 'Posts' menu, if the title has been changed, try changing the labels for it everywhere
189 $custom_menu_titles = explode( ',', $admin_menu_options['custom_menu_titles'] );
190 foreach ( $custom_menu_titles as $custom_menu_title ) {
191 if ( false !== strpos( $custom_menu_title, 'menu-posts__' ) ) {
192 $custom_menu_title = explode( '__', $custom_menu_title );
193 $posts_custom_title = $custom_menu_title[1];
194 $posts_default_title = __( 'Posts', 'admin-site-enhancements' );
195 if ( is_array( $wp_post_types ) ) {
196 if ( isset( $wp_post_types['post'] ) && property_exists( $wp_post_types['post'], 'label' ) ) {
197 $posts_default_title = $wp_post_types['post']->label;
198 }
199 }
200 if ( $posts_default_title != $posts_custom_title ) {
201 add_filter( 'post_type_labels_post', [$this, 'change_post_labels'] );
202 add_action( 'init', [$this, 'change_post_object_label'] );
203 add_action( 'admin_menu', [$this, 'change_post_menu_label'], PHP_INT_MAX );
204 add_action( 'admin_bar_menu', [$this, 'change_wp_admin_bar'], 80 );
205 }
206 }
207 }
208 }
209
210 /**
211 * Get custom title for 'Posts' menu item
212 *
213 * @since 6.9.13
214 */
215 public function get_posts_custom_title() {
216 $post_object = get_post_type_object( 'post' );
217 // object
218 $posts_default_title = '';
219 if ( is_object( $post_object ) ) {
220 if ( property_exists( $post_object, 'label' ) ) {
221 $posts_default_title = $post_object->label;
222 } else {
223 $posts_default_title = $post_object->labels->name;
224 }
225 }
226 $posts_custom_title = $posts_default_title;
227 $options_extra = get_option( ASENHA_SLUG_U . '_extra', array() );
228 $options = ( isset( $options_extra['admin_menu'] ) ? $options_extra['admin_menu'] : array() );
229 $custom_menu_titles = ( isset( $options['custom_menu_titles'] ) ? explode( ',', $options['custom_menu_titles'] ) : array() );
230 if ( !empty( $custom_menu_titles ) ) {
231 foreach ( $custom_menu_titles as $custom_menu_title ) {
232 if ( false !== strpos( $custom_menu_title, 'menu-posts__' ) ) {
233 $custom_menu_title = explode( '__', $custom_menu_title );
234 $posts_custom_title = $custom_menu_title[1];
235 }
236 }
237 }
238 return $posts_custom_title;
239 }
240
241 /**
242 * For 'Posts', apply custom label
243 *
244 * @link https://developer.wordpress.org/reference/hooks/post_type_labels_post_type/
245 * @since 6.9.13
246 */
247 public function change_post_labels( $labels ) {
248 $post_object = get_post_type_object( 'post' );
249 // object
250 $posts_default_title_plural = '';
251 if ( is_object( $post_object ) ) {
252 if ( property_exists( $post_object, 'label' ) ) {
253 $posts_default_title_plural = $post_object->label;
254 } else {
255 $posts_default_title_plural = $post_object->labels->name;
256 }
257 $posts_default_title_singular = $post_object->labels->singular_name;
258 $posts_custom_title = $this->get_posts_custom_title();
259 foreach ( $labels as $key => $label ) {
260 if ( null === $label ) {
261 continue;
262 }
263 $labels->{$key} = str_replace( [$posts_default_title_plural, $posts_default_title_singular], $posts_custom_title, $label );
264 }
265 }
266 return $labels;
267 }
268
269 /**
270 * For 'Posts', apply custom label in post object
271 *
272 * @since 6.9.12
273 */
274 public function change_post_object_label() {
275 global $wp_post_types;
276 $posts_custom_title = $this->get_posts_custom_title();
277 $labels =& $wp_post_types['post']->labels;
278 $labels->name = $posts_custom_title;
279 $labels->singular_name = $posts_custom_title;
280 $labels->all_items = sprintf(
281 /* translators: %s is post type or taxonomy label */
282 __( 'All %s', 'admin-site-enhancements' ),
283 $posts_custom_title
284 );
285 $labels->add_new = __( 'Add New', 'admin-site-enhancements' );
286 $labels->add_new_item = __( 'Add New', 'admin-site-enhancements' );
287 $labels->edit_item = __( 'Edit', 'admin-site-enhancements' );
288 $labels->new_item = $posts_custom_title;
289 $labels->view_item = __( 'View', 'admin-site-enhancements' );
290 $labels->search_items = sprintf(
291 /* translators: %s is post type or taxonomy label */
292 __( 'Search %s', 'admin-site-enhancements' ),
293 $posts_custom_title
294 );
295 $labels->not_found = sprintf(
296 /* translators: %s is the post type label */
297 __( 'No %s found', 'admin-site-enhancements' ),
298 strtolower( $posts_custom_title )
299 );
300 $labels->not_found_in_trash = sprintf(
301 /* translators: %s is the post type label */
302 __( 'No %s found in Trash', 'admin-site-enhancements' ),
303 strtolower( $posts_custom_title )
304 );
305 }
306
307 /**
308 * For 'Posts', apply custom label in menu and submenu
309 *
310 * @since 6.9.12
311 */
312 public function change_post_menu_label() {
313 global $submenu;
314 $posts_custom_title = $this->get_posts_custom_title();
315 if ( !empty( $posts_custom_title ) ) {
316 $submenu['edit.php'][5][0] = sprintf(
317 /* translators: %s is post type or taxonomy label */
318 __( 'All %s', 'admin-site-enhancements' ),
319 $posts_custom_title
320 );
321 } else {
322 $submenu['edit.php'][5][0] = sprintf(
323 /* translators: %s is post type or taxonomy label */
324 __( 'All %s', 'admin-site-enhancements' ),
325 $posts_default_title
326 );
327 }
328 }
329
330 /**
331 * For 'Posts', apply custom label in admin bar
332 *
333 * @since 6.9.12
334 */
335 public function change_wp_admin_bar( $wp_admin_bar ) {
336 $posts_custom_title = $this->get_posts_custom_title();
337 $new_post_node = $wp_admin_bar->get_node( 'new-post' );
338 if ( $new_post_node ) {
339 $new_post_node->title = $posts_custom_title;
340 $wp_admin_bar->add_node( $new_post_node );
341 }
342 }
343
344 /**
345 * Hide parent menu items by adding class(es) to hide them
346 *
347 * @since 2.0.0
348 */
349 public function hide_menu_items() {
350 global $menu;
351 $common_methods = new Common_Methods();
352 $menu_hidden_by_toggle = $common_methods->get_menu_hidden_by_toggle();
353 // indexed array
354 foreach ( $menu as $menu_key => $menu_info ) {
355 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
356 $menu_item_id = $menu_info[2];
357 } else {
358 $menu_item_id = $menu_info[5];
359 }
360 // Append 'hidden' class to hide menu item until toggled
361 if ( in_array( $menu_item_id, $menu_hidden_by_toggle ) ) {
362 $menu[$menu_key][4] = $menu_info[4] . ' hidden asenha_hidden_menu';
363 }
364 }
365 }
366
367 /**
368 * Add toggle to show hidden menu items
369 *
370 * @since 2.0.0
371 */
372 public function add_hidden_menu_toggle() {
373 global $current_user;
374 // Get menu items hidden by toggle
375 $common_methods = new Common_Methods();
376 $menu_hidden_by_toggle = $common_methods->get_menu_hidden_by_toggle();
377 $submenu_hidden_by_toggle = array();
378 // Get user capabilities the "Show All/Less" toggle should be shown for
379 $user_capabilities_to_show_menu_toggle_for = $common_methods->get_user_capabilities_to_show_menu_toggle_for();
380 // Get current user's capabilities from the user's role(s)
381 $current_user_capabilities = '';
382 $current_user_roles = $current_user->roles;
383 // indexed array of role slugs
384 foreach ( $current_user_roles as $current_user_role ) {
385 $current_user_role_capabilities = get_role( $current_user_role )->capabilities;
386 if ( is_array( $current_user_role_capabilities ) ) {
387 $current_user_role_capabilities = array_keys( $current_user_role_capabilities );
388 // indexed array
389 $current_user_role_capabilities = implode( ",", $current_user_role_capabilities );
390 $current_user_capabilities .= ',' . $current_user_role_capabilities;
391 }
392 }
393 // Maybe show "Show All/Less" toggle
394 $show_toggle_menu = false;
395 if ( !empty( $current_user_capabilities ) ) {
396 $current_user_capabilities = array_unique( explode( ",", $current_user_capabilities ) );
397 foreach ( $user_capabilities_to_show_menu_toggle_for as $user_capability_to_show_menu_toggle_for ) {
398 if ( in_array( $user_capability_to_show_menu_toggle_for, $current_user_capabilities ) ) {
399 $show_toggle_menu = true;
400 break;
401 }
402 }
403 }
404 if ( (!empty( $menu_hidden_by_toggle ) || !empty( $submenu_hidden_by_toggle )) && $show_toggle_menu ) {
405 add_menu_page(
406 __( 'Show All', 'admin-site-enhancements' ),
407 __( 'Show All', 'admin-site-enhancements' ),
408 'read',
409 'asenha_show_hidden_menu',
410 function () {
411 return false;
412 },
413 "dashicons-arrow-down-alt2",
414 300
415 );
416 add_menu_page(
417 __( 'Show Less', 'admin-site-enhancements' ),
418 __( 'Show Less', 'admin-site-enhancements' ),
419 'read',
420 'asenha_hide_hidden_menu',
421 function () {
422 return false;
423 },
424 "dashicons-arrow-up-alt2",
425 301
426 );
427 }
428 }
429
430 /**
431 * Script to toggle hidden menu itesm
432 *
433 * @since 2.0.0
434 */
435 public function enqueue_toggle_hidden_menu_script() {
436 // Get menu items hidden by toggle
437 $common_methods = new Common_Methods();
438 $menu_hidden_by_toggle = $common_methods->get_menu_hidden_by_toggle();
439 $submenu_hidden_by_toggle = array();
440 if ( !empty( $menu_hidden_by_toggle ) || !empty( $submenu_hidden_by_toggle ) ) {
441 // Script to set behaviour and actions of the sortable menu
442 wp_enqueue_script(
443 'asenha-toggle-hidden-menu',
444 ASENHA_URL . 'assets/js/toggle-hidden-menu.js',
445 array(),
446 ASENHA_VERSION,
447 false
448 );
449 }
450 }
451
452 /**
453 * Save admin menu via AJAX
454 *
455 * @since 6.3.1
456 */
457 public function save_admin_menu() {
458 if ( isset( $_REQUEST ) ) {
459 if ( check_ajax_referer( 'save-menu-nonce', 'nonce', false ) ) {
460 $options_extra = get_option( ASENHA_SLUG_U . '_extra', array() );
461 $options = ( isset( $options_extra['admin_menu'] ) ? $options_extra['admin_menu'] : array() );
462 $options['custom_menu_order'] = ( isset( $_REQUEST['custom_menu_order'] ) ? $_REQUEST['custom_menu_order'] : $options['custom_menu_order'] );
463 $options['custom_menu_titles'] = ( isset( $_REQUEST['custom_menu_titles'] ) ? wp_unslash( $_REQUEST['custom_menu_titles'] ) : $options['custom_menu_titles'] );
464 $options['custom_menu_hidden'] = ( isset( $_REQUEST['custom_menu_hidden'] ) ? $_REQUEST['custom_menu_hidden'] : $options['custom_menu_hidden'] );
465 $options_extra['admin_menu'] = $options;
466 // vi( $options_extra, '', 'save menu' );
467 $updated = update_option( ASENHA_SLUG_U . '_extra', $options_extra, true );
468 if ( $updated ) {
469 $response = array(
470 'status' => 'success',
471 );
472 } else {
473 $response = array(
474 'status' => 'failed',
475 );
476 }
477 echo json_encode( $response );
478 }
479 }
480 }
481
482 }
483