= NOW() - INTERVAL :days DAY) AS email_hits, (SELECT COUNT(*) FROM submission_logs WHERE phone = :phone AND created_at >= NOW() - INTERVAL :days DAY) AS phone_hits, (SELECT COUNT(*) FROM submission_logs WHERE ip_address = :ip AND created_at >= NOW() - INTERVAL :days DAY) AS ip_hits, (SELECT COUNT(*) FROM submission_logs WHERE ip_address = :ip AND created_at >= NOW() - INTERVAL 1 HOUR) AS ip_hourly "; $stmt = $pdo->prepare($query); $stmt->bindValue(':email', $email); $stmt->bindValue(':phone', $phone); $stmt->bindValue(':ip', $ip); $stmt->bindValue(':days', self::LOOKBACK_DAYS, PDO::PARAM_INT); $stmt->execute(); $data = $stmt->fetch(PDO::FETCH_ASSOC); $emailHits = (int)($data['email_hits'] ?? 0); $phoneHits = (int)($data['phone_hits'] ?? 0); $ipHits = (int)($data['ip_hits'] ?? 0); $ipHourly = (int)($data['ip_hourly'] ?? 0); $totalScore = $emailHits + $phoneHits + $ipHits; if ($emailHits >= 4 || $phoneHits >= 4 || $ipHits >= 5) { return ['action' => 'block', 'reason' => 'IP/email/phone threshold exceeded', 'count' => $totalScore]; } if ($ipHourly >= 3) { return ['action' => 'flag', 'reason' => 'Multiple submissions from IP in last hour', 'count' => $ipHourly]; } if ($totalScore >= 6) { return ['action' => 'notify', 'reason' => 'Cumulative signal from all identifiers', 'count' => $totalScore]; } if ($emailHits >= 2 || $phoneHits >= 2 || $ipHits >= 2) { return ['action' => 'flag', 'reason' => 'Repeated pattern detected', 'count' => $totalScore]; } return ['action' => 'accept', 'reason' => 'accepted', 'count' => $totalScore]; } catch (\Throwable $e) { Logger::error("SubmissionCheck evaluation failed: " . $e->getMessage()); return ['action' => 'error', 'reason' => 'Evaluation error', 'count' => 0]; } } }