Nota: Fui informado de que esta solução não funciona no Magento 1.9.2. Para economizar tempo desperdiçado por outras pessoas, eu gostaria de destacar isso na parte superior deste post. Se eu desenvolver minha própria solução ou encontrar a solução de outra pessoa que funcione na versão 1.9.2, atualizarei esta postagem naquele momento.
Nota: A solução apresentada aqui estende um arquivo de classe de bloco na biblioteca principal do Magento. Revisei o código fonte do Magento antes dessa abordagem e determinei que não havia um bom evento a ser observado para evitar essa abordagem. Se em uma versão futura do Magento esse problema de classificação for resolvido, você poderá desfazer essas alterações abaixo simplesmente desativando a extensão no arquivo XML do app / etc / modules.
Etapa 1: crie o arquivo app / etc / modules / FirstScribe_CatalogOptionSortFix.xml
Conteúdo:
<?xml version="1.0"?>
<config>
<modules>
<FirstScribe_CatalogOptionSortFix>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Catalog />
</depends>
</FirstScribe_CatalogOptionSortFix>
</modules>
</config>
Nota: Para as etapas 2 e 3, crie diretórios para esses arquivos, conforme necessário. Por exemplo, você já pode ter o diretório app / code / local ou não, dependendo das extensões que já instalou no site.
Etapa 2: Crie o arquivo app / code / local / FirstScribe / CatalogOptionSortFix / etc / config.xml
Conteúdo:
<?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>
Etapa 3: Crie o arquivo app / code / local / FirstScribe / CatalogOptionSortFix / Block / Product / View / Type / Configurable.php
Conteúdo:
<?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;
}
}
Etapa 4: Se ativado, atualize o tipo de cache "Configuração" do Magento em Sistema -> Gerenciamento de cache do painel de administração.
Visão geral da extensão
- Estenda a classe Mage_Catalog_Block_Product_View_Type_Configurable.
- Adicione um método para classificar as opções por seu
position
valor, puxando essas informações do banco de dados.
- Reescreva o método getJsonConfig para chamar nossa nova função depois de reunir as opções para um atributo.
Apenas para adicionar meus dois centavos, as outras duas respostas foram boas para me apontar na direção da correção, mas pensei em atacá-la na fonte e não no ponto de apresentação do bloco.
Você pode obter o mesmo resultado estendendo o método
Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection
do modelo_loadPrices()
, que apesar do nome é o local onde uma alteração foi feita (presumivelmente por desempenho), resultando na ordenação dos atributos por ID e não por relevância.A alteração parece ter sido feita para evitar
foreach
instruções aninhadas , mas, por sua vez, também perde a ordem correta. Esta solução modifica ligeiramente a lógica atualizada para rastrear as opções de atributo e, em seguida, executa outro loop com base na ordem original para realmente adicionar.Aqui está um passo a passo ajustado semelhante à resposta do meogi acima :
Etapa 1: registrar um novo módulo
Nota: se você já possui um, reutilize um existente.
Etapa 2: criar a configuração do módulo
Etapa 3: adicionar a extensão do modelo de recurso
Etapa 4: limpe seu cache
Para referência , a mudança real na classe principal em
git diff
seria abaixo (não edite diretamente os arquivos principais!):Isso também está no GitHub se alguém quiser como referência.
Edit: Eu também registrei isso como um bug no Magento .
fonte
Esta não é realmente uma correção adequada, mas foi o que fiz temporariamente para evitar a necessidade de voltar à 1.9.0.1 até que o próximo lançamento do Magento esperançosamente resolva o problema corretamente. Ele classificará os valores das opções em ordem alfabética; é claro que você pode ordenar o que quiser, mas não sei como acessar a ordem de classificação definida no back-end e, alfabeticamente, é bom o suficiente para meus propósitos.
Mude o arquivo
Alterar linha 215
para
fonte