Код нижче застосовується до Magento 2.2.5.
Спочатку на бічній панелі потрібно створити всі можливі діапазони для всіх можливих фільтрів. Крім того, до цього ви матимете огляд кількості продуктів, знайдених у межах даного асортименту.
Наприклад, я зупинюсь на використанні одного фільтра: ціна.
Перш за все, для того, щоб даний атрибут продукту мав право на багатошарову навігацію, його слід правильно налаштувати.
Щоб перевірити, перегляньте в адміністраторі до Stores -> Attribute -> Product
, а потім виберіть атрибут ціни та дотримуйтесь того, що на Storefront Properties
вкладці
Use in Layered Navigation
встановлено значенняFilterable (with results)
На цій фотографії ми бачимо, що для фільтра цін ми бачимо діапазон від 50.00-59.99
містить 10
результати, і 80+
лише для них 1
.
Цей погляд виробляється всередині
/vendor/magento/theme-frontend-luma/Magento_LayeredNavigation/templates/layer/view.phtml
Існує код, подібний до
<?php foreach ($block->getFilters() as $filter): ?>
<?php if ($filter->getItemsCount()): ?>
Що в підсумку складеться до
private function prepareData($key, $count)
і це метод від
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Отже, ми визначили клас, який відповідає за фільтрацію цін, і ми бачимо, що він вже використовувався для створення доступних діапазонів.
Більш важливий стек - це перевірити, що відбувається при виборі певного діапазону.
Наприклад, я натисну діапазон 40,00-49,99, який, як очікується, поверне 4 результати.
Спочатку - метод _prepareLayout()
від
/vendor/magento/module-layered-navigation/Block/Navigation.php
Код є
protected function _prepareLayout()
{
foreach ($this->filterList->getFilters($this->_catalogLayer) as $filter) {
$filter->apply($this->getRequest());
}
$this->getLayer()->apply();
return parent::_prepareLayout();
}
По суті, це говорить, заведіть мені всі фільтри і пророкуйте їх apply
.
Тепер само getFilters () призводить до побудови об'єкта з
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Зухвалий крок , який веде до __construct
з Price
IS
protected function createAttributeFilter(
\Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute,
\Magento\Catalog\Model\Layer $layer
) {
$filterClassName = $this->getAttributeFilterClass($attribute);
$filter = $this->objectManager->create(
$filterClassName,
['data' => ['attribute_model' => $attribute], 'layer' => $layer]
);
return $filter;
}
І це код від
vendor/module-catalog/Model/Layer/FilterList.php
У будь-якому випадку, якщо ми звернемося до $filter->apply($this->getRequest());
коду зверху, це означає, що цей код буде виконаний
public function apply(\Magento\Framework\App\RequestInterface $request)
{
/**
* Filter must be string: $fromPrice-$toPrice
*/
$filter = $request->getParam($this->getRequestVar());
if (!$filter || is_array($filter)) {
return $this;
}
$filterParams = explode(',', $filter);
$filter = $this->dataProvider->validateFilter($filterParams[0]);
if (!$filter) {
return $this;
}
$this->dataProvider->setInterval($filter);
$priorFilters = $this->dataProvider->getPriorFilters($filterParams);
if ($priorFilters) {
$this->dataProvider->setPriorIntervals($priorFilters);
}
list($from, $to) = $filter;
$this->getLayer()->getProductCollection()->addFieldToFilter(
'price',
['from' => $from, 'to' => empty($to) || $from == $to ? $to : $to - self::PRICE_DELTA]
);
$this->getLayer()->getState()->addFilter(
$this->_createItem($this->_renderRangeLabel(empty($from) ? 0 : $from, $to), $filter)
);
return $this;
}
і знову цей код від
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Якщо я уважно слідкую за змінними значеннями, знову ж таки, враховуючи, що я вибрав діапазон 40,00-49,99, то $filter
масив складається з двох елементів: [0 => 40, 1 => 50]
Після виконання цього рядка
list($from, $to) = $filter;
Очевидно, що $from
змінна зараз 40, а $to
змінна зараз 50.
Наступний рядок має вирішальне значення
$this->getLayer()->getProductCollection()->addFieldToFilter(
'price',
['from' => $from, 'to' => empty($to) || $from == $to ? $to : $to - self::PRICE_DELTA]
);
Тут вже зменшується вже наявна колекція, пов'язана з шаром, викликом addFieldToFilter()
.
Можливо, саме тут слід звернути увагу на виявлення помилок, якщо такі є.
Зрештою, програма викликає getLoadedProductCollection () з
vendor/magento/module-catalog/Block/Product/ListProduct.php
який у efect повертає захищену колекцію, яку цей об'єкт інкапсулює.
Magento - це складне застосування.
У цьому одному клацанні миші, який вибрав один єдиний діапазон цін, ми побачили код із трьох різних модулів, що взаємодіють
- модуль-каталог
- модуль-каталог-пошук
- модульно-багатошарова навігація
Можливо, це може здатися непосильним на моменти, але мені здається, приємна синергія між цими модулями.
Дякую за прочитане Я сподіваюся, що це пояснює, і ви зараз оснащені трохи кращим розумінням шаруватої навігації.