Is it possible to sort the product collection based on another array that contains skus
-
16-10-2019 - |
Question
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?
Solution
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, ...);
OTHER TIPS
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.