Ayaline_RangeFilters_v2 - Version 2.0.1

Version Notes

Known issues :
The attribute type "Values ranges" uses default index table of Magento. It means that only integers will be indexed.

TODOs :
Search Results Layered Navigation.

Download this release

Release Info

Developer Magento Core Team
Extension Ayaline_RangeFilters_v2
Version 2.0.1
Comparing to
See all releases


Version 2.0.1

Files changed (35) hide show
  1. app/code/community/Ayaline/RangeFilters/Block/Adminhtml/Catalog/Product/Attribute/Edit/Tab/Options.php +210 -0
  2. app/code/community/Ayaline/RangeFilters/Block/Adminhtml/Catalog/Product/Attribute/Edit/Tabs.php +49 -0
  3. app/code/community/Ayaline/RangeFilters/Block/Catalog/Layer/Filter/Infogroup.php +44 -0
  4. app/code/community/Ayaline/RangeFilters/Block/Catalog/Layer/Filter/Range.php +44 -0
  5. app/code/community/Ayaline/RangeFilters/Block/Catalog/Layer/View.php +64 -0
  6. app/code/community/Ayaline/RangeFilters/Block/Data/Form/Element/Infogroup.php +46 -0
  7. app/code/community/Ayaline/RangeFilters/Block/Data/Form/Element/Range.php +47 -0
  8. app/code/community/Ayaline/RangeFilters/Helper/Data.php +20 -0
  9. app/code/community/Ayaline/RangeFilters/Model/Catalog/Layer/Filter/Infogroup.php +76 -0
  10. app/code/community/Ayaline/RangeFilters/Model/Catalog/Layer/Filter/Range.php +93 -0
  11. app/code/community/Ayaline/RangeFilters/Model/Catalog/Product/Attribute/Frontend/Infogroup.php +24 -0
  12. app/code/community/Ayaline/RangeFilters/Model/Catalog/Product/Attribute/Frontend/Range.php +24 -0
  13. app/code/community/Ayaline/RangeFilters/Model/Catalog/Product/Attribute/Infogroup.php +21 -0
  14. app/code/community/Ayaline/RangeFilters/Model/Catalog/Product/Attribute/Range.php +21 -0
  15. app/code/community/Ayaline/RangeFilters/Model/Catalog/Product/Attribute/Source/Infogroup.php +59 -0
  16. app/code/community/Ayaline/RangeFilters/Model/Catalog/Product/Attribute/Source/Range.php +60 -0
  17. app/code/community/Ayaline/RangeFilters/Model/CatalogIndex/Infogroup.php +58 -0
  18. app/code/community/Ayaline/RangeFilters/Model/CatalogIndex/Range.php +22 -0
  19. app/code/community/Ayaline/RangeFilters/Model/Mysql4/Catalog/Entity/Attribute.php +121 -0
  20. app/code/community/Ayaline/RangeFilters/Model/Mysql4/Catalog/Product/Attribute/Infogroup.php +21 -0
  21. app/code/community/Ayaline/RangeFilters/Model/Mysql4/Catalog/Product/Attribute/Infogroup/Collection.php +67 -0
  22. app/code/community/Ayaline/RangeFilters/Model/Mysql4/Catalog/Product/Attribute/Range.php +21 -0
  23. app/code/community/Ayaline/RangeFilters/Model/Mysql4/Catalog/Product/Attribute/Range/Collection.php +68 -0
  24. app/code/community/Ayaline/RangeFilters/Model/Mysql4/CatalogIndex/Infogroup.php +160 -0
  25. app/code/community/Ayaline/RangeFilters/Model/Mysql4/CatalogIndex/Range.php +102 -0
  26. app/code/community/Ayaline/RangeFilters/Model/Observer.php +124 -0
  27. app/code/community/Ayaline/RangeFilters/etc/config.xml +157 -0
  28. app/code/community/Ayaline/RangeFilters/sql/ayalinerangefilters_setup/mysql4-install-1.0.0.php +99 -0
  29. app/design/adminhtml/default/default/layout/ayaline/range_filters.xml +35 -0
  30. app/design/adminhtml/default/default/template/ayaline/range_filters/catalog/product/attribute/js.phtml +36 -0
  31. app/design/adminhtml/default/default/template/ayaline/range_filters/catalog/product/attribute/options.phtml +279 -0
  32. app/etc/modules/Ayaline_RangeFilters.xml +9 -0
  33. app/locale/en_US/Ayaline_RangeFilters.csv +7 -0
  34. app/locale/fr_FR/Ayaline_RangeFilters.csv +7 -0
  35. package.xml +43 -0
app/code/community/Ayaline/RangeFilters/Block/Adminhtml/Catalog/Product/Attribute/Edit/Tab/Options.php ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 07/03/11
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author sgautier
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Block_Adminhtml_Catalog_Product_Attribute_Edit_Tab_Options extends Mage_Adminhtml_Block_Catalog_Product_Attribute_Edit_Tab_Options implements Mage_Adminhtml_Block_Widget_Tab_Interface {
17
+ protected function _prepareLayout() {
18
+ parent::_prepareLayout();
19
+
20
+ $this->setChild ( 'delete_range_button', $this->getLayout ()->createBlock ( 'adminhtml/widget_button' )->setData ( array (
21
+ 'label' => Mage::helper ( 'catalog' )->__ ( 'Delete' ),
22
+ 'class' => 'delete delete-range' ) ) );
23
+ $this->setChild ( 'add_button_range', $this->getLayout ()->createBlock ( 'adminhtml/widget_button' )->setData ( array (
24
+ 'label' => Mage::helper ( 'catalog' )->__ ( 'Add Option' ),
25
+ 'class' => 'add',
26
+ 'id' => 'add_new_range_button' ) ) );
27
+
28
+ $this->setChild ( 'delete_infogroup_button', $this->getLayout ()->createBlock ( 'adminhtml/widget_button' )->setData ( array (
29
+ 'label' => Mage::helper ( 'catalog' )->__ ( 'Delete' ),
30
+ 'class' => 'delete delete-infogroup' ) ) );
31
+ $this->setChild ( 'add_button_infogroup', $this->getLayout ()->createBlock ( 'adminhtml/widget_button' )->setData ( array (
32
+ 'label' => Mage::helper ( 'catalog' )->__ ( 'Add Option' ),
33
+ 'class' => 'add',
34
+ 'id' => 'add_new_infogroup_button' ) ) );
35
+
36
+ return $this;
37
+ }
38
+
39
+
40
+
41
+ public function getDeleteRangeButtonHtml() {
42
+ return $this->getChildHtml ( 'delete_range_button' );
43
+ }
44
+
45
+ public function getAddNewRangeButtonHtml() {
46
+ return $this->getChildHtml ( 'add_button_range' );
47
+ }
48
+
49
+ /**
50
+ * @return array
51
+ */
52
+ public function getRangeValues() {
53
+ // $attributeType = $this->getAttributeObject ()->getFrontendInput ();
54
+ $values = $this->getData ( 'range_values' );
55
+ if (is_null ( $values )) {
56
+ $values = array ();
57
+ $rangeCollection = Mage::getResourceModel ( 'ayalinerangefilters/catalog_product_attribute_range_collection' )->setAttributeFilter ( $this->getAttributeObject ()->getId () )->setPositionOrder ( 'desc' )->load ();
58
+
59
+ foreach ( $rangeCollection as $range ) {
60
+ $value = array ();
61
+ $value ['id'] = $range->getId ();
62
+ $value ['sort_order'] = $range->getSortOrder ();
63
+ $value ['value_min'] = $range->getValueMin ();
64
+ $value ['value_max'] = $range->getValueMax ();
65
+ foreach ( $this->getStores () as $store ) {
66
+ $storeValues = $this->getStoreRangeValues ( $store->getId () );
67
+ if (isset ( $storeValues [$range->getId ()] )) {
68
+ $value ['store' . $store->getId ()] = htmlspecialchars ( $storeValues [$range->getId ()] );
69
+ } else {
70
+ $value ['store' . $store->getId ()] = '';
71
+ }
72
+ }
73
+ $values [] = new Varien_Object ( $value );
74
+ }
75
+ $this->setData ( 'range_values', $values );
76
+ }
77
+
78
+ return $values;
79
+ }
80
+
81
+ /**
82
+ *
83
+ * @param int $storeId
84
+ * @return array
85
+ */
86
+ public function getStoreRangeValues($storeId) {
87
+ $values = $this->getData ( 'store_range_values_' . $storeId );
88
+ if (is_null ( $values )) {
89
+ $values = array ();
90
+ $valuesCollection = Mage::getResourceModel ( 'ayalinerangefilters/catalog_product_attribute_range_collection' )->setAttributeFilter ( $this->getAttributeObject ()->getId () )->setStoreFilter ( $storeId, false )->load ();
91
+ foreach ( $valuesCollection as $item ) {
92
+ $values [$item->getId ()] = $item->getValue ();
93
+ }
94
+ $this->setData ( 'store_option_values_' . $storeId, $values );
95
+ }
96
+ return $values;
97
+ }
98
+
99
+
100
+
101
+
102
+ public function getDeleteInfogroupButtonHtml() {
103
+ return $this->getChildHtml ( 'delete_infogroup_button' );
104
+ }
105
+
106
+ public function getAddNewInfogroupButtonHtml() {
107
+ return $this->getChildHtml ( 'add_button_infogroup' );
108
+ }
109
+
110
+ /**
111
+ * @return array
112
+ */
113
+ public function getInfogroupValues() {
114
+ // $attributeType = $this->getAttributeObject ()->getFrontendInput ();
115
+ $values = $this->getData ( 'infogroup_values' );
116
+ if (is_null ( $values )) {
117
+
118
+ $values = array ();
119
+ $infogroupCollection = Mage::getResourceModel ( 'ayalinerangefilters/catalog_product_attribute_infogroup_collection' )
120
+ ->setAttributeFilter ( $this->getAttributeObject ()->getId () )
121
+ ->setPositionOrder ( 'desc' )
122
+ ->load ()
123
+ ;
124
+ foreach ( $infogroupCollection as $infogroup ) {
125
+ $value = array ();
126
+ $value ['id'] = $infogroup->getId ();
127
+ $value ['sort_order'] = $infogroup->getSortOrder ();
128
+ $value ['values_group'] = $infogroup->getValuesGroup ();
129
+ foreach ( $this->getStores () as $store ) {
130
+ $storeValues = $this->getStoreInfogroupValues ( $store->getId () );
131
+ if (isset ( $storeValues [$infogroup->getId ()] )) {
132
+ $value ['store' . $store->getId ()] = htmlspecialchars ( $storeValues [$infogroup->getId ()] );
133
+ } else {
134
+ $value ['store' . $store->getId ()] = '';
135
+ }
136
+ }
137
+ $values [] = new Varien_Object ( $value );
138
+ }
139
+ $this->setData ( 'infogroup_values', $values );
140
+ }
141
+
142
+ return $values;
143
+ }
144
+
145
+ /**
146
+ *
147
+ * @param int $storeId
148
+ * @return array
149
+ */
150
+ public function getStoreInfogroupValues($storeId) {
151
+ $values = $this->getData ( 'store_infogroup_values_' . $storeId );
152
+ if (is_null ( $values )) {
153
+ $values = array ();
154
+ $valuesCollection = Mage::getResourceModel ( 'ayalinerangefilters/catalog_product_attribute_infogroup_collection' )->setAttributeFilter ( $this->getAttributeObject ()->getId () )->setStoreFilter ( $storeId, false )->load ();
155
+ foreach ( $valuesCollection as $item ) {
156
+ $values [$item->getId ()] = $item->getValue ();
157
+ }
158
+ $this->setData ( 'store_option_values_' . $storeId, $values );
159
+ }
160
+ return $values;
161
+ }
162
+
163
+
164
+
165
+
166
+
167
+
168
+ /*************************************************/
169
+ /**
170
+ * Behind : Mage_Adminhtml_Block_Widget_Tab_Interface methods
171
+ */
172
+
173
+ /**
174
+ * Return Tab label
175
+ *
176
+ * @return string
177
+ */
178
+ public function getTabLabel() {
179
+ return Mage::helper('catalog')->__('Manage Label / Options');
180
+ }
181
+
182
+ /**
183
+ * Return Tab title
184
+ *
185
+ * @return string
186
+ */
187
+ public function getTabTitle() {
188
+ return Mage::helper('catalog')->__('Manage Label / Options');
189
+ }
190
+
191
+ /**
192
+ * Can show tab in tabs
193
+ *
194
+ * @return boolean
195
+ */
196
+ public function canShowTab() {
197
+ return true;
198
+ }
199
+
200
+ /**
201
+ * Tab is hidden
202
+ *
203
+ * @return boolean
204
+ */
205
+ public function isHidden() {
206
+ return false;
207
+ }
208
+
209
+
210
+ }
app/code/community/Ayaline/RangeFilters/Block/Adminhtml/Catalog/Product/Attribute/Edit/Tabs.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 04/03/11
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author sgautier
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ class Ayaline_RangeFilters_Block_Adminhtml_Catalog_Product_Attribute_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs {
13
+
14
+ public function __construct() {
15
+ parent::__construct ();
16
+ $this->setId ( 'product_attribute_tabs' );
17
+ $this->setDestElementId ( 'edit_form' );
18
+ $this->setTitle ( Mage::helper ( 'catalog' )->__ ( 'Attribute Information' ) );
19
+ }
20
+
21
+ protected function _beforeToHtml() {
22
+ $this->addTab ( 'main',
23
+ array (
24
+ 'label' => Mage::helper ( 'catalog' )->__ ( 'Properties' ),
25
+ 'title' => Mage::helper ( 'catalog' )->__ ( 'Properties' ),
26
+ 'content' => $this->getLayout ()->createBlock ( 'adminhtml/catalog_product_attribute_edit_tab_main' )->toHtml (),
27
+ 'active' => true ) );
28
+
29
+ $model = Mage::registry ( 'entity_attribute' );
30
+
31
+ // Ayaline change : don't use the native labels
32
+ /*$this->addTab ( 'labels',
33
+ array (
34
+ 'label' => Mage::helper ( 'catalog' )->__ ( 'Manage Label / Options' ),
35
+ 'title' => Mage::helper ( 'catalog' )->__ ( 'Manage Label / Options' ),
36
+ 'content' => $this->getLayout ()->createBlock ( 'adminhtml/catalog_product_attribute_edit_tab_options' )->toHtml () ) );*/
37
+
38
+ /*if ('select' == $model->getFrontendInput()) {
39
+ $this->addTab('options_section', array(
40
+ 'label' => Mage::helper('catalog')->__('Options Control'),
41
+ 'title' => Mage::helper('catalog')->__('Options Control'),
42
+ 'content' => $this->getLayout()->createBlock('adminhtml/catalog_product_attribute_edit_tab_options')->toHtml(),
43
+ ));
44
+ }*/
45
+
46
+ return parent::_beforeToHtml ();
47
+ }
48
+
49
+ }
app/code/community/Ayaline/RangeFilters/Block/Catalog/Layer/Filter/Infogroup.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Block_Catalog_Layer_Filter_Infogroup extends Mage_Catalog_Block_Layer_Filter_Abstract {
17
+
18
+ public function __construct() {
19
+ parent::__construct ();
20
+ $this->_filterModelName = 'ayalinerangefilters/catalog_layer_filter_infogroup';
21
+ }
22
+
23
+ protected function _prepareFilter() {
24
+ $this->_filter->setAttributeModel ( $this->getAttributeModel () );
25
+ return $this;
26
+ }
27
+
28
+ /**
29
+ * Retrieve name of the filter block
30
+ *
31
+ * @return string
32
+ */
33
+ public function getName() {
34
+ $frontendLabel = $this->getAttributeModel ()->getFrontend ()->getLabel ();
35
+ $translations = Mage::getModel ( 'core/translate_string' )->load ( Mage_Catalog_Model_Entity_Attribute::MODULE_NAME . Mage_Core_Model_Translate::SCOPE_SEPARATOR . $frontendLabel )->getStoreTranslations ();
36
+
37
+ $storeId = 0;
38
+ $store = Mage::app ()->getStore ();
39
+ if ($store) {
40
+ $storeId = $store->getId ();
41
+ }
42
+ return isset ( $translations [$storeId] ) ? $translations [$storeId] : $frontendLabel;
43
+ }
44
+ }
app/code/community/Ayaline/RangeFilters/Block/Catalog/Layer/Filter/Range.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Block_Catalog_Layer_Filter_Range extends Mage_Catalog_Block_Layer_Filter_Abstract {
17
+
18
+ public function __construct() {
19
+ parent::__construct ();
20
+ $this->_filterModelName = 'ayalinerangefilters/catalog_layer_filter_range';
21
+ }
22
+
23
+ protected function _prepareFilter() {
24
+ $this->_filter->setAttributeModel ( $this->getAttributeModel () );
25
+ return $this;
26
+ }
27
+
28
+ /**
29
+ * Retrieve name of the filter block
30
+ *
31
+ * @return string
32
+ */
33
+ public function getName() {
34
+ $frontendLabel = $this->getAttributeModel ()->getFrontend ()->getLabel ();
35
+ $translations = Mage::getModel ( 'core/translate_string' )->load ( Mage_Catalog_Model_Entity_Attribute::MODULE_NAME . Mage_Core_Model_Translate::SCOPE_SEPARATOR . $frontendLabel )->getStoreTranslations ();
36
+
37
+ $storeId = 0;
38
+ $store = Mage::app ()->getStore ();
39
+ if ($store) {
40
+ $storeId = $store->getId ();
41
+ }
42
+ return isset ( $translations [$storeId] ) ? $translations [$storeId] : $frontendLabel;
43
+ }
44
+ }
app/code/community/Ayaline/RangeFilters/Block/Catalog/Layer/View.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Block_Catalog_Layer_View extends Mage_Catalog_Block_Layer_View {
17
+
18
+ /**
19
+ * @return Ayaline_RangeFilters_Block_Catalog_Layer_View
20
+ */
21
+ public function _prepareLayout() {
22
+ $stateBlock = $this->getLayout()->createBlock($this->_stateBlockName)
23
+ ->setLayer($this->getLayer());
24
+
25
+ $categoryBlock = $this->getLayout()->createBlock($this->_categoryBlockName)
26
+ ->setLayer($this->getLayer())
27
+ ->init();
28
+
29
+ $this->setChild('layer_state', $stateBlock);
30
+ $this->setChild('category_filter', $categoryBlock);
31
+
32
+ $filterableAttributes = $this->_getFilterableAttributes();
33
+ foreach ($filterableAttributes as $attribute) {
34
+ if ($attribute->getAttributeCode() == 'price') {
35
+ $filterBlockName = $this->_priceFilterBlockName;
36
+ }
37
+ // update filter for range type
38
+ elseif ($attribute->getFrontendInput () == 'range') {
39
+ $filterBlockName = 'ayalinerangefilters/catalog_layer_filter_range';
40
+ }
41
+ // update filter for infogroup type
42
+ elseif ($attribute->getFrontendInput () == 'infogroup') {
43
+ $filterBlockName = 'ayalinerangefilters/catalog_layer_filter_infogroup';
44
+ }
45
+ elseif ($attribute->getBackendType() == 'decimal') {
46
+ $filterBlockName = $this->_decimalFilterBlockName;
47
+ }
48
+ else {
49
+ $filterBlockName = $this->_attributeFilterBlockName;
50
+ }
51
+
52
+ $this->setChild($attribute->getAttributeCode() . '_filter',
53
+ $this->getLayout()->createBlock($filterBlockName)
54
+ ->setLayer($this->getLayer())
55
+ ->setAttributeModel($attribute)
56
+ ->init());
57
+ }
58
+
59
+ $this->getLayer()->apply();
60
+
61
+ return $this;
62
+ }
63
+
64
+ }
app/code/community/Ayaline/RangeFilters/Block/Data/Form/Element/Infogroup.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+
17
+ class Ayaline_RangeFilters_Block_Data_Form_Element_Infogroup extends Varien_Data_Form_Element_Abstract {
18
+ public function __construct($attributes = array()) {
19
+ parent::__construct ( $attributes );
20
+ $this->setType ( 'text' );
21
+ }
22
+
23
+ /**
24
+ * @return string
25
+ */
26
+ public function getHtml() {
27
+ $this->addClass ( 'input-text' );
28
+ return parent::getHtml ();
29
+ }
30
+
31
+ /**
32
+ * @return array
33
+ */
34
+ public function getHtmlAttributes() {
35
+ return array (
36
+ 'type',
37
+ 'title',
38
+ 'class',
39
+ 'style',
40
+ 'onclick',
41
+ 'onchange',
42
+ 'disabled',
43
+ 'readonly',
44
+ 'maxlength' );
45
+ }
46
+ }
app/code/community/Ayaline/RangeFilters/Block/Data/Form/Element/Range.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+
17
+ class Ayaline_RangeFilters_Block_Data_Form_Element_Range extends Varien_Data_Form_Element_Abstract {
18
+ public function __construct($attributes = array()) {
19
+ parent::__construct ( $attributes );
20
+ $this->setType ( 'text' );
21
+ }
22
+
23
+ /**
24
+ * @return string
25
+ */
26
+ public function getHtml() {
27
+ $this->addClass ( 'input-text' );
28
+ $this->addClass ( 'validate-number' );
29
+ return parent::getHtml ();
30
+ }
31
+
32
+ /**
33
+ * @return array
34
+ */
35
+ public function getHtmlAttributes() {
36
+ return array (
37
+ 'type',
38
+ 'title',
39
+ 'class',
40
+ 'style',
41
+ 'onclick',
42
+ 'onchange',
43
+ 'disabled',
44
+ 'readonly',
45
+ 'maxlength' );
46
+ }
47
+ }
app/code/community/Ayaline/RangeFilters/Helper/Data.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+
17
+ class Ayaline_RangeFilters_Helper_Data extends Mage_Core_Helper_Abstract
18
+ {
19
+
20
+ }
app/code/community/Ayaline/RangeFilters/Model/Catalog/Layer/Filter/Infogroup.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Model_Catalog_Layer_Filter_Infogroup extends Mage_Catalog_Model_Layer_Filter_Abstract {
17
+ const OPTIONS_ONLY_WITH_RESULTS = 1;
18
+
19
+ public function __construct() {
20
+ parent::__construct ();
21
+ $this->_requestVar = 'attribute';
22
+ }
23
+
24
+ protected function _getOptionText($optionId) {
25
+ return $this->getAttributeModel ()->getFrontend ()->getOption ( $optionId );
26
+ }
27
+
28
+ public function apply(Zend_Controller_Request_Abstract $request, $filterBlock) {
29
+ $filter = $request->getParam ( $this->_requestVar );
30
+ $text = $this->_getOptionText ( $filter );
31
+ if ($filter && $text) {
32
+ /*$entityIds = Mage::getSingleton('catalogindex/attribute')->getFilteredEntities($this->getAttributeModel(), $filter, $this->_getFilterEntityIds());
33
+ if ($entityIds) {
34
+ $this->getLayer()->getProductCollection()
35
+ ->addFieldToFilter('entity_id', array('in' => $entityIds));
36
+
37
+ $this->getLayer()->getState()->addFilter(
38
+ $this->_createItem($text, $filter)
39
+ );
40
+ $this->_items = array();
41
+ }*/
42
+ Mage::getSingleton ( 'ayalinerangefilters/catalogIndex_infogroup' )->applyFilterToCollection ( $this->getLayer ()->getProductCollection (), $this->getAttributeModel (), $filter );
43
+ $this->getLayer ()->getState ()->addFilter ( $this->_createItem ( $text, $filter ) );
44
+ $this->_items = array ();
45
+ }
46
+ return $this;
47
+ }
48
+
49
+ protected function _initItems() {
50
+ $attribute = $this->getAttributeModel ();
51
+ $options = $attribute->getFrontend ()->getSelectOptions ();
52
+
53
+ //$optionsCount = Mage::getSingleton('catalogindex/attribute')->getCount($attribute, $this->_getFilterEntityIds());
54
+ $optionsCount = Mage::getSingleton ( 'ayalinerangefilters/catalogIndex_infogroup' )->getCount ( $attribute, $this->_getBaseCollectionSql () );
55
+
56
+ $this->_requestVar = $attribute->getAttributeCode ();
57
+
58
+ $items = array ();
59
+
60
+ foreach ( $options as $option ) {
61
+ if (strlen ( $option ['value'] )) {
62
+ // Check filter type
63
+ if ($attribute->getIsFilterable () == self::OPTIONS_ONLY_WITH_RESULTS) {
64
+ if (! empty ( $optionsCount [$option ['value']] )) {
65
+ $items [] = Mage::getModel ( 'catalog/layer_filter_item' )->setFilter ( $this )->setLabel ( $option ['label'] )->setValue ( $option ['value'] )->setCount ( $optionsCount [$option ['value']] );
66
+ }
67
+ } else {
68
+ $items [] = Mage::getModel ( 'catalog/layer_filter_item' )->setFilter ( $this )->setLabel ( $option ['label'] )->setValue ( $option ['value'] )->setCount ( isset ( $optionsCount [$option ['value']] ) ? $optionsCount [$option ['value']] : 0 );
69
+ }
70
+ }
71
+ }
72
+
73
+ $this->_items = $items;
74
+ return $this;
75
+ }
76
+ }
app/code/community/Ayaline/RangeFilters/Model/Catalog/Layer/Filter/Range.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Model_Catalog_Layer_Filter_Range extends Mage_Catalog_Model_Layer_Filter_Abstract {
17
+ const OPTIONS_ONLY_WITH_RESULTS = 1;
18
+
19
+ public function __construct() {
20
+ parent::__construct ();
21
+ $this->_requestVar = 'attribute';
22
+ }
23
+
24
+ protected function _getOptionText($optionId) {
25
+ $a = $this->getAttributeModel ();
26
+ $b = $a->getFrontend ();
27
+ $c = $b->getOption ( $optionId );
28
+ return $c;
29
+ }
30
+
31
+ public function apply(Zend_Controller_Request_Abstract $request, $filterBlock) {
32
+ $filter = $request->getParam ( $this->_requestVar );
33
+ $text = $this->_getOptionText ( $filter );
34
+ if ($filter && $text) {
35
+ /*$entityIds = Mage::getSingleton('catalogindex/attribute')->getFilteredEntities($this->getAttributeModel(), $filter, $this->_getFilterEntityIds());
36
+ if ($entityIds) {
37
+ $this->getLayer()->getProductCollection()
38
+ ->addFieldToFilter('entity_id', array('in' => $entityIds));
39
+
40
+ $this->getLayer()->getState()->addFilter(
41
+ $this->_createItem($text, $filter)
42
+ );
43
+ $this->_items = array();
44
+ }*/
45
+ Mage::getSingleton ( 'ayalinerangefilters/catalogIndex_range' )->applyFilterToCollection ( $this->getLayer ()->getProductCollection (), $this->getAttributeModel (), $filter );
46
+ $this->getLayer ()->getState ()->addFilter ( $this->_createItem ( $text, $filter ) );
47
+ $this->_items = array ();
48
+ }
49
+ return $this;
50
+ }
51
+
52
+ protected function _initItems() {
53
+ $attribute = $this->getAttributeModel ();
54
+ $options = $attribute->getFrontend ()->getSelectOptions ();
55
+
56
+ //$optionsCount = Mage::getSingleton('catalogindex/attribute')->getCount($attribute, $this->_getFilterEntityIds());
57
+ $optionsCount = Mage::getSingleton ( 'ayalinerangefilters/catalogIndex_range' )->getCount ( $attribute, $this->_getBaseCollectionSql () );
58
+ $this->_requestVar = $attribute->getAttributeCode ();
59
+
60
+ $items = array ();
61
+
62
+ foreach ( $options as $option ) {
63
+ if (strlen ( $option ['value'] )) {
64
+ // Check filter type
65
+ if ($attribute->getIsFilterable () == self::OPTIONS_ONLY_WITH_RESULTS) {
66
+ if (! empty ( $optionsCount [$option ['value']] )) {
67
+ $items [] = Mage::getModel ( 'catalog/layer_filter_item' )->setFilter ( $this )->setLabel ( $option ['label'] )->setValue ( $option ['value'] )->setCount ( $optionsCount [$option ['value']] );
68
+ }
69
+ } else {
70
+ $items [] = Mage::getModel ( 'catalog/layer_filter_item' )->setFilter ( $this )->setLabel ( $option ['label'] )->setValue ( $option ['value'] )->setCount ( isset ( $optionsCount [$option ['value']] ) ? $optionsCount [$option ['value']] : 0 );
71
+ }
72
+ }
73
+ }
74
+
75
+ $this->_items = $items;
76
+ return $this;
77
+ }
78
+
79
+ public function getName()
80
+ {
81
+ $frontendLabel = $this->getAttributeModel()->getFrontend()->getLabel();
82
+ $translations = Mage::getModel('core/translate_string')
83
+ ->load(Mage_Catalog_Model_Entity_Attribute::MODULE_NAME.Mage_Core_Model_Translate::SCOPE_SEPARATOR.$frontendLabel)
84
+ ->getStoreTranslations();
85
+
86
+ $storeId = 0;
87
+ $store = Mage::app()->getStore();
88
+ if($store){
89
+ $storeId = $store->getId();
90
+ }
91
+ return isset($translations[$storeId]) ? $translations[$storeId] : $frontendLabel;
92
+ }
93
+ }
app/code/community/Ayaline/RangeFilters/Model/Catalog/Product/Attribute/Frontend/Infogroup.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Model_Catalog_Product_Attribute_Frontend_Infogroup extends Mage_Eav_Model_Entity_Attribute_Frontend_Abstract {
17
+
18
+ public function getSelectOptions() {
19
+ return $this->getAttribute ()->getSource ()->getAllOptions ();
20
+ }
21
+
22
+ }
23
+
24
+ ?>
app/code/community/Ayaline/RangeFilters/Model/Catalog/Product/Attribute/Frontend/Range.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Model_Catalog_Product_Attribute_Frontend_Range extends Mage_Eav_Model_Entity_Attribute_Frontend_Abstract {
17
+
18
+ public function getSelectOptions() {
19
+ return $this->getAttribute ()->getSource ()->getAllOptions ();
20
+ }
21
+
22
+ }
23
+
24
+ ?>
app/code/community/Ayaline/RangeFilters/Model/Catalog/Product/Attribute/Infogroup.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+
17
+ class Ayaline_RangeFilters_Model_Catalog_Product_Attribute_Infogroup extends Mage_Core_Model_Abstract {
18
+ public function _construct() {
19
+ $this->_init ( 'ayalinerangefilters/catalog_product_attribute_infogroup' );
20
+ }
21
+ }
app/code/community/Ayaline/RangeFilters/Model/Catalog/Product/Attribute/Range.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+
17
+ class Ayaline_RangeFilters_Model_Catalog_Product_Attribute_Range extends Mage_Core_Model_Abstract {
18
+ public function _construct() {
19
+ $this->_init ( 'ayalinerangefilters/catalog_product_attribute_range' );
20
+ }
21
+ }
app/code/community/Ayaline/RangeFilters/Model/Catalog/Product/Attribute/Source/Infogroup.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+
17
+ class Ayaline_RangeFilters_Model_Catalog_Product_Attribute_Source_Infogroup extends Mage_Eav_Model_Entity_Attribute_Source_Abstract {
18
+
19
+ public function getAllOptions($withEmpty = true) {
20
+ if (is_null ( $this->_options )) {
21
+ $this->_options = Mage::getResourceModel ( 'ayalinerangefilters/catalog_product_attribute_infogroup_collection' )->setAttributeFilter ( $this->getAttribute ()->getId () )->setStoreFilter ( $this->getAttribute ()->getStoreId () )->setPositionOrder ( 'asc' )->load ()->toOptionArray ();
22
+ }
23
+ $options = $this->_options;
24
+ if ($withEmpty) {
25
+ array_unshift ( $options, array (
26
+ 'label' => '',
27
+ 'value' => '',
28
+ 'values_group' => '' ) );
29
+ }
30
+ return $options;
31
+ }
32
+
33
+ public function getOptionText($value) {
34
+ $isMultiple = false;
35
+ if (strpos ( $value, ',' )) {
36
+ $isMultiple = true;
37
+ $value = explode ( ',', $value );
38
+ }
39
+
40
+ $options = $this->getAllOptions ( false );
41
+
42
+ if ($isMultiple) {
43
+ $values = array ();
44
+ foreach ( $options as $item ) {
45
+ if (in_array ( $item ['value'], $value )) {
46
+ $values [] = $item ['label'];
47
+ }
48
+ }
49
+ return $values;
50
+ } else {
51
+ foreach ( $options as $item ) {
52
+ if ($item ['value'] == $value) {
53
+ return $item ['label'];
54
+ }
55
+ }
56
+ return false;
57
+ }
58
+ }
59
+ }
app/code/community/Ayaline/RangeFilters/Model/Catalog/Product/Attribute/Source/Range.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+
17
+ class Ayaline_RangeFilters_Model_Catalog_Product_Attribute_Source_Range extends Mage_Eav_Model_Entity_Attribute_Source_Abstract {
18
+
19
+ public function getAllOptions($withEmpty = true) {
20
+ if (is_null ( $this->_options )) {
21
+ $this->_options = Mage::getResourceModel ( 'ayalinerangefilters/catalog_product_attribute_range_collection' )->setAttributeFilter ( $this->getAttribute ()->getId () )->setStoreFilter ( $this->getAttribute ()->getStoreId () )->setPositionOrder ( 'asc' )->load ()->toOptionArray ();
22
+ }
23
+ $options = $this->_options;
24
+ if ($withEmpty) {
25
+ array_unshift ( $options, array (
26
+ 'label' => '',
27
+ 'value' => '',
28
+ 'value_min' => '',
29
+ 'value_max' => '' ) );
30
+ }
31
+ return $options;
32
+ }
33
+
34
+ public function getOptionText($value) {
35
+ $isMultiple = false;
36
+ if (strpos ( $value, ',' )) {
37
+ $isMultiple = true;
38
+ $value = explode ( ',', $value );
39
+ }
40
+
41
+ $options = $this->getAllOptions ( false );
42
+
43
+ if ($isMultiple) {
44
+ $values = array ();
45
+ foreach ( $options as $item ) {
46
+ if (in_array ( $item ['value'], $value )) {
47
+ $values [] = $item ['label'];
48
+ }
49
+ }
50
+ return $values;
51
+ } else {
52
+ foreach ( $options as $item ) {
53
+ if ($item ['value'] == $value) {
54
+ return $item ['label'];
55
+ }
56
+ }
57
+ return false;
58
+ }
59
+ }
60
+ }
app/code/community/Ayaline/RangeFilters/Model/CatalogIndex/Infogroup.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Model_CatalogIndex_Infogroup extends Mage_CatalogIndex_Model_Attribute {
17
+
18
+ public function _construct() {
19
+ parent::_construct ();
20
+ $this->_init ( 'ayalinerangefilters/catalogIndex_infogroup' );
21
+ $this->_getResource ()->setStoreId ( Mage::app ()->getStore ()->getId () );
22
+ }
23
+
24
+ public function reindex($product) {
25
+ // Suppression des index infogroup
26
+ $this->getResource()->deleteInfogroupIndex ( $product );
27
+
28
+ // indexation
29
+ $attributes = $this->getResource()->loadIndexableInfogroupAttributes ();
30
+ if (count($attributes)>0) {
31
+ $stores = $this->_getStores ();
32
+ foreach ( $stores as $storeId => $store ) {
33
+ $datas = $this->getResource ()->getAttributeData ( $product->getId (), $attributes, $storeId );
34
+ foreach ( $datas as $data ) {
35
+ $model = Mage::getModel ( "ayalinerangefilters/catalogIndex_infogroup" );
36
+ $model->setStoreId ( $storeId );
37
+ $model->setEntityId ( $data ['entity_id'] );
38
+ $model->setAttributeId ( $data ['attribute_id'] );
39
+ $model->setValue ( $data ['value'] );
40
+ $model->save ();
41
+ }
42
+ }
43
+ }
44
+
45
+ }
46
+
47
+ protected function _getStores() {
48
+ $stores = $this->getData ( '_stores' );
49
+ if (is_null ( $stores )) {
50
+ $stores = array ();
51
+ $stores = Mage::getModel ( 'core/store' )->getCollection ()->setLoadDefault ( false )->load ();
52
+ $this->setData ( '_stores', $stores );
53
+ }
54
+ return $stores;
55
+ }
56
+
57
+ }
58
+ ?>
app/code/community/Ayaline/RangeFilters/Model/CatalogIndex/Range.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Model_CatalogIndex_Range extends Mage_CatalogIndex_Model_Attribute {
17
+ protected function _construct() {
18
+ $this->_init ( 'ayalinerangefilters/catalogIndex_range' );
19
+ $this->_getResource ()->setStoreId ( Mage::app ()->getStore ()->getId () );
20
+ }
21
+
22
+ }
app/code/community/Ayaline/RangeFilters/Model/Mysql4/Catalog/Entity/Attribute.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Model_Mysql4_Catalog_Entity_Attribute extends Mage_Eav_Model_Mysql4_Entity_Attribute {
17
+
18
+ public function ayalineSaveOptions(Mage_Core_Model_Abstract $object) {
19
+ $this->_saveRange ( $object );
20
+ $this->_saveInfogroup ( $object );
21
+ return parent::_saveOption ( $object );
22
+ }
23
+
24
+ protected function _saveInfogroup(Mage_Core_Model_Abstract $object) {
25
+ $infogroup = $object->getInfogroup ();
26
+ if (is_array ( $infogroup )) {
27
+ $write = $this->_getWriteAdapter ();
28
+ $infogroupTable = $this->getTable ( 'ayalinerangefilters/eav_attribute_infogroup' );
29
+ $infogroupValueTable = $this->getTable ( 'ayalinerangefilters/eav_attribute_infogroup_value' );
30
+ $stores = Mage::getModel ( 'core/store' )->getResourceCollection ()->setLoadDefault ( true )->load ();
31
+ if (isset ( $infogroup ['value'] )) {
32
+ foreach ( $infogroup ['value'] as $infogroupId => $values ) {
33
+ $intInfogroupId = ( int ) $infogroupId;
34
+ if (! empty ( $infogroup ['delete'] [$infogroupId] )) {
35
+ if ($intInfogroupId) {
36
+ $condition = $write->quoteInto ( 'infogroup_id=?', $intInfogroupId );
37
+ $write->delete ( $infogroupTable, $condition );
38
+ }
39
+ continue;
40
+ }
41
+ if (! $intInfogroupId) {
42
+ $data = array (
43
+ 'attribute_id' => $object->getId (),
44
+ 'values_group' => isset ( $infogroup ['values_group'] [$infogroupId] ) ? $infogroup ['values_group'] [$infogroupId] : 0,
45
+ 'sort_order' => isset ( $infogroup ['order'] [$infogroupId] ) ? $infogroup ['order'] [$infogroupId] : 0 );
46
+ $write->insert ( $infogroupTable, $data );
47
+ $intInfogroupId = $write->lastInsertId ();
48
+ } else {
49
+ $data = array (
50
+ 'values_group' => isset ( $infogroup ['values_group'] [$infogroupId] ) ? $infogroup ['values_group'] [$infogroupId] : 0,
51
+ 'sort_order' => isset ( $infogroup ['order'] [$infogroupId] ) ? $infogroup ['order'] [$infogroupId] : 0 );
52
+ $write->update ( $infogroupTable, $data, $write->quoteInto ( 'infogroup_id=?', $intInfogroupId ) );
53
+ }
54
+ $write->delete ( $infogroupValueTable, $write->quoteInto ( 'infogroup_id=?', $intInfogroupId ) );
55
+ foreach ( $stores as $store ) {
56
+ if (! empty ( $values [$store->getId ()] ) || $values [$store->getId ()] == "0") {
57
+ $data = array (
58
+ 'infogroup_id' => $intInfogroupId,
59
+ 'store_id' => $store->getId (),
60
+ 'value' => $values [$store->getId ()] );
61
+ $write->insert ( $infogroupValueTable, $data );
62
+ }
63
+ }
64
+ }
65
+ $attribute = Mage::getModel ( 'eav/entity_attribute' )->load ( $object->getId () );
66
+ $attribute->save ();
67
+ }
68
+ }
69
+ }
70
+
71
+ protected function _saveRange(Mage_Core_Model_Abstract $object) {
72
+ $range = $object->getRange ();
73
+ if (is_array ( $range )) {
74
+ $write = $this->_getWriteAdapter ();
75
+ $rangeTable = $this->getTable ( 'ayalinerangefilters/eav_attribute_range' );
76
+ $rangeValueTable = $this->getTable ( 'ayalinerangefilters/eav_attribute_range_value' );
77
+ $stores = Mage::getModel ( 'core/store' )->getResourceCollection ()->setLoadDefault ( true )->load ();
78
+ if (isset ( $range ['value'] )) {
79
+ foreach ( $range ['value'] as $rangeId => $values ) {
80
+ $intRangeId = ( int ) $rangeId;
81
+ if (! empty ( $range ['delete'] [$rangeId] )) {
82
+ if ($intRangeId) {
83
+ $condition = $write->quoteInto ( 'range_id=?', $intRangeId );
84
+ $write->delete ( $rangeTable, $condition );
85
+ }
86
+ continue;
87
+ }
88
+ if (! $intRangeId) {
89
+ $data = array (
90
+ 'attribute_id' => $object->getId (),
91
+ 'value_min' => isset ( $range ['value_min'] [$rangeId] ) ? $range ['value_min'] [$rangeId] : 0,
92
+ 'value_max' => isset ( $range ['value_max'] [$rangeId] ) ? $range ['value_max'] [$rangeId] : new Zend_Db_Expr ( "NULL" ),
93
+ 'sort_order' => isset ( $range ['order'] [$rangeId] ) ? $range ['order'] [$rangeId] : 0 );
94
+ $write->insert ( $rangeTable, $data );
95
+ $intRangeId = $write->lastInsertId ();
96
+ } else {
97
+ $data = array (
98
+ 'value_min' => isset ( $range ['value_min'] [$rangeId] ) ? $range ['value_min'] [$rangeId] : 0,
99
+ 'value_max' => isset ( $range ['value_max'] [$rangeId] ) ? $range ['value_max'] [$rangeId] : new Zend_Db_Expr ( "NULL" ),
100
+ 'sort_order' => isset ( $range ['order'] [$rangeId] ) ? $range ['order'] [$rangeId] : 0 );
101
+ $write->update ( $rangeTable, $data, $write->quoteInto ( 'range_id=?', $intRangeId ) );
102
+ }
103
+ $write->delete ( $rangeValueTable, $write->quoteInto ( 'range_id=?', $intRangeId ) );
104
+ foreach ( $stores as $store ) {
105
+ if (! empty ( $values [$store->getId ()] ) || $values [$store->getId ()] == "0") {
106
+ $data = array (
107
+ 'range_id' => $intRangeId,
108
+ 'store_id' => $store->getId (),
109
+ 'value' => $values [$store->getId ()] );
110
+ $write->insert ( $rangeValueTable, $data );
111
+ }
112
+ }
113
+ }
114
+ $attribute = Mage::getModel ( 'eav/entity_attribute' )->load ( $object->getId () );
115
+ $attribute->save ();
116
+ }
117
+ }
118
+ }
119
+ }
120
+
121
+ ?>
app/code/community/Ayaline/RangeFilters/Model/Mysql4/Catalog/Product/Attribute/Infogroup.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+
17
+ class Ayaline_RangeFilters_Model_Mysql4_Catalog_Product_Attribute_Infogroup extends Mage_Core_Model_Mysql4_Abstract {
18
+ public function _construct() {
19
+ $this->_init ( 'ayalinerangefilters/eav_attribute_infogroup', 'infogroup_id' );
20
+ }
21
+ }
app/code/community/Ayaline/RangeFilters/Model/Mysql4/Catalog/Product/Attribute/Infogroup/Collection.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Model_Mysql4_Catalog_Product_Attribute_Infogroup_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract {
17
+ protected $_infogroupValueTable;
18
+
19
+ public function _construct() {
20
+ $this->_init ( 'ayalinerangefilters/catalog_product_attribute_infogroup' );
21
+ $this->_infogroupValueTable = Mage::getSingleton ( 'core/resource' )->getTableName ( 'ayalinerangefilters/eav_attribute_infogroup_value' );
22
+ }
23
+
24
+ public function setAttributeFilter($setId) {
25
+ $this->getSelect ()->where ( 'main_table.attribute_id=?', $setId );
26
+ return $this;
27
+ }
28
+
29
+ public function setStoreFilter($storeId = null, $useDefaultValue = true) {
30
+ if (is_null ( $storeId )) {
31
+ $storeId = Mage::app ()->getStore ()->getId ();
32
+ }
33
+ if ($useDefaultValue) {
34
+ $this->getSelect ()->join ( array (
35
+ 'store_default_value' => $this->_infogroupValueTable ), 'store_default_value.infogroup_id=main_table.infogroup_id', array (
36
+ 'default_value' => 'value' ) )->joinLeft ( array (
37
+ 'store_value' => $this->_infogroupValueTable ), 'store_value.infogroup_id=main_table.infogroup_id AND ' . $this->getConnection ()->quoteInto ( 'store_value.store_id=?', $storeId ),
38
+ array (
39
+ 'store_value' => 'value',
40
+ 'value' => new Zend_Db_Expr ( 'IFNULL(store_value.value,store_default_value.value)' ) ) )->where ( $this->getConnection ()->quoteInto ( 'store_default_value.store_id=?', 0 ) );
41
+ } else {
42
+ $this->getSelect ()->joinLeft ( array (
43
+ 'store_value' => $this->_infogroupValueTable ), 'store_value.infogroup_id=main_table.infogroup_id AND ' . $this->getConnection ()->quoteInto ( 'store_value.store_id=?', $storeId ), 'value' )->where ( $this->getConnection ()->quoteInto ( 'store_value.store_id=?', $storeId ) );
44
+ }
45
+
46
+ return $this;
47
+ }
48
+
49
+ public function setIdFilter($id) {
50
+ if (is_array ( $id )) {
51
+ $this->getSelect ()->where ( 'main_table.infogroup_id IN (?)', $id );
52
+ } else {
53
+ $this->getSelect ()->where ( 'main_table.infogroup_id=?', $id );
54
+ }
55
+ return $this;
56
+ }
57
+
58
+ public function toOptionArray() {
59
+ return $this->_toOptionArray ( 'infogroup_id', 'value', array (
60
+ 'values_group' => 'values_group' ) );
61
+ }
62
+
63
+ public function setPositionOrder($dir = 'asc') {
64
+ $this->setOrder ( 'main_table.sort_order', $dir );
65
+ return $this;
66
+ }
67
+ }
app/code/community/Ayaline/RangeFilters/Model/Mysql4/Catalog/Product/Attribute/Range.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+
17
+ class Ayaline_RangeFilters_Model_Mysql4_Catalog_Product_Attribute_Range extends Mage_Core_Model_Mysql4_Abstract {
18
+ public function _construct() {
19
+ $this->_init ( 'ayalinerangefilters/eav_attribute_range', 'range_id' );
20
+ }
21
+ }
app/code/community/Ayaline/RangeFilters/Model/Mysql4/Catalog/Product/Attribute/Range/Collection.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Model_Mysql4_Catalog_Product_Attribute_Range_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract {
17
+ protected $_rangeValueTable;
18
+
19
+ public function _construct() {
20
+ $this->_init ( 'ayalinerangefilters/catalog_product_attribute_range' );
21
+ $this->_rangeValueTable = Mage::getSingleton ( 'core/resource' )->getTableName ( 'ayalinerangefilters/eav_attribute_range_value' );
22
+ }
23
+
24
+ public function setAttributeFilter($setId) {
25
+ $this->getSelect ()->where ( 'main_table.attribute_id=?', $setId );
26
+ return $this;
27
+ }
28
+
29
+ public function setStoreFilter($storeId = null, $useDefaultValue = true) {
30
+ if (is_null ( $storeId )) {
31
+ $storeId = Mage::app ()->getStore ()->getId ();
32
+ }
33
+ if ($useDefaultValue) {
34
+ $this->getSelect ()->join ( array (
35
+ 'store_default_value' => $this->_rangeValueTable ), 'store_default_value.range_id=main_table.range_id', array (
36
+ 'default_value' => 'value' ) )->joinLeft ( array (
37
+ 'store_value' => $this->_rangeValueTable ), 'store_value.range_id=main_table.range_id AND ' . $this->getConnection ()->quoteInto ( 'store_value.store_id=?', $storeId ),
38
+ array (
39
+ 'store_value' => 'value',
40
+ 'value' => new Zend_Db_Expr ( 'IFNULL(store_value.value,store_default_value.value)' ) ) )->where ( $this->getConnection ()->quoteInto ( 'store_default_value.store_id=?', 0 ) );
41
+ } else {
42
+ $this->getSelect ()->joinLeft ( array (
43
+ 'store_value' => $this->_rangeValueTable ), 'store_value.range_id=main_table.range_id AND ' . $this->getConnection ()->quoteInto ( 'store_value.store_id=?', $storeId ), 'value' )->where ( $this->getConnection ()->quoteInto ( 'store_value.store_id=?', $storeId ) );
44
+ }
45
+
46
+ return $this;
47
+ }
48
+
49
+ public function setIdFilter($id) {
50
+ if (is_array ( $id )) {
51
+ $this->getSelect ()->where ( 'main_table.range_id IN (?)', $id );
52
+ } else {
53
+ $this->getSelect ()->where ( 'main_table.range_id=?', $id );
54
+ }
55
+ return $this;
56
+ }
57
+
58
+ public function toOptionArray() {
59
+ return $this->_toOptionArray ( 'range_id', 'value', array (
60
+ 'value_min' => 'value_min',
61
+ 'value_max' => 'value_max' ) );
62
+ }
63
+
64
+ public function setPositionOrder($dir = 'asc') {
65
+ $this->setOrder ( 'main_table.sort_order', $dir );
66
+ return $this;
67
+ }
68
+ }
app/code/community/Ayaline/RangeFilters/Model/Mysql4/CatalogIndex/Infogroup.php ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Model_Mysql4_CatalogIndex_Infogroup extends Mage_CatalogIndex_Model_Mysql4_Attribute {
17
+
18
+ public function _construct() {
19
+ // Note that the second argument refers to the key field in your database table.
20
+ $this->_init ( 'ayalinerangefilters/catalogindex_infogroup', 'index_id' );
21
+ }
22
+
23
+ static public function _prepareCondition($data) {
24
+ return "'" . addslashes ( $data ) . "'";
25
+ }
26
+
27
+ public function getCount($attribute, $entitySelect) {
28
+ $case = "";
29
+ foreach ( $attribute->getFrontend ()->getSelectOptions () as $infogroup ) {
30
+ if ($infogroup ['value']) {
31
+ $valuesGroup = $infogroup ['values_group'];
32
+ if ($valuesGroup) {
33
+ $conditions = explode ( ",", $valuesGroup );
34
+ $conditions = array_map ( array (
35
+ 'Ayaline_RangeFilters_Model_Mysql4_CatalogIndex_Infogroup',
36
+ '_prepareCondition' ), $conditions );
37
+ $conditions = implode ( ",", $conditions );
38
+ $case .= "WHEN index.value IN ($conditions) THEN {$infogroup['value']} ";
39
+ }
40
+ }
41
+ }
42
+
43
+ $novalues = false;
44
+ if (empty ( $case )) {
45
+ $novalues = true;
46
+ $case = "-1";
47
+ } else {
48
+ $case = "CASE $case END";
49
+ }
50
+
51
+ $_infogroup = new Zend_Db_Expr ( $case );
52
+
53
+ $select = clone $entitySelect;
54
+ $select->reset ( Zend_Db_Select::COLUMNS );
55
+ $select->reset ( Zend_Db_Select::ORDER );
56
+
57
+ $fields = array (
58
+ 'count' => 'COUNT(DISTINCT index.entity_id)',
59
+ '_infogroup' => $_infogroup );
60
+
61
+ $select->from ( '', $fields )->join ( array (
62
+ 'index' => $this->getMainTable () ), 'index.entity_id=e.entity_id', array () )->where ( 'index.store_id = ?', $this->getStoreId () )->where ( 'index.attribute_id = ?', $attribute->getId () )->group ( array (
63
+ '_infogroup' ) );
64
+
65
+ if ($novalues) {
66
+ $select->where('1=0');
67
+ }
68
+
69
+ $select = $select->__toString ();
70
+
71
+ $alias = $this->_getReadAdapter ()->quoteTableAs ( $this->getMainTable (), 'index' );
72
+ $result = $this->_getReadAdapter ()->fetchAll ( $select );
73
+
74
+ $counts = array ();
75
+ foreach ( $result as $row ) {
76
+ $counts [$row ['_infogroup']] = $row ['count'];
77
+ }
78
+ return $counts;
79
+ }
80
+
81
+ public function getAttributeData($products, $attributes, $store) {
82
+ $suffixes = array (
83
+ 'decimal',
84
+ 'varchar',
85
+ 'int',
86
+ 'text',
87
+ 'datetime' );
88
+ if (! is_array ( $products )) {
89
+ $products = new Zend_Db_Expr ( $products );
90
+ }
91
+ $result = array ();
92
+ foreach ( $suffixes as $suffix ) {
93
+ $tableName = "{$this->getTable('catalog/product')}_{$suffix}";
94
+ $condition = "product.entity_id = c.entity_id AND c.store_id = {$store} AND c.attribute_id = d.attribute_id";
95
+ $defaultCondition = "product.entity_id = d.entity_id AND d.store_id = 0";
96
+ $fields = array (
97
+ 'entity_id',
98
+ 'type_id',
99
+ 'attribute_id' => 'IFNULL(c.attribute_id, d.attribute_id)',
100
+ 'value' => 'IFNULL(c.value, d.value)' );
101
+
102
+ $select = $this->_getReadAdapter ()->select ()->from ( array (
103
+ 'product' => $this->getTable ( 'catalog/product' ) ), $fields )->where ( 'product.entity_id in (?)', $products )->joinRight ( array (
104
+ 'd' => $tableName ), $defaultCondition, array () )->joinLeft ( array (
105
+ 'c' => $tableName ), $condition, array () )->where ( 'c.attribute_id IN (?) OR d.attribute_id IN (?)', $attributes );
106
+
107
+ $part = $this->_getReadAdapter ()->fetchAll ( $select );
108
+
109
+ if (is_array ( $part )) {
110
+ $result = array_merge ( $result, $part );
111
+ }
112
+ }
113
+
114
+ return $result;
115
+ }
116
+
117
+ public function loadIndexableInfogroupAttributes() {
118
+ $table = $this->getTable ( 'eav/attribute' );
119
+ $select = $this->_getReadAdapter ()->select ();
120
+ $select
121
+ ->from ( array('ea' => $table), 'attribute_id' )
122
+ ->distinct ( true )
123
+ ->joinInner(
124
+ array('cea' => $this->getTable ( 'catalog/eav_attribute' )),
125
+ 'cea.attribute_id = ea.attribute_id',
126
+ array()
127
+ )
128
+ ;
129
+ $conditions = "ea.frontend_input IN ('infogroup') AND (cea.is_filterable IN (1, 2) OR cea.is_visible_in_advanced_search = 1)";
130
+ $select->where ( $conditions );
131
+ return $this->_getReadAdapter ()->fetchCol ( $select );
132
+ }
133
+
134
+ public function deleteInfogroupIndex($object) {
135
+
136
+ $this->_getWriteAdapter ()->delete ( $this->getMainTable (), $this->_getWriteAdapter ()->quoteInto ( 'entity_id=?', $object->getId () ) );
137
+
138
+ }
139
+
140
+ public function applyFilterToCollection($collection, $attribute, $value) {
141
+
142
+ $valuesGroup = "";
143
+
144
+ foreach ( $attribute->getFrontend ()->getSelectOptions () as $infogroup ) {
145
+ if ($infogroup ['value'] == $value) {
146
+ $valuesGroup = $infogroup ['values_group'];
147
+ break;
148
+ }
149
+ }
150
+
151
+ $conditions = explode ( ",", $valuesGroup );
152
+
153
+ $alias = 'attr_index_' . $attribute->getId ();
154
+ $collection->getSelect ()->join ( array (
155
+ $alias => $this->getMainTable () ), $alias . '.entity_id=e.entity_id', array () )->where ( $alias . '.store_id = ?', $this->getStoreId () )->where ( $alias . '.attribute_id = ?', $attribute->getId () )->where ( $alias . '.value in (?)', $conditions );
156
+
157
+ return $this;
158
+ }
159
+
160
+ }
app/code/community/Ayaline/RangeFilters/Model/Mysql4/CatalogIndex/Range.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Model_Mysql4_CatalogIndex_Range extends Mage_CatalogIndex_Model_Mysql4_Attribute
17
+ {
18
+
19
+ public function getCount($attribute, $entitySelect)
20
+ {
21
+
22
+ $case = "";
23
+ foreach ($attribute->getFrontend()->getSelectOptions() as $range) {
24
+ if ($range['value']) {
25
+ $min = $range['value_min'] ? $range['value_min'] : 0;
26
+ $max = $range['value_max'] ? $range['value_max'] : null;
27
+ if ($max) {
28
+ $case .= "WHEN index.value >= $min AND index.value < $max THEN {$range['value']} ";
29
+ } else {
30
+ $case .= "WHEN index.value >= $min THEN {$range['value']} ";
31
+ }
32
+ }
33
+ }
34
+
35
+ $novalues = false;
36
+ if (empty($case)) {
37
+ $novalues = true;
38
+ $case = "-1";
39
+ } else {
40
+ $case = "CASE $case END";
41
+ }
42
+
43
+ $_range = new Zend_Db_Expr($case);
44
+
45
+ $select = clone $entitySelect;
46
+ $select->reset(Zend_Db_Select::COLUMNS);
47
+ $select->reset(Zend_Db_Select::ORDER);
48
+
49
+ $fields = array('count'=>'COUNT(DISTINCT index.entity_id)', '_range' => $_range);
50
+
51
+ $select->from('', $fields)
52
+ ->join(array('index'=>$this->getMainTable()."_decimal"), 'index.entity_id=e.entity_id', array())
53
+ ->where('index.store_id = ?', $this->getStoreId())
54
+ ->where('index.attribute_id = ?', $attribute->getId())
55
+ ->group(array('_range'));
56
+
57
+ if ($novalues) {
58
+ $select->where('1=0');
59
+ }
60
+
61
+ $select = $select->__toString();
62
+
63
+ $alias = $this->_getReadAdapter()->quoteTableAs($this->getMainTable(), 'index');
64
+
65
+ $result = $this->_getReadAdapter()->fetchAll($select);
66
+
67
+ $counts = array();
68
+ foreach ($result as $row) {
69
+ $counts[$row['_range']] = $row['count'];
70
+ }
71
+ return $counts;
72
+ }
73
+
74
+ public function applyFilterToCollection($collection, $attribute, $value)
75
+ {
76
+
77
+ $min = 0;
78
+ $max = 0;
79
+
80
+ foreach ($attribute->getFrontend()->getSelectOptions() as $range) {
81
+ if ($range['value']==$value) {
82
+ $min = $range['value_min'] ? $range['value_min'] : 0;
83
+ $max = $range['value_max'];
84
+ break;
85
+ }
86
+ }
87
+
88
+ $alias = 'attr_index_'.$attribute->getId();
89
+ $collection->getSelect()->join(
90
+ array($alias => $this->getMainTable()."_decimal"),
91
+ $alias.'.entity_id=e.entity_id',
92
+ array()
93
+ )
94
+ ->where($alias.'.store_id = ?', $this->getStoreId())
95
+ ->where($alias.'.attribute_id = ?', $attribute->getId())
96
+ ->where($alias.'.value >= ?', $min)
97
+ ->where($alias.'.value < ?', $max);
98
+
99
+ return $this;
100
+ }
101
+
102
+ }
app/code/community/Ayaline/RangeFilters/Model/Observer.php ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 03/30/09
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_RangeFilters
7
+ * @author lbourrel
8
+ * @copyright Ayaline - 2011 - http://www.ayaline.com
9
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_RangeFilters
15
+ */
16
+ class Ayaline_RangeFilters_Model_Observer {
17
+
18
+ public function processAfterSaveEvent(Varien_Event_Observer $observer) {
19
+ // indexation des champs
20
+ $eventProduct = $observer->getEvent ()->getProduct ();
21
+ $indexer = Mage::getSingleton("ayalinerangefilters/catalogIndex_infogroup");
22
+ $indexer->reindex($eventProduct);
23
+ }
24
+
25
+ /**
26
+ * Add new attribute types to manage attributes interface
27
+ *
28
+ * event : adminhtml_product_attribute_types
29
+ *
30
+ * @param Varien_Event_Observer $observer
31
+ */
32
+ public function addAttributeTypes(Varien_Event_Observer $observer) {
33
+ $response = $observer->getEvent()->getResponse();
34
+ $types = $response->getTypes();
35
+ $types[] = array(
36
+ 'value' => 'range',
37
+ 'label' => Mage::helper ( 'ayalinerangefilters' )->__ ( 'Values ranges (numeric)' ),
38
+ 'hide_fields' => array(),
39
+ 'disabled_types' => array(
40
+ 'grouped',
41
+ )
42
+ );
43
+ $types[] = array(
44
+ 'value' => 'infogroup',
45
+ 'label' => Mage::helper ( 'ayalinerangefilters' )->__ ( 'Values group (text)' ),
46
+ 'hide_fields' => array(),
47
+ 'disabled_types' => array(
48
+ 'grouped',
49
+ )
50
+ );
51
+
52
+ $response->setTypes($types);
53
+ }
54
+
55
+ /**
56
+ * Change messages displayed for is_filterable element
57
+ *
58
+ * event : adminhtml_catalog_product_attribute_edit_prepare_form
59
+ *
60
+ * @param Varien_Event_Observer $observer
61
+ */
62
+ public function prepareAttributeEditForm(Varien_Event_Observer $observer) {
63
+ $form = $observer->getEvent()->getForm();
64
+
65
+ $field = $form->getElement ( 'is_filterable' );
66
+ $field->setTitle ( Mage::helper ( 'ayalinerangefilters' )->__ ( 'Can be used only with catalog input type Dropdown, Multiple Select, Price, Values group and Values ranges' ) );
67
+ $field->setNote ( Mage::helper ( 'ayalinerangefilters' )->__ ( 'Can be used only with catalog input type Dropdown, Multiple Select, Price, Values group and Values ranges' ) );
68
+ }
69
+
70
+ /**
71
+ * Init the backend type for range and infogroup attributes
72
+ *
73
+ * event : catalog_entity_attribute_save_before
74
+ *
75
+ * @param Varien_Event_Observer $observer
76
+ */
77
+ public function initAttributeProperties(Varien_Event_Observer $observer) {
78
+ $attribute = $observer->getEvent()->getAttribute();
79
+
80
+ if($attribute->getData('frontend_input') == 'range') {
81
+ $attribute
82
+ ->setData('backend_type', 'decimal')
83
+ ->setData('frontend_model', 'ayalinerangefilters/catalog_product_attribute_frontend_range')
84
+ ->setData('source_model', 'ayalinerangefilters/catalog_product_attribute_source_range')
85
+ ;
86
+ } elseif($attribute->getData('frontend_input') == 'infogroup') {
87
+ $attribute
88
+ ->setData('backend_type', 'text')
89
+ ->setData('frontend_model', 'ayalinerangefilters/catalog_product_attribute_frontend_infogroup')
90
+ ->setData('source_model', 'ayalinerangefilters/catalog_product_attribute_source_infogroup')
91
+ ;
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Save options associated to range and infogroup attributes
97
+ *
98
+ * event : catalog_entity_attribute_save_after
99
+ *
100
+ * @param Varien_Event_Observer $observer
101
+ */
102
+ public function saveOptions(Varien_Event_Observer $observer) {
103
+ $attribute = $observer->getEvent()->getAttribute();
104
+
105
+ Mage::getResourceSingleton('ayalinerangefilters/catalog_entity_attribute')->ayalineSaveOptions($attribute);
106
+ }
107
+
108
+ /**
109
+ * Exclude ayaline attributes from standard form generation
110
+ *
111
+ * event : adminhtml_catalog_product_edit_element_types
112
+ *
113
+ * @param Varien_Event_Observer $observer
114
+ */
115
+ public function updateElementTypes(Varien_Event_Observer $observer) {
116
+ $response = $observer->getEvent()->getResponse();
117
+ $types = $response->getTypes();
118
+ $types['range'] = Mage::getConfig()->getBlockClassName('ayalinerangefilters/data_form_element_range');
119
+ $types['infogroup'] = Mage::getConfig()->getBlockClassName('ayalinerangefilters/data_form_element_infogroup');
120
+ $response->setTypes($types);
121
+ return $this;
122
+ }
123
+
124
+ }
app/code/community/Ayaline/RangeFilters/etc/config.xml ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Ayaline_RangeFilters>
5
+ <version>2.0.1</version>
6
+ </Ayaline_RangeFilters>
7
+ </modules>
8
+ <adminhtml>
9
+ <translate>
10
+ <modules>
11
+ <Ayaline_RangeFilters>
12
+ <files>
13
+ <default>Ayaline_RangeFilters.csv</default>
14
+ </files>
15
+ </Ayaline_RangeFilters>
16
+ </modules>
17
+ </translate>
18
+ <layout>
19
+ <updates>
20
+ <ayalinerangefilters>
21
+ <file>ayaline/range_filters.xml</file>
22
+ </ayalinerangefilters>
23
+ </updates>
24
+ </layout>
25
+ <events>
26
+ <adminhtml_product_attribute_types>
27
+ <observers>
28
+ <ayalinerangefilters_add_types>
29
+ <type>model</type>
30
+ <class>ayalinerangefilters/observer</class>
31
+ <method>addAttributeTypes</method>
32
+ </ayalinerangefilters_add_types>
33
+ </observers>
34
+ </adminhtml_product_attribute_types>
35
+ <adminhtml_catalog_product_attribute_edit_prepare_form>
36
+ <observers>
37
+ <ayalinerangefilters_prepare_attribute_edit_form>
38
+ <type>model</type>
39
+ <class>ayalinerangefilters/observer</class>
40
+ <method>prepareAttributeEditForm</method>
41
+ </ayalinerangefilters_prepare_attribute_edit_form>
42
+ </observers>
43
+ </adminhtml_catalog_product_attribute_edit_prepare_form>
44
+ <adminhtml_catalog_product_edit_element_types>
45
+ <observers>
46
+ <ayalinerangefilters_update_element_types>
47
+ <type>model</type>
48
+ <class>ayalinerangefilters/observer</class>
49
+ <method>updateElementTypes</method>
50
+ </ayalinerangefilters_update_element_types>
51
+ </observers>
52
+ </adminhtml_catalog_product_edit_element_types>
53
+ </events>
54
+ </adminhtml>
55
+ <global>
56
+ <models>
57
+ <ayalinerangefilters>
58
+ <class>Ayaline_RangeFilters_Model</class>
59
+ <resourceModel>ayalinerangefilters_mysql4</resourceModel>
60
+ </ayalinerangefilters>
61
+ <ayalinerangefilters_mysql4>
62
+ <class>Ayaline_RangeFilters_Model_Mysql4</class>
63
+ <entities>
64
+ <eav_attribute_range>
65
+ <table>ayaline_eav_attribute_range</table>
66
+ </eav_attribute_range>
67
+ <eav_attribute_range_value>
68
+ <table>ayaline_eav_attribute_range_value</table>
69
+ </eav_attribute_range_value>
70
+ <eav_attribute_infogroup>
71
+ <table>ayaline_eav_attribute_infogroup</table>
72
+ </eav_attribute_infogroup>
73
+ <eav_attribute_infogroup_value>
74
+ <table>ayaline_eav_attribute_infogroup_value</table>
75
+ </eav_attribute_infogroup_value>
76
+ <catalogindex_infogroup>
77
+ <table>ayaline_catalogindex_infogroup</table>
78
+ </catalogindex_infogroup>
79
+ </entities>
80
+ </ayalinerangefilters_mysql4>
81
+ </models>
82
+ <resources>
83
+ <ayalinerangefilters_setup>
84
+ <setup>
85
+ <module>Ayaline_RangeFilters</module>
86
+ </setup>
87
+ <connection>
88
+ <use>core_setup</use>
89
+ </connection>
90
+ </ayalinerangefilters_setup>
91
+ <ayalinerangefilters_write>
92
+ <connection>
93
+ <use>core_write</use>
94
+ </connection>
95
+ </ayalinerangefilters_write>
96
+ <ayalinerangefilters_read>
97
+ <connection>
98
+ <use>core_read</use>
99
+ </connection>
100
+ </ayalinerangefilters_read>
101
+ </resources>
102
+ <blocks>
103
+ <ayalinerangefilters>
104
+ <class>Ayaline_RangeFilters_Block</class>
105
+ </ayalinerangefilters>
106
+ <catalog>
107
+ <rewrite>
108
+ <layer_view>Ayaline_RangeFilters_Block_Catalog_Layer_View</layer_view>
109
+ </rewrite>
110
+ </catalog>
111
+ </blocks>
112
+ <helpers>
113
+ <ayalinerangefilters>
114
+ <class>Ayaline_RangeFilters_Helper</class>
115
+ </ayalinerangefilters>
116
+ </helpers>
117
+ <events>
118
+ <catalog_entity_attribute_save_before>
119
+ <observers>
120
+ <ayalinerangefilters_init_attribute_properties>
121
+ <type>model</type>
122
+ <class>ayalinerangefilters/observer</class>
123
+ <method>initAttributeProperties</method>
124
+ </ayalinerangefilters_init_attribute_properties>
125
+ </observers>
126
+ </catalog_entity_attribute_save_before>
127
+ <catalog_entity_attribute_save_after>
128
+ <observers>
129
+ <ayalinerangefilters_save_options>
130
+ <type>model</type>
131
+ <class>ayalinerangefilters/observer</class>
132
+ <method>saveOptions</method>
133
+ </ayalinerangefilters_save_options>
134
+ </observers>
135
+ </catalog_entity_attribute_save_after>
136
+ <catalog_product_save_after>
137
+ <observers>
138
+ <catalogindex_infogroup>
139
+ <type>singleton</type>
140
+ <class>ayalinerangefilters/observer</class>
141
+ <method>processAfterSaveEvent</method>
142
+ </catalogindex_infogroup>
143
+ </observers>
144
+ </catalog_product_save_after>
145
+ </events>
146
+ </global>
147
+ <default>
148
+ <general>
149
+ <validator_data>
150
+ <input_types>
151
+ <range>range</range>
152
+ <infogroup>infogroup</infogroup>
153
+ </input_types>
154
+ </validator_data>
155
+ </general>
156
+ </default>
157
+ </config>
app/code/community/Ayaline/RangeFilters/sql/ayalinerangefilters_setup/mysql4-install-1.0.0.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+
5
+ $installer->startSetup();
6
+
7
+ $installer->run("
8
+
9
+ DROP TABLE IF EXISTS {$this->getTable('ayaline_eav_attribute_range')};
10
+ CREATE TABLE {$this->getTable('ayaline_eav_attribute_range')} (
11
+ range_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT
12
+ , attribute_id SMALLINT(5) UNSIGNED NOT NULL
13
+ , sort_order SMALLINT(5) UNSIGNED NOT NULL
14
+ , value_min NUMERIC(10, 2) DEFAULT 0
15
+ , value_max NUMERIC(10, 2)
16
+ , PRIMARY KEY (range_id)
17
+ , INDEX (attribute_id)
18
+ , CONSTRAINT FK_ayaline_eav_attribute_range_1 FOREIGN KEY (attribute_id)
19
+ REFERENCES {$this->getTable('eav_attribute')} (attribute_id)
20
+ ON DELETE CASCADE
21
+ ON UPDATE CASCADE
22
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
23
+
24
+ DROP TABLE IF EXISTS {$this->getTable('ayaline_eav_attribute_range_value')};
25
+ CREATE TABLE {$this->getTable('ayaline_eav_attribute_range_value')} (
26
+ value_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT
27
+ , range_id INT(10) UNSIGNED NOT NULL
28
+ , store_id SMALLINT(5) UNSIGNED NOT NULL
29
+ , value VARCHAR(255)
30
+ , PRIMARY KEY (value_id)
31
+ , INDEX (range_id)
32
+ , CONSTRAINT FK_ayaline_eav_attribute_range_value_1 FOREIGN KEY (range_id)
33
+ REFERENCES {$this->getTable('ayaline_eav_attribute_range')} (range_id)
34
+ ON DELETE CASCADE
35
+ ON UPDATE CASCADE
36
+ , INDEX (store_id)
37
+ , CONSTRAINT FK_ayaline_eav_attribute_range_value_2 FOREIGN KEY (store_id)
38
+ REFERENCES {$this->getTable('core_store')} (store_id)
39
+ ON DELETE CASCADE
40
+ ON UPDATE CASCADE
41
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
42
+
43
+ CREATE TABLE {$this->getTable('ayaline_eav_attribute_infogroup')} (
44
+ infogroup_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT
45
+ , attribute_id SMALLINT(5) UNSIGNED NOT NULL
46
+ , sort_order SMALLINT(5) UNSIGNED NOT NULL
47
+ , values_group VARCHAR(255)
48
+ , PRIMARY KEY (infogroup_id)
49
+ , INDEX (attribute_id)
50
+ , CONSTRAINT FK_ayaline_eav_attribute_infogroup_1 FOREIGN KEY (attribute_id)
51
+ REFERENCES {$this->getTable('eav_attribute')} (attribute_id)
52
+ ON DELETE CASCADE
53
+ ON UPDATE CASCADE
54
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
55
+
56
+ CREATE TABLE {$this->getTable('')}ayaline_eav_attribute_infogroup_value (
57
+ value_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT
58
+ , infogroup_id INT(10) UNSIGNED NOT NULL
59
+ , store_id SMALLINT(5) UNSIGNED NOT NULL
60
+ , value VARCHAR(255)
61
+ , PRIMARY KEY (value_id)
62
+ , INDEX (infogroup_id)
63
+ , CONSTRAINT FK_ayaline_eav_attribute_infogroup_value_1 FOREIGN KEY (infogroup_id)
64
+ REFERENCES {$this->getTable('ayaline_eav_attribute_infogroup')} (infogroup_id)
65
+ ON DELETE CASCADE
66
+ ON UPDATE CASCADE
67
+ , INDEX (store_id)
68
+ , CONSTRAINT FK_ayaline_eav_attribute_infogroup_value_2 FOREIGN KEY (store_id)
69
+ REFERENCES {$this->getTable('core_store')} (store_id)
70
+ ON DELETE CASCADE
71
+ ON UPDATE CASCADE
72
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
73
+
74
+ CREATE TABLE {$this->getTable('ayaline_catalogindex_infogroup')} (
75
+ store_id SMALLINT(5) UNSIGNED NOT NULL
76
+ , entity_id INT(10) UNSIGNED NOT NULL
77
+ , attribute_id SMALLINT(5) UNSIGNED NOT NULL
78
+ , value VARCHAR(250) NOT NULL
79
+ , PRIMARY KEY (value, store_id, entity_id, attribute_id)
80
+ , INDEX (store_id)
81
+ , CONSTRAINT FK_ayaline_catalogindex_infogroup_1 FOREIGN KEY (store_id)
82
+ REFERENCES {$this->getTable('core_store')} (store_id)
83
+ ON DELETE CASCADE
84
+ ON UPDATE RESTRICT
85
+ , INDEX (entity_id)
86
+ , CONSTRAINT FK_ayaline_catalogindex_infogroup_2 FOREIGN KEY (entity_id)
87
+ REFERENCES {$this->getTable('catalog_product_entity')} (entity_id)
88
+ ON DELETE CASCADE
89
+ ON UPDATE RESTRICT
90
+ , INDEX (attribute_id)
91
+ , CONSTRAINT FK_ayaline_catalogindex_infogroup_3 FOREIGN KEY (attribute_id)
92
+ REFERENCES {$this->getTable('eav_attribute')} (attribute_id)
93
+ ON DELETE CASCADE
94
+ ON UPDATE RESTRICT
95
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
96
+
97
+ ");
98
+
99
+ $installer->endSetup();
app/design/adminhtml/default/default/layout/ayaline/range_filters.xml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ created : 03/03/11
4
+ @category Ayaline
5
+ @package Ayaline_RangeFilters
6
+ @author sgautier
7
+ @copyright Ayaline - 2011 - http://www.ayaline.com
8
+ -->
9
+
10
+ <layout>
11
+
12
+ <adminhtml_catalog_product_attribute_edit>
13
+ <reference name="left">
14
+ <remove name="attribute_edit_tabs" />
15
+
16
+ <block type="ayalinerangefilters/adminhtml_catalog_product_attribute_edit_tabs" name="ayaline_attribute_edit_tabs">
17
+ <block type="ayalinerangefilters/adminhtml_catalog_product_attribute_edit_tab_options" name="ayaline_attributes_tab_options" template="ayaline/range_filters/catalog/product/attribute/options.phtml">
18
+ <block type="ayalinerangefilters/adminhtml_catalog_product_attribute_edit_tab_options" name="attributes_tab_options_original" as="original" />
19
+ <action method="setAfter">
20
+ <tab_id>main</tab_id>
21
+ </action>
22
+ </block>
23
+ <action method="addTab">
24
+ <tab_id>ayaline_labels</tab_id>
25
+ <tab>ayaline_attributes_tab_options</tab>
26
+ </action>
27
+ </block>
28
+ </reference>
29
+
30
+ <reference name="js">
31
+ <block type="adminhtml/template" name="ayaline.range_filters.attribute_edit_js" template="ayaline/range_filters/catalog/product/attribute/js.phtml"></block>
32
+ </reference>
33
+ </adminhtml_catalog_product_attribute_edit>
34
+
35
+ </layout>
app/design/adminhtml/default/default/template/ayaline/range_filters/catalog/product/attribute/js.phtml ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/javascript">
2
+ // Specific panel management
3
+ function ayalineRangeFilters_checkOptionsPanelVisibility(){
4
+ var input = $('frontend_input');
5
+
6
+ if(!input) {
7
+ return;
8
+ }
9
+
10
+ // Hide all options tabs
11
+ $('matage-options-panel').hide();
12
+ $('matage-range-panel').hide();
13
+ $('matage-infogroup-panel').hide();
14
+
15
+ if(input.value == 'range') {
16
+ $('matage-range-panel').show();
17
+ } else if(input.value == 'infogroup') {
18
+ $('matage-infogroup-panel').show();
19
+ } else { //input.value != 'range' && input.value != 'infogroup'
20
+ // Use the default display
21
+ checkOptionsPanelVisibility();
22
+ return;
23
+ }
24
+
25
+ // Allows is_filterable selection
26
+ if($('is_filterable')){
27
+ $('is_filterable').disabled = false;
28
+ }
29
+ }
30
+
31
+ if($('frontend_input')){
32
+ Event.observe($('frontend_input'), 'change', ayalineRangeFilters_checkOptionsPanelVisibility);
33
+ }
34
+
35
+ ayalineRangeFilters_checkOptionsPanelVisibility();
36
+ </script>
app/design/adminhtml/default/default/template/ayaline/range_filters/catalog/product/attribute/options.phtml ADDED
@@ -0,0 +1,279 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php echo $this->getChildHtml('original') ?>
2
+
3
+ <div class="entity-edit" id="matage-range-panel">
4
+ <div class="entry-edit-head">
5
+ <h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('catalog')->__('Manage Options (values of your attribute)') ?></h4>
6
+ </div>
7
+ <div class="box">
8
+ <div class="hor-scroll">
9
+ <table class="dynamic-grid" cellspacing="0" cellpadding="0">
10
+ <tr id="attribute-range-table">
11
+ <?php foreach ($this->getStores() as $_store): ?>
12
+ <th><?php echo $_store->getName() ?></th>
13
+ <?php endforeach; ?>
14
+ <th><?php echo Mage::helper('ayalinerangefilters')->__('Min Value') ?></th>
15
+ <th><?php echo Mage::helper('ayalinerangefilters')->__('Max Value') ?></th>
16
+ <th><?php echo Mage::helper('catalog')->__('Position') ?></th>
17
+ <th><?php echo $this->getAddNewRangeButtonHtml() ?></th>
18
+ </tr>
19
+ <tr class="no-display template" id="row-template">
20
+ <?php foreach ($this->getStores() as $_store): ?>
21
+ <td><input name="range[value][{{id}}][<?php echo $_store->getId() ?>]" value="{{store<?php echo $_store->getId() ?>}}" class="input-text<?php if($_store->getId()==0): ?> required-option<?php endif; ?>" type="text" /></td>
22
+ <?php endforeach; ?>
23
+ <td><input name="range[value_min][{{id}}]" value="{{store<?php echo $_store->getId() ?>}}" class="input-text validate-number" type="text" /></td>
24
+ <td><input name="range[value_max][{{id}}]" value="{{store<?php echo $_store->getId() ?>}}" class="input-text required-option validate-number" type="text" /></td>
25
+ <td class="a-center"><input class="input-text validate-number" type="text" name="range[order][{{id}}]" value="{{sort_range}}" /></td>
26
+ <td class="a-left">
27
+ <input type="hidden" class="delete-flag" name="range[delete][{{id}}]" value="" />
28
+ <?php echo $this->getDeleteRangeButtonHtml() ?>
29
+ </td>
30
+ </tr>
31
+ </table>
32
+ </div>
33
+ <input type="hidden" id="range-count-check" value=""/>
34
+ </div>
35
+ </div>
36
+ <br/>
37
+
38
+ <script type="text/javascript">
39
+
40
+ // IE removes quotes from element.innerHTML whenever it thinks they're not needed, which breaks html.
41
+ var templateRangeText =
42
+ '<tr class="option-row">'+
43
+ <?php foreach ($this->getStores() as $_store): ?>
44
+ '<td><input name="range[value][{{id}}][<?php echo $_store->getId() ?>]" value="{{store<?php echo $_store->getId() ?>}}" class="input-text<?php if($_store->getId()==0): ?> required-option<?php endif; ?>" type="text"/><\/td>'+
45
+ <?php endforeach; ?>
46
+ '<td><input name="range[value_min][{{id}}]" value="{{value_min}}" class="input-text validate-number" type="text"/><\/td>'+
47
+ '<td><input name="range[value_max][{{id}}]" value="{{value_max}}" class="input-text required-option validate-number" type="text"/><\/td>'+
48
+ '<td><input class="input-text validate-number" type="text" name="range[order][{{id}}]" value="{{sort_order}}"><\/td>'+
49
+ '<td class="a-left">'+
50
+ '<input type="hidden" class="delete-flag" name="range[delete][{{id}}]" value="">'+
51
+ '<?php echo $this->getDeleteRangeButtonHtml() ?>'+
52
+ '<\/td>'+
53
+ '<\/tr>';
54
+
55
+ var attributeRange = {
56
+ table : $('attribute-range-table'),
57
+ templateSyntax : /(^|.|\r|\n)({{(\w+)}})/,
58
+ templateText : templateRangeText,
59
+ itemCount : 0,
60
+ totalItems : 0,
61
+ add : function(data) {
62
+ this.template = new Template(this.templateText, this.templateSyntax);
63
+ if(!data.id){
64
+ data = {};
65
+ data.id = 'range_'+this.itemCount;
66
+ }
67
+ if (!data.intype)
68
+ data.intype = optionDefaultInputType;
69
+
70
+ new Insertion.After(
71
+ this.table,
72
+ this.template.evaluate(data)
73
+ );
74
+ this.bindRemoveButtons();
75
+ this.itemCount++;
76
+ this.totalItems++;
77
+ this.updateItemsCountField();
78
+ },
79
+ remove : function(event){
80
+ var element = $(Event.findElement(event, 'tr')); // !!! Button already
81
+ // have table parent in safari
82
+ // Safari workaround
83
+ element.ancestors().each(function(parentItem){
84
+ if (parentItem.hasClassName('option-row')) {
85
+ element = parentItem;
86
+ throw $break;
87
+ } else if (parentItem.hasClassName('box')) {
88
+ throw $break;
89
+ }
90
+ });
91
+
92
+
93
+ if(element){
94
+ var elementFlags = element.getElementsByClassName('delete-flag');
95
+ if(elementFlags[0]){
96
+ elementFlags[0].value=1;
97
+ }
98
+
99
+ element.addClassName('no-display');
100
+ element.addClassName('template');
101
+ element.hide();
102
+ this.totalItems--;
103
+ this.updateItemsCountField();
104
+ }
105
+ },
106
+ updateItemsCountField: function() {
107
+ if (this.totalItems > 0) {
108
+ $('range-count-check').value = '1';
109
+ } else {
110
+ $('range-count-check').value = '';
111
+ }
112
+ },
113
+ bindRemoveButtons : function(){
114
+ var buttons = $$('.delete-range');
115
+ for(var i=0;i<buttons.length;i++){
116
+ if(!$(buttons[i]).binded){
117
+ $(buttons[i]).binded = true;
118
+ Event.observe(buttons[i], 'click', this.remove.bind(this));
119
+ }
120
+ }
121
+ }
122
+
123
+ }
124
+ if($('row-template')){
125
+ $('row-template').remove();
126
+ }
127
+ attributeRange.bindRemoveButtons();
128
+
129
+ if($('add_new_range_button')){
130
+ Event.observe('add_new_range_button', 'click', attributeRange.add.bind(attributeRange));
131
+ }
132
+
133
+ <?php foreach ($this->getRangeValues() as $_value): ?>
134
+ attributeRange.add(<?php echo $_value->toJson() ?>);
135
+ <?php endforeach; ?>
136
+ </script>
137
+
138
+
139
+
140
+ <div class="entity-edit" id="matage-infogroup-panel">
141
+ <div class="entry-edit-head">
142
+ <h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('catalog')->__('Manage Options (values of your attribute)') ?></h4>
143
+ </div>
144
+ <div class="box">
145
+ <div class="hor-scroll">
146
+ <table class="dynamic-grid" cellspacing="0" cellpadding="0">
147
+ <tr id="attribute-infogroup-table">
148
+ <?php foreach ($this->getStores() as $_store): ?>
149
+ <th><?php echo $_store->getName() ?></th>
150
+ <?php endforeach; ?>
151
+ <th><?php echo Mage::helper('ayalinerangefilters')->__('Values (with coma separator)') ?></th>
152
+ <th><?php echo Mage::helper('catalog')->__('Position') ?></th>
153
+ <th><?php echo $this->getAddNewInfogroupButtonHtml() ?></th>
154
+ </tr>
155
+ <tr class="no-display template" id="row-template">
156
+ <?php foreach ($this->getStores() as $_store): ?>
157
+ <td><input name="infogroup[value][{{id}}][<?php echo $_store->getId() ?>]" value="{{store<?php echo $_store->getId() ?>}}" class="input-text<?php if($_store->getId()==0): ?> required-option<?php endif; ?>" type="text" /></td>
158
+ <?php endforeach; ?>
159
+ <td><input name="infogroup[values_group][{{id}}]" value="{{store<?php echo $_store->getId() ?>}}" class="input-text required-option" type="text" /></td>
160
+ <td class="a-center"><input class="input-text validate-number" type="text" name="infogroup[order][{{id}}]" value="{{sort_order}}" /></td>
161
+ <td class="a-left">
162
+ <input type="hidden" class="delete-flag" name="infogroup[delete][{{id}}]" value="" />
163
+ <?php echo $this->getDeleteInfogroupButtonHtml() ?>
164
+ </td>
165
+ </tr>
166
+ </table>
167
+ </div>
168
+ <input type="hidden" id="infogroup-count-check" value=""/>
169
+ </div>
170
+ </div>
171
+ <br/>
172
+
173
+ <script type="text/javascript">
174
+
175
+ // IE removes quotes from element.innerHTML whenever it thinks they're not needed, which breaks html.
176
+ var templateInfogroupText =
177
+ '<tr class="option-row">'+
178
+ <?php foreach ($this->getStores() as $_store): ?>
179
+ '<td><input name="infogroup[value][{{id}}][<?php echo $_store->getId() ?>]" value="{{store<?php echo $_store->getId() ?>}}" class="input-text<?php if($_store->getId()==0): ?> required-option<?php endif; ?>" type="text"/><\/td>'+
180
+ <?php endforeach; ?>
181
+ '<td><input name="infogroup[values_group][{{id}}]" value="{{values_group}}" class="input-text required-option" type="text"/><\/td>'+
182
+ '<td><input class="input-text validate-number" type="text" name="infogroup[order][{{id}}]" value="{{sort_order}}"><\/td>'+
183
+ '<td class="a-left">'+
184
+ '<input type="hidden" class="delete-flag" name="infogroup[delete][{{id}}]" value="">'+
185
+ '<?php echo $this->getDeleteInfogroupButtonHtml() ?>'+
186
+ '<\/td>'+
187
+ '<\/tr>';
188
+
189
+ var attributeInfogroup = {
190
+ table : $('attribute-infogroup-table'),
191
+ templateSyntax : /(^|.|\r|\n)({{(\w+)}})/,
192
+ templateText : templateInfogroupText,
193
+ itemCount : 0,
194
+ totalItems : 0,
195
+ add : function(data) {
196
+ this.template = new Template(this.templateText, this.templateSyntax);
197
+ if(!data.id){
198
+ data = {};
199
+ data.id = 'range_'+this.itemCount;
200
+ }
201
+ if (!data.intype)
202
+ data.intype = optionDefaultInputType;
203
+
204
+ new Insertion.After(
205
+ this.table,
206
+ this.template.evaluate(data)
207
+ );
208
+ this.bindRemoveButtons();
209
+ this.itemCount++;
210
+ this.totalItems++;
211
+ this.updateItemsCountField();
212
+ },
213
+ remove : function(event){
214
+ var element = $(Event.findElement(event, 'tr')); // !!! Button already
215
+ // have table parent in safari
216
+ // Safari workaround
217
+ element.ancestors().each(function(parentItem){
218
+ if (parentItem.hasClassName('option-row')) {
219
+ element = parentItem;
220
+ throw $break;
221
+ } else if (parentItem.hasClassName('box')) {
222
+ throw $break;
223
+ }
224
+ });
225
+
226
+
227
+ if(element){
228
+ var elementFlags = element.getElementsByClassName('delete-flag');
229
+ if(elementFlags[0]){
230
+ elementFlags[0].value=1;
231
+ }
232
+
233
+ element.addClassName('no-display');
234
+ element.addClassName('template');
235
+ element.hide();
236
+ this.totalItems--;
237
+ this.updateItemsCountField();
238
+ }
239
+ },
240
+ updateItemsCountField: function() {
241
+ if (this.totalItems > 0) {
242
+ $('infogroup-count-check').value = '1';
243
+ } else {
244
+ $('infogroup-count-check').value = '';
245
+ }
246
+ },
247
+ bindRemoveButtons : function(){
248
+ var buttons = $$('.delete-infogroup');
249
+ for(var i=0;i<buttons.length;i++){
250
+ if(!$(buttons[i]).binded){
251
+ $(buttons[i]).binded = true;
252
+ Event.observe(buttons[i], 'click', this.remove.bind(this));
253
+ }
254
+ }
255
+ }
256
+
257
+ }
258
+ if($('row-template')){
259
+ $('row-template').remove();
260
+ }
261
+ attributeInfogroup.bindRemoveButtons();
262
+
263
+ if($('add_new_infogroup_button')){
264
+ Event.observe('add_new_infogroup_button', 'click', attributeRange.add.bind(attributeInfogroup));
265
+ }
266
+
267
+ Validation.addAllThese([
268
+ ['required-option', '<?php echo Mage::helper('catalog')->__('Failed') ?>', function(v) {
269
+ return !Validation.get('IsEmpty').test(v);
270
+ }]]);
271
+ Validation.addAllThese([
272
+ ['required-options-count', '<?php echo Mage::helper('catalog')->__('Options is required') ?>', function(v) {
273
+ return !Validation.get('IsEmpty').test(v);
274
+ }]]);
275
+
276
+ <?php foreach ($this->getInfogroupValues() as $_value): ?>
277
+ attributeInfogroup.add(<?php echo $_value->toJson() ?>);
278
+ <?php endforeach; ?>
279
+ </script>
app/etc/modules/Ayaline_RangeFilters.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Ayaline_RangeFilters>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Ayaline_RangeFilters>
8
+ </modules>
9
+ </config>
app/locale/en_US/Ayaline_RangeFilters.csv ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ "Values group (text)","Values group (text)"
2
+ "Values ranges (numeric)","Values ranges (numeric)"
3
+ "Can be used only with catalog input type Dropdown, Multiple Select, Price, Values group and Values ranges","Can be used only with catalog input type Dropdown, Multiple Select, Price, Values group and Values ranges"
4
+ "Values (with coma separator)","Values (with coma separator)"
5
+ "Min Value","Min Value"
6
+ "Max Value","Max Value"
7
+ "Range","Range"
app/locale/fr_FR/Ayaline_RangeFilters.csv ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ "Values group (text)","Ensemble de valeurs (texte)"
2
+ "Values ranges (numeric)","Intervalles de valeurs (numérique)"
3
+ "Can be used only with catalog input type Dropdown, Multiple Select, Price, Values group and Values ranges","Ne peut être utilisé qu'avec un type de saisie 'liste déroulante', 'choix multiple', 'prix', 'Ensemble de valeurs' ou 'Intervalles de valeurs'"
4
+ "Values (with coma separator)","Valeurs (séparées par une virgule)"
5
+ "Min Value","Valeur min."
6
+ "Max Value","Valeur max."
7
+ "Range","Intervalle"
package.xml ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Ayaline_RangeFilters_v2</name>
4
+ <version>2.0.1</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Better user experience by enhancing layered navigation</summary>
10
+ <description>Ayaline Range Filters extension provides two new attribute types : "Values group" and "Values ranges".&#xD;
11
+ This extension is an enhancement of Sqli Range Filters and is compatible with Magento Community Edition 1.4 and 1.5.&#xD;
12
+ These attributes are intended for a more user friendly layered navigation.&#xD;
13
+ Values group : the layered navigation will display a group of values instead of all the different values.&#xD;
14
+ Values ranges : the layered navigation will display several ranges to search into.&#xD;
15
+ &#xD;
16
+ Plug and play module : no rewrite on core classes&#xD;
17
+ &#xD;
18
+ Use case :&#xD;
19
+ &#xD;
20
+ Values ranges : The customer can filter the results by weight using :&#xD;
21
+ - Light (matching weight between 0 and 5 kg)&#xD;
22
+ - Medium (between 5 and 10kg)&#xD;
23
+ - and Heavy (up to 10kg)&#xD;
24
+ Other example : washing machines with filter by spin speed (fast, very fast, ...).&#xD;
25
+ These attributes of a new type can be created from Magento backend.&#xD;
26
+ &#xD;
27
+ Values group : The customer can filter a list of shirts by kind of cloth (natural or synthetic) :&#xD;
28
+ - natural : includes silk, cotton, wool, etc. &#xD;
29
+ - synthetic : includes nylon, lycra, acrylic, etc.&#xD;
30
+ &#xD;
31
+ [Credits] Developed, tested</description>
32
+ <notes>Known issues :&#xD;
33
+ The attribute type "Values ranges" uses default index table of Magento. It means that only integers will be indexed.&#xD;
34
+ &#xD;
35
+ TODOs :&#xD;
36
+ Search Results Layered Navigation.</notes>
37
+ <authors><author><name>Simon Gautier</name><user>auto-converted</user><email>sgautier@ayaline.com</email></author><author><name>Laurent Bourrel</name><user>auto-converted</user><email>lbourrel@ayaline.com</email></author></authors>
38
+ <date>2011-05-04</date>
39
+ <time>09:50:37</time>
40
+ <contents><target name="magecommunity"><dir name="Ayaline"><dir name="RangeFilters"><dir name="Block"><dir name="Adminhtml"><dir name="Catalog"><dir name="Product"><dir name="Attribute"><dir name="Edit"><dir name="Tab"><file name="Options.php" hash="7658076da5e731de1634eef079565747"/></dir><file name="Tabs.php" hash="dcaf23f53c97124644dcf3fd681a8b28"/></dir></dir></dir></dir></dir><dir name="Catalog"><dir name="Layer"><dir name="Filter"><file name="Infogroup.php" hash="f0bee1238d1d82f4165ec0ac5146423d"/><file name="Range.php" hash="38526cc3f41138a2c63f5253e6b7c3c7"/></dir><file name="View.php" hash="621958de9f237e66ed056c151e467e0a"/></dir></dir><dir name="Data"><dir name="Form"><dir name="Element"><file name="Infogroup.php" hash="b3bc89d98c9607b998550b05806419fd"/><file name="Range.php" hash="b40277cbe690ba98efb876cc2b3a8db1"/></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="3587f7b5a062b03e49cf6fcbc32bcfb9"/></dir><dir name="Model"><dir name="Catalog"><dir name="Layer"><dir name="Filter"><file name="Infogroup.php" hash="89a83fc0afe53bd33abf0a0189491e0c"/><file name="Range.php" hash="5b96f8c92e126870f3707e7cafa02783"/></dir></dir><dir name="Product"><dir name="Attribute"><dir name="Frontend"><file name="Infogroup.php" hash="6bb494ccb35dcb8c61d540164e4e6f43"/><file name="Range.php" hash="6c009ee7746b222df4ece12cfacadb3b"/></dir><dir name="Source"><file name="Infogroup.php" hash="6087251a2a1ea8c3bb6d0429a58c3abe"/><file name="Range.php" hash="5518396e2a2fa62e967fc9e4b8ce46cf"/></dir><file name="Infogroup.php" hash="612690477047960b407df86c410a50d2"/><file name="Range.php" hash="7ee65a3ff825e30c81e04562e53e853e"/></dir></dir></dir><dir name="CatalogIndex"><file name="Infogroup.php" hash="6e9bb7240de1e6ee4c0b932fb674289f"/><file name="Range.php" hash="562a5510d2dbb757f3848ebe71972855"/></dir><dir name="Mysql4"><dir name="Catalog"><dir name="Entity"><file name="Attribute.php" hash="669d40d84264a7af5e8f785b33d59cf3"/></dir><dir name="Product"><dir name="Attribute"><dir name="Infogroup"><file name="Collection.php" hash="70a0bd4b44885e643620784dce0e2864"/></dir><dir name="Range"><file name="Collection.php" hash="b59f7195c342f0c8e6fdd3de945c6489"/></dir><file name="Infogroup.php" hash="b6d8c23233ccd10347d33dd48ae629d4"/><file name="Range.php" hash="345d39ccc5009b4be492164adc0be08e"/></dir></dir></dir><dir name="CatalogIndex"><file name="Infogroup.php" hash="64cee0fe4d25f55524c6fadadb09847d"/><file name="Range.php" hash="418fd41e85845931e95d64ec2a1553be"/></dir></dir><file name="Observer.php" hash="d1aee2e1c89b102799f655f052654a47"/></dir><dir name="etc"><file name="config.xml" hash="863bbf2a5184548b644dfb3ceb205deb"/></dir><dir name="sql"><dir name="ayalinerangefilters_setup"><file name="mysql4-install-1.0.0.php" hash="04794f9db0c668c1c9d8f78716e70a40"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><dir name="ayaline"><file name="range_filters.xml" hash="56bbf7417c10254a27cadb0ce0cc0a1d"/></dir></dir><dir name="template"><dir name="ayaline"><dir name="range_filters"><dir name="catalog"><dir name="product"><dir name="attribute"><file name="js.phtml" hash="6e24c2ccbe47e89d00e8868a99da7679"/><file name="options.phtml" hash="33fe805c2986422ed187f24865389987"/></dir></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Ayaline_RangeFilters.xml" hash="a7ccde7827e8ac2e4c0804daaadea1c4"/></dir></target><target name="magelocale"><dir name="en_US"><file name="Ayaline_RangeFilters.csv" hash="44c2aed24002ea575dc8f0109ca6f686"/></dir><dir name="fr_FR"><file name="Ayaline_RangeFilters.csv" hash="ff7ab7cbd1ca07fb6cce682efe5d1e71"/></dir></target></contents>
41
+ <compatible/>
42
+ <dependencies/>
43
+ </package>