add upload anexos pos ordem criada
This commit is contained in:
@@ -116,6 +116,7 @@ class OrderController
|
||||
|
||||
$conn = \App\Config\Database::getInstance()->getConnection();
|
||||
|
||||
$conn->beginTransaction();
|
||||
try {
|
||||
// Create Order
|
||||
$sql = "INSERT INTO orders (title, type, content, received_at) VALUES (:title, :type, :content, :received_at)";
|
||||
@@ -149,10 +150,13 @@ class OrderController
|
||||
'type' => $typeLabel
|
||||
], $count);
|
||||
|
||||
$conn->commit();
|
||||
|
||||
$_SESSION['flash_success'] = "Ordem criada com sucesso! $count domínios processados.";
|
||||
View::redirect('/admin/orders');
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$conn->rollBack();
|
||||
$_SESSION['flash_error'] = "Erro ao processar ordem: " . $e->getMessage();
|
||||
View::redirect('/admin/orders/create');
|
||||
}
|
||||
@@ -216,4 +220,36 @@ class OrderController
|
||||
readfile($filePath);
|
||||
exit;
|
||||
}
|
||||
|
||||
public function uploadAttachments($id)
|
||||
{
|
||||
$orderModel = new \App\Models\Order();
|
||||
$order = $orderModel->find($id);
|
||||
|
||||
if (!$order) {
|
||||
$_SESSION['flash_error'] = "Ordem não encontrada.";
|
||||
View::redirect('/admin/orders');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (isset($_FILES['new_attachments']) && !empty($_FILES['new_attachments']['name'][0])) {
|
||||
$attachments = $_FILES['new_attachments'];
|
||||
$attachmentService = new AttachmentService();
|
||||
$savedCount = $attachmentService->storeFiles((int) $id, $attachments);
|
||||
|
||||
if ($savedCount > 0) {
|
||||
$_SESSION['flash_success'] = "{$savedCount} anexo(s) adicionado(s) com sucesso à ordem!";
|
||||
} else {
|
||||
$_SESSION['flash_error'] = "Nenhum arquivo válido foi recebido.";
|
||||
}
|
||||
} else {
|
||||
$_SESSION['flash_error'] = "Nenhum arquivo foi selecionado.";
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$_SESSION['flash_error'] = "Erro de upload: " . $e->getMessage();
|
||||
}
|
||||
|
||||
View::redirect('/admin/orders/view/' . $id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,23 @@ class AttachmentService
|
||||
'text/plain' => 'txt',
|
||||
];
|
||||
|
||||
/** Tamanho máximo por arquivo: 20 MB */
|
||||
private const MAX_SIZE = 20 * 1024 * 1024;
|
||||
/**
|
||||
* Retorna o tamanho máximo de upload, lendo do PHP ini.
|
||||
*/
|
||||
private function getMaxSize(): int
|
||||
{
|
||||
$val = ini_get('upload_max_filesize');
|
||||
if (empty($val)) return 20 * 1024 * 1024;
|
||||
$val = trim($val);
|
||||
$last = strtolower($val[strlen($val)-1]);
|
||||
$val = (int)$val;
|
||||
switch($last) {
|
||||
case 'g': $val *= 1024;
|
||||
case 'm': $val *= 1024;
|
||||
case 'k': $val *= 1024;
|
||||
}
|
||||
return $val > 0 ? $val : 20 * 1024 * 1024;
|
||||
}
|
||||
|
||||
/**
|
||||
* Raiz do diretório de uploads (fora do public/).
|
||||
@@ -81,8 +96,10 @@ class AttachmentService
|
||||
throw new \Exception("Erro no upload do arquivo '{$file['name']}': código {$file['error']}");
|
||||
}
|
||||
|
||||
if ($file['size'] > self::MAX_SIZE) {
|
||||
throw new \Exception("O arquivo '{$file['name']}' excede o tamanho máximo permitido de 20 MB.");
|
||||
$maxSize = $this->getMaxSize();
|
||||
if ($file['size'] > $maxSize) {
|
||||
$maxSizeMB = floor($maxSize / (1024 * 1024));
|
||||
throw new \Exception("O arquivo '{$file['name']}' excede o tamanho máximo permitido de {$maxSizeMB} MB.");
|
||||
}
|
||||
|
||||
// Detecta o tipo MIME real do arquivo (não confiar só no header HTTP)
|
||||
|
||||
@@ -36,7 +36,10 @@ class OrderProcessor
|
||||
|
||||
$domains = array_unique($domains); // Remove duplicates in batch
|
||||
|
||||
$conn->beginTransaction();
|
||||
$inTransaction = $conn->inTransaction();
|
||||
if (!$inTransaction) {
|
||||
$conn->beginTransaction();
|
||||
}
|
||||
|
||||
try {
|
||||
$stmtCheck = $conn->prepare("SELECT id FROM domains WHERE name = :name");
|
||||
@@ -77,11 +80,15 @@ class OrderProcessor
|
||||
]);
|
||||
}
|
||||
|
||||
$conn->commit();
|
||||
if (!$inTransaction) {
|
||||
$conn->commit();
|
||||
}
|
||||
return count($domains);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$conn->rollBack();
|
||||
if (!$inTransaction) {
|
||||
$conn->rollBack();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,9 @@ $router->addMiddleware(\App\Middleware\AdminMiddleware::class);
|
||||
$router->get('/admin/orders/attachments/{id}/download', [\App\Controllers\OrderController::class, 'downloadAttachment']);
|
||||
$router->addMiddleware(\App\Middleware\AdminMiddleware::class);
|
||||
|
||||
$router->post('/admin/orders/attachments/upload/{id}', [\App\Controllers\OrderController::class, 'uploadAttachments']);
|
||||
$router->addMiddleware(\App\Middleware\AdminMiddleware::class);
|
||||
|
||||
// Settings
|
||||
$router->get('/admin/settings', [\App\Controllers\SettingsController::class, 'index']);
|
||||
$router->addMiddleware(\App\Middleware\AdminMiddleware::class);
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($attachments)): ?>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<div class="px-6 py-4 border-b border-gray-100 bg-gray-50 flex items-center gap-2">
|
||||
<svg class="w-4 h-4 text-gray-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
@@ -37,6 +36,8 @@
|
||||
</svg>
|
||||
<h3 class="text-sm font-semibold text-gray-800">Anexos (<?= count($attachments) ?>)</h3>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($attachments)): ?>
|
||||
<ul class="divide-y divide-gray-100">
|
||||
<?php foreach ($attachments as $attachment): ?>
|
||||
<li class="flex items-center justify-between px-6 py-3 hover:bg-gray-50 transition-colors">
|
||||
@@ -60,8 +61,21 @@
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php else: ?>
|
||||
<div class="px-6 py-4 text-sm text-gray-500">
|
||||
Nenhum anexo salvo para esta ordem.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="px-6 py-4 bg-gray-50 border-t border-gray-100">
|
||||
<form action="/admin/orders/attachments/upload/<?= (int) $order['id'] ?>" method="POST" enctype="multipart/form-data" class="flex flex-col sm:flex-row items-center gap-3">
|
||||
<input type="file" name="new_attachments[]" multiple class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-lg file:border-0 file:text-sm file:font-semibold file:bg-gray-200 file:text-gray-700 hover:file:bg-gray-300 cursor-pointer" accept=".pdf,.png,.jpg,.jpeg,.gif,.doc,.docx,.xls,.xlsx,.txt" required>
|
||||
<button type="submit" class="px-4 py-2 bg-primary-600 text-white rounded-lg text-sm font-semibold hover:bg-primary-700 w-full sm:w-auto flex-shrink-0 transition-colors">
|
||||
Adicionar Anexos
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<div class="px-6 py-4 border-b border-gray-100 bg-gray-50">
|
||||
|
||||
Reference in New Issue
Block a user