'jpg', 'image/png' => 'png', 'image/gif' => 'gif', 'image/webp' => 'webp', '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 files[] o file (retrocompat) $rawFiles = []; if (!empty($_FILES['files']['name'][0])) { // files[] (múltiples) $count = count($_FILES['files']['name']); for ($i = 0; $i < $count; $i++) { $rawFiles[] = [ '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'])) { // file (singular, retrocompat) $rawFiles[] = [ 'name' => $_FILES['file']['name'], 'tmp_name' => $_FILES['file']['tmp_name'], 'error' => $_FILES['file']['error'], 'size' => $_FILES['file']['size'], ]; } if (empty($rawFiles)) { jsonError('No se recibió ningún archivo'); } $uploadDir = realpath(__DIR__ . '/../../uploads/media'); if (!$uploadDir) { @mkdir(__DIR__ . '/../../uploads/media', 0755, true); $uploadDir = realpath(__DIR__ . '/../../uploads/media'); } if (!$uploadDir || !is_writable($uploadDir)) { jsonError('El directorio de uploads no está disponible'); } $domicilioId = isset($_POST['domicilio_id']) ? (int)$_POST['domicilio_id'] : 0; $pacienteId = isset($_POST['paciente_id']) ? (int)$_POST['paciente_id'] : 0; $om = ($domicilioId && $pacienteId) ? new OrdenMedica() : null; $adminId = adminId(); $archivos = []; foreach ($rawFiles as $file) { if ($file['error'] !== UPLOAD_ERR_OK) { continue; // saltar archivos con error de upload } // Validar tamaño máximo: 10 MB if ($file['size'] > 10 * 1024 * 1024) { jsonError('El archivo "' . basename($file['name']) . '" supera el límite de 10 MB'); } // Validar tipo MIME real $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime = finfo_file($finfo, $file['tmp_name']); finfo_close($finfo); if (!array_key_exists($mime, $allowedMimes)) { jsonError('Tipo de archivo no permitido: ' . $mime); } // Generar nombre único y seguro $origExt = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); $origExt = preg_replace('/[^a-z0-9]/', '', $origExt); if (!$origExt) { $origExt = $allowedMimes[$mime]; } $newName = 'orden_' . date('Ymd_His') . '_' . bin2hex(random_bytes(4)) . '.' . $origExt; $destPath = $uploadDir . DIRECTORY_SEPARATOR . $newName; if (!move_uploaded_file($file['tmp_name'], $destPath)) { jsonError('Error al guardar el archivo en el servidor'); } $ordenId = null; if ($om) { // Crear registro en lab_ordenes_medicas vinculado al domicilio $ordenId = $om->crear([ 'paciente_id' => $pacienteId, 'domicilio_id' => $domicilioId, 'local_file' => $newName, ], $adminId); } $archivos[] = [ 'local_file' => $newName, 'file_name' => $file['name'], 'file_size' => $file['size'], 'mime' => $mime, 'orden_id' => $ordenId, ]; } if (empty($archivos)) { jsonError('No se pudo procesar ningún archivo'); } jsonOk([ 'archivos' => $archivos, 'local_file' => $archivos[0]['local_file'], // retrocompat ]);