Magento 2: Como os dados facetados funcionam para a navegação em camadas?

10

Eu criei um módulo para filtro personalizado na página de categoria, tudo está funcionando bem, exceto a faixa de preço na navegação em camadas.

Por favor, qualquer um pode me explicar como o getFacetedData ('price') funciona no magento2

$productCollection->getFacetedData('price');

Essa função fornece faixas de preço com base na coleção de produtos padrão e não na minha coleção filtrada.

FYI: filtrei a coleção como abaixo,

$productCollection = $layer->getProductCollection()
->clear()
->addAttributeToSelect(['name','price'])
->addAttributeToFilter('sku', array('in' => ['sku1','sku2']));
Nalin Savaliya
fonte

Respostas:

7

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.

insira a descrição da imagem aqui

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 Propertiesguia, Use in Layered Navigationestá definido comoFilterable (with results)

Nesta foto, vemos que, para o filtro de preço, vemos o intervalo de 50.00-59.99contém 10resultados 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 __constructde 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 $filterarray consiste em dois elementos: [0 => 40, 1 => 50]

Depois que essa linha é executada

list($from, $to) = $filter;

Obviamente, a $fromvariável agora é 40 e a $tovariá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.

Marjan
fonte
+1 para a resposta muito detalhada e bem explicada. No entanto, você não explicou como os dados facetados funcionam ... Os dados facetados são usados ​​para gerar contagens de filtro.
Yonn Trimoreau
oi @Marjan, no meu caso a terceira categoria de nível não mostrando em filtro, aqui está a minha pergunta, magento.stackexchange.com/questions/270442/...
Jafar pinjar