PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.3.0
Defender Security – Malware Scanner, Login Security & Firewall v6.3.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
← All changes | src/functions.php +128 -67 5.5.1 → 6.3.0 View file →
@@ -9,9 +9,11 @@
9 9 use WP_Defender\Component\Crypt;
10 10 use WP_Defender\Component\Two_Fa;
11 11 use WP_Defender\Behavior\WPMUDEV;
12 12 use WP_Defender\Component\User_Agent;
13 +use WP_Defender\Component\Config\Config_Hub_Helper;
13 14 use WP_Defender\Controller\Two_Factor;
15 +use WP_Defender\Integrations\Dashboard_Whitelabel;
14 16 use WP_Defender\Model\Setting\Main_Setting;
15 17 use WP_Defender\Helper\Request;
16 18
17 19 if ( ! defined( 'ABSPATH' ) ) {
@@ -28,9 +30,9 @@
28 30 */
29 31 function defender_asset_url( string $path, bool $print_url = false ) {
30 32 $url = untrailingslashit( WP_DEFENDER_BASE_URL ) . $path;
31 33
32 - if ( empty( $print_url ) ) {
34 + if ( ! $print_url ) {
33 35 return $url;
34 36 }
35 37
36 38 echo esc_url_raw( $url );
@@ -99,9 +101,9 @@
99 101
100 102 /**
101 103 * Returns the global DI container for the WP Defender plugin.
102 104 *
103 - * @return \WPMU_DEV\Defender\Vendor\DI\Container The global DI container.
105 + * @return \WP_Defender\Component\Container The global DI container.
104 106 */
105 107 function wd_di() {
106 108 global $wp_defender_di;
107 109
@@ -173,9 +175,9 @@
173 175 */
174 176 function wp_timezone_string() {
175 177 $timezone_string = get_option( 'timezone_string' );
176 178
177 - if ( $timezone_string ) {
179 + if ( '' !== $timezone_string ) {
178 180 return $timezone_string;
179 181 }
180 182
181 183 $offset = (float) get_option( 'gmt_offset' );
@@ -206,19 +208,15 @@
206 208
207 209 /**
208 210 * Get hostname.
209 211 *
210 - * @return string|null
212 + * @return string
211 213 */
212 -function defender_get_hostname() {
214 +function defender_get_hostname(): string {
213 215 $host = wp_parse_url( get_site_url(), PHP_URL_HOST );
214 216 $host = str_replace( 'www.', '', $host );
215 217 $host = explode( '.', $host );
216 - if ( is_array( $host ) ) {
217 - $host = array_shift( $host );
218 - } else {
219 - $host = null;
220 - }
218 + $host = array_shift( $host );
221 219
222 220 return $host;
223 221 }
224 222
@@ -240,11 +238,19 @@
240 238 // Remove percent signs that are not part of an octet.
241 239 $title = str_replace( '%', '', $title );
242 240 // Restore octets.
243 241 $title = preg_replace( '|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title );
244 -
245 - if ( seems_utf8( $title ) ) {
246 - $title = utf8_uri_encode( $title, 200 );
242 + // Support for WordPress 6.9+ and older versions.
243 + if ( function_exists( 'wp_is_valid_utf8' ) ) {
244 + // New function since WP 6.9.0.
245 + if ( wp_is_valid_utf8( $title ) ) {
246 + $title = utf8_uri_encode( $title, 200 );
247 + }
248 + } elseif ( function_exists( 'seems_utf8' ) ) {
249 + // Old method (before WP 6.9.0).
250 + if ( seems_utf8( $title ) ) { // phpcs:ignore WordPress.WP.DeprecatedFunctions.seems_utf8Found
251 + $title = utf8_uri_encode( $title, 200 );
252 + }
247 253 }
248 254
249 255 // Kill entities.
250 256 $title = preg_replace( '/&.+?;/', '', $title );
@@ -290,9 +296,12 @@
290 296 function defender_white_label_status() {
291 297 /* translators: %s: heart icon */
292 298 $footer_text = sprintf( esc_html__( 'Made with %s by WPMU DEV', 'defender-security' ), '<i class="sui-icon-heart"></i>' );
293 299 $custom_image = apply_filters( 'wpmudev_branding_hero_image', '' );
294 - $whitelabled = apply_filters( 'wpmudev_branding_hide_branding', false );
300 + $custom_image = is_string( $custom_image ) ? $custom_image : (string) $custom_image;
301 + $custom_image = trim( $custom_image );
302 + $whitelabeled = apply_filters( 'wpmudev_branding_hide_branding', false );
303 + $whitelabeled = is_bool( $whitelabeled ) ? $whitelabeled : (bool) $whitelabeled;
295 304
296 305 return array(
297 306 'hide_branding' => apply_filters( 'wpmudev_branding_hide_branding', false ),
298 307 'hide_doc_link' => apply_filters( 'wpmudev_branding_hide_doc_link', false ),
@@ -298,20 +307,100 @@
298 307 'hide_doc_link' => apply_filters( 'wpmudev_branding_hide_doc_link', false ),
299 308 'footer_text' => apply_filters( 'wpmudev_branding_footer_text', $footer_text ),
300 309 'hero_image' => $custom_image,
301 310 'change_footer' => apply_filters( 'wpmudev_branding_change_footer', false ),
302 - 'is_unbranded' => empty( $custom_image ) && $whitelabled,
303 - 'is_rebranded' => ! empty( $custom_image ) && $whitelabled,
311 + 'is_unbranded' => '' === $custom_image && $whitelabeled,
312 + 'is_rebranded' => '' !== $custom_image && $whitelabeled,
304 313 );
305 314 }
306 315
307 316 /**
317 + * Get data of the whitelabel feature, e.g. hide_branding, hide_doc_link, footer_text, hero_image, change_footer.
318 + *
319 + * @return array
320 + * @since 6.0.0
321 + */
322 +function defender_whitelabel_data(): array {
323 + $data = array(
324 + 'is_enabled' => false,
325 + );
326 +
327 + if ( wd_di()->get( WPMUDEV::class )->is_whitelabel_enabled() ) {
328 + /* translators: %s: heart icon */
329 + $footer_text = sprintf( esc_html__( 'Made with %s by WPMU DEV', 'defender-security' ), '<i class="sui-icon-heart"></i>' );
330 + $custom_image = apply_filters( 'wpmudev_branding_hero_image', '' );
331 + $custom_image = is_string( $custom_image ) ? $custom_image : (string) $custom_image;
332 + $custom_image = trim( $custom_image );
333 + $whitelabeled = apply_filters( 'wpmudev_branding_hide_branding', false );
334 + $whitelabeled = is_bool( $whitelabeled ) ? $whitelabeled : (bool) $whitelabeled;
335 + $whitelabel = new Dashboard_Whitelabel();
336 + $plugin_name = $whitelabel->can_whitelabel() ? $whitelabel->get_plugin_name( Config_Hub_Helper::WDP_ID ) : false;
337 +
338 + $plugin_icon_url = '';
339 + $plugin_icon_class = '';
340 + $plugin_icon_type = 'default';
341 +
342 + if ( $whitelabel->can_whitelabel() ) {
343 + $wl_settings = WPMUDEV_Dashboard::$whitelabel->get_settings();
344 + $pid = Config_Hub_Helper::WDP_ID;
345 + $labels_networkwide = (bool) ( $wl_settings['labels_networkwide'] ?? true );
346 + $labels_subsites = array_map( 'intval', (array) ( $wl_settings['labels_subsites'] ?? array() ) );
347 + $apply_labels = ! is_multisite()
348 + || is_network_admin()
349 + || $labels_networkwide
350 + || in_array( get_current_blog_id(), $labels_subsites, true );
351 +
352 + if ( $apply_labels && isset( $wl_settings['labels_config'][ $pid ] ) ) {
353 + $cfg = $wl_settings['labels_config'][ $pid ];
354 + $plugin_icon_type = sanitize_key( $cfg['icon_type'] ?? 'default' );
355 +
356 + switch ( $plugin_icon_type ) {
357 + case 'dashicon':
358 + $plugin_icon_class = sanitize_html_class( $cfg['icon_class'] ?? '' );
359 + break;
360 + case 'upload':
361 + $thumb_id = (int) ( $cfg['thumb_id'] ?? 0 );
362 + if ( $thumb_id ) {
363 + $url = wp_get_attachment_image_url( $thumb_id, 'thumbnail', true );
364 + $plugin_icon_url = $url ? $url : '';
365 + }
366 + break;
367 + case 'link':
368 + $plugin_icon_url = esc_url_raw( $cfg['icon_url'] ?? '' );
369 + break;
370 + case 'none':
371 + $plugin_icon_url = null;
372 + break;
373 + }
374 + }
375 + }
376 +
377 + $data = array(
378 + 'is_enabled' => true,
379 + 'hide_branding' => apply_filters( 'wpmudev_branding_hide_branding', false ),
380 + 'hide_doc_link' => apply_filters( 'wpmudev_branding_hide_doc_link', false ),
381 + 'footer_text' => apply_filters( 'wpmudev_branding_footer_text', $footer_text ),
382 + 'hero_image' => $custom_image,
383 + 'change_footer' => apply_filters( 'wpmudev_branding_change_footer', false ),
384 + 'is_unbranded' => '' === $custom_image && $whitelabeled,
385 + 'is_rebranded' => '' !== $custom_image && $whitelabeled,
386 + 'plugin_name' => is_string( $plugin_name ) && '' !== trim( $plugin_name ) ? $plugin_name : '',
387 + 'plugin_icon_url' => $plugin_icon_url,
388 + 'plugin_icon_class' => $plugin_icon_class,
389 + 'plugin_icon_type' => $plugin_icon_type,
390 + );
391 + }
392 +
393 + return $data;
394 +}
395 +
396 +/**
308 397 * Indicate this is not fresh setup.
309 398 *
310 399 * @since 2.5.5
311 400 */
312 401 function defender_no_fresh_install() {
313 - if ( empty( get_site_option( 'wd_nofresh_install' ) ) ) {
402 + if ( false === get_site_option( 'wd_nofresh_install', false ) ) {
314 403 update_site_option( 'wd_nofresh_install', true );
315 404 }
316 405 }
317 406
@@ -461,18 +550,14 @@
461 550 *
462 551 * @return string
463 552 * @since 3.0.0
464 553 */
465 -function defender_generate_random_string( $length = 16, $strings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567' ) {
554 +function defender_generate_random_string( int $length = 16, string $strings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567' ) {
466 555 if ( defined( 'DEFENDER_2FA_SECRET' ) ) {
467 556 // Only use in test.
468 557 return constant( 'DEFENDER_2FA_SECRET' );
469 558 }
470 559
471 - if ( ! is_string( $strings ) ) {
472 - return '';
473 - }
474 -
475 560 $secret = array();
476 561 for ( $i = 0; $i < $length; $i++ ) {
477 562 $secret[] = $strings[ Crypt::random_int( 0, strlen( $strings ) - 1 ) ];
478 563 }
@@ -523,9 +608,9 @@
523 608 * @var Translation_Entry $value
524 609 */
525 610 foreach ( $l10n['defender-security']->entries as $value ) {
526 611 // If there's a translation, use it; otherwise, use the original word/phrase.
527 - $items[ $value->key() ] = empty( $value->translations ) ? $value->key() : $value->translations[0];
612 + $items[ $value->key() ] = isset( $value->translations[0] ) ? $value->translations[0] : $value->key();
528 613 }
529 614
530 615 // Return the list of words/phrases and their translations.
531 616 return $items;
@@ -574,9 +659,9 @@
574 659 */
575 660 function defender_get_user_agent( $default_string = '' ) {
576 661 $user_agent = defender_get_data_from_request( 'HTTP_USER_AGENT', 's' );
577 662
578 - return ! empty( $user_agent ) ? User_Agent::fast_cleaning( $user_agent ) : $default_string;
663 + return '' !== $user_agent ? User_Agent::fast_cleaning( $user_agent ) : $default_string;
579 664 }
580 665
581 666 /**
582 667 * Check if it is a CLI request.
@@ -597,9 +682,9 @@
597 682 * @since 4.2.0
598 683 */
599 684 function defender_is_rest_api_request(): bool {
600 685 $request_uri = Request::get_request_uri();
601 - if ( empty( $request_uri ) ) {
686 + if ( '' === $request_uri ) {
602 687 return false;
603 688 }
604 689
605 690 $rest_prefix = trailingslashit( rest_get_url_prefix() );
@@ -606,43 +691,8 @@
606 691
607 692 return false !== strpos( $request_uri, $rest_prefix );
608 693 }
609 694
610 -/**
611 - * Handle deprecated functions by logging or triggering actions.
612 - * This function is a wrapper for WordPress's _deprecated_function() function.
613 - * It is used to handle deprecated functions by either logging a deprecation
614 - * message or triggering an action. It checks if the current request is an AJAX
615 - * request or a REST API request and acts accordingly.
616 - *
617 - * @param string $function_name The function that was called.
618 - * @param string $version The version number that deprecated the function.
619 - * @param string $replacement (Optional) The function that should be used instead.
620 - *
621 - * @return void
622 - * @since 4.2.0
623 - */
624 -function defender_deprecated_function( string $function_name, string $version, string $replacement = '' ): void {
625 - /**
626 - * Filters whether to trigger an error for deprecated functions.
627 - *
628 - * @param bool $trigger Whether to trigger the error for deprecated functions. Default false.
629 - *
630 - * @since 4.2.1
631 - */
632 - if ( WP_DEBUG && apply_filters( 'defender_deprecated_function_trigger_error', false ) ) {
633 - if ( wp_doing_ajax() || defender_is_rest_api_request() ) {
634 - do_action( 'deprecated_function_run', $function_name, $replacement, $version );
635 -
636 - $log_string = "Function {$function_name} is deprecated since version {$version}!";
637 - $log_string .= $replacement ? " Use {$replacement} instead." : '';
638 - wp_die( esc_html( $log_string ) );
639 - } else {
640 - _deprecated_function( esc_html( $function_name ), esc_html( $version ), esc_html( $replacement ) );
641 - }
642 - }
643 -}
644 -
645 695 if ( ! function_exists( 'defender_get_data_from_request' ) ) {
646 696 /**
647 697 * Retrieves the value of a specific server data key after sanitizing it.
648 698 *
@@ -660,9 +710,9 @@
660 710 string $nonce_action = ''
661 711 ) {
662 712 if ( in_array( $source, array( 'r', 'p', 'g' ), true ) ) {
663 713 if (
664 - ! empty( $nonce_key ) && ! wp_verify_nonce(
714 + '' !== $nonce_key && ! wp_verify_nonce(
665 715 sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_key ] ?? '' ) ),
666 716 $nonce_action
667 717 )
668 718 ) {
@@ -692,9 +742,9 @@
692 742 $data = array();
693 743 break;
694 744 }
695 745
696 - if ( empty( $key ) ) {
746 + if ( null === $key || '' === $key ) {
697 747 return $data;
698 748 } elseif ( 's' === $source ) {
699 749 return sanitize_text_field( wp_unslash( $data[ $key ] ?? '' ) );
700 750 } elseif ( 'data' === $key ) {
@@ -699,9 +749,9 @@
699 749 return sanitize_text_field( wp_unslash( $data[ $key ] ?? '' ) );
700 750 } elseif ( 'data' === $key ) {
701 751 return json_decode( sanitize_text_field( wp_unslash( $data[ $key ] ?? '' ) ), true );
702 752 } elseif ( 'f' === $source && 'file' === $key && isset( $data[ $key ] ) ) {
703 - if ( ! empty( $data[ $key ]['name'] ) ) {
753 + if ( isset( $data[ $key ]['name'] ) && '' !== $data[ $key ]['name'] ) {
704 754 $data[ $key ]['name'] = sanitize_file_name( $data[ $key ]['name'] );
705 755 }
706 756
707 757 return $data[ $key ];
@@ -748,8 +798,17 @@
748 798 return '';
749 799 }
750 800
751 801 /**
802 + * Is a site is from WPMU DEV unlimited hosting?
803 + *
804 + * @return bool
805 + */
806 +function defender_is_unlimited_hosting(): bool {
807 + return defined( 'WPMUDEV_HOSTING_WEBSITE_ID' ) && '' !== WPMUDEV_HOSTING_WEBSITE_ID;
808 +}
809 +
810 +/**
752 811 * Get an internal log file name.
753 812 *
754 813 * @return string
755 814 */
@@ -761,9 +820,9 @@
761 820 * Retrieves the current time, allowing overrides for testing.
762 821 *
763 822 * @return int The current timestamp.
764 823 */
765 -function defender_get_current_time() {
824 +function defender_get_current_time(): int {
766 825 /**
767 826 * Filter the current time.
768 827 *
769 828 * @since 5.2.0
@@ -771,9 +830,10 @@
771 830 * @param int $time The current timestamp.
772 831 *
773 832 * @return int The current/filtered timestamp.
774 833 */
775 - return (int) apply_filters( 'wpdef_current_time', time() );
834 + $current_time = apply_filters( 'wpdef_current_time', time() );
835 + return ! is_int( $current_time ) ? (int) $current_time : $current_time;
776 836 }
777 837
778 838 /**
779 839 * Get the current site domain.
@@ -797,9 +857,10 @@
797 857 * @return string The filtered domain name.
798 858 *
799 859 * @since 5.2.0
800 860 */
801 - $domain = (string) apply_filters( 'wpdef_current_site_domain', $domain );
861 + $domain = apply_filters( 'wpdef_current_site_domain', $domain );
862 + $domain = is_string( $domain ) ? $domain : (string) $domain;
802 863
803 864 return esc_html( $domain );
804 865 }
805 866
@@ -805,9 +866,9 @@
805 866
806 867 /**
807 868 * WP_DEFENDER_PRO sometimes doesn't match WPMUDEV::is_pro().
808 869 *
809 - * @return bool.
870 + * @return bool
810 871 */
811 872 function defender_is_wp_org_version(): bool {
812 873 return ! wd_di()->get( WPMUDEV::class )->is_pro()
813 874 && ( defined( 'WP_DEFENDER_PRO' ) && ! WP_DEFENDER_PRO );