Search Criteria no Magento 2

Contextualizando

O que é Search Criteria?

O Search Criteria (critério de pesquisa) é literalmente um critério para pesquisar e/ou filtrar o resultado de um repositório desejado. É possível realizar um critério de pesquisa implementando uma interface para construir requisições personalizadas com diferentes condições que retornarão um vetor com os itens correspondentes a pesquisa.

Saiba como criar repositórios personalizados no post "Como criar um Repositório personalizado no Magento".

Saiba como criar APIs personalizados no post "Como criar APIs personalizadas no Magento 2".

Código para criar o Search Criteria

Para utilizar o Search Criteria em uma entidade personalizada é necessário criar uma interface de repositório e implementar o seguinte código da interface em uma classe.

API do Repositório

O Search Criteria (critério de pesquisa) deve ser criado dentro da classe de repositório da entidade com um método que implemente a classe \Magento\Framework\Api\SearchCriteriaInterface, que permite criar solicitações personalizadas com condições diferentes para executar filtros, ordenações, etc.

A classe obriga a implementação do método getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria), que define que o repositório deve retornar um objeto do resultado da pesquisa, através da coleção da entidade pesquisada. O objeto desta entidade deve implementar a interface \Magento\Framework\Api\SearchResultsInterface.

<?php

namespace {Vendor}\{Module}\Api;

use {Vendor}\{Module}\Api\Data\{EntityName}Interface;
use Magento\Framework\Api\SearchCriteriaInterface;

interface {EntityName}RepositoryInterface
{
    // Other repository methods

    public function getList(SearchCriteriaInterface $searchCriteria): {EntityName}Interface;
}

API dos Resultados da Pesquisa

O objeto desta entidade deve estender a interface \Magento\Framework\Api\SearchResultsInterface. Esta interface implementará os métodos getItems(), que retorna um array com os items correspondentes ao critério de busca do repositório, e o método setItems(array $items), que deve receber um array com os itens a serem definidos para o critério de busca.

<?php

namespace {Vendor}\{Module}\Api\Data;

use Magento\Framework\Api\SearchResultsInterface;

interface {EntityName}SearchResultsInterface extends SearchResultsInterface
{
    public function getItems(): array;

    public function setItems(array $items): self;
}

di.xml

Após a criação da interface do repositório é necessário a sobrescrição através do arquivo di.xml, para que o arquivo fique devidamente implementado e possa descrever em como os métodos serão executados.

<preference for="{Vendor}\{Module}\Api\Data\{EntityName}SearchResultsInterface" type="{Vendor}\{Module}\Model\{EntityName}SearchResults" />

Resultados da Pesquisa

Esta classe deverá estender a classe \Magento\Framework\Api\SearchResults que implementará os métodos getItems() e setItems(array $items) da api personalizada dos resultados da pesquisa.

<?php

namespace {Vendor}\{Module}\Model;

use Magento\Framework\Api\SearchResults;
use {Vendor}\{Module}\Api\Data\{EntityName}SearchResultsInterface;

class {EntityName}SearchResults extends SearchResults implements {EntityName}SearchResultsInterface
{
}

Repositório

No repositório será implementado o método getList(SearchCriteriaInterface $searchCriteria) que retornará um objeto da entitdade da \{Vendor}\{Module}\Api\Data\{EntityName}SearchResultsInterface.

<?php

namespace {Vendor}\{Module}\Model;

use {Vendor}\{Module}\Api\{EntityName}RepositoryInterface;
use {Vendor}\{Module}\Model\ResourceModel\{EntityName}\CollectionFactory;
use {Vendor}\{Module}\Model\{EntityName}SearchResultsFactory;
use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface;
use Magento\Framework\Api\SearchCriteriaInterface;
use {Vendor}\{Module}\Model\ResourceModel\{EntityName}\Collection;
use {Vendor}\{Module}\Api\Data\{EntityName}SearchResultsInterface;

class {EntityName}Repository implements {EntityName}RepositoryInterface
{
    private CollectionFactory $collectionFactory;
    private {EntityName}SearchResultsFactory $entityNameSearchResultsFactory;
    private CollectionProcessorInterface $collectionProcessor;

    public function __construct(
        // Other classes for dependency injection
        CollectionFactory $collectionFactory,
        {EntityName}SearchResultsFactory $entityNameSearchResultsFactory,
        CollectionProcessorInterface $collectionProcessor
    ) {
        $this->collectionFactory = $collectionFactory;
        $this->entityNameSearchResultsFactory = $entityNameSearchResultsFactory;
        $this->collectionProcessor = $collectionProcessor;
    }

    // Implementation of other repository methods

    public function getList(SearchCriteriaInterface $searchCriteria): {EntityName}SearchResultsInterface
    {
        /** @var Collection $collection */
        $collection = $this->collectionFactory->create();

        $this->collectionProcessor->process($searchCriteria, $collection);

        /** @var {EntityName}SearchResultsInterface $searchResults */
        $searchResults = $this->entityNameSearchResultsFactory->create();
        $searchResults->setSearchCriteria($searchCriteria);
        $searchResults->setItems($collection->getItems());

        return $searchResults;
    }
}

Os objetos do resultado da pesquisa contêm o objeto de critério de pesquisa (que são as entidades retornadas) e as informações sobre a contagem total das entidades encontradas, independentemente de quaisquer limitações definidas nos critérios.

Critérios de Busca nas APIs

Para pesquisas através de APIs que invocam a chamada do método {EntityName}Repository::getList(SearchCriteriaInterface $searchCriteria). Os critérios de busca devem ser especificados na URL da requisição em APIs do método POST. O padrão básico para especificar o critério de busca deve seguir o modelo:

searchCriteria[filter_groups][{index}][filters][{index}][field]={field_name}
searchCriteria[filter_groups][{index}][filters][{index}][value]={search_value}
searchCriteria[filter_groups][{index}][filters][{index}][condition_type]={operator}
  • field: é o nome do atributo pesquisado;
  • value: valor especificado para pesquisa;
  • condition_type: é a condição para busca. Caso o condition_type não seja especificado, eles assumirá o valor de eq.

O index filter_groups no array define um ou mais filters. Cada filtro define um termo de busca e o field, value e condition_type de cada termo de busca deve estar atribuído ao mesmo número do index, iniciando em 0.

Condição da Busca para Search Criteria

Tipo Descrição
eq Igual ao valor passado
finset O valor passado dentro de um conjunto
from O início de um intervalo. Deve ser usado com a condição to
gt Maior que o valor passado
gteq Maior ou igual ao valor passado
in O valor passado pode ser separados por vírgula e estar dentro
like O valor passado pode ter os caracteres especiais SQL
lt Menor que o valor passado
lteq Menor ou igual ao valor passado
moreq Mais ou igual ao valor passado
neq Não igual ao valor passado
nfinset O valor passado não está dentro de um conjunto
nin O valor passado pode ser separados por vírgula e não estar dentro
notnull O valor passado não pode ser null
null O valor passado for null
to O fim de um intervalo. Deve ser usado com a condição from
  • Para utilizar a pesquisa com uma condicional OR (ou), deve especificar múltiplos filters dentro do filter_groups. Condicionais do tipo OR não podem utilizar diferentes filter_groups
  • Para utilizar a pesquisa com uma condicional AND (e), deve especificar múltiplos filter_groups

Outros critérios de busca:

  • searchCriteria[sortOrders][{index}][field]={field-name}: especifica o campo que será ordenado. Por padrão, os resultados desta busca são retornados em ordem decrescente. É possível ordenar múltiplos campos especificando o valor com ASC ou DESC;
  • searchCriteria[pageSize]: especifica o número máximo de itens para retornar. O valor deve ser um inteiro. Caso o valor não for passado, o sistema irá retornar todas os valores;
  • searchCriteria[currentPage]: retorna a página atual da busca.

Finalizando

Valores entre chaves ({test}) devem ser alterados na implementação do código.

Habilitando as alterações

Apague os arquivos que são gerados na compilação do Magento e execute o comando PHP para gerar a configuração das injeções de dependência e todas as classes ausentes que precisam ser geradas (proxys, interceptors, etc) e para limpar todos os caches de armazenamento em cache do processos.

rm -rf var/generation/
rm -rf generated/
php bin/magento setup:di:compile
php bin/magento cache:clean
php bin/magento flush

Diretórios e Arquivos

Segue a a lista de diretórios e arquivos que devem ser criados.

- app/
  - code/
    - {Vendor}/
        - {Module}/
          - Api/
            - {EntityName}RepositoryInterface.php
            - Data/
              - {EntityName}SearchResultsInterface.php
          - etc/
            - module.xml
            - {area}/
              - di.xml
          - Model/
            - {EntityName}Repository.php
            - {EntityName}SearchResults.php
          - registration.php
          - composer.json

22