service_name = 'cloudflare'; $this->title = 'Cloudflare'; $this->icon = 'cloud'; $this->defineFields(); $this->defineInstructions(); parent::__construct(); } protected function defineFields():void { $site_key = $this->addField('site_key', 'Site Key', 'text', 'manage_options'); $site_key->setRequired(); $site_key->setHint('Public key for Turnstile Widget'); $secret_key = $this->addField('secret_key', 'Secret Key', 'text', 'manage_options'); $secret_key->setRequired(); $secret_key->setSubType('password'); $secret_key->setHint('Secret key for server-side verification of Turnstile Widget'); } protected function defineInstructions():void { $this->instructions = [ 'Go to Cloudflare Dashboard', 'Create a new Turnstile widget', 'Add your domain to the widget settings', 'Copy the Site Key and Secret Key' ]; } protected function initialize(): void { // TODO: Implement initialize() method. } public function getServiceDescription():string { return "Add Turnstile captcha protection to your forms and login pages to prevent spam and bot submissions."; } public function performConnectionTest(): bool { $credentials = $this->loadCredentials(); if (!array_key_exists('site_key', $credentials) || !array_key_exists('secret_key', $credentials)) { return false; } // Test with a dummy token to verify API connectivity $response = wp_remote_post('https://challenges.cloudflare.com/turnstile/v0/siteverify', [ 'body' => [ 'secret' => $credentials['secret_key'], 'response' => 'test-token-connection-check' ], 'timeout' => 10 ]); // We expect this to fail with success:false, but not with a connection error if (is_wp_error($response)) { return false; } $result = json_decode(wp_remote_retrieve_body($response), true); // If we get a response with success field (even if false), connection works return array_key_exists('success', $result); } /** * Enqueue Turnstile script */ public function enqueueTurnstileScripts(): void { wp_enqueue_script( 'cloudflare-turnstile', 'https://challenges.cloudflare.com/turnstile/v0/api.js', [], null, true ); wp_script_add_data('cloudflare-turnstile', 'async', true); wp_script_add_data('cloudflare-turnstile', 'defer', true); } /** * Render Turnstile widget * Can be called directly: jvbConnect('cloudflare')->renderTurnstile() * Or Cloudflare::getInstance()->renderTurnstile() */ public function renderTurnstile(array|string $options = []): void { if (!$this->isSetUp()) { return; } if (!is_array($options)) { $options = []; } $defaults = [ 'theme' => $this->theme, 'size' => $this->size, 'wrapper_class' => 'cf-turnstile-wrapper', 'wrapper_style' => 'margin: 1em 0;' ]; $cred = $this->loadCredentials(); $options = wp_parse_args($options, $defaults); echo sprintf( '