How to assign categories to products programmatically in Shopware 6?
In Shopware 6, you can assign as many categories, as you want, to any product, independently of the category level. This is apparent in the Administration, but what if you need to assign the categories programmatically in your plugin?
First of all, you need to have the IDs of the categories, that you want to assign to your product. You can get a category ID for example by getting it by its name from the category repository 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 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 $categoryRepository; public function __construct ( EntityRepositoryInterface $categoryRepository ) { $this->categoryRepository= $categoryRepository; } public function getCategoryId ($categoryName) { //set up the criteria for the search $criteria = new Criteria(); $criteria->addFilter(new EqualsFilter('name', $categoryName)); //search the category repository, based on the criteria $categories = $this->categoryRepository->search($criteria, $context); if ($categories) { //get the first category, that we find $category = $categories->first(); //get the ID of the category $categoryId = $category->getId(); //return the ID of the category return $categoryId; } } } |
For some more information on repositories in Shopware 6 in general and how to get the mysterious “context” from the example, you can read my article here.
Assign a category to a product
So now that we have a category ID, we can assign it to a product. We need this product’s ID for this. You probably already have it available in your code and if not, then you can look for it in the product repository exactly the same way we have looked for the category ID in the category repository. That is all we need to assign a category to a product, so let’s do it:
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 |
<?php namespace ExamplePlugin; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; class ExampleClass { private $productRepository; public function __construct ( EntityRepositoryInterface $productRepository ) { $this->productRepository= $productRepository; } public function setCategoryId ($categoryId) { $this->productRepository->update( [ [ 'id' => $productId, 'categories' => [ [ 'id' => $categoryId ] ] ] ], $context); } } |
And this is it – your product is assigned to your category. Although the data in reality are not saved just in the product table, you can save them using the product repository. Shopware 6 DAL takes care of handling the entity associations for you.
Assign multiple categories to a product
Similarly, we can assign a product to more categories. Let’s select more categories, this time by filtering them by a string, contained in their names:
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 42 43 |
<?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 $categoryRepository; public function __construct ( EntityRepositoryInterface $categoryRepository ) { $this->categoryRepository= $categoryRepository; } public function getCategoryIds ($categoryNamePart) { //set up the criteria for the search $criteria = new Criteria(); $criteria->addFilter(new ContainsFilter('name', $categoryNamePart)); //search the category repository, based on the criteria $categories = $this->categoryRepository->search($criteria, $context); if ($categories) { //create an array for storing the IDs $categoryIds = []; //go through the categories and add their IDs to the array foreach ($categories as $category) { $categoryIds[] = [ 'id' => $category->getId() ]; } //return the IDs of the categories return $categoryIds; } } } |
So for example, if you had categories “Spare parts for cars” and “Spare parts for motorcycles” and you have searched for “spare parts”, now you have two category IDs, stored in an array. And this is how you assign them both to your product:
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 |
<?php namespace ExamplePlugin; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; class ExampleClass { private $productRepository; public function __construct ( EntityRepositoryInterface $productRepository ) { $this->productRepository= $productRepository; } public function setCategoryId ($categoryIds) { $this->productRepository->update( [ [ 'id' => $productId, 'categories' => $categoryIds ] ], $context); } } |
We have simply passed an array of category IDs in the correct format to the product repository and it has saved all the category associations to the product for us.
If you want to know the reverse process of category association, there is an article about how you can remove categories from a product in Shopware 6.