2

I'm creating an events observer module which will group upsell products by category,

below is my module's model/observer.php file,

public function updateUpsells($observer)
    {
        $iCurrentCategory = Mage::registry('current_category')->getId();
        $event = $observer->getEvent();
        $oUpsellCollection = $event->getCollection();
        foreach ($oUpsellCollection->getItems() as $key => $oUpsellProduct) {
            $aCategoriesIds = $oUpsellProduct->getCategoryIds();
            if (!in_array($iCurrentCategory, $aCategoriesIds)) {
                $oUpsellCollection->removeItemByKey($key);
            }
        }
    }
}

After enabling this module, i can include upsell product's category id's in upsell.phtml file by echo $this->getItemCollection()->getItems()

as a result i got,

    Array
(
    [170] => Mage_Catalog_Model_Product Object
        ( 
           .........................
           [_data:protected] => Array
                (
                    [entity_id] => 170
                    [entity_type_id] => 10
                    [attribute_set_id] => 44
                    [type_id] => simple
                    [category_ids] => Array
                        (
                            [0] => 12
                            [1] => 26
                        )
                    .......................

           )
    [171] => Mage_Catalog_Model_Product Object
        ( 
           .........................
           [_data:protected] => Array
                (
                    [entity_id] => 171
                    [entity_type_id] => 10
                    [attribute_set_id] => 44
                    [type_id] => simple
                    [category_ids] => Array
                        (
                            [0] => 16
                            [1] => 24
                        )
                    .......................

           )
)

So now how can i group this array results by category. Example mentioned 2 upsell products assigned to 4 different categories, as a result i need to group products like,

Category id 12
  product1 | Product2

Category id 26
  product1 | Product2

My Upsell.phtml file,

<?php
    $helper = Mage::helper('rainbowsettings');
    $w  =   $helper->getUpsell_Width(150);
    $h  =   $helper->getUpsell_Height(150);
?>
<div class="box-collateral box-up-sell">
    <h2><strong><span><?php echo $this->__('You Might Also Like') ?></span></strong></h2>

    <?php

    $byCategory = array();
    $noCategory = array();
    foreach ($this->getItemCollection()->getItems() as $item) {
        $categoryIds = $item->getCategoryIds();
        if (is_array($categoryIds)) { //if item has categories
            foreach ($categoryIds as $categoryId) { //match the item with the categories
                if (!isset($byCategory[$categoryId])) {
                    $byCategory[$categoryId] = array();
                }
                $byCategory[$categoryId][] = $item;
            }
        }
        else {//if the item is not in a category
            $noCategory[] = $item;
        }
    }

    if (count($noCategory) > 0) {
        $byCategory[0] = $noCategory;
    }
    ?>
    <?php foreach ($byCategory as $categoryId=>$items) : ?>
        <?php if ($categoryId) : ?>
            <?php $category = Mage::getModel('catalog/category')->setStoreId(Mage::app()->getStore()->getId()->load($categoryId))?>
            <a href="<?php echo $category->getUrl()?>"><?php echo $category->getName()?></a>
        <?php else : ?>
            <span><?php echo $this->__('Not Categorized')?></span>
        <?php endif;?>
        <?php foreach ($items as $_link) : ?>
             <!-- HTML for displaying a product goes here -->
             <div id="">
                <ul class="">
                    <?php $this->resetItemsIterator() ?>

                        <li class="item <?php if($_link->getData('gala_label_style') == '')echo 'corner';else echo $_link->getData('gala_label_style'); ?><?php if($i == 0):?> first<?php elseif($i == $count-1):?> last<?php endif ?>">
                            <div class="product-item">
                                <?php Mage::helper('productlabels')->display($_product); ?>
                                <a href="<?php echo $_link->getProductUrl() ?>" title="<?php echo $this->escapeHtml($_link->getName()) ?>" class="product-image">
                                    <img src="<?php echo $this->helper('catalog/image')->init($_link, 'small_image')->resize($w,$h) ?>" width="<?php echo $w ?>" height="<?php echo $h ?>" alt="<?php echo $this->escapeHtml($_link->getName()) ?>" />
                                </a>

                                <div class="product-shop product-shop-color">
                                    <div class="f-fix">
                                        <div class="f-fix-content">

                                            <h3 class="product-name"><a href="<?php echo $_link->getProductUrl() ?>" title="<?php echo $this->escapeHtml($_link->getName()) ?>"><?php echo $this->escapeHtml($_link->getName()) ?></a></h3>

                                            <p class="sku"><?php echo $_link->getSKU()?></p>

                                            <?php echo $this->getReviewsSummaryHtml($_link,"short") ?>

                                            <?php echo $this->getPriceHtml($_link, true, '-upsell') ?>

                                        </div>
                                    </div>
                                </div>
                            </div>
                        </li>
                </ul>
          </div>
        <?php endforeach;?>
    <?php endforeach ;?>
</div>

1 Answer 1

3

You can add this in the upsell template o in the observer (but in this case you still have to modify the upsell template).

$byCategory = array();
$noCategory = array();
foreach ($this->getItemCollection()->getItems() as $item) {
    $categoryIds = $item->getCategoryIds();
    $categoryFound = false;
    if (is_array($categoryIds)) { //if item has categories
        foreach ($categoryIds as $categoryId) { //match the item with the categories
             if ($categoryId == Mage::app()->getStore()->getRootCategoryId()) {
                  continue;
             }
             if (!isset($byCategory[$categoryId])) {
                 $byCategory[$categoryId] = array();
             }
             $byCategory[$categoryId][] = $item;
             $categoryFound = true;
        }
    }
    if (!$categoryFound) {//if the item is not in a category
        $noCategory[] = $item;
    }
}

Now add the products that are not in a category at the end of the array so you won't duplicate any of the code below.

if (count($noCategory) > 0) {
    $byCategory[0] = $noCategory;
}

Now you should have the items split by categories.
To display them do this:

<?php foreach ($byCategory as $categoryId=>$items) : ?>
    <?php if ($categoryId) : ?>
        <?php $category = Mage::getModel('catalog/category')->setStoreId(Mage::app()->getStore()->getId())->load($categoryId)?>
        <a href="<?php echo $category->getUrl()?>"><?php echo $category->getName()?></a>
    <?php else : ?>
        <span><?php echo $this->__('Not Categorized')?></span>
    <?php endif;?>
    <?php foreach ($items as $item) : ?>
         <!-- HTML for displaying a product goes here -->
    <?php endforeach;?>
<?php endforeach ;?>
5
  • Thanks for your quick reply. As like you mentioned i've modified upsell.phtml, Unfortunately i'm getting this error Fatal error: Call to a member function load() on a non-object in ..\template\catalog\product\list\upsell.phtml on line 63 i added my upsell.phtml file in question can you plz have a look of where i'm doing wrong ? Commented Mar 11, 2014 at 7:38
  • @user2098059. C**p. I closed a ). Later than I should. This: $category = Mage::getModel('catalog/category')->setStoreId(Mage::app()->getStore()->getId()->load($categoryId)) should be $category = Mage::getModel('catalog/category')->setStoreId(Mage::app()->getStore()->getId())->load($categoryId). I've edited the answer.
    – Marius
    Commented Mar 11, 2014 at 7:44
  • You are the man. It worked like a charm. One last question, is there any way to skip parent category ? Commented Mar 11, 2014 at 7:54
  • @user2098059. I've modified the answer to exclude the root category. I haven't tested it so there is a chance you will get some errors, but the idea is right. I'm sure.
    – Marius
    Commented Mar 11, 2014 at 8:04
  • It Worked. I'm trying to order those products by it's ordered quantity (Wanna show best selling one on top). Is is possible to do with same event observer ? Commented Mar 15, 2014 at 7:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.