How to add multi-select category tree at admin end in magento 2?
-
06-02-2021 - |
题
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?
解决方案
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;
}
}
?>
其他提示
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);
}
}
}
}