내 두 센트를 추가하기 위해 다른 두 대답은 나를 수정의 방향으로 안내하는 데 효과적이지만 블록 표시 지점이 아닌 소스에서 공격 할 것이라고 생각했습니다.
Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection
모델의 _loadPrices()
방법에도 불구하고 이름이 바뀌었을 때 (성능에 따라) 속성이 관련성이 아니라 ID별로 정렬되어 동일한 결과를 얻을 수 있습니다 .
중첩 된 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 <robbie.averill@kathmandu.co.nz>
*/
$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 <robbie.averill@kathmandu.co.nz>
*/
}
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 <robbie.averill@kathmandu.co.nz>
+ */
+ $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 <robbie.averill@kathmandu.co.nz>
+ */
}
foreach ($pricings[0] as $pricing) {
누군가가 참조하기를 원한다면 이것은 GitHub에도 있습니다 .
편집 : 나는 이것을 Magento의 버그로 기록했습니다 .