How to remove products from categories programmatically in Shopware 6?
In a previous article on how to assign categories to the products in Shopware 6, we have learned, how we can assign one or more categories to a product. But what if we need to unassign them? Well, this article answers that question.
In Shopware 6, the product – category relations are stored in the product_category table. The structure of that table is pretty simple, the important thing is the duo product_id and category_id. Now you could of course just write an SQL query to delete the rows and in some cases, that is a viable approach, but not in this case. We will use the product_category repository to make sure, that we do not omit any background processes, that might be necessary for keeping the data integrity.
Get the categories of a product
In order to be able to remove categories, you must first know, which ones are assigned to your product. You can find them by using the product repository:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<?php namespace ExamplePlugin; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; class ExampleClass { private $productRepository; public function __construct ( EntityRepositoryInterface $productRepository ) { $this->productRepository = $productRepository; } public function getCategoryIds ($productId) { //set up the criteria for the search $criteria = new Criteria(); $criteria->addFilter(new EqualsFilter('id', $productId)); $criteria->addAssociation('categories'); //search the product repository, based on the criteria $data = $this->productRepository->search($criteria, $event->getContext()); if ($data) { //get the data of the product $item = $data->first(); //get an array of category IDs, associated with this product return $item->getCategories()->getIds(); } return false; } } |
Please note, that you must add association to categories in order to be able to get the category information from the repository query. If you forget it, you will just receive null on $item->getCategories()
, which might get confusing.
Delete categories from the product
So now you have the IDs of the categories, that are currently assigned to the product. For the sake of simplicity, let’s assume you want to unassign all of them from the product. For this, you need to inject the product_category repository to your class and then just run a delete command on it with product ID and category ID as parameters. It looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<?php namespace ExamplePlugin; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; class ExampleClass { private $productCategoryRepository; public function __construct ( EntityRepositoryInterface $productCategoryRepository ) { $this->productCategoryRepository = $productCategoryRepository; } public function removeCategoryIds ($productId, $categoryIds) { foreach ($categoryIds as $categoryId) { $this->productCategoryRepository->delete([['productId' => $productId, 'categoryId' => $categoryId]], $context); } } } |