From 230df7c94d55c6c1e3e3319df6f4207501f008f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Dufraisse?= Date: Thu, 1 Dec 2022 11:37:09 +0100 Subject: [PATCH] feat(PdfIframeHandler): create it --- actions/Bazar2PublicationAction.php | 2 +- config.yaml | 3 + controllers/PdfController.php | 66 +++++++++++++++++++ docs/en/README.md | 6 ++ docs/fr/README.md | 6 ++ handlers/PdfHandler.php | 41 +----------- handlers/PdfIframeHandler.php | 55 ++++++++++++++++ javascripts/handler-pdf.js | 4 +- lang/publication_en.inc.php | 1 + lang/publication_fr.inc.php | 1 + lang/publication_pt.inc.php | 1 + services/PdfHelper.php | 6 +- .../bazar/entries/_publication_button.twig | 3 +- templates/handler-pdf.twig | 1 + 14 files changed, 151 insertions(+), 45 deletions(-) create mode 100644 controllers/PdfController.php create mode 100644 handlers/PdfIframeHandler.php diff --git a/actions/Bazar2PublicationAction.php b/actions/Bazar2PublicationAction.php index 8cb49c6..79b83e8 100644 --- a/actions/Bazar2PublicationAction.php +++ b/actions/Bazar2PublicationAction.php @@ -28,7 +28,7 @@ public function run() if (array_key_exists('wiki', $queries)) { unset($queries['wiki']); } - $href = $this->wiki->Href('pdf', null, $queries// merge GET with wiki and following params + $href = $this->wiki->Href('pdf'.testUrlInIframe(), null, $queries// merge GET with wiki and following params +[ 'via' => 'bazarliste', 'template-page' => $this->arguments['templatepage'], diff --git a/config.yaml b/config.yaml index 65b709a..0360617 100644 --- a/config.yaml +++ b/config.yaml @@ -52,3 +52,6 @@ services: YesWiki\Publication\Service\: resource: 'services/*' + + YesWiki\Publication\Controller\: + resource: 'controllers/*' diff --git a/controllers/PdfController.php b/controllers/PdfController.php new file mode 100644 index 0000000..593de9a --- /dev/null +++ b/controllers/PdfController.php @@ -0,0 +1,66 @@ +params = $params; + $this->pdfHelper = $pdfHelper; + $this->wiki = $wiki; + } + + public function run(bool $inIframe = false) + { + if (!empty($_GET['url']) && is_string($_GET['url']) && + !empty($_GET['urlPageTag']) && is_string($_GET['urlPageTag']) && + !empty($_GET['hash']) && is_string($_GET['hash'])) { + // redirect to api + if (!method_exists($this->wiki, 'isCli') || !$this->wiki->isCli()) { + header('Access-Control-Allow-Origin: *'); + header('Access-Control-Expose-Headers: Location, Slug, Accept, Content-Type'); + } + $filteredParams = array_filter($_GET, function ($v, $k) { + return in_array($k, ['url','urlPageTag','hash','refresh','forceNewFormat','via','template-page'], true) && is_scalar($v); + }, ARRAY_FILTER8USE_BOTH); + $this->wiki->redirect($this->wiki->href('', 'api/pdf/getPdf', $filteredParams + [ + 'fromOldPath' => '1' + ], false)); + } + + list( + 'pageTag'=>$pageTag, + 'sourceUrl'=>$sourceUrl, + 'hash'=>$hash, + ) = + $this->pdfHelper->getSourceUrl($_GET ?? [], $_SERVER ?? []); + + $method = $inIframe ? 'render' : 'renderInSquelette'; + + return $this->$method('@publication/handler-pdf.twig', [ + 'isAdmin' => $this->wiki->UserIsAdmin(), + 'isIframe' => $inIframe, + 'pageTag' => $pageTag, + 'sourceUrl' => $sourceUrl, + 'hash' => $hash, + 'urls' => [ + 'local' => $this->pdfHelper->canExecChromium() ? $this->wiki->href('', 'api/pdf/getPdf') : '', + 'external' => empty($this->params->get('htmltopdf_service_url')) ? '' : $this->params->get('htmltopdf_service_url'), + ], + 'refresh' => in_array($_GET['refresh'] ?? false, [1,"1",true,"true"], true), + ]); + } +} diff --git a/docs/en/README.md b/docs/en/README.md index ac6c44e..7f0d956 100644 --- a/docs/en/README.md +++ b/docs/en/README.md @@ -66,6 +66,12 @@ For this: 2. contact administrator of the concerned website to ask to add the current ueswiki's domain to the list of authorized domains. - the concerned adminsitrator will have to modify the parameter `htmltopdf_service_authorized_domains` into page [GererConfig](?GererConfig 'Page config :ignore'), part `publication` (examples of possibles values : `['example.com']` or `['example.com','wiki.example.com','example.net']`) +### What do if print page does not display in `iframe` ? + +If print page does not display in `iframe`, it is possible that server constraints of security prevent its display. + +To authorize it, go as admin in page page [GererConfig](?GererConfig 'Page config :ignore') in part `Main parameters` and add `'pdf','pdfiframe'` to possible values in parameter `allowed_methods_in_iframe`. + ## More precise usage See french help at this [address](/tools/publication/docs/fr/?id=utilisation-d%c3%a9taill%c3%a9e) diff --git a/docs/fr/README.md b/docs/fr/README.md index db4d780..44e30e3 100644 --- a/docs/fr/README.md +++ b/docs/fr/README.md @@ -166,6 +166,12 @@ Pour ceci: 2. contacter l'administrateurice du site concerné pour lui demander d'ajouter votre nom de domaine aux domaines autorisés. - l'administrateurice concernée devra alors modifier le paramètre `htmltopdf_service_authorized_domains` dans la page [GererConfig](?GererConfig 'Page config :ignore') dans la partie `publication` (quelques exemples de valeurs possibles : `['example.com']` ou `['example.com','wiki.example.com','example.net']`) +### Que faire si la page d'impression ne s'affiche pas un cadre de type `iframe` ? + +Si la page d'impression est affichée dans un cadre de type `iframe`, il est possible qu'elle ne s'affiche pas en raison des contraintes de sécurité de certains serveurs. + +Pour en autoriser l'affichage, rendez-vous en temps qu'administrateurice sur la page [GererConfig](?GererConfig 'Page config :ignore') dans la partie `Paramètres principaux` et ajouter `'pdf','pdfiframe'` aux valeurs possibles pour le paramètre `allowed_methods_in_iframe`. + ## Utilisation détaillée Cette partie décrit de façon détaillée les paramètres pour les actions et handlers utilisés. Pour les explications de prise en main, veuillez vous rendre [en haut de ce fichier](?id=prise-en-main). diff --git a/handlers/PdfHandler.php b/handlers/PdfHandler.php index 82622fa..2f6a334 100644 --- a/handlers/PdfHandler.php +++ b/handlers/PdfHandler.php @@ -3,49 +3,12 @@ namespace YesWiki\Publication; use YesWiki\Core\YesWikiHandler; -use YesWiki\Publication\Service\PdfHelper; +use YesWiki\Publication\Controller\PdfController; class PdfHandler extends YesWikiHandler { public function run() { - // get service - $pdfHelper = $this->getService(PdfHelper::class); - - if (!empty($_GET['url']) && is_string($_GET['url']) && - !empty($_GET['urlPageTag']) && is_string($_GET['urlPageTag']) && - !empty($_GET['hash']) && is_string($_GET['hash'])) { - // redirect to api - if (!method_exists($this->wiki, 'isCli') || !$this->wiki->isCli()) { - header('Access-Control-Allow-Origin: *'); - header('Access-Control-Expose-Headers: Location, Slug, Accept, Content-Type'); - } - $filteredParams = array_filter($_GET, function ($v, $k) { - return in_array($k, ['url','urlPageTag','hash','refresh','forceNewFormat','via','template-page'], true) && is_scalar($v); - }, ARRAY_FILTER8USE_BOTH); - $this->wiki->redirect($this->wiki->href('', 'api/pdf/getPdf', $filteredParams + [ - 'fromOldPath' => '1' - ], false)); - } - - - list( - 'pageTag'=>$pageTag, - 'sourceUrl'=>$sourceUrl, - 'hash'=>$hash, - ) = - $pdfHelper->getSourceUrl($_GET ?? [], $_SERVER ?? []); - - return $this->renderInSquelette('@publication/handler-pdf.twig', [ - 'isAdmin' => $this->wiki->UserIsAdmin(), - 'pageTag' => $pageTag, - 'sourceUrl' => $sourceUrl, - 'hash' => $hash, - 'urls' => [ - 'local' => $pdfHelper->canExecChromium() ? $this->wiki->href('', 'api/pdf/getPdf') : '', - 'external' => empty($this->params->get('htmltopdf_service_url')) ? '' : $this->params->get('htmltopdf_service_url'), - ], - 'refresh' => in_array($_GET['refresh'] ?? false, [1,"1",true,"true"], true), - ]); + return $this->getService(PdfController::class)->run(); } } diff --git a/handlers/PdfIframeHandler.php b/handlers/PdfIframeHandler.php new file mode 100644 index 0000000..b160376 --- /dev/null +++ b/handlers/PdfIframeHandler.php @@ -0,0 +1,55 @@ +wiki->UserIsAdmin() && + !in_array( + 'pdfiframe', + is_array($this->params->get('allowed_methods_in_iframe')) ? $this->params->get('allowed_methods_in_iframe') : [] + ) + ) { + // allow local ('self') and everyone (*) to allow display error message + if (!$this->wiki->isCli() && !headers_sent()) { + header("Content-Security-Policy: frame-ancestors 'self' *;"); + } + + return $this->displayInIframe($this->render('@templates/alert-message.twig', [ + 'type' => 'danger', + 'message' => _t('PUBLICATION_IFRAME_NOT_SET', [ + 'gererConfigLink' => "wiki->href('iframe', 'GererConfig')}\">GererConfig" + ]) + ])); + } + return $this->displayInIframe($this->getService(PdfController::class)->run(true)); + } + + protected function displayInIframe(string $content) + { + $output = << +
+
wiki->Format('{{doubleclic iframe="1"}}')}> + $content +
+
+ HTML; + // common footer for all iframe page + + $this->wiki->AddJavascriptFile('tools/templates/libs/vendor/iframeResizer.contentWindow.min.js'); + + // on recupere les entetes html mais pas ce qu'il y a dans le body + $header = explode('wiki->Header()); + $output = $header[0].$output; + // on recupere juste les javascripts et la fin des balises body et html + $output .= preg_replace('/^.+