Примечание: мое внимание было обращено на то, что это решение не работает для Magento 1.9.2. Чтобы сэкономить время впустую, я бы хотел отметить это в верхней части этого поста. Если я разработаю свое собственное решение или найду решение другого, которое работает для 1.9.2, я обновлю этот пост в то время.
Примечание . Решение, изложенное здесь, расширяет файл классов блоков в основной библиотеке Magento. Я рассмотрел исходный код Magento до этого подхода и решил, что не было хорошего события, чтобы наблюдать, чтобы избежать этого подхода. Если в будущей версии Magento эта проблема сортировки будет решена, вы можете отменить эти изменения ниже, просто отключив расширение в его файле app / etc / modules XML.
Шаг 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'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 «Конфигурация» в разделе «Система» -> «Управление кэшем» панели администратора.
Обзор расширений
- Расширьте класс Mage_Catalog_Block_Product_View_Type_Configurable.
- Добавьте метод сортировки опций по их
position
значению, извлекая эту информацию из базы данных.
- Перепишите метод getJsonConfig, чтобы он вызывал нашу новую функцию после сбора параметров для атрибута.
Просто добавив два моих цента, два других ответа хорошо показали мне направление исправления, но я решил напасть на источник, а не на точку представления блока.
Вы можете достичь того же результата, расширив метод
Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection
модели_loadPrices()
, в котором, несмотря на название, было сделано изменение (предположительно для производительности), в результате чего атрибуты упорядочены по идентификатору, а не по релевантности.Похоже, что это изменение было сделано для того, чтобы избежать вложенных
foreach
операторов, но в свою очередь также теряет правильный порядок. Это решение слегка модифицирует обновленную логику для отслеживания параметров атрибута, а затем выполняет другой цикл на основе исходного порядка, чтобы фактически выполнить добавление.Вот скорректированное прохождение, похожее на ответ Меоги выше :
Шаг 1: Зарегистрируйте новый модуль
Примечание: если у вас уже есть, повторно используйте существующий.
Шаг 2: Создайте конфигурацию модуля
Шаг 3: Добавьте расширение модели ресурса
Шаг 4. Очистите кеш
Для справки , фактическое изменение базового класса в a
git diff
будет ниже (не редактируйте напрямую основные файлы!):Это также на GitHub, если кто-то хочет его для справки.
Изменить: я также зарегистрировал это как ошибку с Magento .
источник
Это не совсем правильное исправление, но это то, что я сделал временно, чтобы избежать необходимости возвращаться к 1.9.0.1 до тех пор, пока следующий выпуск Magento, надеюсь, не исправит проблему должным образом. Он будет сортировать значения параметров в алфавитном порядке, конечно, вы можете отсортировать все, что захотите, но я не знаю, как получить доступ к порядку сортировки, заданному в бэкэнде, и по алфавиту достаточно для моих целей.
Изменить файл
Смена строки 215
в
источник