Атрибут сортировки Magento по десятичной системе не алфавитно

Итак, я схожу с ума, как сумасшедший, чтобы попытаться найти решение этой проблемы, которая действительно работает правильно, но пришла с пустыми руками.

При использовании функции Sort By на странице категории для сортировки товаров по атрибуту (емкость, вес и т.д.). Magento подобен этому, потому что он считает, что это текстовая строка:

Продукт A: 10 кг

Продукт B: 11 кг

Продукт C: 15 кг

Продукт D: 9 кг

тогда как он должен выглядеть следующим образом:

Продукт D: 9 кг

Продукт A: 10 кг

Продукт B: 11 кг

Продукт C: 15 кг

Оглядываясь, кажется, что люди предлагают изменить backend_type на десятичные и frontend_input на цену в таблице eav_attribute для атрибутов, которые вы бы как сортировать численно. Однако это не только не работает, но и изменяет формат номера, чтобы иметь перед ним символ доллара ($), и потому, что мы отображаем фактическое значение атрибута на странице продукта, поверх его использования для сортировки, мы не работаем как исправление.

Я пытаюсь выяснить, как работает метод getSortOrder(), но похоже, что эта функциональность довольно глубоко встроена, поэтому я изо всех сил пытаюсь найти способ обхода этой ошибки.

Любая помощь приветствуется!

EDIT:

Для тех, кто хочет решить эту проблему в будущем, здесь исправление, которое я придумал:

Вам нужно переопределить функцию _getProductCollection() в List.php, которая хранится в приложении /Code/Mage/core/catalog/block/product/list.php.
Скопируйте файл в приложение/код/​​Mage/local/catalog/block/product/list.php, чтобы вы не редактировали файлы ядра.

Затем ниже, где говорится:

$this->_productCollection = $layer->getProductCollection();

Введите следующий код:

        // Start of Code to force Magento to numerically sort decimal attributes rather than alphabetically

        $filterAttribute = $this->getRequest()->getParam('order');
        $filterAttributeDir = $this->getRequest()->getParam('dir');
        $attributeType = Mage::getModel('eav/entity_attribute')->loadByCode('catalog_product', $filterAttribute)->getFrontendClass();

        // If a Sort By option is selected on category page and attribute has frontend_class = validate-number or validate-digits 
        // then CAST the attribute values as signed integers

        if (isset($filterAttribute) && ($attributeType == 'validate-digits' || $attributeType == 'validate-number')) {

            $this->_productCollection->getSelect()->reset(Zend_Db_Select::ORDER);
            $this->_productCollection->getSelect()->order('CAST(`' . $filterAttribute . '` AS SIGNED) ' . $filterAttributeDir . "'");

        }

        // End of code to force Magento to numerically sort....

Теперь, если у вас есть входная проверка для владельца магазина в панели администратора для атрибута, установленного на Десятичный номер или целочисленный номер:  attribute type Тогда этот код будет reset порядок сортировки в коллекции продуктов, а затем CAST его как целое число со знаком, так что он будет сортироваться численно, а не буквенно-цифровым способом.

Надеюсь, что это поможет кому-то!

Ответ 1

Итак, я нашел поток в этом в своей документации и, по-видимому, это известная точка боли для продукта. Лучшее решение, которое я нашел, состояло в том, чтобы переопределить ORDER BY для запроса, вызвав примитивный метод класса Collection, вот пример, который они дают:

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

$_productCollection->setOrder(array('cm_brand', 'name', 'cm_length'), 'asc');
$_productCollection->getSelect()->reset(Zend_Db_Select::ORDER);
$_productCollection->getSelect()->order(array('cm_brand ASC', 'name ASC', 'CAST(`cm_length` AS SIGNED) ASC'));

На основе вашего примера только с одним столбцом сортировки, я думаю, вы могли бы пойти с:

$_productCollection = Mage::getModel('catalog/product')->getCollection();
$_productCollection->setOrder('weight', 'asc');
$_productCollection->getSelect()->reset(Zend_Db_Select::ORDER);
$_productCollection->getSelect()->order('CAST(`weight` AS SIGNED) ASC'));

Ответ 2

В ответ на пост Адама Б.

Моя ситуация: мне нужно было сортировать продукты по специальному атрибуту Magento (1.8.1.0) с числовым значением. Однако Magento сортировался следующим образом:

1 , 11 , 123 ,2 ,234, 3 (буквенно-цифровой) вместо: 1, 2, 3, 11, 123, 234 (числовое)

Я честно не понимаю, почему это не работает из коробки, но я получил эту работу со следующей адаптацией:

$this->_productCollection->getSelect()->order(new Zend_Db_Expr("CAST( ".$filterAttribute." AS SIGNED ) ".$filterAttributeDir));

Надеюсь, что это кому-то понравится.

Ответ 3

Можете ли вы рассказать нам "Catalog Input Type for Store Owner"? Например, это текст или выпадаете? Я имею в виду, у вас есть столбец "position" в Magento Admin (Catalog- > Attributes- > Manage attributes- > Manage Label/Options- > Manage Options (значения вашего атрибута)). Если ваш атрибут является текстом, является ли фактическое значение строкой '9kg' или она '9' с 'kg' добавлена ​​позже?

В любом случае, если вы можете установить позицию в редакторе атрибутов, я думаю, что getSortOrder() поможет вам (подтвердите это, и кто-то может опубликовать ответ о getSortOrder()).

Если вы не можете установить позицию (потому что значения не заданы заранее), я думаю, вам нужно будет создать порядок сортировки продукта самостоятельно *, возможно, удалив буквы из значений атрибутов с помощью preg_replace() или str_replace(), сортируя по результату этого, а затем передавая новый отсортированный массив продуктов в циклы отображения - см. "грубый псевдокод" в этом ответе.

*, потому что я не думаю, что какие-либо встроенные общие функции сортировки могут сказать, что строка '9kg' меньше, чем строка '11kg' или '3V' меньше '18V'

** ИЗМЕНИТЬ следующий комментарий:

А, да, и я вижу, что Magento не имеет числового типа ввода для Catalog Input Type for Store Owner. Я думаю, что вы должны закодировать свою собственную сортировку в .phtml или связанном блочном php-классе (или если вы заранее знаете весы, это выпадающее меню, например 1,2,3,4... или 1,1, 1,2, 1,3...4.1, 4.2, 4.3... 19.9), тогда вы можете указать Magento позицию.

Вы можете уйти с типом ввода Date или даже с типом ввода Fixed product tax, но я считаю, что он просит проблему (и много тестирования).

План B может заключаться в том, чтобы добавить XML-код, который определяет новый тип ввода для Catalog Input Type for Store Owner, но я оставил бы это в основных разработчиках Magento - возможно, у них есть веская причина для хранения значений атрибутов в виде строк.

Если вы используете системный атрибут Weight, то это фиксируется как тип ввода text, и я думаю, что у вас нет другого выбора, кроме кодирования вашего собственного вида.

Я только что нашел

//file: app/code/core/Mage/Core/Model/Locale.php
//class: Mage_Core_Model_Locale
//...
     /*
     * @param string|float|int $value
     * @return float|null
     */
    public function getNumber($value){
//...

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

Ответ 4

Относительно ситуации "Атрибут с числовым значением" выше. У меня была та же проблема, и я сделал добавление кероса "0" перед моими значениями.

Например, мои значения: 208, 209, 355, 1152 и 1153.

Я добавил ceros: 00208, 00209, 00355, 01152 и 01153.

Теперь он работает!

Этот пост также помог мне:

http://blog.adin.pro/2014-04-30/magento-custom-sort-on-grid-sort-increment_id-by-numeric-not-alpha/

Надеюсь на эту помощь!

Ответ 5

Извините, я немного опаздываю на обсуждение. Поскольку я не против реализации программных решений, когда это не является строго необходимым, я попытался придумать более легкое решение. Я придумал следующее.

Пример сортировки проблем Исходный порядок сортировки: 10,0 ", 10,5", 14,0 ", 8,0", 8,5 "

Учитывая, что список чисел сортируется буквенно-цифровым образом, я решил, что добавление символов смещения пробела ("") до 8s в моем примере выше должно привести к правильному порядку. Так оно и было. Это было результатом.

Пример правильной сортировки Новый порядок сортировки: 8,0 ", 8,5", 10,0 ", 10,5", 14,0 "

В OP Адам мог бы просто заменить "9 кг" на "9 кг".

В добавлении, если рассматриваемые числа варьируются от одних значений до сотен значений, те значения будут иметь 2 ведущие пробелы, значения десятков будут иметь 1 начальное пространство и т.д.

Ответ 6

Для порядка сортировки по умолчанию:

        // Start of Code to force Magento to numerically sort decimal attributes rather than alphabetically
        $filterAttribute = Mage::getBlockSingleton('catalog/product_list_toolbar')->getCurrentOrder();
        //$filterAttribute = $this->getRequest()->getParam('order');
        $filterAttributeDir = Mage::getBlockSingleton('catalog/product_list_toolbar')->getCurrentDirection();
        //$filterAttributeDir = $this->getRequest()->getParam('dir');