Question

I would like to display *Category Tree Names** in multi select field in magento 2 admin end?

I have tried with below code but displaying only first cateogires could you please any one help on this?

$field = $fieldset->addField(
            'wp_test',
            'multiselect',          
            [
                'name' => 'wp_test',
                'label' => __("Test"),
                'values' => $categorylistsource->toOptionArray(),
                'value' => $this->_getTest(),
                'title' => __('Test.'),
                'note' => __('Test')

            ]
        );

Hello\ConfigurableSku\Model\Config\Source

<?php
/**

@copyright Copyright
*/
namespace Hello\ConfigurableSku\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;
    }
}

But As per the above logic displaying only single line but i need to display like tree as mentioned below screenshot. how to achieve?

OUT PUT I WANT:-
enter image description here

Was it helpful?

Solution

please follow the below logic to get the category collection as tree structure. please let me know if u need any help.

<?php
namespace Hello\ConfigurableSku\Model\Config\Source;

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

class Categorylist implements ArrayInterface
{
    protected $_categoryHelper;
    protected $categoryRepository;
    protected $categoryList;

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

    /*
     * 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);
        $categoryList = $this->renderCategories($categories);
        return $categoryList;
    }

    public function renderCategories($_categories)
    {
        foreach ($_categories as $category){
            $i = 0; 
            $this->categoryList[$category->getEntityId()] = __($category->getName());   // Main categories
            $list = $this->renderSubCat($category,$i);
        }

        return $this->categoryList;     
    }

    public function renderSubCat($cat,$j){

        $categoryObj = $this->categoryRepository->get($cat->getId());

        $level = $categoryObj->getLevel();
        $arrow = str_repeat("---", $level-1);
        $subcategories = $categoryObj->getChildrenCategories(); 

        foreach($subcategories as $subcategory) {
            $this->categoryList[$subcategory->getEntityId()] = __($arrow.$subcategory->getName()); 

            if($subcategory->hasChildren()) {

                $this->renderSubCat($subcategory,$j);

            }
        } 

        return $this->categoryList;
    }
}
?>

OTHER TIPS

Follow Kavya Cheeraia answere and return category accodrding to website in Magento 2.3.4

namespace Vendor\Module\Model\ConfigOptionProvider;

use Magento\Framework\App\RequestInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Catalog\Api\Data\CategoryTreeInterface;
use Magento\Catalog\Api\CategoryManagementInterface;
use Magento\Framework\Api\ExtensibleDataObjectConverter;

class Categories implements \Magento\Framework\Data\OptionSourceInterface
{
    /**
     * @var StoreManagerInterface
     */
    private $storeManager;
    /**
     * @var RequestInterface
     */
    private $request;
    /**
     * @var CategoryManagementInterface
     */
    private $categoryManagement;
    /**
     * @var ExtensibleDataObjectConverter
     */
    private $objectConverter;

    /**
     * Categories constructor.
     * @param StoreManagerInterface $storeManager
     * @param RequestInterface $request
     * @param CategoryManagementInterface $categoryManagement
     * @param ExtensibleDataObjectConverter $objectConverter
     */
    public function __construct(
        StoreManagerInterface $storeManager,
        RequestInterface $request,
        CategoryManagementInterface $categoryManagement,
        ExtensibleDataObjectConverter $objectConverter
    ) {
        $this->storeManager = $storeManager;
        $this->request = $request;
        $this->categoryManagement = $categoryManagement;
        $this->objectConverter = $objectConverter;
    }

    /**
     * Return array of options as value-label pairs
     *
     * @return array Format: array(array('value' => '<value>', 'label' => '<label>'), ...)
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function toOptionArray()
    {
        $data = [];
        $rootCategory = $this->getRootCategory();

        /** @var CategoryTreeInterface $tree */
        $tree = $this->categoryManagement->getTree($rootCategory, 3);
        $categoryArray = $this->objectConverter->toNestedArray($tree, [], CategoryTreeInterface::class);
        if (count($categoryArray)) {
            $data[] = ['value' => $categoryArray["id"], 'label' => $categoryArray["name"]];
            $this->getArray($data, $categoryArray["children_data"], 1);
        }
        return $data;
    }

    /**
     * @return int
     * @throws \Magento\Framework\Exception\LocalizedException
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function getRootCategory()
    {
        $websiteId = $this->request->getParam("website", null);
        $store = $this->storeManager->getStore();
        if ($websiteId) {
            /** @var \Magento\Store\Model\Website $website */
            $website = $this->storeManager->getWebsite($websiteId);
            $store = $website->getDefaultStore();
        }
        return $store->getRootCategoryId();
    }

    public function getArray(&$data, $array, $level = 0)
    {
        foreach ($array as $category) {
            $arrow = str_repeat("---", $level);
            $data[] = ['value' => $category["id"], 'label' => __($arrow." ".$category["name"])];
            if ($category["children_data"]) {
                $this->getArray($data, $category["children_data"], $level+1);
            }
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top