Respostas:
Você precisa obter os IDs da categoria e do produto para definir dados: implemente isto:
$this->getCategoryLinkManagement()->assignProductToCategories(
$product->getSku(),
$product->getCategoryIds()
);
também implementa esta função:
private function getCategoryLinkManagement()
{
if (null === $this->categoryLinkManagement) {
$this->categoryLinkManagement = \Magento\Framework\App\ObjectManager::getInstance()
->get('Magento\Catalog\Api\CategoryLinkManagementInterface');
}
return $this->categoryLinkManagement;
}
dependência de descanso que você deve gerenciar: Magento\Catalog\Api\CategoryLinkManagementInterface
inicializar:
protected $categoryLinkManagement;
O uso direto de \ Magento \ Framework \ App \ ObjectManager :: getInstance () não é válido conforme o magento, portanto você pode injetá-lo no Constructor
Esta resposta é para as versões abaixo do magento 2.2, então, tome nota
Eu acho que isso precisa de uma resposta atualizada que não faça uso do gerenciador de objetos. Além disso, existem algumas distorções envolvidas que não são mencionadas em nenhum lugar.
No seu construtor, injete o CategoryLinkManagementInterface:
protected $categoryLinkManagement;
public function __construct(
...
\Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagementInterface,
...
) {
$this->categoryLinkManagement = $categoryLinkManagementInterface;
...
}
Posteriormente no seu código, atribua categorias da seguinte maneira:
$product = $this->productRepository->getById(1337); // or any other way to get a product model/interface
$categoryIds = [
42,
606
];
$this->categoryLinkManagement->assignProductToCategories(
$product->getSku(),
$categoryIds
);
Isso substituirá todas as atribuições de categoria anteriores. Se você deseja manter as atribuições de categoria existentes, use algo como isto:
$categoryIds = array_unique(
array_merge(
$product->getCategoryIds(),
$categoryIds
)
);
Esteja ciente : o gerenciamento de link adia a atribuição de categoria (para o atributo do produto) ao indexador agendado. Isso significa que, se você fizer outras alterações no produto e salvá-lo após assignProductToCategories ()
$product = $this->productRepository->save($product);
as atribuições de categoria desaparecerão, pois $ product contém nulo (se foi um produto recém-criado) ou apenas as categorias atribuídas anteriormente para seu atributo. Além disso,
$product = $this->productRepository->getById($product->getId());
logo após assignProductToCategories () não ajudará pelo mesmo motivo mencionado acima. Atribua categorias no momento mais recente possível (quando você não salvar o produto posteriormente) ou atribua o atributo manualmente antes de salvar novamente
$product->setCategoryIds($categoryIds);
Se você optar por usar o último, provavelmente poderá voltar a usar apenas setCategoryIds (). Eu não testei nenhum dos casos (assignProductToCategories + setCategoryIds + save ou setCategoryIds only + save) quanto ao impacto no desempenho, por isso não posso comentar sobre isso, mas acho que é importante mencionar toda a circunstância.
Atribuir produtos à categoria
<?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);
Remover produtos da categoria
<?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);
Mesmo se a pergunta já tiver sido respondida, gostaria de adicionar uma maneira mais rápida de atribuir um grupo de produtos a uma categoria, conforme iterativo $this->getCategoryLinkManagement()->assignProductToCategories()
é bastante lenta
Essa alternativa envolve carregar a categoria à qual queremos atribuir nosso grupo de produtos; portanto, precisamos injetar Magento\Catalog\Model\CategoryFactory
, podemos definir um grupo de produtos para a categoria usando o setPostedProducts()
que leva uma matriz de ['entity_id','position']
modo que um exemplo de código seja algo como:
use Magento\Catalog\Model\CategoryFactory;
...
protected $_category;
...
$this->_category = $categoryFactory;
$parentsCollection = $this->_productCollection->create()
->addFieldToSelect('entity_id')
->addFieldToFilter('entity_id',['in' => $data['parent_ids']]);
$parentsPosted = array_fill_keys(array_keys($parentsCollection->toArray(['entity_id'])), 0);
if($catIds == 80 || $catIds == 82) {
$category = $this->_category->create()->load($catIds);
$category->setPostedProducts($parentsPosted);
$category->save();
echo "Products assigned to category: ".$catIds."\n";
}
Espero que isso ajude alguém!
$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();