Atribuir produtos à categoria programaticamente no magento2

9

Como posso atribuir 'Novos produtos' a 'Categoria NOVOS PRODUTOS' programaticamente no magento 2.

chinchu
fonte

Respostas:

17

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

Ronak Chauhan
fonte
Eu usei esse código em um bloco e tentei renderizar esse bloco no arquivo de modelo. Quando tentei esse método, obtive "Erro não capturado: chame uma função de membro assignProductToCategories ()" no arquivo de modelo. Você poderia me ajudar a resolver isso?
chinchu
Você deu dependência para "Magento \ Catalog \ Api \ CategoryLinkManagementInterface" ?
Ronak Chauhan
Sim, eu adicionei. Eu trabalhei bem.
chinchu
Oi @RonakChauhan Eu tentei o seu código, mas ele não parece funcionar. Meus produtos não estão sendo atribuídos a categoria ..
Daniel_12
@ Daniel_12 você está recebendo algum erro?
Ronak Chauhan 30/10
12

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.

T. Dreiling
fonte
oi, @Drelling, Não foi possível salvar produto \ "41859 \" com a posição 0 a categoria 8 ficando acima erro,
Jafar pinjar
Oi @jafarpinjar, é tudo o que você recebe em termos de mensagens de erro? Eu pude pensar em algumas razões pelas quais isso ocorreu: 1. Você acidentalmente usou $ product-> getId () em vez de $ product-> getSku () 2. A chave de URL do produto não é exclusiva (embora eu ache que a mensagem de erro seria específico) 3. O produto já está atribuído à categoria com o ID 8
T. Dreiling
1. não podemos usar $ product-> getId ()? 3. O produto já está atribuído à categoria com ID 8 - T. Se atribuído, não podemos removê-lo?
Jafar pinjar
1. Não, assignProductToCategories () precisa explicitamente do SKU, não do ID! Se esse foi o seu erro, tente novamente com o SKU. 3. Ah, eu estava um pouco errado aqui. O erro que eu estava pensando ocorre quando $ categoryIds conteria a mesma categoria mais de uma vez. Você realmente precisa incluir o código de categoria 8 para mantê-lo nessa categoria. Caso contrário, ele será removido. É assim que você pode remover um produto de uma categoria.
T. Dreiling
O erro que eu estava pensando ocorre quando $ categoryIds conteria a mesma categoria mais de uma vez. Não é possível, é? porque categoria id é única, eu estou passando SKU apenas a este assignProductToCategories método não o id
Jafar pinjar
5

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);
chirag dodia
fonte
recebendo este erro, não foi possível guardar produto com posição de 0 a categoria 8
Jafar pinjar
@jafarpinjar este erro está relacionado a outra personalização. Se você verificar este trecho de código com a nova instalação do Magento, ele funcionará bem. Verifique se qualquer terceira personalização partido prevenir este código de execução
chirag dodia
oi @chirag dodia, não, eu tenho usado este código no arquivo personalizado e executá-lo, movendo a pasta raiz, nenhuma personalização é usado
Jafar pinjar
@jafarpinjar tente com produtos frescos e verifique se isso está relacionado a um produto em particular?
chirag dodia
oi @chirag, eu tenho esse erro: Não podia salvar produto \ "41859 \" com a posição 0 a categoria 8
Jafar pinjar
0

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!

SantiBM
fonte
-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();
Yamen Ashraf
fonte
Este é um pedido muito pesado e executa muito lentamente como se opor a Link Manager
Timik