From 90eef793c65089e83017c0e0e3d66fa12654eba9 Mon Sep 17 00:00:00 2001 From: thomas lemaire Date: Wed, 13 Apr 2022 15:16:13 +0200 Subject: [PATCH] 191: feature integration. --- modules/oe_webtools_html2media/README.md | 33 +++ .../oe_webtools_html2media.settings.yml | 1 + .../schema/oe_webtools_html2media.schema.yml | 8 + .../oe_webtools_html2media.info.yml | 6 + .../oe_webtools_html2media.module | 17 ++ .../oe_webtools_html2media.permissions.yml | 3 + .../oe_webtools_html2media.routing.yml | 7 + .../oe_webtools_html2media.services.yml | 6 + .../Controller/WebtoolsToMediaController.php | 83 ++++++++ .../src/Plugin/Block/PdfVersionBlock.php | 77 +++++++ .../src/WebtoolsHtmlToMedia.php | 191 ++++++++++++++++++ ...e-webtools-html2media-block-link.html.twig | 27 +++ .../tests/src/Functional/HtmlToMediaTest.php | 41 ++++ 13 files changed, 500 insertions(+) create mode 100644 modules/oe_webtools_html2media/README.md create mode 100644 modules/oe_webtools_html2media/config/install/oe_webtools_html2media.settings.yml create mode 100644 modules/oe_webtools_html2media/config/schema/oe_webtools_html2media.schema.yml create mode 100644 modules/oe_webtools_html2media/oe_webtools_html2media.info.yml create mode 100644 modules/oe_webtools_html2media/oe_webtools_html2media.module create mode 100644 modules/oe_webtools_html2media/oe_webtools_html2media.permissions.yml create mode 100644 modules/oe_webtools_html2media/oe_webtools_html2media.routing.yml create mode 100644 modules/oe_webtools_html2media/oe_webtools_html2media.services.yml create mode 100644 modules/oe_webtools_html2media/src/Controller/WebtoolsToMediaController.php create mode 100644 modules/oe_webtools_html2media/src/Plugin/Block/PdfVersionBlock.php create mode 100644 modules/oe_webtools_html2media/src/WebtoolsHtmlToMedia.php create mode 100644 modules/oe_webtools_html2media/templates/oe-webtools-html2media-block-link.html.twig create mode 100644 modules/oe_webtools_html2media/tests/src/Functional/HtmlToMediaTest.php diff --git a/modules/oe_webtools_html2media/README.md b/modules/oe_webtools_html2media/README.md new file mode 100644 index 00000000..f261697d --- /dev/null +++ b/modules/oe_webtools_html2media/README.md @@ -0,0 +1,33 @@ +## 1. Description + +This module allows pages to be converted in several formats (png, pdf, ...) +by providing a wrapper for Webtools HTML 2 Media service. +The Webtools service creates a static copy of the url, hosts the binary file on its server and returns its path. +see https://webgate.ec.europa.eu/fpfis/wikis/display/webtools/HTML+2+Media + +## 1. Usage + +Enable the permission 'Use webtools html2media version' + +### As site builder. + +Use the block "OpenEuropa Webtools PDF version" to get the pdf version of the current page. + +### As developer. + +#### Use a link + +provide a link to the url /oe-webtools-html2media with a least the page url to be converted. +compulsory parameter: + - url: the url of the page to convert +optional parameters: + - output_format: pdf by default + - format: A4 by default + - orientation: portrait by default + - load_delay: 200 in miliseconds + +see for reference https://webgate.ec.europa.eu/fpfis/wikis/display/webtools/HTML+2+Media+-+Technical+details + +#### Use a service to retrieve the binary url on webtools server. +use function getMedia(string $page_url, array $options = array()) same $options as for link. 1 extra parameter: + - $verify_url the url is tested and passed to the webservice only if it returns http code 200. default to TRUE. diff --git a/modules/oe_webtools_html2media/config/install/oe_webtools_html2media.settings.yml b/modules/oe_webtools_html2media/config/install/oe_webtools_html2media.settings.yml new file mode 100644 index 00000000..ee29150e --- /dev/null +++ b/modules/oe_webtools_html2media/config/install/oe_webtools_html2media.settings.yml @@ -0,0 +1 @@ +url: 'https://europa.eu/webtools/rest/html2m/convert.php' diff --git a/modules/oe_webtools_html2media/config/schema/oe_webtools_html2media.schema.yml b/modules/oe_webtools_html2media/config/schema/oe_webtools_html2media.schema.yml new file mode 100644 index 00000000..74e16a25 --- /dev/null +++ b/modules/oe_webtools_html2media/config/schema/oe_webtools_html2media.schema.yml @@ -0,0 +1,8 @@ +oe_webtools_html2media.settings: + type: config_object + label: 'Webtools HTML2Media settings' + mapping: + url: + type: label + label: 'Webtols html2media webservice url' + description: 'A URL that will be called on request.' diff --git a/modules/oe_webtools_html2media/oe_webtools_html2media.info.yml b/modules/oe_webtools_html2media/oe_webtools_html2media.info.yml new file mode 100644 index 00000000..dea04503 --- /dev/null +++ b/modules/oe_webtools_html2media/oe_webtools_html2media.info.yml @@ -0,0 +1,6 @@ +name: 'OpenEuropa Webtools HTML 2 Media' +type: module +description: 'Implements webtools HTML 2 Media services' +core_version_requirement: ^8.8 || ^9 +package: 'ATOF' +php: 7.1 diff --git a/modules/oe_webtools_html2media/oe_webtools_html2media.module b/modules/oe_webtools_html2media/oe_webtools_html2media.module new file mode 100644 index 00000000..d60bdbe7 --- /dev/null +++ b/modules/oe_webtools_html2media/oe_webtools_html2media.module @@ -0,0 +1,17 @@ + [ + 'variables' => ['url' => NULL, 'params' => NULL], + ], + ]; +} diff --git a/modules/oe_webtools_html2media/oe_webtools_html2media.permissions.yml b/modules/oe_webtools_html2media/oe_webtools_html2media.permissions.yml new file mode 100644 index 00000000..a3f90b93 --- /dev/null +++ b/modules/oe_webtools_html2media/oe_webtools_html2media.permissions.yml @@ -0,0 +1,3 @@ +use webtools html2media version: + title: 'Use webtools html2media version' + restrict access: false diff --git a/modules/oe_webtools_html2media/oe_webtools_html2media.routing.yml b/modules/oe_webtools_html2media/oe_webtools_html2media.routing.yml new file mode 100644 index 00000000..a5b8cb5f --- /dev/null +++ b/modules/oe_webtools_html2media/oe_webtools_html2media.routing.yml @@ -0,0 +1,7 @@ +oe_webtools_html2media.webtools: + path: '/oe-webtools-html2media' + defaults: + _controller: '\Drupal\oe_webtools_html2media\Controller\WebtoolsToMediaController::getPage' + _title: 'HTML 2 Media' + requirements: + _permission: 'use webtools html2media version' diff --git a/modules/oe_webtools_html2media/oe_webtools_html2media.services.yml b/modules/oe_webtools_html2media/oe_webtools_html2media.services.yml new file mode 100644 index 00000000..cd9d1c72 --- /dev/null +++ b/modules/oe_webtools_html2media/oe_webtools_html2media.services.yml @@ -0,0 +1,6 @@ +services: + oe_webtools_html2media.webtools: + class: Drupal\oe_webtools_html2media\WebtoolsHtmlToMedia + arguments: ['@config.factory', '@logger.factory', '@messenger', '@http_client'] + tags: + - {name: webtools} diff --git a/modules/oe_webtools_html2media/src/Controller/WebtoolsToMediaController.php b/modules/oe_webtools_html2media/src/Controller/WebtoolsToMediaController.php new file mode 100644 index 00000000..97ea28b6 --- /dev/null +++ b/modules/oe_webtools_html2media/src/Controller/WebtoolsToMediaController.php @@ -0,0 +1,83 @@ +webtools = $webtools; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('oe_webtools_html2media.webtools') + ); + } + + /** + * Callback for webtools version. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The request. + * + * @return string + * returns the binary, which will end up being a page. + */ + public function getPage(Request $request) { + // Get url parameters. + $params = $request->query->all(); + + // Set url to convert. + $url = $params['url'] ?? ''; + if (empty($url)) { + return [ + '#markup' => $this->t('Error: please provide the url of the page to convert'), + ]; + } + + $print_url = $this->webtools->getMedia($url, $params); + + if (!empty($print_url)) { + $response_headers = ['Cache-Control' => 'no-cache, no-store, must-revalidate']; + $response = new TrustedRedirectResponse($print_url, 302, $response_headers); + $response->addCacheableDependency($print_url); + return $response; + } + else { + // Allow user to try again in case of temporary failure. + $current_url = Url::fromRoute('', $params)->setAbsolute()->toString(); + return [ + '#markup' => $this->t('Error processing your request. Please Try again', [':url' => $current_url]), + ]; + + } + + } + +} diff --git a/modules/oe_webtools_html2media/src/Plugin/Block/PdfVersionBlock.php b/modules/oe_webtools_html2media/src/Plugin/Block/PdfVersionBlock.php new file mode 100644 index 00000000..682611db --- /dev/null +++ b/modules/oe_webtools_html2media/src/Plugin/Block/PdfVersionBlock.php @@ -0,0 +1,77 @@ +get('request_stack') + ); + } + + /** + * Plugin constructor. + * + * @param array $configuration + * Configuration. + * @param string $plugin_id + * Plugin id. + * @param mixed $plugin_definition + * Plugin definition. + * @param Symfony\Component\HttpFoundation\RequestStack $request + * Request params instance. + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, RequestStack $request) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->request = $request->getCurrentRequest(); + } + + /** + * {@inheritdoc} + */ + public function build() { + + // Get current page url. + $params = $this->request->query->all(); + $current_url = Url::fromRoute('', $params)->setAbsolute()->toString(); + + $controller_url = Url::fromRoute('oe_webtools_html2media.webtools', + [ + 'url' => $current_url, + ])->toString(); + + return [ + '#theme' => 'oe_webtools_html2media_block_link', + '#url' => $controller_url, + ]; + } + +} diff --git a/modules/oe_webtools_html2media/src/WebtoolsHtmlToMedia.php b/modules/oe_webtools_html2media/src/WebtoolsHtmlToMedia.php new file mode 100644 index 00000000..2dc39786 --- /dev/null +++ b/modules/oe_webtools_html2media/src/WebtoolsHtmlToMedia.php @@ -0,0 +1,191 @@ +logger = $logger->get('oe_webtools_html2media'); + $this->messenger = $messenger; + $this->configFactory = $configFactory; + $this->httpClient = $httpClient; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('http_client') + ); + } + + /** + * Log to watchdog and user interface. + * + * @param string $message + * The message to show. + */ + protected function logError(string $message) { + $this->logger->error($message); + $this->messenger->addError($message); + } + + /** + * Test http response code of a page. + * + * @param string $url + * The page to convert to pdf. + * + * @return int + * The http response code. + */ + public function testPageResponseCode(string $url) { + try { + $response = $this->httpClient->head($url); + return $response->getStatusCode(); + } + catch (RequestException $e) { + if ($e->hasResponse()) { + $response = $e->getResponse(); + // Log the error. + $this->logError($this->t("Invalid url to print @url (@status_code @reason)", + [ + '@url' => $url, + '@status_code' => $response->getStatusCode(), + '@reason' => $response->getReasonPhrase(), + ])); + } + return FALSE; + } + } + + /** + * Use webtools webservice to get a binary version of the page. + * + * @param string $page_url + * The page to convert to pdf. + * @param array $options + * The webservice option to convert to pdf. + * @param bool $verify_url + * Check if provided url returns 200. + */ + public function getMedia(string $page_url, array $options = [], bool $verify_url = TRUE) { + + // Test the url if it returns 200 before passing it to the webservice. + if ($verify_url !== FALSE) { + $response_code = $this->testPageResponseCode($page_url); + if ($response_code != 200) { + return FALSE; + } + } + + // Set options. + $orientation = $options['orientation'] ?? 'portrait'; + $load_delay = $options['load_delay'] ?? 200; + $output_format = $options['output_format'] ?? 'pdf'; + $format = $options['format'] ?? 'A4'; + + // Get webservice url. + $webservice_url = $this->configFactory->get('oe_webtools_html2media.settings')->get('url'); + + if (!UrlHelper::isValid($webservice_url)) { + $this->logError($this->t("Webtools webservice url is not valid")); + return FALSE; + } + + try { + $ws = $this->httpClient->post($webservice_url, [ + 'form_params' => [ + 'url' => $page_url, + 'output_format' => $output_format, + 'format' => $format, + 'load_delay' => $load_delay, + 'orientation' => $orientation, + ], + 'headers' => [ + 'Content-type' => 'application/x-www-form-urlencoded', + ], + ])->getBody()->getContents(); + + $ws = Json::decode($ws); + if ($ws['wtstatus']['success'] == 1) { + // kint($ws); + return $ws['output']; + } + else { + $this->logError($this->t("Webtools webservice error: @error", ['@error' => $ws['wtstatus']['error']])); + return FALSE; + } + } + + catch (RequestException $e) { + if ($e->hasResponse()) { + $response = $e->getResponse(); + // Log the error. + $this->logError($this->t("Error when trying to reach Webtools webservice: @status_code @reason.", + [ + '@status_code' => $response->getStatusCode(), + '@reason' => $response->getReasonPhrase(), + ])); + } + return FALSE; + } + } + +} diff --git a/modules/oe_webtools_html2media/templates/oe-webtools-html2media-block-link.html.twig b/modules/oe_webtools_html2media/templates/oe-webtools-html2media-block-link.html.twig new file mode 100644 index 00000000..478f1032 --- /dev/null +++ b/modules/oe_webtools_html2media/templates/oe-webtools-html2media-block-link.html.twig @@ -0,0 +1,27 @@ +{# +/** + * @file + * Default theme implementation for rendering webtools HTML 2 Media link to media version. + * + * Available variables: + * - url: The page to be converted in pdf. + * + * @ingroup themeable + */ +#} + {% include '@ecl-twig/link' with { + link: { + type: 'primary', + label: 'PDF version', + path: url, + icon_position: 'before' + }, + icon: { + name: 'download', + path: ecl_icon_path + }, + extra_attributes: [ + { name: 'target', value: '_blank' }, + ], + extra_classes: 'oe-webtools-html2media-pdf-link', + } %} diff --git a/modules/oe_webtools_html2media/tests/src/Functional/HtmlToMediaTest.php b/modules/oe_webtools_html2media/tests/src/Functional/HtmlToMediaTest.php new file mode 100644 index 00000000..1ae0b169 --- /dev/null +++ b/modules/oe_webtools_html2media/tests/src/Functional/HtmlToMediaTest.php @@ -0,0 +1,41 @@ +createUser([ + 'use webtools html2media version', + ]); + $this->drupalLogin($user); + $this->drupalGet('oe-webtools-html2media'); + $this->assertSession()->pageTextContains('Error: please provide the url of the page to convert'); + } + +}