[英]sort Magento collection AFTER load
Magento集合排序函數(例如Mage_Eav_Model_Entity_Collection_Abstract::addAttributeToSort
)通過向SQL select語句添加ORDER BY
子句來工作。 但是,有時候已經加載了一個集合,並且有必要對集合進行排序。
當然可以使用toArray($fields)
函數,然后使用PHP數組排序函數(本機或用戶定義),但這有點笨拙。 這也意味着集合中的對象被轉換為“啞”值的行,而沒有可以/可以用算法等實現的魔法getter / setter。
我想知道是否有更優雅/ Magento-esque方法對系列進行排序。
謝謝,
喬納森
沒有正確的方法。 但我認為使用反射是可能的。 您可以檢索集合對象的$ _items屬性,對它們進行排序並將其設置回集合。
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;
}
這是一個提示; 集合的clear
方法clear
它的加載標志,它允許您更改排序或過濾器並運行新查詢。
我在回答僅加載可配置產品時偶然發現了它。
@Ivan Chepurnyi的方法有效但返回一個ReflectionObject對象,在我的例子中我需要一個Varien_Data_Collection。
這是我做的事情
$collectionItems = $collection->getItems();
usort($collectionItems, array($this, '_sortItems'));
$newCollection = new Varien_Data_Collection();
foreach ($collectionItems as $item) {
$newCollection->addItem($item);
}
var_dump($newCollection);
如果這是排序方法
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;
}
}
另一種解決方案:
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;
}
}
上面的解決方案可以正常工作,但它比將查詢添加到查詢本身要慢得多,也更加密集。
如果你有一個大型集合,你將需要使用大量內存,因為你需要在每個結果前加載一個或多個對象並將它們全部存儲起來。
使用集合Magento將只從數據庫一次加載一行,這將比上述解決方案更有效:-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.