Question

In Magento 2, you're supposed to use the interfaces in Magento's API. So, when you want to fetch product(s), you'd use \Magento\Catalog\Api\ProductRepositoryInterface. That works great and it's very convenient.

Now when I want to get a list of categories, based on my search criteria. What's the best way to approach this? I don't really see the options, because:

  • \Magento\Catalog\Api\CategoryRepositoryInterface only supports a single entity, no getList() or something like that.
  • \Magento\Catalog\Model\ResourceModel\Category\Collection\Factory is used a lot from what I've seen from community code. However, this class is deprecated, which clearly means it shouldn't be used.
  • \Magento\Catalog\Model\CategoryFactory is also used a lot. It's a dynamically generated factory. Developers would use this factory to create a category model and get it's collection. That seems really awful to me, but it's a way to go I guess..
Was it helpful?

Solution

About a year later, Magento naturally has evolved and the Magento\Catalog\Api\CategoryListInterface can now be used.

It works great, I can do stuff like this:

/**
 * @var CategoryListInterface
 */
private $categoryListRepository;

/**
 * @var SearchCriteriaBuilder
 */
private $searchCriteriaBuilder;

/**
 * CategoryList constructor.
 * @param CategoryListInterface $categoryList
 * @param SearchCriteriaBuilder $searchCriteriaBuilder
 * @SuppressWarnings(PHPMD.LongVariableNames)
 */
public function __construct(
    CategoryListInterface $categoryListRepository,
    SearchCriteriaBuilder $searchCriteriaBuilder
) {
    $this->categoryListRepository = $categoryListRepository;
    $this->searchCriteriaBuilder = $searchCriteriaBuilder;
}

/**
 * @param int $parentId
 * @return CategoryInterface[]
 */
public function getCategories(int $parentId): array
{
    $this->searchCriteriaBuilder->addFilter('parent_id', $parentId);
    $searchCriteria = $this->searchCriteriaBuilder->create();

    $results = $this->categoryListRepository->getList($searchCriteria);

    return $results->getItems();
}

mpw's answer is useful as well and is supported by Magento, but my question was aiming for a service contract method.

OTHER TIPS

Since Magento\Catalog\Model\ResourceModel\Category\Collection has an @api annotation (as of 2.2), it appears that Magento has officially sanctioned the old style.

Rather than use the deprecated \Magento\Catalog\Model\ResourceModel\Category\Collection\Factory, I believe Magento would prefer usage of \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory, which is generated and has no deprecation.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top