Prestashop : Comment modifier l’affichage et les actions d’un « ModuleAdminControllerCore »

Nous avons vu dans l’article précédent les bases d’un module Prestashop. Nous allons voir dans cet article comment faire des choses un peu plus poussé en modifiant notre controller qui étend « ModuleAdminControllerCore ». En continuant sur le module de test précédent nous seront donc situé dans le fichier « moduletest/controller/admin/AdminModuleTest.php »

Ajouter des boutons dans la toolbar
Par défaut la « header toolbar » contient seulement le bouton « aide », voici comment y ajouter des boutons. Nous ajoutons ici un bouton vers notre formulaire d’ajout (un bouton existe déjà dans la « toolbar » de la liste, mais il sera plus visible à ce niveau).

    public function initPageHeaderToolbar() {
        //Bouton d'ajout
        $this->page_header_toolbar_btn['new'] = array(
            'href' => self::$currentIndex . '&add' . $this->table . '&token=' . $this->token,
            'desc' => $this->module->l('Ajouter un test'),
            'icon' => 'process-icon-new'
        );
        parent::initPageHeaderToolbar();
    }

Bloquer une action existante par défaut
Par défaut différentes actions existe sur votre objet (ajouter, modifier, supprimer) même si les bouton ne sont pas présent les pages existent et sont accessible. Voici comment bloquer les droits d’accès :

    public function access($action, $disable = false) {
        //suppression des droit d'accés à la page d'ajout / edition
        if (in_array($action, array('add', 'edit'))) {
            return false;
        }
        return parent::access($action, $disable);
    }

Et maintenant la petite astuce pour ne pas afficher le bouton d’ajout dans la « toolbar » de la liste

    //suppression du bouton "ajouter"
    public function initToolbar() {
        parent::initToolbar();
        unset($this->toolbar_btn['new']);
    }

Permettre d’ajouter des case à cocher pour supprimer des lignes « en masse »
Dans notre fonction « __construct » il faut ajouter :

        //corps de la fonction
        //...
        //ajout de l'option suppression de masse
        $this->bulk_actions = array(
            'delete' => array(
                'text' => $this->l('Delete selected'),
                'icon' => 'icon-trash',
                'confirm' => $this->l('Delete selected items?'),
            ),
        );

Modifier le comportement d’une action
Il est facile de modifier le comportement des actions existantes (ajout, modification, suppression) en remplaçant (override) leur méthode. Ci dessous par exemple on modifie l’action de « suppression d’une ligne » pour supprimer aussi un fichier ayant l’id de la ligne si il existe.

    public function processDelete() {
        //suppression classique
        $res = parent::processDelete();
        //on appelle notre fonction de suppression du fichier
        $this->deleteFile($res);
        return $res;
    }

    //la fonction de suppression du fichier
    private function deleteFile($obj) {
        //si pas d'erreur
        if ($obj) {
            if (file_exists('/chemin/du/fichier/' . $obj->id)) {
                unlink('/chemin/du/fichier/' . $obj->id);
            }
        }
    }

Attention si vous voulez que l’action « suppression en masse » réalise aussi les suppression de fichiers, il faut alors adapter sa méthode.

    protected function processBulkDelete() {
        //pour chaque ligne à supprimer
        foreach ($this->boxes as $id) {
            //je récupère l’objet correspondant et j'utilise ma fonction de suppression du fichier
            $obj = new $this->className($id);
            $this->deleteFile($obj);
        }
        //action d'origine
        return parent::processBulkDelete();
    }

Ajouter du contenu au dessus ou en dessous de la liste
Pour personnaliser la page, par exemple ajouter un bloc de contenu avec une variable personnalisé et un bouton au dessus de la liste, nous allons utiliser un template. Il faut créer le fichier « moduletest/views/templates/admin/prev-content.tpl » qui contiendra ce code :

<div class="panel col-lg-12">
    <label>Variable custom :</label> {$variable_custom}
    <hr/>
    <button class="btn btn-primary">Bouton d'exemple</button>
</div>

Puis adapter dans notre controller la fonction « initContent » :

    public function initContent() {
        parent::initContent();
        //on charge notre template custom auquel on assigne une "variable_custom"
        $this->context->smarty->assign(array('variable_custom' => 'nanani-nanana'));
        $prevContent = $this->context->smarty->fetch(_PS_MODULE_DIR_ . 'moduletest/views/templates/admin/prev-content.tpl');
        //que l'on place devant le contenu pr défaut
        $this->context->smarty->assign(array('content' => $prevContent . $this->content));
    }

On peux aussi faire une vue complètement personnalisé, par exemple en utilisant le page « details ». En modifiant notre fonction « renderList » on ajoute un bouton « détails » pour chaque ligne.

    public function renderList() {
        //bouton détails et suppression
        $this->addRowAction('details');
        $this->addRowAction('delete');
        return parent::renderList();
    }

Et on adapte « initContent » qui devient :

    public function initContent() {
        if ($this->display == 'details') {
            //chargement de l'objet
            $this->object = $this->loadObject();
            //que l'on transmet au template
            $this->context->smarty->assign(array('object' => $this->object));
            //récupération du template perso
            $content = $this->context->smarty->fetch(_PS_MODULE_DIR_ . 'moduletest/views/templates/admin/details.tpl');
            $this->context->smarty->assign(array('content' => $content));
        } else {
            parent::initContent();
            //on charge notre template custom auquel on assigne une "variable_custom"
            $this->context->smarty->assign(array('variable_custom' => 'nanani-nanana'));
            $prevContent = $this->context->smarty->fetch(_PS_MODULE_DIR_ . 'moduletest/views/templates/admin/prev-content.tpl');
            //que l'on place devant le contenu pr défaut
            $this->context->smarty->assign(array('content' => $prevContent . $this->content));
        }
    }

De la même façon que précédemment on créer le template « moduletest/views/templates/admin/details.tpl » et pour l’exemple ici on y affiche de façon brute notre objet :

<div class="panel col-lg-12">
    <pre>{$object|print_r}</pre>
</div>

Et ce sera pas mal pour commencer.

Laisser un commentaire

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

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.