false, 'error' => 'Método no permitido']); exit; } try { $db = Database::getInstance(); // ── Guardar/actualizar configuración de texto ────────────────────────── // Si se envía sin archivo (solo textos), actualizar la versión activa. $msgAceptacion = trim($_POST['mensaje_aceptacion'] ?? ''); $msgRechazo = trim($_POST['mensaje_rechazo'] ?? ''); $version = trim($_POST['version'] ?? ''); $forzarReenvio = !empty($_POST['forzar_reenvio']) ? 1 : 0; // ── Determinar si hay un archivo ─────────────────────────────────────── $hasFile = isset($_FILES['pdf']) && $_FILES['pdf']['error'] === UPLOAD_ERR_OK; if ($hasFile) { $file = $_FILES['pdf']; $tmpPath = $file['tmp_name']; $mime = mime_content_type($tmpPath); // Validar que sea PDF if ($mime !== 'application/pdf') { if (ob_get_length()) ob_clean(); http_response_code(400); echo json_encode(['success' => false, 'error' => 'Solo se permite subir archivos PDF']); exit; } // Tamaño máximo 20 MB if ($file['size'] > 20 * 1024 * 1024) { if (ob_get_length()) ob_clean(); http_response_code(400); echo json_encode(['success' => false, 'error' => 'El archivo no puede superar 20 MB']); exit; } // Crear directorio de destino si no existe $uploadDir = __DIR__ . '/../uploads/terms/'; if (!is_dir($uploadDir)) { mkdir($uploadDir, 0755, true); } // Nombre único para evitar sobreescribir $safeName = 'terminos_' . date('Ymd_His') . '_' . bin2hex(random_bytes(4)) . '.pdf'; $destPath = $uploadDir . $safeName; if (!move_uploaded_file($tmpPath, $destPath)) { throw new Exception('Error al guardar el archivo en el servidor'); } // URL pública $baseUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST']; // Calcular ruta relativa desde la raíz del proyecto $docRoot = rtrim($_SERVER['DOCUMENT_ROOT'], '/'); $absUpload = realpath($destPath); $relPath = '/' . ltrim(str_replace($docRoot, '', $absUpload), '/'); $docUrl = $baseUrl . $relPath; } // ── Desactivar versiones anteriores si se crea una nueva ────────────── if ($hasFile || !empty($version)) { // Si hay archivo o versión nueva, desactivar la anterior y crear registro nuevo $db->query("UPDATE terms_versions SET activa = 0 WHERE activa = 1"); $insertData = [ 'version' => $version ?: date('Y-m'), 'mensaje_aceptacion' => $msgAceptacion, 'mensaje_rechazo' => $msgRechazo, 'forzar_reenvio' => $forzarReenvio, 'activa' => 1, ]; if ($hasFile) { $insertData['documento_url'] = $docUrl ?? null; $insertData['documento_nombre'] = $file['name']; } $newId = $db->insert('terms_versions', $insertData); // Si forzar_reenvio=1, resetear terms_pending en todos los usuarios para forzar re-lectura if ($forzarReenvio) { $db->query( "UPDATE users SET terms_pending = 0, terms_accepted_at = NULL, terms_version_id = NULL" ); } if (ob_get_length()) ob_clean(); echo json_encode([ 'success' => true, 'version_id' => $newId, 'documento_url' => $insertData['documento_url'] ?? null, 'message' => 'Términos guardados correctamente', ]); } else { // Sin archivo ni versión → solo actualizar textos de la versión activa $active = $db->fetch("SELECT id FROM terms_versions WHERE activa = 1 ORDER BY id DESC LIMIT 1"); if ($active) { $updateData = []; if ($msgAceptacion !== '') $updateData['mensaje_aceptacion'] = $msgAceptacion; if ($msgRechazo !== '') $updateData['mensaje_rechazo'] = $msgRechazo; $updateData['forzar_reenvio'] = $forzarReenvio; $db->update('terms_versions', $updateData, 'id = :id', ['id' => $active['id']]); if ($forzarReenvio) { $db->query("UPDATE users SET terms_pending = 0, terms_accepted_at = NULL, terms_version_id = NULL"); } if (ob_get_length()) ob_clean(); echo json_encode(['success' => true, 'message' => 'Configuración de términos actualizada']); } else { if (ob_get_length()) ob_clean(); http_response_code(400); echo json_encode(['success' => false, 'error' => 'No hay versión activa. Sube un documento primero.']); } } } catch (Exception $e) { error_log('upload_terms_document.php error: ' . $e->getMessage()); if (ob_get_length()) ob_clean(); http_response_code(500); echo json_encode(['success' => false, 'error' => $e->getMessage()]); }