Magento 2: Wie funktionieren facettierte Daten für die geschichtete Navigation?

10

Ich habe ein Modul für einen benutzerdefinierten Filter auf der Kategorieseite erstellt. Bis auf die Preisspanne in der geschichteten Navigation funktioniert alles einwandfrei.

Bitte kann mir jeder erklären, wie getFacetedData ('price') in magento2 funktioniert

$productCollection->getFacetedData('price');

Diese Funktion gibt mir Preisspannen basierend auf der Standardproduktsammlung, die nicht auf meiner gefilterten Sammlung basiert.

Zu Ihrer Information: Ich habe die Sammlung wie folgt gefiltert:

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

Antworten:

7

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.

Geben Sie hier die Bildbeschreibung ein

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 PropertiesRegisterkarte auf Use in Layered Navigationgesetzt istFilterable (with results)

Auf diesem Bild sehen wir, dass für den Preisfilter der Bereich von 50.00-59.99enthält 10Ergebnisse 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 __constructvon führt, Priceist

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, $filterbesteht das Array aus zwei Elementen: [0 => 40, 1 => 50]

Nachdem diese Zeile ausgeführt wurde

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

Offensichtlich ist die $fromVariable jetzt 40 und die $toVariable 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.

Marjan
quelle
+1 für die sehr detaillierte und schön erklärte Antwort. Sie haben jedoch nicht erklärt, wie die facettierten Daten funktionieren ... Die facettierten Daten werden zum Generieren von Filterzählungen verwendet.
Yonn Trimoreau
Hallo @ Marjan, in meinem Fall die dritte Ebene Kategorie nicht im Filter angezeigt
jafar pinjar