From b3e6d6c39b649624339377b9e063758cb7a69b5d Mon Sep 17 00:00:00 2001 From: Adrien Roches Date: Thu, 30 May 2024 09:25:42 +0200 Subject: [PATCH] Fix Markdown screenshot URL + Add headers to client call + Some renaming + Add metadata to files + Units in paper size (#41) * [FIX] Markdown screenshot URL * [FEATURE] Add headers to client call * [UPDATE] Rename some classes * [FEATURE] Add units * [UPDATE] Add Metadata for PDF files * [UPDATE] Use ScreenshotFormat enum --- docs/custom-builders.rst | 8 +- .../Pdf/AbstractChromiumPdfBuilder.php | 127 +++++++++++++----- src/Builder/Pdf/AbstractPdfBuilder.php | 13 +- src/Builder/Pdf/HtmlPdfBuilder.php | 8 +- src/Builder/Pdf/LibreOfficePdfBuilder.php | 43 +++++- src/Builder/Pdf/MarkdownPdfBuilder.php | 8 +- .../AbstractChromiumScreenshotBuilder.php | 21 +-- .../Screenshot/AbstractScreenshotBuilder.php | 8 +- .../Screenshot/HtmlScreenshotBuilder.php | 8 +- .../Screenshot/MarkdownScreenshotBuilder.php | 10 +- .../Screenshot/UrlScreenshotBuilder.php | 4 +- src/Client/GotenbergClient.php | 4 +- src/Client/GotenbergClientInterface.php | 3 +- src/DependencyInjection/Configuration.php | 48 +++++-- src/Enum/PaperSize.php | 17 +++ src/Enum/PaperSizeInterface.php | 2 + src/Enum/Part.php | 10 ++ src/Enum/PdfPart.php | 10 -- src/Enum/Unit.php | 15 +++ tests/Builder/Pdf/HtmlPdfBuilderTest.php | 21 +-- .../Builder/Pdf/LibreOfficePdfBuilderTest.php | 2 + tests/Builder/Pdf/MarkdownPdfBuilderTest.php | 4 + tests/Builder/Pdf/UrlPdfBuilderTest.php | 4 + tests/Client/GotenbergClientTest.php | 2 + .../DependencyInjection/ConfigurationTest.php | 3 + .../SensiolabsGotenbergExtensionTest.php | 2 + tests/GotenbergPdfTest.php | 34 ++++- 27 files changed, 321 insertions(+), 118 deletions(-) create mode 100644 src/Enum/Part.php delete mode 100644 src/Enum/PdfPart.php create mode 100644 src/Enum/Unit.php diff --git a/docs/custom-builders.rst b/docs/custom-builders.rst index d9ab876d..bd607024 100644 --- a/docs/custom-builders.rst +++ b/docs/custom-builders.rst @@ -42,7 +42,7 @@ Alternatively, you can use the BodyPart enum to rename your file on the fly. .. code-block:: php - use Sensiolabs\GotenbergBundle\Enum\PdfPart; + use Sensiolabs\GotenbergBundle\Enum\Part; use Symfony\Component\Mime\Part\DataPart; use Symfony\Component\Mime\Part\File; @@ -54,7 +54,7 @@ Alternatively, you can use the BodyPart enum to rename your file on the fly. public function content(string $path): self { - $dataPart = DataPart::fromPath($path, PdfPart::BodyPart->value); + $dataPart = DataPart::fromPath($path, Part::BodyPart->value); $this->multipartFormData[] = [ 'files' => $dataPart, @@ -92,7 +92,7 @@ and use everything you want. .. code-block:: php - use Sensiolabs\GotenbergBundle\Enum\PdfPart; + use Sensiolabs\GotenbergBundle\Enum\Part; use Symfony\Component\Mime\Part\DataPart; use Symfony\Component\Mime\Part\File; @@ -107,7 +107,7 @@ and use everything you want. public function content(string $path): self { - $dataPart = DataPart::fromPath($path, PdfPart::BodyPart->value); + $dataPart = DataPart::fromPath($path, Part::BodyPart->value); $this->multipartFormData[] = [ 'files' => $dataPart, diff --git a/src/Builder/Pdf/AbstractChromiumPdfBuilder.php b/src/Builder/Pdf/AbstractChromiumPdfBuilder.php index afd6a36c..13226fa5 100644 --- a/src/Builder/Pdf/AbstractChromiumPdfBuilder.php +++ b/src/Builder/Pdf/AbstractChromiumPdfBuilder.php @@ -3,8 +3,11 @@ namespace Sensiolabs\GotenbergBundle\Builder\Pdf; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; +use Sensiolabs\GotenbergBundle\Enum\PaperSize; use Sensiolabs\GotenbergBundle\Enum\PaperSizeInterface; -use Sensiolabs\GotenbergBundle\Enum\PdfPart; +use Sensiolabs\GotenbergBundle\Enum\Part; +use Sensiolabs\GotenbergBundle\Enum\PdfFormat; +use Sensiolabs\GotenbergBundle\Enum\Unit; use Sensiolabs\GotenbergBundle\Exception\InvalidBuilderConfiguration; use Sensiolabs\GotenbergBundle\Exception\PdfPartRenderingException; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; @@ -36,6 +39,18 @@ public function setConfigurations(array $configurations): static return $this; } + /** + * Define whether to print the entire content in one single page. + * + * If the singlePage form field is set to true, it automatically overrides the values from the paperHeight and nativePageRanges form fields. + */ + public function singlePage(bool $bool = true): static + { + $this->formFields['singlePage'] = $bool; + + return $this; + } + /** * Overrides the default paper size, in inches. * @@ -55,32 +70,32 @@ public function setConfigurations(array $configurations): static * * @see https://gotenberg.dev/docs/routes#page-properties-chromium */ - public function paperSize(float $width, float $height): static + public function paperSize(float $width, float $height, Unit $unit = Unit::Inches): static { - $this->paperWidth($width); - $this->paperHeight($height); + $this->paperWidth($width, $unit); + $this->paperHeight($height, $unit); return $this; } public function paperStandardSize(PaperSizeInterface $paperSize): static { - $this->paperWidth($paperSize->width()); - $this->paperHeight($paperSize->height()); + $this->paperWidth($paperSize->width(), $paperSize->unit()); + $this->paperHeight($paperSize->height(), $paperSize->unit()); return $this; } - public function paperWidth(float $width): static + public function paperWidth(float $width, Unit $unit = Unit::Inches): static { - $this->formFields['paperWidth'] = $width; + $this->formFields['paperWidth'] = $width.$unit->value; return $this; } - public function paperHeight(float $height): static + public function paperHeight(float $height, Unit $unit = Unit::Inches): static { - $this->formFields['paperHeight'] = $height; + $this->formFields['paperHeight'] = $height.$unit->value; return $this; } @@ -90,40 +105,40 @@ public function paperHeight(float $height): static * * @see https://gotenberg.dev/docs/routes#page-properties-chromium */ - public function margins(float $top, float $bottom, float $left, float $right): static + public function margins(float $top, float $bottom, float $left, float $right, Unit $unit = Unit::Inches): static { - $this->marginTop($top); - $this->marginBottom($bottom); - $this->marginLeft($left); - $this->marginRight($right); + $this->marginTop($top, $unit); + $this->marginBottom($bottom, $unit); + $this->marginLeft($left, $unit); + $this->marginRight($right, $unit); return $this; } - public function marginTop(float $top): static + public function marginTop(float $top, Unit $unit = Unit::Inches): static { - $this->formFields['marginTop'] = $top; + $this->formFields['marginTop'] = $top.$unit->value; return $this; } - public function marginBottom(float $bottom): static + public function marginBottom(float $bottom, Unit $unit = Unit::Inches): static { - $this->formFields['marginBottom'] = $bottom; + $this->formFields['marginBottom'] = $bottom.$unit->value; return $this; } - public function marginLeft(float $left): static + public function marginLeft(float $left, Unit $unit = Unit::Inches): static { - $this->formFields['marginLeft'] = $left; + $this->formFields['marginLeft'] = $left.$unit->value; return $this; } - public function marginRight(float $right): static + public function marginRight(float $right, Unit $unit = Unit::Inches): static { - $this->formFields['marginRight'] = $right; + $this->formFields['marginRight'] = $right.$unit->value; return $this; } @@ -209,7 +224,7 @@ public function nativePageRanges(string $range): static */ public function header(string $template, array $context = []): static { - return $this->withRenderedPart(PdfPart::HeaderPart, $template, $context); + return $this->withRenderedPart(Part::Header, $template, $context); } /** @@ -220,7 +235,7 @@ public function header(string $template, array $context = []): static */ public function footer(string $template, array $context = []): static { - return $this->withRenderedPart(PdfPart::FooterPart, $template, $context); + return $this->withRenderedPart(Part::Footer, $template, $context); } /** @@ -228,7 +243,7 @@ public function footer(string $template, array $context = []): static */ public function headerFile(string $path): static { - return $this->withPdfPartFile(PdfPart::HeaderPart, $path); + return $this->withPdfPartFile(Part::Header, $path); } /** @@ -236,7 +251,7 @@ public function headerFile(string $path): static */ public function footerFile(string $path): static { - return $this->withPdfPartFile(PdfPart::FooterPart, $path); + return $this->withPdfPartFile(Part::Footer, $path); } /** @@ -422,9 +437,15 @@ public function skipNetworkIdleEvent(bool $bool = true): static * * @See https://gotenberg.dev/docs/routes#pdfa-chromium. */ - public function pdfFormat(string $format): static + public function pdfFormat(PdfFormat|null $format = null): static { - $this->formFields['pdfa'] = $format; + if (null === $format) { + unset($this->formFields['pdfa']); + + return $this; + } + + $this->formFields['pdfa'] = $format->value; return $this; } @@ -441,7 +462,33 @@ public function pdfUniversalAccess(bool $bool = true): static return $this; } - protected function withPdfPartFile(PdfPart $pdfPart, string $path): static + /** + * Resets the metadata. + * + * @see https://gotenberg.dev/docs/routes#metadata-chromium + * @see https://exiftool.org/TagNames/XMP.html#pdf + * + * @param array $metadata + */ + public function metadata(array $metadata): static + { + $this->formFields['metadata'] = $metadata; + + return $this; + } + + /** + * The metadata to write. + */ + public function addMetadata(string $key, string $value): static + { + $this->formFields['metadata'] ??= []; + $this->formFields['metadata'][$key] = $value; + + return $this; + } + + protected function withPdfPartFile(Part $pdfPart, string $path): static { $dataPart = new DataPart( new DataPartFile($this->asset->resolve($path)), @@ -459,7 +506,7 @@ protected function withPdfPartFile(PdfPart $pdfPart, string $path): static * * @throws PdfPartRenderingException if the template could not be rendered */ - protected function withRenderedPart(PdfPart $pdfPart, string $template, array $context = []): static + protected function withRenderedPart(Part $pdfPart, string $template, array $context = []): static { if (!$this->twig instanceof Environment) { throw new \LogicException(sprintf('Twig is required to use "%s" method. Try to run "composer require symfony/twig-bundle".', __METHOD__)); @@ -478,15 +525,22 @@ protected function withRenderedPart(PdfPart $pdfPart, string $template, array $c private function addConfiguration(string $configurationName, mixed $value): void { + $splitAndParseStringWithUnit = static function (mixed $raw, callable $callback): void { + [$value, $unit] = sscanf((string) $raw, '%d%s') ?? throw new \InvalidArgumentException(sprintf('Unexpected value "%s", expected format is "%%d%%s"', $raw)); + + $callback((float) $value, Unit::tryFrom((string) $unit) ?? Unit::Inches); + }; + match ($configurationName) { - 'pdf_format' => $this->pdfFormat($value), + 'single_page' => $this->singlePage($value), + 'pdf_format' => $this->pdfFormat(PdfFormat::from($value)), 'pdf_universal_access' => $this->pdfUniversalAccess($value), 'paper_width' => $this->paperWidth($value), 'paper_height' => $this->paperHeight($value), - 'margin_top' => $this->marginTop($value), - 'margin_bottom' => $this->marginBottom($value), - 'margin_left' => $this->marginLeft($value), - 'margin_right' => $this->marginRight($value), + 'margin_top' => $splitAndParseStringWithUnit($value, $this->marginTop(...)), + 'margin_bottom' => $splitAndParseStringWithUnit($value, $this->marginBottom(...)), + 'margin_left' => $splitAndParseStringWithUnit($value, $this->marginLeft(...)), + 'margin_right' => $splitAndParseStringWithUnit($value, $this->marginRight(...)), 'prefer_css_page_size' => $this->preferCssPageSize($value), 'print_background' => $this->printBackground($value), 'omit_background' => $this->omitBackground($value), @@ -501,6 +555,7 @@ private function addConfiguration(string $configurationName, mixed $value): void 'fail_on_http_status_codes' => $this->failOnHttpStatusCodes($value), 'fail_on_console_exceptions' => $this->failOnConsoleExceptions($value), 'skip_network_idle_event' => $this->skipNetworkIdleEvent($value), + 'metadata' => $this->metadata($value), default => throw new InvalidBuilderConfiguration(sprintf('Invalid option "%s": no method does not exist in class "%s" to configured it.', $configurationName, static::class)), }; } diff --git a/src/Builder/Pdf/AbstractPdfBuilder.php b/src/Builder/Pdf/AbstractPdfBuilder.php index 566df729..089034c1 100644 --- a/src/Builder/Pdf/AbstractPdfBuilder.php +++ b/src/Builder/Pdf/AbstractPdfBuilder.php @@ -4,7 +4,7 @@ use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Client\GotenbergResponse; -use Sensiolabs\GotenbergBundle\Enum\PdfPart; +use Sensiolabs\GotenbergBundle\Enum\Part; use Sensiolabs\GotenbergBundle\Exception\JsonEncodingException; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; use Symfony\Component\HttpFoundation\File\File; @@ -38,20 +38,23 @@ public function __construct( 'assets' => static function (array $value): array { return ['files' => $value]; }, - PdfPart::HeaderPart->value => static function (DataPart $value): array { + Part::Header->value => static function (DataPart $value): array { return ['files' => $value]; }, - PdfPart::BodyPart->value => static function (DataPart $value): array { + Part::Body->value => static function (DataPart $value): array { return ['files' => $value]; }, - PdfPart::FooterPart->value => static function (DataPart $value): array { + Part::Footer->value => static function (DataPart $value): array { return ['files' => $value]; }, 'failOnHttpStatusCodes' => function (mixed $value): array { return $this->encodeData('failOnHttpStatusCodes', $value); }, 'cookies' => function (mixed $value): array { - return $this->encodeData('cookies', array_values($value)); + return $this->encodeData('cookies', \array_values($value)); + }, + 'metadata' => function (mixed $value): array { + return $this->encodeData('metadata', $value); }, ]; } diff --git a/src/Builder/Pdf/HtmlPdfBuilder.php b/src/Builder/Pdf/HtmlPdfBuilder.php index 1c33d2f6..13718f3f 100644 --- a/src/Builder/Pdf/HtmlPdfBuilder.php +++ b/src/Builder/Pdf/HtmlPdfBuilder.php @@ -2,7 +2,7 @@ namespace Sensiolabs\GotenbergBundle\Builder\Pdf; -use Sensiolabs\GotenbergBundle\Enum\PdfPart; +use Sensiolabs\GotenbergBundle\Enum\Part; use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException; use Sensiolabs\GotenbergBundle\Exception\PdfPartRenderingException; @@ -18,7 +18,7 @@ final class HtmlPdfBuilder extends AbstractChromiumPdfBuilder */ public function content(string $template, array $context = []): self { - return $this->withRenderedPart(PdfPart::BodyPart, $template, $context); + return $this->withRenderedPart(Part::Body, $template, $context); } /** @@ -26,12 +26,12 @@ public function content(string $template, array $context = []): self */ public function contentFile(string $path): self { - return $this->withPdfPartFile(PdfPart::BodyPart, $path); + return $this->withPdfPartFile(Part::Body, $path); } public function getMultipartFormData(): array { - if (!\array_key_exists(PdfPart::BodyPart->value, $this->formFields)) { + if (!\array_key_exists(Part::Body->value, $this->formFields)) { throw new MissingRequiredFieldException('Content is required'); } diff --git a/src/Builder/Pdf/LibreOfficePdfBuilder.php b/src/Builder/Pdf/LibreOfficePdfBuilder.php index b8208467..03dbddcf 100644 --- a/src/Builder/Pdf/LibreOfficePdfBuilder.php +++ b/src/Builder/Pdf/LibreOfficePdfBuilder.php @@ -12,12 +12,16 @@ final class LibreOfficePdfBuilder extends AbstractPdfBuilder private const ENDPOINT = '/forms/libreoffice/convert'; private const AVAILABLE_EXTENSIONS = [ - 'bib', 'doc', 'xml', 'docx', 'fodt', 'html', 'ltx', 'txt', 'odt', 'ott', 'pdb', 'pdf', 'psw', 'rtf', 'sdw', - 'stw', 'sxw', 'uot', 'vor', 'wps', 'epub', 'png', 'bmp', 'emf', 'eps', 'fodg', 'gif', 'jpg', 'met', 'odd', - 'otg', 'pbm', 'pct', 'pgm', 'ppm', 'ras', 'std', 'svg', 'svm', 'swf', 'sxd', 'sxw', 'tiff', 'xhtml', 'xpm', - 'fodp', 'potm', 'pot', 'pptx', 'pps', 'ppt', 'pwp', 'sda', 'sdd', 'sti', 'sxi', 'uop', 'wmf', 'csv', 'dbf', - 'dif', 'fods', 'ods', 'ots', 'pxl', 'sdc', 'slk', 'stc', 'sxc', 'uos', 'xls', 'xlt', 'xlsx', 'tif', 'jpeg', - 'odp', 'odg', 'dotx', 'xltx', + '123', '602', 'abw', 'bib', 'bmp', 'cdr', 'cgm', 'cmx', 'csv', 'cwk', 'dbf', 'dif', 'doc', 'docm', + 'docx', 'dot', 'dotm', 'dotx', 'dxf', 'emf', 'eps', 'epub', 'fodg', 'fodp', 'fods', 'fodt', 'fopd', + 'gif', 'htm', 'html', 'hwp', 'jpeg', 'jpg', 'key', 'ltx', 'lwp', 'mcw', 'met', 'mml', 'mw', 'numbers', + 'odd', 'odg', 'odm', 'odp', 'ods', 'odt', 'otg', 'oth', 'otp', 'ots', 'ott', 'pages', 'pbm', 'pcd', + 'pct', 'pcx', 'pdb', 'pdf', 'pgm', 'png', 'pot', 'potm', 'potx', 'ppm', 'pps', 'ppt', 'pptm', 'pptx', + 'psd', 'psw', 'pub', 'pwp', 'pxl', 'ras', 'rtf', 'sda', 'sdc', 'sdd', 'sdp', 'sdw', 'sgl', 'slk', + 'smf', 'stc', 'std', 'sti', 'stw', 'svg', 'svm', 'swf', 'sxc', 'sxd', 'sxg', 'sxi', 'sxm', 'sxw', + 'tga', 'tif', 'tiff', 'txt', 'uof', 'uop', 'uos', 'uot', 'vdx', 'vor', 'vsd', 'vsdm', 'vsdx', 'wb2', + 'wk1', 'wks', 'wmf', 'wpd', 'wpg', 'wps', 'xbm', 'xhtml', 'xls', 'xlsb', 'xlsm', 'xlsx', 'xlt', 'xltm', + 'xltx', 'xlw', 'xml', 'xpm', 'zabw', ]; /** @@ -104,6 +108,32 @@ public function files(string ...$paths): self return $this; } + /** + * Resets the metadata. + * + * @see https://gotenberg.dev/docs/routes#metadata-chromium + * @see https://exiftool.org/TagNames/XMP.html#pdf + * + * @param array $metadata + */ + public function metadata(array $metadata): static + { + $this->formFields['metadata'] = $metadata; + + return $this; + } + + /** + * The metadata to write. + */ + public function addMetadata(string $key, string $value): static + { + $this->formFields['metadata'] ??= []; + $this->formFields['metadata'][$key] = $value; + + return $this; + } + public function getMultipartFormData(): array { if ([] === ($this->formFields['files'] ?? [])) { @@ -126,6 +156,7 @@ private function addConfiguration(string $configurationName, mixed $value): void 'landscape' => $this->landscape($value), 'native_page_ranges' => $this->nativePageRanges($value), 'fail_on_console_exceptions' => $this->merge($value), + 'metadata' => $this->metadata($value), default => throw new InvalidBuilderConfiguration(sprintf('Invalid option "%s": no method does not exist in class "%s" to configured it.', $configurationName, static::class)), }; } diff --git a/src/Builder/Pdf/MarkdownPdfBuilder.php b/src/Builder/Pdf/MarkdownPdfBuilder.php index 4ff6c903..c8a8104f 100644 --- a/src/Builder/Pdf/MarkdownPdfBuilder.php +++ b/src/Builder/Pdf/MarkdownPdfBuilder.php @@ -2,7 +2,7 @@ namespace Sensiolabs\GotenbergBundle\Builder\Pdf; -use Sensiolabs\GotenbergBundle\Enum\PdfPart; +use Sensiolabs\GotenbergBundle\Enum\Part; use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException; use Sensiolabs\GotenbergBundle\Exception\PdfPartRenderingException; use Symfony\Component\Mime\Part\DataPart; @@ -22,7 +22,7 @@ final class MarkdownPdfBuilder extends AbstractChromiumPdfBuilder */ public function wrapper(string $template, array $context = []): self { - return $this->withRenderedPart(PdfPart::BodyPart, $template, $context); + return $this->withRenderedPart(Part::Body, $template, $context); } /** @@ -30,7 +30,7 @@ public function wrapper(string $template, array $context = []): self */ public function wrapperFile(string $path): self { - return $this->withPdfPartFile(PdfPart::BodyPart, $path); + return $this->withPdfPartFile(Part::Body, $path); } public function files(string ...$paths): self @@ -50,7 +50,7 @@ public function files(string ...$paths): self public function getMultipartFormData(): array { - if (!\array_key_exists(PdfPart::BodyPart->value, $this->formFields)) { + if (!\array_key_exists(Part::Body->value, $this->formFields)) { throw new MissingRequiredFieldException('HTML template is required'); } diff --git a/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php b/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php index 2cdc32e3..b950f85e 100644 --- a/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php +++ b/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php @@ -3,7 +3,8 @@ namespace Sensiolabs\GotenbergBundle\Builder\Screenshot; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; -use Sensiolabs\GotenbergBundle\Enum\PdfPart; +use Sensiolabs\GotenbergBundle\Enum\Part; +use Sensiolabs\GotenbergBundle\Enum\ScreenshotFormat; use Sensiolabs\GotenbergBundle\Exception\InvalidBuilderConfiguration; use Sensiolabs\GotenbergBundle\Exception\PdfPartRenderingException; use Sensiolabs\GotenbergBundle\Exception\ScreenshotPartRenderingException; @@ -77,9 +78,9 @@ public function clip(bool $bool = true): static * * @see https://gotenberg.dev/docs/routes#screenshots-route */ - public function format(string $format): static + public function format(ScreenshotFormat $format): static { - $this->formFields['format'] = $format; + $this->formFields['format'] = $format->value; return $this; } @@ -281,7 +282,7 @@ public function skipNetworkIdleEvent(bool $bool = true): static */ public function header(string $template, array $context = []): static { - return $this->withRenderedPart(PdfPart::HeaderPart, $template, $context); + return $this->withRenderedPart(Part::Header, $template, $context); } /** @@ -292,7 +293,7 @@ public function header(string $template, array $context = []): static */ public function footer(string $template, array $context = []): static { - return $this->withRenderedPart(PdfPart::FooterPart, $template, $context); + return $this->withRenderedPart(Part::Footer, $template, $context); } /** @@ -300,7 +301,7 @@ public function footer(string $template, array $context = []): static */ public function headerFile(string $path): static { - return $this->withPdfPartFile(PdfPart::HeaderPart, $path); + return $this->withPdfPartFile(Part::Header, $path); } /** @@ -308,7 +309,7 @@ public function headerFile(string $path): static */ public function footerFile(string $path): static { - return $this->withPdfPartFile(PdfPart::FooterPart, $path); + return $this->withPdfPartFile(Part::Footer, $path); } /** @@ -339,7 +340,7 @@ public function addAsset(string $path): static return $this; } - protected function withPdfPartFile(PdfPart $pdfPart, string $path): static + protected function withPdfPartFile(Part $pdfPart, string $path): static { $dataPart = new DataPart( new DataPartFile($this->asset->resolve($path)), @@ -357,7 +358,7 @@ protected function withPdfPartFile(PdfPart $pdfPart, string $path): static * * @throws ScreenshotPartRenderingException if the template could not be rendered */ - protected function withRenderedPart(PdfPart $pdfPart, string $template, array $context = []): static + protected function withRenderedPart(Part $pdfPart, string $template, array $context = []): static { if (!$this->twig instanceof Environment) { throw new \LogicException(sprintf('Twig is required to use "%s" method. Try to run "composer require symfony/twig-bundle".', __METHOD__)); @@ -380,7 +381,7 @@ private function addConfiguration(string $configurationName, mixed $value): void 'width' => $this->width($value), 'height' => $this->height($value), 'clip' => $this->clip($value), - 'format' => $this->format($value), + 'format' => $this->format(ScreenshotFormat::from($value)), 'quality' => $this->quality($value), 'omit_background' => $this->omitBackground($value), 'optimize_for_speed' => $this->optimizeForSpeed($value), diff --git a/src/Builder/Screenshot/AbstractScreenshotBuilder.php b/src/Builder/Screenshot/AbstractScreenshotBuilder.php index d132632d..53220903 100644 --- a/src/Builder/Screenshot/AbstractScreenshotBuilder.php +++ b/src/Builder/Screenshot/AbstractScreenshotBuilder.php @@ -4,7 +4,7 @@ use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Client\GotenbergResponse; -use Sensiolabs\GotenbergBundle\Enum\PdfPart; +use Sensiolabs\GotenbergBundle\Enum\Part; use Sensiolabs\GotenbergBundle\Exception\JsonEncodingException; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; use Symfony\Component\HttpFoundation\File\File; @@ -38,13 +38,13 @@ public function __construct( 'assets' => static function (array $value): array { return ['files' => $value]; }, - PdfPart::HeaderPart->value => static function (DataPart $value): array { + Part::Header->value => static function (DataPart $value): array { return ['files' => $value]; }, - PdfPart::BodyPart->value => static function (DataPart $value): array { + Part::Body->value => static function (DataPart $value): array { return ['files' => $value]; }, - PdfPart::FooterPart->value => static function (DataPart $value): array { + Part::Footer->value => static function (DataPart $value): array { return ['files' => $value]; }, 'failOnHttpStatusCodes' => function (mixed $value): array { diff --git a/src/Builder/Screenshot/HtmlScreenshotBuilder.php b/src/Builder/Screenshot/HtmlScreenshotBuilder.php index 21480406..efe2e7ae 100644 --- a/src/Builder/Screenshot/HtmlScreenshotBuilder.php +++ b/src/Builder/Screenshot/HtmlScreenshotBuilder.php @@ -2,7 +2,7 @@ namespace Sensiolabs\GotenbergBundle\Builder\Screenshot; -use Sensiolabs\GotenbergBundle\Enum\PdfPart; +use Sensiolabs\GotenbergBundle\Enum\Part; use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException; use Sensiolabs\GotenbergBundle\Exception\PdfPartRenderingException; @@ -18,7 +18,7 @@ final class HtmlScreenshotBuilder extends AbstractChromiumScreenshotBuilder */ public function content(string $template, array $context = []): self { - return $this->withRenderedPart(PdfPart::BodyPart, $template, $context); + return $this->withRenderedPart(Part::Body, $template, $context); } /** @@ -26,12 +26,12 @@ public function content(string $template, array $context = []): self */ public function contentFile(string $path): self { - return $this->withPdfPartFile(PdfPart::BodyPart, $path); + return $this->withPdfPartFile(Part::Body, $path); } public function getMultipartFormData(): array { - if (!\array_key_exists(PdfPart::BodyPart->value, $this->formFields)) { + if (!\array_key_exists(Part::Body->value, $this->formFields)) { throw new MissingRequiredFieldException('Content is required'); } diff --git a/src/Builder/Screenshot/MarkdownScreenshotBuilder.php b/src/Builder/Screenshot/MarkdownScreenshotBuilder.php index 900cffb5..ae9a5c36 100644 --- a/src/Builder/Screenshot/MarkdownScreenshotBuilder.php +++ b/src/Builder/Screenshot/MarkdownScreenshotBuilder.php @@ -2,7 +2,7 @@ namespace Sensiolabs\GotenbergBundle\Builder\Screenshot; -use Sensiolabs\GotenbergBundle\Enum\PdfPart; +use Sensiolabs\GotenbergBundle\Enum\Part; use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException; use Sensiolabs\GotenbergBundle\Exception\PdfPartRenderingException; use Symfony\Component\Mime\Part\DataPart; @@ -10,7 +10,7 @@ final class MarkdownScreenshotBuilder extends AbstractChromiumScreenshotBuilder { - private const ENDPOINT = '/forms/chromium/convert/markdown'; + private const ENDPOINT = '/forms/chromium/screenshot/markdown'; /** * The HTML file that wraps the markdown content, rendered from a Twig template. @@ -22,7 +22,7 @@ final class MarkdownScreenshotBuilder extends AbstractChromiumScreenshotBuilder */ public function wrapper(string $template, array $context = []): self { - return $this->withRenderedPart(PdfPart::BodyPart, $template, $context); + return $this->withRenderedPart(Part::Body, $template, $context); } /** @@ -30,7 +30,7 @@ public function wrapper(string $template, array $context = []): self */ public function wrapperFile(string $path): self { - return $this->withPdfPartFile(PdfPart::BodyPart, $path); + return $this->withPdfPartFile(Part::Body, $path); } public function files(string ...$paths): self @@ -50,7 +50,7 @@ public function files(string ...$paths): self public function getMultipartFormData(): array { - if (!\array_key_exists(PdfPart::BodyPart->value, $this->formFields)) { + if (!\array_key_exists(Part::Body->value, $this->formFields)) { throw new MissingRequiredFieldException('HTML template is required'); } diff --git a/src/Builder/Screenshot/UrlScreenshotBuilder.php b/src/Builder/Screenshot/UrlScreenshotBuilder.php index 7cf48b4a..abdf6d42 100644 --- a/src/Builder/Screenshot/UrlScreenshotBuilder.php +++ b/src/Builder/Screenshot/UrlScreenshotBuilder.php @@ -10,6 +10,8 @@ final class UrlScreenshotBuilder extends AbstractChromiumScreenshotBuilder { + private const ENDPOINT = '/forms/chromium/screenshot/url'; + public function __construct( GotenbergClientInterface $gotenbergClient, AssetBaseDirFormatter $asset, @@ -19,8 +21,6 @@ public function __construct( parent::__construct($gotenbergClient, $asset, $twig); } - private const ENDPOINT = '/forms/chromium/screenshot/url'; - /** * URL of the page you want to convert into PDF. */ diff --git a/src/Client/GotenbergClient.php b/src/Client/GotenbergClient.php index 258d0e5e..5ac7c437 100644 --- a/src/Client/GotenbergClient.php +++ b/src/Client/GotenbergClient.php @@ -12,10 +12,10 @@ public function __construct(private string $gotenbergBaseUri, private HttpClient { } - public function call(string $endpoint, array $multipartFormData): GotenbergResponse + public function call(string $endpoint, array $multipartFormData, array $headers = []): GotenbergResponse { $formData = new FormDataPart($multipartFormData); - $headers = $this->prepareHeaders($formData); + $headers = \array_merge($headers, $this->prepareHeaders($formData)); $response = $this->client->request( 'POST', diff --git a/src/Client/GotenbergClientInterface.php b/src/Client/GotenbergClientInterface.php index 71f43485..12dab586 100644 --- a/src/Client/GotenbergClientInterface.php +++ b/src/Client/GotenbergClientInterface.php @@ -6,6 +6,7 @@ interface GotenbergClientInterface { /** * @param array> $multipartFormData + * @param array $headers */ - public function call(string $endpoint, array $multipartFormData): GotenbergResponse; + public function call(string $endpoint, array $multipartFormData, array $headers = []): GotenbergResponse; } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 030d537b..b1f7b1b6 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -9,6 +9,7 @@ use Symfony\Component\Config\Definition\Builder\NodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; +use function array_map; class Configuration implements ConfigurationInterface { @@ -124,6 +125,10 @@ private function addScreenshotMarkdownNode(): NodeDefinition private function addChromiumPdfOptionsNode(NodeBuilder $treeBuilder): void { $treeBuilder + ->booleanNode('single_page') + ->info('Define whether to print the entire content in one single page. - default false. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->end() ->floatNode('paper_width') ->info('Paper width, in inches - default 8.5. https://gotenberg.dev/docs/routes#page-properties-chromium') ->defaultNull() @@ -132,19 +137,19 @@ private function addChromiumPdfOptionsNode(NodeBuilder $treeBuilder): void ->info('Paper height, in inches - default 11. https://gotenberg.dev/docs/routes#page-properties-chromium') ->defaultNull() ->end() - ->floatNode('margin_top') + ->scalarNode('margin_top') ->info('Top margin, in inches - default 0.39. https://gotenberg.dev/docs/routes#page-properties-chromium') ->defaultNull() ->end() - ->floatNode('margin_bottom') + ->scalarNode('margin_bottom') ->info('Bottom margin, in inches - default 0.39. https://gotenberg.dev/docs/routes#page-properties-chromium') ->defaultNull() ->end() - ->floatNode('margin_left') + ->scalarNode('margin_left') ->info('Left margin, in inches - default 0.39. https://gotenberg.dev/docs/routes#page-properties-chromium') ->defaultNull() ->end() - ->floatNode('margin_right') + ->scalarNode('margin_right') ->info('Right margin, in inches - default 0.39. https://gotenberg.dev/docs/routes#page-properties-chromium') ->defaultNull() ->end() @@ -200,7 +205,7 @@ private function addChromiumPdfOptionsNode(NodeBuilder $treeBuilder): void ->end() ->enumNode('emulated_media_type') ->info('The media type to emulate, either "screen" or "print" - default "print". https://gotenberg.dev/docs/routes#emulated-media-type') - ->values([EmulatedMediaType::Screen->value, EmulatedMediaType::Print->value]) + ->values(array_map(static fn(EmulatedMediaType $case): string => $case->value, EmulatedMediaType::cases())) ->defaultNull() ->end() ->arrayNode('cookies') @@ -269,13 +274,14 @@ private function addChromiumPdfOptionsNode(NodeBuilder $treeBuilder): void ->end() ->enumNode('pdf_format') ->info('Convert the resulting PDF into the given PDF/A format - default None. https://gotenberg.dev/docs/routes#pdfa-chromium') - ->values([PdfFormat::Pdf1b->value, PdfFormat::Pdf2b->value, PdfFormat::Pdf3b->value]) + ->values(array_map(static fn(PdfFormat $case): string => $case->value, PdfFormat::cases())) ->defaultNull() ->end() ->booleanNode('pdf_universal_access') ->info('Enable PDF for Universal Access for optimal accessibility - default false. https://gotenberg.dev/docs/routes#console-exceptions') ->defaultNull() ->end() + ->append($this->addPdfMetadata()) ; } @@ -296,7 +302,7 @@ private function addChromiumScreenshotOptionsNode(NodeBuilder $treeBuilder): voi ->end() ->enumNode('format') ->info('The image compression format, either "png", "jpeg" or "webp" - default png. https://gotenberg.dev/docs/routes#screenshots-route') - ->values([ScreenshotFormat::Png->value, ScreenshotFormat::Jpeg->value, ScreenshotFormat::Webp->value]) + ->values(array_map(static fn(ScreenshotFormat $case): string => $case->value, ScreenshotFormat::cases())) ->defaultNull() ->end() ->integerNode('quality') @@ -335,7 +341,7 @@ private function addChromiumScreenshotOptionsNode(NodeBuilder $treeBuilder): voi ->end() ->enumNode('emulated_media_type') ->info('The media type to emulate, either "screen" or "print" - default "print". https://gotenberg.dev/docs/routes#emulated-media-type') - ->values([EmulatedMediaType::Screen->value, EmulatedMediaType::Print->value]) + ->values(array_map(static fn(EmulatedMediaType $case): string => $case->value, EmulatedMediaType::cases())) ->defaultNull() ->end() ->arrayNode('cookies') @@ -432,13 +438,37 @@ private function addPdfOfficeNode(): NodeDefinition ->end() ->enumNode('pdf_format') ->info('Convert the resulting PDF into the given PDF/A format - default None. https://gotenberg.dev/docs/routes#pdfa-chromium') - ->values([PdfFormat::Pdf1b->value, PdfFormat::Pdf2b->value, PdfFormat::Pdf3b->value]) + ->values(array_map(static fn(PdfFormat $case): string => $case->value, PdfFormat::cases())) ->defaultNull() ->end() ->booleanNode('pdf_universal_access') ->info('Enable PDF for Universal Access for optimal accessibility - default false. https://gotenberg.dev/docs/routes#console-exceptions') ->defaultNull() ->end() + ->append($this->addPdfMetadata()) + ->end() + ; + } + + private function addPdfMetadata(): NodeDefinition + { + $treeBuilder = new TreeBuilder('metadata'); + + return $treeBuilder->getRootNode() + ->info('The metadata to write. Not all metadata are writable. Consider taking a look at https://exiftool.org/TagNames/XMP.html#pdf for an (exhaustive?) list of available metadata.') + ->children() + ->scalarNode('Author')->end() + ->scalarNode('Copyright')->end() + ->scalarNode('CreationDate')->end() + ->scalarNode('Creator')->end() + ->scalarNode('Keywords')->end() + ->booleanNode('Marked')->end() + ->scalarNode('ModDate')->end() + ->scalarNode('PDFVersion')->end() + ->scalarNode('Producer')->end() + ->scalarNode('Subject')->end() + ->scalarNode('Title')->end() + ->enumNode('Trapped')->values(['True', 'False', 'Unknown'])->end() ->end() ; } diff --git a/src/Enum/PaperSize.php b/src/Enum/PaperSize.php index 9ca2ed5a..ed557f0a 100644 --- a/src/Enum/PaperSize.php +++ b/src/Enum/PaperSize.php @@ -4,6 +4,10 @@ enum PaperSize implements PaperSizeInterface { + case Letter; + case Legal; + case Tabloid; + case Ledger; case A0; case A1; case A2; @@ -15,6 +19,10 @@ enum PaperSize implements PaperSizeInterface public function width(): float { return match ($this) { + PaperSize::Letter => 8.5, + PaperSize::Legal => 8.5, + PaperSize::Tabloid => 11, + PaperSize::Ledger => 17, PaperSize::A0 => 33.1, PaperSize::A1 => 23.4, PaperSize::A2 => 16.54, @@ -28,6 +36,10 @@ public function width(): float public function height(): float { return match ($this) { + PaperSize::Letter => 11, + PaperSize::Legal => 14, + PaperSize::Tabloid => 17, + PaperSize::Ledger => 11, PaperSize::A0 => 46.8, PaperSize::A1 => 33.1, PaperSize::A2 => 23.4, @@ -37,4 +49,9 @@ public function height(): float PaperSize::A6 => 5.83, }; } + + public function unit(): Unit + { + return Unit::Inches; + } } diff --git a/src/Enum/PaperSizeInterface.php b/src/Enum/PaperSizeInterface.php index 3f1c718e..16290f57 100644 --- a/src/Enum/PaperSizeInterface.php +++ b/src/Enum/PaperSizeInterface.php @@ -7,4 +7,6 @@ interface PaperSizeInterface public function width(): float; public function height(): float; + + public function unit(): Unit; } diff --git a/src/Enum/Part.php b/src/Enum/Part.php new file mode 100644 index 00000000..6175e38c --- /dev/null +++ b/src/Enum/Part.php @@ -0,0 +1,10 @@ +getFilename()); - self::assertSame(['paperWidth' => '33.1'], $multipartFormData[1]); - self::assertSame(['paperHeight' => '46.8'], $multipartFormData[2]); - self::assertSame(['marginTop' => '1'], $multipartFormData[3]); - self::assertSame(['marginBottom' => '1'], $multipartFormData[4]); - self::assertSame(['marginLeft' => '1'], $multipartFormData[5]); - self::assertSame(['marginRight' => '1'], $multipartFormData[6]); + self::assertSame(['paperWidth' => '33.1in'], $multipartFormData[1]); + self::assertSame(['paperHeight' => '46.8in'], $multipartFormData[2]); + self::assertSame(['marginTop' => '1in'], $multipartFormData[3]); + self::assertSame(['marginBottom' => '1in'], $multipartFormData[4]); + self::assertSame(['marginLeft' => '1in'], $multipartFormData[5]); + self::assertSame(['marginRight' => '1in'], $multipartFormData[6]); self::assertSame(['preferCssPageSize' => 'true'], $multipartFormData[7]); self::assertSame(['printBackground' => 'true'], $multipartFormData[8]); self::assertSame(['omitBackground' => 'true'], $multipartFormData[9]); @@ -116,8 +121,8 @@ public function testWithPaperStandardSize(): void self::assertArrayHasKey('paperWidth', $multipartFormData[1]); self::assertArrayHasKey('paperHeight', $multipartFormData[2]); - self::assertSame((string) PaperSize::A3->width(), $multipartFormData[1]['paperWidth']); - self::assertSame((string) PaperSize::A3->height(), $multipartFormData[2]['paperHeight']); + self::assertSame((string) PaperSize::A3->width().'in', $multipartFormData[1]['paperWidth']); + self::assertSame((string) PaperSize::A3->height().'in', $multipartFormData[2]['paperHeight']); } public function testWithHeader(): void diff --git a/tests/Builder/Pdf/LibreOfficePdfBuilderTest.php b/tests/Builder/Pdf/LibreOfficePdfBuilderTest.php index 11828ee4..30b79961 100644 --- a/tests/Builder/Pdf/LibreOfficePdfBuilderTest.php +++ b/tests/Builder/Pdf/LibreOfficePdfBuilderTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\UsesClass; +use Sensiolabs\GotenbergBundle\Builder\Pdf\AbstractPdfBuilder; use Sensiolabs\GotenbergBundle\Builder\Pdf\LibreOfficePdfBuilder; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; @@ -13,6 +14,7 @@ use Symfony\Component\Mime\Part\DataPart; #[CoversClass(LibreOfficePdfBuilder::class)] +#[UsesClass(AbstractPdfBuilder::class)] #[UsesClass(AssetBaseDirFormatter::class)] #[UsesClass(Filesystem::class)] final class LibreOfficePdfBuilderTest extends AbstractBuilderTestCase diff --git a/tests/Builder/Pdf/MarkdownPdfBuilderTest.php b/tests/Builder/Pdf/MarkdownPdfBuilderTest.php index 29010b95..593a75dc 100644 --- a/tests/Builder/Pdf/MarkdownPdfBuilderTest.php +++ b/tests/Builder/Pdf/MarkdownPdfBuilderTest.php @@ -4,6 +4,8 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\UsesClass; +use Sensiolabs\GotenbergBundle\Builder\Pdf\AbstractChromiumPdfBuilder; +use Sensiolabs\GotenbergBundle\Builder\Pdf\AbstractPdfBuilder; use Sensiolabs\GotenbergBundle\Builder\Pdf\MarkdownPdfBuilder; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; @@ -12,6 +14,8 @@ use Symfony\Component\Mime\Part\DataPart; #[CoversClass(MarkdownPdfBuilder::class)] +#[UsesClass(AbstractChromiumPdfBuilder::class)] +#[UsesClass(AbstractPdfBuilder::class)] #[UsesClass(AssetBaseDirFormatter::class)] #[UsesClass(Filesystem::class)] final class MarkdownPdfBuilderTest extends AbstractBuilderTestCase diff --git a/tests/Builder/Pdf/UrlPdfBuilderTest.php b/tests/Builder/Pdf/UrlPdfBuilderTest.php index 36b0956b..399ce21b 100644 --- a/tests/Builder/Pdf/UrlPdfBuilderTest.php +++ b/tests/Builder/Pdf/UrlPdfBuilderTest.php @@ -4,6 +4,8 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\UsesClass; +use Sensiolabs\GotenbergBundle\Builder\Pdf\AbstractChromiumPdfBuilder; +use Sensiolabs\GotenbergBundle\Builder\Pdf\AbstractPdfBuilder; use Sensiolabs\GotenbergBundle\Builder\Pdf\UrlPdfBuilder; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; @@ -11,6 +13,8 @@ use Symfony\Component\Filesystem\Filesystem; #[CoversClass(UrlPdfBuilder::class)] +#[UsesClass(AbstractChromiumPdfBuilder::class)] +#[UsesClass(AbstractPdfBuilder::class)] #[UsesClass(AssetBaseDirFormatter::class)] #[UsesClass(Filesystem::class)] final class UrlPdfBuilderTest extends AbstractBuilderTestCase diff --git a/tests/Client/GotenbergClientTest.php b/tests/Client/GotenbergClientTest.php index 9c75b5c5..761e7153 100644 --- a/tests/Client/GotenbergClientTest.php +++ b/tests/Client/GotenbergClientTest.php @@ -6,12 +6,14 @@ use PHPUnit\Framework\Attributes\UsesClass; use PHPUnit\Framework\TestCase; use Sensiolabs\GotenbergBundle\Client\GotenbergClient; +use Sensiolabs\GotenbergBundle\Client\GotenbergResponse; use Symfony\Component\HttpClient\MockHttpClient; use Symfony\Component\HttpClient\Response\MockResponse; use Symfony\Component\HttpFoundation\HeaderBag; use Symfony\Component\HttpFoundation\Response; #[CoversClass(GotenbergClient::class)] +#[UsesClass(GotenbergResponse::class)] #[UsesClass(MockResponse::class)] #[UsesClass(MockHttpClient::class)] #[UsesClass(HeaderBag::class)] diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php index ee0d41cf..487c1b0f 100644 --- a/tests/DependencyInjection/ConfigurationTest.php +++ b/tests/DependencyInjection/ConfigurationTest.php @@ -164,6 +164,7 @@ private static function getBundleDefaultConfig(): array 'default_options' => [ 'pdf' => [ 'html' => [ + 'single_page' => null, 'paper_width' => null, 'paper_height' => null, 'margin_top' => null, @@ -188,6 +189,7 @@ private static function getBundleDefaultConfig(): array 'pdf_universal_access' => null, ], 'url' => [ + 'single_page' => null, 'paper_width' => null, 'paper_height' => null, 'margin_top' => null, @@ -212,6 +214,7 @@ private static function getBundleDefaultConfig(): array 'pdf_universal_access' => null, ], 'markdown' => [ + 'single_page' => null, 'paper_width' => null, 'paper_height' => null, 'margin_top' => null, diff --git a/tests/DependencyInjection/SensiolabsGotenbergExtensionTest.php b/tests/DependencyInjection/SensiolabsGotenbergExtensionTest.php index 596a4d12..29b0fb83 100644 --- a/tests/DependencyInjection/SensiolabsGotenbergExtensionTest.php +++ b/tests/DependencyInjection/SensiolabsGotenbergExtensionTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\UsesClass; use PHPUnit\Framework\TestCase; +use Sensiolabs\GotenbergBundle\DependencyInjection\Configuration; use Sensiolabs\GotenbergBundle\DependencyInjection\SensiolabsGotenbergExtension; use Sensiolabs\GotenbergBundle\Enum\PdfFormat; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -12,6 +13,7 @@ #[CoversClass(SensiolabsGotenbergExtension::class)] #[UsesClass(ContainerBuilder::class)] +#[UsesClass(Configuration::class)] final class SensiolabsGotenbergExtensionTest extends TestCase { private function getContainerBuilder(bool $kernelDebug = false): ContainerBuilder diff --git a/tests/GotenbergPdfTest.php b/tests/GotenbergPdfTest.php index 95383995..e639319e 100644 --- a/tests/GotenbergPdfTest.php +++ b/tests/GotenbergPdfTest.php @@ -4,16 +4,42 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\UsesClass; +use Sensiolabs\GotenbergBundle\Builder\Pdf\AbstractChromiumPdfBuilder; +use Sensiolabs\GotenbergBundle\Builder\Pdf\AbstractPdfBuilder; +use Sensiolabs\GotenbergBundle\Builder\Pdf\HtmlPdfBuilder; +use Sensiolabs\GotenbergBundle\Builder\Pdf\LibreOfficePdfBuilder; +use Sensiolabs\GotenbergBundle\Builder\Pdf\MarkdownPdfBuilder; +use Sensiolabs\GotenbergBundle\Builder\Pdf\UrlPdfBuilder; +use Sensiolabs\GotenbergBundle\Client\GotenbergClient; +use Sensiolabs\GotenbergBundle\Debug\Builder\TraceablePdfBuilder; +use Sensiolabs\GotenbergBundle\Debug\TraceableGotenbergPdf; +use Sensiolabs\GotenbergBundle\DependencyInjection\CompilerPass\GotenbergPass; +use Sensiolabs\GotenbergBundle\DependencyInjection\Configuration; +use Sensiolabs\GotenbergBundle\DependencyInjection\SensiolabsGotenbergExtension; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; use Sensiolabs\GotenbergBundle\GotenbergPdf; use Sensiolabs\GotenbergBundle\GotenbergPdfInterface; +use Sensiolabs\GotenbergBundle\SensiolabsGotenbergBundle; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Mime\Part\DataPart; #[CoversClass(GotenbergPdf::class)] +#[UsesClass(AbstractChromiumPdfBuilder::class)] +#[UsesClass(AbstractPdfBuilder::class)] +#[UsesClass(HtmlPdfBuilder::class)] +#[UsesClass(MarkdownPdfBuilder::class)] +#[UsesClass(LibreOfficePdfBuilder::class)] +#[UsesClass(UrlPdfBuilder::class)] +#[UsesClass(GotenbergClient::class)] #[UsesClass(AssetBaseDirFormatter::class)] #[UsesClass(Filesystem::class)] +#[UsesClass(TraceablePdfBuilder::class)] +#[UsesClass(TraceableGotenbergPdf::class)] +#[UsesClass(GotenbergPass::class)] +#[UsesClass(Configuration::class)] +#[UsesClass(SensiolabsGotenbergExtension::class)] +#[UsesClass(SensiolabsGotenbergBundle::class)] final class GotenbergPdfTest extends KernelTestCase { public function testUrlBuilderFactory(): void @@ -46,8 +72,8 @@ public function testHtmlBuilderFactory(): void $builder = $gotenberg->html() ->setConfigurations([ 'margin_top' => 3, - 'margin_bottom' => 1], - ) + 'margin_bottom' => 1, + ]) ; $builder->contentFile(__DIR__.'/../Fixtures/files/content.html'); $multipartFormData = $builder->getMultipartFormData(); @@ -55,10 +81,10 @@ public function testHtmlBuilderFactory(): void self::assertCount(3, $multipartFormData); self::assertArrayHasKey(0, $multipartFormData); - self::assertSame(['marginTop' => '3'], $multipartFormData[0]); + self::assertSame(['marginTop' => '3in'], $multipartFormData[0]); self::assertArrayHasKey(1, $multipartFormData); - self::assertSame(['marginBottom' => '1'], $multipartFormData[1]); + self::assertSame(['marginBottom' => '1in'], $multipartFormData[1]); self::assertArrayHasKey(2, $multipartFormData); self::assertIsArray($multipartFormData[2]);