[ 'script' => 'https://www.google.com/recaptcha/api.js', 'class' => 'g-recaptcha', 'response' => 'g-recaptcha-response', 'verify' => 'https://www.google.com/recaptcha/api/siteverify', ], 'hcaptcha' => [ 'script' => 'https://js.hcaptcha.com/1/api.js', 'class' => 'h-captcha', 'response' => 'h-captcha-response', 'verify' => 'https://hcaptcha.com/siteverify', ], 'turnstile' => [ 'script' => 'https://challenges.cloudflare.com/turnstile/v0/api.js', 'class' => 'cf-turnstile', 'response' => 'cf-turnstile-response', 'verify' => 'https://challenges.cloudflare.com/turnstile/v0/siteverify', ], ]; } /** * Currently selected provider slug, or '' when disabled/unconfigured. * * @return string */ public static function active_provider() { $provider = Plugin::get_option( 'captcha_provider', '' ); $site_key = Plugin::get_option( 'captcha_site_key', '' ); $secret = Plugin::get_option( 'captcha_secret_key', '' ); $providers = self::providers(); if ( ! isset( $providers[ $provider ] ) || '' === $site_key || '' === $secret ) { return ''; } return $provider; } /** * Whether a captcha is active. * * @return bool */ public static function is_active() { return '' !== self::active_provider(); } /** * Enqueue the provider's widget script. */ public static function enqueue() { $provider = self::active_provider(); if ( '' === $provider ) { return; } $providers = self::providers(); wp_enqueue_script( 'phemightforms-captcha', $providers[ $provider ]['script'], [], null, true ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion,WordPress.WP.EnqueuedResourceParameters.NoExplicitVersion } /** * Widget markup to place inside the form. * * @return string */ public static function widget() { $provider = self::active_provider(); if ( '' === $provider ) { return ''; } $providers = self::providers(); $site_key = Plugin::get_option( 'captcha_site_key', '' ); return sprintf( '
', esc_attr( $providers[ $provider ]['class'] ), esc_attr( $site_key ) ); } /** * Verify the captcha token from the current request. * * @return bool True when valid or when no captcha is active. */ public static function verify() { $provider = self::active_provider(); if ( '' === $provider ) { return true; } $providers = self::providers(); $field = $providers[ $provider ]['response']; $token = isset( $_POST[ $field ] ) ? sanitize_text_field( wp_unslash( $_POST[ $field ] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing if ( '' === $token ) { return false; } $response = wp_remote_post( $providers[ $provider ]['verify'], [ 'timeout' => 8, 'body' => [ 'secret' => Plugin::get_option( 'captcha_secret_key', '' ), 'response' => $token, 'remoteip' => isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '', ], ] ); if ( is_wp_error( $response ) ) { return false; } $body = json_decode( wp_remote_retrieve_body( $response ), true ); return ! empty( $body['success'] ); } }