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.
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 Properties
onglet, il
Use in Layered Navigation
est défini surFilterable (with results)
Sur cette image, nous voyons que pour le filtre de prix, nous voyons la plage de 50.00-59.99
contient des 10
ré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 __construct
of Price
est
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 $filter
tableau 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 $from
variable est maintenant de 40 et la $to
variable 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.