Cet article est la suite est de celui qui présente le fonctionnement de base et qui est consultable ici : https://www.h-hennes.fr/blog/2018/11/15/prestashop-admincontroller-pour-un-module/
Il présente les fonctionnalités avancées disponibles dans un adminController réalisé dans le cadre d’un module et il aura vocation a être modifié ou complété au fur et à mesure.
Voici le détails des points qui seront évoqués :

Général :

  • Gestion de la toolbar
    • Changement du titre
    • Ajout d’un bouton d’action
  • Ajouter une action
  • Validation spécifique
  • Gestion d’images
  • Appels Ajax
  • Surcharger le template

Listing :

  • Champs active / non active
  • Ajouter un callback sur un champ
  • Ajouter des actions de masse personnalisée
  • Récupérer les données de plusieurs tables

Formulaire :

  • Lier des champs en ajax
  • Afficher des contenus totalement personnalisé

Options :

  • Ensemble des cas d’affichage d’options
  • Traitement spécifique d’une option

Général :

Gestion de la toolbar :

Ajouter un titre sur la page

Ce point est géré par la fonction initToolbarTitle

    /**
     * Affichage d'un titre personnalisé
     */
    public function initToolbarTitle()
    {
        parent::initToolbarTitle();
 
        switch ($this->display) {
            case '':
            case 'list': //Titre pour le listing
                array_pop($this->toolbar_title);
                $this->toolbar_title[] = $this->module->l('Custom Title for listing');
                break;
            case 'add': //Titre pour l'ajout et l'édition d'un objet
            case 'edit':
                array_pop($this->toolbar_title);
                if (($sample = $this->loadObject(true)) && Validate::isLoadedObject($sample)) {
                    $this->toolbar_title[] = sprintf($this->module->l('Editing sample %s'),$sample->name);
                } else {
                    $this->toolbar_title[] = $this->module->l('Creating a new sample');
                }
                break;
        }
    }

Title controller

Ajouter un bouton d’action :
Cet élément est géré par la fonction initPageHeaderToolbar

public function initPageHeaderToolbar()
    {
 
        //Bouton d'ajout ( standard )
        $this->page_header_toolbar_btn['new'] = array(
            'href' => self::$currentIndex . '&add' . $this->table . '&token=' . $this->token,
            'desc' => $this->module->l('Add new Sample'),
            'icon' => 'process-icon-new'
        );
 
        //Ajout d'un bouton custom
        $this->page_header_toolbar_btn['custom_button'] = array(
            'href' => self::$currentIndex . '&token=' . $this->token.'&action=custom',
            'desc' => $this->module->l('Custom button'),
            'icon' => 'process-icon-configure'
        );
 
        parent::initPageHeaderToolbar();
    }

Custom Button

Ajouter une action personnalisée

Pour ajouter une action personnalisée il suffit de créer une fonction processXxxxx, en prenant l’exemple de l’action « custom » du bouton ajouté ci-dessus.
Il faudrait donc créer la fonction processCustom

   /**
     * Action spécifique pour le controller
     */
    public function processCustom(){
       dump('custom Action called by the button toolbar');
    }

Ceci permets d’appeler un process et de faire un traitement particulier, dans votre controller.

Blog custom action

Validation spécifique

Pour ajouter une validation spécifique sur votre objet il suffit d’implémenter la fonction _childValidation.
Celle-ci est appelée dans la fonction validateRules de l’admin controller

/**
 * Règles de validations spécifiques
 */
protected function _childValidation()
    {
        //Règle de validation custom à mettre en place
        if ( $this->object){
            if ( strlen($this->object->name) < 3 ){ $this->errors[] = $this->l('Name need more than 3 characters');
            }
        }
    }

 

Gestion d’images

Prestashop permets de gérer facilement des images pour votre un objet dans son controller admin.
Pour cela 2 actions sont nécessaires :

Dans la fonction __construct() rajouter la configuration suivante :

        /**
         * Gestion des images
         */
        $this->fieldImageSettings = array(
            'name' => 'image', //Nom du champ dans le formulaire d'édition de l'objet
            'dir' => 'sample' //Nom du dossier dans le dossier img/ de prestashop ( à créer au préalable )
        );

Et dans le formulaire d’édition de l’objet rajouter un champ du nom name ( ici image ) :

                // Champ Custom pour gérer une image via les méthode prestashop
                // Ce champ n'existe pas en base de données
                [
                    'type' => 'file',
                    'label' => $this->module->l('Image for sample'),
                    'name' => 'image', //Nom du champ renseigné dans $this->fieldImageSettings['name']
                    'hint' => $this->module->l('Image managed with prestashop admincontroller default behaviour')
                ],

L’image sera envoyée dans le dossier configuré sous la forme idObject.jpg
 

Options :

Les options sont définies dans la fonction __construct() du controller
Voici un code qui génère une grande partie des cas :

/**
         * Gestion des options
         * Lors de la sauvegarde des options, les clés des options sont enregistrée dans la table de configuration
         */
        $this->fields_options = [
            //Groupe d'option n 1
            'general' => [
                //Titre du groupe d'options
                'title' => $this->l('General configuration'),
                //Champs du group d'options
                'fields' => [
                    //Exemple option de type texte
                    'OPTION_KEY_TEXT' => [ //La clé du tableau correspond au nom de la configuration
                        'title' => $this->l('Field Text'),
                        'hint' => $this->l('Field Text Hint'),
                        'validation' => 'isWeightUnit', //Classe de validation ( de la classe Validate )
                        'required' => true, //Champ requis ou non
                        'type' => 'text', //Type de champ
                        'class' => 'fixed-width-sm' //classe css
                    ],
                    //Exemple option de type texte avec langue
                    'OPTION_KEY_TEXT_LANG' => [
                        'title' => $this->l('Field Text Lang'),
                        'hint' => $this->l('Field Text Lang Hint'),
                        'validation' => 'isWeightUnit',
                        'required' => true,
                        'type' => 'textLang', //Type de champ
                        'class' => 'fixed-width-sm'
                    ],
                    //Exemple option de type textarea
                    'OPTION_KEY_TEXTAREA' => [
                        'title' => $this->l('Field Textarea'),
                        'hint' => $this->l('Field Textarea Hint'),
                        'required' => true,
                        'type' => 'textarea',
                        'cols' => 150, //Champ requis Textarea
                        'rows' => 2 // Champ requis Textarea
                    ],
                    //Exemple option de type textarea lang
                    'OPTION_KEY_TEXTAREA_LANG' => [
                        'title' => $this->l('Field Textarea Lang'),
                        'hint' => $this->l('Field Textarea Hint'),
                        'required' => true,
                        'type' => 'textareaLang',
                        'cols' => 150, //Champ requis Textarea
                        'rows' => 2 // Champ requis Textarea
                    ],
                    //Exemple option de type textarea avec TinyMce
                    'OPTION_KEY_TEXTAREA_MCE' => [
                        'title' => $this->l('Field Textarea editor'),
                        'hint' => $this->l('Field Textarea editor Hint'),
                        'required' => true,
                        'type' => 'textarea',
                        'autoload_rte' => true ,//Flag pour afficher l'éditeur de texte
                        'cols' => 150, //Champ requis Textarea
                        'rows' => 2 // Champ requis Textarea
                    ],
                    //Exemple d'option de type "select"
                    'OPTION_KEY_SELECT' => [
                        'title' => $this->l('Sample select fields'),
                        'hint' => $this->l('This is a select field.'),
                        'cast' => 'intval', //Cast appliqué aux valeurs
                        'type' => 'select',
                        'identifier' => 'id_lang', //Champs requis select clé de l'identifiant
                        'list' => Language::getLanguages(false) //Champ requis select source des données
                    ],
                    //Exemple d'option de type boolean
                    'OPTION_KEY_BOOLEAN' => [
                        'title' => $this->l('Bolean Field'),
                        'hint' => $this->l('Bolean Field Hint'),
                        'validation' => 'isBool',
                        'cast' => 'intval',
                        'type' => 'bool',
                        'default' => '1' //Valeur défaut pour l'option boolean
                    ],
                    //Exemple d'option de type file
                    'OPTION_KEY_FILE' => [
                        'title' => $this->l('File Field'),
                        'hint' => $this->l('File Field Hint'),
                        'type' => 'file',
                        'name' => 'OPTION_KEY_FILE' //Champ requis file
                    ],
                    //Exemple d'option de type file avec un thumb
                    'OPTION_KEY_THUMB' => [
                        'title' => $this->l('Thumb Field'),
                        'hint' => $this->l('Thumb Field Hint'),
                        'type' => 'file',
                        'name' => 'OPTION_KEY_FILE',
                        'thumb' => 'https://upload.wikimedia.org/wikipedia/commons/e/ee/Thumbup.jpg' //Champ requis thumb
                    ],
                    //Exemple d'option de type color
                    'OPTION_KEY_COLOR' => [
                        'title' => $this->l('Color Field'),
                        'hint' => $this->l('Color Field Hint'),
                        'validation' => 'isColor',
                        'type' => 'color',
                        'name' => 'OPTION_KEY_COLOR', // Champs requis Color
                        'size' => 7, //CHamps requis Color
                    ],
 
                ],
                //Bouton de soumission
                'submit' => ['title' => $this->l('Save')]
            ],
            //Groupe d'option n'2
            'localization' => [
                'title' => $this->l('Option bloc 2'),
                'icon' => 'icon-globe',
                'fields' => [
                    'OPTION_KEY_TEXT_2' => [
                        'title' => $this->l('Field Text'),
                        'hint' => $this->l('Field Text Hint'),
                        'validation' => 'isWeightUnit',
                        'required' => true,
                        'type' => 'text',
                        'class' => 'fixed-width-sm'
                    ],
                ],
                'submit' => ['title' => $this->l('Save')]
            ],
        ];

Le rendu sera ensuite le suivant :

1er bloc d’options :

2 ème bloc d’options :

L’avancée de l’article est en cours, n’hésitez pas à partager vos astuces également.