{"id":1983,"date":"2019-05-23T16:55:26","date_gmt":"2019-05-23T14:55:26","guid":{"rendered":"https:\/\/www.h-hennes.fr\/blog\/?p=1983"},"modified":"2019-07-23T12:00:05","modified_gmt":"2019-07-23T10:00:05","slug":"prestashop-simplification-de-la-mise-en-page-des-emails","status":"publish","type":"post","link":"https:\/\/www.h-hennes.fr\/blog\/2019\/05\/23\/prestashop-simplification-de-la-mise-en-page-des-emails\/","title":{"rendered":"Prestashop : Simplification de la mise en page des emails"},"content":{"rendered":"\n<p><strong>Note :<\/strong><br \/>A compter la version 1.7.6 de Prestashop la gestion des emails a \u00e9t\u00e9 chang\u00e9e et cet article n&rsquo;est plus d&rsquo;actualit\u00e9.<\/p>\n<p>Les emails dans Prestashop ne permettent aucune factorisation, chaque email comprends son code html complet, lorsque vous souhaitez modifier du contenu dans l&rsquo;ent\u00eate ou dans le pied de page d&rsquo;un email il est n\u00e9cessaire de r\u00e9aliser la modification sur l&rsquo;ensemble des emails du site.<br \/><br \/>Ce n&rsquo;est pas tr\u00e8s pratique et cela peut \u00eatre source de perte de temps.<br \/>Nous allons voir dans cet article qu&rsquo;il existe des solutions natives et rapides pour optimiser ce point.<br \/>Via des cr\u00e9ations de modules comme souvent \ud83d\ude42<br \/>Nous allons cr\u00e9er dans cet article un module <strong>hhmail<\/strong> dont vous retrouverez le code complet en fin d&rsquo;article<br \/><br \/><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Principe Technique et pr\u00e9requis<\/h3>\n\n\n\n<p>Lors de l&rsquo;envoi d&rsquo;un email de nombreux \u00e9v\u00e9nements sont ex\u00e9cut\u00e9s dans la fonction Mail::send,&nbsp; mais ceux qui nous int\u00e9ressent sont les suivants :<\/p>\n<ul>\n<li>actionEmailAddBeforeContent : ex\u00e9cut\u00e9 <strong>avant<\/strong> la r\u00e9cup\u00e9ration du template de l&#8217;email<\/li>\n<li>actionEmailAddAfterContent : ex\u00e9cut\u00e9 <strong>apr\u00e8s<\/strong> la r\u00e9cup\u00e9ration du template de l&#8217;email<\/li>\n<\/ul>\n<p>Gr\u00e2ces \u00e0 ces hooks nous pouvons donc injecter du contenu avant et apr\u00e8s le contenu de l&#8217;email, il est donc ais\u00e9 de g\u00e9rer un <strong>header<\/strong> et un <strong>footer<\/strong> commun pour l&rsquo;ensemble des emails \ud83d\ude42<\/p>\n<p>Pour \u00e9viter d&rsquo;ajouter ces contenus sur des emails qui le contiennent d\u00e9j\u00e0, il faudra restreindre la liste des templates sur lesquels ces contenus s&rsquo;ajouteront, dans cette version je part du principe que <span style=\"text-decoration: underline;\">seuls les emails surcharg\u00e9s dans le th\u00e8me seront impact\u00e9s.<\/span><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Codes et exemples<\/h3>\n\n\n\n<p>Voici le code du module qui g\u00e8re l&rsquo;ensemble des principes \u00e9nonc\u00e9s ci-dessus, les commentaires sur les diff\u00e9rentes fonctions expliquent le fonctionnement.<\/p>\n\n\n\n<pre escaped=\"true\" lang=\"php\">class Hhmail extends Module\n{\n\n    \/** @var Liste des templates \u00e9ligibles array | null *\/\n    protected $_eligiblesTemplates;\n\n    public function __construct()\n    {\n        $this-&gt;name = 'hhmail';\n        $this-&gt;tab = 'others';\n        $this-&gt;version = '0.1.0';\n        $this-&gt;author = 'hhennes';\n        $this-&gt;bootstrap = true;\n        parent::__construct();\n\n        $this-&gt;displayName = $this-&gt;l('Hh mail');\n        $this-&gt;description = $this-&gt;l('Email Optimisation module');\n       \/\/A compter de la version 1.7.6 , la gestion des emails est chang\u00e9e et n'est plus compatible\n        $this->ps_versions_compliancy = array('min' => '1.6.1.0', 'max' => '1.7.6.0');\n    }\n\n    \/**\n     * Installation du module\n     * @return bool\n     *\/\n    public function install()\n    {\n        if (!parent::install()\n            || !$this-&gt;registerHook([\n                'actionEmailAddBeforeContent',\n                'actionEmailAddAfterContent'\n            ])\n\n        ) {\n            return false;\n        }\n\n        return true;\n    }\n\n\n    \/**\n     * Ajout de contenu AVANT le contenu du template email\n     * @param array(\n     *   'template' =&gt; $template,\n     *   'template_html' =&gt; &amp;$templateHtml,\n     *   'template_txt' =&gt; &amp;$templateTxt,\n     *   'id_lang' =&gt; (int) $idLang,\n     * @throws PrestaShopDatabaseException\n     * @throws PrestaShopException\n     *\/\n    public function hookActionEmailAddBeforeContent($params)\n    {\n        \/\/Via ce param\u00e8tre il est possible de choisir les emails pour lequels appliquer ou non le comportement\n        \/\/Pour l'exemple la fonction r\u00e9cup\u00e8re uniquement les emails sucharg\u00e9s dans le th\u00e8me\n        \/\/Il est possible de faire une conf admin si n\u00e9cessaire pour g\u00e9rer les cas mais ici on est dans le cadre d'un poc ;)\n        if (in_array($params['template'], $this-&gt;_getOverridablesTemplates())) {\n            $params['template_html'] .= $this-&gt;_getHeaderContent();\n        }\n    }\n\n\n    \/**\n     * Ajout de contenu APRES le contenu du template email\n     * @param array(\n     *   'template' =&gt; $template,\n     *   'template_html' =&gt; &amp;$templateHtml,\n     *   'template_txt' =&gt; &amp;$templateTxt,\n     *   'id_lang' =&gt; (int) $idLang,\n     * @throws PrestaShopDatabaseException\n     * @throws PrestaShopException\n     *\/\n    public function hookActionEmailAddAfterContent($params)\n    {\n        if (in_array($params['template'], $this-&gt;_getOverridablesTemplates())) {\n            $params['template_html'] .= $this-&gt;_getFooterContent();\n        }\n    }\n\n    \/**\n     * R\u00e9cup\u00e9ration du contenu du header\n     * @return string\n     *\/\n    protected function _getHeaderContent()\n    {\n        return $this-&gt;_getMailContent('header', $this-&gt;context-&gt;language-&gt;iso_code);\n    }\n\n    \/**\n     * R\u00e9cup\u00e9ration du contenu du footer\n     * @return string\n     *\/\n    protected function _getFooterContent()\n    {\n        return $this-&gt;_getMailContent('footer', $this-&gt;context-&gt;language-&gt;iso_code);\n    }\n\n    \/**\n     * R\u00e9cup\u00e9ration du contenu des fichiers mails situ\u00e9s dans \/mails\/codeLangue\/\n     * @param $template\n     * @param $iso_code\n     * @return bool|false|string\n     *\/\n    protected function _getMailContent($template, $iso_code)\n    {\n        $templateFile = _PS_MODULE_DIR_ . $this-&gt;name . '\/mails\/' . $iso_code . '\/' . $template . '.html';\n        if (is_file($templateFile)) {\n            return Tools::file_get_contents($templateFile);\n        }\n        return false;\n    }\n\n    \/**\n     * R\u00e9cup\u00e9ration des emails \u00e9ligibles pour \u00eatre manag\u00e9s avec un header\/footer\n     * On part du principe que ce ne sont que ceux du th\u00e8me\n     * ( car les emails initiaux de Prestashop les comportent d\u00e9j\u00e0 )\n     * @return array\n     * @throws PrestaShopDatabaseException\n     * @throws PrestaShopException\n     *\/\n    protected function _getOverridablesTemplates()\n    {\n        if (null === $this-&gt;_eligiblesTemplates) {\n\n            $templates = [];\n            $defaultLang = (int)Configuration::get('PS_LANG_DEFAULT');\n            $language = new Language($defaultLang);\n            $mailDefaultDir = _PS_THEME_DIR_ . 'mails\/' . $language-&gt;iso_code . '\/';\n\n            \/\/Pas d'utilisation de lib symfony pour compatibilit\u00e9 avec PS &lt; 1.7\n            if (is_dir($mailDefaultDir)) {\n                $handle = opendir($mailDefaultDir);\n                while (false !== ($entry = readdir($handle))) {\n                    if ($entry != \".\" &amp;&amp; $entry != \"..\" \n                        &amp;&amp; !is_dir($mailDefaultDir . '\/' . $entry) \/\/Exclusion des dossier\n                        \/\/On prends uniquement les fichiers avec extension html\n                        &amp;&amp; 'html' === strtolower(pathinfo($mailDefaultDir . '\/' . $entry, PATHINFO_EXTENSION))\n                    ) {\n                        $templates[] = pathinfo($entry, PATHINFO_FILENAME);\n                    }\n                }\n            }\n            $this-&gt;_eligiblesTemplates = $templates;\n        }\n\n        return $this-&gt;_eligiblesTemplates;\n    }\n}\n<\/pre>\n\n\n\n<p>Voici le contenu d&rsquo;un email dans lequel l&rsquo;ent\u00eate et le pied de page ont \u00e9t\u00e9 supprim\u00e9 ( email mot de passe oubli\u00e9 )<\/p>\n\n\n\n<p>\/<\/p>\n\n\n\n<pre escaped=\"true\" lang=\"html\"><!-- Le header est ajout\u00e9 automatiquement via le module hhmail -->\n\t\t<span style=\"color: #555454; font-family: Open-sans, sans-serif; font-size: small;\">\n\t\t\t<span class=\"title\" style=\"font-weight: 500; font-size: 28px; text-transform: uppercase; line-height: 33px;\">Bonjour {firstname} {lastname},<\/span>\n\t\t<\/span>\n\t\n<\/pre>\n<table class=\"table\" style=\"width: 100%;\">\n<tbody>\n<tr>\n<td style=\"padding: 7px 0;\" width=\"10\">&nbsp;<\/td>\n<td style=\"padding: 7px 0;\">\n<p style=\"border-bottom: 1px solid #D6D4D4; margin: 3px 0 7px; text-transform: uppercase; font-weight: 500; font-size: 18px; padding-bottom: 10px;\" data-html-only=\"1\">\n\t\t\t\t\t\t\tVos nouvelles informations d&rsquo;identification sur {shop_name}\t\t\t\t\t\t<\/p>\n<span style=\"color: #555454; font-family: Open-sans, sans-serif; font-size: small;\">\n\t\t\t\t\t\t<span style=\"color: #777;\">\n\t\t\t\t\t\t\t<span style=\"color: #333;\"><strong>Adresse e-mail :<\/strong><\/span> {email}\n\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t<\/td>\n<td style=\"padding: 7px 0;\" width=\"10\">&nbsp;<\/td>\n\n\t\t\t<\/tr>\n\n\t\t<\/tbody>\n<\/table>\n<pre escaped=\"true\" lang=\"html\">\t\n<br>\n\n\t\t<span style=\"color: #555454; font-family: Open-sans, sans-serif; font-size: small;\">\n\t\t\t\n\t\t\t\tVous pouvez acc\u00e9der \u00e0 tout moment au suivi de votre commande et t\u00e9l\u00e9charger votre facture dans <a style=\"color: #337ff1;\" href=\"{history_url}\">\"Historique des commandes\"<\/a> de la rubrique <a style=\"color: #337ff1;\" href=\"{my_account_url}\">\"Mon compte\"<\/a> sur notre site.\t\t\t\n\t\t<\/span>\n\t\n\n\t\t<span style=\"color: #555454; font-family: Open-sans, sans-serif; font-size: small;\">\n\t\t\t\n\t\t\t\tSi vous avez un compte invit\u00e9, vous pouvez suivre votre commande dans la section <a style=\"color: #337ff1;\" href=\"{guest_tracking_url}?id_order={order_name}\">\"Suivi invit\u00e9\"<\/a> de notre site.\t\t\t\n\t\t<\/span>\n\t\n\n<!-- Le footer est ajout\u00e9 automatiquement via le module hhmail -->\n\n<\/pre>\n\n\n\n<p>Les contenus des parties header et footer ne pr\u00e9sentent pas d&rsquo;int\u00e9r\u00eat je ne les d\u00e9taille pas ici mais vous pouvez les trouvez dans l&rsquo;archive.<\/p>\n<p>Voici le rendu final du mail avec le remplacement du header et du footer ( exactement le m\u00eame que les autres emails. ), mais les contenus sont r\u00e9cup\u00e9r\u00e9s dynamiquement du module hhmail<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"788\" height=\"432\" src=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2019\/05\/email-header-footer.png\" alt=\"\" class=\"wp-image-1984\" srcset=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2019\/05\/email-header-footer.png 788w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2019\/05\/email-header-footer-300x164.png 300w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2019\/05\/email-header-footer-768x421.png 768w\" sizes=\"auto, (max-width: 788px) 100vw, 788px\" \/><figcaption>Email avec header et footer dynamique<\/figcaption><\/figure>\n\n\n\n<p>En revanche si vous avez des modifications \u00e0 faire dans les styles, dans l&rsquo;ent\u00eate ou le footer de vos emails les modifications seront instantan\u00e9es sur tous les emails utilisant les templates,&nbsp; \ud83d\ude42<\/p>\n<p>Vous pouvez t\u00e9l\u00e9charger le module ici :&nbsp;<a href=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2019\/05\/hhmail.zip\" target=\"_blank\" rel=\"noopener noreferrer\">hhmail<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Note :A compter la version 1.7.6 de Prestashop la gestion des emails a \u00e9t\u00e9 chang\u00e9e et cet article n&rsquo;est plus d&rsquo;actualit\u00e9. Les emails dans Prestashop ne permettent aucune factorisation, chaque email comprends son code html complet, lorsque vous souhaitez modifier du contenu dans l&rsquo;ent\u00eate ou dans le pied de page d&rsquo;un email il est n\u00e9cessaire [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[245],"tags":[311,104,524],"class_list":["post-1983","post","type-post","status-publish","format-standard","hentry","category-prestashop-2","tag-emails","tag-prestashop","tag-pretashop-17","prestashop-1-6","prestashop-1-7","prestashop-1-7-2","prestashop-1-7-3","prestashop-1-7-4","prestashop-1-7-5","prestashop-1-7-6","prestashop-1-7-8"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts\/1983","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/comments?post=1983"}],"version-history":[{"count":4,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts\/1983\/revisions"}],"predecessor-version":[{"id":2003,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts\/1983\/revisions\/2003"}],"wp:attachment":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/media?parent=1983"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/categories?post=1983"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/tags?post=1983"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}