From e41ce1c351f886c8275f642dce21f9532f2210a6 Mon Sep 17 00:00:00 2001 From: Robbie Averill Date: Sat, 16 Jan 2016 23:58:15 +1300 Subject: [PATCH] [#12] Fix swatch option ordering * Added helper to determine the sort order for attribute options * Added resource model override for the swatches on the category list page * Moved the Magento attribute order fix to a trait * Both collection classes use the trait * Removed PHP 5.3 support. Updated readme. * Added unit tests for the Data helper --- .travis.yml | 1 - README.md | 7 +- .../AttributeFix/Helper/Data.php | 55 ++++++++ .../AttributeFix/Helper/Mediafallback.php | 114 ++++++++++++++++ .../Product/Attribute/Super/Collection.php | 18 +++ .../Configurable/Attribute/Collection.php | 117 +--------------- .../Attribute/CollectionCommon.php | 129 ++++++++++++++++++ .../AttributeFix/Test/Config/ConfigTest.php | 26 +++- .../AttributeFix/Test/Helper/DataTest.php | 55 ++++++++ ...ShouldGetAttributeOrdersThenOrderThem.yaml | 14 ++ .../testShouldRetrieveOptionsInSortOrder.yaml | 12 ++ .../testShouldRetrieveOptionsInSortOrder.yaml | 28 ++++ ...ShouldGetAttributeOrdersThenOrderThem.yaml | 22 +++ .../testShouldRetrieveOptionsInSortOrder.yaml | 7 + .../RobbieAverill/AttributeFix/etc/config.xml | 17 ++- 15 files changed, 502 insertions(+), 120 deletions(-) create mode 100644 app/code/local/RobbieAverill/AttributeFix/Helper/Data.php create mode 100644 app/code/local/RobbieAverill/AttributeFix/Helper/Mediafallback.php create mode 100644 app/code/local/RobbieAverill/AttributeFix/Model/Resource/Catalog/Product/Attribute/Super/Collection.php create mode 100644 app/code/local/RobbieAverill/AttributeFix/Model/Resource/Product/Type/Configurable/Attribute/CollectionCommon.php create mode 100644 app/code/local/RobbieAverill/AttributeFix/Test/Helper/DataTest.php create mode 100644 app/code/local/RobbieAverill/AttributeFix/Test/Helper/expectations/testShouldGetAttributeOrdersThenOrderThem.yaml create mode 100644 app/code/local/RobbieAverill/AttributeFix/Test/Helper/expectations/testShouldRetrieveOptionsInSortOrder.yaml create mode 100644 app/code/local/RobbieAverill/AttributeFix/Test/Helper/fixtures/testShouldRetrieveOptionsInSortOrder.yaml create mode 100644 app/code/local/RobbieAverill/AttributeFix/Test/Helper/providers/testShouldGetAttributeOrdersThenOrderThem.yaml create mode 100644 app/code/local/RobbieAverill/AttributeFix/Test/Helper/providers/testShouldRetrieveOptionsInSortOrder.yaml diff --git a/.travis.yml b/.travis.yml index 86602ac..f115c16 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: php php: - - 5.3 - 5.4 - 5.5 - 5.6 diff --git a/README.md b/README.md index cdf20b6..1386610 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,15 @@ You can use this extension module to restore to relevance ordering until the cor ## Notes: * Updated to work correctly on Magento CE 1.9.2 -* Conflict possible with the ConfigurableSwatches module recently introduced since it references the collection resource class directly via hierarchy +* Uses traits, so no longer supports PHP 5.3 or lower. Minimum 5.4 required. ## Changelog: +### 1.1.1 + +* Fix #12 - added support for ordering swatch options +* Removed support for PHP 5.3 as we use traits now + ### 1.0.1 * #10 - added `composer.json` for composer installation. diff --git a/app/code/local/RobbieAverill/AttributeFix/Helper/Data.php b/app/code/local/RobbieAverill/AttributeFix/Helper/Data.php new file mode 100644 index 0000000..95d4850 --- /dev/null +++ b/app/code/local/RobbieAverill/AttributeFix/Helper/Data.php @@ -0,0 +1,55 @@ + + */ +class RobbieAverill_AttributeFix_Helper_Data extends Mage_Core_Helper_Abstract +{ + /** + * Sort the attribute options by their sort order + * @param array $options + * @return array + */ + public function sortOptionValues($options) + { + $optionIds = array_keys($options); + $sortOrder = $this->getSortOrderForAttributeOptions($optionIds); + + foreach ($sortOrder as $optionId => &$value) { + $value = $options[$optionId]; + } + + return $sortOrder; + } + + /** + * Given an array of attribute option IDs, get their sort order + * @param array $optionIds + * @return array + */ + public function getSortOrderForAttributeOptions($optionIds) + { + $resource = Mage::getModel('core/resource'); + $connection = $resource->getConnection('core/read'); + + $select = $connection->select() + ->from( + ['e' => $resource->getTableName('eav/attribute_option')], + ['option_id', 'sort_order'] + ) + ->where('option_id IN (' . implode(',', array_map('intval', $optionIds)) . ')') + ->order('sort_order'); + + $orders = $connection->fetchAll($select); + + $output = []; + foreach ($orders as $order) { + $output[$order['option_id']] = $order['sort_order']; + } + + return $output; + } +} diff --git a/app/code/local/RobbieAverill/AttributeFix/Helper/Mediafallback.php b/app/code/local/RobbieAverill/AttributeFix/Helper/Mediafallback.php new file mode 100644 index 0000000..3c8845f --- /dev/null +++ b/app/code/local/RobbieAverill/AttributeFix/Helper/Mediafallback.php @@ -0,0 +1,114 @@ + + */ +class RobbieAverill_AttributeFix_Helper_Mediafallback extends Mage_ConfigurableSwatches_Helper_Mediafallback +{ + /** + * Set child_attribute_label_mapping on products with attribute label -> product mapping + * Depends on following product data: + * - product must have children products attached + * + * @param array $parentProducts + * @param $storeId + * @return void + */ + public function attachConfigurableProductChildrenAttributeMapping(array $parentProducts, $storeId) + { + $listSwatchAttr = Mage::helper('configurableswatches/productlist')->getSwatchAttribute(); + + $parentProductIds = array(); + /* @var $parentProduct Mage_Catalog_Model_Product */ + foreach ($parentProducts as $parentProduct) { + $parentProductIds[] = $parentProduct->getId(); + } + + $configAttributes = Mage::getResourceModel('configurableswatches/catalog_product_attribute_super_collection') + ->addParentProductsFilter($parentProductIds) + ->attachEavAttributes() + ->setStoreId($storeId) + ; + + $optionLabels = array(); + foreach ($configAttributes as $attribute) { + $optionLabels += $attribute->getOptionLabels(); + } + + foreach ($parentProducts as $parentProduct) { + $mapping = array(); + $listSwatchValues = array(); + + /* @var $attribute Mage_Catalog_Model_Product_Type_Configurable_Attribute */ + foreach ($configAttributes as $attribute) { + /* @var $childProduct Mage_Catalog_Model_Product */ + if (!is_array($parentProduct->getChildrenProducts())) { + continue; + } + + foreach ($parentProduct->getChildrenProducts() as $childProduct) { + + // product has no value for attribute, we can't process it + if (!$childProduct->hasData($attribute->getAttributeCode())) { + continue; + } + $optionId = $childProduct->getData($attribute->getAttributeCode()); + + // if we don't have a default label, skip it + if (!isset($optionLabels[$optionId][0])) { + continue; + } + + // normalize to all lower case before we start using them + $optionLabels = array_map(function ($value) { + return array_map('Mage_ConfigurableSwatches_Helper_Data::normalizeKey', $value); + }, $optionLabels); + + // using default value as key unless store-specific label is present + $optionLabel = $optionLabels[$optionId][0]; + if (isset($optionLabels[$optionId][$storeId])) { + $optionLabel = $optionLabels[$optionId][$storeId]; + } + + // initialize arrays if not present + if (!isset($mapping[$optionLabel])) { + $mapping[$optionLabel] = array( + 'product_ids' => array(), + ); + } + $mapping[$optionLabel]['product_ids'][] = $childProduct->getId(); + $mapping[$optionLabel]['label'] = $optionLabel; + $mapping[$optionLabel]['default_label'] = $optionLabels[$optionId][0]; + $mapping[$optionLabel]['labels'] = $optionLabels[$optionId]; + + if ($attribute->getAttributeId() == $listSwatchAttr->getAttributeId() + && !in_array($mapping[$optionLabel]['label'], $listSwatchValues) + ) { + $listSwatchValues[$optionId] = $mapping[$optionLabel]['label']; + } + } // end looping child products + } // end looping attributes + + + foreach ($mapping as $key => $value) { + $mapping[$key]['product_ids'] = array_unique($mapping[$key]['product_ids']); + } + + /** + * Start modification: sort the swatch values by their sort order + * @author Robbie Averill + */ + $listSwatchValues = Mage::helper('attributefix')->sortOptionValues($listSwatchValues); + /** + * End moficiation + * @author Robbie Averill + */ + + $parentProduct->setChildAttributeLabelMapping($mapping) + ->setListSwatchAttrValues($listSwatchValues); + } // end looping parent products + } +} diff --git a/app/code/local/RobbieAverill/AttributeFix/Model/Resource/Catalog/Product/Attribute/Super/Collection.php b/app/code/local/RobbieAverill/AttributeFix/Model/Resource/Catalog/Product/Attribute/Super/Collection.php new file mode 100644 index 0000000..d251ab6 --- /dev/null +++ b/app/code/local/RobbieAverill/AttributeFix/Model/Resource/Catalog/Product/Attribute/Super/Collection.php @@ -0,0 +1,18 @@ + + */ +class RobbieAverill_AttributeFix_Model_Resource_Catalog_Product_Attribute_Super_Collection + extends Mage_ConfigurableSwatches_Model_Resource_Catalog_Product_Attribute_Super_Collection +{ + /** + * Get the override functionality - it's in a trait for re-usability + */ + use RobbieAverill_AttributeFix_Model_Resource_Product_Type_Configurable_Attribute_CollectionCommon; +} diff --git a/app/code/local/RobbieAverill/AttributeFix/Model/Resource/Product/Type/Configurable/Attribute/Collection.php b/app/code/local/RobbieAverill/AttributeFix/Model/Resource/Product/Type/Configurable/Attribute/Collection.php index 222a4aa..a6b5712 100644 --- a/app/code/local/RobbieAverill/AttributeFix/Model/Resource/Product/Type/Configurable/Attribute/Collection.php +++ b/app/code/local/RobbieAverill/AttributeFix/Model/Resource/Product/Type/Configurable/Attribute/Collection.php @@ -11,120 +11,7 @@ class RobbieAverill_AttributeFix_Model_Resource_Product_Type_Configurable_Attrib extends Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection { /** - * Load attribute prices information - * - * @return self + * Get the override functionality - it's in a trait for re-usability */ - 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 - */ - $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() . ':' . $optionValueKey])) { - // 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 - */ - } - - 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; - } + use RobbieAverill_AttributeFix_Model_Resource_Product_Type_Configurable_Attribute_CollectionCommon; } diff --git a/app/code/local/RobbieAverill/AttributeFix/Model/Resource/Product/Type/Configurable/Attribute/CollectionCommon.php b/app/code/local/RobbieAverill/AttributeFix/Model/Resource/Product/Type/Configurable/Attribute/CollectionCommon.php new file mode 100644 index 0000000..1e9971d --- /dev/null +++ b/app/code/local/RobbieAverill/AttributeFix/Model/Resource/Product/Type/Configurable/Attribute/CollectionCommon.php @@ -0,0 +1,129 @@ + + */ +trait RobbieAverill_AttributeFix_Model_Resource_Product_Type_Configurable_Attribute_CollectionCommon +{ + /** + * Load attribute prices information + * @see Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection::_loadPrices + * @return self + */ + 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 + */ + $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() . ':' . $optionValueKey])) { + // 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 + */ + } + + 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; + } +} diff --git a/app/code/local/RobbieAverill/AttributeFix/Test/Config/ConfigTest.php b/app/code/local/RobbieAverill/AttributeFix/Test/Config/ConfigTest.php index dedc259..8d823cf 100644 --- a/app/code/local/RobbieAverill/AttributeFix/Test/Config/ConfigTest.php +++ b/app/code/local/RobbieAverill/AttributeFix/Test/Config/ConfigTest.php @@ -26,13 +26,35 @@ public function testShouldDependOnCatalog() } /** - * Ensure that the resource model is correctly rewritten + * Ensure that the resource model is correctly rewritten for the configurable attribute collection */ - public function testResourceModelShouldBeResolved() + public function testConfigurableAttributeCollectionResourceModelShouldBeResolved() { $this->assertResourceModelAlias( 'catalog_resource/product_type_configurable_attribute_collection', 'RobbieAverill_AttributeFix_Model_Resource_Product_Type_Configurable_Attribute_Collection' ); } + + /** + * Ensure that the resource model is correctly rewritten for the configurable swatch attribute collection + */ + public function testSwatchAttributeCollectionResourceModelShouldBeResolved() + { + $this->assertResourceModelAlias( + 'configurableswatches_resource/catalog_product_attribute_super_collection', + 'RobbieAverill_AttributeFix_Model_Resource_Catalog_Product_Attribute_Super_Collection' + ); + } + + /** + * Ensure the mediafallback helper extension is in place for swatches to display in the correct order + */ + public function testMediaFallbackHelperShouldExtendCore() + { + $this->assertHelperAlias( + 'configurableswatches/mediafallback', + 'RobbieAverill_AttributeFix_Helper_Mediafallback' + ); + } } diff --git a/app/code/local/RobbieAverill/AttributeFix/Test/Helper/DataTest.php b/app/code/local/RobbieAverill/AttributeFix/Test/Helper/DataTest.php new file mode 100644 index 0000000..ca9c33b --- /dev/null +++ b/app/code/local/RobbieAverill/AttributeFix/Test/Helper/DataTest.php @@ -0,0 +1,55 @@ + + */ +class RobbieAverill_AttributeFix_Test_Helper_DataTest extends EcomDev_PHPUnit_Test_Case +{ + /** + * Ensure that attributes have their order retrieved and are returned in order. We mock the + * method that actually retrieves the attribute option sort orders since we test it separately. + * + * @param int $testCase + * @param array $input + * @param array $order + * + * @dataProvider dataProvider + * @loadExpectation + */ + public function testShouldGetAttributeOrdersThenOrderThem($testCase, $input, $order) + { + $mock = $this->getHelperMock('attributefix', ['getSortOrderForAttributeOptions']); + + $mock + ->expects($this->once()) + ->method('getSortOrderForAttributeOptions') + ->will($this->returnValue($order)); + + $result = $mock->sortOptionValues($input); + + $expected = $this->expected('tc_' . $testCase)->getResult(); + + $this->assertSame($expected, $result); + } + + /** + * The option values should be loaded from the eav_attribute_option table according to their + * sort_order, then returned as a simple array + * + * @param int $attributeId For referencing the fixture + * @param array $input + * + * @loadFixture + * @loadExpectation + * @dataProvider dataProvider + */ + public function testShouldRetrieveOptionsInSortOrder($attributeId, $input) + { + $result = Mage::helper('attributefix')->getSortOrderForAttributeOptions($input); + $expected = $this->expected('attr_' . $attributeId)->getResult(); + $this->assertSame($expected, $result); + } +} diff --git a/app/code/local/RobbieAverill/AttributeFix/Test/Helper/expectations/testShouldGetAttributeOrdersThenOrderThem.yaml b/app/code/local/RobbieAverill/AttributeFix/Test/Helper/expectations/testShouldGetAttributeOrdersThenOrderThem.yaml new file mode 100644 index 0000000..f570621 --- /dev/null +++ b/app/code/local/RobbieAverill/AttributeFix/Test/Helper/expectations/testShouldGetAttributeOrdersThenOrderThem.yaml @@ -0,0 +1,14 @@ +# All options have a sort order +tc_1: + result: + 14: attr2 + 18: attr4 + 12: attr + 16: attr3 +# All sort orders are zero +tc_2: + result: + 1: attr + 2: attr2 + 3: attr3 + 4: attr4 diff --git a/app/code/local/RobbieAverill/AttributeFix/Test/Helper/expectations/testShouldRetrieveOptionsInSortOrder.yaml b/app/code/local/RobbieAverill/AttributeFix/Test/Helper/expectations/testShouldRetrieveOptionsInSortOrder.yaml new file mode 100644 index 0000000..a5086ba --- /dev/null +++ b/app/code/local/RobbieAverill/AttributeFix/Test/Helper/expectations/testShouldRetrieveOptionsInSortOrder.yaml @@ -0,0 +1,12 @@ +attr_18: + result: + 4: '10' + 3: '20' + 2: '30' + 1: '40' +attr_20: + result: + 10: '0' + 11: '0' + 12: '0' + 13: '0' diff --git a/app/code/local/RobbieAverill/AttributeFix/Test/Helper/fixtures/testShouldRetrieveOptionsInSortOrder.yaml b/app/code/local/RobbieAverill/AttributeFix/Test/Helper/fixtures/testShouldRetrieveOptionsInSortOrder.yaml new file mode 100644 index 0000000..fc72083 --- /dev/null +++ b/app/code/local/RobbieAverill/AttributeFix/Test/Helper/fixtures/testShouldRetrieveOptionsInSortOrder.yaml @@ -0,0 +1,28 @@ +# A set of attribute options in reverse order from their entity IDs +tables: + eav/attribute_option: + - option_id: 1 + attribute_id: 18 + sort_order: 40 + - option_id: 2 + attribute_id: 18 + sort_order: 30 + - option_id: 3 + attribute_id: 18 + sort_order: 20 + - option_id: 4 + attribute_id: 18 + sort_order: 10 +# Then, a set of attribute options that have no sort order at all + - option_id: 10 + attribute_id: 20 + sort_order: 0 + - option_id: 11 + attribute_id: 20 + sort_order: 0 + - option_id: 12 + attribute_id: 20 + sort_order: 0 + - option_id: 13 + attribute_id: 20 + sort_order: 0 diff --git a/app/code/local/RobbieAverill/AttributeFix/Test/Helper/providers/testShouldGetAttributeOrdersThenOrderThem.yaml b/app/code/local/RobbieAverill/AttributeFix/Test/Helper/providers/testShouldGetAttributeOrdersThenOrderThem.yaml new file mode 100644 index 0000000..8ad06f4 --- /dev/null +++ b/app/code/local/RobbieAverill/AttributeFix/Test/Helper/providers/testShouldGetAttributeOrdersThenOrderThem.yaml @@ -0,0 +1,22 @@ +# All options have a sort order +- + - 1 + - 12: attr + 14: attr2 + 16: attr3 + 18: attr4 + - 14: 1 + 18: 2 + 12: 3 + 16: 4 +# All sort orders are zero +- + - 2 + - 1: attr + 2: attr2 + 3: attr3 + 4: attr4 + - 1: 0 + 2: 0 + 3: 0 + 4: 0 \ No newline at end of file diff --git a/app/code/local/RobbieAverill/AttributeFix/Test/Helper/providers/testShouldRetrieveOptionsInSortOrder.yaml b/app/code/local/RobbieAverill/AttributeFix/Test/Helper/providers/testShouldRetrieveOptionsInSortOrder.yaml new file mode 100644 index 0000000..573c4ad --- /dev/null +++ b/app/code/local/RobbieAverill/AttributeFix/Test/Helper/providers/testShouldRetrieveOptionsInSortOrder.yaml @@ -0,0 +1,7 @@ +# Provide the attribute ID (to reference the expectation) and a list of the option IDs +- + - 18 + - [4, 2, 3, 1] +- + - 20 + - [10, 11, 12, 13] diff --git a/app/code/local/RobbieAverill/AttributeFix/etc/config.xml b/app/code/local/RobbieAverill/AttributeFix/etc/config.xml index e5ab0b8..a22c69b 100644 --- a/app/code/local/RobbieAverill/AttributeFix/etc/config.xml +++ b/app/code/local/RobbieAverill/AttributeFix/etc/config.xml @@ -11,16 +11,31 @@ --> - 1.0.1 + 1.1.1 + + + RobbieAverill_AttributeFix_Helper + + + + RobbieAverill_AttributeFix_Helper_Mediafallback + + + RobbieAverill_AttributeFix_Model_Resource_Product_Type_Configurable_Attribute_Collection + + + RobbieAverill_AttributeFix_Model_Resource_Catalog_Product_Attribute_Super_Collection + +