Prestashop : bloquer les mises à jour de modules dans l’administration

Ce tutoriel est compatible avec les versions de Prestashop suivantes :
1.7 +

Présentation du problème et solution

C’est un comportement bien connu et assez embêtant auquel je m’attaque aujourd’hui.

Qui n’a jamais pesté d’avoir mis à jour un module dans le back office de Prestashop alors qu’on souhaitait uniquement le configurer ..

Par défaut lorsqu’une mise à jour d’un module est disponible, c’est l’action « Upgrade » qui est l’action par défaut.

Un clic trop rapide et on se retrouve avec une version non testée et donc potentiellement des erreurs sur son site.

J’ai donc créé un petit module qui permets de désactiver l’action du bouton de mise à jour et qui affiche un autre message à la place.

Il est possible de configurer le comportement ( normal ou bloqué ) directement depuis la configuration du module.

Fonctionnement technique

Pour gérer cela nous allons créer un module hh_modulesupdater

Ce module va utiliser la possibilité de surcharger les templates symfony du core en reprenant simplement leur chemin dans un module.

Nous allons donc créer un fichier :
modules/hh_modulesupdater/views/PrestaShop/Admin/Module/Includes/action_button.html.twig
qui correspond à une surcharge du template :
src/PrestaShopBundle/Resources/views/Admin/Module/Includes/action_button.html.twig

Le contenu de ce fichier est le suivant , vous pouvez tout à fait mettre à jour le message je n’ai pas géré de traduction spécifique.

{% set displayAction = action|capitalize|replace({'_': " "})|trans({}, 'Admin.Actions') %}
 
{% if (action == 'configure') %}
 
    <a class="{{ classes }}" href="{{ url }}">
      {{ displayAction }}
    </a>
 
{% else %}
 
    {% if action != 'upgrade'%}
    <form class='{{classes_form|default() }}' method="post" action="{{ url }}">
      <button type="submit" class="{{ classes }} module_action_menu_{{ action }}" data-confirm_modal="module-modal-confirm-{{ name }}-{{ action }}">
        {{ displayAction }}
      </button>
    </form>
    {%else%}
        <button type="button" class="{{ classes }}">
            Mise &agrave; jour des modules<br /> d&eacute;sactiv&eacute;e en BO
        </button>
    {% endif%}
 
{% endif %}

L’activation désactivation de la fonctionnalité est ensuite obtenue en renommant le fichier de surcharge en action_button.html.twig.disabled

Voici le code complet du module :

<?php
if (!defined('_PS_VERSION_')) {
    exit;
}
 
use Symfony\Component\Filesystem\Filesystem;
 
class Hh_Modulesupdater extends Module
{
 
    public function __construct()
    {
        $this->name = 'hh_modulesupdater';
        $this->tab = 'others';
        $this->version = '0.1.0';
        $this->author = 'hhennes';
        $this->bootstrap = true;
        parent::__construct();
 
        $this->displayName = $this->l('Manage module update button');
        $this->description = $this->l('Enable or disable update modules button in admin');
    }
 
    /**
     * Install Module
     * @return bool
     */
    public function install()
    {
        if (
            !parent::install()
            || !Configuration::updateGlobalValue($this->name . '_ENABLE_MODULES_UPDATE', 0)
 
        ) {
            return false;
        }
 
        return true;
    }
 
    /**
     * Uninstall Module
     * @return bool
     */
    public function uninstall()
    {
        return parent::uninstall() && Configuration::deleteByName($this->name . '_ENABLE_MODULES_UPDATE');
    }
 
    /**
     * Configure module
     * @return string
     */
    public function getContent()
    {
        $html = '';
        $html .= $this->postProcess();
        $html .= $this->renderForm();
 
        return $html;
    }
 
    /**
     * Manage configuration upgrade
     * @return string|void
     */
    protected function postProcess()
    {
        if (Tools::isSubmit('SubmitConfigForm')) {
            $enableUpdate = Tools::getValue($this->name . '_ENABLE_MODULES_UPDATE');
            if (Configuration::updateValue(
                    $this->name . '_ENABLE_MODULES_UPDATE',
                    $enableUpdate
                ) && $this->toggleModuleUpdate((bool)$enableUpdate)) {
                return $this->displayConfirmation($this->l('Settings Updated'));
            } else {
                return $this->displayError($this->l('Unable to update settings'));
            }
        }
    }
 
    /**
     * Get configuration form
     * @return string
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function renderForm()
    {
        $fields_form = [
            'form' => [
                'legend' => [
                    'title' => $this->l('Configure module upgrade'),
                    'icon' => 'icon-cogs'
                ],
                'input' => [
                    [
                        'type' => 'switch',
                        'label' => $this->l('Enable module Upgrade'),
                        'name' => $this->name . '_ENABLE_MODULES_UPDATE',
                        'hint' => $this->l('Allow to upgrade modules from back office ? (disabled by default by this module)'),
                        'required' => true,
                        'values' => [
                            ['id' => 'on', 'value' => 1, 'label' => $this->l('Yes')],
                            ['id' => 'off', 'value' => 0, 'label' => $this->l('No')],
                        ],
                    ],
                ],
                'submit' => [
                    'title' => $this->l('Save'),
                    'class' => 'button btn btn-default pull-right',
                ]
            ],
        ];
 
        $helper = new HelperForm();
        $helper->show_toolbar = false;
        $lang = new Language((int)Configuration::get('PS_LANG_DEFAULT'));
        $helper->default_form_language = $lang->id;
        $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
        $helper->identifier = $this->name;
        $helper->submit_action = 'SubmitConfigForm';
        $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false) . '&configure=' . $this->name . '&tab_module=' . $this->tab . '&module_name=' . $this->name;
        $helper->token = Tools::getAdminTokenLite('AdminModules');
        $helper->tpl_vars = array(
            'fields_value' => [
                $this->name . '_ENABLE_MODULES_UPDATE' => Tools::getValue($this->name . '_ENABLE_MODULES_UPDATE', 0),
            ],
            'languages' => $this->context->controller->getLanguages(),
            'id_language' => $this->context->language->id
        );
 
        return $helper->generateForm(array($fields_form));
    }
 
    /**
     * Toggle Module Update by changing template name
     * @param bool $enable
     * @return bool
     */
    protected function toggleModuleUpdate($enable)
    {
        $fileSystem = new Filesystem();
        $updagradeTemplatePath = _PS_MODULE_DIR_ . $this->name . '/views/PrestaShop/Admin/Module/Includes/';
        if (true === $enable && $fileSystem->exists($updagradeTemplatePath . 'action_button.html.twig')) {
            try {
                $fileSystem->rename(
                    $updagradeTemplatePath . 'action_button.html.twig',
                    $updagradeTemplatePath . 'action_button.html.twig.disabled'
                );
                return true;
            } catch (Exception $e) {
                return false;
            }
        }
 
        if (false === $enable && $fileSystem->exists($updagradeTemplatePath . 'action_button.html.twig.disabled')) {
            try {
                $fileSystem->rename(
                    $updagradeTemplatePath . 'action_button.html.twig.disabled',
                    $updagradeTemplatePath . 'action_button.html.twig'
                );
                return true;
            } catch (Exception $e) {
                return false;
            }
        }
 
        return false;
    }
}

N’hésitez pas à partager vos retours , pour ceux qui ne veulent pas créer le module vous pouvez télécharger directement l’archive :

4 réflexions sur “Prestashop : bloquer les mises à jour de modules dans l’administration”

  1. Bonjour, super idée, merci. Y aurait il la possibilité de rajouter a ce petit module la desactivation pure et simple de la demande de mise à jour de ces modules ? De cette façon plus de probleme et plus de va et viens de données avec les serveurs de prestashop…

    1. Bonjour,

      Pour ce point c’est ce sera sans doute plus lourd et complexe qu’une simple surcharge de template.
      Et pas sur d’avoir la possibilité de le faire via un module.
      N’hésitez pas à partager vos recherches sur le sujet ça m’intéresse également.

  2. Salut Hervé,

    Petite solution, décorer ou surcharger le service AdminModuleDataProvider.

    prestashop.adapter.admin.data_provider.module:
    class: PrestaShop\PrestaShop\Adapter\Module\AdminModuleDataProvider
    arguments:
    – « @translator »
    – « @logger »
    – « @prestashop.core.admin.data_provider.addons_interface »
    – « @prestashop.categories_provider »
    – « @prestashop.adapter.data_provider.module »
    – « @doctrine.cache.provider »
    – « @=service(‘prestashop.adapter.legacy.context’).getContext().employee »
    calls:
    – [ setRouter, [‘@router’]]
    decorates: prestashop.core.admin.data_provider.module_interface
    public: false

    C’est la méthode generateAddonsUrls qui va gérer les urls/actions à afficher pour chaque modules

    1. Salut Arnaud,

      Super merci pour le partage ! 🙂
      Du coup ça réponds à la problématique de Tiri sur le sujet
      Je vais voir pour adapter l’article avec ce fonctionnement également.

      Cordialement,
      Hervé

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *