From 956015bcec7984a82999d10109299c5d5712c93f Mon Sep 17 00:00:00 2001 From: Steven Renaux Date: Sun, 6 Oct 2024 13:05:08 +0200 Subject: [PATCH 1/8] Add release 8.10.0 --- docs/configuration.md | 33 +++++ docs/pdf/builders_api/HtmlPdfBuilder.md | 4 + .../pdf/builders_api/LibreOfficePdfBuilder.md | 7 + docs/pdf/builders_api/MarkdownPdfBuilder.md | 4 + docs/pdf/builders_api/UrlPdfBuilder.md | 4 + docs/pdf/customization.md | 47 ++++++- docs/pdf/office-builder.md | 60 +++++++- .../builders_api/HtmlScreenshotBuilder.md | 4 + .../builders_api/MarkdownScreenshotBuilder.md | 4 + .../builders_api/UrlScreenshotBuilder.md | 4 + docs/screenshot/customization.md | 47 +++++++ .../Pdf/AbstractChromiumPdfBuilder.php | 28 +++- src/Builder/Pdf/AbstractPdfBuilder.php | 3 + src/Builder/Pdf/ConvertPdfBuilder.php | 28 +++- src/Builder/Pdf/HtmlPdfBuilder.php | 2 +- src/Builder/Pdf/LibreOfficePdfBuilder.php | 39 +++++- src/Builder/Pdf/MarkdownPdfBuilder.php | 2 +- src/Builder/Pdf/MergePdfBuilder.php | 28 +++- .../AbstractChromiumScreenshotBuilder.php | 26 ++++ .../Screenshot/AbstractScreenshotBuilder.php | 3 + .../Screenshot/HtmlScreenshotBuilder.php | 2 +- .../Screenshot/MarkdownScreenshotBuilder.php | 2 +- src/DependencyInjection/Configuration.php | 132 +++++++++++------- .../Builder/Pdf/LibreOfficePdfBuilderTest.php | 3 + .../DependencyInjection/ConfigurationTest.php | 44 ++++++ .../SensiolabsGotenbergExtensionTest.php | 21 +++ 26 files changed, 516 insertions(+), 65 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index d49c041f..76628874 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -66,6 +66,7 @@ sensiolabs_gotenberg: pdf_format: null # None pdf_universal_access: null # false metadata: null # None + download_from: null # None url: header: template: null # None @@ -99,6 +100,7 @@ sensiolabs_gotenberg: pdf_format: null # None pdf_universal_access: null # false metadata: null # None + download_from: null # None markdown: header: template: null # None @@ -132,6 +134,7 @@ sensiolabs_gotenberg: pdf_format: null # None pdf_universal_access: null # false metadata: null # None + download_from: null # None office: landscape: null # false native_page_ranges: null # All pages @@ -158,13 +161,17 @@ sensiolabs_gotenberg: quality: null # 90 reduce_image_resolution: null # false max_image_resolution: null # 300 + password: null # None + download_from: null # None merge: pdf_format: null # None pdf_universal_access: null # false metadata: null # None + download_from: null # None convert: pdf_format: null # None pdf_universal_access: null # false + download_from: null # None screenshot: html: width: null # 800 @@ -183,6 +190,7 @@ sensiolabs_gotenberg: fail_on_http_status_codes: null # [499-599] fail_on_console_exceptions: null # false skip_network_idle_event: null # false + download_from: null # None url: width: null # 800 height: null # 600 @@ -200,6 +208,7 @@ sensiolabs_gotenberg: fail_on_http_status_codes: null # [499-599] fail_on_console_exceptions: null # false skip_network_idle_event: null # false + download_from: null # None markdown: width: null # 800 height: null # 600 @@ -217,6 +226,7 @@ sensiolabs_gotenberg: fail_on_http_status_codes: null # [499-599] fail_on_console_exceptions: null # false skip_network_idle_event: null # false + download_from: null # None ``` > [!TIP] @@ -291,3 +301,26 @@ sensiolabs_gotenberg: > [!TIP] > For more information about [metadata](https://gotenberg.dev/docs/routes#metadata-chromium). + +## download from + +To download files resource from URLs. + +``` yaml +sensiolabs_gotenberg: + default_options: + pdf: + html: + download_from: + - url: 'http://url/to/file.com' + extraHttpHeaders: + - name: 'MyHeader' + value: 'MyValue' + - name: 'User-Agent' + value: 'MyValue' + +``` + +> [!TIP] +> For more information go to [Gotenberg documentations](https://gotenberg.dev/docs/routes#download-from). + diff --git a/docs/pdf/builders_api/HtmlPdfBuilder.md b/docs/pdf/builders_api/HtmlPdfBuilder.md index 2598b015..4dc69023 100644 --- a/docs/pdf/builders_api/HtmlPdfBuilder.md +++ b/docs/pdf/builders_api/HtmlPdfBuilder.md @@ -127,6 +127,10 @@ Resets the metadata. * `addMetadata(string $key, string $value)`: The metadata to write. +* `downloadFrom(array $downloadFrom)`: +Sets download from to download each entry (file) in parallel (default None). +(URLs MUST return a Content-Disposition header with a filename parameter.). + * `fileName(string $fileName, string $headerDisposition)`: * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: diff --git a/docs/pdf/builders_api/LibreOfficePdfBuilder.md b/docs/pdf/builders_api/LibreOfficePdfBuilder.md index 0c1eb061..adab5a3f 100644 --- a/docs/pdf/builders_api/LibreOfficePdfBuilder.md +++ b/docs/pdf/builders_api/LibreOfficePdfBuilder.md @@ -1,5 +1,8 @@ # LibreOfficePdfBuilder +* `password(string $password)`: +Set the password for opening the source file. + * `landscape(bool $bool)`: Sets the paper orientation to landscape. @@ -82,6 +85,10 @@ Specify if the resolution of each image is reduced to the resolution specified b * `maxImageResolution(Sensiolabs\GotenbergBundle\Enumeration\ImageResolutionDPI $resolution)`: If the form field reduceImageResolution is set to true, tell if all images will be reduced to the given value in DPI. Possible values are: 75, 150, 300, 600 and 1200. +* `downloadFrom(array $downloadFrom)`: +Sets download from to download each entry (file) in parallel (default None). +(URLs MUST return a Content-Disposition header with a filename parameter.). + * `fileName(string $fileName, string $headerDisposition)`: * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: diff --git a/docs/pdf/builders_api/MarkdownPdfBuilder.md b/docs/pdf/builders_api/MarkdownPdfBuilder.md index e47d72a4..406f5e28 100644 --- a/docs/pdf/builders_api/MarkdownPdfBuilder.md +++ b/docs/pdf/builders_api/MarkdownPdfBuilder.md @@ -130,6 +130,10 @@ Resets the metadata. * `addMetadata(string $key, string $value)`: The metadata to write. +* `downloadFrom(array $downloadFrom)`: +Sets download from to download each entry (file) in parallel (default None). +(URLs MUST return a Content-Disposition header with a filename parameter.). + * `fileName(string $fileName, string $headerDisposition)`: * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: diff --git a/docs/pdf/builders_api/UrlPdfBuilder.md b/docs/pdf/builders_api/UrlPdfBuilder.md index 60608be5..528dc172 100644 --- a/docs/pdf/builders_api/UrlPdfBuilder.md +++ b/docs/pdf/builders_api/UrlPdfBuilder.md @@ -129,6 +129,10 @@ Resets the metadata. * `addMetadata(string $key, string $value)`: The metadata to write. +* `downloadFrom(array $downloadFrom)`: +Sets download from to download each entry (file) in parallel (default None). +(URLs MUST return a Content-Disposition header with a filename parameter.). + * `fileName(string $fileName, string $headerDisposition)`: * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: diff --git a/docs/pdf/customization.md b/docs/pdf/customization.md index 8a733ac2..fc86dd65 100644 --- a/docs/pdf/customization.md +++ b/docs/pdf/customization.md @@ -27,6 +27,7 @@ ### Additional content [header and footer](#header-and-footer) [headerFile and footerFile](#headerfile-and-footerfile) +[download from](#download-from) ### Style [assets](../assets.md) @@ -47,8 +48,8 @@ [skipNetworkIdleEvent](#skipNetworkIdleEvent) ### Formatting -[metadata](#metadata) -[addMetadata](#addMetadata) +[metadata](#metadata) +[addMetadata](#addMetadata) [pdfFormat](#pdfFormat) [pdfUniversalAccess](#pdfUniversalAccess) @@ -526,6 +527,48 @@ class YourController } ``` +### download from + +To download files resource from URLs. + +```php +namespace App\Controller; + +use Sensiolabs\GotenbergBundle\GotenbergPdfInterface; + +class YourController +{ + public function yourControllerMethod(GotenbergPdfInterface $gotenberg): Response + { + return $gotenberg + ->html() + ->downloadFrom([ + [ + 'url' => 'http://url/to/file.com', + 'extraHttpHeaders' => + [ + 'MyHeader' => 'MyValue', + ], + ], + [ + 'url' => 'http://url/to/file.com', + 'extraHttpHeaders' => + [ + 'MyHeaderOne' => 'MyValue', + 'MyHeaderTwo' => 'MyValue', + ], + ], + ]) + ->generate() + ->stream() + ; + } +} +``` + +> [!TIP] +> For more information go to [Gotenberg documentations](https://gotenberg.dev/docs/routes#download-from). + ## Request ### waitDelay diff --git a/docs/pdf/office-builder.md b/docs/pdf/office-builder.md index f6ec9ef4..4e098bf3 100644 --- a/docs/pdf/office-builder.md +++ b/docs/pdf/office-builder.md @@ -771,19 +771,69 @@ class YourController > [!TIP] > For more information go to [Gotenberg documentations](https://gotenberg.dev/docs/routes#images-libreoffice). +### download from +To download files resource from URLs. +```php +namespace App\Controller; +use Sensiolabs\GotenbergBundle\GotenbergPdfInterface; +class YourController +{ + public function yourControllerMethod(GotenbergPdfInterface $gotenberg): Response + { + return $gotenberg + ->office() + ->downloadFrom([ + [ + 'url' => 'http://url/to/file.com', + 'extraHttpHeaders' => + [ + 'MyHeader' => 'MyValue', + ], + ], + [ + 'url' => 'http://url/to/file.com', + 'extraHttpHeaders' => + [ + 'MyHeaderOne' => 'MyValue', + 'MyHeaderTwo' => 'MyValue', + ], + ], + ]) + ->generate() + ->stream() + ; + } +} +``` +> [!TIP] +> For more information go to [Gotenberg documentations](https://gotenberg.dev/docs/routes#download-from). +## password +Default: `None` + Set the password for opening the source file. +```php +namespace App\Controller; +use Sensiolabs\GotenbergBundle\GotenbergPdfInterface; - - - - - +class YourController +{ + public function yourControllerMethod(GotenbergPdfInterface $gotenberg): Response + { + return $gotenberg->office() + ->files('document.txt') + ->password('My password') + ->generate() + ->stream() + ; + } +} +``` diff --git a/docs/screenshot/builders_api/HtmlScreenshotBuilder.md b/docs/screenshot/builders_api/HtmlScreenshotBuilder.md index 75627e28..551adff1 100644 --- a/docs/screenshot/builders_api/HtmlScreenshotBuilder.md +++ b/docs/screenshot/builders_api/HtmlScreenshotBuilder.md @@ -72,6 +72,10 @@ Adds additional files, like images, fonts, stylesheets, and so on (overrides any * `addAsset(string $path)`: Adds a file, like an image, font, stylesheet, and so on. +* `downloadFrom(array $downloadFrom)`: +Sets download from to download each entry (file) in parallel (default None). +(URLs MUST return a Content-Disposition header with a filename parameter.). + * `fileName(string $fileName, string $headerDisposition)`: * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: diff --git a/docs/screenshot/builders_api/MarkdownScreenshotBuilder.md b/docs/screenshot/builders_api/MarkdownScreenshotBuilder.md index c7e0d8d4..ccd2872a 100644 --- a/docs/screenshot/builders_api/MarkdownScreenshotBuilder.md +++ b/docs/screenshot/builders_api/MarkdownScreenshotBuilder.md @@ -75,6 +75,10 @@ Adds additional files, like images, fonts, stylesheets, and so on (overrides any * `addAsset(string $path)`: Adds a file, like an image, font, stylesheet, and so on. +* `downloadFrom(array $downloadFrom)`: +Sets download from to download each entry (file) in parallel (default None). +(URLs MUST return a Content-Disposition header with a filename parameter.). + * `fileName(string $fileName, string $headerDisposition)`: * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: diff --git a/docs/screenshot/builders_api/UrlScreenshotBuilder.md b/docs/screenshot/builders_api/UrlScreenshotBuilder.md index 65496b31..8fbd868e 100644 --- a/docs/screenshot/builders_api/UrlScreenshotBuilder.md +++ b/docs/screenshot/builders_api/UrlScreenshotBuilder.md @@ -74,6 +74,10 @@ Adds additional files, like images, fonts, stylesheets, and so on (overrides any * `addAsset(string $path)`: Adds a file, like an image, font, stylesheet, and so on. +* `downloadFrom(array $downloadFrom)`: +Sets download from to download each entry (file) in parallel (default None). +(URLs MUST return a Content-Disposition header with a filename parameter.). + * `fileName(string $fileName, string $headerDisposition)`: * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: diff --git a/docs/screenshot/customization.md b/docs/screenshot/customization.md index 804b4a0a..775bdcc7 100644 --- a/docs/screenshot/customization.md +++ b/docs/screenshot/customization.md @@ -9,6 +9,9 @@ [quality](#quality) [omitBackground](#omitBackground) +### Additional content +[download from](#download-from) + ### Style [assets](../assets.md) [addAsset](../assets.md) @@ -182,6 +185,50 @@ class YourController } ``` +## Additional content + +### download from + +To download files resource from URLs. + +```php +namespace App\Controller; + +use Sensiolabs\GotenbergBundle\GotenbergScreenshotInterface; + +class YourController +{ + public function yourControllerMethod(GotenbergScreenshotInterface $gotenberg): Response + { + return $gotenberg + ->html() + ->downloadFrom([ + [ + 'url' => 'http://url/to/file.com', + 'extraHttpHeaders' => + [ + 'MyHeader' => 'MyValue', + ], + ], + [ + 'url' => 'http://url/to/file.com', + 'extraHttpHeaders' => + [ + 'MyHeaderOne' => 'MyValue', + 'MyHeaderTwo' => 'MyValue', + ], + ], + ]) + ->generate() + ->stream() + ; + } +} +``` + +> [!TIP] +> For more information go to [Gotenberg documentations](https://gotenberg.dev/docs/routes#download-from). + ## Request ### optimizeForSpeed diff --git a/src/Builder/Pdf/AbstractChromiumPdfBuilder.php b/src/Builder/Pdf/AbstractChromiumPdfBuilder.php index c4089845..3626253a 100644 --- a/src/Builder/Pdf/AbstractChromiumPdfBuilder.php +++ b/src/Builder/Pdf/AbstractChromiumPdfBuilder.php @@ -522,6 +522,31 @@ public function addMetadata(string $key, string $value): static return $this; } + /** + * Sets download from to download each entry (file) in parallel (default None). + * (URLs MUST return a Content-Disposition header with a filename parameter.). + * + * @see https://gotenberg.dev/docs/routes#download-from + * + * @param list}> $downloadFrom + */ + public function downloadFrom(array $downloadFrom): static + { + if ([] === $downloadFrom) { + unset($this->formFields['downloadFrom']); + + return $this; + } + + $this->formFields['downloadFrom'] = []; + + foreach ($downloadFrom as $file) { + $this->formFields['downloadFrom'][] = $file; + } + + return $this; + } + protected function withPdfPartFile(Part $pdfPart, string $path): static { $dataPart = new DataPart( @@ -588,7 +613,8 @@ protected function addConfiguration(string $configurationName, mixed $value): vo '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)), + 'download_from' => $this->downloadFrom($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 9eddae3d..b7931801 100644 --- a/src/Builder/Pdf/AbstractPdfBuilder.php +++ b/src/Builder/Pdf/AbstractPdfBuilder.php @@ -21,6 +21,9 @@ public function __construct( 'metadata' => function (mixed $value): array { return $this->encodeData('metadata', $value); }, + 'downloadFrom' => function (mixed $value): array { + return $this->encodeData('downloadFrom', $value); + }, ]; } } diff --git a/src/Builder/Pdf/ConvertPdfBuilder.php b/src/Builder/Pdf/ConvertPdfBuilder.php index e072e0f9..715ce4bd 100644 --- a/src/Builder/Pdf/ConvertPdfBuilder.php +++ b/src/Builder/Pdf/ConvertPdfBuilder.php @@ -67,13 +67,38 @@ public function getMultipartFormData(): array throw new MissingRequiredFieldException('At least "pdfa" or "pdfua" must be provided.'); } - if ([] === ($this->formFields['files'] ?? [])) { + if ([] === ($this->formFields['files'] ?? []) && [] === ($this->formFields['downloadFrom'] ?? [])) { throw new MissingRequiredFieldException('At least one PDF file is required'); } return parent::getMultipartFormData(); } + /** + * Sets download from to download each entry (file) in parallel (default None). + * (URLs MUST return a Content-Disposition header with a filename parameter.). + * + * @see https://gotenberg.dev/docs/routes#download-from + * + * @param list}> $downloadFrom + */ + public function downloadFrom(array $downloadFrom): static + { + if ([] === $downloadFrom) { + unset($this->formFields['downloadFrom']); + + return $this; + } + + $this->formFields['downloadFrom'] = []; + + foreach ($downloadFrom as $file) { + $this->formFields['downloadFrom'][] = $file; + } + + return $this; + } + protected function getEndpoint(): string { return self::ENDPOINT; @@ -84,6 +109,7 @@ private function addConfiguration(string $configurationName, mixed $value): void match ($configurationName) { 'pdf_format' => $this->pdfFormat(PdfFormat::from($value)), 'pdf_universal_access' => $this->pdfUniversalAccess($value), + 'download_from' => $this->downloadFrom($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/HtmlPdfBuilder.php b/src/Builder/Pdf/HtmlPdfBuilder.php index 1334f5e7..c168feb0 100644 --- a/src/Builder/Pdf/HtmlPdfBuilder.php +++ b/src/Builder/Pdf/HtmlPdfBuilder.php @@ -31,7 +31,7 @@ public function contentFile(string $path): self public function getMultipartFormData(): array { - if (!\array_key_exists(Part::Body->value, $this->formFields)) { + if (!\array_key_exists(Part::Body->value, $this->formFields) && [] === ($this->formFields['downloadFrom'] ?? [])) { throw new MissingRequiredFieldException('Content is required'); } diff --git a/src/Builder/Pdf/LibreOfficePdfBuilder.php b/src/Builder/Pdf/LibreOfficePdfBuilder.php index 557b81cc..0f76c4ea 100644 --- a/src/Builder/Pdf/LibreOfficePdfBuilder.php +++ b/src/Builder/Pdf/LibreOfficePdfBuilder.php @@ -40,6 +40,16 @@ public function setConfigurations(array $configurations): static return $this; } + /** + * Set the password for opening the source file. + */ + public function password(string $password): self + { + $this->formFields['password'] = $password; + + return $this; + } + /** * Sets the paper orientation to landscape. */ @@ -330,13 +340,38 @@ public function maxImageResolution(ImageResolutionDPI $resolution): self public function getMultipartFormData(): array { - if ([] === ($this->formFields['files'] ?? [])) { + if ([] === ($this->formFields['files'] ?? []) && [] === ($this->formFields['downloadFrom'] ?? [])) { throw new MissingRequiredFieldException('At least one office file is required'); } return parent::getMultipartFormData(); } + /** + * Sets download from to download each entry (file) in parallel (default None). + * (URLs MUST return a Content-Disposition header with a filename parameter.). + * + * @see https://gotenberg.dev/docs/routes#download-from + * + * @param list}> $downloadFrom + */ + public function downloadFrom(array $downloadFrom): self + { + if ([] === $downloadFrom) { + unset($this->formFields['downloadFrom']); + + return $this; + } + + $this->formFields['downloadFrom'] = []; + + foreach ($downloadFrom as $file) { + $this->formFields['downloadFrom'][] = $file; + } + + return $this; + } + protected function getEndpoint(): string { return self::ENDPOINT; @@ -345,6 +380,7 @@ protected function getEndpoint(): string private function addConfiguration(string $configurationName, mixed $value): void { match ($configurationName) { + 'password' => $this->password($value), 'pdf_format' => $this->pdfFormat(PdfFormat::from($value)), 'pdf_universal_access' => $this->pdfUniversalAccess($value), 'landscape' => $this->landscape($value), @@ -370,6 +406,7 @@ private function addConfiguration(string $configurationName, mixed $value): void 'quality' => $this->quality($value), 'reduce_image_resolution' => $this->reduceImageResolution($value), 'max_image_resolution' => $this->maxImageResolution(ImageResolutionDPI::from($value)), + 'download_from' => $this->downloadFrom($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 e7530a1e..08a7258f 100644 --- a/src/Builder/Pdf/MarkdownPdfBuilder.php +++ b/src/Builder/Pdf/MarkdownPdfBuilder.php @@ -54,7 +54,7 @@ public function getMultipartFormData(): array throw new MissingRequiredFieldException('HTML template is required'); } - if ([] === ($this->formFields['files'] ?? [])) { + if ([] === ($this->formFields['files'] ?? []) && [] === ($this->formFields['downloadFrom'] ?? [])) { throw new MissingRequiredFieldException('At least one markdown file is required'); } diff --git a/src/Builder/Pdf/MergePdfBuilder.php b/src/Builder/Pdf/MergePdfBuilder.php index b59d892d..fd6f5313 100644 --- a/src/Builder/Pdf/MergePdfBuilder.php +++ b/src/Builder/Pdf/MergePdfBuilder.php @@ -89,13 +89,38 @@ public function addMetadata(string $key, string $value): static public function getMultipartFormData(): array { - if ([] === ($this->formFields['files'] ?? [])) { + if ([] === ($this->formFields['files'] ?? []) && [] === ($this->formFields['downloadFrom'] ?? [])) { throw new MissingRequiredFieldException('At least one PDF file is required'); } return parent::getMultipartFormData(); } + /** + * Sets download from to download each entry (file) in parallel (default None). + * (URLs MUST return a Content-Disposition header with a filename parameter.). + * + * @see https://gotenberg.dev/docs/routes#download-from + * + * @param list}> $downloadFrom + */ + public function downloadFrom(array $downloadFrom): static + { + if ([] === $downloadFrom) { + unset($this->formFields['downloadFrom']); + + return $this; + } + + $this->formFields['downloadFrom'] = []; + + foreach ($downloadFrom as $file) { + $this->formFields['downloadFrom'][] = $file; + } + + return $this; + } + protected function getEndpoint(): string { return self::ENDPOINT; @@ -107,6 +132,7 @@ private function addConfiguration(string $configurationName, mixed $value): void 'pdf_format' => $this->pdfFormat(PdfFormat::from($value)), 'pdf_universal_access' => $this->pdfUniversalAccess($value), 'metadata' => $this->metadata($value), + 'download_from' => $this->downloadFrom($value), default => throw new InvalidBuilderConfiguration(\sprintf('Invalid option "%s": no method does not exist in class "%s" to configured it.', $configurationName, self::class)), }; } diff --git a/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php b/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php index e3a64568..3e39bcde 100644 --- a/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php +++ b/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php @@ -329,6 +329,31 @@ public function addAsset(string $path): static return $this; } + /** + * Sets download from to download each entry (file) in parallel (default None). + * (URLs MUST return a Content-Disposition header with a filename parameter.). + * + * @see https://gotenberg.dev/docs/routes#download-from + * + * @param list}> $downloadFrom + */ + public function downloadFrom(array $downloadFrom): static + { + if ([] === $downloadFrom) { + unset($this->formFields['downloadFrom']); + + return $this; + } + + $this->formFields['downloadFrom'] = []; + + foreach ($downloadFrom as $file) { + $this->formFields['downloadFrom'][] = $file; + } + + return $this; + } + protected function withScreenshotPartFile(Part $screenshotPart, string $path): static { $dataPart = new DataPart( @@ -383,6 +408,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), + 'download_from' => $this->downloadFrom($value), default => throw new InvalidBuilderConfiguration(\sprintf('Invalid option "%s": no method exists in class "%s" to configured it.', $configurationName, static::class)), }; } diff --git a/src/Builder/Screenshot/AbstractScreenshotBuilder.php b/src/Builder/Screenshot/AbstractScreenshotBuilder.php index dc6a25c9..6f8e9efe 100644 --- a/src/Builder/Screenshot/AbstractScreenshotBuilder.php +++ b/src/Builder/Screenshot/AbstractScreenshotBuilder.php @@ -35,6 +35,9 @@ public function __construct( 'cookies' => function (mixed $value): array { return $this->encodeData('cookies', array_values($value)); }, + 'downloadFrom' => function (mixed $value): array { + return $this->encodeData('downloadFrom', $value); + }, ]; } } diff --git a/src/Builder/Screenshot/HtmlScreenshotBuilder.php b/src/Builder/Screenshot/HtmlScreenshotBuilder.php index 259771cc..ee3c10f9 100644 --- a/src/Builder/Screenshot/HtmlScreenshotBuilder.php +++ b/src/Builder/Screenshot/HtmlScreenshotBuilder.php @@ -31,7 +31,7 @@ public function contentFile(string $path): self public function getMultipartFormData(): array { - if (!\array_key_exists(Part::Body->value, $this->formFields)) { + if (!\array_key_exists(Part::Body->value, $this->formFields) && [] === ($this->formFields['downloadFrom'] ?? [])) { throw new MissingRequiredFieldException('Content is required'); } diff --git a/src/Builder/Screenshot/MarkdownScreenshotBuilder.php b/src/Builder/Screenshot/MarkdownScreenshotBuilder.php index 943d8477..ce601f7d 100644 --- a/src/Builder/Screenshot/MarkdownScreenshotBuilder.php +++ b/src/Builder/Screenshot/MarkdownScreenshotBuilder.php @@ -54,7 +54,7 @@ public function getMultipartFormData(): array throw new MissingRequiredFieldException('HTML template is required'); } - if ([] === ($this->formFields['files'] ?? [])) { + if ([] === ($this->formFields['files'] ?? []) && [] === ($this->formFields['downloadFrom'] ?? [])) { throw new MissingRequiredFieldException('At least one markdown file is required'); } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 1d18b861..afdd8610 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -301,31 +301,7 @@ private function addChromiumPdfOptionsNode(ArrayNodeDefinition $parent): void ->thenInvalid('Invalid value %s') ->end() ->end() - ->arrayNode('extra_http_headers') - ->info('HTTP headers to send by Chromium while loading the HTML document - default None. https://gotenberg.dev/docs/routes#custom-http-headers') - ->defaultValue([]) - ->useAttributeAsKey('name') - ->arrayPrototype() - ->children() - ->scalarNode('name') - ->validate() - ->ifTrue(static function ($option) { - return !\is_string($option); - }) - ->thenInvalid('Invalid header name %s') - ->end() - ->end() - ->scalarNode('value') - ->validate() - ->ifTrue(static function ($option) { - return !\is_string($option); - }) - ->thenInvalid('Invalid header value %s') - ->end() - ->end() - ->end() - ->end() - ->end() + ->append($this->addExtraHttpHeaders()) ->arrayNode('fail_on_http_status_codes') ->info('Return a 409 Conflict response if the HTTP status code from the main page is not acceptable. - default [499,599]. https://gotenberg.dev/docs/routes#invalid-http-status-codes-chromium') ->defaultValue([499, 599]) @@ -341,6 +317,7 @@ private function addChromiumPdfOptionsNode(ArrayNodeDefinition $parent): void ->defaultNull() ->end() ->append($this->addPdfMetadata()) + ->append($this->addDownloadFrom()) ->end() ->validate() ->ifTrue(function ($v) { @@ -448,31 +425,7 @@ private function addChromiumScreenshotOptionsNode(ArrayNodeDefinition $parent): ->thenInvalid('Invalid value %s') ->end() ->end() - ->arrayNode('extra_http_headers') - ->info('HTTP headers to send by Chromium while loading the HTML document - default None. https://gotenberg.dev/docs/routes#custom-http-headers-chromium') - ->defaultValue([]) - ->useAttributeAsKey('name') - ->arrayPrototype() - ->children() - ->scalarNode('name') - ->validate() - ->ifTrue(static function ($option) { - return !\is_string($option); - }) - ->thenInvalid('Invalid header name %s') - ->end() - ->end() - ->scalarNode('value') - ->validate() - ->ifTrue(static function ($option) { - return !\is_string($option); - }) - ->thenInvalid('Invalid header value %s') - ->end() - ->end() - ->end() - ->end() - ->end() + ->append($this->addExtraHttpHeaders()) ->arrayNode('fail_on_http_status_codes') ->info('Return a 409 Conflict response if the HTTP status code from the main page is not acceptable. - default [499,599]. https://gotenberg.dev/docs/routes#invalid-http-status-codes-chromium') ->defaultValue([499, 599]) @@ -487,6 +440,7 @@ private function addChromiumScreenshotOptionsNode(ArrayNodeDefinition $parent): ->info('Do not wait for Chromium network to be idle. - default false. https://gotenberg.dev/docs/routes#performance-mode-chromium') ->defaultNull() ->end() + ->append($this->addDownloadFrom()) ->end() ; } @@ -498,6 +452,10 @@ private function addPdfOfficeNode(): NodeDefinition $treeBuilder->getRootNode() ->addDefaultsIfNotSet() ->children() + ->scalarNode('password') + ->info('Set the password for opening the source file. https://gotenberg.dev/docs/routes#page-properties-libreoffice') + ->defaultNull() + ->end() ->booleanNode('landscape') ->info('The paper orientation to landscape - default false. https://gotenberg.dev/docs/routes#page-properties-chromium') ->defaultNull() @@ -596,6 +554,7 @@ private function addPdfOfficeNode(): NodeDefinition ->values(array_map(static fn (ImageResolutionDPI $case): int => $case->value, ImageResolutionDPI::cases())) ->defaultNull() ->end() + ->append($this->addDownloadFrom()) ->end() ; @@ -608,6 +567,9 @@ private function addPdfConvertNode(): NodeDefinition { $treeBuilder = new TreeBuilder('convert'); $this->addPdfFormat($treeBuilder->getRootNode()); + $treeBuilder->getRootNode() + ->append($this->addDownloadFrom()) + ->end(); return $treeBuilder->getRootNode(); } @@ -618,6 +580,7 @@ private function addPdfMergeNode(): NodeDefinition $this->addPdfFormat($treeBuilder->getRootNode()); $treeBuilder->getRootNode() ->append($this->addPdfMetadata()) + ->append($this->addDownloadFrom()) ->end(); return $treeBuilder->getRootNode(); @@ -663,4 +626,73 @@ private function addPdfMetadata(): NodeDefinition ->end() ; } + + private function addDownloadFrom(): NodeDefinition + { + $treeBuilder = new TreeBuilder('download_from'); + + return $treeBuilder->getRootNode() + ->info('URLs to download files from (JSON format). - default None. https://gotenberg.dev/docs/routes#download-from') + ->defaultValue([]) + ->arrayPrototype() + ->children() + ->scalarNode('url')->end() + ->arrayNode('extraHttpHeaders') + ->useAttributeAsKey('name') + ->arrayPrototype() + ->children() + ->scalarNode('name') + ->validate() + ->ifTrue(static function ($option) { + return !\is_string($option); + }) + ->thenInvalid('Invalid header name %s') + ->end() + ->end() + ->scalarNode('value') + ->validate() + ->ifTrue(static function ($option) { + return !\is_string($option); + }) + ->thenInvalid('Invalid header value %s') + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ; + } + + private function addExtraHttpHeaders(): NodeDefinition + { + $treeBuilder = new TreeBuilder('extra_http_headers'); + + return $treeBuilder->getRootNode() + ->info('HTTP headers to send by Chromium while loading the HTML document - default None. https://gotenberg.dev/docs/routes#custom-http-headers') + ->defaultValue([]) + ->useAttributeAsKey('name') + ->arrayPrototype() + ->children() + ->scalarNode('name') + ->validate() + ->ifTrue(static function ($option) { + return !\is_string($option); + }) + ->thenInvalid('Invalid header name %s') + ->end() + ->end() + ->scalarNode('value') + ->validate() + ->ifTrue(static function ($option) { + return !\is_string($option); + }) + ->thenInvalid('Invalid header value %s') + ->end() + ->end() + ->end() + ->end() + ; + } } diff --git a/tests/Builder/Pdf/LibreOfficePdfBuilderTest.php b/tests/Builder/Pdf/LibreOfficePdfBuilderTest.php index d5742ac3..9a0b0f1b 100644 --- a/tests/Builder/Pdf/LibreOfficePdfBuilderTest.php +++ b/tests/Builder/Pdf/LibreOfficePdfBuilderTest.php @@ -116,6 +116,9 @@ public static function configurationIsCorrectlySetProvider(): \Generator yield 'max_image_resolution' => ['max_image_resolution', 300, [ 'maxImageResolution' => 300, ]]; + yield 'password' => ['password', 'My password', [ + 'password' => 'My password', + ]]; } /** diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php index 48a7fc6d..af3387ad 100644 --- a/tests/DependencyInjection/ConfigurationTest.php +++ b/tests/DependencyInjection/ConfigurationTest.php @@ -82,6 +82,40 @@ public function testWithExtraHeadersConfiguration(): void ], $config); } + public function testWithDownloadFromConfiguration(): void + { + $processor = new Processor(); + /** @var array{'default_options': array} $config */ + $config = $processor->processConfiguration(new Configuration(), [ + [ + 'http_client' => 'http_client', + 'default_options' => [ + 'pdf' => [ + 'html' => [ + 'download_from' => [ + [ + 'url' => 'http://url/to/file.com', + 'extraHttpHeaders' => [['name' => 'MyHeader', 'value' => 'MyValue'], ['name' => 'User-Agent', 'value' => 'MyValue']], + ], + ], + ], + ], + ], + ], + ]); + + $config = $this->cleanOptions($config['default_options']['pdf']['html']); + self::assertEquals([ + 'download_from' => [ + [ + 'url' => 'http://url/to/file.com', + 'extraHttpHeaders' => ['MyHeader' => 'MyValue', 'User-Agent' => 'MyValue'], + ], + ], + 'fail_on_http_status_codes' => ['499', '599'], + ], $config); + } + /** * @return iterable>> */ @@ -176,6 +210,7 @@ private static function getBundleDefaultConfig(): array 'skip_network_idle_event' => null, 'pdf_format' => null, 'pdf_universal_access' => null, + 'download_from' => [], ], 'url' => [ 'single_page' => null, @@ -203,6 +238,7 @@ private static function getBundleDefaultConfig(): array 'skip_network_idle_event' => null, 'pdf_format' => null, 'pdf_universal_access' => null, + 'download_from' => [], ], 'markdown' => [ 'single_page' => null, @@ -230,8 +266,10 @@ private static function getBundleDefaultConfig(): array 'skip_network_idle_event' => null, 'pdf_format' => null, 'pdf_universal_access' => null, + 'download_from' => [], ], 'office' => [ + 'password' => null, 'landscape' => null, 'native_page_ranges' => null, 'do_not_export_form_fields' => null, @@ -256,14 +294,17 @@ private static function getBundleDefaultConfig(): array 'quality' => null, 'reduce_image_resolution' => null, 'max_image_resolution' => null, + 'download_from' => [], ], 'merge' => [ 'pdf_format' => null, 'pdf_universal_access' => null, + 'download_from' => [], ], 'convert' => [ 'pdf_format' => null, 'pdf_universal_access' => null, + 'download_from' => [], ], ], 'screenshot' => [ @@ -284,6 +325,7 @@ private static function getBundleDefaultConfig(): array 'fail_on_http_status_codes' => [499, 599], 'fail_on_console_exceptions' => null, 'skip_network_idle_event' => null, + 'download_from' => [], ], 'url' => [ 'width' => null, @@ -302,6 +344,7 @@ private static function getBundleDefaultConfig(): array 'fail_on_http_status_codes' => [499, 599], 'fail_on_console_exceptions' => null, 'skip_network_idle_event' => null, + 'download_from' => [], ], 'markdown' => [ 'width' => null, @@ -320,6 +363,7 @@ private static function getBundleDefaultConfig(): array 'fail_on_http_status_codes' => [499, 599], 'fail_on_console_exceptions' => null, 'skip_network_idle_event' => null, + 'download_from' => [], ], ], ], diff --git a/tests/DependencyInjection/SensiolabsGotenbergExtensionTest.php b/tests/DependencyInjection/SensiolabsGotenbergExtensionTest.php index 9b11c17c..02a9fc6f 100644 --- a/tests/DependencyInjection/SensiolabsGotenbergExtensionTest.php +++ b/tests/DependencyInjection/SensiolabsGotenbergExtensionTest.php @@ -63,6 +63,7 @@ public function testGotenbergConfiguredWithValidConfig(): void 'skip_network_idle_event' => true, 'pdf_format' => 'PDF/A-1b', 'pdf_universal_access' => true, + 'download_from' => [], ], 'url' => [ 'paper_width' => 21, @@ -87,6 +88,7 @@ public function testGotenbergConfiguredWithValidConfig(): void 'pdf_format' => PdfFormat::Pdf2b->value, 'pdf_universal_access' => false, 'cookies' => [], + 'download_from' => [], ], 'markdown' => [ 'paper_width' => 30, @@ -111,6 +113,7 @@ public function testGotenbergConfiguredWithValidConfig(): void 'pdf_format' => PdfFormat::Pdf3b->value, 'pdf_universal_access' => true, 'cookies' => [], + 'download_from' => [], ], 'office' => [ 'landscape' => false, @@ -118,14 +121,17 @@ public function testGotenbergConfiguredWithValidConfig(): void 'merge' => true, 'pdf_format' => 'PDF/A-1b', 'pdf_universal_access' => true, + 'download_from' => [], ], 'merge' => [ 'pdf_format' => 'PDF/A-3b', 'pdf_universal_access' => true, + 'download_from' => [], ], 'convert' => [ 'pdf_format' => 'PDF/A-2b', 'pdf_universal_access' => true, + 'download_from' => [], ], ], 'screenshot' => [ @@ -152,6 +158,7 @@ public function testGotenbergConfiguredWithValidConfig(): void 'fail_on_http_status_codes' => [401], 'fail_on_console_exceptions' => true, 'skip_network_idle_event' => true, + 'download_from' => [], ], 'url' => [ 'width' => 1000, @@ -177,6 +184,7 @@ public function testGotenbergConfiguredWithValidConfig(): void 'fail_on_http_status_codes' => [401, 403], 'fail_on_console_exceptions' => false, 'skip_network_idle_event' => true, + 'download_from' => [], ], 'markdown' => [ 'width' => 1000, @@ -201,6 +209,7 @@ public function testGotenbergConfiguredWithValidConfig(): void 'fail_on_http_status_codes' => [401, 403], 'fail_on_console_exceptions' => false, 'skip_network_idle_event' => false, + 'download_from' => [], ], ], ]; @@ -307,6 +316,7 @@ public function testDataCollectorIsProperlyConfiguredIfEnabled(): void 'cookies' => [], 'extra_http_headers' => [], 'fail_on_http_status_codes' => [], + 'download_from' => [], ], 'url' => [ 'metadata' => [ @@ -315,6 +325,7 @@ public function testDataCollectorIsProperlyConfiguredIfEnabled(): void 'cookies' => [], 'extra_http_headers' => [], 'fail_on_http_status_codes' => [], + 'download_from' => [], ], 'markdown' => [ 'metadata' => [ @@ -323,19 +334,23 @@ public function testDataCollectorIsProperlyConfiguredIfEnabled(): void 'cookies' => [], 'extra_http_headers' => [], 'fail_on_http_status_codes' => [], + 'download_from' => [], ], 'office' => [ 'metadata' => [ 'Author' => 'SensioLabs OFFICE', ], + 'download_from' => [], ], 'merge' => [ 'metadata' => [ 'Author' => 'SensioLabs MERGE', ], + 'download_from' => [], ], 'convert' => [ 'pdf_format' => 'PDF/A-2b', + 'download_from' => [], ], ], ], @@ -353,6 +368,7 @@ public function testDataCollectorIsProperlyConfiguredIfEnabled(): void 'cookies' => [], 'extra_http_headers' => [], 'fail_on_http_status_codes' => [], + 'download_from' => [], ], 'url' => [ 'metadata' => [ @@ -361,6 +377,7 @@ public function testDataCollectorIsProperlyConfiguredIfEnabled(): void 'cookies' => [], 'extra_http_headers' => [], 'fail_on_http_status_codes' => [], + 'download_from' => [], ], 'markdown' => [ 'metadata' => [ @@ -369,19 +386,23 @@ public function testDataCollectorIsProperlyConfiguredIfEnabled(): void 'cookies' => [], 'extra_http_headers' => [], 'fail_on_http_status_codes' => [], + 'download_from' => [], ], 'office' => [ 'metadata' => [ 'Author' => 'SensioLabs OFFICE', ], + 'download_from' => [], ], 'merge' => [ 'metadata' => [ 'Author' => 'SensioLabs MERGE', ], + 'download_from' => [], ], 'convert' => [ 'pdf_format' => 'PDF/A-2b', + 'download_from' => [], ], ], $dataCollectorOptions); } From 558f3dd4ee37e33097e4df5c6916346fa11a7e78 Mon Sep 17 00:00:00 2001 From: Steven Renaux Date: Sat, 12 Oct 2024 16:12:48 +0200 Subject: [PATCH 2/8] Fix reviews --- docs/configuration.md | 3 ++ docs/pdf/builders_api/HtmlPdfBuilder.md | 4 +- .../pdf/builders_api/LibreOfficePdfBuilder.md | 4 +- docs/pdf/builders_api/MarkdownPdfBuilder.md | 4 +- docs/pdf/builders_api/UrlPdfBuilder.md | 4 +- docs/pdf/customization.md | 3 ++ docs/pdf/office-builder.md | 3 ++ .../builders_api/HtmlScreenshotBuilder.md | 4 +- .../builders_api/MarkdownScreenshotBuilder.md | 4 +- .../builders_api/UrlScreenshotBuilder.md | 4 +- docs/screenshot/customization.md | 3 ++ src/Builder/DownloadFromTrait.php | 53 +++++++++++++++++++ .../Pdf/AbstractChromiumPdfBuilder.php | 25 --------- src/Builder/Pdf/AbstractPdfBuilder.php | 14 +++-- src/Builder/Pdf/ConvertPdfBuilder.php | 25 --------- src/Builder/Pdf/LibreOfficePdfBuilder.php | 27 +--------- src/Builder/Pdf/MergePdfBuilder.php | 25 --------- .../AbstractChromiumScreenshotBuilder.php | 25 --------- .../Screenshot/AbstractScreenshotBuilder.php | 29 ++++------ src/DependencyInjection/Configuration.php | 18 +++---- 20 files changed, 111 insertions(+), 170 deletions(-) create mode 100644 src/Builder/DownloadFromTrait.php diff --git a/docs/configuration.md b/docs/configuration.md index 3f7cbf2a..69fd87fc 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -312,6 +312,9 @@ Enabled byd efault but can be disabled via the `sensiolabs_gotenberg.controller_ ## download from +> [!WARNING] +> URL of the file. It MUST return a `Content-Disposition` header with a filename parameter. + To download files resource from URLs. ``` yaml diff --git a/docs/pdf/builders_api/HtmlPdfBuilder.md b/docs/pdf/builders_api/HtmlPdfBuilder.md index 4dc69023..f1b399b2 100644 --- a/docs/pdf/builders_api/HtmlPdfBuilder.md +++ b/docs/pdf/builders_api/HtmlPdfBuilder.md @@ -128,13 +128,13 @@ Resets the metadata. The metadata to write. * `downloadFrom(array $downloadFrom)`: -Sets download from to download each entry (file) in parallel (default None). -(URLs MUST return a Content-Disposition header with a filename parameter.). * `fileName(string $fileName, string $headerDisposition)`: * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: +* `withDownloadFrom(array $formFields, array $downloadFrom)`: + * `addCookies(array $cookies)`: Add cookies to store in the Chromium cookie jar. diff --git a/docs/pdf/builders_api/LibreOfficePdfBuilder.md b/docs/pdf/builders_api/LibreOfficePdfBuilder.md index adab5a3f..eeee4b63 100644 --- a/docs/pdf/builders_api/LibreOfficePdfBuilder.md +++ b/docs/pdf/builders_api/LibreOfficePdfBuilder.md @@ -86,10 +86,10 @@ Specify if the resolution of each image is reduced to the resolution specified b If the form field reduceImageResolution is set to true, tell if all images will be reduced to the given value in DPI. Possible values are: 75, 150, 300, 600 and 1200. * `downloadFrom(array $downloadFrom)`: -Sets download from to download each entry (file) in parallel (default None). -(URLs MUST return a Content-Disposition header with a filename parameter.). * `fileName(string $fileName, string $headerDisposition)`: * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: +* `withDownloadFrom(array $formFields, array $downloadFrom)`: + diff --git a/docs/pdf/builders_api/MarkdownPdfBuilder.md b/docs/pdf/builders_api/MarkdownPdfBuilder.md index 406f5e28..9dd36ef1 100644 --- a/docs/pdf/builders_api/MarkdownPdfBuilder.md +++ b/docs/pdf/builders_api/MarkdownPdfBuilder.md @@ -131,13 +131,13 @@ Resets the metadata. The metadata to write. * `downloadFrom(array $downloadFrom)`: -Sets download from to download each entry (file) in parallel (default None). -(URLs MUST return a Content-Disposition header with a filename parameter.). * `fileName(string $fileName, string $headerDisposition)`: * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: +* `withDownloadFrom(array $formFields, array $downloadFrom)`: + * `addCookies(array $cookies)`: Add cookies to store in the Chromium cookie jar. diff --git a/docs/pdf/builders_api/UrlPdfBuilder.md b/docs/pdf/builders_api/UrlPdfBuilder.md index 528dc172..555583c1 100644 --- a/docs/pdf/builders_api/UrlPdfBuilder.md +++ b/docs/pdf/builders_api/UrlPdfBuilder.md @@ -130,13 +130,13 @@ Resets the metadata. The metadata to write. * `downloadFrom(array $downloadFrom)`: -Sets download from to download each entry (file) in parallel (default None). -(URLs MUST return a Content-Disposition header with a filename parameter.). * `fileName(string $fileName, string $headerDisposition)`: * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: +* `withDownloadFrom(array $formFields, array $downloadFrom)`: + * `addCookies(array $cookies)`: Add cookies to store in the Chromium cookie jar. diff --git a/docs/pdf/customization.md b/docs/pdf/customization.md index fc86dd65..94eb193a 100644 --- a/docs/pdf/customization.md +++ b/docs/pdf/customization.md @@ -529,6 +529,9 @@ class YourController ### download from +> [!WARNING] +> URL of the file. It MUST return a `Content-Disposition` header with a filename parameter. + To download files resource from URLs. ```php diff --git a/docs/pdf/office-builder.md b/docs/pdf/office-builder.md index 4e098bf3..0b8fe11c 100644 --- a/docs/pdf/office-builder.md +++ b/docs/pdf/office-builder.md @@ -773,6 +773,9 @@ class YourController ### download from +> [!WARNING] +> URL of the file. It MUST return a `Content-Disposition` header with a filename parameter. + To download files resource from URLs. ```php diff --git a/docs/screenshot/builders_api/HtmlScreenshotBuilder.md b/docs/screenshot/builders_api/HtmlScreenshotBuilder.md index 551adff1..35c73f68 100644 --- a/docs/screenshot/builders_api/HtmlScreenshotBuilder.md +++ b/docs/screenshot/builders_api/HtmlScreenshotBuilder.md @@ -73,13 +73,13 @@ Adds additional files, like images, fonts, stylesheets, and so on (overrides any Adds a file, like an image, font, stylesheet, and so on. * `downloadFrom(array $downloadFrom)`: -Sets download from to download each entry (file) in parallel (default None). -(URLs MUST return a Content-Disposition header with a filename parameter.). * `fileName(string $fileName, string $headerDisposition)`: * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: +* `withDownloadFrom(array $formFields, array $downloadFrom)`: + * `addCookies(array $cookies)`: Add cookies to store in the Chromium cookie jar. diff --git a/docs/screenshot/builders_api/MarkdownScreenshotBuilder.md b/docs/screenshot/builders_api/MarkdownScreenshotBuilder.md index ccd2872a..1dec2ca6 100644 --- a/docs/screenshot/builders_api/MarkdownScreenshotBuilder.md +++ b/docs/screenshot/builders_api/MarkdownScreenshotBuilder.md @@ -76,13 +76,13 @@ Adds additional files, like images, fonts, stylesheets, and so on (overrides any Adds a file, like an image, font, stylesheet, and so on. * `downloadFrom(array $downloadFrom)`: -Sets download from to download each entry (file) in parallel (default None). -(URLs MUST return a Content-Disposition header with a filename parameter.). * `fileName(string $fileName, string $headerDisposition)`: * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: +* `withDownloadFrom(array $formFields, array $downloadFrom)`: + * `addCookies(array $cookies)`: Add cookies to store in the Chromium cookie jar. diff --git a/docs/screenshot/builders_api/UrlScreenshotBuilder.md b/docs/screenshot/builders_api/UrlScreenshotBuilder.md index 8fbd868e..5ac3c857 100644 --- a/docs/screenshot/builders_api/UrlScreenshotBuilder.md +++ b/docs/screenshot/builders_api/UrlScreenshotBuilder.md @@ -75,13 +75,13 @@ Adds additional files, like images, fonts, stylesheets, and so on (overrides any Adds a file, like an image, font, stylesheet, and so on. * `downloadFrom(array $downloadFrom)`: -Sets download from to download each entry (file) in parallel (default None). -(URLs MUST return a Content-Disposition header with a filename parameter.). * `fileName(string $fileName, string $headerDisposition)`: * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: +* `withDownloadFrom(array $formFields, array $downloadFrom)`: + * `addCookies(array $cookies)`: Add cookies to store in the Chromium cookie jar. diff --git a/docs/screenshot/customization.md b/docs/screenshot/customization.md index 775bdcc7..f4610162 100644 --- a/docs/screenshot/customization.md +++ b/docs/screenshot/customization.md @@ -189,6 +189,9 @@ class YourController ### download from +> [!WARNING] +> URL of the file. It MUST return a `Content-Disposition` header with a filename parameter. + To download files resource from URLs. ```php diff --git a/src/Builder/DownloadFromTrait.php b/src/Builder/DownloadFromTrait.php new file mode 100644 index 00000000..e1925881 --- /dev/null +++ b/src/Builder/DownloadFromTrait.php @@ -0,0 +1,53 @@ +}> $downloadFrom + */ + abstract public function downloadFrom(array $downloadFrom): static; + + /** + * @param array{downloadFrom?: array}>} $formFields + * @param list}> $downloadFrom + */ + public function withDownloadFrom(array &$formFields, array $downloadFrom): static + { + if ([] === $downloadFrom) { + unset($formFields['downloadFrom']); + + return $this; + } + + $formFields['downloadFrom'] = []; + + foreach ($downloadFrom as $file) { + if (!\array_key_exists('url', $file)) { + throw new MissingRequiredFieldException('Missing field "url"'); + } + + $formFields['downloadFrom'][$file['url']] = $file; + } + + return $this; + } + + private function downloadFromNormalizer(array $value, callable $encoder): array + { + $downloadsFrom = array_values($value); + $data = []; + + array_push($data, ...$downloadsFrom); + + return $encoder('downloadFrom', $data); + } +} diff --git a/src/Builder/Pdf/AbstractChromiumPdfBuilder.php b/src/Builder/Pdf/AbstractChromiumPdfBuilder.php index 3626253a..d5f2cd34 100644 --- a/src/Builder/Pdf/AbstractChromiumPdfBuilder.php +++ b/src/Builder/Pdf/AbstractChromiumPdfBuilder.php @@ -522,31 +522,6 @@ public function addMetadata(string $key, string $value): static return $this; } - /** - * Sets download from to download each entry (file) in parallel (default None). - * (URLs MUST return a Content-Disposition header with a filename parameter.). - * - * @see https://gotenberg.dev/docs/routes#download-from - * - * @param list}> $downloadFrom - */ - public function downloadFrom(array $downloadFrom): static - { - if ([] === $downloadFrom) { - unset($this->formFields['downloadFrom']); - - return $this; - } - - $this->formFields['downloadFrom'] = []; - - foreach ($downloadFrom as $file) { - $this->formFields['downloadFrom'][] = $file; - } - - return $this; - } - protected function withPdfPartFile(Part $pdfPart, string $path): static { $dataPart = new DataPart( diff --git a/src/Builder/Pdf/AbstractPdfBuilder.php b/src/Builder/Pdf/AbstractPdfBuilder.php index b7931801..658cab32 100644 --- a/src/Builder/Pdf/AbstractPdfBuilder.php +++ b/src/Builder/Pdf/AbstractPdfBuilder.php @@ -3,12 +3,14 @@ namespace Sensiolabs\GotenbergBundle\Builder\Pdf; use Sensiolabs\GotenbergBundle\Builder\DefaultBuilderTrait; +use Sensiolabs\GotenbergBundle\Builder\DownloadFromTrait; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; abstract class AbstractPdfBuilder implements PdfBuilderInterface { use DefaultBuilderTrait; + use DownloadFromTrait; public function __construct( GotenbergClientInterface $gotenbergClient, @@ -21,9 +23,15 @@ public function __construct( 'metadata' => function (mixed $value): array { return $this->encodeData('metadata', $value); }, - 'downloadFrom' => function (mixed $value): array { - return $this->encodeData('downloadFrom', $value); - }, + 'downloadFrom' => fn (array $value): array => $this->downloadFromNormalizer($value, $this->encodeData(...)), ]; } + + /** + * @param list}> $downloadFrom + */ + public function downloadFrom(array $downloadFrom): static + { + return $this->withDownloadFrom($this->formFields, $downloadFrom); + } } diff --git a/src/Builder/Pdf/ConvertPdfBuilder.php b/src/Builder/Pdf/ConvertPdfBuilder.php index 715ce4bd..33916fa1 100644 --- a/src/Builder/Pdf/ConvertPdfBuilder.php +++ b/src/Builder/Pdf/ConvertPdfBuilder.php @@ -74,31 +74,6 @@ public function getMultipartFormData(): array return parent::getMultipartFormData(); } - /** - * Sets download from to download each entry (file) in parallel (default None). - * (URLs MUST return a Content-Disposition header with a filename parameter.). - * - * @see https://gotenberg.dev/docs/routes#download-from - * - * @param list}> $downloadFrom - */ - public function downloadFrom(array $downloadFrom): static - { - if ([] === $downloadFrom) { - unset($this->formFields['downloadFrom']); - - return $this; - } - - $this->formFields['downloadFrom'] = []; - - foreach ($downloadFrom as $file) { - $this->formFields['downloadFrom'][] = $file; - } - - return $this; - } - protected function getEndpoint(): string { return self::ENDPOINT; diff --git a/src/Builder/Pdf/LibreOfficePdfBuilder.php b/src/Builder/Pdf/LibreOfficePdfBuilder.php index 0f76c4ea..38272193 100644 --- a/src/Builder/Pdf/LibreOfficePdfBuilder.php +++ b/src/Builder/Pdf/LibreOfficePdfBuilder.php @@ -43,7 +43,7 @@ public function setConfigurations(array $configurations): static /** * Set the password for opening the source file. */ - public function password(string $password): self + public function password(#[\SensitiveParameter] string $password): self { $this->formFields['password'] = $password; @@ -347,31 +347,6 @@ public function getMultipartFormData(): array return parent::getMultipartFormData(); } - /** - * Sets download from to download each entry (file) in parallel (default None). - * (URLs MUST return a Content-Disposition header with a filename parameter.). - * - * @see https://gotenberg.dev/docs/routes#download-from - * - * @param list}> $downloadFrom - */ - public function downloadFrom(array $downloadFrom): self - { - if ([] === $downloadFrom) { - unset($this->formFields['downloadFrom']); - - return $this; - } - - $this->formFields['downloadFrom'] = []; - - foreach ($downloadFrom as $file) { - $this->formFields['downloadFrom'][] = $file; - } - - return $this; - } - protected function getEndpoint(): string { return self::ENDPOINT; diff --git a/src/Builder/Pdf/MergePdfBuilder.php b/src/Builder/Pdf/MergePdfBuilder.php index fd6f5313..6ff9b8b5 100644 --- a/src/Builder/Pdf/MergePdfBuilder.php +++ b/src/Builder/Pdf/MergePdfBuilder.php @@ -96,31 +96,6 @@ public function getMultipartFormData(): array return parent::getMultipartFormData(); } - /** - * Sets download from to download each entry (file) in parallel (default None). - * (URLs MUST return a Content-Disposition header with a filename parameter.). - * - * @see https://gotenberg.dev/docs/routes#download-from - * - * @param list}> $downloadFrom - */ - public function downloadFrom(array $downloadFrom): static - { - if ([] === $downloadFrom) { - unset($this->formFields['downloadFrom']); - - return $this; - } - - $this->formFields['downloadFrom'] = []; - - foreach ($downloadFrom as $file) { - $this->formFields['downloadFrom'][] = $file; - } - - return $this; - } - protected function getEndpoint(): string { return self::ENDPOINT; diff --git a/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php b/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php index 3e39bcde..b41ba859 100644 --- a/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php +++ b/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php @@ -329,31 +329,6 @@ public function addAsset(string $path): static return $this; } - /** - * Sets download from to download each entry (file) in parallel (default None). - * (URLs MUST return a Content-Disposition header with a filename parameter.). - * - * @see https://gotenberg.dev/docs/routes#download-from - * - * @param list}> $downloadFrom - */ - public function downloadFrom(array $downloadFrom): static - { - if ([] === $downloadFrom) { - unset($this->formFields['downloadFrom']); - - return $this; - } - - $this->formFields['downloadFrom'] = []; - - foreach ($downloadFrom as $file) { - $this->formFields['downloadFrom'][] = $file; - } - - return $this; - } - protected function withScreenshotPartFile(Part $screenshotPart, string $path): static { $dataPart = new DataPart( diff --git a/src/Builder/Screenshot/AbstractScreenshotBuilder.php b/src/Builder/Screenshot/AbstractScreenshotBuilder.php index 6f8e9efe..322719f0 100644 --- a/src/Builder/Screenshot/AbstractScreenshotBuilder.php +++ b/src/Builder/Screenshot/AbstractScreenshotBuilder.php @@ -3,6 +3,7 @@ namespace Sensiolabs\GotenbergBundle\Builder\Screenshot; use Sensiolabs\GotenbergBundle\Builder\DefaultBuilderTrait; +use Sensiolabs\GotenbergBundle\Builder\DownloadFromTrait; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Enumeration\Part; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; @@ -11,6 +12,7 @@ abstract class AbstractScreenshotBuilder implements ScreenshotBuilderInterface { use DefaultBuilderTrait; + use DownloadFromTrait; public function __construct( GotenbergClientInterface $gotenbergClient, @@ -20,24 +22,15 @@ public function __construct( $this->asset = $asset; $this->normalizers = [ - 'extraHttpHeaders' => function (mixed $value): array { - return $this->encodeData('extraHttpHeaders', $value); - }, - 'assets' => static function (array $value): array { - return ['files' => $value]; - }, - Part::Body->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)); - }, - 'downloadFrom' => function (mixed $value): array { - return $this->encodeData('downloadFrom', $value); - }, + 'downloadFrom' => fn (array $value): array => $this->downloadFromNormalizer($value, $this->encodeData(...)), ]; } + + /** + * @param list}> $downloadFrom + */ + public function downloadFrom(array $downloadFrom): static + { + return $this->withDownloadFrom($this->formFields, $downloadFrom); + } } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 59dce55f..32c5c3a9 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -259,7 +259,7 @@ private function addChromiumPdfOptionsNode(ArrayNodeDefinition $parent): void ->info('The JavaScript expression to wait before converting an HTML document into PDF until it returns true - default None. https://gotenberg.dev/docs/routes#wait-before-rendering') ->defaultNull() ->validate() - ->ifTrue(static function ($option) { + ->ifTrue(static function ($option): bool { return !\is_string($option); }) ->thenInvalid('Invalid value %s') @@ -299,7 +299,7 @@ private function addChromiumPdfOptionsNode(ArrayNodeDefinition $parent): void ->info('Override the default User-Agent HTTP header. - default None. https://gotenberg.dev/docs/routes#custom-http-headers-chromium') ->defaultNull() ->validate() - ->ifTrue(static function ($option) { + ->ifTrue(static function ($option): bool { return !\is_string($option); }) ->thenInvalid('Invalid value %s') @@ -324,7 +324,7 @@ private function addChromiumPdfOptionsNode(ArrayNodeDefinition $parent): void ->append($this->addDownloadFrom()) ->end() ->validate() - ->ifTrue(function ($v) { + ->ifTrue(function ($v): bool { return isset($v['paper_standard_size']) && (isset($v['paper_height']) || isset($v['paper_width'])); }) ->thenInvalid('You cannot use "paper_standard_size" when "paper_height", "paper_width" or both are set".') @@ -383,7 +383,7 @@ private function addChromiumScreenshotOptionsNode(ArrayNodeDefinition $parent): ->info('The JavaScript expression to wait before converting an HTML document into PDF until it returns true - default None. https://gotenberg.dev/docs/routes#wait-before-rendering') ->defaultNull() ->validate() - ->ifTrue(static function ($option) { + ->ifTrue(static function ($option): bool { return !\is_string($option); }) ->thenInvalid('Invalid value %s') @@ -423,7 +423,7 @@ private function addChromiumScreenshotOptionsNode(ArrayNodeDefinition $parent): ->info('Override the default User-Agent HTTP header. - default None. https://gotenberg.dev/docs/routes#custom-http-headers-chromium') ->defaultNull() ->validate() - ->ifTrue(static function ($option) { + ->ifTrue(static function ($option): bool { return !\is_string($option); }) ->thenInvalid('Invalid value %s') @@ -647,7 +647,7 @@ private function addDownloadFrom(): NodeDefinition ->children() ->scalarNode('name') ->validate() - ->ifTrue(static function ($option) { + ->ifTrue(static function ($option): bool { return !\is_string($option); }) ->thenInvalid('Invalid header name %s') @@ -655,7 +655,7 @@ private function addDownloadFrom(): NodeDefinition ->end() ->scalarNode('value') ->validate() - ->ifTrue(static function ($option) { + ->ifTrue(static function ($option): bool { return !\is_string($option); }) ->thenInvalid('Invalid header value %s') @@ -681,7 +681,7 @@ private function addExtraHttpHeaders(): NodeDefinition ->children() ->scalarNode('name') ->validate() - ->ifTrue(static function ($option) { + ->ifTrue(static function ($option): bool { return !\is_string($option); }) ->thenInvalid('Invalid header name %s') @@ -689,7 +689,7 @@ private function addExtraHttpHeaders(): NodeDefinition ->end() ->scalarNode('value') ->validate() - ->ifTrue(static function ($option) { + ->ifTrue(static function ($option): bool { return !\is_string($option); }) ->thenInvalid('Invalid header value %s') From d8d74949986524732d24b748746befee40b8c315 Mon Sep 17 00:00:00 2001 From: Steven Renaux Date: Sat, 12 Oct 2024 16:18:01 +0200 Subject: [PATCH 3/8] Fix php cs-fixer --- src/Builder/DownloadFromTrait.php | 5 +++++ src/Builder/Pdf/AbstractChromiumPdfBuilder.php | 2 +- src/Builder/Screenshot/AbstractScreenshotBuilder.php | 2 -- tests/DependencyInjection/ConfigurationTest.php | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Builder/DownloadFromTrait.php b/src/Builder/DownloadFromTrait.php index e1925881..a7407bca 100644 --- a/src/Builder/DownloadFromTrait.php +++ b/src/Builder/DownloadFromTrait.php @@ -41,6 +41,11 @@ public function withDownloadFrom(array &$formFields, array $downloadFrom): stati return $this; } + /** + * @param array}> $value + * + * @return list}> + */ private function downloadFromNormalizer(array $value, callable $encoder): array { $downloadsFrom = array_values($value); diff --git a/src/Builder/Pdf/AbstractChromiumPdfBuilder.php b/src/Builder/Pdf/AbstractChromiumPdfBuilder.php index d5f2cd34..90c454b6 100644 --- a/src/Builder/Pdf/AbstractChromiumPdfBuilder.php +++ b/src/Builder/Pdf/AbstractChromiumPdfBuilder.php @@ -589,7 +589,7 @@ protected function addConfiguration(string $configurationName, mixed $value): vo 'skip_network_idle_event' => $this->skipNetworkIdleEvent($value), 'metadata' => $this->metadata($value), 'download_from' => $this->downloadFrom($value), - default => throw new InvalidBuilderConfiguration(sprintf('Invalid option "%s": no method does not exist in class "%s" to configured it.', $configurationName, static::class)), + 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/Screenshot/AbstractScreenshotBuilder.php b/src/Builder/Screenshot/AbstractScreenshotBuilder.php index 322719f0..ecfc50f5 100644 --- a/src/Builder/Screenshot/AbstractScreenshotBuilder.php +++ b/src/Builder/Screenshot/AbstractScreenshotBuilder.php @@ -5,9 +5,7 @@ use Sensiolabs\GotenbergBundle\Builder\DefaultBuilderTrait; use Sensiolabs\GotenbergBundle\Builder\DownloadFromTrait; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; -use Sensiolabs\GotenbergBundle\Enumeration\Part; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; -use Symfony\Component\Mime\Part\DataPart; abstract class AbstractScreenshotBuilder implements ScreenshotBuilderInterface { diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php index 44610fe1..79cc05b1 100644 --- a/tests/DependencyInjection/ConfigurationTest.php +++ b/tests/DependencyInjection/ConfigurationTest.php @@ -86,7 +86,7 @@ public function testWithDownloadFromConfiguration(): void { $processor = new Processor(); /** @var array{'default_options': array} $config */ - $config = $processor->processConfiguration(new Configuration(), [ + $config = $processor->processConfiguration(new Configuration(), [ [ 'http_client' => 'http_client', 'default_options' => [ From ef714869f0acfe2dd67ba746b7c1f1920f36a961 Mon Sep 17 00:00:00 2001 From: Steven Renaux Date: Sun, 13 Oct 2024 09:41:41 +0200 Subject: [PATCH 4/8] Fix accessibility --- src/Builder/DownloadFromTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Builder/DownloadFromTrait.php b/src/Builder/DownloadFromTrait.php index a7407bca..fe6d8c1d 100644 --- a/src/Builder/DownloadFromTrait.php +++ b/src/Builder/DownloadFromTrait.php @@ -20,7 +20,7 @@ abstract public function downloadFrom(array $downloadFrom): static; * @param array{downloadFrom?: array}>} $formFields * @param list}> $downloadFrom */ - public function withDownloadFrom(array &$formFields, array $downloadFrom): static + private function withDownloadFrom(array &$formFields, array $downloadFrom): static { if ([] === $downloadFrom) { unset($formFields['downloadFrom']); From 4885555d4d85ca56e20d33f58cf6552f7d491533 Mon Sep 17 00:00:00 2001 From: Steven Renaux Date: Mon, 14 Oct 2024 09:15:04 +0200 Subject: [PATCH 5/8] Fix doc --- docs/pdf/builders_api/HtmlPdfBuilder.md | 2 -- docs/pdf/builders_api/LibreOfficePdfBuilder.md | 2 -- docs/pdf/builders_api/MarkdownPdfBuilder.md | 2 -- docs/pdf/builders_api/UrlPdfBuilder.md | 2 -- docs/screenshot/builders_api/HtmlScreenshotBuilder.md | 2 -- docs/screenshot/builders_api/MarkdownScreenshotBuilder.md | 2 -- docs/screenshot/builders_api/UrlScreenshotBuilder.md | 2 -- 7 files changed, 14 deletions(-) diff --git a/docs/pdf/builders_api/HtmlPdfBuilder.md b/docs/pdf/builders_api/HtmlPdfBuilder.md index f1b399b2..28100c2e 100644 --- a/docs/pdf/builders_api/HtmlPdfBuilder.md +++ b/docs/pdf/builders_api/HtmlPdfBuilder.md @@ -133,8 +133,6 @@ The metadata to write. * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: -* `withDownloadFrom(array $formFields, array $downloadFrom)`: - * `addCookies(array $cookies)`: Add cookies to store in the Chromium cookie jar. diff --git a/docs/pdf/builders_api/LibreOfficePdfBuilder.md b/docs/pdf/builders_api/LibreOfficePdfBuilder.md index eeee4b63..18390398 100644 --- a/docs/pdf/builders_api/LibreOfficePdfBuilder.md +++ b/docs/pdf/builders_api/LibreOfficePdfBuilder.md @@ -91,5 +91,3 @@ If the form field reduceImageResolution is set to true, tell if all images will * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: -* `withDownloadFrom(array $formFields, array $downloadFrom)`: - diff --git a/docs/pdf/builders_api/MarkdownPdfBuilder.md b/docs/pdf/builders_api/MarkdownPdfBuilder.md index 9dd36ef1..8ac0c84f 100644 --- a/docs/pdf/builders_api/MarkdownPdfBuilder.md +++ b/docs/pdf/builders_api/MarkdownPdfBuilder.md @@ -136,8 +136,6 @@ The metadata to write. * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: -* `withDownloadFrom(array $formFields, array $downloadFrom)`: - * `addCookies(array $cookies)`: Add cookies to store in the Chromium cookie jar. diff --git a/docs/pdf/builders_api/UrlPdfBuilder.md b/docs/pdf/builders_api/UrlPdfBuilder.md index 555583c1..6aedc168 100644 --- a/docs/pdf/builders_api/UrlPdfBuilder.md +++ b/docs/pdf/builders_api/UrlPdfBuilder.md @@ -135,8 +135,6 @@ The metadata to write. * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: -* `withDownloadFrom(array $formFields, array $downloadFrom)`: - * `addCookies(array $cookies)`: Add cookies to store in the Chromium cookie jar. diff --git a/docs/screenshot/builders_api/HtmlScreenshotBuilder.md b/docs/screenshot/builders_api/HtmlScreenshotBuilder.md index 35c73f68..d70c992c 100644 --- a/docs/screenshot/builders_api/HtmlScreenshotBuilder.md +++ b/docs/screenshot/builders_api/HtmlScreenshotBuilder.md @@ -78,8 +78,6 @@ Adds a file, like an image, font, stylesheet, and so on. * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: -* `withDownloadFrom(array $formFields, array $downloadFrom)`: - * `addCookies(array $cookies)`: Add cookies to store in the Chromium cookie jar. diff --git a/docs/screenshot/builders_api/MarkdownScreenshotBuilder.md b/docs/screenshot/builders_api/MarkdownScreenshotBuilder.md index 1dec2ca6..3627b5a1 100644 --- a/docs/screenshot/builders_api/MarkdownScreenshotBuilder.md +++ b/docs/screenshot/builders_api/MarkdownScreenshotBuilder.md @@ -81,8 +81,6 @@ Adds a file, like an image, font, stylesheet, and so on. * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: -* `withDownloadFrom(array $formFields, array $downloadFrom)`: - * `addCookies(array $cookies)`: Add cookies to store in the Chromium cookie jar. diff --git a/docs/screenshot/builders_api/UrlScreenshotBuilder.md b/docs/screenshot/builders_api/UrlScreenshotBuilder.md index 5ac3c857..35e20de4 100644 --- a/docs/screenshot/builders_api/UrlScreenshotBuilder.md +++ b/docs/screenshot/builders_api/UrlScreenshotBuilder.md @@ -80,8 +80,6 @@ Adds a file, like an image, font, stylesheet, and so on. * `processor(Sensiolabs\GotenbergBundle\Processor\ProcessorInterface $processor)`: -* `withDownloadFrom(array $formFields, array $downloadFrom)`: - * `addCookies(array $cookies)`: Add cookies to store in the Chromium cookie jar. From 6ec6244d2e6f4df9148400a89849592bc389863a Mon Sep 17 00:00:00 2001 From: Steven Renaux Date: Mon, 14 Oct 2024 16:02:07 +0200 Subject: [PATCH 6/8] Fix phpstan --- src/Builder/DownloadFromTrait.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Builder/DownloadFromTrait.php b/src/Builder/DownloadFromTrait.php index fe6d8c1d..ee65c56a 100644 --- a/src/Builder/DownloadFromTrait.php +++ b/src/Builder/DownloadFromTrait.php @@ -3,6 +3,7 @@ namespace Sensiolabs\GotenbergBundle\Builder; use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException; +use Symfony\Component\Mime\Part\DataPart; trait DownloadFromTrait { @@ -44,7 +45,7 @@ private function withDownloadFrom(array &$formFields, array $downloadFrom): stat /** * @param array}> $value * - * @return list}> + * @return array|string|\Stringable|int|float|bool|\BackedEnum|DataPart> */ private function downloadFromNormalizer(array $value, callable $encoder): array { From bab72a46d068134c487dc6a05b50dea842b26d94 Mon Sep 17 00:00:00 2001 From: Steven Renaux Date: Thu, 17 Oct 2024 08:49:21 +0200 Subject: [PATCH 7/8] Fix doc --- docs/configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 69fd87fc..155c811c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -308,9 +308,9 @@ sensiolabs_gotenberg: Whenever a controller returns something other than a `Response` object, the [`kernel.view`](https://symfony.com/doc/current/reference/events.html#kernel-view) event is fired. That listener listen to this event and detects if it is a `GotenbergFileResult` object. If so it automatically calls the `->stream()` method to convert it to a Response object. -Enabled byd efault but can be disabled via the `sensiolabs_gotenberg.controller_listener` configuration. +Enabled by default but can be disabled via the `sensiolabs_gotenberg.controller_listener` configuration. -## download from +## Download from > [!WARNING] > URL of the file. It MUST return a `Content-Disposition` header with a filename parameter. From 2ce939abd394d20016cbd85dd5bf76530c2dd902 Mon Sep 17 00:00:00 2001 From: Steven Renaux Date: Fri, 18 Oct 2024 09:23:05 +0200 Subject: [PATCH 8/8] Fix reviews --- docs/configuration.md | 2 +- docs/pdf/customization.md | 4 ++-- docs/screenshot/customization.md | 4 ++-- src/Builder/DownloadFromTrait.php | 7 +------ 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 155c811c..e34802c1 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -323,7 +323,7 @@ sensiolabs_gotenberg: pdf: html: download_from: - - url: 'http://url/to/file.com' + - url: 'http://example.com/url/to/file'' extraHttpHeaders: - name: 'MyHeader' value: 'MyValue' diff --git a/docs/pdf/customization.md b/docs/pdf/customization.md index 94eb193a..479492d7 100644 --- a/docs/pdf/customization.md +++ b/docs/pdf/customization.md @@ -547,14 +547,14 @@ class YourController ->html() ->downloadFrom([ [ - 'url' => 'http://url/to/file.com', + 'url' => 'http://example.com/url/to/file', 'extraHttpHeaders' => [ 'MyHeader' => 'MyValue', ], ], [ - 'url' => 'http://url/to/file.com', + 'url' => 'http://example.com/url/to/file', 'extraHttpHeaders' => [ 'MyHeaderOne' => 'MyValue', diff --git a/docs/screenshot/customization.md b/docs/screenshot/customization.md index f4610162..7df7eef1 100644 --- a/docs/screenshot/customization.md +++ b/docs/screenshot/customization.md @@ -207,14 +207,14 @@ class YourController ->html() ->downloadFrom([ [ - 'url' => 'http://url/to/file.com', + 'url' => 'http://example.com/url/to/file', 'extraHttpHeaders' => [ 'MyHeader' => 'MyValue', ], ], [ - 'url' => 'http://url/to/file.com', + 'url' => 'http://example.com/url/to/file', 'extraHttpHeaders' => [ 'MyHeaderOne' => 'MyValue', diff --git a/src/Builder/DownloadFromTrait.php b/src/Builder/DownloadFromTrait.php index ee65c56a..e77909fc 100644 --- a/src/Builder/DownloadFromTrait.php +++ b/src/Builder/DownloadFromTrait.php @@ -49,11 +49,6 @@ private function withDownloadFrom(array &$formFields, array $downloadFrom): stat */ private function downloadFromNormalizer(array $value, callable $encoder): array { - $downloadsFrom = array_values($value); - $data = []; - - array_push($data, ...$downloadsFrom); - - return $encoder('downloadFrom', $data); + return $encoder('downloadFrom', array_values($value)); } }