Der folgende Code gilt für Magento 2.2.5.
Zunächst müssen in der Seitenleiste alle möglichen Bereiche für alle möglichen Filter erstellt werden. Darüber hinaus erhalten Sie einen Überblick über die Anzahl der Produkte innerhalb des angegebenen Bereichs.
Zum Beispiel werde ich mich auf die Verwendung eines Filters konzentrieren: den Preis.
Damit ein bestimmtes Produktattribut für die mehrschichtige Navigation in Frage kommt, sollte es vor allem ordnungsgemäß konfiguriert sein.
Um dies zu überprüfen, navigieren Sie im Administrator zu Stores -> Attribute -> Product
, wählen Sie dann das Preisattribut aus und beobachten Sie, dass es auf der Storefront Properties
Registerkarte auf
Use in Layered Navigation
gesetzt istFilterable (with results)
Auf diesem Bild sehen wir, dass für den Preisfilter der Bereich von 50.00-59.99
enthält 10
Ergebnisse und 80+
nur für 1
.
Diese Ansicht wird im Inneren erzeugt
/vendor/magento/theme-frontend-luma/Magento_LayeredNavigation/templates/layer/view.phtml
Es gibt einen ähnlichen Code wie
<?php foreach ($block->getFilters() as $filter): ?>
<?php if ($filter->getItemsCount()): ?>
Was sich schließlich stapelt
private function prepareData($key, $count)
und das ist eine Methode aus
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Wir haben also die Klasse identifiziert, die für die Preisfilterung verantwortlich ist, und wir sehen, dass sie bereits zur Erstellung der verfügbaren Bereiche verwendet wurde.
Der wichtigere Stapel besteht darin, zu überprüfen, was passiert, wenn ein bestimmter Bereich ausgewählt wird.
Zum Beispiel werde ich auf den Bereich 40.00-49.99 klicken, der voraussichtlich 4 Ergebnisse liefert.
An erster Stelle steht die Methode _prepareLayout()
von
/vendor/magento/module-layered-navigation/Block/Navigation.php
Der Code ist
protected function _prepareLayout()
{
foreach ($this->filterList->getFilters($this->_catalogLayer) as $filter) {
$filter->apply($this->getRequest());
}
$this->getLayer()->apply();
return parent::_prepareLayout();
}
Im Wesentlichen heißt das, dass ich alle Filter bekomme und jeder von ihnen es tut apply
.
Jetzt führt allein getFilters () schließlich dazu, dass ein Objekt aus erstellt wird
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Ein aufrufender Schritt, der zum __construct
von führt, Price
ist
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;
}
Und das ist Code von
vendor/module-catalog/Model/Layer/FilterList.php
Wenn wir uns auf den $filter->apply($this->getRequest());
Code von oben konzentrieren, bedeutet dies, dass dieser Code ausgeführt wird
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;
}
und wieder ist dieser Code von
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Wenn ich die Variablenwerte erneut genau befolge, da ich den Bereich 40.00-49.99 ausgewählt habe, $filter
besteht das Array aus zwei Elementen: [0 => 40, 1 => 50]
Nachdem diese Zeile ausgeführt wurde
list($from, $to) = $filter;
Offensichtlich ist die $from
Variable jetzt 40 und die $to
Variable ist jetzt 50.
Die nächste Zeile ist entscheidend
$this->getLayer()->getProductCollection()->addFieldToFilter(
'price',
['from' => $from, 'to' => empty($to) || $from == $to ? $to : $to - self::PRICE_DELTA]
);
Hier wird die bereits vorhandene Sammlung, die der Ebene zugeordnet ist, durch Aufrufen von weiter reduziert addFieldToFilter()
.
Vielleicht sollte hier die Aufmerksamkeit auf sich gezogen werden, um etwaige Fehler zu erkennen.
Schließlich ruft das Programm getLoadedProductCollection () von auf
vendor/magento/module-catalog/Block/Product/ListProduct.php
Dies gibt in efect die geschützte Sammlung zurück, die dieses Objekt kapselt.
Magento ist eine komplexe Anwendung.
Bei diesem einzigen Klick, bei dem eine einzelne Preisspanne ausgewählt wurde, sahen wir, wie Code aus drei verschiedenen Modulen interagierte
- Modul-Katalog
- Modul-Katalog-Suche
- Modul-Layered-Navigation
Es mag sich manchmal überwältigend anfühlen, aber es scheint mir, dass es eine schöne Synergie zwischen diesen Modulen gibt.
Danke fürs Lesen. Ich hoffe, das erklärt sich und Sie sind jetzt mit einem etwas besseren Verständnis der geschichteten Navigation ausgestattet.