Nous allons voir les différentes étapes pour réaliser facilement un controller admin basique lié à un module Prestashop.
Puis nous verrons ensuite les caractéristiques de base d’un controller admin, cet article sera complété par un autre pour voir les fonctionnalités avancées 😉

Pour cela nous allons créer un module “samplemodule”.
Le code complet est visible sur github : https://github.com/nenes25/prestashop_samplemodule/tree/admin

Les prérequis suivants sont nécessaires pour réaliser un controller admin pour votre module :

  • Création d’une “Tab”
  • Utilisation d’un objet Prestashop héritant de la classe ObjectModel ( et de la base de données qui lui est associée )

Pour l’objet Prestashop nous partirons sur un objet fictif “Sample” avec les propriétés suivantes :

  • name : nom de l’objet
  • code : code de l’objet
  • email : email de l’objet
  • title : titre de l’objet ( différent en fonction de la langue )
  • description : description de l’objet ( différent en fonction de la langue )

Le code suivant sera dans le fichier classes/Sample.php du module

class Sample extends ObjectModel
{
 
    public $id;
    public $name;
    public $code;
    public $email;
    public $title;
    public $description;
 
    public static $definition = [
        'table' => 'hh_sample',
        'primary' => 'id_sample',
        'multilang' => true,
        'fields' => [
            // Champs Standards
            'name' => ['type' => self::TYPE_STRING, 'validate' => 'isName', 'size' => 255, 'required' => true],
            'code' => ['type' => self::TYPE_STRING, 'validate' => 'isLinkRewrite', 'size' => 255, 'required' => true],
            'email' => ['type' => self::TYPE_STRING, 'validate' => 'isEmail', 'size' => 255, 'required' => true],
            //Champs langue
            'title' => ['type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml', 'size' => 255,],
            'description' => ['type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml',],
        ],
    ];
}

 

Pour la création de la tab et de la base de donnée c’est le module qui se charge de gérer tout cela lors de son installation.

//Inclusion du modèle Sample
require_once _PS_MODULE_DIR_ . '/samplemodule/classes/Sample.php';
 
class SampleModule extends Module
{
    public function __construct()
    {
        $this->author = 'hhennes';
        $this->name = 'samplemodule';
        $this->tab = 'hhennes';
        $this->version = '0.1.1';
        $this->need_instance = 0;
 
        parent::__construct();
 
        $this->displayName = $this->l('Prestashop sample Module');
        $this->description = $this->l('Prestashop sample Module with front controller');
    }
 
    /**
     * Installation du module
     * @return boolean
     */
    public function install()
    {
        return parent::install() && $this->_installSql() && $this->_installTab();
    }
 
    /**
     * Désinstallation du module
     * @return boolean
     */
    public function uninstall()
    {
        return parent::uninstall() && $this->_uninstallSql() && $this->_uninstallTab();
    }
 
    /**
     * Création de la base de donnée
     * @return boolean
     */
    protected function _installSql()
    {
        $sqlCreate = "CREATE TABLE `" . _DB_PREFIX_ . Sample::$definition['table'] . "` (
                `id_sample` int(11) unsigned NOT NULL AUTO_INCREMENT,
                `name` varchar(255) DEFAULT NULL,
                `code` varchar(255) DEFAULT NULL,
                `email` varchar(255) DEFAULT NULL,
                `date_add` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
                `date_upd` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
                PRIMARY KEY (`id_sample`)
                ) ENGINE=InnoDB DEFAULT CHARSET=latin1;";
 
        $sqlCreateLang = "CREATE TABLE `" . _DB_PREFIX_ . Sample::$definition['table'] . "_lang` (
              `id_sample` int(11) unsigned NOT NULL AUTO_INCREMENT,
              `id_lang` int(11) NOT NULL,
              `title` varchar(255) DEFAULT NULL,
              `description` text,
              PRIMARY KEY (`id_sample`,`id_lang`)
            ) ENGINE=InnoDB DEFAULT CHARSET=latin1;";
 
        return Db::getInstance()->execute($sqlCreate) && Db::getInstance()->execute($sqlCreateLang);
    }
 
    /**
     * Installation du controller dans le backoffice
     * @return boolean
     */
    protected function _installTab()
    {
        $tab = new Tab();
        $tab->class_name = 'AdminHhSample';
        $tab->module = $this->name;
        $tab->id_parent = (int)Tab::getIdFromClassName('DEFAULT');
        $tab->icon = 'settings_applications';
        $languages = Language::getLanguages();
        foreach ($languages as $lang) {
            $tab->name[$lang['id_lang']] = $this->l('HH Sample Admin controller');
        }
        try {
            $tab->save();
        } catch (Exception $e) {
            echo $e->getMessage();
            return false;
        }
 
        return true;
    }
 
    /**
     * Désinstallation du controller admin
     * @return boolean
     */
    protected function _uninstallTab()
    {
        $idTab = (int)Tab::getIdFromClassName('AdminHhSample');
        if ($idTab) {
            $tab = new Tab($idTab);
            try {
                $tab->delete();
            } catch (Exception $e) {
                echo $e->getMessage();
                return false;
            }
        }
        return true;
    }
 
    /**
     * Suppression de la base de données
     */
    protected function _uninstallSql()
    {
        $sql = "DROP TABLE ". _DB_PREFIX_ .Sample::$definition['table'].",". _DB_PREFIX_ .Sample::$definition['table']."_lang";
        return Db::getInstance()->execute($sql);
    }
}

Création du controller admin

Celui-ci doit être créé dans le dossier /controllers/admin/ de votre module.
Pour l’exemple celui-ci se nommera AdminHhSample et le fichier AdminHhSample.php

Je rappelle que les fonctions basiques d’un controller admin dans le cadre d’un module sont :

  • d’afficher une liste d’objets Prestashop
  • d’ajouter et d’éditer ces objets

Voici le code basique de ce fichier

require_once _PS_MODULE_DIR_ . '/samplemodule/classes/Sample.php';
class AdminHhSampleController extends ModuleAdminController
{
}

Le nom de classe du controller est nomdufichierController et il doit étendre la classe ModuleAdminController
Dans celui-ci on inclus également le fichier php contenant la classe de l’objet que nous allons gérer.

 

Liste des objets :

La fonction par défaut du controller est d’afficher une liste des objets.
Pour cela il faut renseigner toutes les informations nécessaires dans la fonction __construct() de la classe
J’ai commenté les différents paramètres pour expliquer leur fonctionnement.

A noter que les champs $this->fields_list sont ensuite utilisés dans une liste généré via la classe HelperList, si vous souhaitez visualiser toutes les possibilités.

   /**
     * Instanciation de la classe
     * Définition des paramètres basiques obligatoires
     */
    public function __construct()
    {
        $this->bootstrap = true; //Gestion de l'affichage en mode bootstrap 
        $this->table = Sample::$definition['table']; //Table de l'objet
        $this->identifier = Sample::$definition['primary']; //Clé primaire de l'objet
        $this->className = Sample::class; //Classe de l'objet
        $this->lang = true; //Flag pour dire si utilisation de langues ou non
 
        //Appel de la fonction parente pour pouvoir utiliser la traduction ensuite
        parent::__construct();
 
        //Liste des champs de l'objet à afficher dans la liste
        $this->fields_list = [
            'id_sample' => [ //nom du champ sql
                'title' => $this->module->l('ID'), //Titre
                'align' => 'center', // Alignement
                'class' => 'fixed-width-xs' //classe css de l'élément
            ],
            'name' => [
                'title' => $this->module->l('name'),
                'align' => 'left',
            ],
            'code' => [
                'title' => $this->module->l('code'),
                'align' => 'left',
            ],
            'email' => [
                'title' => $this->module->l('email'),
                'align' => 'left',
            ],
            'title' => [
                'title' => $this->module->l('title'),
                'lang' => true, //Flag pour dire d'utiliser la langue
                'align' => 'left',
            ]
        ];
 
        //Ajout d'actions sur chaque ligne
        $this->addRowAction('edit');
        $this->addRowAction('delete');
    }

Avec ce code nous aurons l’affichage suivant :

blog listing admin

Ajout / Édition d’un objet

Pour l’ajout ou l’édition d’un objet le controller doit implémenter la fonction renderForm avec le contenu suivant :
Pour voir l’ensemble des champs possibles vous pouvez visualiser le controller natif de AdminPatterns via l’url : http://www.votre-site/admin/index.php?controller=AdminPatterns

/**
     * Affichage du formulaire d'ajout / création de l'objet
     * @return string
     * @throws SmartyException
     */
    public function renderForm()
    {
        //Définition du formulaire d'édition
        $this->fields_form = [
            //Entête
            'legend' => [
                'title' => $this->module->l('Edit Sample'),
                'icon' => 'icon-cog'
            ],
            //Champs
            'input' => [
                [
                    'type' => 'text', //Type de champ
                    'label' => $this->module->l('name'), //Label
                    'name' => 'name', //Nom
                    'class' => 'input fixed-width-sm', //classes css
                    'size' => 50, //longueur maximale du champ
                    'required' => true, //Requis ou non
                    'empty_message' => $this->l('Please fill the postcode'), //Message d'erreur si vide
                    'hint' => $this->module->l('Enter sample name') //Indication complémentaires de saisie
                ],
                [
                    'type' => 'text',
                    'label' => $this->module->l('code'),
                    'name' => 'code',
                    'class' => 'input fixed-width-sm',
                    'size' => 5,
                    'required' => true,
                    'empty_message' => $this->module->l('Please fill the code'),
                ],
                [
                    'type' => 'text',
                    'label' => $this->module->l('email'),
                    'name' => 'email',
                    'class' => 'input fixed-width-sm',
                    'size' => 5,
                    'required' => true,
                    'empty_message' => $this->module->l('Please fill email'),
                ],
                [
                    'type' => 'text',
                    'label' => $this->module->l('Title'),
                    'name' => 'title',
                    'class' => 'input fixed-width-sm',
                    'lang' => true, //Flag pour utilisation des langues
                    'required' => true,
                    'empty_message' => $this->l('Please fill the title'),
                ],
                [
                    'type' => 'textarea',
                    'label' => $this->module->l('Description'),
                    'name' => 'description',
                    'lang' => true,
                    'autoload_rte' => true, //Flag pour éditeur Wysiwyg
                ],
            ],
            //Boutton de soumission
            'submit' => [
                'title' => $this->l('Save'), //On garde volontairement la traduction de l'admin par défaut
            ]
        ];
        return parent::renderForm();
    }

Le rendu sera ensuite le suivant :

Blog édition sample

 

Avec ces 2 éléments vous avez à présent un controller admin fonctionnel pour votre module qui permet de gérer facilement votre entité Prestashop 🙂

Bonus : Un bouton d’ajout dans la toolbar

Le bouton d’ajout d’un élément est relativement petit par défaut, voici comment un ajouter un plus visible
Ajouter la fonction initPageHeaderToolbar() dans votre controller avec le contenu suivant :

  /**
     * Gestion de la toolbar
     */
    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('Add new Sample'),
            'icon' => 'process-icon-new'
        );
 
        parent::initPageHeaderToolbar();
    }