【问题标题】:Magento 1.9.1 not sorting Configurable product attributes dropdown by positionMagento 1.9.1 未按位置对可配置产品属性下拉列表进行排序
【发布时间】:2015-01-31 23:14:50
【问题描述】:

全新安装 Magento 1.9.1。

Magento 忽略了在目录->属性->管理属性->管理标签/选项中为可配置产品下拉菜单设置的属性位置。相反,它使用产品 ID 来确定列表顺序。

比较了以下文件/函数,除了少量的税收计算,自 1.7.0.2 以来代码都没有改变。

Mage/Catalog/Model/Product/Type/Configuarable.php:

public function getConfigurableAttributes($product = null)

Mage/Catalog/Model/Product/Option.php:

public function getProductOptionCollection(Mage_Catalog_Model_Product $product)

Mage/Catalog/Block/Product/View/Type/Configuarable.php:

public function getJsonConfig()

我也在一个现场网站的副本数据库上进行了测试,所有的属性排序都是基于产品 ID。

复制:

  1. 创建属性 - 颜色
  2. 添加标签 - 黑色、红色、绿色、蓝色
  3. 保存属性。
  4. 使用上述顺序中的属性创建可配置且简单的关联产品。

编辑属性和更改标签位置。蓝色 0、绿色 1、红色 3、黑色 4

查看产品时,Magento 仍然按产品 ID 对属性进行排序并忽略位置。

【问题讨论】:

  • 有人对如何将排序顺序设置回位置有任何想法吗?

标签: sorting magento attributes position


【解决方案1】:

Meogi 的答案有效,但不是完美的答案,因为它只会对前端的选项进行排序。尝试从管理面板创建可配置产品的订单。您仍然会得到排序错误的属性选项列表。

相反,您可以将 app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute/Collection.php 复制到本地文件夹 app/code/local/Mage/Catalog/Model/Resource/ Product/Type/Configurable/Attribute/Collection.php 并应用此补丁:

Index: app/code/local/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
===================================================================
--- app/code/local/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
+++ app/code/local/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
@@ -301,7 +301,28 @@
                     }
                 }
             }

+            /**
+             * Mage 1.9+ fix for configurable attribute options not sorting to position
+             * @author Harshit <support@cubixws.co.uk>
+             */
+            $sortOrder = 1;
+            foreach ($this->_items as $item) {
+                $productAttribute = $item->getProductAttribute();
+                if (!($productAttribute instanceof Mage_Eav_Model_Entity_Attribute_Abstract)) {
+                    continue;
+                }
+                $options = $productAttribute->getFrontend()->getSelectOptions();
+                foreach ($options as $option) {
+                    if (!$option['value']) {
                         continue;
                     }

+                    if (isset($values[$item->getId() . ':' . $option['value']])) {
+                        $values[$item->getId() . ':' . $option['value']]['order'] = $sortOrder++;
+                    }
+                }
+            }
+            usort($values, function ($a, $b) {
+                return $a['order'] - $b['order'];
+            });
+            
             foreach ($values as $data) {
                 $this->getItemById($data['product_super_attribute_id'])->addPrice($data);
             }

如果您对将核心文件复制到本地文件夹犹豫不决,那么我可以创建一个快速模块,&lt;rewrite&gt; 这个 Collection.php 文件,然后覆盖 _loadPrices() 函数并引入此修复程序。

【讨论】:

  • 我修补了文件并为那些不知道如何操作的人创建了一个演练magentosupport.help/knowledgebase/…
  • is also an answer here 做了类似的事情,但在本地模块中而不是基于文件的覆盖
  • @Harshit,感谢您的解决方案。我已经把它放在一个模块 here 中,供任何想要它的人使用。
【解决方案2】:

根据 Magento 的说法,这个问题将在 CE 1.9.3.0 中修复

Magento 团队 |发布于 2015 年 8 月 14 日下午 4:02

该问题计划在 2016 年上半年发布的下一个次要(非补丁)版本。

来源:https://www.magentocommerce.com/bug-tracking/issue/index/id/413

【讨论】:

    【解决方案3】:

    只是为了增加我的两分钱,其他两个答案很好地为我指明了修复的方向,但我认为我会从源头而不是块呈现点攻击它。

    您可以通过扩展 Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection 模型的 _loadPrices() 方法来获得相同的结果,尽管名称是进行更改的地方(可能是为了性能),导致属性按 ID 而非相关性排序。

    所做的更改似乎是为了避免嵌套的foreach 语句,但反过来也丢失了正确的顺序。该方案稍微修改了更新后的逻辑以跟踪属性选项,然后根据原始顺序执行另一个循环以实际进行添加。

    这是一个类似于meogi's answer above 的调整后的演练:


    第一步:注册一个新模块

    注意:如果您已经拥有一个,请重新使用现有的。

    # File: app/etc/modules/YourCompany_AttributeFix.xml
    <?xml version="1.0"?>
    <config>
        <modules>
            <YourCompany_AttributeFix>
                <active>true</active>
                <codePool>local</codePool>
                <depends>
                    <Mage_Catalog />
                </depends>
            </YourCompany_AttributeFix>
        </modules>
    </config>
    

    第 2 步:创建模块的配置

    # File: app/code/local/YourCompany/AttributeFix/etc/config.xml
    <?xml version="1.0"?>
    <config>
        <modules>
            <YourCompany_AttributeFix>
                <version>0.1.0</version>
            </YourCompany_AttributeFix>
        </modules>    
        <global>
            <models>
                <catalog_resource>
                    <rewrite>
                        <product_type_configurable_attribute_collection>YourCompany_AttributeFix_Model_Resource_Product_Type_Configurable_Attribute_Collection</product_type_configurable_attribute_collection>
                    </rewrite>
                </catalog_resource>
            </models>
        </global>
    </config>
    

    第三步:添加资源模型扩展

    # File: app/code/local/YourCompany/AttributeFix/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
    /**
     * Catalog Configurable Product Attribute Collection - overridden to re-enable the attribute option
     * sorting by relevance rather than by ID as changed in the Magento core class
     */
    class YourCompany_AttributeFix_Model_Resource_Product_Type_Configurable_Attribute_Collection
        extends Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection
    {
        /**
         * Load attribute prices information
         *
         * @return Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection
         */
        protected function _loadPrices()
        {
            if ($this->count()) {
                $pricings = array(
                    0 => array()
                );
    
                if ($this->getHelper()->isPriceGlobal()) {
                    $websiteId = 0;
                } else {
                    $websiteId = (int)Mage::app()->getStore($this->getStoreId())->getWebsiteId();
                    $pricing[$websiteId] = array();
                }
    
                $select = $this->getConnection()->select()
                    ->from(array('price' => $this->_priceTable))
                    ->where('price.product_super_attribute_id IN (?)', array_keys($this->_items));
    
                if ($websiteId > 0) {
                    $select->where('price.website_id IN(?)', array(0, $websiteId));
                } else {
                    $select->where('price.website_id = ?', 0);
                }
    
                $query = $this->getConnection()->query($select);
    
                while ($row = $query->fetch()) {
                    $pricings[(int)$row['website_id']][] = $row;
                }
    
                $values = array();
    
                foreach ($this->_items as $item) {
                    $productAttribute = $item->getProductAttribute();
                    if (!($productAttribute instanceof Mage_Eav_Model_Entity_Attribute_Abstract)) {
                        continue;
                    }
                    $options = $productAttribute->getFrontend()->getSelectOptions();
    
                    $optionsByValue = array();
                    foreach ($options as $option) {
                        $optionsByValue[$option['value']] = $option['label'];
                    }
    
                    /**
                     * Modification to re-enable the sorting by relevance for attribute options
                     * @author Robbie Averill <robbie.averill@kathmandu.co.nz>
                     */
                    $toAdd = array();
                    foreach ($this->getProduct()->getTypeInstance(true)
                                 ->getUsedProducts(array($productAttribute->getAttributeCode()), $this->getProduct())
                             as $associatedProduct) {
    
                        $optionValue = $associatedProduct->getData($productAttribute->getAttributeCode());
    
                        if (array_key_exists($optionValue, $optionsByValue)) {
                            $toAdd[] = $optionValue;
                        }
                    }
    
                    // Add the attribute options, but in the relevant order rather than by ID
                    foreach (array_intersect_key($optionsByValue, array_flip($toAdd)) as $optionValueKey => $optionValue) {
                        // If option available in associated product
                        if (!isset($values[$item->getId() . ':' . $optionValue])) {
                            // If option not added, we will add it.
                            $values[$item->getId() . ':' . $optionValueKey] = array(
                                'product_super_attribute_id' => $item->getId(),
                                'value_index'                => $optionValueKey,
                                'label'                      => $optionsByValue[$optionValueKey],
                                'default_label'              => $optionsByValue[$optionValueKey],
                                'store_label'                => $optionsByValue[$optionValueKey],
                                'is_percent'                 => 0,
                                'pricing_value'              => null,
                                'use_default_value'          => true
                            );
                        }
                    }
                    /**
                     * End attribute option order modification
                     * @author Robbie Averill <robbie.averill@kathmandu.co.nz>
                     */
                }
    
                foreach ($pricings[0] as $pricing) {
                    // Addding pricing to options
                    $valueKey = $pricing['product_super_attribute_id'] . ':' . $pricing['value_index'];
                    if (isset($values[$valueKey])) {
                        $values[$valueKey]['pricing_value']     = $pricing['pricing_value'];
                        $values[$valueKey]['is_percent']        = $pricing['is_percent'];
                        $values[$valueKey]['value_id']          = $pricing['value_id'];
                        $values[$valueKey]['use_default_value'] = true;
                    }
                }
    
                if ($websiteId && isset($pricings[$websiteId])) {
                    foreach ($pricings[$websiteId] as $pricing) {
                        $valueKey = $pricing['product_super_attribute_id'] . ':' . $pricing['value_index'];
                        if (isset($values[$valueKey])) {
                            $values[$valueKey]['pricing_value']     = $pricing['pricing_value'];
                            $values[$valueKey]['is_percent']        = $pricing['is_percent'];
                            $values[$valueKey]['value_id']          = $pricing['value_id'];
                            $values[$valueKey]['use_default_value'] = false;
                        }
                    }
                }
    
                foreach ($values as $data) {
                    $this->getItemById($data['product_super_attribute_id'])->addPrice($data);
                }
            }
            return $this;
        }
    }
    

    第 4 步:清除缓存


    供参考git diff 中核心类的实际更改如下(不要直接编辑核心文件!):

    diff --git a/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute/Collection.php b/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
    index 135d9d3..4d2a59b 100644
    --- a/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
    +++ b/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
    @@ -254,6 +254,11 @@ class Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection
                         $optionsByValue[$option['value']] = $option['label'];
                     }
    
    +                /**
    +                 * Modification to re-enable the sorting by relevance for attribute options
    +                 * @author Robbie Averill <robbie.averill@kathmandu.co.nz>
    +                 */
    +                $toAdd = array();
                     foreach ($this->getProduct()->getTypeInstance(true)
                                  ->getUsedProducts(array($productAttribute->getAttributeCode()), $this->getProduct())
                              as $associatedProduct) {
    @@ -261,22 +266,31 @@ class Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection
                         $optionValue = $associatedProduct->getData($productAttribute->getAttributeCode());
    
                         if (array_key_exists($optionValue, $optionsByValue)) {
    -                        // If option available in associated product
    -                        if (!isset($values[$item->getId() . ':' . $optionValue])) {
    -                            // If option not added, we will add it.
    -                            $values[$item->getId() . ':' . $optionValue] = array(
    -                                'product_super_attribute_id' => $item->getId(),
    -                                'value_index'                => $optionValue,
    -                                'label'                      => $optionsByValue[$optionValue],
    -                                'default_label'              => $optionsByValue[$optionValue],
    -                                'store_label'                => $optionsByValue[$optionValue],
    -                                'is_percent'                 => 0,
    -                                'pricing_value'              => null,
    -                                'use_default_value'          => true
    -                            );
    -                        }
    +                        $toAdd[] = $optionValue;
                         }
                     }
    +
    +                // Add the attribute options, but in the relevant order rather than by ID
    +                foreach (array_intersect_key($optionsByValue, array_flip($toAdd)) as $optionValueKey => $optionValue) {
    +                    // If option available in associated product
    +                    if (!isset($values[$item->getId() . ':' . $optionValue])) {
    +                        // If option not added, we will add it.
    +                        $values[$item->getId() . ':' . $optionValueKey] = array(
    +                            'product_super_attribute_id' => $item->getId(),
    +                            'value_index'                => $optionValueKey,
    +                            'label'                      => $optionsByValue[$optionValueKey],
    +                            'default_label'              => $optionsByValue[$optionValueKey],
    +                            'store_label'                => $optionsByValue[$optionValueKey],
    +                            'is_percent'                 => 0,
    +                            'pricing_value'              => null,
    +                            'use_default_value'          => true
    +                        );
    +                    }
    +                }
    +                /**
    +                 * End attribute option order modification
    +                 * @author Robbie Averill <robbie.averill@kathmandu.co.nz>
    +                 */
                 }
    
                 foreach ($pricings[0] as $pricing) {
    

    This is also on GitHub如果有人想要它作为参考。

    编辑:我也有logged this as a bug with Magento

    【讨论】:

    • @MilanGajjar 请使用 GitHub 存储库,自这篇文章以来已经修复了一些错误
    【解决方案4】:

    覆盖属性集合并添加如下代码更改。这将纠正排序问题以及加载高选项值的问题。 "usort 给出了价格问题,所以注释掉了"

    <?php
    class Custom_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection extends Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection {
    
        protected static $_pricings = array();
    
        protected function _loadPrices() {
            if ($this->count()) {
                $pricings = array(
                    0 => array()
                );
    
                if ($this->getHelper()->isPriceGlobal()) {
                    $websiteId = 0;
                } else {
                    $websiteId = (int)Mage::app()->getStore($this->getStoreId())->getWebsiteId();
                    $pricing[$websiteId] = array();
                }
    
                $select = $this->getConnection()->select()
                    ->from(array('price' => $this->_priceTable))
                    ->where('price.product_super_attribute_id IN (?)', array_keys($this->_items));
    
                if ($websiteId > 0) {
                    $select->where('price.website_id IN(?)', array(0, $websiteId));
                } else {
                    $select->where('price.website_id = ?', 0);
                }
    
                $query = $this->getConnection()->query($select);
    
                while ($row = $query->fetch()) {
                    $pricings[(int)$row['website_id']][] = $row;
                }
    
                $values = array();
    
                //custom codes
                if (!Mage::app()->getStore()->isAdmin() && isset(self::$_pricings[$this->getProduct()->getId()])) {
                    $values = self::$_pricings[$this->getProduct()->getId()];
    
                } else {//custom codes
                    foreach ($this->_items as $item) {
                        $productAttribute = $item->getProductAttribute();
                        if (!($productAttribute instanceof Mage_Eav_Model_Entity_Attribute_Abstract)) {
                            continue;
                        }
                        $options = $productAttribute->getFrontend()->getSelectOptions();
    
                        $optionsByValue = array();
                        $sortOrders = array(); //custom codes
                        $sortOrder = 1; //custom codes
                        foreach ($options as $option) {
                            $optionsByValue[$option['value']] = $option['label'];
                            $sortOrders[$option['value']] = $sortOrder++; //custom codes
                        }
    
                        foreach ($this->getProduct()->getTypeInstance(true)
                                     ->getUsedProducts(array($productAttribute->getAttributeCode()), $this->getProduct())
                                 as $associatedProduct) {
    
                            $optionValue = $associatedProduct->getData($productAttribute->getAttributeCode());
    
                            if (array_key_exists($optionValue, $optionsByValue)) {
                                // If option available in associated product
                                if (!isset($values[$item->getId() . ':' . $optionValue])) {
                                    // If option not added, we will add it.
                                    $values[$item->getId() . ':' . $optionValue] = array(
                                        'product_super_attribute_id' => $item->getId(),
                                        'value_index'                => $optionValue,
                                        'label'                      => $optionsByValue[$optionValue],
                                        'default_label'              => $optionsByValue[$optionValue],
                                        'store_label'                => $optionsByValue[$optionValue],
                                        'is_percent'                 => 0,
                                        'pricing_value'              => null,
                                        'use_default_value'          => true,
                                        'sort_order'                 => $sortOrders[$optionValue] //custom codes
                                    );
                                }
                            }
                        }
                    }
    
                    //custom codes
                    self::$_pricings[$this->getProduct()->getId()] = $values;
                    /**usort($values, function($a, $b) {
                        return $a['sort_order'] > $b['sort_order'];
                    });**/
                }
    
                foreach ($pricings[0] as $pricing) {
                    // Addding pricing to options
                    $valueKey = $pricing['product_super_attribute_id'] . ':' . $pricing['value_index'];
                    if (isset($values[$valueKey])) {
                        $values[$valueKey]['pricing_value']     = $pricing['pricing_value'];
                        $values[$valueKey]['is_percent']        = $pricing['is_percent'];
                        $values[$valueKey]['value_id']          = $pricing['value_id'];
                        $values[$valueKey]['use_default_value'] = true;
                    }
                }
    
                if ($websiteId && isset($pricings[$websiteId])) {
                    foreach ($pricings[$websiteId] as $pricing) {
                        $valueKey = $pricing['product_super_attribute_id'] . ':' . $pricing['value_index'];
                        if (isset($values[$valueKey])) {
                            $values[$valueKey]['pricing_value']     = $pricing['pricing_value'];
                            $values[$valueKey]['is_percent']        = $pricing['is_percent'];
                            $values[$valueKey]['value_id']          = $pricing['value_id'];
                            $values[$valueKey]['use_default_value'] = false;
                        }
                    }
                }
    
                foreach ($values as $data) {
                    $this->getItemById($data['product_super_attribute_id'])->addPrice($data);
                }
            }
            return $this;
        }
    
    }
    

    覆盖类 Mage_Catalog_Block_Product_View_Type_Configurable 检查函数 public function getJsonConfig() 更改 $prices = $attribute->getPrices();到 $prices = $this->_sortPrices($attribute->getPrices()); 函数如下

    public function _sortPrices($prices) {
        $sort_orders = array();
        $sorted_prices = array();
        foreach($prices as $key => $value) {
            $sort_orders[$key] = $value['sort_order'];
        }
        asort($sort_orders);
    
        foreach($sort_orders as $key => $value) {
            $sorted_prices[] = $prices[$key];
        }
        return $sorted_prices;
    }
    

    【讨论】:

      【解决方案5】:

      注意:此处列出的解决方案扩展了 Magento 核心库中的块类文件。在此方法之前,我查看了 Magento 的源代码,并确定没有观察到的好事件来避免这种方法。如果在 Magento 的未来版本中解决了此排序问题,您可以通过禁用其 app/etc/modules XML 文件中的扩展名来撤消这些更改。

      第一步:创建文件app/etc/modules/FirstScribe_CatalogOptionSortFix.xml

      内容:

      <?xml version="1.0"?>
      <config>
          <modules>
              <FirstScribe_CatalogOptionSortFix>
                  <active>true</active>
                  <codePool>local</codePool>
                  <depends>
                      <Mage_Catalog />
                  </depends>
              </FirstScribe_CatalogOptionSortFix>
          </modules>
      </config>
      

      注意:对于第 2 步和第 3 步,根据需要为这些文件创建目录。例如,您可能已经有目录 app/code/local,也可能没有,这取决于您已经在网站上安装了哪些扩展程序。

      第 2 步: 创建文件 app/code/local/FirstScribe/CatalogOptionSortFix/etc/config.xml

      内容:

      <?xml version="1.0"?>
      <!--
      /**
       * Magento 1.9.1.0 has a bug in that the configurable options are sorted by
       * ID rather than position for the Configurable Product's front end view script.
       * This extension addresses this problem.
       *
       * @category    FirstScribe
       * @package     FirstScribe_CatalogOptionSortFix
       * @version     2014.12.15
       */
      -->
      <config>
          <modules>
              <FirstScribe_CatalogOptionSortFix>
                  <version>1.0.0</version>
              </FirstScribe_CatalogOptionSortFix>
          </modules>
          <global>
              <blocks>
                  <catalog>
                      <rewrite>
                          <product_view_type_configurable>FirstScribe_CatalogOptionSortFix_Block_Product_View_Type_Configurable</product_view_type_configurable>
                      </rewrite>
                  </catalog>
              </blocks>
          </global>
      </config>
      

      第 3 步: 创建文件 app/code/local/FirstScribe/CatalogOptionSortFix/Block/Product/View/Type/Configurable.php

      内容:

      <?php
      /**
       * Magento 1.9.1.0 has a bug in that the configurable options are sorted by
       * ID rather than position for the Configurable Product's front end view script.
       * This extension addresses this problem.
       *
       * @category    FirstScribe
       * @package     FirstScribe_CatalogOptionSortFix
       * @version     2014.12.15
       */
      class FirstScribe_CatalogOptionSortFix_Block_Product_View_Type_Configurable extends Mage_Catalog_Block_Product_View_Type_Configurable
      {
          /**
           * @var Magento_Db_Adapter_Pdo_Mysql
           */
          protected $_read;
      
          /**
           * @var string
           */
          protected $_tbl_eav_attribute_option;
      
          /**
           * Composes configuration for js
           *
           * @version 2014.12.15 - Addition of this line:
           *    $info['options'] = $this->_sortOptions($info['options']);
           *
           * @return string
           */
          public function getJsonConfig()
          {
              $attributes = array();
              $options    = array();
              $store      = $this->getCurrentStore();
              $taxHelper  = Mage::helper('tax');
              $currentProduct = $this->getProduct();
      
              $preconfiguredFlag = $currentProduct->hasPreconfiguredValues();
              if ($preconfiguredFlag) {
                  $preconfiguredValues = $currentProduct->getPreconfiguredValues();
                  $defaultValues       = array();
              }
      
              foreach ($this->getAllowProducts() as $product) {
                  $productId  = $product->getId();
      
                  foreach ($this->getAllowAttributes() as $attribute) {
                      $productAttribute   = $attribute->getProductAttribute();
                      $productAttributeId = $productAttribute->getId();
                      $attributeValue     = $product->getData($productAttribute->getAttributeCode());
                      if (!isset($options[$productAttributeId])) {
                          $options[$productAttributeId] = array();
                      }
      
                      if (!isset($options[$productAttributeId][$attributeValue])) {
                          $options[$productAttributeId][$attributeValue] = array();
                      }
                      $options[$productAttributeId][$attributeValue][] = $productId;
                  }
              }
      
              $this->_resPrices = array(
                  $this->_preparePrice($currentProduct->getFinalPrice())
              );
      
              foreach ($this->getAllowAttributes() as $attribute) {
                  $productAttribute = $attribute->getProductAttribute();
                  $attributeId = $productAttribute->getId();
                  $info = array(
                          'id'        => $productAttribute->getId(),
                          'code'      => $productAttribute->getAttributeCode(),
                          'label'     => $attribute->getLabel(),
                          'options'   => array()
                  );
      
                  $optionPrices = array();
                  $prices = $attribute->getPrices();
                  if (is_array($prices)) {
                      foreach ($prices as $value) {
                          if(!$this->_validateAttributeValue($attributeId, $value, $options)) {
                              continue;
                          }
                          $currentProduct->setConfigurablePrice(
                                  $this->_preparePrice($value['pricing_value'], $value['is_percent'])
                          );
                          $currentProduct->setParentId(true);
                          Mage::dispatchEvent(
                                  'catalog_product_type_configurable_price',
                                  array('product' => $currentProduct)
                          );
                          $configurablePrice = $currentProduct->getConfigurablePrice();
      
                          if (isset($options[$attributeId][$value['value_index']])) {
                              $productsIndex = $options[$attributeId][$value['value_index']];
                          } else {
                              $productsIndex = array();
                          }
      
                          $info['options'][] = array(
                                  'id'        => $value['value_index'],
                                  'label'     => $value['label'],
                                  'price'     => $configurablePrice,
                                  'oldPrice'  => $this->_prepareOldPrice($value['pricing_value'], $value['is_percent']),
                                  'products'  => $productsIndex,
                          );
                          $optionPrices[] = $configurablePrice;
                      }
                  }
      
                  // CALL SORT ORDER FIX
                  $info['options'] = $this->_sortOptions($info['options']);
      
                  /**
                   * Prepare formated values for options choose
                   */
                  foreach ($optionPrices as $optionPrice) {
                      foreach ($optionPrices as $additional) {
                          $this->_preparePrice(abs($additional-$optionPrice));
                      }
                  }
                  if($this->_validateAttributeInfo($info)) {
                      $attributes[$attributeId] = $info;
                  }
      
                  // Add attribute default value (if set)
                  if ($preconfiguredFlag) {
                      $configValue = $preconfiguredValues->getData('super_attribute/' . $attributeId);
                      if ($configValue) {
                          $defaultValues[$attributeId] = $configValue;
                      }
                  }
              }
      
              $taxCalculation = Mage::getSingleton('tax/calculation');
              if (!$taxCalculation->getCustomer() && Mage::registry('current_customer')) {
                  $taxCalculation->setCustomer(Mage::registry('current_customer'));
              }
      
              $_request = $taxCalculation->getDefaultRateRequest();
              $_request->setProductClassId($currentProduct->getTaxClassId());
              $defaultTax = $taxCalculation->getRate($_request);
      
              $_request = $taxCalculation->getRateRequest();
              $_request->setProductClassId($currentProduct->getTaxClassId());
              $currentTax = $taxCalculation->getRate($_request);
      
              $taxConfig = array(
                      'includeTax'        => $taxHelper->priceIncludesTax(),
                      'showIncludeTax'    => $taxHelper->displayPriceIncludingTax(),
                      'showBothPrices'    => $taxHelper->displayBothPrices(),
                      'defaultTax'        => $defaultTax,
                      'currentTax'        => $currentTax,
                      'inclTaxTitle'      => Mage::helper('catalog')->__('Incl. Tax')
              );
      
              $config = array(
                      'attributes'        => $attributes,
                      'template'          => str_replace('%s', '#{price}', $store->getCurrentCurrency()->getOutputFormat()),
                      'basePrice'         => $this->_registerJsPrice($this->_convertPrice($currentProduct->getFinalPrice())),
                      'oldPrice'          => $this->_registerJsPrice($this->_convertPrice($currentProduct->getPrice())),
                      'productId'         => $currentProduct->getId(),
                      'chooseText'        => Mage::helper('catalog')->__('Choose an Option...'),
                      'taxConfig'         => $taxConfig
              );
      
              if ($preconfiguredFlag && !empty($defaultValues)) {
                  $config['defaultValues'] = $defaultValues;
              }
      
              $config = array_merge($config, $this->_getAdditionalConfig());    
      
              return Mage::helper('core')->jsonEncode($config);
          }
      
          /**
           * Sort the options based off their position.
           *
           * @param array $options
           * @return array
           */
          protected function _sortOptions($options)
          {
              if (count($options)) {
                  if (!$this->_read || !$this->_tbl_eav_attribute_option) {
                      $resource = Mage::getSingleton('core/resource');
      
                      $this->_read = $resource->getConnection('core_read');
                      $this->_tbl_eav_attribute_option = $resource->getTableName('eav_attribute_option');
                  }
      
                  // Gather the option_id for all our current options
                  $option_ids = array();
                  foreach ($options as $option) {
                      $option_ids[] = $option['id'];
      
                      $var_name  = 'option_id_'.$option['id'];
                      $$var_name = $option;
                  }
      
                  $sql    = "SELECT `option_id` FROM `{$this->_tbl_eav_attribute_option}` WHERE `option_id` IN('".implode('\',\'', $option_ids)."') ORDER BY `sort_order`";
                  $result = $this->_read->fetchCol($sql);
      
                  $options = array();
                  foreach ($result as $option_id) {
                      $var_name  = 'option_id_'.$option_id;
                      $options[] = $$var_name;
                  }
              }
      
              return $options;
          }
      }
      

      第 4 步:如果启用,请在管理面板的系统 -> 缓存管理下刷新 Magento 的“配置”缓存类型。

      扩展概述

      1. 扩展 Mage_Catalog_Block_Product_View_Type_Configurable 类。
      2. 通过从数据库中提取此信息,添加一种按其position 值对选项进行排序的方法。
      3. 在收集到属性的选项后,重写 getJsonConfig 方法以调用我们的新函数。

      【讨论】:

      • 这个答案是正确的,而且效果很好,谢谢。希望一旦正式更新发布后它不会引起任何问题......我很惊讶没有更多关于这个主题的内容。
      • @Joe 欢迎您。关于更新的反馈 - 解决方案的编写方式是,一旦 Magento 的核心团队在更新中修复了该问题,我们所要做的就是在 app/etc/modules/FirstScribe_CatalogOptionSortFix.xml 中禁用此扩展,然后一切都将恢复使用核心 Mage 类,不更多重写核心类。
      • 我按照您的指示操作,它在产品页面上运行完美。商品列表页面上的色板仍然不正常。你有什么建议吗?
      • @tzvi 抱歉,我还没有在产品列表/网格上显示色样的项目。话虽如此,我目前不知道这些块类型的样本是如何加载的。
      • 谢谢!在社区代码池和 GitHub 上拥有这个扩展会很酷;)
      猜你喜欢
      • 2014-06-09
      • 2015-12-31
      • 1970-01-01
      • 2011-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多