PluginProbe ʕ •ᴥ•ʔ
Admin and Site Enhancements (ASE) / 7.1.2
Admin and Site Enhancements (ASE) v7.1.2
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-common-methods.php
admin-site-enhancements / classes Last commit date
class-activation.php 2 years ago class-admin-columns-manager.php 2 years ago class-admin-menu-organizer.php 2 years ago class-auto-publish-posts-with-missed-schedule.php 2 years ago class-avif-upload.php 2 years ago class-change-login-url.php 2 years ago class-cleanup-admin-bar.php 2 years ago class-code-snippets-manager.php 2 years ago class-common-methods.php 2 years ago class-content-duplication.php 2 years ago class-content-order.php 2 years ago class-custom-admin-footer-text.php 2 years ago class-custom-body-class.php 2 years ago class-custom-content-types.php 2 years ago class-custom-css.php 2 years ago class-custom-nav-menu-items-in-new-tab.php 2 years ago class-deactivation.php 2 years ago class-disable-comments.php 2 years ago class-disable-dashboard-widgets.php 2 years ago class-disable-feeds.php 2 years ago class-disable-gutenberg.php 2 years ago class-disable-rest-api.php 2 years ago class-disable-smaller-components.php 2 years ago class-disable-updates.php 2 years ago class-disable-xml-rpc.php 2 years ago class-display-system-summary.php 2 years ago class-email-address-obfuscator.php 2 years ago class-email-delivery.php 2 years ago class-enhance-list-tables.php 2 years ago class-external-permalinks.php 2 years ago class-heartbeat-control.php 2 years ago class-hide-admin-bar.php 2 years ago class-hide-admin-notices.php 2 years ago class-image-sizes-panel.php 2 years ago class-image-upload-control.php 2 years ago class-insert-head-body-footer-code.php 2 years ago class-last-login-column.php 2 years ago class-limit-login-attempts.php 2 years ago class-login-id-type.php 2 years ago class-login-logout-menu.php 2 years ago class-maintenance-mode.php 2 years ago class-manage-ads-appads-txt.php 2 years ago class-manage-robots-txt.php 2 years ago class-media-replacement.php 2 years ago class-multiple-user-roles.php 2 years ago class-obfuscate-author-slugs.php 2 years ago class-open-external-links-in-new-tab.php 2 years ago class-password-protection.php 2 years ago class-redirect-after-login.php 2 years ago class-redirect-after-logout.php 2 years ago class-redirect-fourofour.php 2 years ago class-revisions-control.php 2 years ago class-search-engines-visibility.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-show-custom-taxonomy-filters.php 2 years ago class-site-identity-on-login-page.php 2 years ago class-svg-upload.php 2 years ago class-various-admin-ui-enhancements.php 2 years ago class-view-admin-as-role.php 2 years ago class-wider-admin-menu.php 2 years ago
class-common-methods.php
491 lines
1 <?php
2
3 namespace ASENHA\Classes;
4
5 use WP_Query;
6 /**
7 * Class that provides common methods used throughout the plugin
8 *
9 * @since 2.5.0
10 */
11 class Common_Methods {
12 /**
13 * Get IP of the current visitor/user. In use by at least the Limit Login Attempts feature.
14 * This takes a best guess of the visitor's actual IP address.
15 * Takes into account numerous HTTP proxy headers due to variations
16 * in how different ISPs handle IP addresses in headers between hops.
17 *
18 * @link https://stackoverflow.com/q/1634782
19 * @since 2.5.0
20 */
21 public function get_user_ip_address( $return_type = 'ip', $for_which_module = 'limit-login-attempts' ) {
22 // Check for shared internet/ISP IP
23 if ( !empty( $_SERVER['HTTP_CLIENT_IP'] ) && $this->is_ip_valid( $_SERVER['HTTP_CLIENT_IP'] ) ) {
24 switch ( $return_type ) {
25 case 'ip':
26 return sanitize_text_field( $_SERVER['HTTP_CLIENT_IP'] );
27 break;
28 case 'header':
29 return 'HTTP_CLIENT_IP';
30 break;
31 }
32 }
33 // Check if Cloudflare is used as a proxy
34 // Ref: https://developers.cloudflare.com/fundamentals/reference/http-request-headers/#x-forwarded-for
35 if ( !empty( $_SERVER['CF_CONNECTING_IP'] ) && $this->is_ip_valid( $_SERVER['CF_CONNECTING_IP'] ) ) {
36 switch ( $return_type ) {
37 case 'ip':
38 return sanitize_text_field( $_SERVER['CF_CONNECTING_IP'] );
39 break;
40 case 'header':
41 return 'CF_CONNECTING_IP';
42 break;
43 }
44 }
45 if ( !empty( $_SERVER['HTTP_CF_CONNECTING_IP'] ) && $this->is_ip_valid( $_SERVER['HTTP_CF_CONNECTING_IP'] ) ) {
46 switch ( $return_type ) {
47 case 'ip':
48 return sanitize_text_field( $_SERVER['HTTP_CF_CONNECTING_IP'] );
49 break;
50 case 'header':
51 return 'HTTP_CF_CONNECTING_IP';
52 break;
53 }
54 }
55 if ( !empty( $_SERVER['TRUE_CLIENT_IP'] ) && $this->is_ip_valid( $_SERVER['TRUE_CLIENT_IP'] ) ) {
56 switch ( $return_type ) {
57 case 'ip':
58 return sanitize_text_field( $_SERVER['TRUE_CLIENT_IP'] );
59 break;
60 case 'header':
61 return 'TRUE_CLIENT_IP';
62 break;
63 }
64 }
65 if ( !empty( $_SERVER['HTTP_TRUE_CLIENT_IP'] ) && $this->is_ip_valid( $_SERVER['HTTP_TRUE_CLIENT_IP'] ) ) {
66 switch ( $return_type ) {
67 case 'ip':
68 return sanitize_text_field( $_SERVER['HTTP_TRUE_CLIENT_IP'] );
69 break;
70 case 'header':
71 return 'HTTP_TRUE_CLIENT_IP';
72 break;
73 }
74 }
75 // Check for IPs passing through proxies
76 if ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
77 // Check if multiple IP addresses exist in var
78 $ip_list = explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] );
79 if ( is_array( $ip_list ) && count( $ip_list ) > 1 ) {
80 foreach ( $ip_list as $ip ) {
81 if ( $this->is_ip_valid( trim( $ip ) ) ) {
82 switch ( $return_type ) {
83 case 'ip':
84 return sanitize_text_field( trim( $ip ) );
85 break;
86 case 'header':
87 return 'HTTP_X_FORWARDED_FOR (multiple IPs)';
88 break;
89 }
90 }
91 }
92 } else {
93 switch ( $return_type ) {
94 case 'ip':
95 return sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_FOR'] );
96 break;
97 case 'header':
98 return 'HTTP_X_FORWARDED_FOR';
99 break;
100 }
101 }
102 }
103 if ( !empty( $_SERVER['HTTP_X_FORWARDED'] ) && $this->is_ip_valid( $_SERVER['HTTP_X_FORWARDED'] ) ) {
104 switch ( $return_type ) {
105 case 'ip':
106 return sanitize_text_field( $_SERVER['HTTP_X_FORWARDED'] );
107 break;
108 case 'header':
109 return 'HTTP_X_FORWARDED';
110 break;
111 }
112 }
113 if ( !empty( $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'] ) && $this->is_ip_valid( $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'] ) ) {
114 switch ( $return_type ) {
115 case 'ip':
116 return sanitize_text_field( $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'] );
117 break;
118 case 'header':
119 return 'HTTP_X_CLUSTER_CLIENT_IP';
120 break;
121 }
122 }
123 if ( !empty( $_SERVER['HTTP_FORWARDED_FOR'] ) && $this->is_ip_valid( $_SERVER['HTTP_FORWARDED_FOR'] ) ) {
124 switch ( $return_type ) {
125 case 'ip':
126 return sanitize_text_field( $_SERVER['HTTP_FORWARDED_FOR'] );
127 break;
128 case 'header':
129 return 'HTTP_FORWARDED_FOR';
130 break;
131 }
132 }
133 if ( !empty( $_SERVER['HTTP_FORWARDED'] ) && $this->is_ip_valid( $_SERVER['HTTP_FORWARDED'] ) ) {
134 switch ( $return_type ) {
135 case 'ip':
136 return sanitize_text_field( $_SERVER['HTTP_FORWARDED'] );
137 break;
138 case 'header':
139 return 'HTTP_FORWARDED';
140 break;
141 }
142 }
143 // Return unreliable IP address since all else failed
144 switch ( $return_type ) {
145 case 'ip':
146 return sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
147 break;
148 case 'header':
149 return 'REMOTE_ADDR';
150 break;
151 }
152 }
153
154 /**
155 * Check if the supplied IP address is valid or not
156 *
157 * @param string $ip an IP address
158 * @link https://stackoverflow.com/q/1634782
159 * @return boolean true if supplied address is valid IP, and false otherwise
160 */
161 public function is_ip_valid( $ip ) {
162 if ( empty( $ip ) ) {
163 return false;
164 }
165 // Ref: https://www.php.net/manual/en/filter.filters.validate.php
166 if ( false == filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
167 return false;
168 } else {
169 return true;
170 }
171 }
172
173 /**
174 * Convert number of seconds into hours, minutes, seconds. In use by at least the Limit Login Attempts feature.
175 *
176 * @since 2.5.0
177 */
178 public function seconds_to_period( $seconds, $conversion_type ) {
179 $period_start = new \DateTime('@0');
180 $period_end = new \DateTime("@{$seconds}");
181 if ( $conversion_type == 'to-days-hours-minutes-seconds' ) {
182 return $period_start->diff( $period_end )->format( '%a days, %h hours, %i minutes and %s seconds' );
183 } elseif ( $conversion_type == 'to-hours-minutes-seconds' ) {
184 return $period_start->diff( $period_end )->format( '%h hours, %i minutes and %s seconds' );
185 } elseif ( $conversion_type == 'to-minutes-seconds' ) {
186 return $period_start->diff( $period_end )->format( '%i minutes and %s seconds' );
187 } else {
188 return $period_start->diff( $period_end )->format( '%a days, %h hours, %i minutes and %s seconds' );
189 }
190 }
191
192 /**
193 * Remove html tags and content inside the tags from a string
194 *
195 * @since 3.0.3
196 */
197 public function strip_html_tags_and_content( $string ) {
198 // Strip HTML tags and content inside them. Ref: https://stackoverflow.com/a/39320168
199 if ( !is_null( $string ) ) {
200 $string = preg_replace( '@<(\\w+)\\b.*?>.*?</\\1>@si', '', $string );
201 // Strip any remaining HTML or PHP tags
202 $string = strip_tags( $string );
203 }
204 return $string;
205 }
206
207 /**
208 * Get menu hidden by toggle
209 *
210 * @since 5.1.0
211 */
212 public function get_menu_hidden_by_toggle() {
213 $menu_hidden_by_toggle = array();
214 $options = get_option( ASENHA_SLUG_U, array() );
215 if ( array_key_exists( 'custom_menu_hidden', $options ) ) {
216 $menu_hidden = $options['custom_menu_hidden'];
217 $menu_hidden = explode( ',', $menu_hidden );
218 $menu_hidden_by_toggle = array();
219 foreach ( $menu_hidden as $menu_id ) {
220 $menu_hidden_by_toggle[] = $this->restore_menu_item_id( $menu_id );
221 }
222 }
223 return $menu_hidden_by_toggle;
224 }
225
226 /**
227 * Get user capabilities for which the "Show All/Less" menu toggle should be shown for
228 *
229 * @since 5.1.0
230 */
231 public function get_user_capabilities_to_show_menu_toggle_for() {
232 global $menu, $submenu;
233 $menu_always_hidden = array();
234 $user_capabilities_menus_are_hidden_for = array();
235 $menu_hidden_by_toggle = $this->get_menu_hidden_by_toggle();
236 // indexed array
237 foreach ( $menu as $menu_key => $menu_info ) {
238 foreach ( $menu_hidden_by_toggle as $hidden_menu_id ) {
239 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
240 $menu_item_id = $menu_info[2];
241 } else {
242 $menu_item_id = $menu_info[5];
243 }
244 if ( $menu_item_id == $hidden_menu_id ) {
245 $user_capabilities_menus_are_hidden_for[] = $menu_info[1];
246 }
247 }
248 }
249 $user_capabilities_menus_are_hidden_for = array_unique( $user_capabilities_menus_are_hidden_for );
250 return $user_capabilities_menus_are_hidden_for;
251 // indexed array
252 }
253
254 /**
255 * Transform menu item's ID
256 *
257 * @since 5.1.0
258 */
259 public function transform_menu_item_id( $menu_item_id ) {
260 // Transform e.g. edit.php?post_type=page ==> edit__php___post_type____page
261 $menu_item_id_transformed = str_replace( array(
262 ".",
263 "?",
264 "=/",
265 "=",
266 "&",
267 "/"
268 ), array(
269 "__",
270 "___",
271 "_______",
272 "____",
273 "_____",
274 "______"
275 ), $menu_item_id );
276 return $menu_item_id_transformed;
277 }
278
279 /**
280 * Transform menu item's ID
281 *
282 * @since 5.1.0
283 */
284 public function restore_menu_item_id( $menu_item_id_transformed ) {
285 // Transform e.g. edit__php___post_type____page ==> edit.php?post_type=page
286 $menu_item_id = str_replace( array(
287 "_______",
288 "______",
289 "_____",
290 "____",
291 "___",
292 "__"
293 ), array(
294 "=/",
295 "/",
296 "&",
297 "=",
298 "?",
299 "."
300 ), $menu_item_id_transformed );
301 return $menu_item_id;
302 }
303
304 /**
305 * Sanitize hexedecimal numbers used for colors
306 *
307 * @link https://plugins.trac.wordpress.org/browser/bm-custom-login/trunk/bm-custom-login.php
308 * @param string $color Hex number to sanitize.
309 * @return string
310 */
311 public function sanitize_hex_color( $color ) {
312 if ( '' === $color ) {
313 return '';
314 }
315 // Make sure the color starts with a hash.
316 $color = '#' . ltrim( $color, '#' );
317 // 3 or 6 hex digits, or the empty string.
318 if ( preg_match( '|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) ) {
319 return $color;
320 }
321 return null;
322 }
323
324 /**
325 * Get the post ID of the most recent post in a custom post type
326 *
327 * @since 6.4.1
328 */
329 public function get_most_recent_post_id( $post_type ) {
330 $args = array(
331 'post_type' => $post_type,
332 'posts_per_page' => 1,
333 'orderby' => 'date',
334 'order' => 'DESC',
335 );
336 $query = new WP_Query($args);
337 if ( $query->have_posts() ) {
338 $query->the_post();
339 $post_id = get_the_ID();
340 wp_reset_postdata();
341 return $post_id;
342 }
343 return 0;
344 // Return 0 if no posts found
345 }
346
347 /**
348 * Extended ruleset for wp_kses() that includes SVG tag and it's children
349 *
350 * @since 6.8.3
351 */
352 public function get_kses_extended_ruleset() {
353 $kses_defaults = wp_kses_allowed_html( 'post' );
354 // For SVG icons
355 $svg_args = array(
356 'svg' => array(
357 'class' => true,
358 'aria-hidden' => true,
359 'aria-labelledby' => true,
360 'role' => true,
361 'xmlns' => true,
362 'width' => true,
363 'height' => true,
364 'viewbox' => true,
365 'viewBox' => true,
366 ),
367 'g' => array(
368 'fill' => true,
369 'fill-rule' => true,
370 'stroke' => true,
371 'stroke-linejoin' => true,
372 'stroke-width' => true,
373 'stroke-linecap' => true,
374 ),
375 'title' => array(
376 'title' => true,
377 ),
378 'path' => array(
379 'd' => true,
380 'fill' => true,
381 'stroke' => true,
382 'stroke-linejoin' => true,
383 'stroke-width' => true,
384 'stroke-linecap' => true,
385 ),
386 'rect' => array(
387 'width' => true,
388 'height' => true,
389 'x' => true,
390 'y' => true,
391 'rx' => true,
392 'ry' => true,
393 ),
394 'circle' => array(
395 'cx' => true,
396 'cy' => true,
397 'r' => true,
398 ),
399 );
400 $kses_with_extras = array_merge( $kses_defaults, $svg_args );
401 // For embedded PDF viewer
402 $style_script_args = array(
403 'style' => true,
404 'script' => array(
405 'src' => true,
406 ),
407 );
408 return array_merge( $kses_with_extras, $style_script_args );
409 }
410
411 /**
412 * Get the singular label from a $post object
413 *
414 * @since 6.9.3
415 */
416 function get_post_type_singular_label( $post ) {
417 $post_type_singular_label = '';
418 if ( property_exists( $post, 'post_type' ) ) {
419 $post_type_object = get_post_type_object( $post->post_type );
420 if ( is_object( $post_type_object ) && property_exists( $post_type_object, 'label' ) ) {
421 $post_type_singular_label = $post_type_object->labels->singular_name;
422 }
423 }
424 return $post_type_singular_label;
425 }
426
427 function is_in_block_editor() {
428 $current_screen = get_current_screen();
429 if ( method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor() ) {
430 return true;
431 } else {
432 return false;
433 }
434 }
435
436 /**
437 * Check if WooCommerce is active
438 *
439 * @since 6.9.9
440 */
441 public function is_woocommerce_active() {
442 if ( function_exists( 'is_plugin_active' ) && is_plugin_active( 'woocommerce/woocommerce.php' ) ) {
443 return true;
444 } else {
445 return false;
446 }
447 }
448
449 /**
450 * Convert HEX color to RGBA
451 *
452 * @link https://stackoverflow.com/a/31934345
453 * @since 7.0.0
454 */
455 public function hex_to_rgba( $hex, $alpha = false ) {
456 $hex = str_replace( '#', '', trim( $hex ) );
457 $length = strlen( $hex );
458 $rgb['r'] = hexdec( ( $length == 6 ? substr( $hex, 0, 2 ) : (( $length == 3 ? str_repeat( substr( $hex, 0, 1 ), 2 ) : 0 )) ) );
459 $rgb['g'] = hexdec( ( $length == 6 ? substr( $hex, 2, 2 ) : (( $length == 3 ? str_repeat( substr( $hex, 1, 1 ), 2 ) : 0 )) ) );
460 $rgb['b'] = hexdec( ( $length == 6 ? substr( $hex, 4, 2 ) : (( $length == 3 ? str_repeat( substr( $hex, 2, 1 ), 2 ) : 0 )) ) );
461 if ( false !== $alpha ) {
462 $rgb['a'] = $alpha;
463 }
464 // Return array of r, g, b and a
465 // return $rgb;
466 // Return rgb(255,255,255) or rgba(255,255,255,.5)
467 return implode( array_keys( $rgb ) ) . '(' . implode( ', ', $rgb ) . ')';
468 }
469
470 /**
471 * Detect if a color is light or dark
472 *
473 * @link https://stackoverflow.com/a/12228730
474 * @since 7.0.0
475 */
476 public function is_color_dark( $hex ) {
477 $hex = str_replace( '#', '', trim( $hex ) );
478 $r = hexdec( $hex[0] . $hex[1] );
479 $g = hexdec( $hex[2] . $hex[3] );
480 $b = hexdec( $hex[4] . $hex[5] );
481 $lightness = (max( $r, $g, $b ) + min( $r, $g, $b )) / 510.0;
482 // HSL algorithm
483 if ( $lightness > 0.8 ) {
484 return false;
485 } else {
486 return true;
487 }
488 }
489
490 }
491