TL;DR: How to filter multiple select/dropdown attributes (multi-selects would be cumbersome)? Or use a different method?
Consider a product select/dropdown attribute whose values correspond to each letter of the alphabet (English in this case). The first option's label is "A", its value is 1. "B" is 2, "C" is 3, and so on:
I have this attribute assigned to control layered navigation filters. So a user can click the link for a specific value, and it will add ?my_attribute=2
into the request parameters, and the product list shows only products whose attribute value is "B".
I would like to, instead, display any products who's attribute value is greater than or equal to the selected option. So in the case a user clicks the "B" link in layered nav, the results would be every product from "B-Z" (2-26).
The URL structure: ?my_attribute=2&my_attribute_3&my_attribute=4...
would be ugly and besides, it does not work, but the idea is there. ?my_attribute=2-26
would obviously be ideal, but again, this is not what Magento does.
Curiously, using advanced search provides this URL structure (through the advanced search controller instead of layered nav):
?my_attribute%5B%5D=7&my_attribute%5B%5D=8&my_attribute%5B%5D=9&my_attribute%5B%5D=10
This indeed does provide the desired results; however, this structure does not work with category/layered pages, only advanced search.
I am trying to decide which would be a better path at this point; Should I abandon all the built-in usefulness of layered navigation, and instead rewrite the product_list
block's loaded product collection based on my attribute value? Or should I adapt some functionality from advanced search results to fit my needs?
It seems like it would be best to leave layered navigation functionality alone so that other product filters continue to work as expected; but it does not seem it will allow multiple values from a single attribute be selected at the same time. Alternatively, a workaround would be to use a multi-select attribute, and if a product would be assigned "B", it would have to be assigned all options from "B-Z". While this would provide the greatest instant results (everything will work without more modifications), it is certainly a sloppy solution that will be error-prone and clunky to manage in the future.
Best Answer
What I did in this case was to rewrite both the model and the corresponding resource, so first rewrite the class
Mage_Catalog_Model_Layer_Filter_Attribute
to be able to accept multiple values. In my case, I am using commas as a separator, so I can filter like?my_attribute=1,2,3
In the method
apply()
I parse the attribute to put the different values in an array:Then in the file
Mage_Catalog_Model_Resource_Eav_Mysql4_Layer_Filter_Attribute
you have to make sure that you are able to filter for multiple values in your query, so I rewrote the following method like this: