El siguiente código se aplica a Magento 2.2.5.
En primer lugar, en la barra lateral, se deben producir todos los rangos posibles para todos los filtros posibles. Además, para esto, tendrá una visión general del recuento de productos encontrados dentro del rango dado.
Por ejemplo, me enfocaré en usar un filtro: el precio.
Antes que nada, para que un atributo de producto determinado sea elegible para la navegación en capas, debe configurarse correctamente.
Para verificar, busque en el administrador Stores -> Attribute -> Product
, luego seleccione el atributo de precio y observe que en la Storefront Properties
pestaña,
Use in Layered Navigation
se establece enFilterable (with results)
En esta imagen, vemos que para el filtro de precios, vemos que el rango 50.00-59.99
contiene 10
resultados, y 80+
solo por 1
.
Esta vista se produce dentro
/vendor/magento/theme-frontend-luma/Magento_LayeredNavigation/templates/layer/view.phtml
Hay un código similar a
<?php foreach ($block->getFilters() as $filter): ?>
<?php if ($filter->getItemsCount()): ?>
Que finalmente se acumula hasta
private function prepareData($key, $count)
y este es un método de
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Por lo tanto, hemos identificado la clase responsable del filtrado de precios y vemos que ya se usó para producir los rangos disponibles.
La pila más importante es verificar qué sucede cuando se selecciona un rango particular.
Por ejemplo, haré clic en el rango 40.00-49.99, que se espera que arroje 4 resultados.
Primero es el método _prepareLayout()
de
/vendor/magento/module-layered-navigation/Block/Navigation.php
El código es
protected function _prepareLayout()
{
foreach ($this->filterList->getFilters($this->_catalogLayer) as $filter) {
$filter->apply($this->getRequest());
}
$this->getLayer()->apply();
return parent::_prepareLayout();
}
En esencia, esto dice, consígueme todos los filtros y cada uno de ellos lo haga apply
.
Ahora, solo getFilters (), eventualmente lleva a construir un objeto a partir de
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Un paso de llamada que conduce a la __construct
de Price
es
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;
}
Y este es el código de
vendor/module-catalog/Model/Layer/FilterList.php
De todos modos, si nos enfocamos nuevamente en el $filter->apply($this->getRequest());
código de arriba, esto significa que este código se ejecutará
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;
}
y nuevamente, este código es de
vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php
Si sigo de cerca los valores de las variables, una vez más, dado que he seleccionado el rango 40.00-49.99, entonces la $filter
matriz consta de dos elementos: [0 => 40, 1 => 50]
Después de ejecutar esta línea
list($from, $to) = $filter;
Obviamente, la $from
variable ahora es 40 y la $to
variable ahora es 50.
La siguiente línea es crucial.
$this->getLayer()->getProductCollection()->addFieldToFilter(
'price',
['from' => $from, 'to' => empty($to) || $from == $to ? $to : $to - self::PRICE_DELTA]
);
Aquí es donde la colección ya presente asociada con la capa, se reduce aún más llamando al addFieldToFilter()
.
Tal vez, aquí es donde debe colocarse la atención para detectar errores, si los hay.
Finalmente, el programa llama a getLoadedProductCollection () desde
vendor/magento/module-catalog/Block/Product/ListProduct.php
que en efecto devuelve la colección protegida que encapsula este objeto.
Magento es una aplicación compleja.
En este solo clic que seleccionó un rango único de precios, vimos código de tres módulos diferentes interactuando
- catálogo de módulos
- módulo-búsqueda-catálogo
- módulo de navegación en capas
Puede parecer abrumador por momentos, pero me parece que hay una buena sinergia entre estos módulos.
Gracias por leer. Espero que esto explique y que ahora esté equipado con una mejor comprensión de la navegación por capas.