From ae88dfa55f8939b66a73e2e5d61cb19ba1709579 Mon Sep 17 00:00:00 2001 From: PedroTroller Date: Wed, 16 Oct 2024 16:12:27 +0200 Subject: [PATCH] feat(core): implement frontends for all backends --- .gitignore | 2 + .phpunit.result.cache | 1 - phpunit.xml.dist | 10 +- src/Backend/Dompdf/DompdfAdapter.php | 4 +- src/Core/Backend/Adapter/StreamToPdf.php | 13 ++ src/Core/Bridge/FromHtmlFileToHtmlToPdf.php | 36 ------ src/Core/Bridge/FromHtmlToHtmlFileToPdf.php | 39 ------ src/Core/Filesystem/SplResourceInfo.php | 21 ++++ src/Core/Frontend/DOMDocumentToPdf.php | 62 ++++++++++ src/Core/Frontend/HtmlFileToPdf.php | 64 ++++++++++ src/Core/Frontend/HtmlToPdf.php | 60 +++++++++ src/Core/Frontend/StreamToPdf.php | 64 ++++++++++ src/Core/Stream/FileStream.php | 15 --- .../Tests/Filesystem/SplResourceInfoTest.php | 24 ++++ .../Tests/Frontend/DOMDocumentToPdfTest.php | 107 ++++++++++++++++ src/Core/Tests/Frontend/HtmlFileToPdfTest.php | 115 ++++++++++++++++++ src/Core/Tests/Frontend/HtmlToPdfTest.php | 112 +++++++++++++++++ src/Core/Tests/Frontend/StreamToPdfTest.php | 111 +++++++++++++++++ src/Core/Tests/Stream/FileStreamTest.php | 12 +- src/Core/composer.json | 3 +- src/Core/phpunit.xml.dist | 20 +++ .../DependencyInjection/SnappyExtension.php | 58 ++++++++- .../SnappyExtensionTest.php | 45 ++++++- 23 files changed, 884 insertions(+), 114 deletions(-) delete mode 100644 .phpunit.result.cache create mode 100644 src/Core/Backend/Adapter/StreamToPdf.php delete mode 100644 src/Core/Bridge/FromHtmlFileToHtmlToPdf.php delete mode 100644 src/Core/Bridge/FromHtmlToHtmlFileToPdf.php create mode 100644 src/Core/Filesystem/SplResourceInfo.php create mode 100644 src/Core/Frontend/DOMDocumentToPdf.php create mode 100644 src/Core/Frontend/HtmlFileToPdf.php create mode 100644 src/Core/Frontend/HtmlToPdf.php create mode 100644 src/Core/Frontend/StreamToPdf.php create mode 100644 src/Core/Tests/Filesystem/SplResourceInfoTest.php create mode 100644 src/Core/Tests/Frontend/DOMDocumentToPdfTest.php create mode 100644 src/Core/Tests/Frontend/HtmlFileToPdfTest.php create mode 100644 src/Core/Tests/Frontend/HtmlToPdfTest.php create mode 100644 src/Core/Tests/Frontend/StreamToPdfTest.php create mode 100644 src/Core/phpunit.xml.dist diff --git a/.gitignore b/.gitignore index ff72e2d0..3c04f0ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ +/.php-cs-fixer.cache +/.phpunit.result.cache /composer.lock /vendor diff --git a/.phpunit.result.cache b/.phpunit.result.cache deleted file mode 100644 index 7399b970..00000000 --- a/.phpunit.result.cache +++ /dev/null @@ -1 +0,0 @@ -{"version":1,"defects":{"KNPLabs\\Snappy\\Framework\\Symfony\\Tests\\DependencyInjection\\SnappyExtensionTest::testLoadEmptyConfiguration":8,"KNPLabs\\Snappy\\Framework\\Symfony\\Tests\\DependencyInjection\\SnappyExtensionTest::testConfigure":5,"KNPLabs\\Snappy\\Framework\\Symfony\\Tests\\DependencyInjection\\SnappyExtensionTest::testConfigureTmpDirectory":7,"KNPLabs\\Snappy\\Framework\\Symfony\\Tests\\DependencyInjection\\SnappyExtensionTest::testDompdfBackendConfiguration":8,"KNPLabs\\Snappy\\Core\\Tests\\Stream\\FileStreamTest::testTmpFileIsAutomaticalyRemoved":8},"times":{"KNPLabs\\Snappy\\Framework\\Symfony\\Tests\\DependencyInjection\\SnappyExtensionTest::testLoadEmptyConfiguration":0.008,"KNPLabs\\Snappy\\Framework\\Symfony\\Tests\\DependencyInjection\\SnappyExtensionTest::testConfigure":0,"KNPLabs\\Snappy\\Framework\\Symfony\\Tests\\DependencyInjection\\SnappyExtensionTest::testConfigureTmpDirectory":0,"KNPLabs\\Snappy\\Framework\\Symfony\\Tests\\DependencyInjection\\SnappyExtensionTest::testDompdfBackendConfiguration":0.015,"KNPLabs\\Snappy\\Core\\Tests\\Stream\\FileStreamTest::testTmpFileStream":0.005,"KNPLabs\\Snappy\\Core\\Tests\\Stream\\FileStreamTest::testTmpFileStreamCreateTemporaryFile":0.003,"KNPLabs\\Snappy\\Core\\Tests\\Stream\\FileStreamTest::testTmpFileStreamReadTheFile":0.004,"KNPLabs\\Snappy\\Core\\Tests\\Stream\\FileStreamTest::testTmpFileIsAutomaticalyRemoved":0.003}} \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist index f42624f3..d0ec867c 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -13,17 +13,11 @@ - - ./src/Backend/Dompdf - - - ./src/Backend/WkHtmlToPdf - - ./src/Core/ + ./src/Core/Tests/ - ./src/Framework/Symfony/ + ./src/Framework/Symfony/Tests/ diff --git a/src/Backend/Dompdf/DompdfAdapter.php b/src/Backend/Dompdf/DompdfAdapter.php index f46ab4fc..6dc46be0 100644 --- a/src/Backend/Dompdf/DompdfAdapter.php +++ b/src/Backend/Dompdf/DompdfAdapter.php @@ -32,10 +32,10 @@ public function __construct( $this->options = $options; } - public function generateFromDOMDocument(DOMDocument $DOMDocument): StreamInterface + public function generateFromDOMDocument(DOMDocument $document): StreamInterface { $dompdf = $this->buildDompdf(); - $dompdf->loadDOM($DOMDocument); + $dompdf->loadDOM($document); return $this->createStream($dompdf); } diff --git a/src/Core/Backend/Adapter/StreamToPdf.php b/src/Core/Backend/Adapter/StreamToPdf.php new file mode 100644 index 00000000..466e3ffd --- /dev/null +++ b/src/Core/Backend/Adapter/StreamToPdf.php @@ -0,0 +1,13 @@ +getPathname()); - - if (false === $html) { - throw new \RuntimeException('Unable to read file.'); - } - - return $this->adapter->generateFromHtml($html); - } - - public function withOptions(Options|callable $options): self - { - return new self( $this->adapter->withOptions($options)); - } -} diff --git a/src/Core/Bridge/FromHtmlToHtmlFileToPdf.php b/src/Core/Bridge/FromHtmlToHtmlFileToPdf.php deleted file mode 100644 index 03f2e397..00000000 --- a/src/Core/Bridge/FromHtmlToHtmlFileToPdf.php +++ /dev/null @@ -1,39 +0,0 @@ -streamFactory); - - file_put_contents($temporary->file->getPathname(), $html); - - return $this->adapter->generateFromHtmlFile($temporary->file); - } - - public function withOptions(Options|callable $options): self - { - return new self( - $this->adapter->withOptions($options), - $this->streamFactory, - ); - } -} diff --git a/src/Core/Filesystem/SplResourceInfo.php b/src/Core/Filesystem/SplResourceInfo.php new file mode 100644 index 00000000..5578c1d1 --- /dev/null +++ b/src/Core/Filesystem/SplResourceInfo.php @@ -0,0 +1,21 @@ +resource)['uri']); + } +} diff --git a/src/Core/Frontend/DOMDocumentToPdf.php b/src/Core/Frontend/DOMDocumentToPdf.php new file mode 100644 index 00000000..acc0c6eb --- /dev/null +++ b/src/Core/Frontend/DOMDocumentToPdf.php @@ -0,0 +1,62 @@ +adapter->withOptions($options), + $this->streamFactory, + ); + } + + public function generateFromDOMDocument(DOMDocument $document): StreamInterface + { + if ($this->adapter instanceof Adapter\DOMDocumentToPdf) { + return $this->adapter->generateFromDOMDocument($document); + } + + $html = $document->saveHTML(); + + if (false === $html) { + throw new \Exception(); + } + + if ($this->adapter instanceof Adapter\HtmlToPdf) { + return $this->adapter->generateFromHtml($html); + } + + if ($this->adapter instanceof Adapter\StreamToPdf) { + return $this->adapter->generateFromStream( + $this->streamFactory->createStream($html) + ); + } + + if ($this->adapter instanceof Adapter\HtmlFileToPdf) { + $file = SplResourceInfo::fromTmpFile(); + + fwrite($file->resource, $html); + + return $this->adapter->generateFromHtmlFile($file); + } + + throw new \Exception(); + } +} diff --git a/src/Core/Frontend/HtmlFileToPdf.php b/src/Core/Frontend/HtmlFileToPdf.php new file mode 100644 index 00000000..24e7be80 --- /dev/null +++ b/src/Core/Frontend/HtmlFileToPdf.php @@ -0,0 +1,64 @@ +adapter->withOptions($options), + $this->streamFactory + ); + } + + public function generateFromHtmlFile(SplFileInfo $file): StreamInterface + { + if ($this->adapter instanceof Adapter\HtmlFileToPdf) { + return $this->adapter->generateFromHtmlFile($file); + } + + if ($this->adapter instanceof Adapter\StreamToPdf) { + return $this->adapter->generateFromStream( + new FileStream( + $file, + $this->streamFactory->createStreamFromFile($file->getPathname()), + ), + ); + } + + if ($this->adapter instanceof Adapter\HtmlToPdf) { + $html = file_get_contents($file->getPathname()); + + if (false === $html) { + throw new \Exception("Unable to read content of {$file->getPathname()}."); + } + + return $this->adapter->generateFromHtml($html); + } + + if ($this->adapter instanceof Adapter\DOMDocumentToPdf) { + $document = new \DOMDocument(); + $document->loadHTMLFile($file->getPathname()); + + return $this->adapter->generateFromDOMDocument($document); + } + + throw new \Exception(); + } +} diff --git a/src/Core/Frontend/HtmlToPdf.php b/src/Core/Frontend/HtmlToPdf.php new file mode 100644 index 00000000..7d2c7980 --- /dev/null +++ b/src/Core/Frontend/HtmlToPdf.php @@ -0,0 +1,60 @@ +adapter->withOptions($options), + $this->streamFactory + ); + } + + public function generateFromHtml(string $html): StreamInterface + { + if ($this->adapter instanceof Adapter\HtmlToPdf) { + return $this->adapter->generateFromHtml($html); + } + + if ($this->adapter instanceof Adapter\DOMDocumentToPdf) { + $document = new \DOMDocument(); + $document->loadHTML($html); + + return $this->adapter->generateFromDOMDocument($document); + } + + if ($this->adapter instanceof Adapter\StreamToPdf) { + return $this->adapter->generateFromStream( + $this->streamFactory->createStream($html), + ); + } + + if ($this->adapter instanceof Adapter\HtmlFileToPdf) { + $file = SplResourceInfo::fromTmpFile(); + + fwrite($file->resource, $html); + + return $this->adapter->generateFromHtmlFile($file); + } + + throw new \Exception(); + } + +} diff --git a/src/Core/Frontend/StreamToPdf.php b/src/Core/Frontend/StreamToPdf.php new file mode 100644 index 00000000..72238965 --- /dev/null +++ b/src/Core/Frontend/StreamToPdf.php @@ -0,0 +1,64 @@ +adapter->withOptions($options), + $this->streamFactory + ); + } + + public function generateFromStream(StreamInterface $stream): StreamInterface + { + if ($this->adapter instanceof Adapter\StreamToPdf) { + return $this->adapter->generateFromStream($stream); + } + + if ($this->adapter instanceof Adapter\HtmlToPdf) { + return $this->adapter->generateFromHtml((string) $stream); + } + + if ($this->adapter instanceof Adapter\HtmlFileToPdf) { + $file = SplResourceInfo::fromTmpFile(); + + $input = $stream->detach(); + + if (null === $input) { + throw new \Exception('Unable to get resource from stream.'); + } + + stream_copy_to_stream($input, $file->resource); + + return $this->adapter->generateFromHtmlFile($file); + } + + if ($this->adapter instanceof Adapter\DOMDocumentToPdf) { + $document = new \DOMDocument(); + $document->loadHTML((string) $stream); + + return $this->adapter->generateFromDOMDocument($document); + } + + throw new \Exception(); + } +} diff --git a/src/Core/Stream/FileStream.php b/src/Core/Stream/FileStream.php index 3e115434..cf03f9e2 100644 --- a/src/Core/Stream/FileStream.php +++ b/src/Core/Stream/FileStream.php @@ -12,21 +12,6 @@ final class FileStream implements StreamInterface { use StreamWrapper; - public static function createTmpFile(StreamFactoryInterface $streamFactory): self - { - $stream = $streamFactory->createStreamFromResource(tmpFile()); - $filename = $stream->getMetadata('uri'); - - if (false === is_string($filename)) { - throw new \UnexpectedValueException('Unable to retrieve the uri of the temporary file created.'); - } - - return new self( - new SplFileInfo($filename), - $stream - ); - } - public function __construct(public readonly SplFileInfo $file, StreamInterface $stream) { $this->stream = $stream; diff --git a/src/Core/Tests/Filesystem/SplResourceInfoTest.php b/src/Core/Tests/Filesystem/SplResourceInfoTest.php new file mode 100644 index 00000000..ba21b7d5 --- /dev/null +++ b/src/Core/Tests/Filesystem/SplResourceInfoTest.php @@ -0,0 +1,24 @@ +getPathname(); + + $this->assertFileExists($path); + + unset($file); + + $this->assertFileDoesNotExist($path); + } +} diff --git a/src/Core/Tests/Frontend/DOMDocumentToPdfTest.php b/src/Core/Tests/Frontend/DOMDocumentToPdfTest.php new file mode 100644 index 00000000..f11822a2 --- /dev/null +++ b/src/Core/Tests/Frontend/DOMDocumentToPdfTest.php @@ -0,0 +1,107 @@ +output = $this->createStub(StreamInterface::class); + $this->streamFactory = new Psr17Factory(); + $this->document = new \DOMDocument(); + $this->document->loadHTML(''); + } + + public function testWithDOMDocumentToPdf(): void + { + $backend = $this->createMock(Adapter\DOMDocumentToPdf::class); + $frontend = new Frontend\DOMDocumentToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromDOMDocument') + ->with($this->document) + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromDOMDocument($this->document), + $this->output, + ); + } + + public function testWithHtmlToPdf(): void + { + $backend = $this->createMock(Adapter\HtmlToPdf::class); + $frontend = new Frontend\DOMDocumentToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromHtml') + ->with($this->document->saveHTML()) + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromDOMDocument($this->document), + $this->output, + ); + } + + public function testWithHtmlFileToPdf(): void + { + $backend = $this->createMock(Adapter\HtmlFileToPdf::class); + $frontend = new Frontend\DOMDocumentToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromHtmlFile') + ->with( + new Constraint\Callback( + fn (\SplFileInfo $file) => $this->document->saveHTML() === file_get_contents($file->getPathname()) + ) + ) + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromDOMDocument($this->document), + $this->output, + ); + } + + public function testWithStreamToPdf(): void + { + $backend = $this->createMock(Adapter\StreamToPdf::class); + $frontend = new Frontend\DOMDocumentToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromStream') + ->with( + new Constraint\Callback( + fn (StreamInterface $stream) => $this->document->saveHTML() === (string) $stream + ) + ) + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromDOMDocument($this->document), + $this->output, + ); + } +} diff --git a/src/Core/Tests/Frontend/HtmlFileToPdfTest.php b/src/Core/Tests/Frontend/HtmlFileToPdfTest.php new file mode 100644 index 00000000..dc473b89 --- /dev/null +++ b/src/Core/Tests/Frontend/HtmlFileToPdfTest.php @@ -0,0 +1,115 @@ +output = $this->createStub(StreamInterface::class); + $this->streamFactory = new Psr17Factory(); + $this->file = SplResourceInfo::fromTmpFile(); + + fwrite($this->file->resource, ''); + } + + public function testWithDOMDocumentToPdf(): void + { + $backend = $this->createMock(Adapter\DOMDocumentToPdf::class); + $frontend = new Frontend\HtmlFileToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromDOMDocument') + ->with( + new Constraint\Callback( + function (\DOMDocument $document) { + $expected = new \DOMDocument(); + $expected->loadHTML(''); + + return $document->saveHTML() === $expected->saveHTML(); + } + ) + ) + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromHtmlFile($this->file), + $this->output, + ); + } + + public function testWithHtmlToPdf(): void + { + $backend = $this->createMock(Adapter\HtmlToPdf::class); + $frontend = new Frontend\HtmlFileToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromHtml') + ->with('') + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromHtmlFile($this->file), + $this->output, + ); + } + + public function testWithHtmlFileToPdf(): void + { + $backend = $this->createMock(Adapter\HtmlFileToPdf::class); + $frontend = new Frontend\HtmlFileToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromHtmlFile') + ->with($this->file) + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromHtmlFile($this->file), + $this->output, + ); + } + + public function testWithStreamToPdf(): void + { + $backend = $this->createMock(Adapter\StreamToPdf::class); + $frontend = new Frontend\HtmlFileToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromStream') + ->with( + new Constraint\Callback( + fn (StreamInterface $stream) => '' === (string) $stream, + ) + ) + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromHtmlFile($this->file), + $this->output, + ); + } +} diff --git a/src/Core/Tests/Frontend/HtmlToPdfTest.php b/src/Core/Tests/Frontend/HtmlToPdfTest.php new file mode 100644 index 00000000..26c11f1d --- /dev/null +++ b/src/Core/Tests/Frontend/HtmlToPdfTest.php @@ -0,0 +1,112 @@ +output = $this->createStub(StreamInterface::class); + $this->streamFactory = new Psr17Factory(); + } + + public function testWithDOMDocumentToPdf(): void + { + $backend = $this->createMock(Adapter\DOMDocumentToPdf::class); + $frontend = new Frontend\HtmlToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromDOMDocument') + ->with( + new Constraint\Callback( + function (\DOMDocument $document) { + $expected = new \DOMDocument(); + $expected->loadHTML(''); + + return $document->saveHTML() === $expected->saveHTML(); + } + ) + ) + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromHtml(''), + $this->output, + ); + } + + public function testWithHtmlToPdf(): void + { + $backend = $this->createMock(Adapter\HtmlToPdf::class); + $frontend = new Frontend\HtmlToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromHtml') + ->with('') + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromHtml(''), + $this->output, + ); + } + + public function testWithHtmlFileToPdf(): void + { + $backend = $this->createMock(Adapter\HtmlFileToPdf::class); + $frontend = new Frontend\HtmlToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromHtmlFile') + ->with( + new Constraint\Callback( + fn (\SplFileInfo $file) => '' === file_get_contents($file->getPathname()) + ) + ) + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromHtml(''), + $this->output, + ); + } + + public function testWithStreamToPdf(): void + { + $backend = $this->createMock(Adapter\StreamToPdf::class); + $frontend = new Frontend\HtmlToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromStream') + ->with( + new Constraint\Callback( + fn (StreamInterface $stream) => '' === (string) $stream, + ) + ) + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromHtml(''), + $this->output, + ); + } +} diff --git a/src/Core/Tests/Frontend/StreamToPdfTest.php b/src/Core/Tests/Frontend/StreamToPdfTest.php new file mode 100644 index 00000000..c1b3c1ab --- /dev/null +++ b/src/Core/Tests/Frontend/StreamToPdfTest.php @@ -0,0 +1,111 @@ +output = $this->createStub(StreamInterface::class); + $this->streamFactory = new Psr17Factory(); + $this->stream = $this->streamFactory->createStream(''); + } + + public function testWithDOMDocumentToPdf(): void + { + $backend = $this->createMock(Adapter\DOMDocumentToPdf::class); + $frontend = new Frontend\StreamToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromDOMDocument') + ->with( + new Constraint\Callback( + function (\DOMDocument $document) { + $expected = new \DOMDocument(); + $expected->loadHTML(''); + + return $document->saveHTML() === $expected->saveHTML(); + } + ) + ) + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromStream($this->stream), + $this->output, + ); + } + + public function testWithHtmlToPdf(): void + { + $backend = $this->createMock(Adapter\HtmlToPdf::class); + $frontend = new Frontend\StreamToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromHtml') + ->with((string) $this->stream) + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromStream($this->stream), + $this->output, + ); + } + + public function testWithHtmlFileToPdf(): void + { + $backend = $this->createMock(Adapter\HtmlFileToPdf::class); + $frontend = new Frontend\StreamToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromHtmlFile') + ->with( + new Constraint\Callback( + fn (\SplFileInfo $file) => '' === file_get_contents($file->getPathname()) + ) + ) + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromStream($this->stream), + $this->output, + ); + } + + public function testWithStreamToPdf(): void + { + $backend = $this->createMock(Adapter\StreamToPdf::class); + $frontend = new Frontend\StreamToPdf($backend, $this->streamFactory); + + $backend + ->method('generateFromStream') + ->with($this->stream) + ->willReturn($this->output) + ; + + $this->assertSame( + $frontend->generateFromStream($this->stream), + $this->output, + ); + } +} diff --git a/src/Core/Tests/Stream/FileStreamTest.php b/src/Core/Tests/Stream/FileStreamTest.php index f5d88ed4..7fdccc21 100644 --- a/src/Core/Tests/Stream/FileStreamTest.php +++ b/src/Core/Tests/Stream/FileStreamTest.php @@ -4,6 +4,7 @@ namespace KNPLabs\Snappy\Core\Tests\Stream; +use KNPLabs\Snappy\Core\Filesystem\SplResourceInfo; use KNPLabs\Snappy\Core\Stream\FileStream; use Nyholm\Psr7\Factory\Psr17Factory; use PHPUnit\Framework\TestCase; @@ -14,8 +15,11 @@ final class FileStreamTest extends TestCase public function setUp(): void { - $this->stream = FileStream::createTmpFile( - new Psr17Factory, + $file = SplResourceInfo::fromTmpFile(); + + $this->stream = new FileStream( + $file, + (new Psr17Factory())->createStreamFromResource($file->resource), ); } @@ -24,8 +28,8 @@ public function testTmpFileStreamCreateTemporaryFile(): void $file = $this->stream->file; $this->assertFileExists($file->getPathname()); - $this->assertFileIsReadable( $file->getPathname()); - $this->assertFileIsWritable( $file->getPathname()); + $this->assertFileIsReadable($file->getPathname()); + $this->assertFileIsWritable($file->getPathname()); } public function testTmpFileStreamReadTheFile(): void diff --git a/src/Core/composer.json b/src/Core/composer.json index 7616157e..5d0fdf6b 100644 --- a/src/Core/composer.json +++ b/src/Core/composer.json @@ -2,6 +2,7 @@ "name": "knplabs/snappy-core", "require": { "php": ">=8.1", + "psr/http-factory": "^1.1", "psr/http-message": "^2.0" }, "require-dev": { @@ -13,4 +14,4 @@ "KNPLabs\\Snappy\\Core\\": "./" } } -} \ No newline at end of file +} diff --git a/src/Core/phpunit.xml.dist b/src/Core/phpunit.xml.dist new file mode 100644 index 00000000..efb18ef8 --- /dev/null +++ b/src/Core/phpunit.xml.dist @@ -0,0 +1,20 @@ + + + + + + + + + + ./Tests/ + + + diff --git a/src/Framework/Symfony/DependencyInjection/SnappyExtension.php b/src/Framework/Symfony/DependencyInjection/SnappyExtension.php index 7e138013..9e63034d 100644 --- a/src/Framework/Symfony/DependencyInjection/SnappyExtension.php +++ b/src/Framework/Symfony/DependencyInjection/SnappyExtension.php @@ -4,20 +4,32 @@ namespace KNPLabs\Snappy\Framework\Symfony\DependencyInjection; +use KNPLabs\Snappy\Core\Backend\Adapter; +use KNPLabs\Snappy\Core\Backend\Factory; use KNPLabs\Snappy\Core\Backend\Options; use KNPLabs\Snappy\Core\Backend\Options\PageOrientation; use KNPLabs\Snappy\Core\Filesystem\TmpDirectory; +use KNPLabs\Snappy\Core\Frontend; use KNPLabs\Snappy\Framework\Symfony\DependencyInjection\Configuration\AdapterConfigurationFactory; use KNPLabs\Snappy\Framework\Symfony\DependencyInjection\Configuration\BackendConfigurationFactory; use KNPLabs\Snappy\Framework\Symfony\DependencyInjection\Configuration\DompdfConfigurationFactory; use KNPLabs\Snappy\Framework\Symfony\DependencyInjection\Configuration\WkHtmlToPdfConfigurationFactory; +use Psr\Http\Message\StreamFactoryInterface; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Extension\Extension; +use Symfony\Component\DependencyInjection\Reference; final class SnappyExtension extends Extension { + private const FRONTENDS = [ + Adapter\DOMDocumentToPdf::class => Frontend\DOMDocumentToPdf::class, + Adapter\HtmlFileToPdf::class => Frontend\HtmlFileToPdf::class, + Adapter\HtmlToPdf::class => Frontend\HtmlToPdf::class, + Adapter\StreamToPdf::class => Frontend\StreamToPdf::class, + ]; + public function load(array $configuration, ContainerBuilder $container): void { $configuration = $this->processConfiguration( @@ -48,6 +60,25 @@ public function load(array $configuration, ContainerBuilder $container): void $options, ) ; + + foreach (self::FRONTENDS as $adapterClass => $frontendClass) { + $frontendId = $this->buildFrontendServiceId($backendName, $frontendClass); + + $container + ->setDefinition( + $frontendId, + new Definition( + $frontendClass, + [ + '$adapter' => new Reference($backendId), + '$streamFactory' => new Reference(StreamFactoryInterface::class), + ], + ), + ) + ; + } + + $container->registerAliasForArgument($frontendId, $adapterClass, $backendName); } } } @@ -79,7 +110,7 @@ private function getFactories(): array */ private function buildBackendServiceId(string $name): string { - return "snappy.backend.$name"; + return $this->normalizeId(Adapter::class).".".$name; } /** @@ -87,7 +118,26 @@ private function buildBackendServiceId(string $name): string */ private function buildFactoryServiceId(string $name): string { - return "snappy.backend.$name.factory"; + return $this->normalizeId(Factory::class).'.'.$name; + } + + /** + * @return non-empty-string + * @param class-string $class + */ + private function buildFrontendServiceId(string $name, string $class): string + { + return $this->normalizeId($class).'.'.$name; + } + + /** + * @param non-empty-string $id + * + * @return non-empty-string + */ + private function normalizeId(string $id): string + { + return strtolower(str_replace('\\', '.', $id)); } /** @@ -112,7 +162,7 @@ private function buildOptions(string $backendName, string $backendType, array $c ); } - $arguments[ '$pageOrientation'] = PageOrientation::from($configuration['pageOrientation']); + $arguments['$pageOrientation'] = PageOrientation::from($configuration['pageOrientation']); } if (isset($configuration['extraOptions'])) { @@ -127,7 +177,7 @@ private function buildOptions(string $backendName, string $backendType, array $c ); } - $arguments[ '$extraOptions'] = $configuration['extraOptions']; + $arguments['$extraOptions'] = $configuration['extraOptions']; } return new Definition( Options::class, $arguments); diff --git a/src/Framework/Symfony/Tests/DependencyInjection/SnappyExtensionTest.php b/src/Framework/Symfony/Tests/DependencyInjection/SnappyExtensionTest.php index f38c0f69..b4ed5156 100644 --- a/src/Framework/Symfony/Tests/DependencyInjection/SnappyExtensionTest.php +++ b/src/Framework/Symfony/Tests/DependencyInjection/SnappyExtensionTest.php @@ -7,6 +7,7 @@ use KNPLabs\Snappy\Backend\Dompdf\DompdfAdapter; use KNPLabs\Snappy\Backend\Dompdf\DompdfFactory; use KNPLabs\Snappy\Core\Backend\Adapter; +use KNPLabs\Snappy\Core\Frontend; use KNPLabs\Snappy\Core\Backend\Options; use KNPLabs\Snappy\Core\Backend\Options\PageOrientation; use KNPLabs\Snappy\Core\Filesystem\TmpDirectory; @@ -84,8 +85,12 @@ public function testDompdfBackendConfiguration(): void [ 'service_container', StreamFactoryInterface::class, - 'snappy.backend.myBackend.factory', - 'snappy.backend.myBackend', + 'knplabs.snappy.core.backend.factory.myBackend', + 'knplabs.snappy.core.backend.adapter.myBackend', + 'knplabs.snappy.core.frontend.domdocumenttopdf.myBackend', + 'knplabs.snappy.core.frontend.htmlfiletopdf.myBackend', + 'knplabs.snappy.core.frontend.htmltopdf.myBackend', + 'knplabs.snappy.core.frontend.streamtopdf.myBackend', ] ); @@ -93,7 +98,7 @@ public function testDompdfBackendConfiguration(): void $this->assertInstanceOf(StreamFactoryInterface::class, $streamFactory); - $factory = $this->container->get('snappy.backend.myBackend.factory'); + $factory = $this->container->get('knplabs.snappy.core.backend.factory.myBackend'); $this->assertInstanceOf(DompdfFactory::class, $factory); $this->assertEquals( @@ -101,7 +106,7 @@ public function testDompdfBackendConfiguration(): void new DompdfFactory($streamFactory) ); - $backend = $this->container->get('snappy.backend.myBackend'); + $backend = $this->container->get('knplabs.snappy.core.backend.adapter.myBackend'); $this->assertInstanceOf(DompdfAdapter::class, $backend); $this->assertEquals( @@ -123,5 +128,37 @@ public function testDompdfBackendConfiguration(): void $streamFactory, ), ); + + $this->assertEquals( + $this->container->get('knplabs.snappy.core.frontend.domdocumenttopdf.myBackend'), + new Frontend\DOMDocumentToPdf( + $backend, + $streamFactory, + ), + ); + + $this->assertEquals( + $this->container->get('knplabs.snappy.core.frontend.htmlfiletopdf.myBackend'), + new Frontend\HtmlFileToPdf( + $backend, + $streamFactory, + ), + ); + + $this->assertEquals( + $this->container->get('knplabs.snappy.core.frontend.htmltopdf.myBackend'), + new Frontend\HtmlToPdf( + $backend, + $streamFactory, + ), + ); + + $this->assertEquals( + $this->container->get('knplabs.snappy.core.frontend.streamtopdf.myBackend'), + new Frontend\StreamToPdf( + $backend, + $streamFactory, + ), + ); } }