Skip to content

Magento 2 System config Categories list not working on website scope update

I have created a system configuration to show the Categories list as assigned website-wise.
When we change the website scope the categories list options are the same.

Would you please share your thoughts on the same?

system.xml

<field id="categorylist" translate="label" type="multiselect" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
  <label>Categories List </label>
  <source_model>PrinceMyModuleModelSourceCategories</source_model>
</field>

Model/Source/Categories.php

<?php
namespace PrinceMyModuleModelSource;

use MagentoCatalogModelResourceModelCategoryCollectionFactory;
use MagentoFrameworkOptionArrayInterface;
use MagentoFrameworkAppRequestInterface;
use MagentoStoreModelStoreManagerInterface;
use MagentoCatalogHelperCategory;

class Categories implements ArrayInterface
{
    public const ALL_CATEGORIES = 0;
    public const SYSTEM_CATEGORY_ID = 1;
    public const ROOT_LEVEL = 1;


    /**
     * @var CollectionFactory
     */
    private $collectionFactory;
    /**
     * @var StoreManagerInterface
     */
    private $storeManager;
    /**
     * @var RequestInterface
     */
    private $requestInterface;
    /**
     * @var Category
     */
    private $categoryHelper;

    /**
     * Categories constructor.
     *
     * @param StoreManagerInterface $storeManager
     * @param CollectionFactory $collectionFactory
     * @param RequestInterface $requestInterface
     * @param Category $categoryHelper
     */
    public function __construct(
        StoreManagerInterface $storeManager,
        CollectionFactory $collectionFactory,
        RequestInterface $requestInterface,
        Category $categoryHelper
    ) {
        $this->collectionFactory = $collectionFactory;
        $this->storeManager = $storeManager;
        $this->requestInterface = $requestInterface;
        $this->categoryHelper = $categoryHelper;
    }


    /**
     * Options getter
     *
     * @return array
     */
    public function toOptionArray()
    {
        $optionArray = [];
        $arr = $this->toArray();
        foreach ($arr as $value => $label) {
            $optionArray[] = [
                'value' => $value,
                'label' => $label
            ];
        }
        return $optionArray;
    }

    /**
     * Get options in "key-value" format
     *
     * @return array
     */
    public function toArray()
    {
        
        $catIdAsWebsite = $this->storeManager->getGroup()->getRootCategoryId();

        return $this->getChildren(self::SYSTEM_CATEGORY_ID, self::ROOT_LEVEL,$catIdAsWebsite);
    }

    
    private function getChildren($parentCategoryId, $level,catIdAsWebsite)
    {
      
        $collection = $this->collectionFactory->create();
        $collection->addAttributeToSelect('name');
        $collection->addAttributeToFilter('parent_id', $parentCategoryId);
        $collection->addAttributeToFilter('level', $level);
        $collection->addAttributeToFilter('is_active', 1);
        $collection->setOrder('position', 'asc');

        foreach ($collection as $category) {
        
            $options[$category->getId()] = $category->getLevel();
            if ($category->hasChildren()) {
                $options = array_replace($options, $this->getChildren($category->getId(), $category->getLevel() + 1,$catIdAsStoreId));
            }
        }
        return $options;
    }
}