I have created module for custom filter on category page every thing is working fine except price range in layered navigation.
Please anybody can explain me how getFacetedData('price') works in magento2
$productCollection->getFacetedData('price');
This function gives me price ranges based on default product collection not based on my filtered collection.
FYI:
I have filtered collection as below,
$productCollection = $layer->getProductCollection()
->clear()
->addAttributeToSelect(['name','price'])
->addAttributeToFilter('sku', array('in' => ['sku1','sku2']));
Best Answer
The code below applies to Magento 2.2.5.
First off, in the sidebar, all possible ranges for all possible filters need to be produced. Additionally, to this, you will have the overview of the count of product found within the given range.
For example, I will be focusing on using one filter: the price.
Before anything else, in order for a given product attribute to be eligible for layered navigation, it should be properly configured.
To check, browse in the admin to
Stores -> Attribute -> Product
, then select the price attribute and observe that in theStorefront Properties
tab,Use in Layered Navigation
is set toFilterable (with results)
On this picture we see that for the price filter, we see the range from
50.00-59.99
contains10
results, and for80+
only1
.This view is produced inside
There is a code similar to
Which eventually stacks up to
and this is a method from
So, we have identified the class that is responsible for the price filtering, and we see it was already used to produce the available ranges.
The more important stack is to check what happens when a particular range is selected.
For example, I will click on the 40.00-49.99 range, which is expected to return 4 results.
First up is method
_prepareLayout()
fromThe code is
In essence, this says, get me all filters and foreach of them do
apply
.Now, the getFilters() alone, eventually leads to constructing an object from
A calling step that leads to the
__construct
ofPrice
isAnd this is code from
Anyways, if we focus back to the
$filter->apply($this->getRequest());
code from above, this means that this code will get executedand again, this code is from
If I closely follow variable values, again, given that I have selected the 40.00-49.99 range, then
$filter
is array consiting of two elements: [0 => 40, 1 => 50 ]After this line is executed
Obviously, the
$from
variable is now 40, and the$to
variable is now 50.The next line is crucial
This is where the already present collection associated with the Layer, gets further reduced by calling the
addFieldToFilter()
.Perhaps, this is where the attention should be placed in order to detect bugs, if any.
Eventually, the program calls getLoadedProductCollection() from
which in efect returns the protected collection that this object encapsulates.
Magento is a complex application.
In this ones single click that selected one single range of prices, we saw code from three different modules interacting
It may feel overwhelming at moments, but it seems to me, there is a nice synergy between this modules.
Thank you for reading. I hope this does explain and you are now equipped with slightly better understanding of the layered navigation.