From c7f28a79f47cd518d6e1014bfadaff1f1bf9e978 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Fri, 20 Feb 2026 10:29:52 -0500 Subject: [PATCH] up --- api/version/media-url.php | 36 ++++++++++++++++++++++++++++++++++++ classes/MediaService.php | 10 ++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/api/version/media-url.php b/api/version/media-url.php index 4d77220..dac20ab 100644 --- a/api/version/media-url.php +++ b/api/version/media-url.php @@ -101,6 +101,42 @@ if (!$mediaId && !$providedUrl) { exit; } +// ── PRIORIDAD: Buscar archivo local en BD antes de consultar Graph API ── +if ($mediaId) { + try { + $db = Database::getInstance(); + // Buscar por media_url (que almacena el media ID) o por whatsapp_media_id + $row = $db->fetchOne( + "SELECT local_file, local_thumb, mime_type, filename FROM conversations WHERE (media_url = :mid OR whatsapp_media_id = :mid2) AND local_file IS NOT NULL AND local_file != '' ORDER BY id DESC LIMIT 1", + ['mid' => $mediaId, 'mid2' => $mediaId] + ); + if ($row && !empty($row['local_file'])) { + $localPath = realpath(__DIR__ . '/../../' . ltrim($row['local_file'], '/')); + $base = realpath(__DIR__ . '/../../uploads'); + if ($localPath && strpos($localPath, $base) === 0 && file_exists($localPath)) { + media_log("Serving local file for media ID {$mediaId}: {$localPath}"); + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $ctype = finfo_file($finfo, $localPath) ?: ($row['mime_type'] ?? 'application/octet-stream'); + finfo_close($finfo); + + header_remove('Content-Type'); + header('Cache-Control: public, max-age=86400'); + header('Content-Type: ' . $ctype); + header('Content-Length: ' . filesize($localPath)); + if ($download) { + $fname = $row['filename'] ?: basename($localPath); + header('Content-Disposition: attachment; filename="' . $fname . '"'); + } + readfile($localPath); + exit; + } + } + } catch (Exception $e) { + media_log("Error buscando local_file en BD: " . $e->getMessage()); + // Continuar con Graph API como fallback + } +} + $mediaUrl = null; if ($providedUrl) { diff --git a/classes/MediaService.php b/classes/MediaService.php index 898f84b..627f8f4 100644 --- a/classes/MediaService.php +++ b/classes/MediaService.php @@ -129,19 +129,24 @@ class MediaService { public function extensionFromMime($mime) { if (!$mime) return null; + // Remover parámetros del mime type (ej: "audio/ogg; codecs=opus" -> "audio/ogg") + $baseMime = strtolower(trim(explode(';', $mime)[0])); $map = [ 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/gif' => 'gif', 'image/webp' => 'webp', + 'image/svg+xml' => 'svg', 'audio/mpeg' => 'mp3', 'audio/ogg' => 'ogg', - 'audio/opus' => 'opus', + 'audio/opus' => 'ogg', 'audio/aac' => 'aac', 'audio/amr' => 'amr', + 'audio/mp4' => 'm4a', 'video/mp4' => 'mp4', 'video/3gpp' => '3gp', 'video/quicktime' => 'mov', + 'video/webm' => 'webm', 'text/csv' => 'csv', 'text/plain' => 'txt', 'application/pdf' => 'pdf', @@ -153,8 +158,9 @@ class MediaService { 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx', 'application/zip' => 'zip', 'application/x-rar-compressed' => 'rar', + 'application/octet-stream' => 'bin', ]; - return $map[$mime] ?? null; + return $map[$baseMime] ?? null; } public function isImageMime($mime) {