N'hésitez pas à me le signaler si nécessaire via le formulaire de contact.
J’ai récemment fait face à un problème, car je souhaitais remontée un champ produit spécifique dans les informations du panier sur prestashop 1.7
( La modification décrite fonctionne également sur prestashop 1.6.1.x )
Après analyse, il s’avère que les informations disponibles sont remontées depuis la fonction getProducts de la classe Cart.
L’ensemble des champs remontés sont listé dans la requête sql de remontée des produits, et il n’est pas possible de récupérer nos nouveaux champs.
// Build query $sql = new DbQuery(); // Build SELECT $sql->select('cp.`id_product_attribute`, cp.`id_product`, cp.`quantity` AS cart_quantity, cp.id_shop, cp.`id_customization`, pl.`name`, p.`is_virtual`, pl.`description_short`, pl.`available_now`, pl.`available_later`, product_shop.`id_category_default`, p.`id_supplier`, p.`id_manufacturer`, m.`name` AS manufacturer_name, product_shop.`on_sale`, product_shop.`ecotax`, product_shop.`additional_shipping_cost`, product_shop.`available_for_order`, product_shop.`show_price`, product_shop.`price`, product_shop.`active`, product_shop.`unity`, product_shop.`unit_price_ratio`, stock.`quantity` AS quantity_available, p.`width`, p.`height`, p.`depth`, stock.`out_of_stock`, p.`weight`, p.`available_date`, p.`date_add`, p.`date_upd`, IFNULL(stock.quantity, 0) as quantity, pl.`link_rewrite`, cl.`link_rewrite` AS category, CONCAT(LPAD(cp.`id_product`, 10, 0), LPAD(IFNULL(cp.`id_product_attribute`, 0), 10, 0), IFNULL(cp.`id_address_delivery`, 0), IFNULL(cp.`id_customization`, 0)) AS unique_id, cp.id_address_delivery, product_shop.advanced_stock_management, ps.product_supplier_reference supplier_reference'); // Build FROM $sql->from('cart_product', 'cp'); ... |
Vous pouvez consulter le fichier complet ici : https://github.com/PrestaShop/PrestaShop/blob/1.7.3.x/classes/Cart.php#605
La bonne nouvelle c’est que la requête est effectuée via un objet Dbquery, ce qui va nous permettre d’interférer assez facilement avec la requête.
Pour ajouter une fonctionnalité de modification de cette requête nous allons donc créer une surcharge de la classe Cart qui va reprendre la function getProducts de la classe parente et rajouter le contenu suivant :
// Nouveau hook pour pouvoir modifier la requête de récupération des produits Hook::exec('actionCartGetProductsSqlQuery',['query' => &$sql]); |
juste avant l’exécution de la requête dans la ligne
$result = Db::getInstance()->executeS($sql); |
Via ce hook nouvellement créé auquel l’instance de l’objet DqQuery est passé en paramètre, il est à présent possible de faire un peu prêt tout sur cette requête.
La variable étant passée par référence, les modifications sur la requête sont appliquées directement.
Pour ajouter un champ il suffira donc de créer un module et de le greffer sur le hook actionCartGetProductsSqlQuery
/** * Nouveau Hook pour modifier la requête de sélection des produits du panier * Cf. override du cart * @param array $params => 'query' => &DbQuery */ public function hookActionCartGetProductsSqlQuery($params) { $params['query']->select('p.marque'); } |
Gentil Hervé,
J’ai besoin de récupérer les données enregistrés dans le module ‘virement bancaire’ et les afficher dans une facture électronique crée par mon module.
Pouvez-vous m’aider? Merci
Davide
Bonjour Hervé,
j’ai 2 problèmes avec cette technique:
1/ j’ai tout bien suivi l’article, mais quand je dump la variable $sql, mon champ personnalisé ne remonte pas…
2/ quand j’ajoute mon champ directement dans la requête, cette fois si il remonte bien dans le dump, mais malgré tout, pas moyen de l’afficher dans le panier, il considère qu’il n’existe pas. Je suppose qu’il s’agit d’un problème avec les LazyArray mais je ne vois pas comment corriger ça (version de prestashop : 1.7.5.1)
Merci !
Rebonjour,
pour le point 1, c’est résolu, c’était bêtement un problème de multiboutique (j’avais réinitialisé le module sur la mauvaise boutique)
Bonjour Agnès,
Cet article a été écrit lors de la version 1.7.3 de Prestashop
Il est possible que les modifications ultérieures fassent que ce ne soit plus fonctionnel sur la dernière version.
Je n’ai pas encore eut l’occasion de le tester.
Cordialement,
Hervé
Bonjour Hervé,
après avoir fouillé partout, a priori il faut ajouter le champ en question dans la variable $whitelist dans la fonction __construct du fichier src/Core/Filter/FrontEndObject/ProductFilter.php
Pas très propre, mais au moins ça fonctionne…
Bonjour Agnès,
Super merci pour votre retour et votre analyse !
En cherchant sur le blog Prestashop j’ai trouvé cet article qui propose une approche pour gérer les whitelist
http://build.prestashop.com/news/exposing-data-with-confidence/
Je vais la tester et voir si elle fonctionne 🙂