sort Magento collection AFTER load

后端 未结 5 1152
无人及你
无人及你 2020-12-09 07:02

The Magento collection sorting functions (e.g. Mage_Eav_Model_Entity_Collection_Abstract::addAttributeToSort) work by adding an ORDER BY clause to

相关标签:
5条回答
  • 2020-12-09 07:15

    Another solution which works:

    class Aligent_Navigation_Block_Dropdown extends Mage_Catalog_Block_Product_List {
    
    public function getProductsByShortDesc(){
        $data = $this->getLoadedProductCollection()->getItems();  //an array of objects
        usort($data,array('Aligent_Navigation_Block_Dropdown','sortByShortDesc'));
        return $data;
    }
    
    public static function sortByShortDesc($a, $b)
    {
      if($a->getShortDescription() ==  $b->getShortDescription()){ return 0 ; }
      return ($a->getShortDescription() < $b->getShortDescription()) ? -1 : 1;
    }
    }
    
    0 讨论(0)
  • 2020-12-09 07:27

    Here's a tip; A collection's clear method unsets it's loaded flag, it allows you to change the sort or filters and run the new query.

    I accidentally discovered it when answering load only configurable products.

    0 讨论(0)
  • The method of @Ivan Chepurnyi worked but returns a ReflectionObject object, in my case I needed a Varien_Data_Collection.
    Here is what I did instead

    $collectionItems = $collection->getItems();
    usort($collectionItems, array($this, '_sortItems'));
    $newCollection = new Varien_Data_Collection();
    
    foreach ($collectionItems as $item) {
        $newCollection->addItem($item);
    }
    
    var_dump($newCollection);
    

    And in case here is the sorting method

    public function _sortItems($a, $b)
    {
        $columnId = "your_column_that_you_need_to_sort";
        $dir      = "desc";
    
        $al = strtolower($a->getData($columnId));
        $bl = strtolower($b->getData($columnId));
    
        if ($al == $bl) {
            return 0;
        }
    
        if ($dir == 'asc') {
            return ($al < $bl) ? -1 : 1;
        } else {
            return ($al > $bl) ? -1 : 1;
        }
    }
    
    0 讨论(0)
  • 2020-12-09 07:33

    The above solution will work fine, but it's a LOT slower and more intensive than adding the sort to the query itself.

    If you have a large collection you will use a huge amount of memory as you need to load an object (or objects) fore each result and store them all.

    Using the collection Magento will only load one row at a time from the database which will be a lot more efficient than the above solution :-)

    0 讨论(0)
  • 2020-12-09 07:36

    There is no proper way of doing it. But I think it is possible with using of Reflection. You can retrieve $_items property of collection object, sort them and set it back to the collection.

    function sortCollection(Varien_Data_Collection $collection, callable $sorter) {
        $collectionReflection = new ReflectionObject($collection);
        $itemsPropertyReflection = $collectionReflection->getProperty('_items');
        $itemsPropertyReflection->setAccessible(true); // Make it accessible
    
        $collectionItems = $itemsPropertyReflection->getValue($collection);
    
        usort($collectionItems, $sorter);
    
        $itemsPropertyReflection->setValue($collection, $collectionItems);
    
        $itemsPropertyReflection->setAccessible(false); // Return restriction back
    
        return $collection;
    }
    
    0 讨论(0)
提交回复
热议问题