Skip to content

Commit c873af3

Browse files
committedNov 11, 2024
feat(core): implement frontends for all backends
1 parent 3ed9af8 commit c873af3

32 files changed

+986
-122
lines changed
 

‎.gitignore

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

‎.phpunit.result.cache

-1
This file was deleted.

‎phpunit.xml.dist

+2-8
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,11 @@
1313
</php>
1414

1515
<testsuites>
16-
<testsuite name="Snappy Dompdf backend">
17-
<directory>./src/Backend/Dompdf</directory>
18-
</testsuite>
19-
<testsuite name="Snappy WkHtmlToPdf backend">
20-
<directory>./src/Backend/WkHtmlToPdf</directory>
21-
</testsuite>
2216
<testsuite name="Snappy core">
23-
<directory>./src/Core/</directory>
17+
<directory>./src/Core/Tests/</directory>
2418
</testsuite>
2519
<testsuite name="Snappy Symfony framework integration">
26-
<directory>./src/Framework/Symfony/</directory>
20+
<directory>./src/Framework/Symfony/Tests/</directory>
2721
</testsuite>
2822
</testsuites>
2923
</phpunit>

‎src/Backend/Dompdf/DompdfAdapter.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ public function __construct(
3232
$this->options = $options;
3333
}
3434

35-
public function generateFromDOMDocument(DOMDocument $DOMDocument): StreamInterface
35+
public function generateFromDOMDocument(DOMDocument $document): StreamInterface
3636
{
3737
$dompdf = $this->buildDompdf();
38-
$dompdf->loadDOM($DOMDocument);
38+
$dompdf->loadDOM($document);
3939

4040
return $this->createStream($dompdf);
4141
}

‎src/Core/Backend/Adapter.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
interface Adapter
88
{
99
/**
10-
* @param Options|(callable(Options $options): Options) $options
10+
* @param (callable(Options $options): Options)|Options $options
1111
*/
12-
public function withOptions(Options|callable $options): static;
12+
public function withOptions(callable|Options $options): static;
1313
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ trait Reconfigurable
2121
/**
2222
* @return TAdapter
2323
*/
24-
public function withOptions(Options|callable $options): static
24+
public function withOptions(callable|Options $options): static
2525
{
2626
if (is_callable($options)) {
2727
$options = $options($this->options);
+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

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ final class Options
1414
public function __construct(
1515
public readonly ?PageOrientation $pageOrientation,
1616
public readonly array $extraOptions
17-
) {
18-
}
17+
) {}
1918

2019
public static function create(): self
2120
{

‎src/Core/Bridge/FromHtmlFileToHtmlToPdf.php

-36
This file was deleted.

‎src/Core/Bridge/FromHtmlToHtmlFileToPdf.php

-39
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)