esc_html__( 'reCAPTCHA verification failed. Please try again.', 'defender-security' ), 'turnstile_message' => esc_html__( 'Turnstile verification failed. Please try again.', 'defender-security' ), ); } /** * Load default values. * * @return void */ protected function before_load(): void { $default_values = $this->get_default_values(); $this->provider = 'recaptcha'; $this->message = $default_values['message']; $this->language = 'automatic'; $this->data_v2_checkbox = array( 'key' => '', 'secret' => '', 'size' => 'normal', 'style' => 'light', ); $this->data_v2_invisible = array( 'key' => '', 'secret' => '', ); $this->data_v3_recaptcha = array( 'key' => '', 'secret' => '', 'threshold' => '0.5', ); $this->data_turnstile = array( 'key' => '', 'secret' => '', 'size' => 'normal', 'style' => 'auto', 'message' => $default_values['turnstile_message'], 'language' => 'auto', ); } /** * Checks if the given Captcha type is valid and has all the necessary data. * * @param string $active_type The Captcha type to check. * * @return bool Returns true if the Captcha type is valid and has all the necessary data, false otherwise. */ private function check_captcha_type( string $active_type ): bool { if ( 'v2_checkbox' === $active_type && '' !== $this->data_v2_checkbox['key'] && '' !== $this->data_v2_checkbox['secret'] ) { return true; } elseif ( 'v2_invisible' === $active_type && '' !== $this->data_v2_invisible['key'] && '' !== $this->data_v2_invisible['secret'] ) { return true; } elseif ( 'v3_recaptcha' === $active_type && '' !== $this->data_v3_recaptcha['key'] && '' !== $this->data_v3_recaptcha['secret'] ) { return true; } elseif ( 'turnstile' === $active_type && '' !== $this->data_turnstile['key'] && '' !== $this->data_turnstile['secret'] ) { return true; } else { return false; } } /** * Checks if the CAPTCHA is active. * * @return bool Returns true if the CAPTCHA is active, false otherwise. */ public function is_active(): bool { $hook_name = 'turnstile' === $this->active_type ? 'wd_turnstile_enable' : 'wd_recaptcha_enable'; return (bool) apply_filters( $hook_name, $this->enabled && '' !== $this->active_type && '' !== $this->language // For each Captcha type. && $this->check_captcha_type( $this->active_type ) ); } /** * Is activated any default location? * * @return bool */ public function enable_default_location(): bool { return array() !== $this->locations; } /** * Level#2 check by any activated location. Only if the plugin is enabled. * * @return bool */ public function enable_woo_location(): bool { return $this->detect_woo && array() !== $this->woo_checked_locations; } /** * Level#2 check by deactivated locations. Only if the plugin is enabled. * * @return bool */ public function is_unchecked_woo_locations(): bool { return $this->detect_woo && array() === $this->woo_checked_locations; } /** * Level#1 check. If the plugin is disabled, there is no point further. * * @param bool $is_woo_activated Whether WooCommerce is activated or not. * * @return bool */ public function check_woo_locations( $is_woo_activated ): bool { if ( ! $is_woo_activated ) { return false; } return $this->enable_woo_location(); } /** * Level#2 check by any activated location. Only if the plugin is enabled. * * @return bool */ public function enable_buddypress_location(): bool { return $this->detect_buddypress && array() !== $this->buddypress_checked_locations; } /** * Level#2 check by deactivated locations. Only if the plugin is enabled. * * @return bool */ public function is_unchecked_buddypress_locations(): bool { return $this->detect_buddypress && array() === $this->buddypress_checked_locations; } /** * Level#1 Checks if the BuddyPress locations are valid and have all the necessary data. * * @param bool $is_buddypress_activated Whether BuddyPress is activated or not. * * @return bool Returns true if the BuddyPress locations are valid and have all the necessary data, false otherwise. */ public function check_buddypress_locations( $is_buddypress_activated ): bool { if ( ! $is_buddypress_activated ) { return false; } return $this->enable_buddypress_location(); } /** * Define settings labels. * * @return array */ public function labels(): array { return array( 'enabled' => self::get_module_name(), 'active_type' => esc_html__( 'Configure CAPTCHA', 'defender-security' ), 'v2_checkbox' => esc_html__( 'V2 Checkbox', 'defender-security' ), 'v2_invisible' => esc_html__( 'V2 Invisible', 'defender-security' ), 'v3_recaptcha' => esc_html__( 'reCAPTCHA V3', 'defender-security' ), 'language' => esc_html__( 'Language', 'defender-security' ), 'message' => esc_html__( 'Error Message', 'defender-security' ), 'locations' => esc_html__( 'CAPTCHA Locations', 'defender-security' ), 'detect_woo' => esc_html__( 'WooCommerce', 'defender-security' ), 'detect_buddypress' => esc_html__( 'BuddyPress', 'defender-security' ), 'disable_for_known_users' => esc_html__( 'Disable for logged in users', 'defender-security' ), ); } /** * Validates the form after submission. * * @return void */ protected function after_validate(): void { // Case with multi errors. if ( $this->is_unchecked_woo_locations() && $this->is_unchecked_buddypress_locations() ) { // The text of the notation is only in the first key, but we add the number of keys depending on the disabled locations of the plugins. $this->errors['enable_woo'] = esc_html__( 'You have enabled reCaptcha for more than one plugin. Please select at least one form location for each plugin and click Save Changes again.', 'defender-security' ); $this->errors['enable_buddypress'] = ''; } else { // Individual cases with plugins. if ( $this->is_unchecked_woo_locations() ) { $this->errors['enable_woo'] = esc_html__( 'reCAPTCHA for WooCommerce is enabled, but no WooCommerce forms are selected. Please select at least one WooCommerce form location and then click Save Changes again.', 'defender-security' ); } if ( $this->is_unchecked_buddypress_locations() ) { $this->errors['enable_buddypress'] = esc_html__( 'reCAPTCHA for BuddyPress is enabled, but no BuddyPress forms are selected. Please select at least one BuddyPress form location and then click Save Changes again.', 'defender-security' ); } } } /** * Disable for logged in users or enable. * * @return bool */ public function display_for_known_users(): bool { return ! ( $this->disable_for_known_users && is_user_logged_in() ); } /** * Get module name. * * @return string */ public static function get_module_name(): string { return esc_html__( 'CAPTCHA', 'defender-security' ); } }