💻 DéveloppementIntermédiaire PS 1.6 PS 1.7 PS 8.x

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.

Publié le 21 mars 2026 5 min de lecture Alexandre Carette

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
#manufacturer #blockbestsellers #module #smarty #SQL #override

Questions fréquentes

Tout ce que vous devez savoir sur ce sujet.

Un projet PrestaShop ?

Discutons-en directement.

★★★★★

193 projets livrés

Gratuit & sans engagement — réponse sous 24h

Alexandre Carette

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.