Module : Les clients ayant acheté cet article ont également acheté

  • De le 03 juillet 2010
  • Difficulté : 3/4

Module : Les clients ayant acheté cet article ont également acheté Plutôt courant sur les sites e-commerce, cette extension Magento développé par Magentix permet de favoriser l'ajout de produits complémentaires au panier. Selon les produits acquis par les internautes, elle se chargera de récupérer et d'afficher l'ensemble produits achetés en complément du produit consulté.

L'objectif de cette extension est de proposer aux internautes des produits complémentaires générés automatiquement selon les produits acquis précédemment au sein d'un même panier. Cette technique de recoupement a pour avantage de fonctionner en totale autonomie, les produits apparaîtront au fur à mesure des achats sur le site (à condition que les paniers comportent plus d'un produit).

Produits complémentaires acquis par les internautes

L'enjeu principale pour réaliser ce module est d'établir la bonne requête. L'extension est disponible en téléchargement sur la page de cet article (colonne de droite), voici quelques explications complémentaires.

Architecture du module

  • app/code/local/Magentix/AlsoBought
  • Block
  • Bought.php
  • etc
  • config.xml
  • Model
  • Mysql4
  • Bought.php
  • Bought.php
  • app/design/frontend/base/default
  • layout
  • alsobought.xml
  • template
  • alsobought
  • bought.phtml
  • app/etc/modules
  • Magentix_AlsoBought.xml

Développement du module

Avant de se lancer dans le développement du module, il est primordiale de déterminer la requête à exécuter pour l'acquisition de l'identifiant des produits achetés en même temps que le produit consulté.

L'ensemble des produits achetés se situent dans la table sales_flat_order_item. Les conditions doivent être les suivantes :

  • J'isole les commandes comportant le produit spécifique
  • Je supprime les commandes dont le statut est annulé
  • J'isole les produits contenus dans ces commandes
  • Je supprime le produit spécifique des résultats
  • Je regroupe les produits par identifiant afin d'éviter les doublons

Ce qui nous amène finalement à la requête suivante (où X représente l'identifiant du produit consulté) :

Requête

SELECT `s2`.`product_id` AS `id`
FROM `sales_flat_order_item` AS `s1`
INNER JOIN `sales_flat_order_item` AS `s2` ON s1.order_id = s2.order_id
WHERE (s1.product_id = 'X') AND (s2.product_id != 'X') AND (s1.qty_canceled = 0)
GROUP BY `s2`.`product_id`

Nous pouvons maintenant construire la requête à l'aide des méthodes proposés par Zend. Le méthode getProductsIds de la classe Magentix_AlsoBought_Model_Mysql4_Bought permet la construction puis l'exécution de la requête (l'adaptateur de lecture de la ressource est définie dans le fichier de configuration).

app/code/local/Magentix/AlsoBought/Model/Mysql4/Bought.php

<?php

class Magentix_AlsoBought_Model_Mysql4_Bought extends Mage_Core_Model_Mysql4_Abstract {

     protected function _construct() {
          $this->_init('alsobought/bought','id');
     }

     public function getProductsIds($product_id) {
          $connection = $this->_getReadAdapter();

          $select = $this->_getReadAdapter()->select()
               ->from(array('s1' => 'sales_flat_order_item'),array('id' => 's2.product_id'))
               ->join(array('s2' => 'sales_flat_order_item'),"s1.order_id = s2.order_id",array())
               ->where('s1.product_id = ?', $product_id)
               ->where('s2.product_id != ?', $product_id)
               ->where('s1.qty_canceled = ?', 0)
               ->group('s2.product_id');

          if(!$connection->fetchRow($select)) return 0;

          return $connection->fetchAll($select);
     }
}

En paramètre se trouve l'identifiant du produit actuellement consulté. Depuis le modèle Magentix_AlsoBought_Model_Bought il est alors possible de filtrer une collection de produits selon les identifiants de produits récupérés grâce à la méthode getProductsIds que nous venons d'établir.

app/code/local/Magentix/AlsoBought/Model/Bought.php

<?php

class Magentix_AlsoBought_Model_Bought extends Mage_Core_Model_Abstract {

     protected function _getResource() {
          if (is_null($this->_resource)) {
               $this->_resource = Mage::getResourceModel('alsobought/bought');
          }
          return $this->_resource;
     }

     public function getAlsoBoughtProductCollection($product_id) {
          $ids = $this->_getResource()->getProductsIds($product_id);
          $products = Mage::getResourceModel('catalog/product_collection')->addAttributeToFilter('entity_id',$ids);

          return $products;
     }

}

La suite du développement du module concerne la mise en place d'un bloc classique. Nous ne le détaillerons pas.

Affichage des produits

L'affichage des produits se gère depuis le fichier du template alsobought/bought.phtml. Il faudra prendre soin de le déplacer dans le template adéquat. Ce fichier est à peu de chose près identique au fichier du template de base utilisé pour l'affichage des produits en upsell (montée en gamme).

Le layout indique que le bloc est enfant du bloc product.info de la référence content. Il spécifie également le template à utiliser (alsobought/bought.phtml).

app/design/frontend/base/default/layout/alsobought.xml

<?xml version="1.0"?>
<layout version="0.1.0">
     <catalog_product_view>
          <reference name="content">
               <block name="product.info">
                    <block type="alsobought/bought" name="product.info.alsobought" as="alsobought_products" template="alsobought/bought.phtml">
                         <action method="setColumnCount"><columns>4</columns></action>
                         <action method="setItemLimit"><type>alsobought</type><limit>4</limit></action>
                    </block>
               </block>
          </reference>
     </catalog_product_view>
</layout>

De la même manière que pour les produits en upsell, on indique ici le nombre de colonne par ligne, et le nombre de produits total à afficher.

il ne reste plus qu'à éditer le fichier du template utilisé pour la fiche produit, et à ajouter le bloc alsobought à l'endroit souhaité :

app/design/frontend/base/default/template/catalog/product/view.phtml

<!-- ... -->
<div class="product-collateral">
     <?php echo $this->getChildHtml('description') ?>
     <?php echo $this->getChildHtml('additional') ?>
     <?php echo $this->getChildHtml('upsell_products') ?>

     <!-- Les clients ayant acheté cet article ont également acheté -->
     <?php echo $this->getChildHtml('alsobought_products') ?>

     <?php echo $this->getChildHtml('product_additional_data') ?>
</div>
<!-- ... -->

Notez que pour éviter l'exécution des requêtes à chaque visualisation d'une fiche produit j'ai opté pour une mise en cache de ces informations. La durée de vie définie dans le constructeur du bloc Magentix_AlsoBought_Block_Bought est de 3600 secondes.

Le module est compatible avec les versions 1.3.X et 1.4.X de Magento.

commentaires

Commentez cet article : Module : Les clients ayant acheté cet article ont également acheté