Uwaga: Zwrócono mi uwagę, że to rozwiązanie nie działa w Magento 1.9.2. Aby zaoszczędzić innym zmarnowany czas, chciałbym wskazać to na początku tego postu. Jeśli opracuję własne rozwiązanie lub znajdę rozwiązanie, które działa dla 1.9.2, zaktualizuję ten post w tym czasie.
Uwaga: Przedstawione tutaj rozwiązanie rozszerza plik klasy bloków w podstawowej bibliotece Magento. Przejrzałem kod źródłowy Magento przed tym podejściem i ustaliłem, że nie było dobrego wydarzenia, którego można by uniknąć, aby uniknąć takiego podejścia. Jeśli w przyszłej wersji Magento problem z sortowaniem zostanie rozwiązany, możesz cofnąć te zmiany poniżej, po prostu wyłączając rozszerzenie w pliku XML aplikacji / etc / modules.
Krok 1: Utwórz plik aplikacji / etc / modules / FirstScribe_CatalogOptionSortFix.xml
Zawartość:
<?xml version="1.0"?>
<config>
<modules>
<FirstScribe_CatalogOptionSortFix>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Catalog />
</depends>
</FirstScribe_CatalogOptionSortFix>
</modules>
</config>
Uwaga: W kroku 2 i 3 utwórz katalogi dla tych plików, jeśli to konieczne. Na przykład możesz już mieć katalog app / code / local , albo nie, w zależności od tego, jakie rozszerzenia już zainstalowałeś w swojej witrynie.
Krok 2: Utwórz plik app / code / local / FirstScribe / CatalogOptionSortFix / etc / config.xml
Zawartość:
<?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>
Krok 3: Utwórz plik app / code / local / FirstScribe / CatalogOptionSortFix / Block / Product / View / Type / Configurable.php
Zawartość:
<?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;
}
}
Krok 4: Jeśli jest włączony, odśwież typ pamięci podręcznej „Konfiguracja” Magento w obszarze System -> Zarządzanie pamięcią podręczną panelu administracyjnego.
Przegląd rozszerzeń
- Rozszerz klasę Mage_Catalog_Block_Product_View_Type_Configurable.
- Dodaj metodę sortowania opcji według ich
position
wartości, pobierając te informacje z bazy danych.
- Przepisz metodę getJsonConfig, aby wywoływała naszą nową funkcję po zebraniu opcji dla atrybutu.
Żeby dodać moje dwa centy, pozostałe dwie odpowiedzi dobrze skierowały mnie w stronę poprawki, ale myślałem, że zaatakuję to u źródła, a nie w punkcie prezentacji bloku.
Możesz osiągnąć ten sam wynik, rozszerzając metodę
Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection
modelu_loadPrices()
, która pomimo nazwy jest miejscem, w którym dokonano zmiany (przypuszczalnie ze względu na wydajność), powodując, że atrybuty są uporządkowane według ID, a nie według trafności.Wydaje się, że zmiana została wprowadzona, aby uniknąć zagnieżdżenia
foreach
instrukcji, ale z kolei traci ona również prawidłową kolejność. To rozwiązanie nieznacznie modyfikuje zaktualizowaną logikę, aby śledzić opcje atrybutów, a następnie wykonuje kolejną pętlę na podstawie oryginalnej kolejności, aby faktycznie dodać.Oto poprawiony przewodnik podobny do powyższej odpowiedzi meogina :
Krok 1: Zarejestruj nowy moduł
Uwaga: jeśli już go masz, użyj go ponownie.
Krok 2: Utwórz konfigurację modułu
Krok 3: Dodaj rozszerzenie modelu zasobów
Krok 4: Wyczyść pamięć podręczną
Dla porównania , rzeczywista zmiana klasy podstawowej w a
git diff
byłaby poniżej (nie edytuj bezpośrednio plików podstawowych!):Dotyczy to również GitHub, jeśli ktoś chce to w celach informacyjnych.
Edycja: Zalogowałem to również jako błąd w Magento .
źródło
To naprawdę nie jest poprawna poprawka, ale zrobiłem to tymczasowo, aby uniknąć konieczności powrotu do wersji 1.9.0.1, dopóki następna wersja Magento nie rozwiąże problemu. Sortuje wartości opcji alfabetycznie, możesz oczywiście sortować według wszystkiego, co chcesz, ale nie wiem, jak uzyskać dostęp do kolejności sortowania ustawionej w backendie i alfabetycznie jest wystarczająca do moich celów.
Zmień plik
Zmień linię 215
do
źródło