Skip to content

merge: el PDF nativo con FPDF llega a feat/app-documentate - #283

Open
erseco wants to merge 5 commits into
feat/app-documentatefrom
integra/app-documentate-pdf-nativo
Open

merge: el PDF nativo con FPDF llega a feat/app-documentate#283
erseco wants to merge 5 commits into
feat/app-documentatefrom
integra/app-documentate-pdf-nativo

Conversation

@erseco

@erseco erseco commented Sep 6, 2026

Copy link
Copy Markdown
Member

Qué es

Traer a feat/app-documentate lo que se mezcló en main con el PR #282: el PDF se dibuja en el servidor con FPDF a partir de maquetas HTML por tipo de documento, Collabora Online y el conversor WASM quedan como motores seleccionables, la descarga editable se ofrece solo en el formato de la plantilla, y los ficheros generados quedan protegidos en uploads/documentate/.

Es una mezcla de main, no un rehacer: un solo commit de merge.

Adaptado a las convenciones de esta rama

Sin i18n. Las doce cadenas que llegaban con __() y esc_html_e() pasan a literales en castellano, y languages/ sigue sin existir. Los tests que afirmaban sobre el texto en inglés afirman ahora sobre el castellano.

En main Aquí
Native PDF rendering PDF nativo (FPDF)
Editable download: Descarga editable:
PDF layout Maqueta PDF
The generated PDF could not be saved. No se ha podido guardar el PDF generado.

Conflictos y cómo se resolvieron

Once ficheros, resueltos a favor de la estructura de main y del idioma de esta rama.

  • Ajustes y tipos de documento: entra el motor fpdf y el selector de maqueta PDF, con sus etiquetas en castellano.
  • Documentate_Admin_Helper: build_format_state() cede ante own_format_state(), que ofrece solo el formato de la plantilla del tipo. Los tests de la función que desaparece se eliminan con ella.
  • Datos de ejemplo: las definiciones conservan prefix y has_management de esta rama junto a pdf_layout de main.
  • protect_output_dir() se elimina: Documentate_Private_Output hace lo mismo y más — permisos, migración de ficheros anteriores y fallo cerrado. El .htaccess que dejara la versión anterior sigue siendo válido, porque ya declara «Require all denied».
  • Spec de previsualización: se queda la versión de main, que parchea window.open en vez de esperar a que la pestaña pinte; el endpoint que abre el botón es documentate_preview_stream, que es sobre el que afirma.
  • composer.lock: regenerado con composer update --lock sobre el composer.json ya fusionado, que aquí no lleva wp-cli/i18n-command.

E2E adaptado

Los specs que llegan de main daban por hecho que un documento publicado se puede editar. Aquí el flujo lo aprueba y lo bloquea, y el metabox de acciones solo se pinta para quien puede editar el documento, así que los cuatro tests que afirman sobre sus botones lo devuelven antes a revisión. El botón se llama «Previsualizar PDF» en esta rama, no «Vista previa».

El bloque de exportación de la aplicación esperaba un botón DOCX deshabilitado en un tipo con plantilla ODT. Con la descarga editable limitada al formato propio, ese control ya no existe apagado: no existe. El spec lo comprueba ahora así.

Tres specs de la aplicación (documentate-app.spec.js, documentate-app-flow.spec.js, documentate-app-roles.spec.js) fallaban por datos acumulados en el sitio de desarrollo, no por la mezcla: fallan igual en feat/app-documentate sin ella, y pasan tras make reset-demo.

Presupuesto de PHPMD

La mezcla cruzaba la puerta por cinco líneas. Sin tocar phpmd-baseline.xml:

  • Documentate_Demo_Data estaba en 2504 líneas. La tabla de valores de ejemplo, 155 líneas de datos con un solo punto de llamada, se va a Documentate_Demo_Field_Values.
  • load_dependencies() estaba en 151. La carga de la aplicación de /documentate/ pasa a su propio método.

Verificación

Comprobación Resultado
make test 2775 tests, 17 782 aserciones
make test-generation 412 tests, 9981 aserciones
make lint limpio
make phpmd sin violaciones fuera del baseline
make check-plugin sin errores
make test-e2e 105 pasan, 4 omitidos, 0 fallan (tras make reset-demo)

…r opcional (#282)

El PDF se genera de forma nativa con FPDF a partir de maquetas HTML por tipo de documento. Collabora Online y el conversor WASM se conservan como motores seleccionables. La descarga editable se ofrece en el formato de la plantilla. Los ficheros generados quedan protegidos en uploads/documentate.
Trae el motor nativo de PDF, la protección del directorio de salida y la
descarga editable en el formato de la plantilla, adaptados a las
convenciones de esta rama.

Sin i18n: las doce cadenas que llegaban con `__()` y `esc_html_e()` pasan a
literales en castellano, y `languages/` sigue sin existir. Los tests que
afirmaban sobre el texto en inglés afirman ahora sobre el castellano.

Conflictos resueltos a favor de la estructura de main y del idioma de esta
rama: el selector de maqueta PDF y el motor `fpdf` en Ajustes, la descarga
editable solo en el formato propio, y las definiciones de los tipos de
ejemplo, que conservan `prefix` y `has_management` de aquí junto a
`pdf_layout` de allí.

`Documentate_Private_Output` sustituye a `protect_output_dir()`, que hacía
lo mismo peor y queda eliminado; su `.htaccess` antiguo sigue siendo
aceptado, porque ya declara «Require all denied».

La mezcla cruzaba la puerta de PHPMD por cuatro líneas en
`Documentate_Demo_Data` y por una en `load_dependencies()`. La tabla de
valores de ejemplo se va a `Documentate_Demo_Field_Values` y la carga de
la aplicación a su propio método, sin tocar el baseline.
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

WordPress Playground Preview

The changes in this pull request can previewed and tested using a WordPress Playground instance.

Open WordPress Playground Preview

El metabox de acciones solo se pinta para quien puede editar el documento,
y aquí un documento publicado queda aprobado y bloqueado: los cuatro tests
que afirman sobre sus botones lo devuelven antes a revisión. El botón se
llama «Previsualizar PDF» en esta rama.

El bloque de exportación ya no ofrece un DOCX deshabilitado para un tipo
con plantilla ODT: la descarga editable solo ofrece el formato propio, así
que el control no existe en vez de existir apagado.
…#283

El PDF nativo se dibujaba dentro de un `<div>` propio, así que un `</div>`
sobrante en un campo rich —que `wp_kses_post()` conserva y que un layout con
`strconv=no` inyecta tal cual— cerraba el envoltorio y tiraba en silencio todo
lo que venía detrás: el RESUELVO, la firma y los anexos. Se dibuja desde un
`<body>`, donde libxml se recupera de la etiqueta sobrante en vez de obedecerla.

Las filas de un repetidor se emparejaban con las guardadas por posición, y el
navegador renumera las filas en cada alta, baja y arrastre: el área podía mover
el IGIC o el importe aprobado de gestión a otro proveedor sin tocar la columna.
Ahora cada fila lleva su identidad en un `__row` oculto.

El resto:

- Un adjunto se servía inline con su propio mime, y la metacaja de wp-admin
  escribe esa misma meta desde cualquier ID de la mediateca: un SVG o un HTML
  se ejecutaba en el origen del sitio. Lo que no aceptó la aplicación se
  entrega como descarga opaca.
- El filtro `comments_clauses` se registraba por consulta y se desenganchaba
  solo en su primera llamada, que no ocurre cuando `WP_Comment_Query` responde
  desde su caché: quedaba puesto y vaciaba la actividad de un documento que su
  lector sí puede ver. Se registra una vez y decide mirando la consulta.
- `remove_role()` dejaba a los miembros del rol sin capacidad ninguna, ni
  `read`. Ahora pasan al rol por defecto antes de quitarlo.
- `page_url()` resolvía por slug e ignoraba `documentate_app_page_id`: renombrar
  la página dejaba en blanco todos los enlaces y redirecciones.
- `devolver_area` existe desde `en_gestion` y desde `pending`, y
  `confirmation()`, `redirect()` y `flag()` sólo miraban la clave.
- `mode()` fallaba en cualquier sistema donde `chmod` es cosmético (Windows,
  CIFS, bind mounts), bloqueando toda generación; y un render abortado dejaba
  su `.tmp` para siempre.
- `assign_missing()` escribía el marcador aunque `get_terms()` fallara, con lo
  que un tropiezo cancelaba la migración de layouts para siempre.
- La desinstalación dejaba la página, cuatro opciones y los documentos
  generados, que llevan datos personales.
- El último `__()` del plugin, en inglés sobre una interfaz en español.
- `nombre_completo` nunca llegaba a su valor de ejemplo, y el autoloader del
  PDF se apilaba una vez por instancia.
…oj no avance

`test_existing_document_preserves_dates` insertaba un borrador sin fecha, leía
su `post_date` y comprobaba que el update no lo movía. Un borrador sin fecha
lleva `post_date_gmt` a ceros, que para WordPress significa «esta fecha aún
flota» y la refresca en cada guardado: la comprobación solo se cumplía si el
insert y el update caían dentro del mismo segundo, y en CI no siempre caen.
Falló así en el último run de #283, esperando 06:50:23 y recibiendo 06:50:24.

Con la fecha puesta a mano deja de flotar, y cualquier desplazamiento pasa a
ser cosa del plugin, que es justo lo que el test quiere vigilar.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant