3

My problem to get all available categories and display them in a system config multi-select field list.

Here is a link for Magento 1.x. How can it be achieved for Magento 2.x?

13

VendorName/ModuleName/etc/adminhtml/system.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <section id="module_section" translate="label" type="text"
                 sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Module</label>
            <tab>tab_name</tab>
            <resource>VendorName_ModuleName::config_module_name</resource>
            <group id="module_section_page" translate="label" type="text"
                   sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>Module page settings</label>
                <field id="latest_category" translate="label" type="multiselect" sortOrder="12" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>New Product Category</label>
                    <source_model>VendorName\ModuleName\Model\Config\Source\Categorylist</source_model>
                </field>
            </group>
        </section>
    </system>
</config>

VendorName/ModuleName/etc/acl.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/acl.xsd">
    <acl>
        <resources>
            <resource id="Magento_Backend::admin">
                <resource id="Magento_Backend::stores">
                    <resource id="Magento_Backend::stores_settings">
                        <resource id="Magento_Config::config">
                            <resource id="VendorName_ModuleName::config_module_name" title="Module Section" />
                        </resource>
                    </resource>
                </resource>
            </resource>
        </resources>
    </acl>
</config>

VendorName/ModuleName/Model/Config/Source/Categorylist.php

<?php

namespace VendorName\ModuleName\Model\Config\Source;

use Magento\Framework\Option\ArrayInterface;

class Categorylist implements ArrayInterface
{
    protected $_categoryFactory;
    protected $_categoryCollectionFactory;

    public function __construct(
        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory
    )
    {
        $this->_categoryFactory = $categoryFactory;
        $this->_categoryCollectionFactory = $categoryCollectionFactory;
    }

    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 toOptionArray()
    {
        $arr = $this->_toArray();
        $ret = [];

        foreach ($arr as $key => $value)
        {
            $ret[] = [
                'value' => $key,
                'label' => $value
            ];
        }

        return $ret;
    }

    private function _toArray()
    {
        $categories = $this->getCategoryCollection(true, false, false, false);

        $catagoryList = array();
        foreach ($categories as $category)
        {
            $catagoryList[$category->getEntityId()] = __($this->_getParentName($category->getPath()) . $category->getName());
        }

        return $catagoryList;
    }

    private function _getParentName($path = '')
    {
        $parentName = '';
        $rootCats = array(1,2);

        $catTree = explode("/", $path);
        // Deleting category itself
        array_pop($catTree);

        if($catTree && (count($catTree) > count($rootCats)))
        {
            foreach ($catTree as $catId)
            {
                if(!in_array($catId, $rootCats))
                {
                    $category = $this->_categoryFactory->create()->load($catId);
                    $categoryName = $category->getName();
                    $parentName .= $categoryName . ' -> ';
                }
            }
        }

        return $parentName;
    }
}

Here is a screenshot: enter image description here

  • Sir can you please explain... I used the same class as you mentioned above and its works perfectly for me.. but when I submit my module to Magento QA they send my module back to me with a note that dublicating the class Category.php since I used Category.php in place of Categorylist.php – Asad Khan Apr 29 at 8:48
7

In system.xml file field for multi select of category is like:

<group id="bannerblock_setting" translate="label" type="text" default="1" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1">
    <label>Setting</label>
    <field id="bannerlist" translate="label" type="multiselect" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
        <label>Select Category</label>
        <!-- <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>-->
        <source_model>Ipragmatech\Bannerblock\Model\Config\Source\Categorylist</source_model>
    </field>
</group>

Create a file Categorylist.php in Companyname\Modulename\Model\Config\Source

namespace Companyname\Modulename\Model\Config\Source;

use Magento\Framework\Option\ArrayInterface;

class Categorylist implements ArrayInterface
{
    protected $_categoryHelper;

    public function __construct(\Magento\Catalog\Helper\Category $catalogCategory)
    {
        $this->_categoryHelper = $catalogCategory;
    }

    /*
     * Return categories helper
     */

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

    /*  
     * Option getter
     * @return array
     */
    public function toOptionArray()
    {


        $arr = $this->toArray();
        $ret = [];

        foreach ($arr as $key => $value)
        {

            $ret[] = [
                'value' => $key,
                'label' => $value
            ];
        }

        return $ret;
    }

    /*
     * Get options in "key-value" format
     * @return array
     */
    public function toArray()
    {

        $categories = $this->getStoreCategories(true,false,true);

        $catagoryList = array();
        foreach ($categories as $category){

            $catagoryList[$category->getEntityId()] = __($category->getName());
        }

        return $catagoryList;
    }

}

Here is a screenshot:

enter image description here


  • But in this case you'll get first level only and categories included in menu – WaPoNe Dec 12 '16 at 13:46
  • You can little part modify code and get call subcategories..it upon you to make category and subcategory array and return that. – Manish Dec 13 '16 at 4:41
  • Hi @manish I have followed your post/answer everything working fine but we are facing an issue with displaying selected value after saving at admin end attribute level can you please suggest is there any thing i missed it. – Nagaraju Kasa Oct 31 '18 at 9:07
0

If somebody needs more clear code, you are welcome :)

<?php

declare(strict_types=1);

namespace Vendor\Module\Model\Config\Source;

use Magento\Catalog\Helper\Category as CategoryHelper;
use Magento\Framework\Option\ArrayInterface;

class Category implements ArrayInterface
{
    /**
     * @var \Magento\Catalog\Helper\Category
     */
    protected $categoryHelper;

    /**
     * Category constructor.
     *
     * @param \Magento\Catalog\Helper\Category $catalogCategory
     */
    public function __construct(CategoryHelper $catalogCategory)
    {
        $this->categoryHelper = $catalogCategory;
    }

    /**
     * @inheritDoc
     */
    public function toOptionArray(): array
    {
        $options = [];

        foreach ($this->toArray() as $key => $value) {
            $options[] = ['value' => $key, 'label' => $value,];
        }

        return $options;
    }

    /**
     * @return array
     */
    public function toArray(): array
    {
        $categoryList = [];

        foreach ($this->categoryHelper->getStoreCategories() as $category) {
            $categoryList[$category->getEntityId()] = $category->getName();
        }

        return $categoryList;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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