Skip to content

Commit 9f7adcf

Browse files
committed
feat: implement wkhtmltopdf backend
1 parent 3ed9af8 commit 9f7adcf

10 files changed

+190
-4
lines changed
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Backend\WkHtmlToPdf;
6+
7+
interface ExtraOption {
8+
/** @return array<string|int|float> */
9+
public function compile(): array;
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Backend\WkHtmlToPdf\ExtraOption;
6+
7+
use KNPLabs\Snappy\Backend\WkHtmlToPdf\ExtraOption;
8+
9+
final class CollateOption implements ExtraOption
10+
{
11+
public function __construct() {}
12+
13+
public function compile(): array
14+
{
15+
return ['--collate'];
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Backend\WkHtmlToPdf\ExtraOption;
6+
7+
use KNPLabs\Snappy\Backend\WkHtmlToPdf\ExtraOption;
8+
9+
final class CookieJarOption implements ExtraOption
10+
{
11+
public function __construct(public readonly string $path) {}
12+
13+
public function compile(): array
14+
{
15+
return ['--no-collate'];
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Backend\WkHtmlToPdf\ExtraOption;
6+
7+
use KNPLabs\Snappy\Backend\WkHtmlToPdf\ExtraOption;
8+
9+
final class CopiesOption implements ExtraOption
10+
{
11+
public function __construct(private readonly int $number) {}
12+
13+
public function compile(): array
14+
{
15+
return ['--copies', $this->number];
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Backend\WkHtmlToPdf\ExtraOption;
6+
7+
use KNPLabs\Snappy\Backend\WkHtmlToPdf\ExtraOption;
8+
9+
final class DpiOptions implements ExtraOption
10+
{
11+
public function __construct(private readonly int $dpi) {}
12+
13+
public function compile(): array
14+
{
15+
return ['--dpi', $this->dpi];
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Backend\WkHtmlToPdf\ExtraOption;
6+
7+
final class GrayscaleOption
8+
{
9+
public function __construct() {}
10+
11+
public function compile(): array
12+
{
13+
return ['--grayscale'];
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Backend\WkHtmlToPdf\ExtraOption;
6+
7+
final class ImageDpiOption
8+
{
9+
public function __construct(public readonly int $dpi) {}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Backend\WkHtmlToPdf\ExtraOption;
6+
7+
final class NoCollateOption
8+
{
9+
public function __construct() {}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Backend\WkHtmlToPdf\ExtraOption;
6+
7+
final class Orientation
8+
{
9+
public function __construct() {}
10+
}

src/Backend/WkHtmlToPdf/WkHtmlToPdfAdapter.php

+67-4
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,21 @@
44

55
namespace KNPLabs\Snappy\Backend\WkHtmlToPdf;
66

7-
use KNPLabs\Snappy\Core\Backend\Adapter;
7+
use KNPLabs\Snappy\Backend\WkHtmlToPdf\ExtraOption\Orientation;
88
use KNPLabs\Snappy\Core\Backend\Adapter\HtmlFileToPdf;
99
use KNPLabs\Snappy\Core\Backend\Adapter\Reconfigurable;
10+
use KNPLabs\Snappy\Core\Backend\Adapter\UriToPdf;
1011
use KNPLabs\Snappy\Core\Backend\Options;
12+
use KNPLabs\Snappy\Core\Backend\Options\PageOrientation;
13+
use KNPLabs\Snappy\Core\Stream\FileStream;
14+
use Psr\Http\Message\StreamFactoryInterface;
1115
use Psr\Http\Message\StreamInterface;
16+
use Psr\Http\Message\UriFactoryInterface;
17+
use Psr\Http\Message\UriInterface;
18+
use Symfony\Component\Process\Process;
1219
use SplFileInfo;
1320

14-
final class WkHtmlToPdfAdapter implements HtmlFileToPdf
21+
final class WkHtmlToPdfAdapter implements HtmlFileToPdf, UriToPdf
1522
{
1623
/**
1724
* @use Reconfigurable<self>
@@ -26,14 +33,70 @@ public function __construct(
2633
private string $binary,
2734
private int $timeout,
2835
WkHtmlToPdfFactory $factory,
29-
Options $options
36+
Options $options,
37+
private readonly StreamFactoryInterface $streamFactory,
38+
private readonly UriFactoryInterface $uriFactory,
3039
) {
3140
$this->factory = $factory;
41+
42+
foreach ($options->extraOptions as $extraOption) {
43+
if (!$extraOption instanceof ExtraOption) {
44+
throw new \InvalidArgumentException("Invalid option type");
45+
}
46+
}
47+
3248
$this->options = $options;
3349
}
3450

3551
public function generateFromHtmlFile(SplFileInfo $file): StreamInterface
3652
{
37-
throw new \Exception("Not implemented for {$this->binary} with timeout {$this->timeout}.");
53+
$filepath = $file->getRealPath();
54+
55+
if ($filepath === false) {
56+
throw new \RuntimeException("File not found: {$file->getPathname()}.");
57+
}
58+
59+
return $this->generateFromUri(
60+
$this->uriFactory->createUri($filepath)->withScheme('file')
61+
);
62+
}
63+
64+
public function generateFromUri(UriInterface $uri): StreamInterface
65+
{
66+
$outputStream = FileStream::createTmpFile($this->streamFactory);
67+
68+
$process = new Process(
69+
command: [
70+
$this->binary,
71+
...$this->compileOptions(),
72+
$uri->toString(),
73+
$outputStream->file->getPathname(),
74+
],
75+
timeout: $this->timeout,
76+
);
77+
78+
return $outputStream;
79+
}
80+
81+
/**
82+
* @return array<string|int|float>
83+
*/
84+
private function compileOptions(): array
85+
{
86+
return array_reduce(
87+
$this->options->extraOptions,
88+
fn (array $carry, ExtraOption $extraOption) =>
89+
$this->options->pageOrientation !== null && $extraOption instanceof Orientation
90+
? [
91+
...$carry,
92+
...(new Orientation($this->options->pageOrientation->value))->compile(),
93+
]
94+
: [
95+
...$carry,
96+
...$extraOption->compile(),
97+
]
98+
,
99+
[],
100+
);
38101
}
39102
}

0 commit comments

Comments
 (0)