Jump to content

[RESOLU] Classement par "Position" avec module Blocklayered


Swedge

Recommended Posts

Bonjour à tous,

 

Voilà, sur notre boutique nous utilisons le module de navigation à facette (blocklayered) qui permet d'afficher les produits répondant seulement à certains critères (marque, couleur etc...).

 

Le problème que nous rencontrons, c'est qu'avec ce module les produits sont classés n'importe comment dans les catégories. En effet, lorsque le module blocklayered est désactivé les produits sont classé par "Position" (que l'on détermine dans l'admin en faisant remonter ou descendre les produits).

Par contre, dès que le module blocklayered est activé les produits sont classés d'une manière qui m'échappe (en tout cas pas par position ça c'est sur).

 

En fait, je voudrais simplement que les produits soit classés par leur position dans la catégorie (définie en admin).

Par exemple, j'arrive sur une catégorie: tous les produits sont classés par position, puis si je choisi les produits de couleur rouge: tous les produits rouges apparaissent classés par position également.

 

J'ai fouillé dans le Php du module est j'ai trouvé la requête qui affiche les produits. C'est la suivante (ligne 734 de modules/blocklayered/blocklayered.php)

 

 

$this->products = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
SELECT p.id_product, p.on_sale, p.out_of_stock, p.available_for_order, p.quantity, p.minimal_quantity, p.id_category_default, p.customizable, p.show_price, p.`weight`,
p.ean13, pl.available_later, pl.description_short, pl.link_rewrite, pl.name, i.id_image, il.legend,  m.name manufacturer_name, p.condition, p.id_manufacturer,
DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new
FROM '._DB_PREFIX_.'product p
LEFT JOIN '._DB_PREFIX_.'product_lang pl ON (pl.id_product = p.id_product)
LEFT JOIN '._DB_PREFIX_.'image i ON (i.id_product = p.id_product AND i.cover = 1)
LEFT JOIN '._DB_PREFIX_.'image_lang il ON (i.id_image = il.id_image AND il.id_lang = '.(int)($cookie->id_lang).')
LEFT JOIN '._DB_PREFIX_.'manufacturer m ON (m.id_manufacturer = p.id_manufacturer)
WHERE p.`active` = 1 AND pl.id_lang = '.(int)$cookie->id_lang.$queryFilters
.' ORDER BY '.Tools::getProductsOrder('by', Tools::getValue('orderby')).' '.Tools::getProductsOrder('way', Tools::getValue('orderway'))
' LIMIT '.(((int)Tools::getValue('p', 1) - 1) * $n.','.$n));

 

J'ai aussi vu que dans le fichier Tools.php que la fonction getProductsOrder avait un tableau pour déterminer par quoi on classe les résultats produit dans une requête.

Le tableau est le suivant:

0 => name

1 => price

2 => date_add

3 => date_upd

4 => position

5 => manufacturer_name

6 => quantity

 

J'ai donc essayé la requête suivante dans blocklayered.php

 

 

$this->products = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
SELECT p.id_product, p.on_sale, p.out_of_stock, p.available_for_order, p.quantity, p.minimal_quantity, p.id_category_default, p.customizable, p.show_price, p.`weight`,
p.ean13, pl.available_later, pl.description_short, pl.link_rewrite, pl.name, i.id_image, il.legend,  m.name manufacturer_name, p.condition, p.id_manufacturer,
DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new
FROM '._DB_PREFIX_.'product p
LEFT JOIN '._DB_PREFIX_.'product_lang pl ON (pl.id_product = p.id_product)
LEFT JOIN '._DB_PREFIX_.'image i ON (i.id_product = p.id_product AND i.cover = 1)
LEFT JOIN '._DB_PREFIX_.'image_lang il ON (i.id_image = il.id_image AND il.id_lang = '.(int)($cookie->id_lang).')
LEFT JOIN '._DB_PREFIX_.'manufacturer m ON (m.id_manufacturer = p.id_manufacturer)
WHERE p.`active` = 1 AND pl.id_lang = '.(int)$cookie->id_lang.$queryFilters
.' ORDER BY '.Tools::getProductsOrder('by', 4).' '.Tools::getProductsOrder('way', 1).
' LIMIT '.(((int)Tools::getValue('p', 1) - 1) * $n.','.$n));

 

En fait je force à classer par position en mettant 4 en "dur". Malheureusement le classement reste le même et toujours un mystère.

 

J'ai essayé de mettre d'autres chiffres. Par exemple 0 pour "name" et là ça classe bien par nom. En fait on dirait que c'est seulement "position" qui ne veut pas fonctionner. C'est dommage...

 

Quelqu'un aurait une solution ?

 

Merci pour votre aide.

 

P.S: Nous utilisons Prestashop v1.4.4.0 et le module blocklayered v1.4

Link to comment
Share on other sites

Bonjour,

 

Bienvenue au club. J'ai posté exactement le même pb hier sur un post avec en plus un pb sur le nb de produit que j'ai résolu. En effet, j'ai la même interrogation que toi sur le tri de ce module. Tu as plus avancé que moi en tout cas sur le pb. Etant donné que tu utilises ce module, as-tu toi aussi une première page de produit qui s'affiche quand le client choisit une catégorie et ensuite le module blocklayered réactualise la page (chargement affiché en haut de page) en réaffichant la liste des produits ?

 

Je vais regarder de mon côté également

 

PS : 1.4.4

Link to comment
Share on other sites

Oui j'ai exactement ça. Au début tout est bien classé. Mais au rafraichissement tout se déclasse...

 

Cela dit c'est normal car le module blocklayered a une requête spéciale (celle que je mentionne dans mon post). Donc la page part sur la requête de base et au chargement du module il fait la requête ci dessus. Enfin c'est ce que j'en déduit...

Link to comment
Share on other sites

Re bonjour,

 

Oui, c'est ce que j'ai compris aussi mais c'est pas top pour le client. Même si on arrivait à avoir le même tri, c'est pas très élégant d'avoir un premier affichage puis un réaffichage avec la même page. Bon, déjà si on arrive avoir le même tri c'est serait pas mal.

 

J'ai remarqué que le champ postion est un champ de la table ps_category_product qui elle n'est pas dans la requête. Alors que les autres champs sont des champs des tables mises en jeu dans la requête.

 

Il y a certainement une subtilité de ce côté là.

Link to comment
Share on other sites

Bon je pense avoir trouvé. Cela ne doir pas être très académique mais ça fonctionne bien.

En fait il faut changer la requête par défaut et en préparer une autre au cas ou le client veut changer le tri (par prix, par nom A-Z ou Z-A etc...)

 

Donc dans le fichier blocklayered.php toujours à la ligne 734 remplacer la requête que j'expose ci-dessus par:

 

 

if(Tools::getValue('orderby') == 'position')
{
$this->products = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
SELECT p.id_product, p.on_sale, p.out_of_stock, p.available_for_order, p.quantity, p.minimal_quantity, p.id_category_default, p.customizable, p.show_price, p.`weight`,
p.ean13, pl.available_later, pl.description_short, pl.link_rewrite, pl.name, i.id_image, il.legend,  m.name manufacturer_name, p.condition, p.id_manufacturer,
DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new
FROM '._DB_PREFIX_.'category_product cp
LEFT JOIN '._DB_PREFIX_.'product p ON p.id_product = cp.id_product
LEFT JOIN '._DB_PREFIX_.'product_lang pl ON (pl.id_product = p.id_product)
LEFT JOIN '._DB_PREFIX_.'image i ON (i.id_product = p.id_product AND i.cover = 1)
LEFT JOIN '._DB_PREFIX_.'image_lang il ON (i.id_image = il.id_image AND il.id_lang = '.(int)($cookie->id_lang).')
LEFT JOIN '._DB_PREFIX_.'manufacturer m ON (m.id_manufacturer = p.id_manufacturer)
WHERE cp.id_category = '.$parent->id_category.' AND p.`active` = 1 AND pl.id_lang = '.(int)$cookie->id_lang.$queryFilters
.' ORDER BY cp.position LIMIT '.(((int)Tools::getValue('p', 1) - 1) * $n.','.$n));
}
else
{
$this->products = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
SELECT p.id_product, p.on_sale, p.out_of_stock, p.available_for_order, p.quantity, p.minimal_quantity, p.id_category_default, p.customizable, p.show_price, p.`weight`,
p.ean13, pl.available_later, pl.description_short, pl.link_rewrite, pl.name, i.id_image, il.legend,  m.name manufacturer_name, p.condition, p.id_manufacturer,
DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new
FROM '._DB_PREFIX_.'product p
LEFT JOIN '._DB_PREFIX_.'product_lang pl ON (pl.id_product = p.id_product)
LEFT JOIN '._DB_PREFIX_.'image i ON (i.id_product = p.id_product AND i.cover = 1)
LEFT JOIN '._DB_PREFIX_.'image_lang il ON (i.id_image = il.id_image AND il.id_lang = '.(int)($cookie->id_lang).')
LEFT JOIN '._DB_PREFIX_.'manufacturer m ON (m.id_manufacturer = p.id_manufacturer)
WHERE p.`active` = 1 AND pl.id_lang = '.(int)$cookie->id_lang.$queryFilters
.' ORDER BY '.Tools::getProductsOrder('by', Tools::getValue('orderby')).' '.Tools::getProductsOrder('way', Tools::getValue('orderway'))
.' LIMIT '.(((int)Tools::getValue('p', 1) - 1) * $n.','.$n));
}

 

P.S: Ne pas oublier dans l'admin Préférences-> Produits "Tri par défaut" choisir "Position dans la catégorie"

 

J'espère que cette solution marchera pour d'autres. Si quelqu'un a une solution plus propre qu'il n'hésite pas...

  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...

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...