Skip to content

Commit 8c58d7f

Browse files
authoredNov 19, 2024
feat(core): implement frontends for all backends (#506)
1 parent 3770bea commit 8c58d7f

29 files changed

+1009
-92
lines changed
 

‎.gitignore

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
**/composer.lock
2-
**/vendor
3-
**cache**
1+
/.php-cs-fixer.cache
2+
/.phpunit.result.cache
3+
/composer.lock
4+
/vendor

‎phpunit.xml.dist

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@
1313
</php>
1414

1515
<testsuites>
16-
<testsuite name="Snappy Dompdf backend">
16+
<testsuite name="knplabs/snappy-dompdf">
1717
<directory>./src/Backend/Dompdf</directory>
1818
</testsuite>
19-
<testsuite name="Snappy WkHtmlToPdf backend">
19+
<testsuite name="knplabs/snappy-wkhtmltopdf">
2020
<directory>./src/Backend/WkHtmlToPdf</directory>
2121
</testsuite>
22-
<testsuite name="Snappy core">
22+
<testsuite name="knplabs/snappy-core">
2323
<directory>./src/Core/</directory>
2424
</testsuite>
25-
<testsuite name="Snappy Symfony framework integration">
25+
<testsuite name="knplabs/snappy-symfony">
2626
<directory>./src/Framework/Symfony/</directory>
2727
</testsuite>
2828
</testsuites>

‎src/Backend/Dompdf/DompdfAdapter.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ public function __construct(DompdfFactory $factory, Options $options, private St
2626
$this->options = $options;
2727
}
2828

29-
public function generateFromDOMDocument(\DOMDocument $DOMDocument): StreamInterface
29+
public function generateFromDOMDocument(\DOMDocument $document): StreamInterface
3030
{
3131
$dompdf = $this->buildDompdf();
32-
$dompdf->loadDOM($DOMDocument);
32+
$dompdf->loadDOM($document);
3333

3434
return $this->createStream($dompdf);
3535
}

‎src/Core/Backend/Adapter/DOMDocumentToPdf.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99

1010
interface DOMDocumentToPdf extends Adapter
1111
{
12-
public function generateFromDOMDocument(\DOMDocument $DOMDocument): StreamInterface;
12+
public function generateFromDOMDocument(\DOMDocument $document): StreamInterface;
1313
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Core\Backend\Adapter;
6+
7+
use KNPLabs\Snappy\Core\Backend\Adapter;
8+
use Psr\Http\Message\StreamInterface;
9+
10+
interface StreamToPdf extends Adapter
11+
{
12+
public function generateFromStream(StreamInterface $stream): StreamInterface;
13+
}

‎src/Core/Backend/Options.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ final class Options
1111
/**
1212
* @param array<mixed> $extraOptions
1313
*/
14-
public function __construct(public readonly ?PageOrientation $pageOrientation, public readonly array $extraOptions) {}
14+
public function __construct(
15+
public readonly ?PageOrientation $pageOrientation,
16+
public readonly array $extraOptions
17+
) {}
1518

1619
public static function create(): self
1720
{

‎src/Core/Bridge/FromHtmlFileToHtmlToPdf.php

-31
This file was deleted.

‎src/Core/Bridge/FromHtmlToHtmlFileToPdf.php

-37
This file was deleted.

‎src/Core/Exception.php

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Core;
6+
7+
abstract class Exception extends \Exception {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Core\Exception;
6+
7+
use KNPLabs\Snappy\Core\Exception;
8+
9+
final class DOMDocumentException extends Exception {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Core\Exception;
6+
7+
use KNPLabs\Snappy\Core\Exception;
8+
9+
final class FileNotFoundException extends Exception {}
+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\Core\Exception;
6+
7+
use KNPLabs\Snappy\Core\Exception;
8+
9+
final class FileReadException extends Exception
10+
{
11+
public function __construct(\SplFileInfo $file)
12+
{
13+
file_exists($file->getPathname())
14+
? parent::__construct("File {$file->getPathname()} can't be read.")
15+
: parent::__construct("File {$file->getPathname()} not found.");
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Core\Exception;
6+
7+
use KNPLabs\Snappy\Core\Exception;
8+
9+
final class FrontendUnsupportedBackendException extends Exception
10+
{
11+
public function __construct(string $frontendClass, string $backendClass)
12+
{
13+
parent::__construct(
14+
\sprintf(
15+
'Snappy frontend "%s" does not support backend "%s"',
16+
$frontendClass,
17+
$backendClass,
18+
)
19+
);
20+
}
21+
}
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\Core\Exception;
6+
7+
use KNPLabs\Snappy\Core\Exception;
8+
9+
final class StreamDetachedException extends Exception
10+
{
11+
public function __construct()
12+
{
13+
parent::__construct('Stream is detached.');
14+
}
15+
}
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Core\Filesystem;
6+
7+
final class SplResourceInfo extends \SplFileInfo
8+
{
9+
/**
10+
* @param resource $resource
11+
*/
12+
public function __construct(public readonly mixed $resource)
13+
{
14+
parent::__construct(stream_get_meta_data($this->resource)['uri']);
15+
}
16+
17+
public static function fromTmpFile(): self
18+
{
19+
return new self(tmpfile());
20+
}
21+
}
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Core\Frontend;
6+
7+
use KNPLabs\Snappy\Core\Backend\Adapter;
8+
use KNPLabs\Snappy\Core\Backend\Options;
9+
use KNPLabs\Snappy\Core\Exception\DOMDocumentException;
10+
use KNPLabs\Snappy\Core\Exception\FrontendUnsupportedBackendException;
11+
use KNPLabs\Snappy\Core\Filesystem\SplResourceInfo;
12+
use Psr\Http\Message\StreamFactoryInterface;
13+
use Psr\Http\Message\StreamInterface;
14+
15+
final class DOMDocumentToPdf implements Adapter\DOMDocumentToPdf
16+
{
17+
public function __construct(private readonly Adapter $adapter, private readonly StreamFactoryInterface $streamFactory) {}
18+
19+
public function withOptions(callable|Options $options): static
20+
{
21+
return new self(
22+
$this->adapter->withOptions($options),
23+
$this->streamFactory,
24+
);
25+
}
26+
27+
public function generateFromDOMDocument(\DOMDocument $document): StreamInterface
28+
{
29+
if ($this->adapter instanceof Adapter\DOMDocumentToPdf) {
30+
return $this->adapter->generateFromDOMDocument($document);
31+
}
32+
33+
$html = $document->saveHTML();
34+
35+
if (false === $html) {
36+
throw new DOMDocumentException('Unable to read HTML from DOMDocument.');
37+
}
38+
39+
if ($this->adapter instanceof Adapter\HtmlToPdf) {
40+
return $this->adapter->generateFromHtml($html);
41+
}
42+
43+
if ($this->adapter instanceof Adapter\StreamToPdf) {
44+
return $this->adapter->generateFromStream(
45+
$this->streamFactory->createStream($html)
46+
);
47+
}
48+
49+
if ($this->adapter instanceof Adapter\HtmlFileToPdf) {
50+
$file = SplResourceInfo::fromTmpFile();
51+
52+
fwrite($file->resource, $html);
53+
54+
return $this->adapter->generateFromHtmlFile($file);
55+
}
56+
57+
throw new FrontendUnsupportedBackendException(
58+
self::class,
59+
$this->adapter::class,
60+
);
61+
}
62+
}

‎src/Core/Frontend/HtmlFileToPdf.php

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KNPLabs\Snappy\Core\Frontend;
6+
7+
use KNPLabs\Snappy\Core\Backend\Adapter;
8+
use KNPLabs\Snappy\Core\Backend\Options;
9+
use KNPLabs\Snappy\Core\Exception\FileReadException;
10+
use KNPLabs\Snappy\Core\Exception\FrontendUnsupportedBackendException;
11+
use KNPLabs\Snappy\Core\Stream\FileStream;
12+
use Psr\Http\Message\StreamFactoryInterface;
13+
use Psr\Http\Message\StreamInterface;
14+
15+
final class HtmlFileToPdf implements Adapter\HtmlFileToPdf
16+
{
17+
public function __construct(private readonly Adapter $adapter, private readonly StreamFactoryInterface $streamFactory) {}
18+
19+
public function withOptions(callable|Options $options): static
20+
{
21+
return new self(
22+
$this->adapter->withOptions($options),
23+
$this->streamFactory
24+
);
25+
}
26+
27+
public function generateFromHtmlFile(\SplFileInfo $file): StreamInterface
28+
{
29+
if ($this->adapter instanceof Adapter\HtmlFileToPdf) {
30+
return $this->adapter->generateFromHtmlFile($file);
31+
}
32+
33+
if ($this->adapter instanceof Adapter\StreamToPdf) {
34+
return $this->adapter->generateFromStream(
35+
new FileStream(
36+
$file,
37+
$this->streamFactory->createStreamFromFile($file->getPathname()),
38+
),
39+
);
40+
}
41+
42+
if ($this->adapter instanceof Adapter\HtmlToPdf) {
43+
$html = file_get_contents($file->getPathname());
44+
45+
if (false === $html) {
46+
throw new FileReadException($file);
47+
}
48+
49+
return $this->adapter->generateFromHtml($html);
50+
}
51+
52+
if ($this->adapter instanceof Adapter\DOMDocumentToPdf) {
53+
$document = new \DOMDocument();
54+
$document->loadHTMLFile($file->getPathname());
55+
56+
return $this->adapter->generateFromDOMDocument($document);
57+
}
58+
59+
throw new FrontendUnsupportedBackendException(
60+
self::class,
61+
$this->adapter::class,
62+
);
63+
}
64+
}

0 commit comments

Comments
 (0)