diff --git a/includes/sources/class-cf7-source.php b/includes/sources/class-cf7-source.php new file mode 100644 index 0000000..79dbe8d --- /dev/null +++ b/includes/sources/class-cf7-source.php @@ -0,0 +1,94 @@ +enqueue_from_submission($submission, 'Honeypot or filter'); + } + return (bool)$spam; + } + + public function on_submission($submission): void + { + if (!is_object($submission) || !method_exists($submission, 'get_status')) return; + if ($submission->get_status() !== 'spam') return; + $this->enqueue_from_submission($submission, 'Статус spam'); + } + + private function enqueue_from_submission($submission, string $fallback_reason): void + { + $fields = method_exists($submission, 'get_posted_data') ? (array)$submission->get_posted_data() : []; + $form = method_exists($submission, 'get_contact_form') ? $submission->get_contact_form() : null; + $form_title = $form && method_exists($form, 'title') ? $form->title() : ''; + $form_id = $form && method_exists($form, 'id') ? (int)$form->id() : null; + + $reason = $this->detect_reason($submission, $fallback_reason); + $classification = Classifier::classify($fields, ['reason' => $reason]); + + $post_id = FlamingoHelper::find_post_id_for_submission($submission); + if ($post_id !== null && Queue::exists_for_flamingo($post_id, false)) { + return; + } + + $ip = $this->remote_addr(); + $ua = isset($_SERVER['HTTP_USER_AGENT']) ? (string)$_SERVER['HTTP_USER_AGENT'] : ''; + + $payload = MessageFormatter::build([ + 'fields' => $fields, + 'classification' => $classification, + 'site_title' => Settings::get_site_title(), + 'form_title' => $form_title, + 'submitted_at' => wp_date('d.m.Y H:i'), + 'reason' => $reason, + 'ip' => $ip, + 'user_agent' => $ua, + 'is_retro' => false, + ]); + + Queue::enqueue([ + 'flamingo_post_id' => $post_id, + 'form_id' => $form_id, + 'source_key' => 'cf7', + 'payload_json' => wp_json_encode($payload), + 'label' => $classification['label'], + 'is_retro' => 0, + ]); + } + + private function detect_reason($submission, string $fallback): string + { + $data = method_exists($submission, 'get_posted_data') ? (array)$submission->get_posted_data() : []; + // Honeypot plugin by Nocean adds a non-empty field usually prefixed by 'wpcf7_hp' or a custom name. + foreach ($data as $k => $v) { + if (is_string($k) && (stripos($k, 'honeypot') !== false || stripos($k, 'wpcf7_hp') !== false) && !empty($v)) { + return 'Honeypot'; + } + } + if (method_exists($submission, 'get_spam_log') && $submission->get_spam_log()) { + return 'Akismet'; + } + return $fallback; + } + + private function remote_addr(): string + { + foreach (['HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR'] as $key) { + if (!empty($_SERVER[$key])) { + $first = explode(',', (string)$_SERVER[$key])[0]; + return trim($first); + } + } + return ''; + } +} diff --git a/includes/sources/interface-spam-source.php b/includes/sources/interface-spam-source.php new file mode 100644 index 0000000..2a642d9 --- /dev/null +++ b/includes/sources/interface-spam-source.php @@ -0,0 +1,9 @@ +