Auto Populate Cross Sell with Products from Current Category Magento

April 16th, 2011 Posted by Public 26 comments on “Auto Populate Cross Sell with Products from Current Category Magento”

eCommerce Data is clear – you need to have cross sell items for every product in your catalog to help conversion.  The usual process consists of manually associating items in the Magento Admin interface.  This process works fine if you have hundreds or even a few thousand items – OR – you have this data in back end systems.

What happens if you don’t have the data and you have 15,000+ items in your catalog?

  • Hire someone to associate all products?
  • Randomly apply products in your data feed?
  • Develop custom code?

All of the above items are true for my Medical Supplies business – Medical Delivered so I needed a solution.  I decided to auto assign cross sell products on the front end on product page render.

In action: http://www.medicaldelivered.com/medline-k1-excel-wheelchair.html

Rules:

  1. The item must be “visible”
  2. The item must reside in the same category as the current item
  3. Don’t display the item from the current product detail page

Results:

  1. All products automatically have cross sells displayed
  2. No need to assign products on the back end
  3. BAD:  Less control over items displayed

This solution won’t work for everyone, if you are an advanced retailer you won’t want to lose this control but if you just want cross sells and don’t have the time/resources to define manually you can try the code below.

Path:  app/design/frontend/default/<template>/catalog/product/list/upsell.phtml

(you may need to create this path – make sure to replace <template> with your template name)


<?php
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE_AFL.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@magentocommerce.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magentocommerce.com for more information.
*
* @category   design_default
* @package    Mage
* @copyright  Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
* @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
* @author        Nick Cron
* @authorweb  www.njcmedia.com
*/
?>
<?php
$_related = $this->getProduct();
// get the parent id to skip
$_parentid = $_related->getId();

if ($_related) {
// get collection of categories this product is associated with
$categories =$_related->getCategoryCollection()
->setPage(1, 1)
->load();

// if the product is associated with any category
if ($categories->count())
foreach ($categories as $_category)
{
$cur_category = Mage::getModel('catalog/category')->load($_category->getId());

?>

<div>
<div><h4><?php echo $this->__('You may also be interested in the following product(s)') ?></h4></div>
<table cellspacing="0" id="upsell-product-table">

<tr>

<?php

$visibility = array(
Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG
);

$products = Mage::getResourceModel('catalog/product_collection')
->addCategoryFilter($_category)
->addAttributeToFilter('visibility', $visibility)
->addAttributeToSelect('small_image');

$products->getSelect()->limit(5);

// count the number of displayed products
$_i=0;

foreach ( $products as $productModel )       {
$_related = Mage::getModel('catalog/product')->load($productModel->getId());
$_realtedid = $_related->getId();

// prevents displaying the same product your are already on
if ($_realtedid != $_parentid && $_i<4):

?>

<td>
<p><a href="<?php echo $_related->getProductUrl() ?>"><img src="<?php echo $this->helper('catalog/image')->init($_related, 'small_image')->resize(125) ?>" width="125" height="125" alt="<?php echo $this->htmlEscape($_related->getName()) ?>" /></a></p>
<h5><a href="<?php echo $_related->getProductUrl() ?>"><?php echo $this->htmlEscape($_related->getName()) ?></a></h5>

<?php echo $this->getPriceHtml($_related, true) ?>
<?php echo $this->getReviewsSummaryHtml($_related) ?>
</td>

<?php
// increment displayed products
$_i++;
endif;
}
?>

</tr>

<?php }
}
?>
</table>
<script type="text/javascript">decorateTable('upsell-product-table')</script>
</div>

Room for improvement:

  1. Display items from the back end if exist
  2. Display only items with images
  3. ..?

I hope this helps someone.  If you have any suggestions for improvement or code upgrades/fixes please let me know in the comments.

Tags: , , ,
  • Lniculescu

    Based on color attribute would be nice. (or eny attribute)

  • Franck

    Excellent !!! Thanks a lot. I don’t understand why nobody already sells an extension like that !

  • Lex

    G E N I A L

    Thanks for sharing

  • Mark

    Dear Nick,

    Can you help me with something?

  • Mark

    This code works for me, but I want to keep the look & feel of my template… How can I do that? Now the images are to small and don’t light up when mouse-over… Hope somebody can help, because my site goes live tomorrow!

    upsell.phtml – em0023 template:

    ?>
    get_upsell_width();
    $h = $image->get_upsell_height();
    $bg = $image->get_upsell_bgcolor(); 
    ?>
    getItemCollection()->getItems())): ?>

        __(‘You may also be interested in the following product(s)’) ?>
       
        setColumnCount(5); // uncomment this line if you want to have another number of columns. also can be changed in layout ?>
        resetItemsIterator() ?>
        <?php for($_i=0;$_igetRowCount();$_i++): ?>
           
            <?php for($_j=0;$_jgetColumnCount();$_j++): ?>
                getIterableItem()): ?>
               
                    <a href="getProductUrl() ?>” title=”htmlEscape($_link->getName()) ?>” class=”product-image”><img style="background-color:” src=”helper(‘catalog/image’)->init($_link, ‘small_image’)->resize($w,$h) ?>” width=”” height=”” alt=”htmlEscape($_link->getName()) ?>” />
                    <a href="getProductUrl() ?>” title=”htmlEscape($_link->getName()) ?>”>htmlEscape($_link->getName()) ?>
                    getPriceHtml($_link, true, ‘-upsell’) ?>
                    getReviewsSummaryHtml($_link) ?>
               
               
           
           
       
       
        decorateTable(‘upsell-product-table’)

    • Nick Cron

      Mark – This is likely a CSS issue. If you send me a link I can take a quick look and see what I can come up with.

  • leozzz

    Products in different category come out! Strange part is , their url has http://xxxxxx/category%5Bid%5D where the id is the same category of the currently viewing page but the belongs to that related product!

    • leozzz

      Sorry for typo:
      Products in different category come out! Strange part is , their url has
      http://xxxxxx/category%5Bid%5D where the id is the same category of the
      currently viewing page but “NOT” belongs to that related product!

      • leozzz

        i finally got the bug and solution. That is because my categories has 3-4 levels, by the code you provide, the related product share the most common 1st level category.
        For me, the related product is meant by sharing the same brand, that is the 3rd level category, so i add the “level” filter with value 3

        // get collection of categories this product is associated with
        $categories =$_related->getCategoryCollection()->addFieldToFilter(‘level’,’3′)  ->setPage(1, 1)->load();

  • Mendel Kramer

    Is there any way to do this with “crossselling” as opposed to “upselling” ?? Thanks

    • Nick Cron

      Mendel – this code does not really upsell or cross sell. It just pulls random products from the same category. If you want to set up specific cross or up sells you can do this in the Magento admin.

  • Anonymous

    It looks like the last items are displayed first. is it possible to change the sort order so that the first item of a category is also the first that is displayed? thank you!

  • Mlieberum

    Nothing ist happening in magento 1.5.1
    i have created the file, but no cross-sell products are displayed.

  • Insomnia24

    This is good but itcould be better like not showing out of stock products and can show like 8 products instead of 4  or 2 products.

  • Jainvishal2005

    hi after applying this code in phtml its taking only first four id in all the products. i want random i got 900 products in my catalog. can you help me out.
    thanks

  • Jim

    Thanks so much for this code. It helped me immensely. I added a few things right after product collection, and before select limit. Check it out.

    // Limiting to  In Stock
    Mage::getSingleton(‘cataloginventory/stock’)->addInStockFilterToCollection($products);

    // Sorting collection randomly
    $products->getSelect()->order(new Zend_Db_Expr(‘RAND()’));

    • Ahmed

      Would u please send the complete code after your addition ?

      • Jim

        The code is like this now:

        $products = Mage::getResourceModel('catalog/product_collection')
        ->addCategoryFilter($_category)
        ->addAttributeToSelect('small_image')
        ->addAttributeToFilter('visibility', $visibility);

        // Limiting to In Stock
        Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($products);

        // Sorting collection randomly
        $products->getSelect()->order(new Zend_Db_Expr('RAND()'));

        $products->getSelect()->limit(4);

        I just added the In Stock and Randomness as shown here.

        • Third

          Hi, thanks for this!

          I was able to make it work. I set my 5 of my products (both simple and configurable) into 1 category. Everything works fine except for the following:

          1. $products->getSelect()->limit(4); <—- shows only 3 products

          2. When i go to the configurable product page, nothing shows in the You may also be interested in the following product(s) area

          Thanks

  • http://www.facebook.com/karanveer.singh.581 Karanveer Singh Kamboj

    worked beautifully!!!!

  • Third

    Hi, thanks for this!

    I was able to make it work. I set my 5 of my products (both simple
    and configurable) into 1 category. Everything works fine except for the
    following:

    1. $products->getSelect()->limit(4); <—- shows only 3 products

    2. When i go to the configurable product page, nothing shows in the You may also be interested in the following product(s) area

    Thanks

  • Drew

    Any ideas how I can filter the results based on a the color attribute within the same category?

    Thanks in advance

  • mau

    Thank you very much, it’s working for me on 1.8.

  • Sarah Robertson

    I use an extension for related products (Customers also viewed by Amasty). They are added automatically depending on their popularity. I created a rule to show products only from the same category.

  • pauls

    Good stuff, thanks for sharing.
    I faced some issues with images, images are not shown in desired size.
    I used one Who Bought This Also Bought This by FME, which works great.

  • http://www.fmemodules.com/ Amelia Johns

    The tips are quite good in the sense that they are equally useful for all platforms like I have a PrestaShop FME Store and I can make use of them easily. Additionally, I want to ask that is there important to place keywords for your website home page??? I think Google don’t considers them now.