Estou tentando usar um repositório de produtos para buscar uma lista de produtos. Quero buscar com base em dois filtros, combinados com umAND
critério, mas as coisas parecem não estar funcionando. Não entendo como os grupos de filtros funcionam? Ou isso é um bug que deve ser relatado?
Especificamente, (exemplo bobo por uma questão de simplicidade) eu tenho um construtor em que injeto um construtor de filtros, um construtor de grupos de filtros e um construtor de critérios de pesquisa
public function __construct(
\Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
\Magento\Framework\Api\FilterBuilder $filterBuilder,
\Magento\Framework\Api\Search\FilterGroupBuilder $filterGroupBuilder
)
{
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->filterBuilder = $filterBuilder;
$this->filterGroupBuilder = $filterGroupBuilder;
}
Mais tarde, em um método, eu uso os construtores de filtros para criar dois filtros
$filter1 = $this->filterBuilder->setField('sku')
->setValue('24-MB01')
->setConditionType('eq')
->create();
$filter2 = $this->filterBuilder->setField('sku')
->setValue('WT08-XS-Black')
->setConditionType('eq')
->create();
Então eu uso o construtor de grupos de filtros para criar um grupo de filtros que consiste nesses dois filtros
$filter_group = $this->filterGroupBuilder
->addFilter($filter1)
->addFilter($filter2)
->create();
Então eu usei um construtor de critérios de pesquisa, defina o grupo de filtros nele
$criteria = $this->searchCriteriaBuilder
->setFilterGroups([$filter_group])
->setPageSize(100)
->create();
return $criteria
Finalmente, quando eu uso esse critério com um repositório de produtos (usado em outro lugar, deixando de fora construtor e di para evitar confusão)
/* @var Magento\Catalog\Api\ProductRepositoryInterface */
$list = $productRepository->getList($searchCriteria);
A ligação é bem-sucedida, mas recebo de volta dois produtos. ou seja, o filtro SKU foi aplicado como umOR
, não um AND
. Eu esperaria que esta consulta não retornasse nada.
Se eu entrar na Magento\Catalog\Api\ProductRepository
turma e dar uma olhada na declaração de seleção da coleção
protected function addFilterGroupToCollection(
\Magento\Framework\Api\Search\FilterGroup $filterGroup,
Collection $collection
) {
//...
if ($fields) {
$collection->addFieldToFilter($fields);
}
//printf lives in my heart forever
echo($collection->getSelect()->__toString());
exit;
}
Vejo os critérios adicionados com um OR
SELECT `e`.*, IF(at_status.value_id > 0, at_status.value, at_status_default.value) AS `status`, IF(at_visibility.value_id > 0, at_visibility.value, at_visibility_default.value) AS `visibility`
FROM `catalog_product_entity` AS `e`
INNER JOIN `catalog_product_entity_int` AS `at_status_default` ON (`at_status_default`.`entity_id` = `e`.`entity_id`) AND (`at_status_default`.`attribute_id` = '94') AND `at_status_default`.`store_id` = 0 LEFT JOIN `catalog_product_entity_int` AS `at_status` ON (`at_status`.`entity_id` = `e`.`entity_id`) AND (`at_status`.`attribute_id` = '94') AND (`at_status`.`store_id` = 1)
INNER JOIN `catalog_product_entity_int` AS `at_visibility_default` ON (`at_visibility_default`.`entity_id` = `e`.`entity_id`) AND (`at_visibility_default`.`attribute_id` = '96') AND `at_visibility_default`.`store_id` = 0 LEFT JOIN `catalog_product_entity_int` AS `at_visibility` ON (`at_visibility`.`entity_id` = `e`.`entity_id`) AND (`at_visibility`.`attribute_id` = '96') AND (`at_visibility`.`store_id` = 1)
WHERE ((`e`.`sku` = '24-MB01') OR (`e`.`sku` = 'WT08-XS-Black'))
Isso é um inseto? Existe uma maneira (além de confiar diretamente nas coleções de produtos e abandonar os repositórios) para fazer isso funcionar?