false, 'error' => 'No autenticado']); exit; } $pdo = Database::getInstance()->getConnection(); $uploadDir = dirname(__DIR__, 3) . '/uploads/turnero/'; $publicBase = rtrim(BASE_URL, '/') . '/uploads/turnero/'; // ── Crear carpeta si no existe ──────────────────────────────── if (!is_dir($uploadDir)) { if (!mkdir($uploadDir, 0755, true)) { echo json_encode(['ok' => false, 'error' => 'No se pudo crear el directorio de uploads']); exit; } } // ── Acción: borrar ──────────────────────────────────────────── $rawBody = file_get_contents('php://input'); $bodyJson = $rawBody ? json_decode($rawBody, true) : null; if (isset($bodyJson['accion']) && $bodyJson['accion'] === 'borrar') { // Obtener ruta guardada $stmt = $pdo->prepare("SELECT valor FROM lab_config WHERE clave = 'turnero_tv_video' LIMIT 1"); $stmt->execute(); $row = $stmt->fetch(PDO::FETCH_ASSOC); if ($row && $row['valor']) { // Derivar nombre de archivo de la URL guardada $filename = basename(parse_url($row['valor'], PHP_URL_PATH)); $filepath = $uploadDir . $filename; if ($filepath && is_file($filepath)) { @unlink($filepath); } } // Borrar de la BD $pdo->prepare("DELETE FROM lab_config WHERE clave = 'turnero_tv_video'")->execute(); echo json_encode(['ok' => true]); exit; } // ── Acción: subir ────────────────────────────────────────────── if (!isset($_FILES['video'])) { echo json_encode(['ok' => false, 'error' => 'No se recibió ningún archivo']); exit; } $file = $_FILES['video']; if ($file['error'] !== UPLOAD_ERR_OK) { $errores = [ UPLOAD_ERR_INI_SIZE => 'El archivo supera upload_max_filesize en php.ini', UPLOAD_ERR_FORM_SIZE => 'El archivo supera MAX_FILE_SIZE del formulario', UPLOAD_ERR_PARTIAL => 'El archivo se subió parcialmente', UPLOAD_ERR_NO_FILE => 'No se seleccionó ningún archivo', UPLOAD_ERR_NO_TMP_DIR => 'Falta la carpeta temporal', UPLOAD_ERR_CANT_WRITE => 'Error al escribir el archivo', ]; echo json_encode(['ok' => false, 'error' => $errores[$file['error']] ?? 'Error de subida desconocido']); exit; } // Validar tamaño (máx 500 MB) $maxBytes = 500 * 1024 * 1024; if ($file['size'] > $maxBytes) { echo json_encode(['ok' => false, 'error' => 'El video supera el límite de 500 MB']); exit; } // Validar tipo MIME (solo MP4 y WebM) $allowedMime = ['video/mp4', 'video/webm', 'video/ogg']; $finfo = new finfo(FILEINFO_MIME_TYPE); $mime = $finfo->file($file['tmp_name']); if (!in_array($mime, $allowedMime, true)) { echo json_encode(['ok' => false, 'error' => 'Solo se permiten videos MP4 o WebM']); exit; } // Definir extensión segura desde el MIME real $extMap = ['video/mp4' => 'mp4', 'video/webm' => 'webm', 'video/ogg' => 'ogv']; $ext = $extMap[$mime]; // Borrar video anterior si existe foreach (['mp4', 'webm', 'ogv'] as $oldExt) { $oldPath = $uploadDir . 'tv_video.' . $oldExt; if (is_file($oldPath)) { @unlink($oldPath); } } $destFilename = 'tv_video.' . $ext; $destPath = $uploadDir . $destFilename; if (!move_uploaded_file($file['tmp_name'], $destPath)) { echo json_encode(['ok' => false, 'error' => 'No se pudo guardar el archivo']); exit; } $publicUrl = $publicBase . $destFilename; // Guardar URL en lab_config (upsert) $stmt = $pdo->prepare( "INSERT INTO lab_config (clave, valor) VALUES ('turnero_tv_video', ?) ON DUPLICATE KEY UPDATE valor = VALUES(valor)" ); $stmt->execute([$publicUrl]); echo json_encode(['ok' => true, 'url' => $publicUrl]);