2
votes

I am working on a Magento 2.1.7 shop and I have created a child-theme of Magento Blank.

The products are organized into categories and subcategories. In other words, they are organized into parent categories and children categories.

Whenever a product is assigned, through the Magento admin, to a child category, I want it to be automatically assigned to all the ancestor categories of that child category.

The Footwear category tree

I want to manually assign all the boot brands in the store to the "Boots" child category add I want all boots to be automatically put, by Magento, in the "Footwear" parent category.

Magento 2.x provides a way to do that from the Dashboard:

  • Go to Products > Categories.
  • Click on the (parent) category in which you want to show the products of the sub-category.
  • Under Display Settings, set Yes for Anchor field.
  • Save the category, flush Magento's cache and reindex.

But this is tedious work especially considering the website has a "rich" category-tree. Here is an example: Home > Consumabile Auto & Moto > Lubrifianti > Uleiuri Motor > 0W-20.

The only category that has products here is 0W-20. It makes sense that all the products from 0W-20 should also be in its the parent categories.

Question: What is the programming solution that would do the job, recursively?

1
Do you have any idea how to do in magento 1? @Razvan Zamfirzus

1 Answers

1
votes

We can use event controller_action_catalog_product_save_entity_after which call whenever you save product through the Magento admin. In this event we can to assign current product to parent categories.

Firstly, we must create custom module. We'll not pay attention on this proccess, it was described many times on StackOveflow.

app/code/Vendor/Module/registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_Module',
    __DIR__
);

app/code/Vendor/Module/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_Module" setup_version="1.0.0" />
</config>

We must to register event to assign product to categories:

app/code/Vendor/Module/etc/adminhtml/events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="controller_action_catalog_product_save_entity_after">
        <observer name="catalog_assign_to_parents"
                  instance="Vendor\Module\Observer\CatalogAssignToParents" />
    </event>
</config>

app/code/Vendor/Module/Observer/CatalogAssignToParents.php

<?php

namespace Vendor\Module\Observer;

class CatalogAssignToParents implements \Magento\Framework\Event\ObserverInterface
{
    /** @var \Magento\Catalog\Api\CategoryLinkManagementInterface */
    protected $categoryLinkManagement;

    /**
     * @param \Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagement
     */
    function __construct(
        \Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagement
    ) {
        $this->categoryLinkManagement = $categoryLinkManagement;
    }

    /**
     * @param \Magento\Framework\Event\Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        /** @var \Magento\Catalog\Model\Product $product */
        $product = $observer->getEvent()->getProduct();

        $categories = [];
        /** @var \Magento\Catalog\Model\Category $category */
        foreach($product->getCategoryCollection() as $category) {
            foreach($category->getParentCategories() as $parentCategory) {
                $categories[] = $parentCategory->getId();
            }
        }
        $categories = array_unique($categories);

        $this->categoryLinkManagement->assignProductToCategories($product->getSku(), $categories);
    }
}

Don't forget run php bin/magento setup:upgrade after create module files. Write me if you have any issues.