Skip to content

Commit 8e5fee7

Browse files
committed
fix weasyprint process
1 parent 887ae8a commit 8e5fee7

2 files changed

Lines changed: 34 additions & 15 deletions

File tree

src/Controller/GeoroadBookController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ public function export(string $id, Request $request): JsonResponse
306306
$roadbook->saveOptions($options);
307307

308308
try {
309-
$roadbook->exportPdf($this->internalBaseUrl, $this->weasyprintUrl, $this->weasyprintBin);
309+
$roadbook->exportPdf($this->internalBaseUrl, $this->weasyprintUrl, $this->weasyprintBin, $this->publicDir);
310310
} catch (\RuntimeException $e) {
311311
$this->appLogger->error('PDF export failed', [
312312
'exception' => $e,

src/Roadbook/Roadbook.php

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,23 +68,28 @@ public function getPdfFile(): string
6868

6969
/**
7070
* Renders the raw roadbook page to PDF, either through the WeasyPrint
71-
* HTTP sidecar (dev/Docker) or the standalone `weasyprint` binary
72-
* (production, when $weasyprintUrl is "cli").
71+
* HTTP sidecar (dev/Docker) or the standalone `weasyprint` binary reading
72+
* the rendered HTML straight off disk (production, when $weasyprintUrl
73+
* is "cli" — no network hop, so $internalBaseUrl/DNS don't matter there).
7374
*
7475
* @throws \RuntimeException when the conversion fails
7576
*/
76-
public function exportPdf(string $internalBaseUrl, string $weasyprintUrl, string $weasyprintBin = 'weasyprint'): void
77+
public function exportPdf(string $internalBaseUrl, string $weasyprintUrl, string $weasyprintBin = 'weasyprint', ?string $publicDir = null): void
7778
{
7879
$pdfDir = dirname($this->getPdfFile());
7980
if (!is_dir($pdfDir)) {
8081
mkdir($pdfDir, 0775, true);
8182
}
8283

83-
$url = rtrim($internalBaseUrl, '/') . '/roadbook/' . $this->id . '/raw';
84-
85-
$body = $weasyprintUrl === 'cli'
86-
? $this->convertPdfViaCli($url, $weasyprintBin)
87-
: $this->convertPdfViaHttp($url, $weasyprintUrl);
84+
if ($weasyprintUrl === 'cli') {
85+
if ($publicDir === null) {
86+
throw new \RuntimeException('publicDir is required for CLI-mode PDF export.');
87+
}
88+
$body = $this->convertPdfViaCli($publicDir, $weasyprintBin);
89+
} else {
90+
$url = rtrim($internalBaseUrl, '/') . '/roadbook/' . $this->id . '/raw';
91+
$body = $this->convertPdfViaHttp($url, $weasyprintUrl);
92+
}
8893

8994
if (!$this->saveFile($this->getPdfFile(), $body)) {
9095
throw new \RuntimeException('Unable to write the PDF file.');
@@ -107,7 +112,7 @@ private function convertPdfViaHttp(string $url, string $weasyprintUrl): string
107112

108113
$body = @file_get_contents($convertUrl, false, $context);
109114
$status = 0;
110-
foreach (http_get_last_response_headers() as $header) {
115+
foreach (http_get_last_response_headers() ?? [] as $header) {
111116
if (preg_match('#^HTTP/\S+\s+(\d{3})#', $header, $m)) {
112117
$status = (int) $m[1];
113118
}
@@ -129,25 +134,39 @@ private function convertPdfViaHttp(string $url, string $weasyprintUrl): string
129134
return $body;
130135
}
131136

132-
private function convertPdfViaCli(string $url, string $weasyprintBin): string
137+
private function convertPdfViaCli(string $publicDir, string $weasyprintBin): string
133138
{
134-
$outputFile = tempnam(sys_get_temp_dir(), 'weasyprint_');
139+
$html = $this->twig->render('raw.twig.html', [
140+
'suffix_css_js' => '',
141+
'style' => $this->getCustomCss(),
142+
'content' => (string) file_get_contents($this->getHtmlFile()),
143+
]);
144+
145+
$htmlFile = tempnam(sys_get_temp_dir(), 'weasyprint_src_') . '.html';
146+
$outputFile = tempnam(sys_get_temp_dir(), 'weasyprint_out_');
135147

136148
try {
137-
$process = new Process([$weasyprintBin, $url, $outputFile], timeout: 120);
149+
file_put_contents($htmlFile, $html);
150+
151+
// Rendered from disk directly: relative/absolute asset paths (/design,
152+
// /img, /images) resolve against the local filesystem, no HTTP round-trip.
153+
$baseUrl = 'file://' . rtrim($publicDir, '/') . '/';
154+
155+
$process = new Process([$weasyprintBin, $htmlFile, $outputFile, '--base-url', $baseUrl], timeout: 120);
138156
$process->run();
139157

140158
if (!$process->isSuccessful()) {
141-
throw new \RuntimeException(sprintf('PDF conversion failed (weasyprint_bin=%s, raw_url=%s): %s', $weasyprintBin, $url, trim($process->getErrorOutput()) !== '' ? trim($process->getErrorOutput()) : trim($process->getOutput())), previous: new ProcessFailedException($process));
159+
throw new \RuntimeException(sprintf('PDF conversion failed (weasyprint_bin=%s, roadbook_id=%s): %s', $weasyprintBin, $this->id, trim($process->getErrorOutput()) !== '' ? trim($process->getErrorOutput()) : trim($process->getOutput())), previous: new ProcessFailedException($process));
142160
}
143161

144162
$body = file_get_contents($outputFile);
145163
if ($body === false || $body === '') {
146-
throw new \RuntimeException(sprintf('PDF conversion produced an empty file (weasyprint_bin=%s, raw_url=%s)', $weasyprintBin, $url));
164+
throw new \RuntimeException(sprintf('PDF conversion produced an empty file (weasyprint_bin=%s, roadbook_id=%s)', $weasyprintBin, $this->id));
147165
}
148166

149167
return $body;
150168
} finally {
169+
@unlink($htmlFile);
151170
@unlink($outputFile);
152171
}
153172
}

0 commit comments

Comments
 (0)