Il codice seguente si applica a Magento 2.2.5.
Prima di tutto, nella barra laterale, devono essere prodotti tutti i possibili intervalli per tutti i possibili filtri. Inoltre, avrai a disposizione una panoramica del conteggio dei prodotti trovati all'interno della gamma indicata.
Ad esempio, mi concentrerò sull'uso di un filtro: il prezzo.
Prima di ogni altra cosa, affinché un determinato attributo del prodotto sia idoneo per la navigazione a più livelli, dovrebbe essere configurato correttamente.
Per verificare, navigare nell'amministratore per Stores -> Attribute -> Product
, quindi selezionare l'attributo prezzo e osservare che nella Storefront Properties
scheda
Use in Layered Navigation
è impostato suFilterable (with results)
In questa immagine vediamo che per il filtro dei prezzi, vediamo che l'intervallo da 50.00-59.99
contiene 10
risultati, e 80+
solo 1
.
Questa vista è prodotta all'interno
/vendor/magento/theme-frontend-luma/Magento_LayeredNavigation/templates/layer/view.phtml
C'è un codice simile a
<?php foreach ($block->getFilters() as $filter): ?>
<?php if ($filter->getItemsCount()): ?>
Che alla fine si accumula fino a
private function prepareData($key, $count)
e questo è un metodo da
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Quindi, abbiamo identificato la classe responsabile del filtro dei prezzi e vediamo che è già stata utilizzata per produrre gli intervalli disponibili.
Lo stack più importante è verificare cosa succede quando viene selezionato un determinato intervallo.
Ad esempio, farò clic sull'intervallo 40,00-49,99, che dovrebbe restituire 4 risultati.
Il primo è il metodo _prepareLayout()
da
/vendor/magento/module-layered-navigation/Block/Navigation.php
Il codice è
protected function _prepareLayout()
{
foreach ($this->filterList->getFilters($this->_catalogLayer) as $filter) {
$filter->apply($this->getRequest());
}
$this->getLayer()->apply();
return parent::_prepareLayout();
}
In sostanza, questo dice, procurami tutti i filtri e foreach di loro fanno apply
.
Ora, solo getFilters () porta alla fine a costruire un oggetto
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Un passaggio di chiamata che porta al __construct
di 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 questo è il codice di
vendor/module-catalog/Model/Layer/FilterList.php
Comunque, se ci concentriamo di nuovo sul $filter->apply($this->getRequest());
codice dall'alto, questo significa che questo codice verrà eseguito
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 ancora, questo codice proviene da
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Se seguo da vicino i valori delle variabili, di nuovo, dato che ho selezionato l'intervallo 40,00-49,99, allora l' $filter
array è costituito da due elementi: [0 => 40, 1 => 50]
Dopo che questa linea è stata eseguita
list($from, $to) = $filter;
Ovviamente, la $from
variabile ora è 40 e la $to
variabile ora è 50.
La riga successiva è cruciale
$this->getLayer()->getProductCollection()->addFieldToFilter(
'price',
['from' => $from, 'to' => empty($to) || $from == $to ? $to : $to - self::PRICE_DELTA]
);
È qui che la raccolta già presente associata al livello viene ulteriormente ridotta chiamando il addFieldToFilter()
.
Forse, è qui che dovrebbe essere posta l'attenzione al fine di rilevare eventuali bug.
Alla fine, il programma chiama getLoadedProductCollection () da
vendor/magento/module-catalog/Block/Product/ListProduct.php
che in effetti restituisce la raccolta protetta che questo oggetto incapsula.
Magento è un'applicazione complessa.
In questi singoli clic che hanno selezionato una singola gamma di prezzi, abbiamo visto interagire il codice di tre diversi moduli
- Modulo-Catalogo
- Modulo-Catalogo-ricerca
- Modulo-layered-navigazione
Può sembrare travolgente in alcuni momenti, ma mi sembra che ci sia una bella sinergia tra questi moduli.
Grazie per aver letto. Spero che questo spieghi e ora sei dotato di una comprensione leggermente migliore della navigazione a strati.