O código abaixo se aplica ao Magento 2.2.5.
Primeiro, na barra lateral, todos os intervalos possíveis para todos os filtros possíveis precisam ser produzidos. Além disso, você terá uma visão geral da contagem de produtos encontrados dentro do intervalo especificado.
Por exemplo, vou me concentrar em usar um filtro: o preço.
Antes de mais nada, para que um determinado atributo do produto seja elegível para navegação em camadas, ele deve ser configurado corretamente.
Para verificar, navegue no administrador para Stores -> Attribute -> Product
, selecione o atributo price e observe que, na Storefront Properties
guia,
Use in Layered Navigation
está definido comoFilterable (with results)
Nesta foto, vemos que, para o filtro de preço, vemos o intervalo de 50.00-59.99
contém 10
resultados e 80+
apenas 1
.
Essa visão é produzida dentro
/vendor/magento/theme-frontend-luma/Magento_LayeredNavigation/templates/layer/view.phtml
Existe um código semelhante a
<?php foreach ($block->getFilters() as $filter): ?>
<?php if ($filter->getItemsCount()): ?>
Que eventualmente acumula até
private function prepareData($key, $count)
e este é um método de
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Assim, identificamos a classe responsável pela filtragem de preços e vemos que ela já foi usada para produzir os intervalos disponíveis.
A pilha mais importante é verificar o que acontece quando um intervalo específico é selecionado.
Por exemplo, clicarei no intervalo 40.00-49.99, que deve retornar 4 resultados.
Primeiro é o método _prepareLayout()
de
/vendor/magento/module-layered-navigation/Block/Navigation.php
O código é
protected function _prepareLayout()
{
foreach ($this->filterList->getFilters($this->_catalogLayer) as $filter) {
$filter->apply($this->getRequest());
}
$this->getLayer()->apply();
return parent::_prepareLayout();
}
Em essência, isso diz, me traga todos os filtros e cada um deles apply
.
Agora, somente o getFilters () leva à construção de um objeto a partir de
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Uma etapa de chamada que leva ao __construct
de Price
é
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;
}
E este é o código de
vendor/module-catalog/Model/Layer/FilterList.php
De qualquer forma, se focarmos o $filter->apply($this->getRequest());
código acima, isso significa que esse código será executado
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;
}
e novamente, esse código é de
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Se eu seguir de perto os valores das variáveis, novamente, considerando que selecionei o intervalo 40.00-49.99, o $filter
array consiste em dois elementos: [0 => 40, 1 => 50]
Depois que essa linha é executada
list($from, $to) = $filter;
Obviamente, a $from
variável agora é 40 e a $to
variável agora é 50.
A próxima linha é crucial
$this->getLayer()->getProductCollection()->addFieldToFilter(
'price',
['from' => $from, 'to' => empty($to) || $from == $to ? $to : $to - self::PRICE_DELTA]
);
É aqui que a coleção já presente associada à Camada é reduzida ainda mais chamando o addFieldToFilter()
.
Talvez seja aqui que a atenção deve ser colocada para detectar erros, se houver.
Eventualmente, o programa chama getLoadedProductCollection () de
vendor/magento/module-catalog/Block/Product/ListProduct.php
que efetivamente retorna a coleção protegida que esse objeto encapsula.
Magento é uma aplicação complexa.
Nesse único clique que selecionou uma única faixa de preços, vimos o código de três módulos diferentes interagindo
- catálogo de módulos
- pesquisa de catálogo de módulo
- navegação em camadas do módulo
Pode parecer esmagador em alguns momentos, mas me parece que há uma sinergia agradável entre esses módulos.
Obrigado pela leitura. Espero que isso explique e agora você está equipado com uma compreensão um pouco melhor da navegação em camadas.