PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 5.4.0
Defender Security – Malware Scanner, Login Security & Firewall v5.4.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
defender-security / src / component / class-recaptcha.php

class-recaptcha.php in Defender Security – Malware Scanner, Login Security & Firewall 5.4.0, at src/component/class-recaptcha.php

169 lines 4.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Handles reCAPTCHA functionality.
4 *
5 * @package WP_Defender\Component
6 */
7
8 namespace WP_Defender\Component;
9
10 use Calotes\Base\Component;
11 use WP_Defender\Model\Setting\Recaptcha as Recaptcha_Model;
12
13 /**
14 * Provides methods to handle Google reCAPTCHA integration, including rendering,
15 * validation, and script management.
16 */
17 class Recaptcha extends Component {
18
19 /**
20 * Default form identifiers for reCAPTCHA integration.
21 */
22 public const DEFAULT_LOGIN_FORM = 'login',
23 DEFAULT_REGISTER_FORM = 'register',
24 DEFAULT_LOST_PASSWORD_FORM = 'lost_password',
25 DEFAULT_COMMENT_FORM = 'comments';
26
27 /**
28 * The reCAPTCHA settings model.
29 *
30 * @var Recaptcha_Model
31 */
32 protected $model;
33
34 /**
35 * Recaptcha constructor.
36 *
37 * @param Recaptcha_Model $model The reCAPTCHA settings model.
38 */
39 public function __construct( Recaptcha_Model $model ) {
40 $this->model = $model;
41 }
42
43 /**
44 * Determines if any reCAPTCHA location is enabled.
45 *
46 * @param bool $exist_woo Whether WooCommerce is active.
47 * @param bool $exist_bp Whether BuddyPress is active.
48 *
49 * @return bool True if any location is enabled, false otherwise.
50 */
51 public function enable_any_location( $exist_woo, $exist_bp ): bool {
52 return $this->model->enable_default_location()
53 || $this->model->check_woo_locations( $exist_woo )
54 || $this->model->check_buddypress_locations( $exist_bp );
55 }
56
57 /**
58 * Excludes reCAPTCHA for specific requests.
59 *
60 * @return bool True if the current request is excluded, false otherwise.
61 */
62 public function exclude_recaptcha_for_requests(): bool {
63 $current_request = defender_get_data_from_request( 'REQUEST_URI', 's' ) ?? '/';
64 $excluded_requests = (array) apply_filters( 'wd_recaptcha_excluded_requests', array() );
65
66 return in_array( $current_request, $excluded_requests, true );
67 }
68
69 /**
70 * Removes duplicate reCAPTCHA scripts.
71 *
72 * @return bool|void False if no scripts are registered, or void otherwise.
73 */
74 public function remove_dublicate_scripts() {
75 global $wp_scripts;
76
77 if ( ! is_object( $wp_scripts ) || empty( $wp_scripts ) ) {
78 return false;
79 }
80 /**
81 * Exclude scripts from Defender and Forminator to display reCAPTCHA.
82 *
83 * @since 5.1.0
84 */
85 $excluded_handles = (array) apply_filters(
86 'wd_recaptcha_excluded_handles',
87 array(
88 'wpdef_recaptcha_api',
89 'forminator-google-recaptcha',
90 )
91 );
92 foreach ( $wp_scripts->registered as $script_name => $args ) {
93 if ( is_string( $args->src ) && preg_match( '|google\.com/recaptcha/api\.js|', $args->src )
94 && ! in_array( $script_name, $excluded_handles, true )
95 ) {
96 wp_dequeue_script( $script_name );
97 }
98 }
99 }
100
101 /**
102 * Returns a custom error message for reCAPTCHA validation failure.
103 *
104 * @return string The formatted error message.
105 */
106 public function error_message(): string {
107 $default_values = $this->model->get_default_values();
108
109 return sprintf(
110 '<strong>%s:</strong> %s',
111 esc_html__( 'Error', 'defender-security' ),
112 empty( $this->model->message ) ? $default_values['message'] : $this->model->message
113 );
114 }
115
116 /**
117 * Sends an HTTP POST request to the Google reCAPTCHA API and returns the validation result.
118 *
119 * @param array $post_body The POST request body.
120 *
121 * @return bool True if the reCAPTCHA validation is successful, false otherwise.
122 */
123 public function recaptcha_post_request( array $post_body ): bool {
124 $args = array(
125 'body' => $post_body,
126 'sslverify' => false,
127 );
128 $url = 'https://www.google.com/recaptcha/api/siteverify';
129 $request = wp_remote_post( $url, $args );
130
131 if ( is_wp_error( $request ) ) {
132 return false;
133 }
134
135 $response_body = wp_remote_retrieve_body( $request );
136 $response_keys = json_decode( $response_body, true );
137 if ( 'v3_recaptcha' === $this->model->active_type ) {
138 if (
139 $response_keys['success']
140 && isset( $this->model->data_v3_recaptcha['threshold'], $response_keys['score'] )
141 && is_numeric( $this->model->data_v3_recaptcha['threshold'] )
142 && is_numeric( $response_keys['score'] )
143 ) {
144 $is_success = $response_keys['score'] >= (float) $this->model->data_v3_recaptcha['threshold'];
145 } else {
146 $is_success = false;
147 }
148 } else {
149 $is_success = (bool) $response_keys['success'];
150 }
151
152 return $is_success;
153 }
154
155 /**
156 * Retrieves the list of default forms where reCAPTCHA can be integrated.
157 *
158 * @return array An associative array of form identifiers and their display names.
159 */
160 public static function get_forms(): array {
161 return array(
162 self::DEFAULT_LOGIN_FORM => esc_html__( 'Login', 'defender-security' ),
163 self::DEFAULT_REGISTER_FORM => esc_html__( 'Register', 'defender-security' ),
164 self::DEFAULT_LOST_PASSWORD_FORM => esc_html__( 'Lost Password', 'defender-security' ),
165 self::DEFAULT_COMMENT_FORM => esc_html__( 'Comments', 'defender-security' ),
166 );
167 }
168 }
169