Фильтрация хранилища объектов Magento 2

24

В Magento 2, вы можете использовать репозиторий продуктов для фильтрации по атрибутам продукта?

В Magento 2 вы можете использовать объект критериев поиска

\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria,

и хранилище

\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,

Чтобы получить список объектов

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

Однако объект searchCriteria не имеет (кажется?) Возможности прямой фильтрации. Класс критерии поиска действительно есть методы для добавления что - то называют 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);
}    

Но не ясно, что именно представляет собой группа фильтров благодаря нетипизированным массивам PHP.

Как я могу использовать хранилище Magento 2 для таких вещей, как

  • Покажите мне все продукты с [этим конкретным SKU]
  • Покажите мне все продукты, созданные после [этой даты]
  • и т.п.
Алан Сторм
источник
2
Похоже, что указанные группы являются массивом Magento \ Framework \ Api \ Search \ FilterGroup, который, в свою очередь, имеет фильтры \ Magento \ Framework \ Api \ Filter, фильтры можно создавать с помощью \ Magento \ Framework \ Api \ FilterBuilder, а условие_типа находится в форма 'eq', 'neq', 'gt' и т. д. Но не удалось найти список поддерживаемых типов условий: \
Петар Джамбазов
2
На самом деле, что-то вроде списка можно найти на Magento / Framework / Api / CriteriaInterface.php: 79
Петар Джамбазов

Ответы:

30

Проверьте следующий пример класса. Чтобы отфильтровать по SKU, попробуйте это:

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

Чтобы получить продукты, созданные после определенной даты, это:

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

Образец класса:

<?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();
    }
}
Алекс Палиаруш
источник
4
Спасибо, только что я был после! Похоже, что добавление нескольких фильтров создает условия «ИЛИ» - есть ли способ создать условия «И»?
Алан Сторм
3
- если у вас есть минутка. Я правильно использую группу фильтров? Похоже, что они подают
Alan Storm
4
Фильтры объединяются с «ИЛИ» внутри одной группы фильтров, а каждая группа объединяется с «И» на уровне критериев поиска. Взгляните на: \ Magento \ Framework \ Api \ SearchCriteriaBuilder :: setFilterGroups ($ groups []) и \ Magento \ Framework \ Api \ Search \ FilterGroupBuilder :: setFilters ($ filters [])
Алекс Палиаруш
Я использую Magento 2.3, построитель критериев поиска не фильтрует элемент, если элемент "out_of_stock"?
Осьминог
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
источник
1
Похоже, в вашем примере \Magento\Framework\Api\Search\SearchCriteriaBuilderиспользуется (специфичный для поиска), а я использовал \Magento\Framework\Api\SearchCriteriaBuilder(универсальный для всех сервисов), смотрите мой ответ. Также это обеспечивает более простой способ добавления фильтра, addFilter()подписи разные.
Алекс Палиаруш
Согласитесь, это немного другое решение.
LDusan
может addfilter использовать только 1 параметр?
Антонио Педичини
@LDusan, Подскажите, пожалуйста, как я могу использовать "$ searchCriteriaBuilder" в objectmanager?
Сарфарадж Сипай
2
Я думаю, что вы должны добавить его в конструктор вашего класса, зачем вам использовать диспетчер объектов для этого?
LDusan