PluginProbe ʕ •ᴥ•ʔ
Admin and Site Enhancements (ASE) / 6.2.7
Admin and Site Enhancements (ASE) v6.2.7
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 8.3.2 8.4.0 8.4.1 8.4.2 8.5.0 8.5.1 8.5.2 8.6.0 8.6.1 8.6.2 8.7.0 5.0.1 5.0.2 5.0.2.1 5.0.2.2 5.0.2.3 5.0.2.4 5.1.0 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.8.0 5.8.1 6.0.0 6.0.3 6.0.4 6.0.5 6.0.5.1 6.0.6 6.0.7 6.0.8.1 6.1.0 6.1.3 6.2.0 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.7 6.3.0 6.3.1 6.3.2 6.4.0 6.5.0 6.5.1 6.6.0 6.7.0 6.8.0 6.8.2 6.8.3 6.9.0 6.9.1 6.9.10 6.9.11 6.9.12 6.9.13.1 6.9.13.2 6.9.2 6.9.3 6.9.4 6.9.5 6.9.6 6.9.7 6.9.8 6.9.9 7.0.0 7.0.2 7.0.2.1 7.0.2.2 7.0.2.3 7.0.3 7.1.0 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2.0 7.2.1 7.3.0 7.3.1 7.3.2 7.3.3 7.4.0 7.4.2 7.4.4 7.4.5 7.4.6 7.4.7 7.4.8 7.5.0 7.5.1 7.5.2 7.5.3 7.5.4 7.6.0 7.6.1 7.6.1.1 7.6.10 7.6.11 7.6.2 7.6.3 7.6.4 7.6.5 7.6.6 7.6.7 7.6.7.1 7.6.8 7.6.9 7.7.0 7.8.0 7.8.1 7.8.10 7.8.11 7.8.12 7.8.13 7.8.14 7.8.15 7.8.16 7.8.17 7.8.18 7.8.2 7.8.3 7.8.4 7.8.5 7.8.5.1 7.8.6 7.8.7 7.8.8 7.8.9 7.9.0 7.9.1 7.9.10 7.9.11 7.9.2 7.9.3 7.9.4 7.9.5 7.9.6 7.9.7 7.9.8 7.9.9 8.0.0 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.0.6 8.0.7 8.0.8 8.1.0 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 trunk 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 1.9.0 2.0.0 2.1.0 2.2.0 2.3.0 2.4.0 2.5.0 2.6.0 2.7.0 2.8.0 2.8.1 2.8.2 2.8.3 2.9.0 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.2.0 3.3.0 3.4.0 3.5.0 3.6.1 3.7.0 3.8.0 3.9.0 3.9.1 3.9.2 4.0.0 4.0.1 4.1.0 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.9.0 4.9.1 4.9.2 4.9.3 5.0.0
admin-site-enhancements / classes / class-admin-interface.php
admin-site-enhancements / classes Last commit date
class-activation.php 2 years ago class-admin-interface.php 2 years ago class-common-methods.php 2 years ago class-content-management.php 2 years ago class-custom-code.php 2 years ago class-deactivation.php 2 years ago class-disable-components.php 2 years ago class-login-logout.php 2 years ago class-optimizations.php 2 years ago class-security.php 2 years ago class-settings-fields-render.php 2 years ago class-settings-sanitization.php 2 years ago class-settings-sections-fields.php 2 years ago class-utilities.php 2 years ago
class-admin-interface.php
1264 lines
1 <?php
2
3 namespace ASENHA\Classes;
4
5 use WP_Admin_Bar ;
6 use ArrayObject ;
7 use NumberFormatter ;
8 /**
9 * Class related to Admin Interface features
10 *
11 * @since 1.2.0
12 */
13 class Admin_Interface
14 {
15 /**
16 * Modify admin bar menu for Admin Interface >> Hide or Modify Elements feature
17 *
18 * @param $wp_admin_bar object The admin bar.
19 * @since 1.9.0
20 */
21 public function modify_admin_bar_menu( $wp_admin_bar )
22 {
23 $options = get_option( ASENHA_SLUG_U, array() );
24 // Hide WP Logo Menu
25
26 if ( array_key_exists( 'hide_ab_wp_logo_menu', $options ) && $options['hide_ab_wp_logo_menu'] ) {
27 remove_action( 'admin_bar_menu', 'wp_admin_bar_wp_menu', 10 );
28 // priority needs to match default value. Use QM to reference.
29 }
30
31 // Hide Customize Menu
32
33 if ( array_key_exists( 'hide_ab_customize_menu', $options ) && $options['hide_ab_customize_menu'] ) {
34 remove_action( 'admin_bar_menu', 'wp_admin_bar_customize_menu', 40 );
35 // priority needs to match default value. Use QM to reference.
36 }
37
38 // Hide Updates Counter/Link
39
40 if ( array_key_exists( 'hide_ab_updates_menu', $options ) && $options['hide_ab_updates_menu'] ) {
41 remove_action( 'admin_bar_menu', 'wp_admin_bar_updates_menu', 50 );
42 // priority needs to match default value. Use QM to reference.
43 }
44
45 // Hide Comments Counter/Link
46
47 if ( array_key_exists( 'hide_ab_comments_menu', $options ) && $options['hide_ab_comments_menu'] ) {
48 remove_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 60 );
49 // priority needs to match default value. Use QM to reference.
50 }
51
52 // Hide New Content Menu
53
54 if ( array_key_exists( 'hide_ab_new_content_menu', $options ) && $options['hide_ab_new_content_menu'] ) {
55 remove_action( 'admin_bar_menu', 'wp_admin_bar_new_content_menu', 70 );
56 // priority needs to match default value. Use QM to reference.
57 }
58
59 // Hide 'Howdy' text
60
61 if ( array_key_exists( 'hide_ab_howdy', $options ) && $options['hide_ab_howdy'] ) {
62 // Remove the whole my account sectino and later rebuild it
63 remove_action( 'admin_bar_menu', 'wp_admin_bar_my_account_item', 7 );
64 $current_user = wp_get_current_user();
65 $user_id = get_current_user_id();
66 $profile_url = get_edit_profile_url( $user_id );
67 $avatar = get_avatar( $user_id, 26 );
68 // size 26x26 pixels
69 $display_name = $current_user->display_name;
70 $class = 'with-avatar';
71 $wp_admin_bar->add_menu( array(
72 'id' => 'my-account',
73 'parent' => 'top-secondary',
74 'title' => $display_name . $avatar,
75 'href' => $profile_url,
76 'meta' => array(
77 'class' => $class,
78 ),
79 ) );
80 }
81
82 }
83
84 /**
85 * Wrapper for admin notices being output on admin screens
86 *
87 * @since 1.2.0
88 */
89 public function admin_notices_wrapper()
90 {
91 if ( current_user_can( 'manage_options' ) ) {
92 echo '<div class="asenha-admin-notices-drawer" style="display:none;"><h2>Admin Notices</h2></div>' ;
93 }
94 }
95
96 /**
97 * Admin bar menu item for the hidden admin notices
98 *
99 * @link https://developer.wordpress.org/reference/classes/wp_admin_bar/add_menu/
100 * @link https://developer.wordpress.org/reference/classes/wp_admin_bar/add_node/
101 * @since 1.2.0
102 */
103 public function admin_notices_menu( WP_Admin_Bar $wp_admin_bar )
104 {
105 if ( current_user_can( 'manage_options' ) ) {
106 $wp_admin_bar->add_menu( array(
107 'id' => 'asenha-hide-admin-notices',
108 'parent' => 'top-secondary',
109 'grou' => null,
110 'title' => 'Notices<span class="asenha-admin-notices-counter" style="opacity:0;">0</span>',
111 'meta' => array(
112 'class' => 'asenha-admin-notices-menu',
113 'title' => 'Click to view hidden admin notices',
114 ),
115 ) );
116 }
117 }
118
119 /**
120 * Inline CSS for the admin bar notices menu
121 *
122 * @since 1.2.0
123 */
124 public function admin_notices_menu_inline_css()
125 {
126
127 if ( current_user_can( 'manage_options' ) ) {
128 wp_add_inline_style( 'admin-bar', '
129
130 #wpadminbar .asenha-admin-notices-counter {
131 box-sizing: border-box;
132 margin: 1px 0 -1px 6px ;
133 padding: 2px 6px 3px 5px;
134 min-width: 18px;
135 height: 18px;
136 border-radius: 50%;
137 background-color: #ca4a1f;
138 color: #fff;
139 font-size: 11px;
140 line-height: 1.6;
141 text-align: center;
142 }
143
144 ' );
145 // Below we pre-emptively hide notices to avoid having them shown briefly before being moved into the notices panel via JS
146 ?>
147 <style type="text/css">
148 /* #wpbody-content .notice:not(.system-notice,.update-message),
149 #wpbody-content .notice-error,
150 #wpbody-content .error,
151 #wpbody-content .notice-info,
152 #wpbody-content .notice-information,
153 #wpbody-content #message,
154 #wpbody-content .notice-warning:not(.update-message),
155 #wpbody-content .notice-success:not(.update-message),
156 #wpbody-content .notice-updated,
157 #wpbody-content .updated:not(.active, .inactive, .plugin-update-tr),
158 #wpbody-content .update-nag, */
159 #wpbody-content > .wrap > .notice:not(.system-notice,.hidden),
160 #wpbody-content > .wrap > .notice-error,
161 #wpbody-content > .wrap > .error:not(.hidden),
162 #wpbody-content > .wrap > .notice-info,
163 #wpbody-content > .wrap > .notice-information,
164 #wpbody-content > .wrap > #message,
165 #wpbody-content > .wrap > .notice-warning:not(.hidden),
166 #wpbody-content > .wrap > .notice-success,
167 #wpbody-content > .wrap > .notice-updated,
168 #wpbody-content > .wrap > .updated,
169 #wpbody-content > .wrap > .update-nag,
170 #wpbody-content > .wrap > div > .notice:not(.system-notice,.hidden),
171 #wpbody-content > .wrap > div > .notice-error,
172 #wpbody-content > .wrap > div > .error:not(.hidden),
173 #wpbody-content > .wrap > div > .notice-info,
174 #wpbody-content > .wrap > div > .notice-information,
175 #wpbody-content > .wrap > div > #message,
176 #wpbody-content > .wrap > div > .notice-warning:not(.hidden),
177 #wpbody-content > .wrap > div > .notice-success,
178 #wpbody-content > .wrap > div > .notice-updated,
179 #wpbody-content > .wrap > div > .updated,
180 #wpbody-content > .wrap > div > .update-nag,
181 #wpbody-content > div > .wrap > .notice:not(.system-notice,.hidden),
182 #wpbody-content > div > .wrap > .notice-error,
183 #wpbody-content > div > .wrap > .error:not(.hidden),
184 #wpbody-content > div > .wrap > .notice-info,
185 #wpbody-content > div > .wrap > .notice-information,
186 #wpbody-content > div > .wrap > #message,
187 #wpbody-content > div > .wrap > .notice-warning:not(.hidden),
188 #wpbody-content > div > .wrap > .notice-success,
189 #wpbody-content > div > .wrap > .notice-updated,
190 #wpbody-content > div > .wrap > .updated,
191 #wpbody-content > div > .wrap > .update-nag,
192 #wpbody-content > .notice,
193 #wpbody-content > .error,
194 #wpbody-content > .updated,
195 #wpbody-content > .update-nag,
196 #wpbody-content > .jp-connection-banner,
197 #wpbody-content > .jitm-banner,
198 #wpbody-content > .jetpack-jitm-message,
199 #wpbody-content > .ngg_admin_notice,
200 #wpbody-content > .imagify-welcome,
201 #wpbody-content #wordfenceAutoUpdateChoice,
202 #wpbody-content #easy-updates-manager-dashnotice {
203 display: none !important;
204 }
205 </style>
206 <?php
207 }
208
209 }
210
211 /**
212 * Disable dashboard widgets
213 *
214 * @since 4.2.0
215 */
216 public function disable_dashboard_widgets()
217 {
218 global $wp_meta_boxes ;
219 // Get list of disabled widgets
220 $options = get_option( ASENHA_SLUG_U, array() );
221 $disabled_dashboard_widgets = $options['disabled_dashboard_widgets'];
222 // Store default widgets in extra options. This will be referenced from settings field.
223 $dashboard_widgets = $this->get_dashboard_widgets();
224 $extra_options = get_option( 'admin_site_enhancements_extra', array() );
225 $extra_options['dashboard_widgets'] = $dashboard_widgets;
226 update_option( 'admin_site_enhancements_extra', $extra_options );
227 // Disable widgets
228 if ( is_array( $disabled_dashboard_widgets ) || is_object( $disabled_dashboard_widgets ) ) {
229 foreach ( $disabled_dashboard_widgets as $disabled_widget_id_context_priority => $is_disabled ) {
230 // e.g. dashboard_activity__normal__core => true/false
231
232 if ( $is_disabled ) {
233 $disabled_widget = explode( '__', $disabled_widget_id_context_priority );
234 $widget_id = $disabled_widget[0];
235 $widget_context = $disabled_widget[1];
236 $widget_priority = $disabled_widget[2];
237 // remove_meta_box( $widget_id, get_current_screen()->base, $widget_context );
238 unset( $wp_meta_boxes['dashboard'][$widget_context][$widget_priority][$widget_id] );
239 }
240
241 }
242 }
243 }
244
245 /**
246 * Get dashboard widgets
247 *
248 * @since 4.2.0
249 */
250 public function get_dashboard_widgets()
251 {
252 global $wp_meta_boxes ;
253 $dashboard_widgets = array();
254
255 if ( !isset( $wp_meta_boxes['dashboard'] ) ) {
256 $extra_options = get_option( 'admin_site_enhancements_extra', array() );
257
258 if ( !array_key_exists( 'dashboard_widgets', $extra_options ) ) {
259 require_once ABSPATH . '/wp-admin/includes/dashboard.php';
260 set_current_screen( 'dashboard' );
261 wp_dashboard_setup();
262 }
263
264 }
265
266 if ( isset( $wp_meta_boxes['dashboard'] ) ) {
267 foreach ( $wp_meta_boxes['dashboard'] as $context => $priorities ) {
268 foreach ( $priorities as $priority => $widgets ) {
269 foreach ( $widgets as $widget_id => $data ) {
270 $widget_title = ( isset( $data['title'] ) ? wp_strip_all_tags( preg_replace( '/ <span.*span>/im', '', $data['title'] ) ) : 'Undetectable' );
271 $dashboard_widgets[$widget_id] = array(
272 'id' => $widget_id,
273 'title' => $widget_title,
274 'context' => $context,
275 'priority' => $priority,
276 );
277 }
278 }
279 }
280 }
281 $dashboard_widgets = wp_list_sort(
282 $dashboard_widgets,
283 'title',
284 'ASC',
285 true
286 );
287 return $dashboard_widgets;
288 }
289
290 /**
291 * Hide admin bar on the frontend for the user roles selected
292 *
293 * @since 1.3.0
294 */
295 public function hide_admin_bar_for_roles_on_frontend()
296 {
297 $options = get_option( ASENHA_SLUG_U );
298 $hide_admin_bar = $options['hide_admin_bar'];
299 $for_roles_frontend = $options['hide_admin_bar_for'];
300 $current_user = wp_get_current_user();
301 $current_user_roles = (array) $current_user->roles;
302 // single dimensional array of role slugs
303 // User has no role, i.e. logged-out
304
305 if ( count( $current_user_roles ) == 0 ) {
306 return false;
307 // hide admin bar
308 }
309
310 // User has role(s). Do further checks.
311
312 if ( isset( $for_roles_frontend ) && count( $for_roles_frontend ) > 0 ) {
313 // Assemble single-dimensional array of roles for which admin bar would be hidden
314 $roles_admin_bar_hidden_frontend = array();
315 foreach ( $for_roles_frontend as $role_slug => $admin_bar_hidden ) {
316 if ( $admin_bar_hidden ) {
317 $roles_admin_bar_hidden_frontend[] = $role_slug;
318 }
319 }
320 // Check if any of the current user roles is one for which admin bar should be hidden
321 foreach ( $current_user_roles as $role ) {
322
323 if ( in_array( $role, $roles_admin_bar_hidden_frontend ) ) {
324 return false;
325 // hide admin bar
326 }
327
328 }
329 }
330
331 return true;
332 // show admin bar
333 }
334
335 /**
336 * Set custom admin menu width
337 *
338 * @since 5.2.0
339 */
340 public function set_custom_menu_width()
341 {
342 $options = get_option( ASENHA_SLUG_U, array() );
343 $custom_width = $options['admin_menu_width'];
344 $wp_version = get_bloginfo( 'version' );
345
346 if ( version_compare( $wp_version, '5', '>' ) ) {
347 require_once ASENHA_PATH . 'includes/admin-menu-width/wp-v5-greater.php';
348 } elseif ( version_compare( $wp_version, '4', '>=' ) ) {
349 require_once ASENHA_PATH . 'includes/admin-menu-width/wp-v4-greater.php';
350 } else {
351 }
352
353 }
354
355 /**
356 * Render custom menu order
357 *
358 * @param $menu_order array an ordered array of menu items
359 * @link https://developer.wordpress.org/reference/hooks/menu_order/
360 * @since 2.0.0
361 */
362 public function render_custom_menu_order( $menu_order )
363 {
364 global $menu ;
365 $options = get_option( ASENHA_SLUG_U );
366 // Get current menu order. We're not using the default $menu_order which uses index.php, edit.php as array values.
367 $current_menu_order = array();
368 foreach ( $menu as $menu_key => $menu_info ) {
369
370 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
371 $menu_item_id = $menu_info[2];
372 } else {
373 $menu_item_id = $menu_info[5];
374 }
375
376 $current_menu_order[] = array( $menu_item_id, $menu_info[2] );
377 }
378 // Get custom menu order
379 $custom_menu_order = $options['custom_menu_order'];
380 // comma separated
381 $custom_menu_order = explode( ",", $custom_menu_order );
382 // array of menu ID, e.g. menu-dashboard
383 // Return menu order for rendering
384 $rendered_menu_order = array();
385 // Render menu based on items saved in custom menu order
386 foreach ( $custom_menu_order as $custom_menu_item_id ) {
387 foreach ( $current_menu_order as $current_menu_item_id => $current_menu_item ) {
388 if ( $custom_menu_item_id == $current_menu_item[0] ) {
389 $rendered_menu_order[] = $current_menu_item[1];
390 }
391 }
392 }
393 // Add items from current menu not already part of custom menu order, e.g. new plugin activated and adds new menu item
394 foreach ( $current_menu_order as $current_menu_item_id => $current_menu_item ) {
395 if ( !in_array( $current_menu_item[0], $custom_menu_order ) ) {
396 $rendered_menu_order[] = $current_menu_item[1];
397 }
398 }
399 return $rendered_menu_order;
400 }
401
402 /**
403 * Apply custom menu item titles
404 *
405 * @since 2.9.0
406 */
407 public function apply_custom_menu_item_titles()
408 {
409 global $menu ;
410 $options = get_option( ASENHA_SLUG_U );
411 // Get custom menu item titles
412 $custom_menu_titles = $options['custom_menu_titles'];
413 $custom_menu_titles = explode( ',', $custom_menu_titles );
414 foreach ( $menu as $menu_key => $menu_info ) {
415
416 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
417 $menu_item_id = $menu_info[2];
418 } else {
419 $menu_item_id = $menu_info[5];
420 }
421
422 // Get defaul/custom menu item title
423 foreach ( $custom_menu_titles as $custom_menu_title ) {
424 // At this point, $custom_menu_title value looks like toplevel_page_snippets__Code Snippets
425 $custom_menu_title = explode( '__', $custom_menu_title );
426
427 if ( $custom_menu_title[0] == $menu_item_id ) {
428 $menu_item_title = $custom_menu_title[1];
429 // e.g. Code Snippets
430 break;
431 // stop foreach loop so $menu_item_title is not overwritten in the next iteration
432 } else {
433 $menu_item_title = $menu_info[0];
434 }
435
436 }
437 $menu[$menu_key][0] = $menu_item_title;
438 }
439 }
440
441 /**
442 * Hide menu items by adding a class to hide them (part of WP Core's common.css)
443 *
444 * @since 2.0.0
445 */
446 public function hide_menu_items()
447 {
448 global $menu ;
449 $common_methods = new Common_Methods();
450 $menu_hidden_by_toggle = $common_methods->get_menu_hidden_by_toggle();
451 // indexed array
452 foreach ( $menu as $menu_key => $menu_info ) {
453
454 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
455 $menu_item_id = $menu_info[2];
456 } else {
457 $menu_item_id = $menu_info[5];
458 }
459
460 // Append 'hidden' class to hide menu item until toggled
461 if ( in_array( $menu_item_id, $menu_hidden_by_toggle ) ) {
462 $menu[$menu_key][4] = $menu_info[4] . ' hidden asenha_hidden_menu';
463 }
464 }
465 }
466
467 /**
468 * Add toggle to show hidden menu items
469 *
470 * @since 2.0.0
471 */
472 public function add_hidden_menu_toggle()
473 {
474 global $current_user ;
475 // Get menu items hidden by toggle
476 $common_methods = new Common_Methods();
477 $menu_hidden_by_toggle = $common_methods->get_menu_hidden_by_toggle();
478 // Get user capabilities the "Show All/Less" toggle should be shown for
479 $user_capabilities_to_show_menu_toggle_for = $common_methods->get_user_capabilities_to_show_menu_toggle_for();
480 // Get current user's capabilities from the user's role(s)
481 $current_user_capabilities = '';
482 $current_user_roles = $current_user->roles;
483 // indexed array of role slugs
484 foreach ( $current_user_roles as $current_user_role ) {
485 $current_user_role_capabilities = get_role( $current_user_role )->capabilities;
486 $current_user_role_capabilities = array_keys( $current_user_role_capabilities );
487 // indexed array
488 $current_user_role_capabilities = implode( ",", $current_user_role_capabilities );
489 $current_user_capabilities .= $current_user_role_capabilities;
490 }
491 $current_user_capabilities = array_unique( explode( ",", $current_user_capabilities ) );
492 // Maybe show "Show All/Less" toggle
493 $show_toggle_menu = false;
494 foreach ( $user_capabilities_to_show_menu_toggle_for as $user_capability_to_show_menu_toggle_for ) {
495
496 if ( in_array( $user_capability_to_show_menu_toggle_for, $current_user_capabilities ) ) {
497 $show_toggle_menu = true;
498 break;
499 }
500
501 }
502
503 if ( !empty($menu_hidden_by_toggle) && $show_toggle_menu ) {
504 add_menu_page(
505 'Show All',
506 'Show All',
507 'read',
508 'asenha_show_hidden_menu',
509 function () {
510 return false;
511 },
512 "dashicons-arrow-down-alt2",
513 300
514 );
515 add_menu_page(
516 'Show Less',
517 'Show Less',
518 'read',
519 'asenha_hide_hidden_menu',
520 function () {
521 return false;
522 },
523 "dashicons-arrow-up-alt2",
524 301
525 );
526 }
527
528 }
529
530 /**
531 * Script to toggle hidden menu itesm
532 *
533 * @since 2.0.0
534 */
535 public function enqueue_toggle_hidden_menu_script()
536 {
537 // Get menu items hidden by toggle
538 $common_methods = new Common_Methods();
539 $menu_hidden_by_toggle = $common_methods->get_menu_hidden_by_toggle();
540 if ( !empty($menu_hidden_by_toggle) ) {
541 // Script to set behaviour and actions of the sortable menu
542 wp_enqueue_script(
543 'asenha-toggle-hidden-menu',
544 ASENHA_URL . 'assets/js/toggle-hidden-menu.js',
545 array(),
546 ASENHA_VERSION,
547 false
548 );
549 }
550 }
551
552 /**
553 * Get and set default columns
554 *
555 * @since 6.0.9
556 */
557 public function get_default_columns( $post_type )
558 {
559 global $taxonomy_slugs ;
560 // indexed array of taxonomy slugs
561 $available_columns = array(
562 'date_published' => 'Published',
563 'postid' => 'ID',
564 'modified' => 'Last Modified',
565 'password_protected' => 'Password Protected',
566 'permalink' => 'Permalink',
567 'slug' => 'Slug',
568 'status' => 'Status',
569 'date' => 'Date',
570 );
571 if ( 'post' == $post_type ) {
572 $available_columns['sticky'] = 'Sticky';
573 }
574
575 if ( post_type_supports( $post_type, 'title' ) ) {
576 $available_columns['title'] = 'Title';
577 // $available_columns['title_raw'] = 'Title Only';
578 }
579
580 if ( post_type_supports( $post_type, 'editor' ) || post_type_supports( $post_type, 'excerpt' ) ) {
581 $available_columns['excerpt'] = 'Excerpt';
582 }
583 if ( post_type_supports( $post_type, 'thumbnail' ) ) {
584 $available_columns['featured_image'] = 'Featured Image';
585 }
586
587 if ( post_type_supports( $post_type, 'author' ) ) {
588 $available_columns['author'] = 'Author';
589 // $available_columns['author_name'] = 'Author';
590 // $available_columns['last_modified_author'] = 'Last Modified Author';
591 }
592
593 if ( post_type_supports( $post_type, 'post-formats' ) ) {
594 $available_columns['post_formats'] = 'Post Format';
595 }
596
597 if ( post_type_supports( $post_type, 'comments' ) ) {
598 $available_columns['comments'] = 'Comments';
599 $available_columns['comment_count'] = 'Comment Count';
600 $available_columns['comment_status'] = 'Allow Comment';
601 }
602
603 if ( post_type_supports( $post_type, 'trackbacks' ) ) {
604 $available_columns['ping_status'] = 'Ping Status';
605 }
606 if ( post_type_supports( $post_type, 'post-formats' ) ) {
607 $available_columns['post_formats'] = 'Post Format';
608 }
609
610 if ( post_type_supports( $post_type, 'page-attributes' ) || is_post_type_hierarchical( $post_type ) ) {
611 $available_columns['post_parent'] = 'Post Parent';
612 $available_columns['menu_order'] = 'Menu Order';
613 }
614
615 // Add taxonomy columns according to the custom taxonomies assigned to each post type
616 $attached_taxonomies = get_object_taxonomies( $post_type );
617
618 if ( !empty($attached_taxonomies) ) {
619 $taxonomy_slugs = array();
620 foreach ( $attached_taxonomies as $taxonomy_slug ) {
621 $taxonomy_object = get_taxonomy( $taxonomy_slug );
622 $taxonomy_label = $taxonomy_object->labels->name;
623
624 if ( 'category' == $taxonomy_slug ) {
625 $taxonomy_slug = 'categories';
626 } elseif ( 'post_tag' == $taxonomy_slug ) {
627 $taxonomy_slug = 'tags';
628 }
629
630 $taxonomy_slugs[] = $taxonomy_slug;
631 $available_columns[$taxonomy_slug] = $taxonomy_label;
632 }
633 }
634
635 // Sort by array value in ascending order, so they are displayed in that order in the 'Default' pane
636 asort( $available_columns );
637 $options = get_option( ASENHA_SLUG_U . '_extra', array() );
638 $options['admin_columns_available'][$post_type] = $available_columns;
639 update_option( ASENHA_SLUG_U . '_extra', $options );
640 return $available_columns;
641 }
642
643 /**
644 * Get ACF field object data
645 *
646 * @since 6.3.0
647 */
648 public function get_acf_field_object(
649 $column_name = '',
650 $post_id = false,
651 $in_collection = false,
652 $parent_field = false,
653 $parent_type = ''
654 )
655 {
656 $field_data = array();
657
658 if ( !$in_collection ) {
659 $field_data = get_field_object( $column_name, $post_id );
660 } else {
661 $parent_field_data = get_field_object( $parent_field, $post_id );
662
663 if ( 'group' == $parent_type || 'repeater' == $parent_type ) {
664 $sub_fields = $parent_field_data['sub_fields'];
665 foreach ( $sub_fields as $sub_field ) {
666 if ( $column_name == $sub_field['name'] ) {
667 $field_data = $sub_field;
668 }
669 }
670 }
671
672
673 if ( 'flexible_content' == $parent_type ) {
674 $layouts = $parent_field_data['layouts'];
675 foreach ( $layouts as $layout ) {
676 $sub_fields = $layout['sub_fields'];
677 foreach ( $sub_fields as $sub_field ) {
678 if ( $column_name == $sub_field['name'] ) {
679 $field_data = $sub_field;
680 }
681 }
682 }
683 }
684
685 }
686
687 return $field_data;
688 }
689
690 /**
691 * Reload list table after performing Quick Edit on post types with custom admin columns
692 * This is modified from wp_ajax_inline_save() by adding a script before wp_die() at the end
693 *
694 * @link https://github.com/WordPress/wordpress-develop/blob/6.3/src/wp-admin/includes/ajax-actions.php#L2049-L2159
695 * @since 6.0.6
696 */
697 public function wp_ajax_inline_save_with_page_reload()
698 {
699 global $mode ;
700 check_ajax_referer( 'inlineeditnonce', '_inline_edit' );
701 if ( !isset( $_POST['post_ID'] ) || !(int) $_POST['post_ID'] ) {
702 wp_die();
703 }
704 $post_id = (int) $_POST['post_ID'];
705
706 if ( 'page' === $_POST['post_type'] ) {
707 if ( !current_user_can( 'edit_page', $post_id ) ) {
708 wp_die( __( 'Sorry, you are not allowed to edit this page.' ) );
709 }
710 } else {
711 if ( !current_user_can( 'edit_post', $post_id ) ) {
712 wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
713 }
714 }
715
716 $last = wp_check_post_lock( $post_id );
717
718 if ( $last ) {
719 $last_user = get_userdata( $last );
720 $last_user_name = ( $last_user ? $last_user->display_name : __( 'Someone' ) );
721 /* translators: %s: User's display name. */
722 $msg_template = __( 'Saving is disabled: %s is currently editing this post.' );
723 if ( 'page' === $_POST['post_type'] ) {
724 /* translators: %s: User's display name. */
725 $msg_template = __( 'Saving is disabled: %s is currently editing this page.' );
726 }
727 printf( $msg_template, esc_html( $last_user_name ) );
728 wp_die();
729 }
730
731 $data =& $_POST;
732 $post = get_post( $post_id, ARRAY_A );
733 // Since it's coming from the database.
734 $post = wp_slash( $post );
735 $data['content'] = $post['post_content'];
736 $data['excerpt'] = $post['post_excerpt'];
737 // Rename.
738 $data['user_ID'] = get_current_user_id();
739 if ( isset( $data['post_parent'] ) ) {
740 $data['parent_id'] = $data['post_parent'];
741 }
742 // Status.
743
744 if ( isset( $data['keep_private'] ) && 'private' === $data['keep_private'] ) {
745 $data['visibility'] = 'private';
746 $data['post_status'] = 'private';
747 } else {
748 $data['post_status'] = $data['_status'];
749 }
750
751 if ( empty($data['comment_status']) ) {
752 $data['comment_status'] = 'closed';
753 }
754 if ( empty($data['ping_status']) ) {
755 $data['ping_status'] = 'closed';
756 }
757 // Exclude terms from taxonomies that are not supposed to appear in Quick Edit.
758 if ( !empty($data['tax_input']) ) {
759 foreach ( $data['tax_input'] as $taxonomy => $terms ) {
760 $tax_object = get_taxonomy( $taxonomy );
761 /** This filter is documented in wp-admin/includes/class-wp-posts-list-table.php */
762 if ( !apply_filters(
763 'quick_edit_show_taxonomy',
764 $tax_object->show_in_quick_edit,
765 $taxonomy,
766 $post['post_type']
767 ) ) {
768 unset( $data['tax_input'][$taxonomy] );
769 }
770 }
771 }
772 // Hack: wp_unique_post_slug() doesn't work for drafts, so we will fake that our post is published.
773
774 if ( !empty($data['post_name']) && in_array( $post['post_status'], array( 'draft', 'pending' ), true ) ) {
775 $post['post_status'] = 'publish';
776 $data['post_name'] = wp_unique_post_slug(
777 $data['post_name'],
778 $post['ID'],
779 $post['post_status'],
780 $post['post_type'],
781 $post['post_parent']
782 );
783 }
784
785 // Update the post.
786 edit_post();
787 $wp_list_table = _get_list_table( 'WP_Posts_List_Table', array(
788 'screen' => $_POST['screen'],
789 ) );
790 $mode = ( 'excerpt' === $_POST['post_view'] ? 'excerpt' : 'list' );
791 $level = 0;
792
793 if ( is_post_type_hierarchical( $wp_list_table->screen->post_type ) ) {
794 $request_post = array( get_post( $_POST['post_ID'] ) );
795 $parent = $request_post[0]->post_parent;
796 while ( $parent > 0 ) {
797 $parent_post = get_post( $parent );
798 $parent = $parent_post->post_parent;
799 $level++;
800 }
801 }
802
803 $wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ), $level );
804 // INTERCEPT: Add a script to reload the list table page
805 ?>
806 <script type="text/javascript">
807 jQuery('#post-<?php
808 echo $_POST['post_ID'] ;
809 ?>').css('opacity','0.3');
810 document.location.reload(true);
811 </script>
812 <?php
813 // end INTERCEPT
814 wp_die();
815 }
816
817 /**
818 * Hide the Help tab and drawer
819 *
820 * @since 4.5.0
821 */
822 public function hide_help_drawer()
823 {
824
825 if ( is_admin() ) {
826 $screen = get_current_screen();
827 $screen->remove_help_tabs();
828 }
829
830 }
831
832 /**
833 * Current post type. For Content Admin >> Show Custom Taxonomy Filters functionality.
834 */
835 public $post_type ;
836 /**
837 * Show featured images column in list tables for pages and post types that support featured image
838 *
839 * @since 1.0.0
840 */
841 public function show_featured_image_column()
842 {
843 $post_types = get_post_types( array(
844 'public' => true,
845 ), 'names' );
846 foreach ( $post_types as $post_type_key => $post_type_name ) {
847
848 if ( post_type_supports( $post_type_key, 'thumbnail' ) ) {
849 add_filter( "manage_{$post_type_name}_posts_columns", [ $this, 'add_featured_image_column' ], 999 );
850 add_action(
851 "manage_{$post_type_name}_posts_custom_column",
852 [ $this, 'add_featured_image' ],
853 10,
854 2
855 );
856 }
857
858 }
859 }
860
861 /**
862 * Add a column called Featured Image as the first column
863 *
864 * @param mixed $columns
865 * @return void
866 * @since 1.0.0
867 */
868 public function add_featured_image_column( $columns )
869 {
870 $new_columns = array();
871 foreach ( $columns as $key => $value ) {
872 if ( 'title' == $key ) {
873 // We add featured image column before the 'title' column
874 $new_columns['asenha-featured-image'] = 'Featured Image';
875 }
876 if ( 'thumb' == $key ) {
877 // For WooCommerce products, we add featured image column before it's native thumbnail column
878 $new_columns['asenha-featured-image'] = 'Product Image';
879 }
880 $new_columns[$key] = $value;
881 }
882 // Replace WooCommerce thumbnail column with ASE featured image column
883 if ( array_key_exists( 'thumb', $new_columns ) ) {
884 unset( $new_columns['thumb'] );
885 }
886 return $new_columns;
887 }
888
889 /**
890 * Echo featured image's in thumbnail size to a column
891 *
892 * @param mixed $column_name
893 * @param mixed $id
894 * @since 1.0.0
895 */
896 public function add_featured_image( $column_name, $id )
897 {
898 if ( 'asenha-featured-image' === $column_name ) {
899
900 if ( has_post_thumbnail( $id ) ) {
901 $size = 'thumbnail';
902 echo get_the_post_thumbnail( $id, $size, '' ) ;
903 } else {
904 echo '<img src="' . esc_url( plugins_url( 'assets/img/default_featured_image.jpg', __DIR__ ) ) . '" />' ;
905 }
906
907 }
908 }
909
910 /**
911 * Show excerpt column in list tables for pages and post types that support excerpt.
912 *
913 * @since 1.0.0
914 */
915 public function show_excerpt_column()
916 {
917 $post_types = get_post_types( array(
918 'public' => true,
919 ), 'names' );
920 foreach ( $post_types as $post_type_key => $post_type_name ) {
921
922 if ( post_type_supports( $post_type_key, 'excerpt' ) ) {
923 add_filter( "manage_{$post_type_name}_posts_columns", [ $this, 'add_excerpt_column' ] );
924 add_action(
925 "manage_{$post_type_name}_posts_custom_column",
926 [ $this, 'add_excerpt' ],
927 10,
928 2
929 );
930 }
931
932 }
933 }
934
935 /**
936 * Add a column called Featured Image as the first column
937 *
938 * @param mixed $columns
939 * @return void
940 * @since 1.0.0
941 */
942 public function add_excerpt_column( $columns )
943 {
944 $new_columns = array();
945 foreach ( $columns as $key => $value ) {
946 $new_columns[$key] = $value;
947 if ( $key == 'title' ) {
948 $new_columns['asenha-excerpt'] = 'Excerpt';
949 }
950 }
951 return $new_columns;
952 }
953
954 /**
955 * Echo featured image's in thumbnail size to a column
956 *
957 * @param mixed $column_name
958 * @param mixed $id
959 * @since 1.0.0
960 */
961 public function add_excerpt( $column_name, $id )
962 {
963
964 if ( 'asenha-excerpt' === $column_name ) {
965 $excerpt = get_the_excerpt( $id );
966 // about 310 characters
967 $excerpt = substr( $excerpt, 0, 160 );
968 // truncate to 160 characters
969 $short_excerpt = substr( $excerpt, 0, strrpos( $excerpt, ' ' ) );
970 echo wp_kses_post( $short_excerpt ) ;
971 }
972
973 }
974
975 /**
976 * Add ID column list table of pages, posts, custom post types, media, taxonomies, custom taxonomies, users amd comments
977 *
978 * @since 1.0.0
979 */
980 public function show_id_column()
981 {
982 // For pages and hierarchical post types list table
983 add_filter( 'manage_pages_columns', [ $this, 'add_id_column' ] );
984 add_action(
985 'manage_pages_custom_column',
986 [ $this, 'add_id_echo_value' ],
987 10,
988 2
989 );
990 // For posts and non-hierarchical custom posts list table
991 add_filter( 'manage_posts_columns', [ $this, 'add_id_column' ] );
992 add_action(
993 'manage_posts_custom_column',
994 [ $this, 'add_id_echo_value' ],
995 10,
996 2
997 );
998 // For media list table
999 add_filter( 'manage_media_columns', [ $this, 'add_id_column' ] );
1000 add_action(
1001 'manage_media_custom_column',
1002 [ $this, 'add_id_echo_value' ],
1003 10,
1004 2
1005 );
1006 // For list table of all taxonomies
1007 $taxonomies = get_taxonomies( [
1008 'public' => true,
1009 ], 'names' );
1010 foreach ( $taxonomies as $taxonomy ) {
1011 add_filter( 'manage_edit-' . $taxonomy . '_columns', [ $this, 'add_id_column' ] );
1012 add_action(
1013 'manage_' . $taxonomy . '_custom_column',
1014 [ $this, 'add_id_return_value' ],
1015 10,
1016 3
1017 );
1018 }
1019 // For users list table
1020 add_filter( 'manage_users_columns', [ $this, 'add_id_column' ] );
1021 add_action(
1022 'manage_users_custom_column',
1023 [ $this, 'add_id_return_value' ],
1024 10,
1025 3
1026 );
1027 // For comments list table
1028 add_filter( 'manage_edit-comments_columns', [ $this, 'add_id_column' ] );
1029 add_action(
1030 'manage_comments_custom_column',
1031 [ $this, 'add_id_echo_value' ],
1032 10,
1033 3
1034 );
1035 }
1036
1037 /**
1038 * Add a column called ID
1039 *
1040 * @param mixed $columns
1041 * @return void
1042 * @since 1.0.0
1043 */
1044 public function add_id_column( $columns )
1045 {
1046 $columns['asenha-id'] = 'ID';
1047 return $columns;
1048 }
1049
1050 /**
1051 * Echo post ID value to a column
1052 *
1053 * @param mixed $column_name
1054 * @param mixed $id
1055 * @since 1.0.0
1056 */
1057 public function add_id_echo_value( $column_name, $id )
1058 {
1059 if ( 'asenha-id' === $column_name ) {
1060 echo esc_html( $id ) ;
1061 }
1062 }
1063
1064 /**
1065 * Return post ID value to a column
1066 *
1067 * @param mixed $value
1068 * @param mixed $column_name
1069 * @param mixed $id
1070 * @since 1.0.0
1071 */
1072 public function add_id_return_value( $value, $column_name, $id )
1073 {
1074 if ( 'asenha-id' === $column_name ) {
1075 $value = $id;
1076 }
1077 return $value;
1078 }
1079
1080 /**
1081 * Add ID in the action row of list tables for pages, posts, custom post types, media, taxonomies, custom taxonomies, users amd comments
1082 *
1083 * @since 4.7.4
1084 */
1085 public function show_id_in_action_row()
1086 {
1087 add_filter(
1088 'page_row_actions',
1089 array( $this, 'add_id_in_action_row' ),
1090 10,
1091 2
1092 );
1093 add_filter(
1094 'post_row_actions',
1095 array( $this, 'add_id_in_action_row' ),
1096 10,
1097 2
1098 );
1099 add_filter(
1100 'cat_row_actions',
1101 array( $this, 'add_id_in_action_row' ),
1102 10,
1103 2
1104 );
1105 add_filter(
1106 'tag_row_actions',
1107 array( $this, 'add_id_in_action_row' ),
1108 10,
1109 2
1110 );
1111 add_filter(
1112 'media_row_actions',
1113 array( $this, 'add_id_in_action_row' ),
1114 10,
1115 2
1116 );
1117 add_filter(
1118 'comment_row_actions',
1119 array( $this, 'add_id_in_action_row' ),
1120 10,
1121 2
1122 );
1123 add_filter(
1124 'user_row_actions',
1125 array( $this, 'add_id_in_action_row' ),
1126 10,
1127 2
1128 );
1129 }
1130
1131 /**
1132 * Output the ID in the action row
1133 *
1134 * @since 4.7.4
1135 */
1136 public function add_id_in_action_row( $actions, $object )
1137 {
1138
1139 if ( current_user_can( 'edit_posts' ) ) {
1140 // For pages, posts, custom post types, media/attachments, users
1141 if ( property_exists( $object, 'ID' ) ) {
1142 $id = $object->ID;
1143 }
1144 // For taxonomies
1145 if ( property_exists( $object, 'term_id' ) ) {
1146 $id = $object->term_id;
1147 }
1148 // For comments
1149 if ( property_exists( $object, 'comment_ID' ) ) {
1150 $id = $object->comment_ID;
1151 }
1152 $actions['asenha-list-table-item-id'] = '<span class="asenha-list-table-item-id">ID: ' . $id . '</span>';
1153 }
1154
1155 return $actions;
1156 }
1157
1158 /**
1159 * Hide comments column in list tables for pages, post types that support comments, and alse media/attachments.
1160 *
1161 * @since 1.0.0
1162 */
1163 public function hide_comments_column()
1164 {
1165 $post_types = get_post_types( array(
1166 'public' => true,
1167 ), 'names' );
1168 foreach ( $post_types as $post_type_key => $post_type_name ) {
1169 if ( post_type_supports( $post_type_key, 'comments' ) ) {
1170
1171 if ( 'attachment' != $post_type_name ) {
1172 // For list tables of pages, posts and other post types
1173 add_filter( "manage_{$post_type_name}_posts_columns", [ $this, 'remove_comment_column' ] );
1174 } else {
1175 // For list table of media/attachment
1176 add_filter( 'manage_media_columns', [ $this, 'remove_comment_column' ] );
1177 }
1178
1179 }
1180 }
1181 }
1182
1183 /**
1184 * Add a column called ID
1185 *
1186 * @param mixed $columns
1187 * @return void
1188 * @since 1.0.0
1189 */
1190 public function remove_comment_column( $columns )
1191 {
1192 unset( $columns['comments'] );
1193 return $columns;
1194 }
1195
1196 /**
1197 * Hide tags column in list tables for posts.
1198 *
1199 * @since 1.0.0
1200 */
1201 public function hide_post_tags_column()
1202 {
1203 $post_types = get_post_types( array(
1204 'public' => true,
1205 ), 'names' );
1206 foreach ( $post_types as $post_type_key => $post_type_name ) {
1207 if ( $post_type_name == 'post' ) {
1208 add_filter( "manage_posts_columns", [ $this, 'remove_post_tags_column' ] );
1209 }
1210 }
1211 }
1212
1213 /**
1214 * Add a column called ID
1215 *
1216 * @param mixed $columns
1217 * @return void
1218 * @since 1.0.0
1219 */
1220 public function remove_post_tags_column( $columns )
1221 {
1222 unset( $columns['tags'] );
1223 return $columns;
1224 }
1225
1226 /**
1227 * Show custom (hierarchical) taxonomy filter(s) for all post types.
1228 *
1229 * @since 1.0.0
1230 */
1231 public function show_custom_taxonomy_filters( $post_type )
1232 {
1233 $post_taxonomies = get_object_taxonomies( $post_type, 'objects' );
1234 // Only show custom taxonomy filters for post types other than 'post'
1235 if ( 'post' != $post_type && 'attachment' != $post_type ) {
1236 array_walk( $post_taxonomies, [ $this, 'output_taxonomy_filter' ] );
1237 }
1238 }
1239
1240 /**
1241 * Output filter on the post type's list table for a taxonomy
1242 *
1243 * @since 1.0.0
1244 */
1245 public function output_taxonomy_filter( $post_taxonomy )
1246 {
1247 // Only show taxonomy filter when the taxonomy is hierarchical
1248 if ( true === $post_taxonomy->hierarchical ) {
1249 wp_dropdown_categories( array(
1250 'show_option_all' => sprintf( 'All %s', $post_taxonomy->label ),
1251 'orderby' => 'name',
1252 'order' => 'ASC',
1253 'hide_empty' => false,
1254 'hide_if_empty' => true,
1255 'selected' => sanitize_text_field( ( isset( $_GET[$post_taxonomy->query_var] ) && !empty($_GET[$post_taxonomy->query_var]) ? $_GET[$post_taxonomy->query_var] : '' ) ),
1256 'hierarchical' => true,
1257 'name' => $post_taxonomy->query_var,
1258 'taxonomy' => $post_taxonomy->name,
1259 'value_field' => 'slug',
1260 ) );
1261 }
1262 }
1263
1264 }