Jump to content

Probleme de notation product comments


Recommended Posts

Bonjour à tous,

Je suis sur une nouvelle boutique, prestashop 8.2 , adresse www.huiles-essentielles.biz .

J'ai un probleme avec l'application product comments de prestashop, pour les notations. L'appli est a jour.

Ca fonctionne sur la page d'accueil avec les blocs produits populaires et meilleures ventes.

 

Screenshot2024-12-11at08-28-27HuilesessentiellesbiologiquesdeCorse.thumb.png.cb4456511bc8a76dce551a464553a5e5.png

Ca fonctionne sur la fiche produit, pour le produit de la page. Mais pas les listings en dessous.

Par exemple dans le bloc "vous aimerez aussi" de la fiche produit ca fonctionne pas :

Screenshot2024-12-11at08-39-55HuileessentielledimmortelledeCorseBio5ml1700.png.acce79220aa81a247d8c22d5647b0891.png

Mais aussi ce bloc :

Screenshot2024-12-11at08-57-17HuileEssentielledEucalyptusGlobulusbio.thumb.png.e3c79d64ed1812f4fd11dc1b5839aa7c.png

J'ai désactivé pagespeed sur o2switch, vider le cache sur la boutique prestashop, ca ne donne rien.

Le html donne ca :

<div class="star-content star-empty clearfix"><div class="star" style="visibility: hidden;"></div><div class="star"></div><div class="star"></div><div class="star"></div><div class="star"></div></div><div class="star-content star-full clearfix"><div class="star-on"></div></div>

Est ce que quelqu'un a une idée de pourquoi certains listings affichent les notations correctement et pas d'autres ?

Peut etre une erreur sql.

J'ai regardé le code du module crossselling au cas ou, je ne vois pas mention des notations dans les requetes sql.


use PrestaShop\PrestaShop\Adapter\Image\ImageRetriever;
use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter;
use PrestaShop\PrestaShop\Adapter\Product\ProductColorsRetriever;
use PrestaShop\PrestaShop\Core\Module\WidgetInterface;

if (!defined('_PS_VERSION_')) {
    exit;
}

class Ps_Crossselling extends Module implements WidgetInterface
{
    const LIMIT_FACTOR = 50;
    private $templateFile;

    public function __construct()
    {
        $this->name = 'ps_crossselling';
        $this->tab = 'pricing_promotion';
        $this->author = 'PrestaShop';
        $this->version = '2.0.2';
        $this->need_instance = 0;

        $this->ps_versions_compliancy = [
            'min' => '1.7.2.0',
            'max' => _PS_VERSION_,
        ];

        $this->bootstrap = true;
        parent::__construct();

        $this->displayName = $this->trans('Cross-selling', [], 'Modules.Crossselling.Admin');
        $this->description = $this->trans('Offer your customers the possibility to buy matching items when on a product page.', [], 'Modules.Crossselling.Admin');

        $this->templateFile = 'module:ps_crossselling/views/templates/hook/ps_crossselling.tpl';
    }

    public function install()
    {
        $this->_clearCache('*');

        return parent::install()
            && Configuration::updateValue('CROSSSELLING_DISPLAY_PRICE', 1)
            && Configuration::updateValue('CROSSSELLING_NBR', 8)
            && $this->registerHook('displayFooterProduct')
            && $this->registerHook('actionOrderStatusPostUpdate');
    }

    public function uninstall()
    {
        $this->_clearCache('*');

        return parent::uninstall()
            && Configuration::deleteByName('CROSSSELLING_DISPLAY_PRICE')
            && Configuration::deleteByName('CROSSSELLING_NBR');
    }

    public function getContent()
    {
        $html = '';

        if (Tools::isSubmit('submitCross')) {
            if (0 != Tools::getValue('displayPrice') && 1 != Tools::getValue('CROSSSELLING_DISPLAY_PRICE')) {
                $html .= $this->displayError('Invalid displayPrice');
            } elseif (!($product_nbr = Tools::getValue('CROSSSELLING_NBR')) || empty($product_nbr)) {
                $html .= $this->displayError($this->trans('You must fill in the "Number of displayed products" field.', [], 'Modules.Crossselling.Admin'));
            } elseif (0 === (int) $product_nbr) {
                $html .= $this->displayError($this->trans('Invalid number.', [], 'Modules.Crossselling.Admin'));
            } else {
                Configuration::updateValue('CROSSSELLING_DISPLAY_PRICE', (int) Tools::getValue('CROSSSELLING_DISPLAY_PRICE'));
                Configuration::updateValue('CROSSSELLING_NBR', (int) Tools::getValue('CROSSSELLING_NBR'));

                $this->_clearCache('*');

                $html .= $this->displayConfirmation($this->trans('The settings have been updated.', [], 'Admin.Notifications.Success'));
            }
        }

        return $html . $this->renderForm();
    }

    public function hookActionOrderStatusPostUpdate($params)
    {
        $products = OrderDetail::getList((int) $params['id_order']);
        foreach ($products as $p) {
            $this->_clearCache('*', $this->getCacheIdKey([$p['product_id']]));
        }
    }

    protected function _clearCache($template, $cacheId = null, $compileId = null)
    {
        parent::_clearCache($this->templateFile, $cacheId);
    }

    public function renderForm()
    {
        $fields_form = [
            'form' => [
                'legend' => [
                    'title' => $this->trans('Settings', [], 'Admin.Global'),
                    'icon' => 'icon-cogs',
                ],
                'input' => [
                    [
                        'type' => 'switch',
                        'label' => $this->trans('Display price on products', [], 'Modules.Crossselling.Admin'),
                        'name' => 'CROSSSELLING_DISPLAY_PRICE',
                        'desc' => $this->trans('Show the price on the products in the block.', [], 'Modules.Crossselling.Admin'),
                        'values' => [
                            [
                                'id' => 'active_on',
                                'value' => 1,
                                'label' => $this->trans('Yes', [], 'Admin.Global'),
                            ],
                            [
                                'id' => 'active_off',
                                'value' => 0,
                                'label' => $this->trans('No', [], 'Admin.Global'),
                            ],
                        ],
                    ],
                    [
                        'type' => 'text',
                        'label' => $this->trans('Number of displayed products', [], 'Modules.Crossselling.Admin'),
                        'name' => 'CROSSSELLING_NBR',
                        'class' => 'fixed-width-xs',
                        'desc' => $this->trans('Set the number of products displayed in this block.', [], 'Modules.Crossselling.Admin'),
                    ],
                ],
                'submit' => [
                    'title' => $this->trans('Save', [], 'Admin.Actions'),
                ],
            ],
        ];

        $lang = new Language((int) Configuration::get('PS_LANG_DEFAULT'));

        $helper = new HelperForm();
        $helper->show_toolbar = false;
        $helper->table = $this->table;
        $helper->default_form_language = $lang->id;
        $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
        $helper->identifier = $this->identifier;
        $helper->submit_action = 'submitCross';
        $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false) .
            '&configure=' . $this->name .
            '&tab_module=' . $this->tab .
            '&module_name=' . $this->name;
        $helper->token = Tools::getAdminTokenLite('AdminModules');
        $helper->tpl_vars = [
            'fields_value' => $this->getConfigFieldsValues(),
            'languages' => $this->context->controller->getLanguages(),
            'id_language' => $this->context->language->id,
        ];

        return $helper->generateForm([$fields_form]);
    }

    public function getConfigFieldsValues()
    {
        return [
            'CROSSSELLING_NBR' => Tools::getValue('CROSSSELLING_NBR', Configuration::get('CROSSSELLING_NBR')),
            'CROSSSELLING_DISPLAY_PRICE' => Tools::getValue('CROSSSELLING_DISPLAY_PRICE', Configuration::get('CROSSSELLING_DISPLAY_PRICE')),
        ];
    }

    public function getCacheIdKey($productIds)
    {
        return parent::getCacheId('ps_crossselling|' . implode('|', $productIds));
    }

    private function getProductIds($hookName, array $configuration)
    {
        if ('displayShoppingCart' === $hookName || 'displayShoppingCartFooter' === $hookName) {
            $productIds = array_map(function ($elem) {
                return $elem['id_product'];
            }, $configuration['cart']->getProducts());
        } else {
            $productIds = [$configuration['product']['id_product']];
        }

        return array_unique($productIds);
    }

    public function getWidgetVariables($hookName, array $configuration)
    {
        $productIds = $this->getProductIds($hookName, $configuration);
        if (!empty($productIds)) {
            $products = $this->getOrderProducts($productIds);

            if (!empty($products)) {
                return [
                    'products' => $products,
                ];
            }
        }

        return false;
    }

    public function renderWidget($hookName, array $configuration)
    {
        $productIds = $this->getProductIds($hookName, $configuration);

        if (empty($productIds)) {
            return;
        }

        if (!$this->isCached($this->templateFile, $this->getCacheIdKey($productIds))) {
            $variables = $this->getWidgetVariables($hookName, $configuration);

            if (empty($variables)) {
                return false;
            }

            $this->smarty->assign($variables);
        }

        return $this->fetch($this->templateFile, $this->getCacheIdKey($productIds));
    }

    protected function getOrderProducts(array $productIds = [])
    {
        $q_orders = 'SELECT o.id_order
        FROM ' . _DB_PREFIX_ . 'orders o
        LEFT JOIN ' . _DB_PREFIX_ . 'order_detail od ON (od.id_order = o.id_order)
        WHERE o.valid = 1
        AND od.product_id IN (' . implode(',', $productIds) . ')
        ORDER BY o.id_order DESC
        LIMIT ' . ((int) Configuration::get('CROSSSELLING_NBR')) * static::LIMIT_FACTOR;

        $orders = Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->executeS($q_orders);

        if (0 < count($orders)) {
            $list = '';
            foreach ($orders as $order) {
                $list .= (int) $order['id_order'] . ',';
            }
            $list = rtrim($list, ',');
            $list_product_ids = join(',', $productIds);

            $sql_groups_join = $sql_groups_where = '';
            if (Group::isFeatureActive()) {
                $sql_groups_join = '
                LEFT JOIN `' . _DB_PREFIX_ . 'category_product` cp ON (cp.`id_category` = product_shop.id_category_default AND cp.id_product = product_shop.id_product)
                LEFT JOIN `' . _DB_PREFIX_ . 'category_group` cg ON (cp.`id_category` = cg.`id_category`)';
                $groups = FrontController::getCurrentCustomerGroups();
                $sql_groups_where = 'AND cg.`id_group` ' . (count($groups) ? 'IN (' . implode(',', $groups) . ')' : '=' . (int) Group::getCurrent()->id);
            }

            $order_products = Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->executeS('
                SELECT DISTINCT od.product_id
                FROM ' . _DB_PREFIX_ . 'order_detail od
                LEFT JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = od.product_id)
                ' . Shop::addSqlAssociation('product', 'p') .
                $sql_groups_join . '
                WHERE od.id_order IN (' . $list . ')
                AND od.product_id NOT IN (' . $list_product_ids . ')
                AND product_shop.visibility IN (\'both\',\'catalog\')
                AND product_shop.active = 1
                ' . $sql_groups_where . '
                ORDER BY RAND()
                LIMIT ' . (int) Configuration::get('CROSSSELLING_NBR')
            );
        }

        if (!empty($order_products)) {
            $showPrice = (bool) Configuration::get('CROSSSELLING_DISPLAY_PRICE');

            $assembler = new ProductAssembler($this->context);

            $presenterFactory = new ProductPresenterFactory($this->context);
            $presentationSettings = $presenterFactory->getPresentationSettings();
            if (version_compare(_PS_VERSION_, '1.7.5', '>=')) {
                $presenter = new \PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductListingPresenter(
                    new ImageRetriever(
                        $this->context->link
                    ),
                    $this->context->link,
                    new PriceFormatter(),
                    new ProductColorsRetriever(),
                    $this->context->getTranslator()
                );
            } else {
                $presenter = new \PrestaShop\PrestaShop\Core\Product\ProductListingPresenter(
                    new ImageRetriever(
                        $this->context->link
                    ),
                    $this->context->link,
                    new PriceFormatter(),
                    new ProductColorsRetriever(),
                    $this->context->getTranslator()
                );
            }

            $productsForTemplate = [];

            $presentationSettings->showPrices = $showPrice;

            if (is_array($order_products)) {
                foreach ($order_products as $productId) {
                    $productsForTemplate[] = $presenter->present(
                        $presentationSettings,
                        $assembler->assembleProduct(['id_product' => $productId['product_id']]),
                        $this->context->language
                    );
                }
            }

            return $productsForTemplate;
        }

        return false;
    }
}

 

et le fichier tpl il me semble que c'est le meme (crossseling utilise _partial/miniature/product.tpl) , mais je peux me tromper, entre les listings de categorie et les listings crossseling .

Si quelqu'un a une idée, je suis preneur !

Merci et bonne journée a tous

 

Screenshot 2024-12-11 at 08-25-37 Huiles essentielles biologiques de Corse.png

Link to comment
Share on other sites

Pour info, pour la migration de 1.6 a 8.2 , j'ai copier le contenu des tables :

product_comment_grade

product_comment

product_comment_usefulness

Les autres tables de ce module etant vides, je n'ai pas recopié autre chose.

 

 

Link to comment
Share on other sites

Re,

Je ne trouve aucune cohérence dans les notations pour mieux cibler d'ou viendrait le probleme.

Sur la fiche d'un produit, la notation d'un produit présent dans les produits vues ou recommandés est parfois a 5 et sur la fiche d'un autre produit, dans le meme bloc,  le produit sera noté a 1.

Par exemple dans les captures ci dessous, le bouchon vaporisateur est parfois noté 1 parfois 5.

J'ai essayé de désactiver le cache prestashop, sans résultat.

 

 

 

Screenshot 2024-12-11 at 12-56-03 Huile essentielle de Pin Laricio bio.png

Screenshot 2024-12-11 at 12-53-37 Hydrolat de Fenouil Doux bio 200ml.png

Screenshot 2024-12-11 at 12-50-49 Huile essentielle de Pin Laricio bio.png

Screenshot 2024-12-11 at 12-56-21 Huile essentielle de Pin Laricio bio.png

Link to comment
Share on other sites

Non , pas de modification des templates... Mais j'ai trouvé une piste.

La notation dans les listings dans la page produit ne déconne que si le produit de la page en cours dispose de plusieurs caractéristiques.

Par exemple :
Flacon disponible en un seul format, la notation fonctionne pour tous les listings en dessous.
Flacon disponible en 5 ou 10ml, ou alors 2,5 et 5ml, toutes les notations dans les listings en dessous déconne et n'afficheront qu'une étoile. Mais alors pour régler ce probleme je suis un peu perdu. Est ce que quelqu'un aurait une idée vers ou chercher ? sql, javascript, php ? un debug possible ?

 

 

Link to comment
Share on other sites

D'ailleurs sur les produits qui n'ont pas de caracteristiques, la note s affiche en dessous du ajouter au panier.

Screenshot2024-12-11at20-44-12HydrolatdImmortelledeCorseBio200ml.png.8ec20879d958170ebb8e50e08b511844.png

Et sur les articles avec plusieurs caractéristiques, ca s'affiche 1 seconde et ca disparait :

Screenshot2024-12-11at20-45-10HuileessentielledimmortelledeCorseBio5ml1700.png.26c3b40147c6c0876e7869e1e6afdab7.png

Sur les affichages rapides, meme si la note est érroné dans le listing, ca s'affichera correctement :

 

Screenshot2024-12-11at20-45-33HuileessentielledimmortelledeCorseBio5ml1700.png.34fbcd9a9bec702aa37d3e9af5c2d92a.png

et par contre des qu'il y aura un clic sur la deuxieme caractéristique ca redescend a 1. et ca ne reviendra pas en changeant de caractéristiques.

Donc je penche pour un serieux souci de javascript. Par contre je ne sais pas trop comment debugger le js, c'est pas vraiment mon domaine. J'ai regardé du coté de la console de dev firefox, mais je n'ai rien trouvé pour m'aider. Je suis donc preneur de  tout conseil,suggestion d'outils pour debugger ca, etc. . Merci !

 

Link to comment
Share on other sites

Apparemment le retour du fichier , dans le debug reseau/json,  est correct "/module/productcomments/CommentGrade?id_products[]=4&id_products[]=5&id_products[]=10&id_products[]=11&id_products[]=17&id_products[]=18&id_products[]=19&id_products[]=21&id_products[]=23&id_products[]=24&id_products[]=25&id_products[]=26&id_products[]=27&id_products[]=28&id_products[]=29&id_products[]=31&id_products[]=32&id_products[]=45&id_products[]=46&id_products[]=48&id_products[]=51&id_products[]=63"  :

{"products":[{"id_product":4,"comments_nb":"4","average_grade":4.75},{"id_product":5,"comments_nb":"2","average_grade":5},{"id_product":10,"comments_nb":"0","average_grade":null},{"id_product":11,"comments_nb":"0","average_grade":null},{"id_product":17,"comments_nb":"1","average_grade":5},{"id_product":18,"comments_nb":"0","average_grade":null},{"id_product":19,"comments_nb":"0","average_grade":null},{"id_product":21,"comments_nb":"0","average_grade":null},{"id_product":23,"comments_nb":"0","average_grade":null},{"id_product":24,"comments_nb":"0","average_grade":null},{"id_product":25,"comments_nb":"0","average_grade":null},{"id_product":26,"comments_nb":"1","average_grade":5},{"id_product":27,"comments_nb":"0","average_grade":null},{"id_product":28,"comments_nb":"0","average_grade":null},{"id_product":29,"comments_nb":"0","average_grade":null},{"id_product":31,"comments_nb":"0","average_grade":null},{"id_product":32,"comments_nb":"0","average_grade":null},{"id_product":45,"comments_nb":"0","average_grade":null},{"id_product":46,"comments_nb":"0","average_grade":null},{"id_product":48,"comments_nb":"0","average_grade":null},{"id_product":51,"comments_nb":"0","average_grade":null},{"id_product":63,"comments_nb":"5","average_grade":5}]}

Le nombre de notations et la moyenne est correcte pour les différents produits, donc le probleme est plus loin.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...