{"id":2178,"date":"2020-10-12T12:42:58","date_gmt":"2020-10-12T10:42:58","guid":{"rendered":"https:\/\/www.h-hennes.fr\/blog\/?p=2178"},"modified":"2022-10-29T23:02:28","modified_gmt":"2022-10-29T21:02:28","slug":"prestashop-bloquer-les-mises-a-jour-de-modules-dans-ladministration","status":"publish","type":"post","link":"https:\/\/www.h-hennes.fr\/blog\/2020\/10\/12\/prestashop-bloquer-les-mises-a-jour-de-modules-dans-ladministration\/","title":{"rendered":"Prestashop : bloquer les mises \u00e0 jour de modules dans l&rsquo;administration"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\">Pr\u00e9sentation du probl\u00e8me et solution<\/h3>\n\n\n\n<p>C&rsquo;est un comportement bien connu et assez emb\u00eatant auquel je m&rsquo;attaque aujourd&rsquo;hui.<br \/><br \/>Qui n&rsquo;a jamais pest\u00e9 d&rsquo;avoir mis \u00e0 jour un module dans le back office de Prestashop alors qu&rsquo;on souhaitait uniquement le configurer ..<\/p>\n<p>Par d\u00e9faut lorsqu&rsquo;une mise \u00e0 jour d&rsquo;un module est disponible, c&rsquo;est l&rsquo;action \u00ab\u00a0Upgrade\u00a0\u00bb qui est l&rsquo;action par d\u00e9faut.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"807\" height=\"243\" src=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2020\/10\/image.png\" alt=\"\" class=\"wp-image-2179\" srcset=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2020\/10\/image.png 807w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2020\/10\/image-300x90.png 300w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2020\/10\/image-768x231.png 768w\" sizes=\"auto, (max-width: 807px) 100vw, 807px\" \/><\/figure>\n\n\n\n<p>Un clic trop rapide et on se retrouve avec une version non test\u00e9e et donc potentiellement des erreurs sur son site.<br \/><br \/>J&rsquo;ai donc cr\u00e9\u00e9 un petit module qui permets de d\u00e9sactiver l&rsquo;action du bouton de mise \u00e0 jour et qui affiche un autre message \u00e0 la place.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"177\" src=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2020\/10\/image-2-1024x177.png\" alt=\"\" class=\"wp-image-2181\" srcset=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2020\/10\/image-2-1024x177.png 1024w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2020\/10\/image-2-300x52.png 300w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2020\/10\/image-2-768x133.png 768w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2020\/10\/image-2.png 1203w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Il est possible de configurer le comportement ( normal ou bloqu\u00e9 ) directement depuis la configuration du module.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"717\" height=\"207\" src=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2020\/10\/image-1.png\" alt=\"\" class=\"wp-image-2180\" srcset=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2020\/10\/image-1.png 717w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2020\/10\/image-1-300x87.png 300w\" sizes=\"auto, (max-width: 717px) 100vw, 717px\" \/><\/figure>\n\n\n\n\n\n<h3 class=\"wp-block-heading\">Fonctionnement technique<\/h3>\n\n\n\n<p>Pour g\u00e9rer cela nous allons cr\u00e9er un module <strong>hh_modulesupdater<\/strong><br \/><br \/>Ce module va utiliser la possibilit\u00e9 de surcharger les templates symfony du core en reprenant simplement leur chemin dans un module.<br \/><br \/>Nous allons donc cr\u00e9er un fichier : <br \/><em>modules\/hh_modulesupdater\/views\/PrestaShop\/Admin\/Module\/Includes\/action_button.html.twig<\/em> <br \/>qui correspond \u00e0 une surcharge du template : <br \/>src\/PrestaShopBundle\/Resources\/views\/Admin\/Module\/Includes\/action_button.html.twig<\/p>\n<p>Le contenu de ce fichier est le suivant , vous pouvez tout \u00e0 fait mettre \u00e0 jour le message je n&rsquo;ai pas g\u00e9r\u00e9 de traduction sp\u00e9cifique.<\/p>\n\n\n\n<pre lang=\"twig\" escaped=\"true\">\n{% set displayAction = action|capitalize|replace({'_': &quot; &quot;})|trans({}, 'Admin.Actions') %}\n\n{% if (action == 'configure') %}\n\n    &lt;a class=&quot;{{ classes }}&quot; href=&quot;{{ url }}&quot;&gt;\n      {{ displayAction }}\n    &lt;\/a&gt;\n\n{% else %}\n\n    {% if action != 'upgrade'%}\n    &lt;form class='{{classes_form|default() }}' method=&quot;post&quot; action=&quot;{{ url }}&quot;&gt;\n      &lt;button type=&quot;submit&quot; class=&quot;{{ classes }} module_action_menu_{{ action }}&quot; data-confirm_modal=&quot;module-modal-confirm-{{ name }}-{{ action }}&quot;&gt;\n        {{ displayAction }}\n      &lt;\/button&gt;\n    &lt;\/form&gt;\n    {%else%}\n        &lt;button type=&quot;button&quot; class=&quot;{{ classes }}&quot;&gt;\n            Mise &agrave; jour des modules&lt;br \/&gt; d&eacute;sactiv&eacute;e en BO\n        &lt;\/button&gt;\n    {% endif%}\n\n{% endif %}\n\n<\/pre>\n\n\n\n<p>L&rsquo;activation d\u00e9sactivation de la fonctionnalit\u00e9 est ensuite obtenue en renommant le fichier de surcharge en <em>action_button.html.twig.disabled<\/em><\/p>\n<p>Voici le code complet du module :<\/p>\n\n\n\n<pre lang=\"php\" escaped=\"true\">\n<?php\nif (!defined('_PS_VERSION_')) {\n    exit;\n}\n\nuse Symfony\\Component\\Filesystem\\Filesystem;\n\nclass Hh_Modulesupdater extends Module\n{\n\n    public function __construct()\n    {\n        $this->name = 'hh_modulesupdater';\n        $this->tab = 'others';\n        $this->version = '0.1.0';\n        $this->author = 'hhennes';\n        $this->bootstrap = true;\n        parent::__construct();\n\n        $this->displayName = $this->l('Manage module update button');\n        $this->description = $this->l('Enable or disable update modules button in admin');\n    }\n\n    \/**\n     * Install Module\n     * @return bool\n     *\/\n    public function install()\n    {\n        if (\n            !parent::install()\n            || !Configuration::updateGlobalValue($this->name . '_ENABLE_MODULES_UPDATE', 0)\n\n        ) {\n            return false;\n        }\n\n        return true;\n    }\n\n    \/**\n     * Uninstall Module\n     * @return bool\n     *\/\n    public function uninstall()\n    {\n        return parent::uninstall() && Configuration::deleteByName($this->name . '_ENABLE_MODULES_UPDATE');\n    }\n\n    \/**\n     * Configure module\n     * @return string\n     *\/\n    public function getContent()\n    {\n        $html = '';\n        $html .= $this->postProcess();\n        $html .= $this->renderForm();\n\n        return $html;\n    }\n\n    \/**\n     * Manage configuration upgrade\n     * @return string|void\n     *\/\n    protected function postProcess()\n    {\n        if (Tools::isSubmit('SubmitConfigForm')) {\n            $enableUpdate = Tools::getValue($this->name . '_ENABLE_MODULES_UPDATE');\n            if (Configuration::updateValue(\n                    $this->name . '_ENABLE_MODULES_UPDATE',\n                    $enableUpdate\n                ) && $this->toggleModuleUpdate((bool)$enableUpdate)) {\n                return $this->displayConfirmation($this->l('Settings Updated'));\n            } else {\n                return $this->displayError($this->l('Unable to update settings'));\n            }\n        }\n    }\n\n    \/**\n     * Get configuration form\n     * @return string\n     * @throws PrestaShopDatabaseException\n     * @throws PrestaShopException\n     *\/\n    protected function renderForm()\n    {\n        $fields_form = [\n            'form' => [\n                'legend' => [\n                    'title' => $this->l('Configure module upgrade'),\n                    'icon' => 'icon-cogs'\n                ],\n                'input' => [\n                    [\n                        'type' => 'switch',\n                        'label' => $this->l('Enable module Upgrade'),\n                        'name' => $this->name . '_ENABLE_MODULES_UPDATE',\n                        'hint' => $this->l('Allow to upgrade modules from back office ? (disabled by default by this module)'),\n                        'required' => true,\n                        'values' => [\n                            ['id' => 'on', 'value' => 1, 'label' => $this->l('Yes')],\n                            ['id' => 'off', 'value' => 0, 'label' => $this->l('No')],\n                        ],\n                    ],\n                ],\n                'submit' => [\n                    'title' => $this->l('Save'),\n                    'class' => 'button btn btn-default pull-right',\n                ]\n            ],\n        ];\n\n        $helper = new HelperForm();\n        $helper->show_toolbar = false;\n        $lang = new Language((int)Configuration::get('PS_LANG_DEFAULT'));\n        $helper->default_form_language = $lang->id;\n        $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;\n        $helper->identifier = $this->name;\n        $helper->submit_action = 'SubmitConfigForm';\n        $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false) . '&configure=' . $this->name . '&tab_module=' . $this->tab . '&module_name=' . $this->name;\n        $helper->token = Tools::getAdminTokenLite('AdminModules');\n        $helper->tpl_vars = array(\n            'fields_value' => [\n                $this->name . '_ENABLE_MODULES_UPDATE' => Tools::getValue($this->name . '_ENABLE_MODULES_UPDATE', 0),\n            ],\n            'languages' => $this->context->controller->getLanguages(),\n            'id_language' => $this->context->language->id\n        );\n\n        return $helper->generateForm(array($fields_form));\n    }\n\n    \/**\n     * Toggle Module Update by changing template name\n     * @param bool $enable\n     * @return bool\n     *\/\n    protected function toggleModuleUpdate($enable)\n    {\n        $fileSystem = new Filesystem();\n        $updagradeTemplatePath = _PS_MODULE_DIR_ . $this->name . '\/views\/PrestaShop\/Admin\/Module\/Includes\/';\n        if (true === $enable && $fileSystem->exists($updagradeTemplatePath . 'action_button.html.twig')) {\n            try {\n                $fileSystem->rename(\n                    $updagradeTemplatePath . 'action_button.html.twig',\n                    $updagradeTemplatePath . 'action_button.html.twig.disabled'\n                );\n                return true;\n            } catch (Exception $e) {\n                return false;\n            }\n        }\n\n        if (false === $enable && $fileSystem->exists($updagradeTemplatePath . 'action_button.html.twig.disabled')) {\n            try {\n                $fileSystem->rename(\n                    $updagradeTemplatePath . 'action_button.html.twig.disabled',\n                    $updagradeTemplatePath . 'action_button.html.twig'\n                );\n                return true;\n            } catch (Exception $e) {\n                return false;\n            }\n        }\n\n        return false;\n    }\n}\n\n<\/pre>\n\n\n\n<p>N&rsquo;h\u00e9sitez pas \u00e0 partager vos retours , pour ceux qui ne veulent pas cr\u00e9er le module vous pouvez t\u00e9l\u00e9charger directement l&rsquo;archive :<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2020\/10\/hh_modulesupdater.zip\">hh_modulesupdater<\/a><a href=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2020\/10\/hh_modulesupdater.zip\" class=\"wp-block-file__button\" download>T\u00e9l\u00e9charger<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Pr\u00e9sentation du probl\u00e8me et solution C&rsquo;est un comportement bien connu et assez emb\u00eatant auquel je m&rsquo;attaque aujourd&rsquo;hui. Qui n&rsquo;a jamais pest\u00e9 d&rsquo;avoir mis \u00e0 jour un module dans le back office de Prestashop alors qu&rsquo;on souhaitait uniquement le configurer .. Par d\u00e9faut lorsqu&rsquo;une mise \u00e0 jour d&rsquo;un module est disponible, c&rsquo;est l&rsquo;action \u00ab\u00a0Upgrade\u00a0\u00bb qui est [&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,6],"tags":[348,361,483,558],"class_list":["post-2178","post","type-post","status-publish","format-standard","hentry","category-prestashop-2","category-trucs-et-astuces","tag-admin","tag-modules","tag-prestashop-1-7","tag-upgrade","prestashop-1-6","prestashop-1-7","prestashop-1-7-6"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts\/2178","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=2178"}],"version-history":[{"count":1,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts\/2178\/revisions"}],"predecessor-version":[{"id":2183,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts\/2178\/revisions\/2183"}],"wp:attachment":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/media?parent=2178"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/categories?post=2178"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/tags?post=2178"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}