11

I want to get all categories names from a specific store. I'm trying:

$categoryFactory = $objectManager->create('Magento\Catalog\Model\ResourceModel\Category\CollectionFactory');
$categories = $categoryFactory->create()                              
    ->addAttributeToSelect('*')
    ->setProductStoreId($store->getId());

    foreach ($categories as $category){
        $category->getName();
    }

But it shows all the categories in the same language (same-store view).

So ->setProductStoreId($store->getId()) doesn't work.

I'm also tried $category->setStoreId($store->getId())->getName().

How can I get all the categories names for specific store view?

6 Answers 6

8

Try this :

protected $_storeManager;
protected $categoryCollectionFactory;
public function __construct(
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory
    $data = []
) {
    $this->_storeManager = $storeManager;
    $this->categoryCollectionFactory = $categoryCollectionFactory;
    parent::__construct($data);
}
$categories = $this->categoryCollectionFactory->create()                              
    ->addAttributeToSelect('*')
    ->setStore($this->_storeManager->getStore()); //categories from current store will be fetched

foreach ($categories as $category){
    $category->getName();
}
1
  • Include the $objectManager = $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    – senthil
    Commented Oct 30, 2018 at 10:22
24

Use directly objectmanager is not best/Recommended way to do in magento use Block with consturct and fetch method in your phtml file.

$categoryFactory = $objectManager->create('Magento\Catalog\Helper\Category');
$categoryFactory->getStoreCategories(false,false,true);

For More details kindly refer blogs link, Category Collection per store wise

Using Block way,

class Categorydata extends \Magento\Framework\View\Element\Template {
    protected $_categoryHelper;
    protected $categoryFactory;
    protected $_catalogLayer;

    public function __construct(
        \Magento\Catalog\Block\Product\Context $context,     
        \Magento\Catalog\Helper\Category $categoryHelper,        
        array $data = []
    ) {
        $this->_categoryHelper = $categoryHelper;   
        parent::__construct(
            $context,          
            $data
        );
    }

    /**
     * Retrieve current store level 2 category
     *
     * @param bool|string $sorted (if true display collection sorted as name otherwise sorted as based on id asc)
     * @param bool $asCollection (if true display all category otherwise display second level category menu visible category for current store)
     * @param bool $toLoad
     */

    public function getStoreCategories($sorted = false, $asCollection = false, $toLoad = true)
    {
        return $this->_categoryHelper->getStoreCategories($sorted , $asCollection, $toLoad);
    }

  }

call inside phtml file,

 $categorys = $this->getStoreCategories(false,false,true);
  foreach($categorys as $category){
     echo $category->getName()
  }
7
  • Shouldn't $context be an instance of \Magento\Framework\View\Element\Template\Context? Per the constructor method of \Magento\Framework\View\Element\Template which your answer's block is extending. Commented Jul 7, 2017 at 11:29
  • Additionally, any class which extends \Magento\Framework\View\Element\Template already has \Magento\Store\Model\StoreManagerInterface accessible to it via the protected class property $_storeManager, so setting it within our own classes' constructors to another property is unnecessary. +1 For assistance with the OP's question though this helped a lot thanks. Commented Jul 7, 2017 at 11:33
  • I tried this but got null.
    – P S
    Commented Dec 13, 2017 at 15:09
  • 1
    You should mention that this will return only categories that are included in the menu. Commented Jun 26, 2018 at 16:55
  • 1
    Thanks a ton, it works just perfect in magneto 2.3.x. Commented Feb 16, 2021 at 11:05
11

Create Block and add below code to your block.

namespace <vendor>\<module>\Block;

class FeaturedCategories extends \Magento\Framework\View\Element\Template{
protected $_categoryCollection;
protected $_storeManager;

public function __construct(
    \Magento\Backend\Block\Template\Context $context,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollection,
    array $data = []
)
{
    $this->_categoryCollection = $categoryCollection;
    $this->_storeManager = $storeManager;
    parent::__construct($context, $data);
}

public function getCategoryCollection()
{
    $collection = $this->_categoryCollection->create()
        ->addAttributeToSelect('*')
        ->setStore($this->_storeManager->getStore())
        //->addAttributeToFilter('attribute_code', '1')
        ->addAttributeToFilter('is_active','1');
   return $collection;
}
}

And $block->getCategoryCollection() used this in your template file. to get category collection

1
  • 1
    This will load only information available on catalog_category_entity table. It will not load attributes like name for example. Commented Jun 26, 2018 at 17:17
3

Method 1 - Using Dependency Injection (DI)

Here is the example code to get the list of all categories in Magento 2 using dependency injection.

To get the category information, we might need to inject the object of \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory and \Magento\Catalog\Helper\Category classes in the constructor of our module’s block class and access it from the view ( .phtml ) file.

app/code/YourCompanyName/YourModuleName/Block/YourCustomBlock.php

<?php
namespace YourCompanyName\YourModuleName\Block;
class YourCustomBlock extends \Magento\Framework\View\Element\Template
{ 
    protected $_categoryCollectionFactory;
  
    protected $_categoryHelper;
   
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
        \Magento\Catalog\Helper\Category $categoryHelper,
        array $data = []
    ) {
        $this->_categoryCollectionFactory = $categoryCollectionFactory;
        $this->_categoryHelper = $categoryHelper;
        parent::__construct($context, $data);
    }
   
    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);
        }
   
        // set pagination
        if ($pageSize) {
            $collection->setPageSize($pageSize); 
        } 
   
        return $collection;
    }

 /**
 * Retrieve current store level 2 category
 *
 * @param bool|string $sorted (if true display collection sorted as name otherwise sorted as based on id asc)
 * @param bool $asCollection (if true display all category otherwise display second level category menu visible category for current store)
 * @param bool $toLoad
 */
   
    public function getStoreCategories($sorted = false, $asCollection = false, $toLoad = true) {
        return $this->_categoryHelper->getStoreCategories($sorted = false, $asCollection = false, $toLoad = true);
    }
}

Now, we can use the functions in our view ( .phtml ) file as follows.

// get the list of all categories
$categories = $block->getCategoryCollection(); 
foreach ($categories as $category) {
    echo $category->getId() . '<br />';
    echo $category->getName() . '<br />';
}
   
// get categories sorted by category name
$categories = $block->getCategoryCollection(true, false, 'name', false);
foreach ($categories as $category) { 
    echo $category->getId() . '<br />';
    echo $category->getName() . '<br />';
}
   
// get current store’s categories
$categories = $block->getStoreCategories();
foreach ($categories as $category) { 
    echo $category->getId() . '<br />';
    echo $category->getName() . '<br />';
}

Method 2- Using Object Manager

Here is the code to get the list of all categories in Magento 2 using object manager.

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
  
// get the list of all categories
$categoryCollection = $objectManager->get('\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory');
$categories = $categoryCollection->create();
$categories->addAttributeToSelect('*');
   
foreach ($categories as $category) {
    echo $category->getId() . '<br />';
    echo $category->getName() . '<br />';
    echo $category->getUrl() . '<br />';
}
  
// get current store’s categories 
$categoryHelper = $objectManager->get('\Magento\Catalog\Helper\Category');
$categories = $categoryHelper->getStoreCategories();
   
foreach ($categories as $category) {
    echo $category->getId() . '<br />';
    echo $category->getName() . '<br />';
}
2

Just to mention, none of these answers are going to work from cron scope or admin scope.
storeManager doesnt work properly in these scopes, i.e. it always resolves to the default scope

e.g.
$storeManager->getStore($storeId) -> works
$storeManager->getStore() -> always returns default scope

Its something to keep in mind when not working in frontend (FE) scope


So to answer this,
firstly, avoid using entity factory for fetching entity, use collection or repository.
thing is, entity factory will return pure resource model, while collection might have additional related data loaded in the resource model (and contains any and all business logic of that resource)

secondly, get store id from some other entity youre connecting with categories there (customer, order, quote, product....) or if its just a loop over stores, pass down the store id like so

$storeId = $storeId ?? $customer->getStoreId();
$categoryCollectionFactory->create()
   ->setStoreId(
       $storeManager->getStore($storeId)
          ->getId()
    );

this way you can be sure it wont break on some scope other than FE

1

Get All Store Categories

<?php
    /**
     * Category action class
     *
     * Copyright © Devendra, Inc. All rights reserved.
     * See COPYING.txt for license details.
     */
    namespace DevG\Category\Controller\Index;
    
    use Magento\Framework\App\ActionInterface;
    use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
    use Magento\Framework\Controller\Result\JsonFactory;
    
    /**
     * Category request further.
     * 
     */
    class Index implements ActionInterface
    {
        /**
         * @var CollectionFactory
         */
        protected $categoryCollection;
        /**
         * @var JsonFactory
         */
        private $resultJsonFactory;
        /**
         * Index construct function
         *
         * @param CollectionFactory $categoryCollection
         * @param JsonFactory $resultJsonFactory
         */
        public function __construct(
            CollectionFactory $categoryCollection,
            JsonFactory $resultJsonFactory
        ) {
            $this->categoryCollection = $categoryCollection;
            $this->resultJsonFactory = $resultJsonFactory;
        }
    
        /**
         * get Store Category
         *
         * @return void
         */
        public function execute()
        {
            $categories = $this->categoryCollection->create();
            $categories->addAttributeToSelect('*');
            $result = [];        
            foreach ($categories as $category) {
                $result[] = ["name" => $category->getName(), "id" => $category->getId(), "url" => $category->getUrl()];
            }
            $result = array_slice($result, 2); 
            $resultJson = $this->resultJsonFactory->create();
            return $resultJson->setData(['categories' => $result]);
        }
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.