122 lines
4.1 KiB
PHP
122 lines
4.1 KiB
PHP
<?php
|
|
/**
|
|
* POST /api/lab/upload_nota_imagen.php
|
|
* Sube uno o varios archivos adjuntos a una nota de domicilio.
|
|
* Acepta: imágenes (jpg, png, webp, gif), PDF, Word, Excel, texto.
|
|
* Límite: 10 MB por archivo.
|
|
*
|
|
* POST multipart/form-data con campo 'file' (uno) o 'files[]' (varios)
|
|
* Devuelve: { success, archivos: [{nombre, path, mime, size}] }
|
|
*/
|
|
require_once __DIR__ . '/../../config/config.php';
|
|
require_once __DIR__ . '/../../classes/Database.php';
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
header('X-Content-Type-Options: nosniff');
|
|
|
|
requireAuthentication();
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
http_response_code(405);
|
|
echo json_encode(['success' => false, 'error' => 'Método no permitido']);
|
|
exit;
|
|
}
|
|
|
|
$allowedMimes = [
|
|
// Imágenes
|
|
'image/jpeg' => 'jpg',
|
|
'image/png' => 'png',
|
|
'image/webp' => 'webp',
|
|
'image/gif' => 'gif',
|
|
// Documentos
|
|
'application/pdf' => 'pdf',
|
|
'application/msword' => 'doc',
|
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
|
|
'application/vnd.ms-excel' => 'xls',
|
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
|
|
'text/plain' => 'txt',
|
|
'text/csv' => 'csv',
|
|
];
|
|
|
|
// Normalizar: acepta 'file' (uno) o 'files[]' (varios)
|
|
$incoming = [];
|
|
if (!empty($_FILES['files']['name'][0])) {
|
|
// múltiples
|
|
for ($i = 0; $i < count($_FILES['files']['name']); $i++) {
|
|
$incoming[] = [
|
|
'name' => $_FILES['files']['name'][$i],
|
|
'tmp_name' => $_FILES['files']['tmp_name'][$i],
|
|
'error' => $_FILES['files']['error'][$i],
|
|
'size' => $_FILES['files']['size'][$i],
|
|
];
|
|
}
|
|
} elseif (!empty($_FILES['file']['tmp_name'])) {
|
|
$incoming[] = [
|
|
'name' => $_FILES['file']['name'],
|
|
'tmp_name' => $_FILES['file']['tmp_name'],
|
|
'error' => $_FILES['file']['error'],
|
|
'size' => $_FILES['file']['size'],
|
|
];
|
|
}
|
|
|
|
if (empty($incoming)) {
|
|
echo json_encode(['success' => false, 'error' => 'No se recibieron archivos']);
|
|
exit;
|
|
}
|
|
|
|
$uploadDir = __DIR__ . '/../../uploads/media';
|
|
if (!is_dir($uploadDir)) {
|
|
@mkdir($uploadDir, 0755, true);
|
|
}
|
|
|
|
$resultado = [];
|
|
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
|
|
|
foreach ($incoming as $file) {
|
|
if ($file['error'] !== UPLOAD_ERR_OK) {
|
|
echo json_encode(['success' => false, 'error' => "Error al recibir archivo: código {$file['error']}"]);
|
|
finfo_close($finfo);
|
|
exit;
|
|
}
|
|
if ($file['size'] > 10 * 1024 * 1024) {
|
|
echo json_encode(['success' => false, 'error' => "El archivo '{$file['name']}' supera 10 MB"]);
|
|
finfo_close($finfo);
|
|
exit;
|
|
}
|
|
|
|
$mime = finfo_file($finfo, $file['tmp_name']);
|
|
if (!isset($allowedMimes[$mime])) {
|
|
echo json_encode(['success' => false, 'error' => "Tipo no permitido ($mime). Imágenes, PDF o documentos Office."]);
|
|
finfo_close($finfo);
|
|
exit;
|
|
}
|
|
|
|
$ext = $allowedMimes[$mime];
|
|
$newName = 'nota_' . date('Ymd_His') . '_' . bin2hex(random_bytes(4)) . '.' . $ext;
|
|
$dest = realpath($uploadDir) . '/' . $newName;
|
|
|
|
if (!move_uploaded_file($file['tmp_name'], $dest)) {
|
|
echo json_encode(['success' => false, 'error' => 'Error al guardar el archivo en el servidor']);
|
|
finfo_close($finfo);
|
|
exit;
|
|
}
|
|
|
|
$nombreOriginal = mb_substr(preg_replace('/[^\w.\-áéíóúÁÉÍÓÚñÑ ]/u', '', $file['name']), 0, 100);
|
|
|
|
$resultado[] = [
|
|
'nombre' => $nombreOriginal ?: $newName,
|
|
'path' => $newName,
|
|
'mime' => $mime,
|
|
'size' => $file['size'],
|
|
];
|
|
}
|
|
|
|
finfo_close($finfo);
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'archivos' => $resultado,
|
|
// retrocompatibilidad: si solo fue uno, devolver también imagen_path
|
|
'imagen_path'=> count($resultado) === 1 ? $resultado[0]['path'] : null,
|
|
]);
|