Ajouter une colonne dans une liste de la partie administration avec filtre et comptage réel dans Prestashop 1.7.8 +
Dans certains cas, il est nécessaire d’ajouter une colonne dans une liste de l’administration de Prestashop pour effectuer une action spéciale ou filtrer / trier par cette colonne.
Petite modification depuis la publication, j’ai validé ce fonctionnement sur un PS 1.7.8.
Prenons un exemple concret :
Nous souhaitons pouvoir trier les commandes par transporteur afin d’effectuer une tâche groupée.
Contraintes :
- Nous devons altérer les données issues de la requête pour prendre en charge le champs ajouté.
- Les données sont sélectionnées directement dans le SRC (donc non surchargeable), la réalisation d’un module est nécessaire.
La mise en place d’un module ne sera pas détaillée ici, le but de ce billet est uniquement d’expliquer la marche à suivre ainsi que les hooks à mettre en place et leur fonctionnement.
Pré-requis déclarer l’utilisation de certaines classes de SRC :
use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn;
use PrestaShop\PrestaShop\Core\Grid\Filter\Filter;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
Sinon votre code ne fonctionnera pas, cependant un message d’erreur explicite vous aidera dans ce cas.
Première étape, déclarer les hooks à utiliser dans votre module, vous pouvez le faire où bon vous semble, pour ma part j’ai dans tous mes modules une méthode qui s’appelle _checkSystem qui est vérifiée dans le constructeur et qui va comparer la version en base du module et celle du fichier en cours, si cette dernière est inférieure, alors l’action est exécutée et la version mise à jour :
/**
* Check system
*
* @return void
*/
private function _checkSystem()
{
// Only if installed
if (Module::isInstalled('aitoto')) {
// Version 0.1.1 compatibility
if (Configuration::get('AIPRONATUR_VERSION') === false || Tools::version_compare(Configuration::get('AIPRONATUR_VERSION'), '0.2.1')) {
$this->registerHook(
[
'actionOrderGridDefinitionModifier',
'actionOrderGridQueryBuilderModifier',
]
);
}
// Set new version
Configuration::updateValue('AITOTO_VERSION', $this->version);
}
}
Ici les deux hooks nécessaires sont enregistrés, le module sera donc appelé si besoin.
A noter pour cette partie que Prestashop a défini la possibilité d’utiliser des hooks en fonction des classes action [ClassName] GridDefinitionModifier pour la partie modification visuelle et action [ClassName] GridQueryBuilderModifier pour la modification des données collectées.
Pour notre cas, il s’agit de la classe Order, les hooks appelés sont donc actionOrderGridDefinitionModifier et actionOrderGridQueryBuilderModifier.
Deuxième étape, la modification de l’affichage de la grille, ajout d’un champs et de ses valeurs de filtre :
public function hookActionOrderGridDefinitionModifier($params)
{
// Add column definition
$definition = $params['definition'];
$definition
->getColumns()
->addAfter(
'payment',
(new DataColumn('carrier_name'))
->setName($this->l('Carrier'))
->setOptions(
[
'field' => 'carrier_name',
]
)
);
// Add filter choices
$choices = [];
$carriers = Carrier::getCarriers(1, false, false, false, null, Carrier::CARRIERS_MODULE);
foreach ($carriers as $carrier) {
$choices[$carrier['name']] = (int)$carrier['id_carrier'];
}
// For search filter dropdown
$definition->getFilters()->add(
(new Filter('carrier', ChoiceType::class))
->setTypeOptions([
'required' => false,
'choices' => $choices, // This key added to show dropdown in search options
])
->setAssociatedColumn('carrier_name')
);
}
Dans cette partie nous indiquons au moteur d’ajouter une colonne carrier_name, et que ses valeurs de filtre sont tous les transporteurs qui dépendent d’un module (Carrier::CARRIERS_MODULE), plusieurs autres valeurs sont possibles, pour cela se référer à la signature de la méthode présente dans github.
Troisième étape, la modification de la requête de sélection et de la gestion du filtre :
public function hookActionOrderGridQueryBuilderModifier($params)
{
// Get all parts to update
$searchQueryBuilder = $params['search_query_builder'];
$searchCriteria = $params['search_criteria'];
$countQueryBuilder = $params['count_query_builder'];
// Alter search query builder to get the new field
$searchQueryBuilder->addSelect(
'carrier.name AS carrier_name'
);
$searchQueryBuilder->leftJoin(
'o',
'`' . pSQL(_DB_PREFIX_) . 'carrier`',
'carrier',
'carrier.`id_carrier` = o.`id_carrier`'
);
// Alter count query builder to get the real counting values
$countQueryBuilder->addSelect(
'carrier.name AS carrier_name'
);
$countQueryBuilder->leftJoin(
'o',
'`' . pSQL(_DB_PREFIX_) . 'carrier`',
'carrier',
'carrier.`id_carrier` = o.`id_carrier`'
);
// Alter filter if needed (if carrier filter) for both search and count
foreach ($searchCriteria->getFilters() as $filterName => $filterValue) {
if ('carrier' === $filterName) {
$searchQueryBuilder->andWhere('carrier.`id_carrier` = :carrier');
$searchQueryBuilder->setParameter('carrier', $filterValue);
if (!$filterValue) {
$searchQueryBuilder->orWhere('carrier.`id_carrier` IS NULL');
}
$countQueryBuilder->andWhere('carrier.`id_carrier` = :carrier');
$countQueryBuilder->setParameter('carrier', $filterValue);
if (!$filterValue) {
$countQueryBuilder->orWhere('carrier.`id_carrier` IS NULL');
}
}
}
}
A partir de là votre nouvelle colonne sera affichée, ainsi que son filtre et toute modification de filtre affichera les bonnes commandes :
Sans filtre :

Avec filtre :

C’est terminé pour ce billet, comme d’habitude, il existe sans doute d’autres méthodes, mais celle ci fonctionne et permet d’arriver à ses fins sans trop de difficulté.