Question

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>
Was it helpful?

Solution

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 ;?>
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top