Magento 2: Comment fonctionnent les données à facettes pour la navigation en couches?

10

J'ai créé un module pour un filtre personnalisé sur la page de catégorie, tout fonctionne correctement, sauf la fourchette de prix dans la navigation en couches.

S'il vous plaît, n'importe qui peut m'expliquer comment fonctionne getFacetedData ('prix') dans magento2

$productCollection->getFacetedData('price');

Cette fonction me donne des fourchettes de prix basées sur la collection de produits par défaut et non sur ma collection filtrée.

FYI: J'ai filtré la collection comme ci-dessous,

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

Réponses:

7

Le code ci-dessous s'applique à Magento 2.2.5.

Tout d'abord, dans la barre latérale, toutes les plages possibles pour tous les filtres possibles doivent être produites. De plus, vous aurez un aperçu du nombre de produits trouvés dans la gamme donnée.

entrez la description de l'image ici

Par exemple, je vais me concentrer sur l'utilisation d'un seul filtre: le prix.

Avant toute autre chose, pour qu'un attribut de produit donné soit éligible à la navigation en couches, il doit être correctement configuré.

Pour vérifier, naviguez dans l’administrateur vers Stores -> Attribute -> Product, puis sélectionnez l’attribut de prix et observez que dans l’ Storefront Propertiesonglet, il Use in Layered Navigationest défini surFilterable (with results)

Sur cette image, nous voyons que pour le filtre de prix, nous voyons la plage de 50.00-59.99contient des 10résultats, et pour 80+seulement 1.

Cette vue est produite à l'intérieur

/vendor/magento/theme-frontend-luma/Magento_LayeredNavigation/templates/layer/view.phtml

Il existe un code similaire à

<?php foreach ($block->getFilters() as $filter): ?>
    <?php if ($filter->getItemsCount()): ?>

Qui finit par s'empiler jusqu'à

private function prepareData($key, $count)

et ceci est une méthode de

vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php

Nous avons donc identifié la classe qui est responsable du filtrage des prix et nous voyons qu'elle a déjà été utilisée pour produire les gammes disponibles.


La pile la plus importante consiste à vérifier ce qui se passe lorsqu'une plage particulière est sélectionnée.

Par exemple, je clique sur la plage 40,00-49,99, qui devrait renvoyer 4 résultats.

Le premier est la méthode _prepareLayout()de

/vendor/magento/module-layered-navigation/Block/Navigation.php

Le code est

protected function _prepareLayout()
{
    foreach ($this->filterList->getFilters($this->_catalogLayer) as $filter) {
        $filter->apply($this->getRequest());
    }
    $this->getLayer()->apply();
    return parent::_prepareLayout();
}

Essentiellement, cela dit, obtenez-moi tous les filtres et chacun d'entre eux le fait apply.

Maintenant, le getFilters () seul, conduit finalement à la construction d'un objet à partir de

vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php

Une étape d'appel qui mène au __constructof Priceest

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;
}

Et voici le code de

vendor/module-catalog/Model/Layer/FilterList.php

Quoi qu'il en soit, si nous nous concentrons sur le $filter->apply($this->getRequest());code ci-dessus, cela signifie que ce code sera exécuté

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;
}

et encore une fois, ce code est de

vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php

Si je suis de près les valeurs des variables, encore une fois, étant donné que j'ai sélectionné la plage 40,00-49,99, alors le $filtertableau se compose de deux éléments: [0 => 40, 1 => 50]

Après l'exécution de cette ligne

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

De toute évidence, la $fromvariable est maintenant de 40 et la $tovariable est maintenant de 50.

La ligne suivante est cruciale

    $this->getLayer()->getProductCollection()->addFieldToFilter(
        'price',
        ['from' => $from, 'to' =>  empty($to) || $from == $to ? $to : $to - self::PRICE_DELTA]
    );

C'est là que la collection déjà présente associée au calque est encore réduite en appelant le addFieldToFilter().

C'est peut-être là que l'attention doit être portée afin de détecter les bogues, le cas échéant.

Finalement, le programme appelle getLoadedProductCollection () de

vendor/magento/module-catalog/Block/Product/ListProduct.php

qui en effet renvoie la collection protégée que cet objet encapsule.


Magento est une application complexe.

Dans celui-ci, un seul clic qui a sélectionné une seule gamme de prix, nous avons vu le code de trois modules différents interagir

  • module-catalogue
  • module-catalogue-recherche
  • navigation par couches de modules

Cela peut sembler écrasant à certains moments, mais il me semble qu'il existe une belle synergie entre ces modules.

Merci pour la lecture. J'espère que cela s'explique et que vous êtes maintenant équipé d'une meilleure compréhension de la navigation en couches.

Marjan
la source
+1 pour la réponse très détaillée et bien expliquée. Cependant, vous n'avez pas expliqué comment fonctionnent les données à facettes ... Les données à facettes sont utilisées pour générer des décomptes de filtres.
Yonn Trimoreau
salut @Marjan, dans mon cas, la catégorie de troisième niveau ne s'affiche pas dans le filtre, voici ma question, magento.stackexchange.com/questions/270442/…
jafar pinjar