简体   繁体   English

Magento按十进制排序属性不是字母数字

[英]Magento Sort Attribute by Decimal not Alphanumerically

So I've Googled like crazy to try and find a solution to this problem that actually works properly but have come up empty handed. 所以我用谷歌搜索疯狂试图找到一个解决这个问题的方法,这个问题实际上是正常运行的,但却空手而归。

When using the Sort By function on a category page to sort products by an attribute (capacity ,weight etc). 在类别页面上使用“排序依据”功能时,可以按属性(容量,重量等)对产品进行排序。 Magento sorts like this because it thinks the number is a text string: Magento这样排序是因为它认为数字是一个文本字符串:

Product A: 10kg 产品A:10kg

Product B: 11kg 产品B:11kg

Product C: 15kg 产品C:15kg

Product D: 9kg 产品D:9kg

whereas it should sort like: 而它应该类似于:

Product D: 9kg 产品D:9kg

Product A: 10kg 产品A:10kg

Product B: 11kg 产品B:11kg

Product C: 15kg 产品C:15kg

Looking around it seems like people suggest to change backend_type to decimal and frontend_input to price in the eav_attribute table for attributes that you'd like to sort numerically. 环顾四周,好像人建议改变backend_type为十进制和frontend_input价格在eav_attribute表,你想用数字排序的属性。 However, not only does this not seem to actually work, but it changes the format of the number to have a dollar ($) symbol in front of it and because we display the actual attribute value on the product page, on top of using it to sort by, we doesn't work as a fix. 但是,这不仅实际上不起作用,而且它改变了数字的格式,在它前面有一个美元($)符号,因为我们在产品页面上显示实际属性值,在使用它之上排序依据,我们不能解决问题。

I'm trying to figure out exactly how the getSortOrder() method works but it looks like this functionality is pretty deeply embedded so I'm struggling to figure a workaround for this bug. 我正在试图弄清楚getSortOrder()方法是如何工作的,但看起来这个功能非常深入嵌入,所以我很难找到这个bug的解决方法。

Any help is appreciated! 任何帮助表示赞赏!

EDIT: 编辑:

For anyone looking to solve this issue in the future, here's the fix I came up with: 对于那些希望将来解决这个问题的人来说,这是我提出的解决方案:

You'll need to override the function _getProductCollection() in List.php that is stored in app/Code/Mage/core/catalog/block/product/list.php. 您需要覆盖List.php中存储在app / Code / Mage / core / catalog / block / product / list.php中的函数_getProductCollection()。
Copy the file to app/code/Mage/local/catalog/block/product/list.php so that you aren't editing core files. 将文件复制到app / code / Mage / local / catalog / block / product / list.php,这样就不会编辑核心文件。

Then below where it says: 然后在下面说:

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

Put the following code: 输入以下代码:

        // 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....

Now if you have Input Validation for Store Owner in the admin panel for the attribute set to Decimal Number or Integer Number: 现在,如果您在管理面板中对存储所有者进行输入验证,则将属性设置为十进制数或整数: 属性类型 Then this code will reset the sort order on a product collection and then CAST it as a signed integer so that it sorts numerically rather than alphanumerically. 然后,此代码将重置产品集合上的排序顺序,然后将其作为有符号整数进行CAST,以便按数字排序,而不是按字母数字排序。

Hope that helps someone! 希望有人帮助!

So I found a thread on this on their documentation, and apparently it's a known pain point for the product. 所以我在他们的文档找到了一个关于此线程 ,显然这是该产品的一个已知的痛点。 The best solution I found was to override the ORDER BY for the query by calling a primitive method of the Collection class, here's the example they give: 我找到的最佳解决方案是通过调用Collection类的原始方法来覆盖查询的ORDER BY ,这是他们提供的示例:

$_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'));

Based on your example with only one sorting column, I would think you could go with: 根据您的示例只有一个排序列,我认为您可以使用:

$_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'));

In response to Adam B's post. 回应Adam B的帖子。

My situation: I needed to sort products by a custom Magento (1.8.1.0) attribute with a numerical value. 我的情况:我需要通过带有数值的自定义Magento(1.8.1.0)属性对产品进行排序。 However, Magento was sorting like: 然而,Magento排序如下:

1 , 11 , 123 ,2 ,234, 3 (alphanumerical) instead of: 1, 2, 3, 11, 123, 234 (numerical) 1 , 11 , 123 ,2 ,234, 3 (字母数字)代替: 1, 2, 3, 11, 123, 234 (数字)

I honestly don't get why this is not working out of the box but I got this working with the following adaption: 老实说,我不明白为什么这不是开箱即用的工具,但我得到了以下适应性:

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

Hope it's to any use for someone. 希望这对某人有用。

Can you tell us the ' Catalog Input Type for Store Owner '? 您能告诉我们“ Catalog Input Type for Store OwnerCatalog Input Type for Store Owner ”吗? Eg is it text or drop down? 例如是文字还是下拉? I mean, do you have a 'position' column in the Magento Admin (Catalog->Attributes->Manage attributes->Manage Label / Options->Manage Options (values of your attribute)). 我的意思是,你在Magento Admin中有一个“位置”列(目录 - >属性 - >管理属性 - >管理标签/选项 - >管理选项(属性的值))。 If your attribute is text, is the actual value the string '9kg' or is it '9' with 'kg' added later? 如果您的属性是文本,实际值是字符串'9kg'还是'9'并且后来添加'kg'

Anyway, if you can set a position in the attribute editor then I think getSortOrder() will help you (confirm this and someone can post an answer about getSortOrder() ). 无论如何,如果你可以在属性编辑器中设置一个位置,那么我认为getSortOrder()会帮助你(确认这一点,有人可以发布关于getSortOrder()的答案)。

If you cannot set a position (because the values are not pre-determined) then I think you will need to create the product sort order yourself* by perhaps stripping out the letters from the attribute values with a preg_replace() or str_replace() , sorting on the result of that and then passing the new sorted product array into the display loop - see 'rough pseudo code' in this answer . 如果你不能设置一个位置(因为这些值没有预先确定),那么我认为你需要自己创建产品排序顺序*通过使用preg_replace()str_replace()从属性值中删除字母,对结果进行排序,然后将新的已排序产品数组传递到显示循环中 - 请参阅此答案中的“粗略伪代码”

*because I don't think any built-in generic sorting functions can tell the string '9kg' is less than teh string '11kg' or '3V' is less than '18V' *因为我不认为任何内置的通用排序功能可以告诉字符串'9kg'小于字符串'11kg''3V'小于'18V'

**EDIT following comment: **编辑以下评论:

Ah, yes, and I see Magento does not have a numeric input type for Catalog Input Type for Store Owner . 啊,是的,我看到Magento没有Catalog Input Type for Store Owner的数字输入类型。 I think you should code your own sorting in the .phtml or the associated block php class (or if you know the weights in advance make it a dropdown eg 1,2,3,4... or 1.1, 1.2, 1.3...4.1, 4.2, 4.3...19.9) then you can tell Magento the position. 我认为你应该在.phtml或相关的块php类中编码你自己的排序(或者如果你事先知道权重使它成为一个下拉列表,例如1,2,3,4 ...或1.1,1.2,1.3 .. .4.1,4.2,4.3 ...... 19.9)那么你可以告诉Magento这个位置。

You might get away with the Date input type or even the Fixed product tax input type but I reckon that is asking for trouble (and a lot of testing). 您可能会使用Date输入类型甚至Fixed product tax输入类型,但我认为这是在寻找麻烦(以及大量测试)。

Plan B might be to add some XML that defines a new numeric input type for Catalog Input Type for Store Owner but I'd leave that to the core Magento developers - maybe they have a good reason for storing attribute values as strings. B计划可能是添加一些XML, Catalog Input Type for Store Owner定义一个新的数字输入类型,但我将其留给核心Magento开发人员 - 也许他们有充分的理由将属性值存储为字符串。

If you are using the system attribute Weight then that is fixed as input type text and I think you have no choice other than coding your own sort. 如果您正在使用系统属性Weight那么它将被修复为输入类型text ,我认为除了编码自己的排序之外别无选择。

I just found 我刚发现

//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){
//...

Which could be useful. 哪个可能有用。 I don't think it will take you long to code your own sort. 我不认为你需要很长时间来编写自己的代码。

Regarding the "Attribute with Numerical Value" situation above. 关于上面的“具有数值的属性”的情况。 I had the same problem and what I did was adding ceros "0" in front of my values. 我有同样的问题,我所做的是在我的价值观前加上“0”。

For ex, my values were: 208, 209, 355, 1152 and 1153. 例如,我的价值观是:208,209,355,1152和1153。

I added ceros: 00208, 00209, 00355, 01152 and 01153. 我添加了ceros:00208,00209,00355,01152和01153。

It works now! 它现在有效!

This post also helped me: 这篇文章也帮助了我:

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

Hope this help! 希望这有帮助!

Sorry, I'm a little late to the discussion. 对不起,我讨论的时间有点晚了。 As I'm adverse to implementing code solutions when it isn't strictly necessary, I tried to think of an easier solution. 由于在不是绝对必要的情况下我不能实现代码解决方案,我试着想出一个更简单的解决方案。 I came up with the following. 我想出了以下内容。

Example problem sorting Original sorting order: 10.0", 10.5", 14.0", 8.0", 8.5" 示例问题排序原始排序顺序:10.0“,10.5”,14.0“,8.0”,8.5“

Given that the list of numbers is sorted alphanumerically, I deduced that adding offsetting space characters (" ") before the 8s in my example above should result in the correct ordering. 鉴于数字列表是按字母顺序排序的,我推断在上面的示例中在8s之前添加偏移空格字符(“”)应该导致正确的排序。 It did. 它做了。 This was the result. 这是结果。

Example correct sorting New sorting order: 8.0", 8.5", 10.0", 10.5", 14.0" 示例正确排序新排序顺序:8.0“,8.5”,10.0“,10.5”,14.0“

In the OP, Adam might have simple been able to replace "9kg" with " 9kg". 在OP中,亚当可能很简单地能够用“9kg”代替“9kg”。

By extension, if the numbers in question range from ones values to hundreds values, the ones values would have 2 leading spaces, the tens values would have 1 leading space, etc. 通过扩展,如果所讨论的数字从一个值到几百个值,那么这些值将具有2个前导空格,十个值将具有1个前导空格等。

For default sort order: 对于默认排序顺序:

        // 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');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM