2

I have an array that contains some SKUs belonging to the current category.

I want to reorder the collection based on that array so that the SKUs present in my order array will come first.

For this i have been trying to edit the list.phtml file

$category = Mage::registry('current_category');
$inArray = explode(',', $category->getData('top_skus'));

usort($_productCollection, function($a, $b) use ($inArray){ 
    print_r($a);
    $aAge = $a['sku'];
    $bAge = $b['sku'];
    $aWeight = 0;
    $bWeight = 0;
    if (in_array($aAge, $inArray)) 
        $aWeight++;

    if (in_array($bAge, $inArray)) 
        $bWeight++;

    if ($aWeight != $bWeight) {
        return $aWeight > $bWeight ? -1 : 1;
    } else if ($aWeight > 0) {
        // need to sort by order which specified in array
        $aIndex = array_search($aAge, $inArray);
        $bIndex = array_search($bAge, $inArray);
        return ($aIndex == $bIndex ? 0 : ($aIndex > $bIndex ? 1 : -1));
    } else {
        // just compare age values
        return ($aAge == $bAge ? 0 : ($aAge > $bAge ? 1 : -1));
    }
});

I am getting an error like this

Warning: usort() expects parameter 1 to be array, object given  in C:\wamp\www\magento1\app\design\frontend\base\default\template\catalog\product\list.phtml on line 74

How to supply the array that contains the products to my usort? From where i will get that array?

2

I assume you are constructing the collection like this:

$_productCollection = Mage::getModel('catalog/product')->getCollection()->...;

and then calling

usort($_productCollection, ...)

it doesn't work because $_productCollection is not an array, but you figured that out from the error message (I'm just being Captain Obvious).
You can try this instead.

$productArray = (array)$_productCollection->getIterator();
usort($productArray, ...);
  • I did it using normal php foreach with a wiered code.its working.. once i get time i will test this code and give u feedback, thanks for your time – zamil Nov 11 '13 at 10:32
  • I am getting product collection like this in my phtml $_productCollection = $this->getLoadedProductCollection();but the output of $productArray = $_productCollection->getIterator(); echo is_object($productArray); is true, which means it is still an object – zamil Nov 11 '13 at 12:47
  • @zamil. I've edited the answer. I forgot a cast to array() – Marius Nov 11 '13 at 12:49
  • That works perfect, But is there any way to make these changes to the object $_productCollection so that i don't need to change the $_productCollection from the foreach loop.just asking for a suggestion – zamil Nov 11 '13 at 13:09
3

I've done this a while back for a shop that required sorting by a specific value present in the object of each item in the product collection.

For this I created a custom extension and extended the Mage_Catalog_Block_Product_List class as shown below.

class [Namespace]_[Module]_Block_Mage_Catalog_Product_List extends Mage_Catalog_Block_Product_List
{

    protected function _getProductCollection()
    {

        if( is_object(Mage::registry('current_category')) ) {
            $collection = Mage::getResourceModel('catalog/product_collection')->addCategoryFilter(Mage::registry('current_category'));
        } else {
            $collection = Mage::getResourceModel('catalog/product_collection');
        }
        Mage::getModel('catalog/layer')->prepareProductCollection($collection);

        $collection->addAttributeToSelect('category_sort_value');


        // Do some fancy sorting
        $collectionReflection = new ReflectionObject($collection);
        $itemsPropertyReflection = $collectionReflection->getProperty('_items');
        $itemsPropertyReflection->setAccessible(true); // Make it accessible

        $collectionItems = $itemsPropertyReflection->getValue($collection);

        usort($collectionItems, array("[Namespace]_[Module]_Block_Mage_Catalog_Product_List", "cmp"));

        $itemsPropertyReflection->setValue($collectionReflection, $collectionItems);

        $itemsPropertyReflection->setAccessible(false); // Return restriction back
        // End them fancyness


        $this->_productCollection = $collection;

        return $this->_productCollection;
    }


    public function cmp($a, $b) 
    {
        $a_sort = (int)$a->getData('category_sort_value');
        $b_sort = (int)$b->getData('category_sort_value');

        if ($a_sort == $b_sort) return 0;
        return ($a_sort < $b_sort) ? -1 : 1;
    }
}

This basically is a fancy version of usort for objects. Small sidenote... you need PHP 5.3 for this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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