Jump to content

Frontpage catégory modifié


Recommended Posts

Bonjour,

Je voulais afficher les catégories de mes produits sur la home page, pour cela j'ai utilisé ce module qui marche parfaitement bien et qui m'affiche le titre de la catégorie ainsi que sa description.

Maintenant je voudrais afficher le prix le plus bas dans chaque catégorie (du genre, à partir de 20 euros par exemple), j'ai déjà cherché l'astuce mais rien trouvé, j'ai même déjà tenté de voir la structure de la base de donnée de prestashop afin de trouver quel table on extrait les prix mais j'avoue que je suis totalement perdu.

 

Est ce que quelqu'un peut me diriger? j'utilise la dernière version de prestashop et ci-dessous le code de homecategorie.php que j'utilise.

 

<?php
class Homecategories extends Module
{
private $_html = '';
private $_postErrors = array();
function __construct()
{
 $this->name = 'homecategories';
 $this->tab = 'front_office_features';
 $this->version = 1.1;
 $this->author = 'Ecommerce Forum';

 parent::__construct(); // The parent construct is required for translations
 $this->page = basename(__FILE__, '.php');
 $this->displayName = $this->l('Homepage Categories');
 $this->description = $this->l('Displays categories in the middle of your homepage');
}
function install()
{
  return (parent::install() AND $this->registerHook('home') AND $this->registerHook('header'));
}
public function getContent()
{
 $output = '<h2>'.$this->displayName.'</h2>';
 if (Tools::isSubmit('submitHomecategories'))
 {
  $nbr = intval(Tools::getValue('nbr'));
  if (!$nbr OR $nbr <= 0 OR !Validate::isInt($nbr))
   $errors[] = $this->l('Invalid number of categories');
  else
   Configuration::updateValue('HOME_categories_NBR', $nbr);
  if (isset($errors) AND sizeof($errors))
   $output .= $this->displayError(implode('<br />', $errors));
  else
   $output .= $this->displayConfirmation($this->l('Settings updated'));
 }
 return $output.$this->displayForm();
}
public function displayForm()
{
 $output = '
 <form action="'.$_SERVER['REQUEST_URI'].'" method="post">
  <fieldset><legend><img src="'.$this->_path.'logo.gif" alt="" title="" />'.$this->l('Settings').'</legend>
   <label>'.$this->l('Number of categories displayed').'</label>
   <div class="margin-form">
 <input type="text" size="5" name="nbr" value="'.Tools::getValue('nbr', Configuration::get('HOME_categories_NBR')).'" />
 <p class="clear">'.$this->l('The number of catgeories displayed on homepage (default: 10)').'</p>

   </div>
   <center><input type="submit" name="submitHomecategories" value="'.$this->l('Save').'" class="button" /></center>
  </fieldset>
 </form>';
 return $output;
}


 public function hookHeader()
{
 Tools::addCSS(($this->_path).'homecategories.css', 'all');
}
function hookHome($params)
{

 global $smarty, $cookie, $link;

 $id_customer = (int)$params['cookie']->id_customer;
 $id_group = $id_customer ? Customer::getDefaultGroupId($id_customer) : _PS_DEFAULT_CUSTOMER_GROUP_;
 $id_lang = (int)$params['cookie']->id_lang;


 $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
 SELECT c.*, cl.*
 FROM `'._DB_PREFIX_.'category` c
 LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (c.`id_category` = cl.`id_category` AND `id_lang` = '.$id_lang.')
 LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = c.`id_category`)
 WHERE level_depth = 1
 AND c.`active` = 1
 AND cg.`id_group` = '.$id_group.'
 ORDER BY c.`position` ASC');


 $category = new Category(1);
 $nb = intval(Configuration::get('HOME_categories_NBR'));

   global $link;


    $smarty->assign(array(
	    'categories' => $result, Category::getHomeCategories(intval($params['cookie']->id_lang), true),
  'link' => $link

    ));


 $smarty->assign(array(
  'category' => $category,
  'lang' => Language::getIsoById(intval($params['cookie']->id_lang)),
 ));
 return $this->display(__FILE__, 'homecategories.tpl');
}
}

 

Merci pour votre aide et je pense que cela aiderait aussi plus d'un.

Link to comment
Share on other sites

Bonjour.

 

C'est très simple et casse-tête à la fois. Pour faire ce genre de requête il faut déjà mettre sur papier les tables nécessaires :

 

- category : c'est un peu la base

- category_group : parce que le module en a apparemment besoin, pour faire une recherche par groupe.

- category_lang : pour avoir les noms en francais

- category_product : pour avoir tous les produits d'une catégorie

- product : pour avoir toutes les informations d'un produit

 

À partir de là, tu as 80% de ta requête. Le problème est qu'en appelant la table category_product, tu vas avoir des doublons, donc tu risques d'avoir par exemple la catégorie "A" répétées inutilement 5 fois parce qu'elle a 5 produits. En SQL, un mot clé devient donc intéressant dans ce cas là : GROUP BY. Autre problème, GROUP BY va quand même affiché l'ID d'un produit, on ne sait pas lequel (sûrement le premier qu'il va trouver) alors qu'on veut le produit qui a le prix le moins cher ; encore une fois, en SQL un mot clé devient intéressant : MIN.

 

SELECT c.*, cl.*, MIN(p.`price`) AS price
FROM `ps_category` c
LEFT JOIN `ps_category_group` cg ON (cg.`id_category` = c.`id_category`)
LEFT JOIN `ps_category_lang` cl ON (cl.`id_category` = c.`id_category` AND cl.`id_lang` = 2)
LEFT JOIN `ps_category_product` cp ON (cp.`id_category` = c.`id_category`)
LEFT JOIN `ps_product` p ON (cp.`id_product` = p.`id_product`)
WHERE level_depth = 1
AND c.`active` = 1
AND cg.`id_group` = 1
GROUP BY c.`id_category`
ORDER BY c.`position` ASC

 

Il faudra remettre les variables à leur place, à savoir _DB_PREFIX_, $id_group et $id_lang. Normalement ça marche, mais je n'ai pas testé. Tiens moi donc au courant.

 

Je te conseil d'aller tester cette requête en enlevant les différents mots-clés pour bien la comprendre. Je pense qu'il est inutile de te préciser qu'un simple c/c ne t'avancera pas et que si tu as un problème, tu perdras beaucoup de temps.

Link to comment
Share on other sites

Bonjour.

 

C'est très simple et casse-tête à la fois. Pour faire ce genre de requête il faut déjà mettre sur papier les tables nécessaires :

 

- category : c'est un peu la base

- category_group : parce que le module en a apparemment besoin, pour faire une recherche par groupe.

- category_lang : pour avoir les noms en francais

- category_product : pour avoir tous les produits d'une catégorie

- product : pour avoir toutes les informations d'un produit

 

À partir de là, tu as 80% de ta requête. Le problème est qu'en appelant la table category_product, tu vas avoir des doublons, donc tu risques d'avoir par exemple la catégorie "A" répétées inutilement 5 fois parce qu'elle a 5 produits. En SQL, un mot clé devient donc intéressant dans ce cas là : GROUP BY. Autre problème, GROUP BY va quand même affiché l'ID d'un produit, on ne sait pas lequel (sûrement le premier qu'il va trouver) alors qu'on veut le produit qui a le prix le moins cher ; encore une fois, en SQL un mot clé devient intéressant : MIN.

 

SELECT c.*, cl.*, MIN(p.`price`)
FROM `ps_category` c
LEFT JOIN `ps_category_group` cg ON (cg.`id_category` = c.`id_category`)
LEFT JOIN `ps_category_lang` cl ON (cl.`id_category` = c.`id_category` AND cl.`id_lang` = 2)
LEFT JOIN `ps_category_product` cp ON (cp.`id_category` = c.`id_category`)
LEFT JOIN `ps_product` p ON (cp.`id_product` = p.`id_product`)
WHERE level_depth = 1
AND c.`active` = 1
AND cg.`id_group` = 1
GROUP BY c.`id_category`
ORDER BY c.`position` ASC

 

Il faudra remettre les variables à leur place, à savoir _DB_PREFIX_, $id_group et $id_lang. Normalement ça marche, mais je n'ai pas testé. Tiens moi donc au courant.

 

Je te conseil d'aller tester cette requête en enlevant les différents mots-clés pour bien la comprendre. Je pense qu'il est inutile de te préciser qu'un simple c/c ne t'avancera pas et que si tu as un problème, tu perdras beaucoup de temps.

Merci Sbizz, j'avoue que je ne suis pas développeur dans l'âme mais plutôt intégrateur, mais je suis débrouillard quand même, je suis nouveau sur prestashop et je ne connais pas encore la structure de la base de donnée, je vais tester ton code et je ferais un report ici après, juste une question débile, comment afficher le resultat dans le fichier template tpl du module (homecategories.tpl)?

 

Merci encore

Link to comment
Share on other sites

La requête que je viens de te donner et à mettre à la place de la requête qui se trouve dans $result.

 

$result étant directement assignée dans smarty à la variable categories, tu n'auras pas besoin de modifier le code PHP. Dans le template, je suppose que Prestashop fait un foreach sur categories. Voici un exemple de code que tu pourrais trouver dans le fichier template :

 

{foreach from=$categories item=category}
Price min: {$category.price}
{/foreach}

 

Ce qui veut dire, en gros :

 

"Pour toutes les entrées du tableau categories, je nomme une variable category pour chaque entrée trouvée et je veux afficher la valeur price"

 

PS: Attention, dans la requête j'ai oublié de renommer la variable, je viens d'edit.

Link to comment
Share on other sites

Merci encore, ci-dessous donc le report :

j'ai remplacé la requette dans result ce qui donne :

$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
 SELECT c.*, cl.*, MIN(p.`price`)
 FROM `'._DB_PREFIX_.'category` c
 LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (c.`id_category` = cl.`id_category` AND `id_lang` = '.$id_lang.')
 LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = c.`id_category`)
 LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_category` = c.`id_category`)
 LEFT JOIN `'._DB_PREFIX_.'product` p ON (cp.`id_product` = p.`id_product`)
 WHERE level_depth = 1
 AND c.`active` = 1
 AND cg.`id_group` = '.$id_group.'
 ORDER BY c.`position` ASC');

Par contre à l'affichage du site, il n'affiche qu'une seule catégorie :(, j'ai manqué quelque chose?

Link to comment
Share on other sites

Effectivement j'ai manqué quelque chose, voici donc le bon code en suivant ton conseil :

$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
 SELECT c.*, cl.*, MIN(p.`price`)
 FROM `'._DB_PREFIX_.'category` c
 LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = c.`id_category`)
 LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (cl.`id_category` = c.`id_category` AND cl.`id_lang` = 2)
 LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_category` = c.`id_category`)
 LEFT JOIN `'._DB_PREFIX_.'product` p ON (cp.`id_product` = p.`id_product`)
 WHERE level_depth = 1
 AND c.`active` = 1
 AND cg.`id_group` = 1
 GROUP BY c.`id_category`
 ORDER BY c.`position` ASC');

Par contre le prix ne s'affiche pas même en ajoutant

{$category.price}

dans la boucle foreach

Link to comment
Share on other sites

Peux-tu copier le template ? De l'ouverture de la balise {foreach} à sa fermeture {/foreach}.

 

Edit: en voyant ton dernier message, je remarque que tu n'as toujours pas effectué la modif du "MIN" ! C'est pour ça que ça n'affiche rien.

Link to comment
Share on other sites

Le template

<!-- MODULE Home categories -->
<div class="home_categories">
   <!--h2>{l s='Categories' mod='homecategories'}</h2-->
   {if isset($categories) AND $categories}
	    <ul id="cadres" class="container_3">
	    {foreach from=$categories item=category name=homeCategories}
		    {assign var='categoryLink' value=$link->getcategoryLink($category.id_category, $category.link_rewrite)}
		    <li class="grid_1 ajax_block_category {if $smarty.foreach.homeCategories.first}first_item{elseif $smarty.foreach.homeCategories.last}last_item{else}item{/if}">

   <div>
 <h2>{$category.name|truncate:35}</h2>
 <!--a href="{$categoryLink}" title="{$category.legend}" class="category_desc">
  {$category.description}
 </a-->
 {$category.price}
   </div>
   </li>
	    {/foreach}
	    </ul>
   {else}
    <p>{l s='No categories' mod='homecategories'}</p>
   {/if}
</div>
<!-- /MODULE Home categories -->

Link to comment
Share on other sites

La fonction php number_format devrait t'aider.

 

{$category.price|number_format:2}

 

PS: Jamais testé.

 

Edit: il y a aussi une fonction créée par Prestashop pour smarty pour afficher les prix, qui doit être displayPrice. Je dois rentrer chez moi, je verrais plus tard. Tu devrais trouver tout seul, de toute façon. Si tu es intégrateur, connaître smarty est une priorité. Le template product.tpl affiche des prix, peut-être que tu trouveras ta réponse là bas.

Link to comment
Share on other sites

Bonjour,

J'ai voulu mettre sur le forum le module complet pour la communauté, par contre en testant un peu sur mon site, j'ai trouvé que lorsqu'on clique sur une catégorie aucun article apparait comme sur ce lien. Par contre lorsque je désactive le module tout semble normal.

 

Ci-dessous le code complet de homecategories.php

<?php
class Homecategories extends Module
{
private $_html = '';
private $_postErrors = array();
function __construct()
{
 $this->name = 'homecategories';
 $this->tab = 'front_office_features';
 $this->version = 1.1;
 $this->author = 'Ecommerce Forum';

 parent::__construct(); // The parent construct is required for translations
 $this->page = basename(__FILE__, '.php');
 $this->displayName = $this->l('Homepage Categories');
 $this->description = $this->l('Displays categories in the middle of your homepage');
}
function install()
{
  return (parent::install() AND $this->registerHook('home') AND $this->registerHook('header'));
}
public function getContent()
{
 $output = '<h2>'.$this->displayName.'</h2>';
 if (Tools::isSubmit('submitHomecategories'))
 {
  $nbr = intval(Tools::getValue('nbr'));
  if (!$nbr OR $nbr <= 0 OR !Validate::isInt($nbr))
   $errors[] = $this->l('Invalid number of categories');
  else
   Configuration::updateValue('HOME_categories_NBR', $nbr);
  if (isset($errors) AND sizeof($errors))
   $output .= $this->displayError(implode('<br />', $errors));
  else
   $output .= $this->displayConfirmation($this->l('Settings updated'));
 }
 return $output.$this->displayForm();
}
public function displayForm()
{
 $output = '
 <form action="'.$_SERVER['REQUEST_URI'].'" method="post">
  <fieldset><legend><img src="'.$this->_path.'logo.gif" alt="" title="" />'.$this->l('Settings').'</legend>
   <label>'.$this->l('Number of categories displayed').'</label>
   <div class="margin-form">
 <input type="text" size="5" name="nbr" value="'.Tools::getValue('nbr', Configuration::get('HOME_categories_NBR')).'" />
 <p class="clear">'.$this->l('The number of catgeories displayed on homepage (default: 10)').'</p>

   </div>
   <center><input type="submit" name="submitHomecategories" value="'.$this->l('Save').'" class="button" /></center>
  </fieldset>
 </form>';
 return $output;
}


 public function hookHeader()
{
 Tools::addCSS(($this->_path).'homecategories.css', 'all');
}
function hookHome($params)
{

 global $smarty, $cookie, $link;

 $id_customer = (int)$params['cookie']->id_customer;
 $id_group = $id_customer ? Customer::getDefaultGroupId($id_customer) : _PS_DEFAULT_CUSTOMER_GROUP_;
 $id_lang = (int)$params['cookie']->id_lang;




 $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
 SELECT c.*, cl.*,MIN(p.`price`) AS price
 FROM `'._DB_PREFIX_.'category` c
 LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = c.`id_category`)
 LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (c.`id_category` = cl.`id_category` AND `id_lang` = '.$id_lang.')
 LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_category` = c.`id_category`)
 LEFT JOIN `'._DB_PREFIX_.'product` p ON (cp.`id_product` = p.`id_product`)
 WHERE level_depth = 1
 AND c.`active` = 1
 AND cg.`id_group` = '.$id_group.'
 GROUP BY c.`id_category`
 ORDER BY c.`position` ASC');

 $category = new Category(1);
 $nb = intval(Configuration::get('HOME_categories_NBR'));

   global $link;


    $smarty->assign(array(
	    'categories' => $result, Category::getHomeCategories(intval($params['cookie']->id_lang), true),
  'link' => $link

    ));


 $smarty->assign(array(
  'category' => $category,
  'lang' => Language::getIsoById(intval($params['cookie']->id_lang)),
 ));
 return $this->display(__FILE__, 'homecategories.tpl');
}
}

Link to comment
Share on other sites

Désole, s’était une erreur de chemin css, au lieu de mettre les règles dans themes/montheme/css/modules/homecategories.css j'ai fait un import @import url('grid.css'); qui a causé l'affichage, je ne sais pas pourquoi mais dès que je l'ai enlevé tout rentre dans l'ordre.

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