Magento 2: ¿Cómo funcionan los datos facetados para la navegación en capas?

10

He creado un módulo para el filtro personalizado en la página de categoría, todo funciona bien, excepto el rango de precios en la navegación por capas.

Por favor, cualquiera puede explicarme cómo funciona getFacetedData ('precio') en magento2

$productCollection->getFacetedData('price');

Esta función me da rangos de precios basados ​​en la colección de productos predeterminada que no está basada en mi colección filtrada.

FYI: he filtrado la colección de la siguiente manera,

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

Respuestas:

7

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.

ingrese la descripción de la imagen aquí

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 Propertiespestaña, Use in Layered Navigationse establece enFilterable (with results)

En esta imagen, vemos que para el filtro de precios, vemos que el rango 50.00-59.99contiene 10resultados, 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 __constructde Pricees

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 $filtermatriz consta de dos elementos: [0 => 40, 1 => 50]

Después de ejecutar esta línea

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

Obviamente, la $fromvariable ahora es 40 y la $tovariable 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.

Marjan
fuente
+1 para la respuesta muy detallada y bien explicada. Sin embargo, no explicó cómo funcionan los datos facetados ... Los datos facetados se utilizan para generar recuentos de filtros.
Yonn Trimoreau
hola @Marjan, en mi caso la categoría de tercer nivel no se muestra en el filtro, aquí está mi pregunta, magento.stackexchange.com/questions/270442/…
jafar pinjar