Filtrando um Repositório de Objetos Magento 2

24

No Magento 2, você pode usar um repositório de produtos para filtrar por atributos do produto?

No Magento 2, você pode usar um objeto de critério de pesquisa

\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria,

e um repositório

\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,

Para buscar uma lista de objetos

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

No entanto, o objeto searchCriteria não (parece?) Possui recursos de filtragem direta. A classe critérios de pesquisa não têm métodos para adicionar algo chamado 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);
}    

Mas não está claro o que exatamente um grupo de filtros é graças às matrizes não tipadas do PHP.

Como posso usar um repositório Magento 2 para fazer coisas como

  • Mostre-me todos os produtos com [este SKU específico]
  • Mostre-me todos os produtos criados após [esta data]
  • etc.
Alan Storm
fonte
2
Parece que esses grupos são uma matriz do Magento \ Framework \ Api \ Search \ FilterGroup, que por sua vez possui filtros \ Magento \ Framework \ Api \ Filter, os filtros podem ser criados com o \ Magento \ Framework \ Api \ FilterBuilder e o condition_type está em a forma de 'eq', 'neq', 'gt' etc. etc. Mas não foi possível encontrar a lista dos tipos de condição suportados: \
Petar Dzhambazov
2
Na verdade, algo como uma lista pode ser encontrada em Magento / Framework / Api / CriteriaInterface.php: 79
Petar Dzhambazov

Respostas:

30

Confira a seguinte classe de amostra. Para filtrar por SKU, tente o seguinte:

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

Para criar produtos após uma data específica, faça o seguinte:

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

Classe de exemplo:

<?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
fonte
4
Obrigado, exatamente o que eu estava procurando! Parece que adicionar vários filtros cria condições "OU" - existe uma maneira de criar condições "AND"?
Alan Storm
3
- se você tiver um momento. Estou usando o grupo de filtros corretamente? Eles parecem estar aplicando como um OR, não um E magento.stackexchange.com/questions/91023/...
Alan Storm
4
Os filtros são combinados com "OR" dentro de um grupo de filtros e cada grupo é combinado com "AND" no nível dos critérios de pesquisa. Dê uma olhada em: \ Magento \ Framework \ Api \ SearchCriteriaBuilder :: setFilterGroups ($ groups []) e \ Magento \ Framework \ Api \ Search \ FilterGroupBuilder :: setFilters ($ Filters [])
Alex Paliarush
Estou usando o Magento 2.3, o construtor Critérios de pesquisa não filtra o item se um item for "out_of_stock"?
Octopus
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
fonte
1
Parece que no seu exemplo \Magento\Framework\Api\Search\SearchCriteriaBuilderé usado (específico da pesquisa), enquanto eu usei \Magento\Framework\Api\SearchCriteriaBuilder(genérico para todos os serviços), veja minha resposta. Além disso, fornece uma maneira mais simples de adicionar filtro, as addFilter()assinaturas são diferentes.
Alex Paliarush
Concordado, é uma solução ligeiramente diferente.
LDusan
o addfilter pode usar apenas 1 param?
Antonio Pedicini 24/09
@LDusan, Você pode me dizer como posso usar "$ searchCriteriaBuilder" no gerenciador de objetos?
Sarfaraj Sipai
2
Eu acho que você deve adicioná-lo no construtor da sua classe, por que você deseja usar o gerenciador de objetos para isso?
LDusan