En complément d’un de mes précédents articles sur comment ajouter des nouveaux champs dans le listing des produits ( pour prestashop 1.7 ), nous allons voir comment effectuer cette action sur les autres controllers de l’administration.

Les listing des controllers concernés sont ceux qui utilisent encore l’ancienne infrastructure et les anciennes méthodes ( Clients, adresses, commandes , employés … )

Ce tutoriel fonctionne à partir de la version 1.6.0.2 de Prestashop et utilise le hook dynamique action.$this->controller_name.ListingFieldsModifier

Pour les versions inférieures il sera nécessaire de faire un override du controller concerné et d’ajouter les informations directement à la suite des paramètres de classe
$this->_select,
$this->_join,
$this->_where

Exécuté par via le code suivant dans la fonction getList de la classe AdminController

Hook::exec('action'.$this->controller_name.'ListingFieldsModifier', array(
'select' => &$this->_select,
'join' => &$this->_join,
'where' => &$this->_where,
'group_by' => &$this->_group,
'order_by' => &$this->_orderBy,
'order_way' => &$this->_orderWay,
'fields' => &$this->fields_list,
));

Les paramètres sont passés par référence au hook ce qui permets de modifier directement les variables qui seront appellées depuis un module.

Les éléments select, join, where, group_by, order_by , order_way permettent de modifier la requête de récupération de la liste des entités.
Alors que le champ fields est un tableau qui regroupe l’ensemble des colonnes qui seront affichées dans la liste.

Pour tester tout cela nous allons faire un module hh_admin dont le but sera le suivant :

– Ajouter 2 nouvelles colonnes dans le listing des clients et supprimer 2 existants :

Le module devra donc implémenter le hook suivant :

  • actionAdminCustomersListingFieldsModifier

Pour modifier le listing client le contenu sera le suivant :

    /**
     * Ajout de champs dans le listing des clients
     * @param type $params
     */
    public function hookActionAdminCustomersListingFieldsModifier($params)
    {
        //Pour l'exemple on va ajouter 2 champs dans le listing
 
        // champ simple texte : date d'inscription à la newsletter ( newsletter_date_add dans la table customer )
        $params['fields']['newsletter_date_add'] = array(
            'title' => $this->l('Date souscription Newsletter')
        );
 
        //Champ un peu plus "complexe" groupe par défaut  select ( id_default_group dans la table customer et récupération des noms des groupes via une jointure )
        $params['select'] .= ' ,grl.name as default_group_name '; //Ajout du champ dans la requête select
        $params['join'] .= 'LEFT JOIN '._DB_PREFIX_.'group_lang grl ON (a.id_default_group = grl.id_group )'; //Jointure avec la table des groupes
 
	//Récupération de la liste des groupes via la méthode prestashop + création d'un tableau sous la forme id_group => name 
	$groups = Group::getGroups($this->context->language->id); 
        $groupsList = array();
        foreach( $groups as $group)
            $groupsList[$group['id_group']] = $group['name'];
 
        //Ajout du nouveau champ à afficher dans le listing
        $params['fields']['default_group_name'] = array(
            'title' => $this->l('Groupe par défaut'),
            'type' => 'select',
            'list' => $groupsList,
            'filter_key' => 'a!id_default_group' //Clé de filtrage dans la requête sous la forme "NomTable!champ"  
        );
 
	//Suppression des champs "Titre","Optin"
        unset($params['fields']['title']);
        unset($params['fields']['optin']);
    }

Une fois le code implémenté nous voyons bien nos 2 nouvelles colonnes dans la liste et les 2 anciennes ont bien disparu.
Tout est fonctionnel sans la moindre surcharge 🙂



Bonus :
Une demande récurrente est également de pouvoir placer les nouveaux champs à un autre endroit qu’a la fin.

Pour cela j’ai créé la fonction suivante :

    /**
     * Ajout du nouveau champ après un autre 
     * @param type $fieldParams
     * @param type $afertName
     * @param type $fieldsArray
     */
    public function addNewFieldAfter($fieldParams,$afterName,array &$fieldsArray)
    {
 
        if (array_key_exists($afterName, $fieldsArray)) {
            $pos = array_search($afterName, array_keys($fieldsArray));
            $before = array_slice($fieldsArray,0,$pos+1);
            $after = array_slice($fieldsArray, $pos); 
            $fieldsArray = array_merge($before,$fieldParams,$after);
 
        } else {
            $fieldsArray = array_merge($fieldsArray,$fieldParams);
        }
    }

Il est possible de l’utiliser de cette manière :

 /**
     * Ajout de champs dans le listing des clients
     * @param type $params
     */
    public function hookActionAdminCustomersListingFieldsModifier($params)
    {
 
        $newField = array( 'default_group_name' => 
		array(
            'title' => $this->l('Groupe par défaut'),
            'type' => 'select',
            'list' => $groupsList,
            'filter_key' => 'a!id_default_group' //Clé de filtrage dans la requête sous la forme "NomTable!champ" 
            )
        );
 
        $this->addNewFieldAfter($newField, 'lastname', $params['fields']);
 
    }

Voici le code code complet du module :

<?php
class HhAdmin extends Module {
 
    public function __construct() {
        $this->name = 'hhadmin';
        $this->tab = 'others';
        $this->author = 'hhennes';
        $this->version = '0.1.0';
        $this->need_instance = 0;
        $this->bootstrap = true;
 
        parent::__construct();
 
        $this->displayName = $this->l('hhadmin');
        $this->description = $this->l('hhadmin description');
        $this->ps_versions_compliancy = array('min' => '1.7.0', 'max' => _PS_VERSION_);
    }
 
    /**
     * @return boolean
     */
    public function install() {
        if (!parent::install() 
                || !$this->registerHook('actionAdminCustomersListingFieldsModifier')      
        ) {
            return false;
        }
 
        return true;
    }
 
    /**
     * Ajout de champs dans le listing des clients
     * @param type $params
     */
    public function hookActionAdminCustomersListingFieldsModifier($params)
    {
        //Pour l'exemple on va ajouter 2 champs dans le listing
 
 
        // champ simple texte : date d'inscription à la newsletter ( dans la table customer )
        $params['fields']['newsletter_date_add'] = array(
            'title' => $this->l('Newsletter subscribe date')
        );
 
        //Champ un peu plus "complexe" groupe par défaut  select ( id_default_group dans la table customer 
        //et récupération des noms des groupes via une jointure )
        $params['select'] .= ' ,grl.name as default_group_name '; //Ajout du champ dans la requête select
        $params['join'] .= 'LEFT JOIN '._DB_PREFIX_.'group_lang grl ON (a.id_default_group = grl.id_group )'; //Jointure avec la table des groupes
        $groups = Group::getGroups($this->context->language->id); //Récupération de la liste des groupes
 
        $groupsList = array();
        foreach( $groups as $group)
            $groupsList[$group['id_group']] = $group['name'];
 
       //Affichage du nouveau champ ( méthode standard)
        /*$params['fields']['default_group_name'] = array(
            'title' => $this->l('Groupe par défaut'),
            'type' => 'select',
            'list' => $groupsList,
            'filter_key' => 'a!id_default_group' //Clé de filtrage dans la requête sous la forme "NomTable!champ"  
        );*/
 
		//Ajout du nouveau champ dans une certaine position
        $newField = array( 'default_group_name' => array(
            'title' => $this->l('Groupe par défaut'),
            'type' => 'select',
            'list' => $groupsList,
            'filter_key' => 'a!id_default_group' //Clé de filtrage dans la requête sous la forme "NomTable!champ" 
            )
        );
        $this->addNewFieldAfter($newField, 'lastname', $params['fields']);
    }
 
	 /**
     * Ajout du nouveau champ après
     * @param type $fieldParams
     * @param type $afertName
     * @param type $fieldsArray
     */
    public function addNewFieldAfter($fieldParams,$afterName,array &$fieldsArray)
    {
 
        if (array_key_exists($afterName, $fieldsArray)) {
            $pos = array_search($afterName, array_keys($fieldsArray));
            $before = array_slice($fieldsArray,0,$pos+1);
            $after = array_slice($fieldsArray, $pos); 
            $fieldsArray = array_merge($before,$fieldParams,$after);
 
        } else {
            $fieldsArray = array_merge($fieldsArray,$fieldParams);
        }
    }
}