fix(bootstrap): no duplicar inyección en </head> dentro de template literals

ESCRITURAS.HTML tiene una función exportPDF que genera HTML para una ventana
de impresión usando un template literal. Ese literal contiene `</head>`,
`</body>`, `</script>`, etc. como cadenas dentro de \`...\`.

Bootstrap::inject hacía str_replace('</head>', ...) que matchea TODAS las
ocurrencias — incluyendo las que están dentro del template literal del JS.
Resultado: inyectaba `<script>window.DONNA=...</script>` dentro del literal
del exportPDF, y ese `</script>` cerraba prematuramente el <script>
exterior. Todo el JS después del corte se renderizaba como texto plano en
la página (visible al final del view: `${fecha}`, `${rows.length}`, etc.).

Efectos colaterales del bug: el gear de Panel de Control no se mostraba en
escrituras porque el JS que lo activa (`if isSocio show gear`) estaba
después del corte y nunca corría.

Fix: usar strpos+substr para inyectar SOLO antes de la primera ocurrencia
de </head> (la legítima del <head> del documento).
This commit is contained in:
Soporte ZH Consultores
2026-06-05 00:19:36 +00:00
parent 684c83f2c9
commit 25f3d7461b
+8 -2
View File
@@ -31,8 +31,14 @@ final class Bootstrap {
http_response_code(500);
exit('Vista no disponible.');
}
$out = str_replace('</head>', $inject . "\n</head>", $html, $count);
if ($count === 0) {
// Inyectar SOLO antes de la primera ocurrencia de </head>. str_replace
// remplazaba todas — incluyendo las que viven dentro de template
// literals de JS (ej. en exportPDF), lo cual metía un </script>
// espurio que cortaba el <script> exterior del view.
$pos = strpos($html, '</head>');
if ($pos !== false) {
$out = substr($html, 0, $pos) . $inject . "\n" . substr($html, $pos);
} else {
$out = $inject . "\n" . $html;
}
echo $out;