Magento 2 – Get Descending Category Collection for Breadcrumbs

breadcrumbscategorycollection;magento2

I want to have the breadcrumbs show on product pages even when searched or accessed directly.

As my pages cache are all warmed up via sitemap this basically removes breadcrumbs in my case as they seem to be part of the full page cache.

My main issue is getting a collection of categories related to a product ordered by level. This also needs to only show one path to the product (probably just the first that magento finds and limit to 1).

e.g.

//Problem 1 this pulls categories from all the stores
$categoryIds = $product->getCustomAttribute('category_ids');
//These is probably a better way to do this but had to build the array for collection to work           
foreach ($categoryIds->getValue() as $categoryId) {
    $catIdArray[] = $categoryId;
}

//get the category collection based on categories that product is listed in
$categories = $this->categoryFactory->create()
                        ->addAttributeToFilter('entity_id', $catIdArray)
                        ->setStore($this->_storeManager->getStore());       
//filter to just the top level category (deepest)
$categories = $categories->getSelect()->order('level DESC')->limit(1);
//get the top level category and get all parents get first item not working
$categorieslist = $category->getFirstItem()->getParentCategories();
//then i will use this collection to loop through and create breadcrumbs
  1. This does not seem to be filtering by store as $categoryIds = $product->getCustomAttribute('category_ids'); pulls all categories for each store.

  2. $categories = $categories->getSelect()->order('level DESC'); gives an empty collection.

  3. GetFirstItem() does not work here.

Not sure how to get the above code to work as above was a bit of a guess.

Best Answer

You can use $product->getCategoryCollection(), it takes the current store into account. But the return value is cached, so you cannot be sure if the collection already has been loaded. Clone and reset it so that you can adjust the query:

$categoryCollection = clone $product->getCategoryCollection();
$categoryCollection->clear();

$categoryCollection->addAttributeToSort('level', $categoryCollection::SORT_ORDER_DESC);
$categoryCollection->setPageSize(1);

$breadcrumbCategories = $categoryCollection->getFirstItem()->getParentCategories()

Note that I replaced the direct query manipulation with getSelect() by the appropiate collection methods for ORDER and LIMIT.