This article shows how we can get list of all categories from current product or any particular product as well.
Both ways (Dependency Injection & Object Manager way) are shown below:
Using Dependency Injection (DI)
Below is a block class of my custom module (Chapagain_HelloWorld). I have injected object of \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory
, \Magento\Catalog\Model\ProductRepository
and \Magento\Framework\Registry
classes in the constructor of my module’s block class.
app/code/Chapagain/HelloWorld/Block/HelloWorld.php
<?php
namespace Chapagain\HelloWorld\Block;
class HelloWorld extends \Magento\Framework\View\Element\Template
{
protected $_categoryCollectionFactory;
protected $_productRepository;
protected $_registry;
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
\Magento\Catalog\Model\ProductRepository $productRepository,
\Magento\Framework\Registry $registry,
array $data = []
)
{
$this->_categoryCollectionFactory = $categoryCollectionFactory;
$this->_productRepository = $productRepository;
$this->_registry = $registry;
parent::__construct($context, $data);
}
/**
* Get category collection
*
* @param bool $isActive
* @param bool|int $level
* @param bool|string $sortBy
* @param bool|int $pageSize
* @return \Magento\Catalog\Model\ResourceModel\Category\Collection or array
*/
public function getCategoryCollection($isActive = true, $level = false, $sortBy = false, $pageSize = false)
{
$collection = $this->_categoryCollectionFactory->create();
$collection->addAttributeToSelect('*');
// select only active categories
if ($isActive) {
$collection->addIsActiveFilter();
}
// select categories of certain level
if ($level) {
$collection->addLevelFilter($level);
}
// sort categories by some value
if ($sortBy) {
$collection->addOrderField($sortBy);
}
// select certain number of categories
if ($pageSize) {
$collection->setPageSize($pageSize);
}
return $collection;
}
public function getProductById($id)
{
return $this->_productRepository->getById($id);
}
public function getCurrentProduct()
{
return $this->_registry->registry('current_product');
}
}
?>
To get the current product, we use getCurrentProduct()
function. Otherwise, to get any particular product, we use getProductById($id)
function.
We then fetch the category ids associated with that product. After that, we fetch the category collection data for those category ids. Here’s the code to be written in template (.phtml) file.
$productId = 1; // YOUR PRODUCT ID
$product = $block->getProductById($productId);
// for current product
// $product = $block->getCurrentProduct();
$categoryIds = $product->getCategoryIds();
$categories = $block->getCategoryCollection()
->addAttributeToFilter('entity_id', $categoryIds);
foreach ($categories as $category) {
echo $category->getName() . '<br>';
}
Using Object Manager
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$categoryCollection = $objectManager->get('\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory');
$productRepository = $objectManager->get('\Magento\Catalog\Model\ProductRepository');
$appState = $objectManager->get('\Magento\Framework\App\State');
$appState->setAreaCode('frontend');
$productId = 1; // YOUR PRODUCT ID
$product = $productRepository->getById($productId);
$categoryIds = $product->getCategoryIds();
$categories = $categoryCollection->create()
->addAttributeToSelect('*')
->addAttributeToFilter('entity_id', $categoryIds);
foreach ($categories as $category) {
echo $category->getName() . '<br>';
}
Hope this helps. Thanks.