diff --git a/src/Backend/Dompdf/DompdfAdapter.php b/src/Backend/Dompdf/DompdfAdapter.php index 8cb2e4fe..bc49a0c1 100644 --- a/src/Backend/Dompdf/DompdfAdapter.php +++ b/src/Backend/Dompdf/DompdfAdapter.php @@ -39,7 +39,7 @@ public function generateFromDOMDocument(DOMDocument $DOMDocument): StreamInterfa public function generateFromHtmlFile(SplFileInfo $file): StreamInterface { $dompdf = $this->buildDompdf(); - $dompdf->loadHtmlFile($file->getPath()); + $dompdf->loadHtmlFile($file->getPathname()); return $this->createStream($dompdf); } diff --git a/src/Backend/Dompdf/Tests/DompdfAdapterTest.php b/src/Backend/Dompdf/Tests/DompdfAdapterTest.php new file mode 100644 index 00000000..a6729674 --- /dev/null +++ b/src/Backend/Dompdf/Tests/DompdfAdapterTest.php @@ -0,0 +1,150 @@ +tempDir = sys_get_temp_dir(); + $this->options = new Options(null, [ + 'output' => __DIR__, + 'construct' => [ + 'chroot' => $this->tempDir, + ] + ]); + + $this->streamFactoryMock = $this->createMock(StreamFactoryInterface::class); + + $factory = new DompdfFactory($this->streamFactoryMock); + $this->adapter = $factory->create($this->options); + } + + public function testGenerateFromDOMDocument(): void + { + $domDocument = new DOMDocument(); + $domDocument->loadHTML('Hello World'); + + $expectedStreamMock = $this->createMock(StreamInterface::class); + $this->streamFactoryMock + ->expects($this->once()) + ->method('createStream') + ->with($this->isType('string')) + ->willReturn($expectedStreamMock); + + $output = $this->adapter->generateFromDOMDocument($domDocument); + + $this->assertSame($expectedStreamMock, $output); + } + + public function testGenerateFromHtmlFile(): void + { + $tempFilePath = $this->tempDir . '/test.html'; + file_put_contents($tempFilePath, 'Temporary Test File'); + $fileMock = new \SplFileInfo($tempFilePath); + + $expectedStreamMock = $this->createMock(StreamInterface::class); + $this->streamFactoryMock + ->expects($this->once()) + ->method('createStream') + ->with($this->isType('string')) + ->willReturn($expectedStreamMock); + + $output = $this->adapter->generateFromHtmlFile($fileMock); + + $this->assertSame($expectedStreamMock, $output); + + if (file_exists($tempFilePath)) { + unlink($tempFilePath); + } + } + + public function testGenerateFromHtml(): void + { + $htmlContent = 'Test HTML content'; + + $expectedStreamMock = $this->createMock(StreamInterface::class); + $this->streamFactoryMock + ->expects($this->once()) + ->method('createStream') + ->willReturn($expectedStreamMock); + + $output = $this->adapter->generateFromHtml($htmlContent); + + $this->assertSame($expectedStreamMock, $output); + } + + public function testGenerateFromInvalidHtml(): void + { + $invalidHtmlContent = '

Unclosed Header'; + + $expectedStreamMock = $this->createMock(StreamInterface::class); + $this->streamFactoryMock + ->expects($this->once()) + ->method('createStream') + ->willReturn($expectedStreamMock); + + $output = $this->adapter->generateFromHtml($invalidHtmlContent); + + $this->assertSame($expectedStreamMock, $output); + } + + public function testGenerateFromEmptyHtml(): void + { + $htmlContent = ''; + + $expectedStreamMock = $this->createMock(StreamInterface::class); + $this->streamFactoryMock + ->expects($this->once()) + ->method('createStream') + ->willReturn($expectedStreamMock); + + $output = $this->adapter->generateFromHtml($htmlContent); + + $this->assertSame($expectedStreamMock, $output); + } + + public function testStreamContentFromHtml(): void + { + $htmlContent = 'Test Content'; + $expectedOutput = 'PDF content for Test Content'; + + $this->streamFactoryMock + ->method('createStream') + ->willReturn($this->createStreamWithContent($expectedOutput)); + + $output = $this->adapter->generateFromHtml($htmlContent); + $this->assertSame($expectedOutput, $output->getContents()); + } + + private function createStreamWithContent(string $content): StreamInterface + { + $streamMock = $this->createMock(StreamInterface::class); + $streamMock->method('getContents')->willReturn($content); + return $streamMock; + } + + public function testOptionsHandling(): void + { + $this->options = new Options(PageOrientation::LANDSCAPE, []); + $this->adapter = (new DompdfFactory($this->streamFactoryMock))->create($this->options); + + $this->assertTrue(true); + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption.php b/src/Backend/WkHtmlToPdf/ExtraOption.php new file mode 100644 index 00000000..569d8d83 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption.php @@ -0,0 +1,12 @@ + */ + public function compile(): array; +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/Allow.php b/src/Backend/WkHtmlToPdf/ExtraOption/Allow.php new file mode 100644 index 00000000..cb5f98b1 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/Allow.php @@ -0,0 +1,24 @@ +path]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/BypassProxyFor.php b/src/Backend/WkHtmlToPdf/ExtraOption/BypassProxyFor.php new file mode 100644 index 00000000..37ac72db --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/BypassProxyFor.php @@ -0,0 +1,24 @@ +value]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/CacheDir.php b/src/Backend/WkHtmlToPdf/ExtraOption/CacheDir.php new file mode 100644 index 00000000..ad36a9d8 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/CacheDir.php @@ -0,0 +1,24 @@ +path]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/CheckBoxSvg.php b/src/Backend/WkHtmlToPdf/ExtraOption/CheckBoxSvg.php new file mode 100644 index 00000000..8df4c443 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/CheckBoxSvg.php @@ -0,0 +1,24 @@ +path]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/CheckboxCheckedSvg.php b/src/Backend/WkHtmlToPdf/ExtraOption/CheckboxCheckedSvg.php new file mode 100644 index 00000000..70b9d043 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/CheckboxCheckedSvg.php @@ -0,0 +1,24 @@ +path]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/Cookie.php b/src/Backend/WkHtmlToPdf/ExtraOption/Cookie.php new file mode 100644 index 00000000..7e586a33 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/Cookie.php @@ -0,0 +1,24 @@ +name, $this->value]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/CookieJar.php b/src/Backend/WkHtmlToPdf/ExtraOption/CookieJar.php new file mode 100644 index 00000000..cbff71ea --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/CookieJar.php @@ -0,0 +1,22 @@ +number]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/CustomHeader.php b/src/Backend/WkHtmlToPdf/ExtraOption/CustomHeader.php new file mode 100644 index 00000000..e30c0e4b --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/CustomHeader.php @@ -0,0 +1,24 @@ +name, $this->value]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/CustomHeaderPropagation.php b/src/Backend/WkHtmlToPdf/ExtraOption/CustomHeaderPropagation.php new file mode 100644 index 00000000..a268a3a6 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/CustomHeaderPropagation.php @@ -0,0 +1,20 @@ +dpi]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/EnableForms.php b/src/Backend/WkHtmlToPdf/ExtraOption/EnableForms.php new file mode 100644 index 00000000..05b3d413 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/EnableForms.php @@ -0,0 +1,20 @@ +encoding]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/ExcludeFromOutline.php b/src/Backend/WkHtmlToPdf/ExtraOption/ExcludeFromOutline.php new file mode 100644 index 00000000..85c03e42 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/ExcludeFromOutline.php @@ -0,0 +1,18 @@ +text]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/FooterFontName.php b/src/Backend/WkHtmlToPdf/ExtraOption/FooterFontName.php new file mode 100644 index 00000000..a6e4b684 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/FooterFontName.php @@ -0,0 +1,22 @@ +fontName]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/FooterFontSize.php b/src/Backend/WkHtmlToPdf/ExtraOption/FooterFontSize.php new file mode 100644 index 00000000..ae24a7e3 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/FooterFontSize.php @@ -0,0 +1,25 @@ +size]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/FooterHtml.php b/src/Backend/WkHtmlToPdf/ExtraOption/FooterHtml.php new file mode 100644 index 00000000..6bdd74d6 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/FooterHtml.php @@ -0,0 +1,22 @@ +uri]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/FooterLeft.php b/src/Backend/WkHtmlToPdf/ExtraOption/FooterLeft.php new file mode 100644 index 00000000..abc79b90 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/FooterLeft.php @@ -0,0 +1,22 @@ +text]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/FooterLine.php b/src/Backend/WkHtmlToPdf/ExtraOption/FooterLine.php new file mode 100644 index 00000000..5f9f8df8 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/FooterLine.php @@ -0,0 +1,20 @@ +text]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/FooterSpacing.php b/src/Backend/WkHtmlToPdf/ExtraOption/FooterSpacing.php new file mode 100644 index 00000000..467f8366 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/FooterSpacing.php @@ -0,0 +1,22 @@ +spacing]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/Grayscale.php b/src/Backend/WkHtmlToPdf/ExtraOption/Grayscale.php new file mode 100644 index 00000000..789f141f --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/Grayscale.php @@ -0,0 +1,20 @@ +text]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/HeaderFontName.php b/src/Backend/WkHtmlToPdf/ExtraOption/HeaderFontName.php new file mode 100644 index 00000000..ac485223 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/HeaderFontName.php @@ -0,0 +1,22 @@ +fontName]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/HeaderFontSize.php b/src/Backend/WkHtmlToPdf/ExtraOption/HeaderFontSize.php new file mode 100644 index 00000000..4833c847 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/HeaderFontSize.php @@ -0,0 +1,25 @@ +size]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/HeaderHtml.php b/src/Backend/WkHtmlToPdf/ExtraOption/HeaderHtml.php new file mode 100644 index 00000000..bf30d64e --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/HeaderHtml.php @@ -0,0 +1,22 @@ +uri]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/HeaderLeft.php b/src/Backend/WkHtmlToPdf/ExtraOption/HeaderLeft.php new file mode 100644 index 00000000..d7cf916e --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/HeaderLeft.php @@ -0,0 +1,22 @@ +text]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/HeaderLine.php b/src/Backend/WkHtmlToPdf/ExtraOption/HeaderLine.php new file mode 100644 index 00000000..5c34d086 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/HeaderLine.php @@ -0,0 +1,20 @@ +text]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/HeaderSpacing.php b/src/Backend/WkHtmlToPdf/ExtraOption/HeaderSpacing.php new file mode 100644 index 00000000..f1f36a8c --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/HeaderSpacing.php @@ -0,0 +1,22 @@ +spacing]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/ImageDpi.php b/src/Backend/WkHtmlToPdf/ExtraOption/ImageDpi.php new file mode 100644 index 00000000..f07e2d19 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/ImageDpi.php @@ -0,0 +1,25 @@ +dpi]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/ImageQuality.php b/src/Backend/WkHtmlToPdf/ExtraOption/ImageQuality.php new file mode 100644 index 00000000..9857331f --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/ImageQuality.php @@ -0,0 +1,25 @@ +quality]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/JavascriptDelay.php b/src/Backend/WkHtmlToPdf/ExtraOption/JavascriptDelay.php new file mode 100644 index 00000000..1f80eecd --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/JavascriptDelay.php @@ -0,0 +1,26 @@ +msec]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/KeepRelativeLinks.php b/src/Backend/WkHtmlToPdf/ExtraOption/KeepRelativeLinks.php new file mode 100644 index 00000000..944d4217 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/KeepRelativeLinks.php @@ -0,0 +1,20 @@ +margin]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/MarginLeft.php b/src/Backend/WkHtmlToPdf/ExtraOption/MarginLeft.php new file mode 100644 index 00000000..37979c63 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/MarginLeft.php @@ -0,0 +1,22 @@ +margin]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/MarginRight.php b/src/Backend/WkHtmlToPdf/ExtraOption/MarginRight.php new file mode 100644 index 00000000..db942fd0 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/MarginRight.php @@ -0,0 +1,22 @@ +margin]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/MarginTop.php b/src/Backend/WkHtmlToPdf/ExtraOption/MarginTop.php new file mode 100644 index 00000000..04935d49 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/MarginTop.php @@ -0,0 +1,22 @@ +margin]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/MinimumFontSize.php b/src/Backend/WkHtmlToPdf/ExtraOption/MinimumFontSize.php new file mode 100644 index 00000000..81092a5c --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/MinimumFontSize.php @@ -0,0 +1,27 @@ +size]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/NoBackground.php b/src/Backend/WkHtmlToPdf/ExtraOption/NoBackground.php new file mode 100644 index 00000000..60884db2 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/NoBackground.php @@ -0,0 +1,20 @@ + ExtraOption\Orientation\Value::PORTRAIT, + PageOrientation::LANDSCAPE => ExtraOption\Orientation\Value::LANDSCAPE, + } + ); + } + + public function compile(): array + { + return ['--orientation', $this->orientation->value]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/Orientation/Value.php b/src/Backend/WkHtmlToPdf/ExtraOption/Orientation/Value.php new file mode 100644 index 00000000..191e86fc --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/Orientation/Value.php @@ -0,0 +1,11 @@ +depth]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/PageHeight.php b/src/Backend/WkHtmlToPdf/ExtraOption/PageHeight.php new file mode 100644 index 00000000..2b5c5afe --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/PageHeight.php @@ -0,0 +1,22 @@ +height]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/PageOffset.php b/src/Backend/WkHtmlToPdf/ExtraOption/PageOffset.php new file mode 100644 index 00000000..6a82f63f --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/PageOffset.php @@ -0,0 +1,25 @@ +offset]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/PageSize.php b/src/Backend/WkHtmlToPdf/ExtraOption/PageSize.php new file mode 100644 index 00000000..7f03ed39 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/PageSize.php @@ -0,0 +1,22 @@ +size]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/PageWidth.php b/src/Backend/WkHtmlToPdf/ExtraOption/PageWidth.php new file mode 100644 index 00000000..8f8337da --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/PageWidth.php @@ -0,0 +1,22 @@ +width]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/Password.php b/src/Backend/WkHtmlToPdf/ExtraOption/Password.php new file mode 100644 index 00000000..1d4bbd51 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/Password.php @@ -0,0 +1,24 @@ +password]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/Post.php b/src/Backend/WkHtmlToPdf/ExtraOption/Post.php new file mode 100644 index 00000000..c85d5f8f --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/Post.php @@ -0,0 +1,23 @@ +name, $this->value]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/PostFile.php b/src/Backend/WkHtmlToPdf/ExtraOption/PostFile.php new file mode 100644 index 00000000..e5532b45 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/PostFile.php @@ -0,0 +1,24 @@ +name, $this->value]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/PrintMediaType.php b/src/Backend/WkHtmlToPdf/ExtraOption/PrintMediaType.php new file mode 100644 index 00000000..8959d2a2 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/PrintMediaType.php @@ -0,0 +1,20 @@ +proxy]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/ProxyHostnameLookup.php b/src/Backend/WkHtmlToPdf/ExtraOption/ProxyHostnameLookup.php new file mode 100644 index 00000000..a109f6c4 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/ProxyHostnameLookup.php @@ -0,0 +1,20 @@ +path]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/RadiobuttonCheckedSvg.php b/src/Backend/WkHtmlToPdf/ExtraOption/RadiobuttonCheckedSvg.php new file mode 100644 index 00000000..7477d6df --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/RadiobuttonCheckedSvg.php @@ -0,0 +1,24 @@ +path]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/Replace.php b/src/Backend/WkHtmlToPdf/ExtraOption/Replace.php new file mode 100644 index 00000000..7b5c0368 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/Replace.php @@ -0,0 +1,22 @@ +name, $this->value]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/RunScript.php b/src/Backend/WkHtmlToPdf/ExtraOption/RunScript.php new file mode 100644 index 00000000..938c1d28 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/RunScript.php @@ -0,0 +1,24 @@ +js]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/SslCrtPath.php b/src/Backend/WkHtmlToPdf/ExtraOption/SslCrtPath.php new file mode 100644 index 00000000..d514000b --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/SslCrtPath.php @@ -0,0 +1,24 @@ +path]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/SslKeyPassword.php b/src/Backend/WkHtmlToPdf/ExtraOption/SslKeyPassword.php new file mode 100644 index 00000000..44282c16 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/SslKeyPassword.php @@ -0,0 +1,24 @@ +password]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/SslKeyPath.php b/src/Backend/WkHtmlToPdf/ExtraOption/SslKeyPath.php new file mode 100644 index 00000000..f2e842c3 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/SslKeyPath.php @@ -0,0 +1,24 @@ +path]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/Title.php b/src/Backend/WkHtmlToPdf/ExtraOption/Title.php new file mode 100644 index 00000000..e53fe3f2 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/Title.php @@ -0,0 +1,22 @@ +title]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/Toc.php b/src/Backend/WkHtmlToPdf/ExtraOption/Toc.php new file mode 100644 index 00000000..50d04aa4 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/Toc.php @@ -0,0 +1,20 @@ +text]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/TocLevelIndentation.php b/src/Backend/WkHtmlToPdf/ExtraOption/TocLevelIndentation.php new file mode 100644 index 00000000..832ac118 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/TocLevelIndentation.php @@ -0,0 +1,22 @@ +width]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/TocTextSizeShrink.php b/src/Backend/WkHtmlToPdf/ExtraOption/TocTextSizeShrink.php new file mode 100644 index 00000000..1da8cdfa --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/TocTextSizeShrink.php @@ -0,0 +1,22 @@ +scale]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/UseXserver.php b/src/Backend/WkHtmlToPdf/ExtraOption/UseXserver.php new file mode 100644 index 00000000..5a9f0210 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/UseXserver.php @@ -0,0 +1,20 @@ +path]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/Username.php b/src/Backend/WkHtmlToPdf/ExtraOption/Username.php new file mode 100644 index 00000000..51cc0aa0 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/Username.php @@ -0,0 +1,24 @@ +username]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/ViewPortSize.php b/src/Backend/WkHtmlToPdf/ExtraOption/ViewPortSize.php new file mode 100644 index 00000000..0cd36e04 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/ViewPortSize.php @@ -0,0 +1,24 @@ +viewSize]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/WindowsStatus.php b/src/Backend/WkHtmlToPdf/ExtraOption/WindowsStatus.php new file mode 100644 index 00000000..a2661325 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/WindowsStatus.php @@ -0,0 +1,23 @@ +windowsStatus]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/XslStyleSheet.php b/src/Backend/WkHtmlToPdf/ExtraOption/XslStyleSheet.php new file mode 100644 index 00000000..b36acded --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/XslStyleSheet.php @@ -0,0 +1,22 @@ +file]; + } +} diff --git a/src/Backend/WkHtmlToPdf/ExtraOption/Zoom.php b/src/Backend/WkHtmlToPdf/ExtraOption/Zoom.php new file mode 100644 index 00000000..887c9586 --- /dev/null +++ b/src/Backend/WkHtmlToPdf/ExtraOption/Zoom.php @@ -0,0 +1,24 @@ +float]; + } +} \ No newline at end of file diff --git a/src/Backend/WkHtmlToPdf/Tests/WkHtmlToPdfAdapterTest.php b/src/Backend/WkHtmlToPdf/Tests/WkHtmlToPdfAdapterTest.php new file mode 100644 index 00000000..98a44dcd --- /dev/null +++ b/src/Backend/WkHtmlToPdf/Tests/WkHtmlToPdfAdapterTest.php @@ -0,0 +1,124 @@ +tempDir = sys_get_temp_dir(); + $this->streamFactory = $this->createMock(StreamFactoryInterface::class); + $this->uriFactory = $this->createMock(UriFactoryInterface::class); + + $this->factory = new WkHtmlToPdfFactory( + 'wkhtmltopdf', + 60, + $this->streamFactory, + $this->uriFactory + ); + + $this->wkHtmlToPdfAdapter = $this->factory->create(new Options(null, [])); + } + + public function testGenerateFromHtmlFile(): void + { + $htmlContent = '

Test PDF

'; + $testFilePath = $this->tempDir . '/test.html'; + file_put_contents($testFilePath, $htmlContent); + + $this->uriFactory + ->method('createUri') + ->with($testFilePath) + ->willReturn(new Uri($testFilePath)); + + $stream = $this->createMock(StreamInterface::class); + $stream->method('getContents')->willReturn('%PDF-1.4 content'); + + $this->streamFactory + ->expects($this->once()) + ->method('createStreamFromResource') + ->willReturn($stream); + + + try { + $resultStream = $this->wkHtmlToPdfAdapter->generateFromHtmlFile(new \SplFileInfo($testFilePath)); + } catch (\Exception $e) { + $this->fail("Erreur lors de la génération du PDF : " . $e->getMessage()); + } + + $this->assertNotNull($resultStream); + $this->assertInstanceOf(StreamInterface::class, $resultStream); + $this->assertNotEmpty($resultStream->getContents()); + + unlink($testFilePath); + } + + public function testGenerateFromInvalidHtmlFile(): void + { + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('File not found:'); + + $this->wkHtmlToPdfAdapter->generateFromHtmlFile(new SplFileInfo($this->tempDir . '/nonexistent.html')); + } + + public function testGenerateWithAdditionalOptions(): void + { + $htmlContent = 'Test PDF

Test PDF

'; + $testFilePath = $this->tempDir . '/test_with_options.html'; + file_put_contents($testFilePath, $htmlContent); + + $options = new Options(null, [ + new Title('Test PDF Title') + ]); + + $this->factory = new WkHtmlToPdfFactory( + 'wkhtmltopdf', + 60, + $this->streamFactory, + $this->uriFactory + ); + + $this->wkHtmlToPdfAdapter = $this->factory->create($options); + + $this->uriFactory + ->method('createUri') + ->with($testFilePath) + ->willReturn(new Uri(realpath($testFilePath))); + + $stream = $this->createMock(StreamInterface::class); + $stream->method('getContents')->willReturn('%PDF-1.4 content'); + + $this->streamFactory + ->method('createStreamFromResource') + ->willReturn($stream); + + + $resultStream = $this->wkHtmlToPdfAdapter->generateFromHtmlFile(new SplFileInfo($testFilePath)); + + $this->assertNotNull($resultStream); + $this->assertInstanceOf(StreamInterface::class, $resultStream); + $this->assertNotEmpty($resultStream->getContents()); + + unlink($testFilePath); + } +} diff --git a/src/Backend/WkHtmlToPdf/WkHtmlToPdfAdapter.php b/src/Backend/WkHtmlToPdf/WkHtmlToPdfAdapter.php index 59babeb4..4ab696ad 100644 --- a/src/Backend/WkHtmlToPdf/WkHtmlToPdfAdapter.php +++ b/src/Backend/WkHtmlToPdf/WkHtmlToPdfAdapter.php @@ -4,14 +4,22 @@ namespace KNPLabs\Snappy\Backend\WkHtmlToPdf; +use KNPLabs\Snappy\Backend\WkHtmlToPdf\ExtraOption; use KNPLabs\Snappy\Core\Backend\Adapter\HtmlFileToPdf; use KNPLabs\Snappy\Core\Backend\Adapter\Reconfigurable; +use KNPLabs\Snappy\Core\Backend\Adapter\UriToPdf; use KNPLabs\Snappy\Core\Backend\Options; +use KNPLabs\Snappy\Core\Filesystem\SplResourceInfo; +use Psr\Http\Message\StreamFactoryInterface; use Psr\Http\Message\StreamInterface; +use Psr\Http\Message\UriFactoryInterface; +use Psr\Http\Message\UriInterface; +use Symfony\Component\Process\Process; +use Symfony\Component\Process\Exception\ProcessFailedException; use SplFileInfo; use Exception; -final class WkHtmlToPdfAdapter implements HtmlFileToPdf +final class WkHtmlToPdfAdapter implements HtmlFileToPdf, UriToPdf { /** * @use Reconfigurable @@ -26,14 +34,97 @@ public function __construct( private string $binary, private int $timeout, WkHtmlToPdfFactory $factory, - Options $options + Options $options, + private readonly StreamFactoryInterface $streamFactory, + private readonly UriFactoryInterface $uriFactory, ) { + self::validateOptions($options); + $this->factory = $factory; $this->options = $options; } public function generateFromHtmlFile(SplFileInfo $file): StreamInterface { - throw new Exception("Not implemented for {$this->binary} with timeout {$this->timeout}."); + $filepath = $file->getRealPath(); + + if ($filepath === false) { + throw new \RuntimeException("File not found: {$file->getPathname()}."); + } + + return $this->generateFromUri( + $this->uriFactory->createUri($filepath) + ); + } + + public function generateFromUri(UriInterface $uri): StreamInterface + { + $outputFile = SplResourceInfo::fromTmpFile(); + + $process = new Process( + command: [ + $this->binary, + '--log-level', + 'none', + '--quiet', + ...$this->compileOptions(), + (string) $uri, + $outputFile->getPathname(), + ], + timeout: $this->timeout, + ); + + $process->run(); + + if (!$process->isSuccessful()) { + throw new ProcessFailedException($process); + } + + return $this->streamFactory->createStreamFromResource($outputFile->resource); + } + + private static function validateOptions(Options $options): void + { + $optionTypes = []; + + foreach ($options->extraOptions as $option) { + if (!$option instanceof ExtraOption) { + throw new \InvalidArgumentException(sprintf( + "Invalid option type provided. Expected \"%s\", received \"%s\".", + ExtraOption::class, + gettype($option) === 'object' ? get_class($option) : gettype($option), + )); + } + + if (\in_array($option::class, $optionTypes, true) && !$option->isRepeatable()) { + throw new \InvalidArgumentException(sprintf( + "Duplicate option type provided: \"%s\".", + $option::class, + )); + } + + $optionTypes[] = $option::class; + } + } + + /** + * @return array + */ + private function compileOptions(): array + { + return array_reduce( + $this->options->extraOptions, + fn(array $carry, ExtraOption $extraOption) => + $extraOption instanceof ExtraOption\Orientation && $this->options->pageOrientation !== null + ? [ + ...$carry, + ...ExtraOption\Orientation::fromPageOrientation($this->options->pageOrientation)->compile(), + ] + : [ + ...$carry, + ...$extraOption->compile(), + ], + [], + ); } } diff --git a/src/Backend/WkHtmlToPdf/WkHtmlToPdfFactory.php b/src/Backend/WkHtmlToPdf/WkHtmlToPdfFactory.php index c73ba6a6..ce125f5a 100644 --- a/src/Backend/WkHtmlToPdf/WkHtmlToPdfFactory.php +++ b/src/Backend/WkHtmlToPdf/WkHtmlToPdfFactory.php @@ -7,6 +7,8 @@ use KNPLabs\Snappy\Core\Backend\Adapter; use KNPLabs\Snappy\Core\Backend\Factory; use KNPLabs\Snappy\Core\Backend\Options; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Message\UriFactoryInterface; /** * @implements Factory @@ -17,9 +19,12 @@ final class WkHtmlToPdfFactory implements Factory * @param non-empty-string $binary * @param positive-int $timeout */ - public function __construct(private readonly string $binary, private readonly int $timeout) - { - + public function __construct( + private readonly string $binary, + private readonly int $timeout, + private readonly StreamFactoryInterface $streamFactory, + private readonly UriFactoryInterface $uriFactory, + ) { } public function create(Options $options): Adapter @@ -29,6 +34,8 @@ public function create(Options $options): Adapter $this->timeout, $this, $options, + $this->streamFactory, + $this->uriFactory, ); } } 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/composer.json b/src/Core/composer.json index 7616157e..26bc9659 100644 --- a/src/Core/composer.json +++ b/src/Core/composer.json @@ -13,4 +13,4 @@ "KNPLabs\\Snappy\\Core\\": "./" } } -} \ No newline at end of file +}