'DB connection failed']); exit; } pg_query($db, "SET search_path TO admin, affiliate, public"); $action = $_GET['action'] ?? 'status'; $offer_id = intval($_GET['offer_id'] ?? 0); switch ($action) { case 'import_csv': if (!$offer_id) { echo json_encode(['error'=>'offer_id required']); exit; } // Accept CSV from POST body or file upload $csv = ''; if (!empty($_FILES['file']['tmp_name'])) { $csv = file_get_contents($_FILES['file']['tmp_name']); } else { $csv = file_get_contents('php://input'); } if (!$csv) { echo json_encode(['error'=>'No CSV data']); exit; } $lines = preg_split('/[ ]+/', trim($csv)); $imported = 0; $skipped = 0; $invalid = 0; pg_query($db, "BEGIN"); $stmt = pg_prepare($db, "ins_supp", "INSERT INTO admin.offer_suppression(offer_id, email, reason) VALUES($1, $2, 'sponsor_list') ON CONFLICT(offer_id, email) DO NOTHING"); foreach ($lines as $line) { $email = strtolower(trim($line)); // Skip headers, empty lines if (!$email || strpos($email, '@') === false || $email === 'email') { $skipped++; continue; } // Basic email validation if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { $invalid++; continue; } $res = pg_execute($db, "ins_supp", [$offer_id, $email]); if ($res && pg_affected_rows($res) > 0) $imported++; else $skipped++; } pg_query($db, "COMMIT"); echo json_encode(['success'=>true, 'offer_id'=>$offer_id, 'imported'=>$imported, 'skipped'=>$skipped, 'invalid'=>$invalid, 'total_lines'=>count($lines)]); break; case 'add': if (!$offer_id) { echo json_encode(['error'=>'offer_id required']); exit; } $email = strtolower(trim($_GET['email'] ?? '')); if (!$email || !filter_var($email, FILTER_VALIDATE_EMAIL)) { echo json_encode(['error'=>'valid email required']); exit; } $res = pg_query_params($db, "INSERT INTO admin.offer_suppression(offer_id, email, reason) VALUES($1, $2, 'sponsor_list') ON CONFLICT(offer_id, email) DO NOTHING", [$offer_id, $email]); echo json_encode(['success'=>true, 'offer_id'=>$offer_id, 'email'=>$email, 'added'=>pg_affected_rows($res) > 0]); break; case 'add_bulk': if (!$offer_id) { echo json_encode(['error'=>'offer_id required']); exit; } $body = json_decode(file_get_contents('php://input'), true); $emails = $body['emails'] ?? []; if (!$emails) { echo json_encode(['error'=>'emails array required']); exit; } pg_query($db, "BEGIN"); $stmt = pg_prepare($db, "ins_bulk", "INSERT INTO admin.offer_suppression(offer_id, email, reason) VALUES($1, $2, 'sponsor_list') ON CONFLICT(offer_id, email) DO NOTHING"); $imported = 0; foreach ($emails as $e) { $e = strtolower(trim($e)); if ($e && filter_var($e, FILTER_VALIDATE_EMAIL)) { $res = pg_execute($db, "ins_bulk", [$offer_id, $e]); if ($res && pg_affected_rows($res) > 0) $imported++; } } pg_query($db, "COMMIT"); echo json_encode(['success'=>true, 'offer_id'=>$offer_id, 'imported'=>$imported, 'total'=>count($emails)]); break; case 'count': if ($offer_id) { $res = pg_query_params($db, "SELECT COUNT(*) as cnt FROM admin.offer_suppression WHERE offer_id=$1", [$offer_id]); } else { $res = pg_query($db, "SELECT offer_id, COUNT(*) as cnt FROM admin.offer_suppression GROUP BY 1 ORDER BY 2 DESC"); } $rows = []; while ($r = pg_fetch_assoc($res)) $rows[] = $r; echo json_encode(['suppression_counts'=>$rows]); break; case 'check': if (!$offer_id) { echo json_encode(['error'=>'offer_id required']); exit; } $email = strtolower(trim($_GET['email'] ?? '')); $res = pg_query_params($db, "SELECT 1 FROM admin.offer_suppression WHERE offer_id=$1 AND email=$2", [$offer_id, $email]); $suppressed = ($res && pg_num_rows($res) > 0); // Also check global $gres = pg_query_params($db, "SELECT 1 FROM admin.global_suppression WHERE email=$1", [$email]); $global_suppressed = ($gres && pg_num_rows($gres) > 0); echo json_encode(['email'=>$email, 'offer_id'=>$offer_id, 'offer_suppressed'=>$suppressed, 'global_suppressed'=>$global_suppressed]); break; case 'clear': if (!$offer_id) { echo json_encode(['error'=>'offer_id required']); exit; } $res = pg_query_params($db, "DELETE FROM admin.offer_suppression WHERE offer_id=$1", [$offer_id]); echo json_encode(['success'=>true, 'offer_id'=>$offer_id, 'deleted'=>pg_affected_rows($res)]); break; case 'status': default: $total = pg_fetch_assoc(pg_query($db, "SELECT COUNT(*) as c FROM admin.offer_suppression"))['c']; $global = pg_fetch_assoc(pg_query($db, "SELECT COUNT(*) as c FROM admin.global_suppression"))['c']; $by_offer = []; $res = pg_query($db, "SELECT os.offer_id, o.name, COUNT(*) as cnt FROM admin.offer_suppression os LEFT JOIN affiliate.offers o ON o.id = os.offer_id GROUP BY 1,2 ORDER BY 3 DESC LIMIT 20"); while ($r = pg_fetch_assoc($res)) $by_offer[] = $r; echo json_encode([ 'total_offer_suppressed' => intval($total), 'total_global_suppressed' => intval($global), 'by_offer' => $by_offer, 'note' => 'Import via: POST /api/suppression-import.php?action=import_csv&offer_id=X with CSV body' ]); break; } pg_close($db);