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 :