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?
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?
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;
}
}
dublicating the class Category.php
since I used Category.php
in place of Categorylist.php
Commented
Apr 29, 2019 at 8:48
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
inCompanyname\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:
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;
}
}
If any one want code with parent and child category then follow below code :
<?php
namespace Vendor\Module\Model\Config\Source;
use Magento\Framework\Option\ArrayInterface;
class Category implements ArrayInterface
{
protected $_categoryFactory;
protected $_categoryCollectionFactory;
protected $_storeManager;
public function __construct(
\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
\Magento\Catalog\Model\CategoryFactory $categoryFactory,
\Magento\Store\Model\StoreManagerInterface $storeManager
) {
$this->_categoryCollectionFactory = $categoryCollectionFactory;
$this->_categoryFactory = $categoryFactory;
$this->_storeManager = $storeManager;
}
/**
* Get category collection
*
* @param bool $isActive
* @param bool|int $level
* @param bool|string $sortBy
* @param bool|int $pageSize
* @return \Magento\Catalog\Model\ResourceModel\Category\Collection or array
*/
public function getCategoryCollection($isActive = true, $level = false, $sortBy = false, $pageSize = false)
{
$collection = $this->_categoryCollectionFactory->create();
$collection->addAttributeToSelect('*');
$collection->setStore($this->_storeManager->getStore());
// 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);
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;
}
}