Intereting Posts
Невозможно изменить значение xml с помощью PHP textarea устанавливает высоту на основе содержимого js или jquery Переменная привязки для имени столбца в PHP для запроса Postgresql Сессии с cURL Попытка создать статический класс базы данных, доступ к которому я могу получить из любой функции вне класса Сохранять данные формы через несколько шагов в Laravel Как использовать графический API Facebook для извлечения фан-фотографий, загруженных на стену страницы поклонников? Используйте Require_once () для правильного включения переменных подключения базы данных Круговая диаграмма с разным процентом заполнения PHP: Как создать имена файлов в Юникоде Где использовать mysql_real_escape_string для предотвращения внедрения SQL? Как сделать левое присоединение к Доктрине? загрузка изображения в форму с помощью codeigniter / ajax PHP CURL ничего не возвращает PHP MongoDB обновляет несколько документов, используя $ in / $ или

сортировать коллекцию Magento ПОСЛЕ загрузки

Функции сортировки коллекции Magento (например, Mage_Eav_Model_Entity_Collection_Abstract::addAttributeToSort ) работают путем добавления предложения ORDER BY в оператор выбора SQL. Однако есть моменты, когда коллекция уже загружена, и необходимо сортировать коллекцию.

Конечно, возможно использовать функцию toArray($fields) а затем функции сортировки массива PHP (как собственные, так и пользовательские), однако это немного неуклюжие. Это также означает, что объекты в коллекции преобразуются в «немые» строки значений без магических геттеров / сеттеров, которые могут быть реализованы с помощью алгоритмов и т. Д.

Мне интересно, есть ли более элегантные / Magento-esque методы сортировки коллекции.

Благодаря,
Джонатан

Нет правильного способа сделать это. Но я думаю, что это возможно с использованием Reflection. Вы можете получить свойство $ _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 метод коллекции отключает флаг загрузки, он позволяет вам изменять сортировку или фильтры и запускать новый запрос.

Я случайно обнаружил это при ответе на нагрузку только на настраиваемые продукты .

Другое решение, которое работает:

 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; } } 

Метод @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; } } 

Вышеупомянутое решение будет работать нормально, но оно LOT медленнее и интенсивнее, чем добавление сортировки к самому запросу.

Если у вас большая коллекция, вы будете использовать огромный объем памяти, так как вам нужно загрузить объект (или объекты) для каждого результата и сохранить их все.

Использование коллекции Magento будет загружать только одну строку за раз из базы данных, которая будет намного более эффективной, чем вышеупомянутое решение 🙂