Afficher le fabricant sur les meilleures ventes PrestaShop
Comment afficher le nom du fabricant (manufacturer) dans le module des meilleures ventes PrestaShop. Méthode complète avec modification SQL et template.
En bref : Pour afficher le fabricant dans le module meilleures ventes PrestaShop, créez un override de ProductSale::getBestSalesLight() ajoutant un LEFT JOIN sur ps_manufacturer, puis exploitez la variable manufacturer_name dans votre template Smarty.
Le problème : des meilleures ventes sans identité de marque
Le module des meilleures ventes de PrestaShop affiche par défaut le nom du produit, son prix et son image — mais pas le fabricant. C'est un manque important pour les boutiques multi-marques : le nom du fabricant est un facteur de réassurance et de décision d'achat majeur.
Voici comment ajouter cette information en comprenant la chaîne complète du code, de la requête SQL jusqu'au template.
Comprendre le flux de données du module
Avant de modifier quoi que ce soit, il faut tracer le parcours des données. C'est une compétence fondamentale en développement PrestaShop : chaque module suit un schéma similaire.
Étape 1 : identifier la méthode principale du module
Dans le module blockbestsellers (PrestaShop 1.6) ou ps_bestsellers (1.7+), la méthode getBestSellers() récupère les produits :
protected function getBestSellers($params)
{
if (Configuration::get('PS_CATALOG_MODE')) {
return false;
}
$result = ProductSale::getBestSalesLight(
(int) $params['cookie']->id_lang,
0,
(int) Configuration::get('PS_BLOCK_BESTSELLERS_TO_DISPLAY')
);
if (!$result) {
return Configuration::get('PS_BLOCK_BESTSELLERS_DISPLAY') ? [] : false;
}
// Enrichissement des données (prix, etc.)
$currency = new Currency($params['cookie']->id_currency);
$usetax = (Product::getTaxCalculationMethod((int) $this->context->customer->id) != PS_TAX_EXC);
foreach ($result as &$row) {
$row['price'] = Tools::displayPrice(
Product::getPriceStatic((int) $row['id_product'], $usetax),
$currency
);
}
return $result;
}
Le point clé ici : les données produit proviennent de ProductSale::getBestSalesLight(). C'est cette méthode qu'il faut enrichir.
Étape 2 : analyser la requête SQL source
Dans classes/ProductSale.php, la méthode getBestSalesLight() exécute une requête SQL qui sélectionne les colonnes de base du produit. Par défaut, elle ne joint pas la table manufacturer.
Voici la requête d'origine simplifiée :
SELECT p.id_product, pl.name, p.id_manufacturer, /* ... */
FROM ps_product p
LEFT JOIN ps_product_lang pl ON (p.id_product = pl.id_product)
INNER JOIN ps_product_sale ps ON (p.id_product = ps.id_product)
WHERE pl.id_lang = {id_lang}
ORDER BY ps.quantity DESC
La colonne p.id_manufacturer est parfois présente, mais le nom du fabricant n'est jamais récupéré car il n'y a pas de jointure sur la table ps_manufacturer_lang.
Solution : override de ProductSale
La bonne pratique PrestaShop est de ne jamais modifier les fichiers core. On utilise le système d'override.
Créer l'override
Créez le fichier override/classes/ProductSale.php :
<?php
/**
* @author Alexandre Carette <contact@alexandrecarette.fr>
* @copyright 2026 Alexandre Carette
* @license Propriétaire et Confidentiel
*/
class ProductSale extends ProductSaleCore
{
public static function getBestSalesLight($idLang, $pageNumber = 0, $nbProducts = 10)
{
$context = Context::getContext();
if ($pageNumber < 0) {
$pageNumber = 0;
}
if ($nbProducts < 1) {
$nbProducts = 10;
}
// Groupes clients pour le filtrage des prix
$groups = FrontController::getCurrentCustomerGroups();
$sqlGroups = implode(',', array_map('intval', $groups));
$sql = new DbQuery();
$sql->select('p.id_product, p.id_manufacturer,
pl.name, pl.link_rewrite,
m.name AS manufacturer_name,
ps.quantity AS sales_quantity,
i.id_image, il.legend');
$sql->from('product_sale', 'ps');
$sql->leftJoin('product', 'p', 'p.id_product = ps.id_product');
$sql->leftJoin('product_lang', 'pl',
'p.id_product = pl.id_product
AND pl.id_lang = ' . (int) $idLang . '
AND pl.id_shop = ' . (int) $context->shop->id);
$sql->leftJoin('manufacturer', 'm', 'p.id_manufacturer = m.id_manufacturer');
$sql->leftJoin('image_shop', 'i',
'i.id_product = p.id_product
AND i.cover = 1
AND i.id_shop = ' . (int) $context->shop->id);
$sql->leftJoin('image_lang', 'il',
'i.id_image = il.id_image
AND il.id_lang = ' . (int) $idLang);
$sql->innerJoin('category_product', 'cp', 'cp.id_product = p.id_product');
$sql->innerJoin('category_group', 'cg',
'cp.id_category = cg.id_category
AND cg.id_group IN (' . $sqlGroups . ')');
$sql->where('p.active = 1');
$sql->where('p.visibility != "none"');
$sql->groupBy('p.id_product');
$sql->orderBy('ps.quantity DESC');
$sql->limit((int) $nbProducts, (int) $pageNumber * (int) $nbProducts);
return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
}
}
La jointure clé ajoutée :
LEFT JOIN ps_manufacturer m ON (p.id_manufacturer = m.id_manufacturer)
Cela rend disponible manufacturer_name dans le tableau de résultats.
Vider le cache des classes
Après avoir créé l'override, supprimez le fichier de cache :
rm -f var/cache/prod/class_index.php
rm -f var/cache/dev/class_index.php
# Sur PrestaShop 1.6 :
rm -f cache/class_index.php
Sans cette étape, PrestaShop continuera d'utiliser la classe originale.
Afficher le fabricant dans le template
PrestaShop 1.6 (Smarty)
Dans le template du module (blockbestsellers.tpl ou votre thème), ajoutez :
{foreach from=$best_sellers item=product}
<div class="product-container">
<h5>{$product.name|escape:'html':'UTF-8'}</h5>
{if $product.manufacturer_name}
<span class="product-manufacturer">
{$product.manufacturer_name|escape:'html':'UTF-8'}
</span>
{/if}
<span class="price">{$product.price}</span>
</div>
{/foreach}
PrestaShop 1.7 / 8.x (approche moderne)
Sur PrestaShop 1.7+, le module ps_bestsellers utilise ProductPresenter qui gère déjà le fabricant. La solution est plus simple — il suffit d'exploiter les données déjà disponibles dans le template :
{block name='product_manufacturer'}
{if $product.manufacturer_name}
<div class="product-manufacturer">
<a href="{$product.manufacturer_name|escape:'html':'UTF-8'}">
{$product.manufacturer_name|escape:'html':'UTF-8'}
</a>
</div>
{/if}
{/block}
Sur PrestaShop 8.x, vérifiez d'abord si le ProductPresenter enrichit déjà vos données. Dans la majorité des cas sur les versions récentes, le fabricant est inclus nativement dans les listes de produits si votre thème l'exploite.
Méthode alternative sans override (PrestaShop 1.7+)
Si vous souhaitez éviter l'override, vous pouvez enrichir les données côté module via le hook :
public function hookActionProductSearchComplete($params)
{
$products = $params['result']->getProducts();
foreach ($products as &$product) {
if (!empty($product['id_manufacturer'])) {
$manufacturer = new Manufacturer(
(int) $product['id_manufacturer'],
(int) $this->context->language->id
);
$product['manufacturer_name'] = $manufacturer->name;
}
}
$params['result']->setProducts($products);
}
Cette approche est plus propre car elle ne touche pas au core, mais elle ajoute une requête par produit. Pour un bloc de 8 à 10 meilleures ventes, l'impact est négligeable.
Bonnes pratiques
- **Toujours échapper les données** avec `escape:'html':'UTF-8'` dans Smarty ou `htmlspecialchars()` en PHP
- **Utiliser `LEFT JOIN`** et non `INNER JOIN` pour le fabricant : certains produits peuvent ne pas avoir de fabricant assigné
- **Tester en multiboutique** : la requête doit filtrer par `id_shop` pour éviter les doublons
- **Penser au cache** : si le module utilise un cache (fichier ou Smarty), purgez-le après modification
- **Préférer les overrides** aux modifications directes : vos changements survivront aux mises à jour du module
Questions fréquentes
Tout ce que vous devez savoir sur ce sujet.
Un projet PrestaShop ?
Discutons-en directement.
193 projets livrés
Lire sur le blog

Alexandre Carette
Expert PrestaShop & Architecture E-commerce
Développeur PrestaShop depuis 2014, 193 projets livrés. Je conçois des architectures headless Nuxt + PrestaShop et des outils d'automatisation IA pour les e-commerçants.