getConnection(); // Search by ID, Title, or Domain Content // Using DISTINCT to avoid duplicates if multiple domains match in same order $sql = "SELECT DISTINCT o.* FROM orders o LEFT JOIN order_items oi ON o.id = oi.order_id LEFT JOIN domains d ON oi.domain_id = d.id WHERE o.id LIKE :search OR o.title LIKE :search OR d.name LIKE :search ORDER BY o.id DESC"; $stmt = $conn->prepare($sql); $stmt->execute(['search' => "%$search%"]); $orders = $stmt->fetchAll(); } else { $orders = $orderModel->findAll(); // Sort by ID desc usort($orders, function ($a, $b) { return $b['id'] - $a['id']; }); } // Pagination Logic $page = isset($_GET['page']) ? (int) $_GET['page'] : 1; $perPage = 30; $total = count($orders); $totalPages = ceil($total / $perPage); $offset = ($page - 1) * $perPage; $paginatedOrders = array_slice($orders, $offset, $perPage); View::render('layouts.admin', [ 'title' => 'Ordens Judiciais', 'content' => __DIR__ . '/../../resources/views/admin/orders/index.php', 'orders' => $paginatedOrders, 'pagination' => [ 'current' => $page, 'total' => $totalPages, 'next' => ($page < $totalPages) ? $page + 1 : null, 'prev' => ($page > 1) ? $page - 1 : null ] ]); } public function create() { View::render('layouts.admin', [ 'title' => 'Nova Ordem', 'content' => __DIR__ . '/../../resources/views/admin/orders/create.php' ]); } public function store() { if (!isset($_FILES['csv_file']) || $_FILES['csv_file']['error'] !== UPLOAD_ERR_OK) { $_SESSION['flash_error'] = "Erro no upload do arquivo CSV."; View::redirect('/admin/orders/create'); return; } $title = $_POST['title']; $type = $_POST['type']; $content = \App\Utils\TextFormatter::normalizeLineBreaks($_POST['content']); $received_at = $_POST['received_at']; $conn = \App\Config\Database::getInstance()->getConnection(); try { // Create Order $sql = "INSERT INTO orders (title, type, content, received_at) VALUES (:title, :type, :content, :received_at)"; $stmt = $conn->prepare($sql); $stmt->execute([ 'title' => $title, 'type' => $type, 'content' => $content, 'received_at' => $received_at ]); $orderId = $conn->lastInsertId(); // Process CSV (unchanged) $processor = new OrderProcessor(); $count = $processor->process($orderId, $type, $_FILES['csv_file']['tmp_name']); // Store attachments (if any were sent) if (isset($_FILES['attachments']) && !empty($_FILES['attachments']['name'][0])) { $attachmentService = new AttachmentService(); $attachmentService->storeFiles((int) $orderId, $_FILES['attachments']); } // Send Telegram Notification $telegramService = new TelegramService(); $typeLabel = ($type === 'block') ? 'Bloqueio' : (($type === 'unblock') ? 'Desbloqueio' : $type); $telegramService->sendOrderNotification([ 'id' => $orderId, 'title' => $title, 'type' => $typeLabel ], $count); $_SESSION['flash_success'] = "Ordem criada com sucesso! $count domínios processados."; View::redirect('/admin/orders'); } catch (\Exception $e) { $_SESSION['flash_error'] = "Erro ao processar ordem: " . $e->getMessage(); View::redirect('/admin/orders/create'); } } public function view($id) { $orderModel = new Order(); $order = $orderModel->find($id); if (!$order) { View::redirect('/admin/orders'); } // Get Items $conn = \App\Config\Database::getInstance()->getConnection(); $stmt = $conn->prepare("SELECT d.name, oi.action FROM order_items oi JOIN domains d ON oi.domain_id = d.id WHERE oi.order_id = :id"); $stmt->execute(['id' => $id]); $items = $stmt->fetchAll(); // Get Attachments $attachmentModel = new OrderAttachment(); $attachments = $attachmentModel->findByOrderId((int) $id); View::render('layouts.admin', [ 'title' => 'Detalhes da Ordem #' . $id, 'content' => __DIR__ . '/../../resources/views/admin/orders/view.php', 'order' => $order, 'items' => $items, 'attachments' => $attachments, ]); } public function downloadAttachment($id) { $attachmentModel = new OrderAttachment(); $attachment = $attachmentModel->find($id); if (!$attachment) { $_SESSION['flash_error'] = "Anexo não encontrado."; View::redirect('/admin/orders'); return; } $attachmentService = new AttachmentService(); $filePath = $attachmentService->getFilePath((int) $attachment['order_id'], $attachment['stored_name']); if (!file_exists($filePath)) { $_SESSION['flash_error'] = "Arquivo físico não encontrado no servidor."; View::redirect('/admin/orders/view/' . $attachment['order_id']); return; } // Serve o arquivo para download header('Content-Type: ' . ($attachment['mime_type'] ?? 'application/octet-stream')); header('Content-Disposition: attachment; filename="' . addslashes($attachment['original_name']) . '"'); header('Content-Length: ' . filesize($filePath)); header('Cache-Control: private, no-cache'); header('Pragma: no-cache'); readfile($filePath); exit; } }