Nota: Se me ha señalado que esta solución no funciona para Magento 1.9.2. Para ahorrar tiempo perdido a los demás, me gustaría señalar esto en la parte superior de esta publicación. Si desarrollo mi propia solución o encuentro la solución de otra persona que funciona para 1.9.2, actualizaré esta publicación en ese momento.
Aviso: La solución presentada aquí extiende un archivo de clase de bloque en la biblioteca principal de Magento. Revisé el código fuente de Magento antes de este enfoque y determiné que no había un buen evento para observar para evitar este enfoque. Si en una versión futura de Magento se resuelve este problema de clasificación, puede deshacer estos cambios a continuación simplemente deshabilitando la extensión en su archivo XML de la aplicación / etc / modules.
Paso 1: cree la aplicación de archivo / etc / modules / FirstScribe_CatalogOptionSortFix.xml
Contenido:
<?xml version="1.0"?>
<config>
<modules>
<FirstScribe_CatalogOptionSortFix>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Catalog />
</depends>
</FirstScribe_CatalogOptionSortFix>
</modules>
</config>
Nota: Para los pasos 2 y 3, cree directorios para estos archivos según sea necesario. Por ejemplo, es posible que ya tenga la aplicación de directorio / código / local , o puede que no, según las extensiones que ya haya instalado en su sitio.
Paso 2: Cree el archivo app / code / local / FirstScribe / CatalogOptionSortFix / etc / config.xml
Contenido:
<?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>
Paso 3: Cree el archivo app / code / local / FirstScribe / CatalogOptionSortFix / Block / Product / View / Type / Configurable.php
Contenido:
<?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;
}
}
Paso 4: si está habilitado, actualice el tipo de caché "Configuración" de Magento en Sistema -> Administración de caché del panel de administración.
Descripción general de la extensión
- Extienda la clase Mage_Catalog_Block_Product_View_Type_Configurable.
- Agregue un método para ordenar las opciones por su
position
valor al extraer esta información de la base de datos.
- Vuelva a escribir el método getJsonConfig para llamar a nuestra nueva función después de haber reunido las opciones para un atributo.
Solo para agregar mis dos centavos, las otras dos respuestas hicieron bien en señalarme en la dirección de la solución, pero pensé que lo atacaría en la fuente en lugar del punto de presentación del bloque.
Puede lograr el mismo resultado extendiendo el
Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection
modelo_loadPrices()
método , que a pesar del nombre es donde se realizó un cambio (presumiblemente para el rendimiento) que da como resultado que los atributos se ordenen por ID en lugar de por relevancia.El cambio parece haberse realizado para evitar anidadas
foreach
sentencias , pero a su vez también pierde el orden correcto. Esta solución modifica ligeramente la lógica actualizada para rastrear las opciones de atributos, luego realiza otro ciclo basado en el orden original para hacer la suma.Aquí hay un tutorial ajustado similar a la respuesta de meogi anterior :
Paso 1: registra un nuevo módulo
Nota: si ya tiene uno, reutilice uno existente.
Paso 2: crea la configuración del módulo
Paso 3: agregue la extensión del modelo de recurso
Paso 4: borra tu caché
Como referencia , el cambio real a la clase principal en a
git diff
sería el siguiente (¡no edite directamente los archivos principales!):Esto también está en GitHub si alguien lo quiere como referencia.
Editar: También he registrado esto como un error con Magento .
fuente
Esto no es realmente una solución adecuada, pero es lo que he hecho temporalmente para evitar tener que volver a 1.9.0.1 hasta que la próxima versión de Magento solucione el problema correctamente. Clasificará los valores de las opciones alfabéticamente, por supuesto, puede ordenarlos por lo que desee, pero no sé cómo acceder al orden de clasificación establecido en el backend y alfabéticamente es lo suficientemente bueno para mis propósitos.
Cambiar el archivo
Cambiar línea 215
a
fuente