3

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

11

2 Answers 2

7

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;
    }
}
?>
2
  • Thanks for your answer will check and getback Nov 14, 2018 at 6:24
  • 1
    Finally got perfect solution. Thanks. Aug 2, 2019 at 9:58
1

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);
            }
        }
    }
}

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.