A la suite de mon précédent article sur comment ajouter des champs produits dans l’administration de prestashop 1.7 : https://www.h-hennes.fr/blog/2017/10/19/prestashop-1-7-ajouter-des-champs-produit/ , nous allons à présent voir comment ajouter des champs dans le listing des produits de l’administration.

Cette page est gérée via les nouveaux controllers symfony et leur fonctionnement est donc différents des autres listing de l’administration.

Je précise tout de suite, à date d’aujourd’hui et avec la version 1.7.2.x et inférieur il n’est pas possible de réaliser cette modification sans toucher à des fichiers « coeur » puisque la surcharge des templates symfony n’est pas encore gérée via les modules ( c’est en cours d’implémentation pour les versions suivantes, je mettrais à jour mon article en conséquence )

Pour autant la solution que je propose reste assez propre les seules lignes qui seront ajoutées le seront pour ajouter un appel de hook.

Je ne détaille pas la base de la création du module qui pourra reprendre celle de l’article sur la création des champs produits.

Le module devra implémenter les hooks suivants :

  • actionAdminProductsListingFieldsModifier (hook natif )
  • displayAdminCatalogTwigListingProductFields ( hook custom)
  • displayAdminCatalogTwigProductFilter ( hook custom )
  • displayAdminCatalogTwigProductHeader ( hook custom )

Pour l’exemple nous allons ajouter un filtre sur les marques des produits, mais la logique s’applique à n’importe quel champ.

Modification des fichiers twigs pour la création des nouveaux hooks

Les templates utilisés pour le listing des produits sont les suivants :

  • src\PrestaShopBundle\Resources\views\Admin\Product\catalog.html.twig
  • src\PrestaShopBundle\Resources\views\Admin\Product\list.html.twig

Dans catalog.html.twig :

Rajouter le code suivant :

 {# Hhennes Hook Custom pour afficher des colonnes supplémentaires #}
 {{ renderhook('displayAdminCatalogTwigProductHeader') }}

Après le code :

 <th>
 {{ "Category"|trans({}, 'Admin.Catalog.Feature') }}
 {% include 'PrestaShopBundle:Admin/Product/Include:catalog_order_carrets.html.twig' with {
 'column': 'name_category'
 } %}
 </th>

Rajouter le code suivant :

 {# Hhennes Hook Custom pour afficher des filtres supplémentaires #}
 {{ renderhook('displayAdminCatalogTwigProductFilter') }}

Après le code :

 <th>
 <input
 type="text"
 class="form-control"
 placeholder="{{ "Search category"|trans({}, 'Admin.Catalog.Help') }}"
 name="filter_column_name_category"
 value="{{ filter_column_name_category }}"
 />
 </th>

Dans list.html.twig :
Rajouter le code suivant :

 {# Hhennes Hook Custom pour afficher les nouveaux champs dans le listing #}
 {{ renderhook('displayAdminCatalogTwigListingProductFields', { 'product': product }) }}

Après le code :

 <td>
 {{ product.name_category|default('') }} 
 </td>

Affichage des nouveaux champs via les hooks du fichier twig

Nos nouveaux hooks étant maintenant créé il est temps d’ajouter nos champs via les hooks du module :

hook displayAdminCatalogTwigProductHeader : Affichage de l’entête de la colonne

 /**
 * Hook personnalisé ( non core ) pour afficher le header product
 * cf. src\PrestaShopBundle\Resources\views\Admin\Product\catalog.html.twig
 * @param type $params
 */
 public function hookDisplayAdminCatalogTwigProductHeader($params)
 {
 return $this->display(__FILE__,'views/templates/hook/displayAdminCatalogTwigProductHeader.tpl'); 
 }

Contenu du fichier displayAdminCatalogTwigProductHeader.tpl :

 <th>{l s='Manufacturer' mod='hhproduct'}</th>

 

hook displayAdminCatalogTwigProductFilter : Affichage du champ html du filtre

 /**
 * Hook personnalisé ( non core ) pour afficher le filter product
 * cf. src\PrestaShopBundle\Resources\views\Admin\Product\catalog.html.twig
 * @param type $param
 */
 public function hookDisplayAdminCatalogTwigProductFilter($params)
 {
 $manufacturers = Manufacturer::getManufacturers();
 $this->context->smarty->assign(
 [
 'filter_column_name_manufacturer' => Tools::getValue('filter_column_name_manufacturer',''),
 'manufacturers' => $manufacturers,
 ]
 );
 return $this->display(__FILE__,'views/templates/hook/displayAdminCatalogTwigProductFilter.tpl');
 }

Contenu du fichier displayAdminCatalogTwigProductFilter.tpl :

 <th>
 <select name="filter_column_name_manufacturer" data-toggle="select2">
 <option value="">{l s='Manufacturer' mod='hhproduct'}</option>
 {foreach from=$manufacturers item=manufacturer}
 <option value="{$manufacturer.id_manufacturer}" 
 {if $filter_column_name_manufacturer == $manufacturer.id_manufacturer} selected="selected"{/if}>
 {$manufacturer.name}
 </option>
 {/foreach}
 </select>
</th>

 

hook displayAdminCatalogTwigListingProductFields : Affichage de la valeur du champ pour chaque produit

 /**
 * Hook personnalisé (non core) pour afficher les informations additionnelles produits )
 * cf. src\PrestaShopBundle\Resources\views\Admin\Product\list.html.twig
 * @param type $params
 */
 public function hookDisplayAdminCatalogTwigListingProductFields($params)
 {
 $this->context->smarty->assign('product',$params['product']);
 return $this->display(__FILE__,'views/templates/hook/displayAdminCatalogTwigListingProductFields.tpl');
 }

Contenu du fichier displayAdminCatalogTwigListingProductFields.tpl :

 <td>{$product.manufacturer}</td>

 

Avec ces codes nous devrions à présent obtenir l’affichage suivant :

Prestashop produt fields

C’est bien joli mais il n’y a pas de données 😉

 

Affichage et filtrage des résultats

Pour remonter ces données la bonne nouvelle c’est que le hooks natif de prestashop 1.6 fonctionne encore !
Dans le fichier \src\Adapter\Product\AdminProductDataProvider.php, le hook actionAdminProductsListingFieldsModifier est toujours appellé.
Comme vous pouvez le voir ligne 280

 // exec legacy hook but with different parameters (retro-compat < 1.7 is broken here)
 \HookCore::exec('actionAdminProductsListingFieldsModifier', array(
 '_ps_version' => _PS_VERSION_,
 'sql_select' => &$sqlSelect,
 'sql_table' => &$sqlTable,
 'sql_where' => &$sqlWhere,
 'sql_order' => &$sqlOrder,
 'sql_limit' => &$sqlLimit,
 ));

Voici donc l’implémentation du hook dans notre module :

/**
* Modification de la requête de la liste
* @param type $params
*/
public function hookActionAdminProductsListingFieldsModifier($params)
{
/**
* Rajout du fabricant
*/
//Champ sql
$params['sql_select']['manufacturer'] = [
'table' => 'm',
'field' => 'name',
'filtering' => \PrestaShop\PrestaShop\Adapter\Admin\AbstractAdminQueryBuilder::FILTERING_LIKE_BOTH
];
//Table sql
$params['sql_table']['m'] = [
'table' => 'manufacturer',
'join' => 'LEFT JOIN',
'on' => 'p.`id_manufacturer` = m.`id_manufacturer`',
];
 
//Gestion du filtre, si un paramètre post est défini ( c'est le nom du champ dans le fichier displayAdminCatalogTwigProductFilter.tpl )
$manufacturer_filter = Tools::getValue('filter_column_name_manufacturer',false);
if ( $manufacturer_filter && $manufacturer_filter != '') {
$params['sql_where'][] .= "p.id_manufacturer =".$manufacturer_filter;
}
}

Voici donc comment rajouter et filtrer les résultats de l’attribut manufacturer 🙂

Et voici le rendu final, avec le filtre qui fonctionne :

Colonne manufacturer OK