$request_id, 'site_id' => $config['site_id'], 'form_ref' => $form_ref, 'delivery_protocol' => 'receipt_v1', 'payload' => ['text_fields' => $fields], ]); if (!is_string($body) || strlen($body) > 65536) { return null; } $timestamp = (string) time(); $path = '/v1/decisions'; $signature = hash_hmac('sha256', implode("\n", ['POST', $path, $timestamp, $request_id, hash('sha256', $body)]), $config['secret']); $response = wp_remote_post(rtrim($origin, '/') . $path, [ 'timeout' => 5, 'redirection' => 0, 'headers' => [ 'Content-Type' => 'application/json', 'X-FormGuard-Key-Id' => $config['key_id'], 'X-FormGuard-Timestamp' => $timestamp, 'X-FormGuard-Signature' => $signature, ], 'body' => $body, 'limit_response_size' => 16384, ]); if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) { update_option('formguard_status', ['state' => 'degraded', 'at' => time()], false); return null; // Continue the existing form flow on infrastructure failure. } $result = json_decode(wp_remote_retrieve_body($response), true); if (!is_array($result) || ($result['request_id'] ?? '') !== $request_id || !in_array($result['decision']['action'] ?? '', ['allow', 'block', 'review'], true)) { return null; } // Review can only hold a submission that was durably captured. if ($result['decision']['action'] === 'review' && ($result['capture']['status'] ?? '') !== 'stored') { return null; } update_option('formguard_status', ['state' => $result['enforcement']['status'] ?? 'unknown', 'at' => time()], false); return $result; } } require_once __DIR__ . '/includes/fluentforms.php'; require_once __DIR__ . '/includes/forminator.php'; require_once __DIR__ . '/includes/forms.php'; require_once __DIR__ . '/includes/releases.php'; require_once __DIR__ . '/includes/receipts.php'; require_once __DIR__ . '/includes/settings.php'; FormGuard_Settings::register(); // Enable only after a successful connection or an explicit development opt-in. // WordPress returns persisted boolean options as "1"/"" on later requests. if ((defined('FORMGUARD_ENABLE_ADAPTERS') && FORMGUARD_ENABLE_ADAPTERS === true) || (bool) get_option('formguard_enabled', false)) { FormGuard_Forms::register(); FormGuard_Releases::register(); FormGuard_Receipts::register(); } register_deactivation_hook(__FILE__, static function (): void { wp_clear_scheduled_hook('formguard_release_poll'); });