Advertisement

Facebook

How to Assign Products to Categories in Magento 2 Programmatically

How to Assign Products to Categories in Magento 2 Programmatically

Assigning products to categories is a common task in Magento 2, especially if you want to automate how products are organized. For example, you might want to assign all "New Products" to a category called "NEW PRODUCTS." In this blog post, I'll show you how to do it step by step in a simple way.

Steps to Assign a Product to a Category Programmatically

In Magento 2, we use the CategoryLinkManagementInterface to assign products to categories. This interface provides a method called assignProductToCategories that makes this task easy. Here’s what we’ll cover:

  • Setting up the necessary code.
  • Assigning a product to one or more categories.
  • Keeping existing categories or replacing them.
  • Important tips to avoid issues.

Step 1: Add Dependencies

First, we need to include the tools Magento provides for working with products and categories. These are called "dependencies." We include them in our class using the constructor.

protected $categoryLinkManagement;
protected $productRepository;

public function __construct(
    \Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagement,
    \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
) {
    $this->categoryLinkManagement = $categoryLinkManagement;
    $this->productRepository = $productRepository;
}
  • CategoryLinkManagementInterface: Helps assign products to categories.
  • ProductRepositoryInterface: Helps load and save product information.

Step 2: Assign a Product to a Category

Let’s write a function to assign a product to a category:

public function assignProductToCategory($productId, $categoryId)
{
    try {
        // Load the product using its ID
        $product = $this->productRepository->getById($productId);

        // Add the new category to the product's existing categories
        $categoryIds = array_unique(
            array_merge(
                $product->getCategoryIds(),
                [$categoryId]
            )
        );

        // Assign the product to the updated categories
        $this->categoryLinkManagement->assignProductToCategories(
            $product->getSku(),
            $categoryIds
        );

        echo "Product successfully assigned to the category.";
    } catch (\Exception $e) {
        echo "Error: " . $e->getMessage();
    }
}
Parameters:
  • $productId: The ID of the product you want to update.
  • $newCategoryId: The ID of the category to assign the product to.

Step 3: Replace All Categories (Optional)

If you don’t want to keep the product’s current categories and only assign it to new categories, you can skip merging the category IDs:

$this->categoryLinkManagement->assignProductToCategories(
    $product->getSku(),
    [$categoryId] // Replace with new category
);

Step 4: Assign Multiple Products to a Category

If you want to assign many products to a category at once, you can loop through the product IDs:

public function assignProductsToCategory(array $productIds, $categoryId)
{
    try {
        foreach ($productIds as $productId) {
            $product = $this->productRepository->getById($productId);

            $categoryIds = array_unique(
                array_merge(
                    $product->getCategoryIds(),
                    [$categoryId]
                )
            );

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

        echo "All products successfully assigned to the category.";
    } catch (\Exception $e) {
        echo "Error: " . $e->getMessage();
    }
}

Practical Example: Assign "New Products" to "NEW PRODUCTS" Category

Let’s say you want to assign all products created in the last 30 days to a category called "NEW PRODUCTS." Here’s how:

public function assignNewProductsToCategory($categoryId)
{
    try {
        $today = new \DateTime();
        $lastMonth = $today->modify('-30 days')->format('Y-m-d H:i:s');

        // Load products created in the last 30 days
        $searchCriteria = $this->searchCriteriaBuilder
            ->addFilter('created_at', $lastMonth, 'gteq')
            ->create();

        $productList = $this->productRepository->getList($searchCriteria);

        foreach ($productList->getItems() as $product) {
            $categoryIds = array_unique(
                array_merge(
                    $product->getCategoryIds(),
                    [$categoryId]
                )
            );

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

        echo "New products assigned to the 'NEW PRODUCTS' category.";
    } catch (\Exception $e) {
        echo "Error: " . $e->getMessage();
    }
}

Important Tips

  • Indexing: Assigning categories programmatically updates the database, but Magento uses indexers to reflect these changes on the frontend. Run the following command to reindex:
  • bin/magento indexer:reindex catalog_category_product
  • Saving the Product After Assignment: If you save the product after assigning categories, the assignment might be lost. To avoid this, set the categories manually before saving:
  • $product->setCategoryIds($categoryIds);
    $this->productRepository->save($product);
  • Error Handling: Always use try-catch blocks to handle errors and ensure your code doesn’t break if something goes wrong.

Conclusion

With the above steps, you can easily assign products to categories in Magento 2 programmatically. Whether you’re working with one product or many, Magento’s CategoryLinkManagementInterface provides a flexible and efficient way to manage category assignments. Always remember to handle indexers and test your code to ensure smooth operations.

If you have any questions or would like to share your thoughts on assigning products to categories in Magento 2, feel free to leave a comment below! We’re always happy to help and hear from our readers.

Post a Comment

0 Comments

Buy Me A Coffee