-
-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathPdf.php
More file actions
113 lines (91 loc) · 3.38 KB
/
Pdf.php
File metadata and controls
113 lines (91 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php
declare(strict_types=1);
/*
* This file is part of the community-maintained Playwright PHP project.
* It is not affiliated with or endorsed by Microsoft.
*
* (c) 2025-Present - Playwright PHP - https://github.com/playwright-php
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Playwright\Media\Pdf;
use Playwright\Exception\RuntimeException;
use Playwright\Media\Filesystem\FilesystemInterface;
use Playwright\Media\Screenshot\ScreenshotHelper;
use Playwright\Page\Options\PdfOptions;
use Playwright\Transport\TransportInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
final readonly class Pdf
{
public function __construct(
private TransportInterface $transport,
private FilesystemInterface $filesystem,
private LoggerInterface $logger = new NullLogger(),
) {
}
/**
* @param array<string, mixed>|PdfOptions $options
*/
public function take(string $pageId, ?string $path, string $url, array|PdfOptions $options = []): string
{
$options = PdfOptions::from($options);
$finalPath = $options->path() ?: '';
$finalPath .= $path;
if (null === $path) {
$finalPath .= $this->generateFilename($url);
}
if (null !== $options->path()) {
$options = $options->withPath(null);
}
$this->logger->debug('Generating PDF', ['path' => $finalPath, 'options' => $options->toArray()]);
try {
$finalPath = $this->filesystem->write($finalPath, $this->content($pageId, $options));
} catch (\Throwable $e) {
$this->logger->error('Failed to generate PDF', [
'path' => $finalPath,
'error' => $e->getMessage(),
'exception' => $e,
]);
throw $e;
}
$this->logger->info('PDF saved successfully', ['path' => $finalPath]);
return $finalPath;
}
/**
* @param array<string, mixed>|PdfOptions $options
*/
public function content(string $pageId, array|PdfOptions $options = []): string
{
$options = PdfOptions::from($options);
if (null !== $options->path()) {
throw new RuntimeException('Do not provide a "path" option when requesting inline PDF content.');
}
try {
/** @var array{binary: ?string} $response */
$response = $this->transport->send(
array_merge($options->toArray(), [
'action' => 'page.pdf',
'pageId' => $pageId,
]),
);
return base64_decode($response['binary'] ?? throw new \RuntimeException('Failed to retrieve PDF content'));
} catch (\Throwable $e) {
$this->logger->error('Failed to generate PDF', [
'error' => $e->getMessage(),
'exception' => $e,
]);
throw $e;
}
}
private function generateFilename(string $url): string
{
$now = microtime(true);
$datetime = date('Ymd_His', (int) $now);
$milliseconds = sprintf('%03d', ($now - floor($now)) * 1000);
$urlSlug = ScreenshotHelper::slugifyUrl($url);
$safeExtension = ltrim('pdf', '.');
return sprintf('%s_%s_%s.%s', $datetime, $milliseconds, $urlSlug, $safeExtension ?: 'pdf');
}
}