From e39a8dc7a1632637eb1c6e1c17be139c16eca09b Mon Sep 17 00:00:00 2001 From: Steven Renaux Date: Mon, 11 Mar 2024 21:43:11 +0100 Subject: [PATCH] Update configurations --- config/services.php | 4 +- docs/configuration.rst | 94 +++-- src/DependencyInjection/Configuration.php | 343 ++++++++++-------- .../SensiolabsGotenbergExtension.php | 10 +- src/Pdf/Gotenberg.php | 14 +- .../DependencyInjection/ConfigurationTest.php | 177 +++++---- .../SensiolabsGotenbergExtensionTest.php | 176 +++++++-- tests/Pdf/GotenbergTest.php | 8 + 8 files changed, 534 insertions(+), 292 deletions(-) diff --git a/config/services.php b/config/services.php index 72212f1..65c5468 100644 --- a/config/services.php +++ b/config/services.php @@ -19,7 +19,9 @@ $services->set('sensiolabs_gotenberg', Gotenberg::class) ->args([ service('sensiolabs_gotenberg.client'), - abstract_arg('chromium configuration options'), + abstract_arg('html configuration options'), + abstract_arg('url configuration options'), + abstract_arg('markdown configuration options'), abstract_arg('office configuration options'), service('sensiolabs_gotenberg.asset.base_dir_formatter'), service('twig')->nullOnInvalid(), diff --git a/docs/configuration.rst b/docs/configuration.rst index 2664152..5929c63 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -11,31 +11,75 @@ The default configuration for the bundle looks like : base_uri: 'http://localhost:3000' base_directory: '%kernel.project_dir%' default_options: - pdf_format: null # None - pdf_universal_access: null # false - default_chromium_options: - paper_width: null # 8.5 - paper_height: null # 11 - margin_top: null # 0.39 - margin_bottom: null # 0.39 - margin_left: null # 0.39 - margin_right: null # 0.39 - prefer_css_page_size: null # false - print_background: null # false - omit_background: null # false - landscape: null # false - scale: null # 1.0 - native_page_ranges: null # All pages - wait_delay: null # None - wait_for_expression: null # None - emulated_media_type: null # 'print' - user_agent: null # None - extra_http_headers: null # None - fail_on_console_exceptions: null # false - default_office_options: - landscape: null # false - native_page_ranges: null # All pages - merge: null # false + html: + paper_width: null # 8.5 + paper_height: null # 11 + margin_top: null # 0.39 + margin_bottom: null # 0.39 + margin_left: null # 0.39 + margin_right: null # 0.39 + prefer_css_page_size: null # false + print_background: null # false + omit_background: null # false + landscape: null # false + scale: null # 1.0 + native_page_ranges: null # All pages + wait_delay: null # None + wait_for_expression: null # None + emulated_media_type: null # 'print' + user_agent: null # None + extra_http_headers: null # None + fail_on_console_exceptions: null # false + pdf_format: null # None + pdf_universal_access: null # false + url: + paper_width: null # 8.5 + paper_height: null # 11 + margin_top: null # 0.39 + margin_bottom: null # 0.39 + margin_left: null # 0.39 + margin_right: null # 0.39 + prefer_css_page_size: null # false + print_background: null # false + omit_background: null # false + landscape: null # false + scale: null # 1.0 + native_page_ranges: null # All pages + wait_delay: null # None + wait_for_expression: null # None + emulated_media_type: null # 'print' + user_agent: null # None + extra_http_headers: null # None + fail_on_console_exceptions: null # false + pdf_format: null # None + pdf_universal_access: null # false + markdown: + paper_width: null # 8.5 + paper_height: null # 11 + margin_top: null # 0.39 + margin_bottom: null # 0.39 + margin_left: null # 0.39 + margin_right: null # 0.39 + prefer_css_page_size: null # false + print_background: null # false + omit_background: null # false + landscape: null # false + scale: null # 1.0 + native_page_ranges: null # All pages + wait_delay: null # None + wait_for_expression: null # None + emulated_media_type: null # 'print' + user_agent: null # None + extra_http_headers: null # None + fail_on_console_exceptions: null # false + pdf_format: null # None + pdf_universal_access: null # false + office: + landscape: null # false + native_page_ranges: null # All pages + merge: null # false + pdf_format: null # None + pdf_universal_access: null # false .. caution:: diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index c6c08e6..7a5cb6a 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -4,6 +4,8 @@ use Sensiolabs\GotenbergBundle\Enum\EmulatedMediaType; use Sensiolabs\GotenbergBundle\Enum\PdfFormat; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; +use Symfony\Component\Config\Definition\Builder\NodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -33,168 +35,225 @@ public function getConfigTreeBuilder(): TreeBuilder ->cannotBeEmpty() ->end() ->arrayNode('default_options') - ->addDefaultsIfNotSet() + ->addDefaultsIfNotSet() ->children() - ->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::Pdf1a->value, PdfFormat::Pdf2b->value, PdfFormat::Pdf3b->value]) - ->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->addHtmlNode()) ->end() - ->end() - ->arrayNode('default_chromium_options') - ->addDefaultsIfNotSet() ->children() - ->floatNode('paper_width') - ->info('Paper width, in inches - default 8.5. https://gotenberg.dev/docs/routes#page-properties-chromium') - ->defaultNull() - ->end() - ->floatNode('paper_height') - ->info('Paper height, in inches - default 11. https://gotenberg.dev/docs/routes#page-properties-chromium') - ->defaultNull() - ->end() - ->floatNode('margin_top') - ->info('Top margin, in inches - default 0.39. https://gotenberg.dev/docs/routes#page-properties-chromium') - ->defaultNull() - ->end() - ->floatNode('margin_bottom') - ->info('Bottom margin, in inches - default 0.39. https://gotenberg.dev/docs/routes#page-properties-chromium') - ->defaultNull() - ->end() - ->floatNode('margin_left') - ->info('Left margin, in inches - default 0.39. https://gotenberg.dev/docs/routes#page-properties-chromium') - ->defaultNull() - ->end() - ->floatNode('margin_right') - ->info('Right margin, in inches - default 0.39. https://gotenberg.dev/docs/routes#page-properties-chromium') - ->defaultNull() - ->end() - ->booleanNode('prefer_css_page_size') - ->info('Define whether to prefer page size as defined by CSS - default false. https://gotenberg.dev/docs/routes#page-properties-chromium') - ->defaultNull() - ->end() - ->booleanNode('print_background') - ->info('Print the background graphics - default false. https://gotenberg.dev/docs/routes#page-properties-chromium') - ->defaultNull() - ->end() - ->booleanNode('omit_background') - ->info('Hide the default white background and allow generating PDFs with transparency - default false. https://gotenberg.dev/docs/routes#page-properties-chromium') - ->defaultNull() - ->end() - ->booleanNode('landscape') - ->info('The paper orientation to landscape - default false. https://gotenberg.dev/docs/routes#page-properties-chromium') - ->defaultNull() - ->end() - ->floatNode('scale') - ->info('The scale of the page rendering (e.g., 1.0) - default 1.0. https://gotenberg.dev/docs/routes#page-properties-chromium') - ->defaultNull() - ->end() - ->scalarNode('native_page_ranges') - ->info('Page ranges to print, e.g., "1-5, 8, 11-13" - default All pages. https://gotenberg.dev/docs/routes#page-properties-chromium') - ->defaultNull() - ->validate() - ->ifTrue(static function ($option): bool { - return preg_match('/([\d]+[-][\d]+)/', $option) !== 1; - }) - ->thenInvalid('Invalid range values, the range value format need to look like e.g 1-20.') - ->end() - ->end() - ->scalarNode('wait_delay') - ->info('Duration (e.g, "5s") to wait when loading an HTML document before converting it into PDF - default None. https://gotenberg.dev/docs/routes#wait-before-rendering') - ->defaultNull() - ->validate() - ->ifTrue(static function ($option): bool { - return !\is_string($option); - }) - ->thenInvalid('Invalid value %s') - ->end() - ->end() - ->scalarNode('wait_for_expression') - ->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() + ->append($this->addUrlNode()) + ->end() + ->children() + ->append($this->addMarkdownNode()) + ->end() + ->append($this->addOfficeNode()) + ->end() + ->end() + ; + + return $treeBuilder; + } + + private function addUrlNode(): NodeDefinition + { + $treebuilder = new TreeBuilder('url'); + + $treebuilder->getRootNode()->addDefaultsIfNotSet(); + $children = $treebuilder->getRootNode()->children(); + $this->addChromiumOptionsNode($children); + + return $children->end(); + } + + private function addHtmlNode(): NodeDefinition + { + $treebuilder = new TreeBuilder('html'); + + $treebuilder->getRootNode()->addDefaultsIfNotSet(); + $children = $treebuilder->getRootNode()->children(); + $this->addChromiumOptionsNode($children); + + return $children->end(); + } + + private function addMarkdownNode(): NodeDefinition + { + $treebuilder = new TreeBuilder('markdown'); + + $treebuilder->getRootNode()->addDefaultsIfNotSet(); + $children = $treebuilder->getRootNode()->children(); + $this->addChromiumOptionsNode($children); + + return $children->end(); + } + + private function addChromiumOptionsNode(NodeBuilder $treeBuilder): void + { + $treeBuilder + ->floatNode('paper_width') + ->info('Paper width, in inches - default 8.5. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->end() + ->floatNode('paper_height') + ->info('Paper height, in inches - default 11. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->end() + ->floatNode('margin_top') + ->info('Top margin, in inches - default 0.39. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->end() + ->floatNode('margin_bottom') + ->info('Bottom margin, in inches - default 0.39. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->end() + ->floatNode('margin_left') + ->info('Left margin, in inches - default 0.39. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->end() + ->floatNode('margin_right') + ->info('Right margin, in inches - default 0.39. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->end() + ->booleanNode('prefer_css_page_size') + ->info('Define whether to prefer page size as defined by CSS - default false. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->end() + ->booleanNode('print_background') + ->info('Print the background graphics - default false. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->end() + ->booleanNode('omit_background') + ->info('Hide the default white background and allow generating PDFs with transparency - default false. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->end() + ->booleanNode('landscape') + ->info('The paper orientation to landscape - default false. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->end() + ->floatNode('scale') + ->info('The scale of the page rendering (e.g., 1.0) - default 1.0. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->end() + ->scalarNode('native_page_ranges') + ->info('Page ranges to print, e.g., "1-5, 8, 11-13" - default All pages. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->validate() + ->ifTrue(static function ($option): bool { + return preg_match('/([\d]+[-][\d]+)/', $option) !== 1; + }) + ->thenInvalid('Invalid range values, the range value format need to look like e.g 1-20.') + ->end() + ->end() + ->scalarNode('wait_delay') + ->info('Duration (e.g, "5s") to wait when loading an HTML document before converting it into PDF - default None. https://gotenberg.dev/docs/routes#wait-before-rendering') + ->defaultNull() + ->validate() + ->ifTrue(static function ($option): bool { + return !\is_string($option); + }) + ->thenInvalid('Invalid value %s') + ->end() + ->end() + ->scalarNode('wait_for_expression') + ->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) { + return !\is_string($option); + }) + ->thenInvalid('Invalid value %s') + ->end() + ->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]) + ->defaultNull() + ->end() + ->scalarNode('user_agent') + ->info('Override the default User-Agent header - default None. https://gotenberg.dev/docs/routes#custom-http-headers') + ->defaultNull() + ->validate() + ->ifTrue(static function ($option) { + return !\is_string($option); + }) + ->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 value %s') + ->thenInvalid('Invalid header name %s') ->end() ->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]) - ->defaultNull() - ->end() - ->scalarNode('user_agent') - ->info('Override the default User-Agent header - default None. https://gotenberg.dev/docs/routes#custom-http-headers') - ->defaultNull() + ->scalarNode('value') ->validate() ->ifTrue(static function ($option) { return !\is_string($option); }) - ->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() + ->thenInvalid('Invalid header value %s') ->end() ->end() - ->booleanNode('fail_on_console_exceptions') - ->info('Return a 409 Conflict response if there are exceptions in the Chromium console - default false. https://gotenberg.dev/docs/routes#console-exceptions') - ->defaultNull() - ->end() ->end() ->end() - ->arrayNode('default_office_options') - ->addDefaultsIfNotSet() - ->children() - ->booleanNode('landscape') - ->info('The paper orientation to landscape - default false. https://gotenberg.dev/docs/routes#page-properties-chromium') - ->defaultNull() - ->end() - ->scalarNode('native_page_ranges') - ->info('Page ranges to print, e.g., "1-5, 8, 11-13" - default All pages. https://gotenberg.dev/docs/routes#page-properties-chromium') - ->defaultNull() - ->validate() - ->ifTrue(static function ($option): bool { - return preg_match('/([\d]+[-][\d]+)/', $option) !== 1; - }) - ->thenInvalid('Invalid range values, the range value format need to look like e.g 1-20.') - ->end() - ->end() - ->booleanNode('merge') - ->info('Merge alphanumerically the resulting PDFs. - default false. https://gotenberg.dev/docs/routes#merge-libreoffice') - ->defaultNull() - ->end() + ->end() + ->booleanNode('fail_on_console_exceptions') + ->info('Return a 409 Conflict response if there are exceptions in the Chromium console - default false. https://gotenberg.dev/docs/routes#console-exceptions') + ->defaultNull() + ->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::Pdf1a->value, PdfFormat::Pdf2b->value, PdfFormat::Pdf3b->value]) + ->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() + ; + } + + private function addOfficeNode(): NodeDefinition + { + $treeBuilder = new TreeBuilder('office'); + + return $treeBuilder->getRootNode() + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('landscape') + ->info('The paper orientation to landscape - default false. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->end() + ->scalarNode('native_page_ranges') + ->info('Page ranges to print, e.g., "1-5, 8, 11-13" - default All pages. https://gotenberg.dev/docs/routes#page-properties-chromium') + ->defaultNull() + ->validate() + ->ifTrue(static function ($option): bool { + return preg_match('/([\d]+[-][\d]+)/', $option) !== 1; + }) + ->thenInvalid('Invalid range values, the range value format need to look like e.g 1-20.') ->end() ->end() + ->booleanNode('merge') + ->info('Merge alphanumerically the resulting PDFs. - default false. https://gotenberg.dev/docs/routes#merge-libreoffice') + ->defaultNull() + ->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::Pdf1a->value, PdfFormat::Pdf2b->value, PdfFormat::Pdf3b->value]) + ->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() ->end() ; - - return $treeBuilder; } } diff --git a/src/DependencyInjection/SensiolabsGotenbergExtension.php b/src/DependencyInjection/SensiolabsGotenbergExtension.php index 864568d..aabf4be 100644 --- a/src/DependencyInjection/SensiolabsGotenbergExtension.php +++ b/src/DependencyInjection/SensiolabsGotenbergExtension.php @@ -16,18 +16,20 @@ public function load(array $configs, ContainerBuilder $container): void $configuration = new Configuration(); - /** @var array{base_uri: string, base_directory: string, default_options: array, default_chromium_options: array, default_office_options: array} $config */ + /** @var array{base_uri: string, base_directory: string, default_options: array{html: array, url: array, markdown: array, office: array}} $config */ $config = $this->processConfiguration($configuration, $configs); $definition = $container->getDefinition('sensiolabs_gotenberg.client'); $definition->replaceArgument(0, $config['base_uri']); $definition = $container->getDefinition('sensiolabs_gotenberg'); - $definition->replaceArgument(1, $this->cleanUserOptions(array_merge($config['default_options'], $config['default_chromium_options']))); - $definition->replaceArgument(2, $this->cleanUserOptions(array_merge($config['default_options'], $config['default_office_options']))); + $definition->replaceArgument(1, $this->cleanUserOptions($config['default_options']['html'])); + $definition->replaceArgument(2, $this->cleanUserOptions($config['default_options']['url'])); + $definition->replaceArgument(3, $this->cleanUserOptions($config['default_options']['markdown'])); + $definition->replaceArgument(4, $this->cleanUserOptions($config['default_options']['office'])); $definition = $container->getDefinition('sensiolabs_gotenberg.asset.base_dir_formatter'); - $definition->replaceArgument(0, $config['base_directory']); + $definition->replaceArgument(2, $config['base_directory']); } /** diff --git a/src/Pdf/Gotenberg.php b/src/Pdf/Gotenberg.php index 0b0fe6c..f5b969e 100644 --- a/src/Pdf/Gotenberg.php +++ b/src/Pdf/Gotenberg.php @@ -13,12 +13,16 @@ final readonly class Gotenberg implements GotenbergInterface { /** - * @param array $chromiumConfiguration + * @param array $htmlConfiguration + * @param array $urlConfiguration + * @param array $markdownConfiguration * @param array $officeConfiguration */ public function __construct( private GotenbergClientInterface $gotenbergClient, - private array $chromiumConfiguration, + private array $htmlConfiguration, + private array $urlConfiguration, + private array $markdownConfiguration, private array $officeConfiguration, private AssetBaseDirFormatter $asset, private ?Environment $twig = null, @@ -28,21 +32,21 @@ public function __construct( public function html(): HtmlPdfBuilder { return (new HtmlPdfBuilder($this->gotenbergClient, $this->asset, $this->twig)) - ->setConfigurations($this->chromiumConfiguration) + ->setConfigurations($this->htmlConfiguration) ; } public function url(): UrlPdfBuilder { return (new UrlPdfBuilder($this->gotenbergClient, $this->asset, $this->twig)) - ->setConfigurations($this->chromiumConfiguration) + ->setConfigurations($this->urlConfiguration) ; } public function markdown(): MarkdownPdfBuilder { return (new MarkdownPdfBuilder($this->gotenbergClient, $this->asset, $this->twig)) - ->setConfigurations($this->chromiumConfiguration) + ->setConfigurations($this->markdownConfiguration) ; } diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php index d99b335..57fd18d 100644 --- a/tests/DependencyInjection/ConfigurationTest.php +++ b/tests/DependencyInjection/ConfigurationTest.php @@ -27,26 +27,19 @@ public static function provideInvalidRange(): array /** * @return iterable>> */ - public static function provideValidCrossOptionsConfiguration(): iterable + public static function provideValidHtmlConfiguration(): iterable { - yield 'pdf format configuration' => [['default_options' => ['pdf_format' => 'PDF/A-3b']]]; - yield 'pdf universal configuration' => [['default_options' => ['pdf_universal_access' => true]]]; - yield 'both pdf configuration' => [['default_options' => ['pdf_format' => 'PDF/A-3b', 'pdf_universal_access' => true]]]; - } - - /** - * @return iterable>> - */ - public static function provideValidChromiumOptionsConfiguration(): iterable - { - yield 'paper size config' => [['default_chromium_options' => ['paper_width' => 33.1, 'paper_height' => 46.8, 'margin_top' => 1, 'margin_bottom' => 1, 'margin_left' => 1, 'margin_right' => 1]]]; - yield 'styles config' => [['default_chromium_options' => ['prefer_css_page_size' => true, 'print_background' => true, 'omit_background' => true, 'landscape' => true]]]; - yield 'different scale' => [['default_chromium_options' => ['scale' => 2.0]]]; - yield 'range a page to generate' => [['default_chromium_options' => ['native_page_ranges' => '1-12']]]; - yield 'delay to wait before generate' => [['default_chromium_options' => ['wait_delay' => '5s', 'wait_for_expression' => 'window.globalVar === "ready"']]]; - yield 'emulated media type' => [['default_chromium_options' => ['emulated_media_type' => 'screen']]]; - yield 'different user agent' => [['default_chromium_options' => ['user_agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML => like Gecko) Version/11.0 Mobile/15A372 Safari/604.1']]]; - yield 'exception render' => [['default_chromium_options' => ['fail_on_console_exceptions' => true]]]; + yield 'paper size config' => [['default_options' => ['html' => ['paper_width' => 33.1, 'paper_height' => 46.8, 'margin_top' => 1, 'margin_bottom' => 1, 'margin_left' => 1, 'margin_right' => 1]]]]; + yield 'styles config' => [['default_options' => ['html' => ['prefer_css_page_size' => true, 'print_background' => true, 'omit_background' => true, 'landscape' => true]]]]; + yield 'different scale' => [['default_options' => ['html' => ['scale' => 2.0]]]]; + yield 'range a page to generate' => [['default_options' => ['html' => ['native_page_ranges' => '1-12']]]]; + yield 'delay to wait before generate' => [['default_options' => ['html' => ['wait_delay' => '5s', 'wait_for_expression' => 'window.globalVar === "ready"']]]]; + yield 'emulated media type' => [['default_options' => ['html' => ['emulated_media_type' => 'screen']]]]; + yield 'different user agent' => [['default_options' => ['html' => ['user_agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML => like Gecko) Version/11.0 Mobile/15A372 Safari/604.1']]]]; + yield 'exception render' => [['default_options' => ['html' => ['fail_on_console_exceptions' => true]]]]; + yield 'pdf format configuration' => [['default_options' => ['html' => ['pdf_format' => 'PDF/A-3b']]]]; + yield 'pdf universal configuration' => [['default_options' => ['html' => ['pdf_universal_access' => true]]]]; + yield 'both pdf configuration' => [['default_options' => ['html' => ['pdf_format' => 'PDF/A-3b', 'pdf_universal_access' => true]]]]; } public function testDefaultConfig(): void @@ -77,15 +70,15 @@ public function testInvalidRange(mixed $range): void $processor = new Processor(); $processor->processConfiguration( new Configuration(), - [['default_chromium_options' => ['native_page_ranges' => $range]]], + [['html' => ['native_page_ranges' => $range]]], ); } /** * @param array> $optionConfig */ - #[DataProvider('provideValidCrossOptionsConfiguration')] - public function testValidCrossOptionsConfiguration(array $optionConfig): void + #[DataProvider('provideValidHtmlConfiguration')] + public function testValidHtmlConfiguration(array $optionConfig): void { $processor = new Processor(); /** @var array{'base_uri': string,'default_options': array} $config */ @@ -96,50 +89,36 @@ public function testValidCrossOptionsConfiguration(array $optionConfig): void ], ]); - $config = $this->cleanOptions($config['default_options']); - self::assertEquals($optionConfig['default_options'], $config); - } - - /** - * @param array> $optionConfig - */ - #[DataProvider('provideValidChromiumOptionsConfiguration')] - public function testValidChromiumOptionsConfiguration(array $optionConfig): void - { - $processor = new Processor(); - /** @var array{'base_uri': string,'default_chromium_options': array} $config */ - $config = $processor->processConfiguration(new Configuration(), [ - [ - 'base_uri' => 'http://gotenberg:3000', - ...$optionConfig, - ], - ]); - - $config = $this->cleanOptions($config['default_chromium_options']); - self::assertEquals($optionConfig['default_chromium_options'], $config); + $config = $this->cleanOptions($config['default_options']['html']); + self::assertEquals($optionConfig['default_options']['html'], $config); } public function testWithExtraHeadersConfiguration(): void { $processor = new Processor(); - /** @var array{'base_uri': string,'default_chromium_options': array} $config */ + /** @var array{'base_uri': string,'default_options': array} $config */ $config = $processor->processConfiguration(new Configuration(), [ [ 'base_uri' => 'http://gotenberg:3000', - 'default_chromium_options' => ['extra_http_headers' => [['name' => 'MyHeader', 'value' => 'MyValue'], ['name' => 'User-Agent', 'value' => 'MyValue']]], + 'default_options' => [ + 'html' => ['extra_http_headers' => [['name' => 'MyHeader', 'value' => 'MyValue'], ['name' => 'User-Agent', 'value' => 'MyValue']]], + ], ], ]); - $config = $this->cleanOptions($config['default_chromium_options']); + $config = $this->cleanOptions($config['default_options']['html']); self::assertEquals(['extra_http_headers' => ['MyHeader' => 'MyValue', 'User-Agent' => 'MyValue']], $config); } /** * @return array{ * 'base_uri': string, - * 'default_options': array, - * 'default_chromium_options': array, - * 'default_office_options': array + * 'default_options': array{ + * 'html': array, + * 'url': array, + * 'markdown': array, + * 'office': array, + * } * } */ private static function getBundleDefaultConfig(): array @@ -148,33 +127,79 @@ private static function getBundleDefaultConfig(): array 'base_uri' => 'http://localhost:3000', 'base_directory' => '%kernel.project_dir%', 'default_options' => [ - 'pdf_format' => null, - 'pdf_universal_access' => null, - ], - 'default_chromium_options' => [ - 'paper_width' => null, - 'paper_height' => null, - 'margin_top' => null, - 'margin_bottom' => null, - 'margin_left' => null, - 'margin_right' => null, - 'prefer_css_page_size' => null, - 'print_background' => null, - 'omit_background' => null, - 'landscape' => null, - 'scale' => null, - 'native_page_ranges' => null, - 'wait_delay' => null, - 'wait_for_expression' => null, - 'emulated_media_type' => null, - 'user_agent' => null, - 'extra_http_headers' => [], - 'fail_on_console_exceptions' => null, - ], - 'default_office_options' => [ - 'landscape' => null, - 'native_page_ranges' => null, - 'merge' => null, + 'html' => [ + 'paper_width' => null, + 'paper_height' => null, + 'margin_top' => null, + 'margin_bottom' => null, + 'margin_left' => null, + 'margin_right' => null, + 'prefer_css_page_size' => null, + 'print_background' => null, + 'omit_background' => null, + 'landscape' => null, + 'scale' => null, + 'native_page_ranges' => null, + 'wait_delay' => null, + 'wait_for_expression' => null, + 'emulated_media_type' => null, + 'user_agent' => null, + 'extra_http_headers' => [], + 'fail_on_console_exceptions' => null, + 'pdf_format' => null, + 'pdf_universal_access' => null, + ], + 'url' => [ + 'paper_width' => null, + 'paper_height' => null, + 'margin_top' => null, + 'margin_bottom' => null, + 'margin_left' => null, + 'margin_right' => null, + 'prefer_css_page_size' => null, + 'print_background' => null, + 'omit_background' => null, + 'landscape' => null, + 'scale' => null, + 'native_page_ranges' => null, + 'wait_delay' => null, + 'wait_for_expression' => null, + 'emulated_media_type' => null, + 'user_agent' => null, + 'extra_http_headers' => [], + 'fail_on_console_exceptions' => null, + 'pdf_format' => null, + 'pdf_universal_access' => null, + ], + 'markdown' => [ + 'paper_width' => null, + 'paper_height' => null, + 'margin_top' => null, + 'margin_bottom' => null, + 'margin_left' => null, + 'margin_right' => null, + 'prefer_css_page_size' => null, + 'print_background' => null, + 'omit_background' => null, + 'landscape' => null, + 'scale' => null, + 'native_page_ranges' => null, + 'wait_delay' => null, + 'wait_for_expression' => null, + 'emulated_media_type' => null, + 'user_agent' => null, + 'extra_http_headers' => [], + 'fail_on_console_exceptions' => null, + 'pdf_format' => null, + 'pdf_universal_access' => null, + ], + 'office' => [ + 'landscape' => null, + 'native_page_ranges' => null, + 'merge' => null, + 'pdf_format' => null, + 'pdf_universal_access' => null, + ], ], ]; } diff --git a/tests/DependencyInjection/SensiolabsGotenbergExtensionTest.php b/tests/DependencyInjection/SensiolabsGotenbergExtensionTest.php index 14b081d..1bdde27 100644 --- a/tests/DependencyInjection/SensiolabsGotenbergExtensionTest.php +++ b/tests/DependencyInjection/SensiolabsGotenbergExtensionTest.php @@ -6,6 +6,7 @@ use PHPUnit\Framework\Attributes\UsesClass; use PHPUnit\Framework\TestCase; use Sensiolabs\GotenbergBundle\DependencyInjection\SensiolabsGotenbergExtension; +use Sensiolabs\GotenbergBundle\Enum\PdfFormat; use Symfony\Component\DependencyInjection\ContainerBuilder; #[CoversClass(SensiolabsGotenbergExtension::class)] @@ -24,8 +25,6 @@ public function testGotenbergConfiguredWithValidConfig(): void self::assertSame( [ - 'pdf_format' => 'PDF/A-1a', - 'pdf_universal_access' => true, 'paper_width' => 33.1, 'paper_height' => 46.8, 'margin_top' => 1, @@ -44,19 +43,71 @@ public function testGotenbergConfiguredWithValidConfig(): void 'user_agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML => like Gecko) Version/11.0 Mobile/15A372 Safari/604.1', 'extra_http_headers' => ['MyHeader' => 'MyValue', 'User-Agent' => 'MyValue'], 'fail_on_console_exceptions' => true, + 'pdf_format' => PdfFormat::Pdf1a->value, + 'pdf_universal_access' => true, ], $arguments[1], ); self::assertSame( [ - 'pdf_format' => 'PDF/A-1a', - 'pdf_universal_access' => true, + 'paper_width' => 21, + 'paper_height' => 50, + 'margin_top' => 0.5, + 'margin_bottom' => 0.5, + 'margin_left' => 0.5, + 'margin_right' => 0.5, + 'prefer_css_page_size' => false, + 'print_background' => false, + 'omit_background' => false, 'landscape' => false, + 'scale' => 1.5, 'native_page_ranges' => '1-10', - 'merge' => true, + 'wait_delay' => '5s', + 'wait_for_expression' => 'window.globalVar === "ready"', + 'emulated_media_type' => 'screen', + 'user_agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML => like Gecko) Version/11.0 Mobile/15A372 Safari/604.1', + 'extra_http_headers' => ['MyHeader' => 'MyValue', 'User-Agent' => 'MyValue'], + 'fail_on_console_exceptions' => false, + 'pdf_format' => PdfFormat::Pdf2b->value, + 'pdf_universal_access' => false, ], $arguments[2], ); + self::assertSame( + [ + 'paper_width' => 30, + 'paper_height' => 45, + 'margin_top' => 1, + 'margin_bottom' => 1, + 'margin_left' => 1, + 'margin_right' => 1, + 'prefer_css_page_size' => true, + 'print_background' => false, + 'omit_background' => false, + 'landscape' => true, + 'scale' => 1.5, + 'native_page_ranges' => '1-5', + 'wait_delay' => '10s', + 'wait_for_expression' => 'window.globalVar === "ready"', + 'emulated_media_type' => 'screen', + 'user_agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML => like Gecko) Version/11.0 Mobile/15A372 Safari/604.1', + 'extra_http_headers' => ['MyHeader' => 'MyValue', 'User-Agent' => 'MyValue'], + 'fail_on_console_exceptions' => false, + 'pdf_format' => PdfFormat::Pdf3b->value, + 'pdf_universal_access' => true, + ], + $arguments[3], + ); + self::assertSame( + [ + 'landscape' => false, + 'native_page_ranges' => '1-2', + 'merge' => true, + 'pdf_format' => PdfFormat::Pdf1a->value, + 'pdf_universal_access' => true, + ], + $arguments[4], + ); } public function testGotenbergConfiguredWithNoConfig(): void @@ -101,14 +152,15 @@ public function testGotenbergClientConfiguredWithValidConfig(): void } /** - * @return list< - * array{ + * @return array, - * 'default_chromium_options': array, - * 'default_office_options': array, - * } - * > + * 'default_options': array{ + * 'html': array, + * 'url': array, + * 'markdown': array, + * 'office': array, + * } + * }> */ private static function getValidConfig(): array { @@ -116,33 +168,79 @@ private static function getValidConfig(): array [ 'base_uri' => 'http://localhost:3000', 'default_options' => [ - 'pdf_format' => 'PDF/A-1a', - 'pdf_universal_access' => true, - ], - 'default_chromium_options' => [ - 'paper_width' => 33.1, - 'paper_height' => 46.8, - 'margin_top' => 1, - 'margin_bottom' => 1, - 'margin_left' => 1, - 'margin_right' => 1, - 'prefer_css_page_size' => true, - 'print_background' => true, - 'omit_background' => true, - 'landscape' => true, - 'scale' => 1.5, - 'native_page_ranges' => '1-5', - 'wait_delay' => '10s', - 'wait_for_expression' => 'window.globalVar === "ready"', - 'emulated_media_type' => 'screen', - 'user_agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML => like Gecko) Version/11.0 Mobile/15A372 Safari/604.1', - 'extra_http_headers' => [['name' => 'MyHeader', 'value' => 'MyValue'], ['name' => 'User-Agent', 'value' => 'MyValue']], - 'fail_on_console_exceptions' => true, - ], - 'default_office_options' => [ - 'landscape' => false, - 'native_page_ranges' => '1-10', - 'merge' => true, + 'html' => [ + 'paper_width' => 33.1, + 'paper_height' => 46.8, + 'margin_top' => 1, + 'margin_bottom' => 1, + 'margin_left' => 1, + 'margin_right' => 1, + 'prefer_css_page_size' => true, + 'print_background' => true, + 'omit_background' => true, + 'landscape' => true, + 'scale' => 1.5, + 'native_page_ranges' => '1-5', + 'wait_delay' => '10s', + 'wait_for_expression' => 'window.globalVar === "ready"', + 'emulated_media_type' => 'screen', + 'user_agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML => like Gecko) Version/11.0 Mobile/15A372 Safari/604.1', + 'extra_http_headers' => [['name' => 'MyHeader', 'value' => 'MyValue'], ['name' => 'User-Agent', 'value' => 'MyValue']], + 'fail_on_console_exceptions' => true, + 'pdf_format' => PdfFormat::Pdf1a->value, + 'pdf_universal_access' => true, + ], + 'url' => [ + 'paper_width' => 21, + 'paper_height' => 50, + 'margin_top' => 0.5, + 'margin_bottom' => 0.5, + 'margin_left' => 0.5, + 'margin_right' => 0.5, + 'prefer_css_page_size' => false, + 'print_background' => false, + 'omit_background' => false, + 'landscape' => false, + 'scale' => 1.5, + 'native_page_ranges' => '1-10', + 'wait_delay' => '5s', + 'wait_for_expression' => 'window.globalVar === "ready"', + 'emulated_media_type' => 'screen', + 'user_agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML => like Gecko) Version/11.0 Mobile/15A372 Safari/604.1', + 'extra_http_headers' => [['name' => 'MyHeader', 'value' => 'MyValue'], ['name' => 'User-Agent', 'value' => 'MyValue']], + 'fail_on_console_exceptions' => false, + 'pdf_format' => PdfFormat::Pdf2b->value, + 'pdf_universal_access' => false, + ], + 'markdown' => [ + 'paper_width' => 30, + 'paper_height' => 45, + 'margin_top' => 1, + 'margin_bottom' => 1, + 'margin_left' => 1, + 'margin_right' => 1, + 'prefer_css_page_size' => true, + 'print_background' => false, + 'omit_background' => false, + 'landscape' => true, + 'scale' => 1.5, + 'native_page_ranges' => '1-5', + 'wait_delay' => '10s', + 'wait_for_expression' => 'window.globalVar === "ready"', + 'emulated_media_type' => 'screen', + 'user_agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML => like Gecko) Version/11.0 Mobile/15A372 Safari/604.1', + 'extra_http_headers' => [['name' => 'MyHeader', 'value' => 'MyValue'], ['name' => 'User-Agent', 'value' => 'MyValue']], + 'fail_on_console_exceptions' => false, + 'pdf_format' => PdfFormat::Pdf3b->value, + 'pdf_universal_access' => true, + ], + 'office' => [ + 'landscape' => false, + 'native_page_ranges' => '1-2', + 'merge' => true, + 'pdf_format' => PdfFormat::Pdf1a->value, + 'pdf_universal_access' => true, + ], ], ], ]; diff --git a/tests/Pdf/GotenbergTest.php b/tests/Pdf/GotenbergTest.php index 74196d2..84b8dc7 100644 --- a/tests/Pdf/GotenbergTest.php +++ b/tests/Pdf/GotenbergTest.php @@ -24,8 +24,10 @@ public function testUrlBuilderFactory(): void $gotenberg = new Gotenberg( $gotenbergClient, + [], ['native_page_ranges' => '1-5'], [], + [], $assetBaseDirFormatter, ); $builder = $gotenberg->url(); @@ -44,6 +46,8 @@ public function testHtmlBuilderFactory(): void $gotenbergClient, ['margin_top' => 3, 'margin_bottom' => 1], [], + [], + [], $assetBaseDirFormatter, $twig, ); @@ -77,6 +81,8 @@ public function testMarkdownBuilderFactory(): void $gotenbergClient, [], [], + [], + [], $assetBaseDirFormatter, $twig, ); @@ -109,6 +115,8 @@ public function testOfficeBuilderFactory(): void $gotenberg = new Gotenberg( $gotenbergClient, [], + [], + [], ['native_page_ranges' => '1-5'], $assetBaseDirFormatter, $twig,