Filtering a Magento 2 Object Repository

The question:

In Magento 2, can you use a product repository to filter by product attributes?

In Magento 2, you can use a search criteria object

MagentoFrameworkApiSearchCriteriaInterface $searchCriteria,

and a repository

MagentoCatalogApiProductRepositoryInterface $productRepository,

To fetch a list of objects

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

However, the searchCriteria object doesn’t (seem to?) have direct filtering capabilities. The search criteria class does have methods for adding something called 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);
}    

But it’s not clear what, exactly, a filter group is thanks to PHP’s untyped arrays.

How can I use a Magento 2 repository to do things like

  • Show me all the products with [this specific SKU]
  • Show me all the products created after [this date]
  • etc.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

Check out the following sample class. To filter by SKU, try this:

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

To get products created after specific date, this:

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

Sample class:

<?php
namespace VendorModlueNameModel;

use MagentoFrameworkApiSearchCriteriaBuilder;
use MagentoCatalogApiProductRepositoryInterface;

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 MagentoCatalogApiDataProductInterface[]
     */
    public function getProducts($fieldName, $fieldValue, $filterType)
    {
        $searchCriteria = $this->searchCriteriaBuilder->addFilter($fieldName, $fieldValue, $filterType)->create();
        $products = $this->productRepository->getList($searchCriteria);
        return $products->getItems();
    }
}

Method 2

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();
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment