getConnection(); if (!file_exists($csvPath)) { throw new \Exception("Arquivo CSV não encontrado."); } $handle = fopen($csvPath, "r"); if ($handle === FALSE) { throw new \Exception("Erro ao abrir arquivo CSV."); } $domains = []; while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $raw = trim($data[0] ?? ''); if (empty($raw)) continue; $domain = $this->cleanDomain($raw); if ($domain) { $domains[] = $domain; } } fclose($handle); $domains = array_unique($domains); // Remove duplicates in batch $conn->beginTransaction(); try { $stmtCheck = $conn->prepare("SELECT id FROM domains WHERE name = :name"); $stmtInsertDomain = $conn->prepare("INSERT INTO domains (name, status, last_order_id) VALUES (:name, :status, :order_id)"); $stmtUpdateDomain = $conn->prepare("UPDATE domains SET status = :status, last_order_id = :order_id WHERE id = :id"); $stmtInsertItem = $conn->prepare("INSERT INTO order_items (order_id, domain_id, action) VALUES (:order_id, :domain_id, :action)"); $status = ($type === 'block') ? 'blocked' : 'unblocked'; foreach ($domains as $domainName) { // Check if exists $stmtCheck->execute(['name' => $domainName]); $existing = $stmtCheck->fetch(); $domainId = null; if ($existing) { $domainId = $existing['id']; $stmtUpdateDomain->execute([ 'status' => $status, 'order_id' => $orderId, 'id' => $domainId ]); } else { $stmtInsertDomain->execute([ 'name' => $domainName, 'status' => $status, 'order_id' => $orderId ]); $domainId = $conn->lastInsertId(); } // Insert Item History $stmtInsertItem->execute([ 'order_id' => $orderId, 'domain_id' => $domainId, 'action' => $type ]); } $conn->commit(); return count($domains); } catch (\Exception $e) { $conn->rollBack(); throw $e; } } private function cleanDomain($input) { // 1. Remove whitespace and common trailing punctuation $input = trim($input); $input = rtrim($input, ';,."\''); // 2. Transliterate accents (e.g., domínio -> dominio) // Using iconv to transliterate to ASCII if (function_exists('iconv')) { $input = iconv('UTF-8', 'ASCII//TRANSLIT', $input); } // 3. Handle Protocols and URLs // If it doesn't have a protocol but looks like a URL path (e.g. domain.com/page), parse_url might fail or treat as path. // We prepend http:// if missing to help parse_url, unless it's a mailto if (stripos($input, 'mailto:') === 0) { $input = str_ireplace('mailto:', '', $input); } if (strpos($input, '://') === false) { $input = 'http://' . $input; } $parsed = parse_url($input); if (!$parsed || !isset($parsed['host'])) { return null; } $domain = $parsed['host']; // 4. Remove 'www.' prefix (requested "www é um protocolo") if (strpos($domain, 'www.') === 0) { $domain = substr($domain, 4); } // 5. Lowercase $domain = strtolower($domain); // 6. Final Validation // Must contain at least one dot (unless localhost, but for blocking usually FQDN) // Must allow hyphens, dots, numbers, letters. if (!preg_match('/^([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]([a-z0-9-]*[a-z0-9])?$/', $domain)) { return null; } return $domain; } }