Filtrar un repositorio de objetos de Magento 2


24

En Magento 2, ¿puede usar un repositorio de productos para filtrar por atributos del producto?

En Magento 2, puede usar un objeto de criterio de búsqueda

\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria,

y un repositorio

\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,

Para buscar una lista de objetos

$searchCriteria->getPageSize(10);
$list = $productRepository->getList($searchCriteria);

Sin embargo, el objeto searchCriteria no tiene (¿parece?) Capacidades de filtrado directo. La clase criterios de búsqueda no tiene métodos para agregar algo llamado filterGroups

#File: lib/internal/Magento/Framework/Api/SearchCriteria.php        

public function getFilterGroups()
{
    $filterGroups = $this->_get(self::FILTER_GROUPS);
    return is_array($filterGroups) ? $filterGroups : [];
}

public function setFilterGroups(array $filterGroups = null)
{
    return $this->setData(self::FILTER_GROUPS, $filterGroups);
}    

Pero no está claro qué es exactamente un grupo de filtros gracias a las matrices sin tipo de PHP.

¿Cómo puedo usar un repositorio de Magento 2 para hacer cosas como

  • Muéstrame todos los productos con [este SKU específico]
  • Muéstrame todos los productos creados después de [esta fecha]
  • etc.

2
Parece que dichos grupos son una matriz de Magento \ Framework \ Api \ Search \ FilterGroup, que a su vez tiene filtros \ Magento \ Framework \ Api \ Filter, los filtros se pueden construir con \ Magento \ Framework \ Api \ FilterBuilder y condition_type está en la forma de 'eq', 'neq', 'gt', etc. Pero no se pudo encontrar la lista de tipos de condición admitidos: \
— Petar Dzhambazov

2
En realidad, se puede encontrar algo así como una lista en Magento / Framework / Api / CriteriaInterface.php: 79
— Petar Dzhambazov

Respuestas:


30

Echa un vistazo a la siguiente clase de muestra. Para filtrar por SKU, intente esto:

$productFilterDemo->getProducts('sku', 'product_sku_value', 'eq');

Para obtener productos creados después de una fecha específica, esto:

$productFilterDemo->getProducts('created_at', 'creation date', 'gt');

Clase de muestra:

<?php
namespace Vendor\ModlueName\Model;

use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Catalog\Api\ProductRepositoryInterface;

class ProductFilterDemo
{
    /** @var ProductRepositoryInterface */
    protected $productRepository;

    /** @var SearchCriteriaBuilder */
    protected $searchCriteriaBuilder;

    /**
     * Initialize dependencies.
     *
     * @param ProductRepositoryInterface $productRepository
     * @param SearchCriteriaBuilder $searchCriteriaBuilder
     */
    public function __construct(
        ProductRepositoryInterface $productRepository,
        SearchCriteriaBuilder $searchCriteriaBuilder
    ) {
        $this->productRepository = $productRepository;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
    }

    /**
     * Get products with filter.
     * 
     * @param string $fieldName
     * @param string $fieldValue
     * @param string $filterType
     * @return \Magento\Catalog\Api\Data\ProductInterface[]
     */
    public function getProducts($fieldName, $fieldValue, $filterType)
    {
        $searchCriteria = $this->searchCriteriaBuilder->addFilter($fieldName, $fieldValue, $filterType)->create();
        $products = $this->productRepository->getList($searchCriteria);
        return $products->getItems();
    }
}

44
Gracias, justo lo que estaba buscando! Parece que agregar varios filtros crea condiciones "OR". ¿Hay alguna forma de crear condiciones "AND"?
— Alan Storm

3
- Si tienes un momento. ¿Estoy usando el grupo de filtros correctamente? Parecen estar aplicando como OR, no como AND magento.stackexchange.com/questions/91023/…
— Alan Storm

44
Los filtros se combinan con "O" dentro de un grupo de filtros, y cada grupo se combina con "Y" en el nivel de criterios de búsqueda. Eche un vistazo a: \ Magento \ Framework \ Api \ SearchCriteriaBuilder :: setFilterGroups ($ groups []) y \ Magento \ Framework \ Api \ Search \ FilterGroupBuilder :: setFilters ($ filters [])
— Alex Paliarush el

Estoy usando Magento 2.3, ¿el generador de criterios de búsqueda no filtra el elemento si un elemento está "agotado"?
— Pulpo

14
public function __construct(
    ProductRepositoryInterface $productRepository,
    SearchCriteriaBuilder $searchCriteriaBuilder,
    FilterBuilder $filterBuilder,
) {
    $this->productRepository = $productRepository;
    $this->searchCriteriaBuilder = $searchCriteriaBuilder;
    $this->filterBuilder = $filterBuilder;
}

public function getProducts()
{
    $filters[] = $this->filterBuilder
        ->setField('sku')
        ->setConditionType('eq')
        ->setValue('something')
        ->create();
    $this->searchCriteriaBuilder->addFilters($filters);

    $searchCriteria = $this->searchCriteriaBuilder->create();
    $searchResults = $this->productRepository->getList($searchCriteria);
    return $searchResults->getItems();
}

1
Parece que en su ejemplo \Magento\Framework\Api\Search\SearchCriteriaBuilderse usa (búsqueda específica), mientras que yo usé \Magento\Framework\Api\SearchCriteriaBuilder(genérico para todos los servicios), vea mi respuesta. También proporciona una forma más simple de agregar filtros, las addFilter()firmas son diferentes.
— Alex Paliarush

De acuerdo, es una solución ligeramente diferente.
— LDusan

¿Puede addfilter usar solo 1 parámetro?
— Antonio Pedicini

@LDusan, ¿puede decirme cómo puedo usar "$ searchCriteriaBuilder" en objectmanager?
— Sarfaraj Sipai

2
Creo que deberías agregarlo en el constructor de tu clase, ¿por qué querrías usar el administrador de objetos para eso?
— LDusan
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.