Prestashop: Afficher les commentaires produits dans les onglets de la fiche produit

Ce tutoriel est compatible avec les versions de Prestashop suivantes :
1.7 +

Petit tutoriel rapide aujourd’hui sur une optimisation que j’ai voulu faire cette semaine et qui s’est avérée un peu plus embêtante que prévue.
Le besoin est relativement simple je veux déplacer le contenu des commentaires dans les onglets affichés sur la fiche produit. ( Dans un thème basé sur classic )
Les commentaires utilisent le module natif de Prestashop productcomments
L’affichage du contenu des onglets est géré par le hook displayProductExtraContent
Voici une capture du comportement avant :

Et voici une capture du comportement que je souhaite obtenir après.

Plusieurs approches techniques sont possibles pour faire cela, pour ma part j’ai choisi de le faire un module complémentaire hhproductcomments qui dépends du module natif productcomments.
Cela présente l’avantage de ne pas toucher devoir toucher ni au module natif, ni au thème pour gérer cet affichage.
L’idée est de greffer ce nouveau module sur le hook displayProductExtraContent pour gérer l’affichage en onglet et d’appeller le hook natif displayFooterProduct du module productcomments

Le gros point d’attention à avoir , c’est que la fonction hookDisplayFooterProduct attends une instance de  \PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductLazyArray et non pas un instance du produit ( Product ) telle qu’on la reçoit dans le hook initial.
Il va donc falloir transformer le paramètre pour que ça fonctionne.

Voici l’ensemble du code du module :

<?php
use PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductLazyArray;
use PrestaShop\PrestaShop\Core\Product\ProductExtraContent;
use PrestaShop\PrestaShop\Core\Product\ProductPresentationSettings;
 
if (!defined('_PS_VERSION_')) {
    exit;
}
 
 
class Hhproductcomments extends Module
{
 
    /** @var string Nom du module de gestion des commentaires */
    const PRODUCT_COMMENTS_MODULE_NAME = 'productcomments';
 
    public function __construct()
    {
        $this->name = 'hhproductcomments';
        $this->tab = 'others';
        $this->version = '0.1.0';
        $this->author = 'hhennes';
        $this->bootstrap = true;
        $this->dependencies = [self::PRODUCT_COMMENTS_MODULE_NAME];
        parent::__construct();
 
        $this->displayName = $this->l('Hh product comments');
        $this->description = $this->l('Display prestashop module comments in product extra content');
    }
 
    /**
     * Installation du module
     * @return bool
     */
    public function install()
    {
        return parent::install()
            && $this->registerHook('displayProductExtraContent')
            && $this->unregisterProductCommentsFooter();
    }
 
    /**
     * Suppression du hook footer pour le module productComments
     * @return bool
     */
    protected function unregisterProductCommentsFooter(): bool
    {
        if ($productCommentModule = $this->getProductCommentsModule()) {
            return $productCommentModule->unregisterHook('displayFooterProduct');
        }
        return true;
    }
 
    /**
     * Récupération du module de commentaire produits
     * @return false|Module
     */
    protected function getProductCommentsModule()
    {
        return Module::getInstanceByName(self::PRODUCT_COMMENTS_MODULE_NAME);
    }
 
    /**
     * Affichage du contenu du module productComments dans le hookDisplay extra Content
     * @param array $params
     * @return array
     */
    public function hookDisplayProductExtraContent($params)
    {
        $return = [];
        $productCommentModule = $this->getProductCommentsModule();
        if ($productCommentModule && $productCommentModule->active == true) {
            /** @var \ProductComments $productCommentModule */
            try {
                //Problème à ce niveau : dans notre hook on a une instance de Product et le hook du module veut avoir un ProductLazyArray
                $params['product'] = $this->getPresentedProduct($params);
                $content = $productCommentModule->hookDisplayFooterProduct($params);
            } catch (Exception $e) {
                $content = 'Error ' . $e->getMessage();
            }
            $return[] = (new ProductExtraContent())
                ->setTitle($this->l('Reviews'))
                ->setContent($content);
        }
        return $return;
    }
 
    /**
     * Récupération d'une instance ProductLazyArray pour le frontOffice
     * @param array $params
     * @return ProductLazyArray
     * @throws ReflectionException
     */
    protected function getPresentedProduct(array $params): ProductLazyArray
    {
        //Gestion des paramètres de présentation
        $settings = new ProductPresentationSettings();
        $settings->catalog_mode = Configuration::isCatalogMode();
        $settings->catalog_mode_with_prices = (int)Configuration::get('PS_CATALOG_MODE_WITH_PRICES');
        $settings->include_taxes = true;
        $settings->allow_add_variant_to_cart_from_listing = (int)Configuration::get('PS_ATTRIBUTE_CATEGORY_DISPLAY');
        $settings->stock_management_enabled = Configuration::get('PS_STOCK_MANAGEMENT');
        $settings->showPrices = Configuration::showPrices();
        $settings->lastRemainingItems = Configuration::get('PS_LAST_QTIES');
        $settings->showLabelOOSListingPages = (bool)Configuration::get('PS_SHOW_LABEL_OOS_LISTING_PAGES');
 
        //Récupération de l'instance du presenter
        $productPresenter = new ProductPresenterFactory($this->context, null);
        $presenter = $productPresenter->getPresenter();
 
        //Récupération d'une instance de l'assembler
        $assembler = new ProductAssembler($this->context);
 
        //Conversion de l'objet "Product" en tableau et ajout de son identifiant
        $product = (array)$params['product'];
        $product['id_product'] = $product['id'];
 
        return $presenter->present(
            $settings,
            $assembler->assembleProduct($product),
            $this->context->language
        );
    }
 
 
}

Télécharger le module complet ( et gratuit ) sur la boutique

2 réflexions sur “Prestashop: Afficher les commentaires produits dans les onglets de la fiche produit”

    1. Bonjour,

      Ce blog cible avant tout un public technique, c’est pour cela que les « basiques » tels que la création de module ou leur rangement dans Prestashop ne sont pas évoqués.
      J’ai mis à jour l’article avec un lien pour télécharger le module complet sur la boutique ( c’est gratuit mais c’est pour me faciliter la maintenance )

      Cordialement,
      Hervé

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.