0

I have to get the list of categories those have a specific attribute assigned,

So to achieve this i have created a custom attribute boolean type like this:

public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
    /** @var EavSetup $eavSetup */
    $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
    $eavSetup->addAttribute(
        Category::ENTITY,
        'top_category',
        [
            'type' => 'int',
            'label' => 'Top Category',
            'input' => 'boolean',
            'source' => 'Magento\Eav\Model\Entity\Attribute\Source\Boolean',
            'sort_order' => 3,
            'visible_on_front' => true,
            'used_in_product_listing' => true,
            'filterable' => true,
            'user_defined' => true,
            'global' => ScopedAttributeInterface::SCOPE_STORE,
            'group' => 'General Information',
        ]
    );
}

And then have created the form field as follows:

<?xml version="1.0" ?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<fieldset name="general">
    <field name="top_category" sortOrder="100" formElement="checkbox">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="source" xsi:type="string">category</item>
                <item name="default" xsi:type="number">0</item>
            </item>
        </argument>
        <settings>
            <validation>
                <rule name="required-entry" xsi:type="boolean">false</rule>
            </validation>
            <dataType>boolean</dataType>
            <label translate="true">Top Category</label>
        </settings>
        <formElements>
            <checkbox>
                <settings>
                    <valueMap>
                        <map name="false" xsi:type="string">0</map>
                        <map name="true" xsi:type="string">1</map>
                    </valueMap>
                    <prefer>toggle</prefer>
                </settings>
            </checkbox>
        </formElements>
    </field>
 </fieldset>
 </form>

It is showing and saved on category level enter image description here

Then Created a block to get the categories:

class Categories extends \Magento\Framework\View\Element\Template

{ protected $_categoryCollectionFactory; protected $_categoryHelper;

public function __construct(
    \Magento\Backend\Block\Template\Context $context,
    \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
    \Magento\Catalog\Helper\Category $categoryHelper,
    array $data = []
)
{
    $this->_categoryCollectionFactory = $categoryCollectionFactory;
    $this->_categoryHelper = $categoryHelper;
    parent::__construct($context, $data);
}

/**
 * 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('*')
        ->addAttributeToFilter('top_category',['eq'=>1])
        ->setOrder('updated_at', 'desc');

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

/**
 * Retrieve current store categories
 *
 * @param bool|string $sorted
 * @param bool $asCollection
 * @param bool $toLoad
 * @return \Magento\Framework\Data\Tree\Node\Collection or
 * \Magento\Catalog\Model\ResourceModel\Category\Collection or array
 */
public function getStoreCategories($sorted = false, $asCollection = false, $toLoad = true)
{
    return $this->_categoryHelper->getStoreCategories($sorted = false, $asCollection = false, $toLoad = true);
}

Then In Template i have get the categories for now as this:

// get current store's categories
$categories = $block->getStoreCategories();
foreach ($categories as $category) {
   echo $category->getName() . '<br />';
   echo $category->getTopCategory() . '<br />';
}

As you can see i have added the filter attribute on collection, but still it is showing all the categories not just those which have specific attribute.

Is there anything wrong i am doing, Need help to solve it out.

0

Never Mind Guys, I was using Second function to filter the categories but i suppose to use the getCategoryCollection() function to to get the filterable collection.

Anyhow i believe the post will somehow help to create it from scratch.

Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.