Magento 1.9.1 не сортировка Настраиваемые атрибуты атрибутов продукта по положению

Свежая установка Magento 1.9.1.

Magento игнорирует положение атрибута, установленное в Catalogue-> Attributes-> Manage Attributes-> Manage Labels/Options для выпадающего меню настраиваемого продукта. Вместо этого он использует идентификатор продукта для определения порядка списка.

Сравнили следующие файлы/функции и, кроме небольшого расчета налога, ни один из кодов не изменился с 1.7.0.2.

Mage/Каталог/модель/продукта/тип /Configuarable.php:

public function getConfigurableAttributes($product = null)

Mage/Каталог/модель/продукта /Option.php:

public function getProductOptionCollection(Mage_Catalog_Model_Product $product)

Маг/Каталог/блока/продукта/Вид/Тип /Configuarable.php:

public function getJsonConfig()

Я также проверил базу данных копий живого сайта, и вся сортировка атрибутов основана на идентификаторе продукта.

Копировать:

  1. Создать атрибут - Цвет
  2. Добавить метки - черный, красный, зеленый, синий
  3. Сохранить атрибут.
  4. Создавайте настраиваемые и простые связанные продукты с атрибутами в указанном выше порядке.

Отредактируйте атрибут и измените позиции метки. Синий 0, Зеленый 1, Красный 3, Черный 4

При просмотре товара Magento по-прежнему сортирует атрибуты по идентификатору товара и игнорирует позиции.

Ответ 1

Ответ Мегио работает, но не является идеальным ответом, поскольку он будет сортировать только опции на интерфейсе. Попробуйте создать заказ с панели администратора для настраиваемого продукта. Вы по-прежнему получите список параметров с неправильной сортировкой атрибутов.

Вместо этого вы можете скопировать 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 <[email protected]>
+             */
+            $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);
             }

Если вы не решаетесь копировать файл ядра в локальную папку, я могу создать быстрый модуль, <rewrite> этот файл Collection.php и просто переопределить функцию _loadPrices() и ввести это исправление.

Ответ 2

Примечание: Решение, изложенное здесь, расширяет файл блочного класса в основной библиотеке Magento. Я рассмотрел исходный код Magento до этого подхода и определил, что не было хорошего события для наблюдения, чтобы избежать такого подхода. Если в будущей версии Magento эта проблема сортировки устранена, вы можете отменить эти изменения ниже, просто отключив расширение в файле XML/приложения/etc/modules.

Шаг 1: создать файл 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 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 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 "Конфигурация" в разделе "Система" → "Управление кешем" панели администратора.

Обзор расширений

  • Расширьте класс Mage_Catalog_Block_Product_View_Type_Configurable.
  • Добавьте способ сортировки параметров по их значению position, потянув эту информацию из базы данных.
  • Перепишите метод getJsonConfig для вызова нашей новой функции после того, как вы собрали параметры для атрибута.

Ответ 3

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

Вы можете добиться того же результата, расширив метод Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection model _loadPrices(), который, несмотря на то, что имя было изменено (предположительно для производительности), в результате чего атрибуты упорядочиваются по идентификатору, а не по релевантности.

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

Здесь скорректированное пошаговое руководство, подобное meogi, ответит выше:


Шаг 1: зарегистрируйте новый модуль

Примечание: если у вас уже есть, повторите использование существующего.

# 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>

Шаг 3: добавьте расширение модели ресурса

# 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 <[email protected]>
                 */
                $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 <[email protected]>
                 */
            }

            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 <[email protected]>
+                 */
+                $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 <[email protected]>
+                 */
             }

             foreach ($pricings[0] as $pricing) {

Это также на GitHub, если кто-то хочет его для справки.

Изменить: я также зарегистрировал это как ошибку с Magento.

Ответ 4

Согласно Magento, эта проблема будет исправлена ​​в CE 1.9.3.0

Команда Magento | отправлено 8/14/15 4:02 вечера

Проблема запланирована на следующий небольшой (не патч) выпуск, ожидаемый в H1 2016.

Источник: https://www.magentocommerce.com/bug-tracking/issue/index/id/413

Ответ 5

Отмените сбор атрибутов и добавьте изменения кода, как показано ниже. Это устранит проблему сортировки, а также проблему загрузки значений высоких опций. "Усорт дает проблемы в ценах, поэтому прокомментировал"

<?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(); to $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;
}