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.
Alan Storm
fuente
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();
    }
}
Alex Paliarush
fuente
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();
}
LDusan
fuente
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