Ir al contenido

Arranque y descubrimiento en compat-legacy de NextPDF

nextpdf/compat-legacy expone una fachada compatible con TCPDF —la clase NextPDF\Compat\Tcpdf\TCPDF— que delega en el motor de NextPDF. Es una capa de compatibilidad, no un clon de reemplazo directo. Cubre, mediante delegación directa, 94 de los aproximadamente 120 métodos de TCPDF 6.x analizados. Los métodos restantes presentan diferencias documentadas de comportamiento (véase /integrations/tcpdf-compat/method-coverage/).

No hay enlace global durante la autocarga. De forma predeterminada, requerir el paquete no crea una clase global \TCPDF. Los alias globales se habilitan de forma explícita o —la opción preferida durante la migración— se importa la clase del adaptador en cada archivo.

La fachada es una clase normal autocargada según PSR-4:

ElementoValor
Clase de fachadaNextPDF\Compat\Tcpdf\TCPDF
Prefijo PSR-4NextPDF\Compat\Tcpdf\ se asigna a src/Compat/Tcpdf/
Contrato compartidoNextPDF\Compat\Contracts\CompatAdapterInterface
Vía de escapeTCPDF::getDocument() devuelve el NextPDF\Core\Document envuelto

De forma intencionada, la clase no es final: los usuarios de TCPDF heredado suelen crear subclases de TCPDF para sobrescribir Header() y Footer(), por lo que el adaptador conserva ese punto de extensión. Internamente, la clase es una fachada. Agrupa 25 traits de responsabilidad única y delega todas las operaciones de PDF en una instancia de Document que se construye durante la construcción.

Composer autoload

Class referenced: new TCPDF or new global TCPDF

Constructor runs

LegacyDefaults::register defines K_/PDF_ constants if absent

ConstructorBridge::build maps orientation/unit/format to Document

Document, UnitConverter, PageSize stored on the facade

Creator/Author seeded from PDF_CREATOR / PDF_AUTHOR

Diagram

La construcción es el único paso de «arranque». El paquete en sí no registra nada en un contenedor de servicios ni arranca ningún framework. La integración con el framework se añade como una capa fina —véase /integrations/tcpdf-compat/integration/.

LegacyDefaults::register() es idempotente: solo define una constante si aún no está definida. Las constantes definidas por la aplicación siempre prevalecen, siempre que se definan antes de la primera construcción (véase /integrations/tcpdf-compat/configuration/ § Orden de resolución de la configuración).

Si la base de código llama a new \TCPDF(...) sobre el espacio de nombres global y todavía no es posible cambiar esos puntos de llamada, conviene registrar los alias globales una vez durante el arranque de la aplicación:

examples/boot-aliases.php
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\LegacyBootstrap;
LegacyBootstrap::enableAliases();
// Global names now resolve to the adapter:
$pdf = new \TCPDF('P', 'mm', 'A4');

enableAliases() registra \TCPDF, \TCPDF_STATIC, \TCPDF_FONTS, \TCPDF_COLORS y \TCPDF_IMAGES. El comportamiento, verificado por tests/Unit/Compat/Tcpdf/LegacyBootstrapTest.php, es el siguiente:

  • Es idempotente: llamarlo dos veces no lanza ninguna excepción y solo registra una vez.
  • LegacyBootstrap::isRegistered() indica si ya se ha ejecutado.
  • Después del registro, un new \TCPDF() es una instancia del adaptador.

Cómo evitar conflictos con una instalación real de TCPDF

Sección titulada «Cómo evitar conflictos con una instalación real de TCPDF»

Esta es la regla más importante de toda la página.

enableAliases() registra un alias solo si aún no existe una clase con ese nombre (class_exists($alias, autoload: false)). Por lo tanto:

  • Si tecnickcom/tcpdf está instalado y su \TCPDF se carga primero, el alias se omite de forma silenciosa y el código sigue usando el TCPDF heredado, no el adaptador.
  • Ejecutar ambas bibliotecas con los alias globales activados en el mismo proceso no está soportado y produce un comportamiento ambiguo.

Durante la migración, es preferible usar importaciones explícitas por archivo (use NextPDF\Compat\Tcpdf\TCPDF;). Son fáciles de localizar con grep y no son ambiguas. Debe eliminarse tecnickcom/tcpdf una vez que se supere la auditoría en modo estricto (véase /integrations/tcpdf-compat/migration/ Etapa 5). Si \TCPDF se resuelve a la clase incorrecta, /integrations/tcpdf-compat/troubleshooting/ incluye el diagnóstico.

El paquete no incluye enlaces de contenedor para ningún framework. Si se enlaza la fachada en un contenedor, conviene enlazar una fábrica que devuelva un NextPDF\Compat\Tcpdf\TCPDF nuevo por cada documento. El estado del documento es por instancia y no debe compartirse entre documentos no relacionados (véase /integrations/tcpdf-compat/production-usage/ § Concurrencia). En /integrations/tcpdf-compat/integration/ se muestra un enlace típico.

En el momento de la construcción, el adaptador resuelve la configuración en este orden: primero los argumentos del constructor, después las constantes heredadas ya definidas por la aplicación y, por último, los valores predeterminados de LegacyDefaults de TCPDF 6.2.13 para cualquier constante que aún no esté definida. Para conocer todos los detalles y el objeto moderno AdaptationConfig, véase /integrations/tcpdf-compat/configuration/.

Para comprobar que la fachada está conectada y que el enlace con el motor se resuelve, se puede construir un adaptador, generar un PDF de una página y luego verificar el prefijo %PDF. Esta es la misma superficie que verifican las pruebas de salida del paquete. La comprobación ejecutable se encuentra en /integrations/tcpdf-compat/install/ § Verificar la instalación.

Para detectar un conflicto con un TCPDF real antes de activar los alias, comprobar si ya existe un \TCPDF global en el punto donde se llamaría a enableAliases(). Si existe, el alias se omitirá; por tanto, hay que resolver el conflicto (usar importaciones explícitas o eliminar el TCPDF real) antes de confiar en el adaptador.

La matriz de cobertura autorizada y verificada mediante pruebas es el archivo del repositorio docs/TCPDF_COVERAGE.md. El resumen para lectores, que incluye las listas de métodos ignorados de forma silenciosa y no implementados, es /integrations/tcpdf-compat/method-coverage/. Este paquete no afirma ser un «reemplazo directo» ni ser «100 % compatible con TCPDF»; es una alternativa compatible con TCPDF, con una superficie de compatibilidad conocida y probada, y diferencias de comportamiento documentadas.

  • docs/TCPDF_COVERAGE.md — fuente autorizada de cobertura (en el repositorio)
  • /integrations/tcpdf-compat/integration/ — integración de la fachada en una aplicación/framework
  • /integrations/tcpdf-compat/method-coverage/ — comportamiento y carencias por método
  • /integrations/tcpdf-compat/migration/ — estrategia de migración por etapas
  • /integrations/tcpdf-compat/troubleshooting/ — diagnóstico de conflictos de alias/TCPDF real
  • tests/Unit/Compat/Tcpdf/LegacyBootstrapTest.php — oráculo de comportamiento de los alias