7

How can I assign 'New products' to 'NEW PRODUCTS category' programatically in magento 2.

14

You need to get category Ids and product Id to set data: impliment this :

$this->getCategoryLinkManagement()->assignProductToCategories(
                $product->getSku(),
                $product->getCategoryIds()
            );

also impliment this function :

private function getCategoryLinkManagement()
{
    if (null === $this->categoryLinkManagement) {
        $this->categoryLinkManagement = \Magento\Framework\App\ObjectManager::getInstance()
            ->get('Magento\Catalog\Api\CategoryLinkManagementInterface');
    }
    return $this->categoryLinkManagement;
}

rest dependency you should manage for : Magento\Catalog\Api\CategoryLinkManagementInterface

intialize :

protected $categoryLinkManagement;

Direct use of \Magento\Framework\App\ObjectManager::getInstance() is not valid as per magento so you can inject it in Constructor

This answer is for below magento 2.2 versions, so please take a note

  • I used this code in a block and tried to render that block in template file. When I tried this method I got "Uncaught Error: Call to a member function assignProductToCategories()" in the template file. Could you please help me to sort out this? – chinchu Oct 17 '16 at 9:58
  • Have you give dependency for "Magento\Catalog\Api\CategoryLinkManagementInterface" ? – Ronak Chauhan Oct 17 '16 at 12:40
  • Yes, I have added. I worked fine. – chinchu Oct 18 '16 at 8:48
  • Hi @RonakChauhan I tried your code but it doesnt seem like working . My products are not getting assigned to category.. – Daniel_12 Oct 30 '18 at 15:18
  • @Daniel_12 are you getting any error? – Ronak Chauhan Oct 30 '18 at 17:24
9

I think, this needs an updated answer which does not make use of the object manager. Also, there are some kinks involved which are not mentioned anywhere.

In your constructor, inject the CategoryLinkManagementInterface:

protected $categoryLinkManagement;

public function __construct(
    ...
    \Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagementInterface,
    ...
) {
    $this->categoryLinkManagement = $categoryLinkManagementInterface;
    ...
}

Later in your code, assign categories the following way:

$product = $this->productRepository->getById(1337); // or any other way to get a product model/interface
$categoryIds = [
    42,
    606
];
$this->categoryLinkManagement->assignProductToCategories(
    $product->getSku(),
    $categoryIds
);

This will replace all previous category assignments. If you want to keep the existing category assignments, use something like this:

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

Be aware: The link management defers the category assignment (for the product attribute) to the scheduled indexer. This means that if you make other changes to the product and save it after assignProductToCategories()

$product = $this->productRepository->save($product);

the category assignments will be gone as $product contains either null (if it was a newly created product) or only the previously assigned categories for its attribute. Also,

$product = $this->productRepository->getById($product->getId());

right after assignProductToCategories() will not help for the same reason mentioned above. Either assign categories at the latest possible point in time (when you do not save the product afterwards) or assign the attribute manually before saving again

$product->setCategoryIds($categoryIds);

If you opt to use the latter, you could probably fall back to only using setCategoryIds(). I have not tested either case (assignProductToCategories + setCategoryIds + save or setCategoryIds only + save) for performance impact, so I can not comment on that, but I think the whole circumstance was important to mention.

  • hi, @Drelling, Could not save product \"41859\" with position 0 to category 8 getting above error, – jafar pinjar Nov 26 '18 at 11:59
  • Hi @jafarpinjar, is that all you got in terms of error messages? I could think of a few reasons, why this occured: 1. You accidentally used $product->getId() instead of $product->getSku() 2. The product's URL key is not unique (although I think that the error message would be specific) 3. The product is already assigned to category with id 8 – T. Dreiling Nov 27 '18 at 12:07
  • 1. can we not use $product->getId()? 3. The product is already assigned to category with id 8 – T. if assigned can we not remove it? – jafar pinjar Nov 27 '18 at 12:18
  • 1. No, assignProductToCategories() explicitly needs the SKU, not the ID! If that was your error, try again with SKU instead. 3. Ah, I was somewhat wrong here. The error I was thinking of occurs when $categoryIds would contain the same category more than once. You actually need to include category id 8 to keep it in that category. If you don't, it will be removed. So that's how you can remove a product from a category. – T. Dreiling Nov 27 '18 at 12:53
  • The error I was thinking of occurs when $categoryIds would contain the same category more than once. Its not possible is it? because category id is unique, I am passing sku only to this method assignProductToCategories not the id – jafar pinjar Nov 27 '18 at 13:22
4

Assign Products To Category

 <?php
 $new_category_id = array('100','101');
 $sku = 'sku of product';

 $objectManager = \Magento\Framework\App\ObjectManager::getInstance();

 $CategoryLinkRepository = $objectManager->get('\Magento\Catalog\Api\CategoryLinkManagementInterface');
 $CategoryLinkRepository->assignProductToCategories($sku, $new_category_id);

Remove Products From Category

 <?php
 $category_id = 101;
 $sku = 'sku of product';

 $objectManager = \Magento\Framework\App\ObjectManager::getInstance();

 $CategoryLinkRepository = $objectManager->get('\Magento\Catalog\Model\CategoryLinkRepository');
 $CategoryLinkRepository->deleteByIds($category_id ,$sku);
  • getting this error, Could not save product with position 0 to category 8 – jafar pinjar Nov 24 '18 at 10:49
  • @jafarpinjar this error is related to other customization. If you check this code snippet with fresh Magento install, it will work well. Please check if any third party customization preventing this code from execution – chirag dodia Nov 26 '18 at 3:57
  • hi @chirag dodia, no, I have used this code in custom file and running it by moving to root folder, no customization is used – jafar pinjar Nov 26 '18 at 6:00
  • @jafarpinjar try with fresh product and check is this something related to a particular product? – chirag dodia Nov 26 '18 at 11:52
  • hi @chirag, i got this error, Could not save product \"41859\" with position 0 to category 8 – jafar pinjar Nov 26 '18 at 11:55
-1
$objectManager = ObjectManager::getInstance();
$catalogProduct = $objectManager->create('Magento\Catalog\Model\Product');
$catalogProduct->setSku('sku-1');
$catalogProduct->setName('name');
$catalogProduct->setAttributeSetId(4);
$catalogProduct->setStatus(1); // Status on product enabled/ disabled 1/0
$catalogProduct->setVisibility(4);
$catalogProduct->setTypeId('simple'); // type of product (simple/virtual/downloadable/configurable)
$catalogProduct->setPrice(100);

$catalogProduct->setCategoryIds(['id']); // here you are

$catalogProduct->setStockData([
    'is_in_stock' => true,
    'qty'         => 10
]);

$catalogProduct->setStoreId(1); // $this->storeManagerInterface->getStore()->getId()
$catalogProduct->setWebsiteIds([1]); // $this->storeManagerInterface->getStore()->getWebsiteId()

$catalogProduct->save();
  • This is a very heavy request and executes very slowly as oppose to Link Manager – Timik Aug 16 '18 at 18:53

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.