magento2でプログラムにより製品をカテゴリに割り当てる


9

magento 2でプログラム的に「新製品」を「新製品カテゴリ」に割り当てるにはどうすればよいですか。

回答:


17

データを設定するには、カテゴリIDと製品IDを取得する必要があります。これを暗示する:

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

この機能も実装します:

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

管理する必要がある残りの依存関係: Magento\Catalog\Api\CategoryLinkManagementInterface

初期化:

protected $categoryLinkManagement;

\ Magento \ Framework \ App \ ObjectManager :: getInstance()の直接使用はmagentoごとに有効ではないため、コンストラクターに挿入できます

この回答はmagento 2.2バージョン以下を対象としているため、メモしてください


このコードをブロックで使用し、そのブロックをテンプレートファイルにレンダリングしようとしました。この方法を試したところ、テンプレートファイルに「Uncaught Error:Call to a member function assignProductToCategories()」が表示されました。これを整理するのを手伝ってくれませんか。
ちんちゅ2016年

「Magento \ Catalog \ Api \ CategoryLinkManagementInterface」に依存関係を与えましたか?
Ronak Chauhan 2016

はい、追加しました。私はうまく働きました。
ちんちゅ2016年

こんにちは@RonakChauhan私はあなたのコードを試しましたが、うまくいっていないようです。私の製品はカテゴリに割り当てられていません..
Daniel_12 '30

@ Daniel_12エラーが発生していますか?
Ronak Chauhan

12

私は、これにはオブジェクトマネージャを利用しない更新された回答が必要だと思います。また、どこにも言及されていないいくつかのねじれが関与しています。

コンストラクターで、CategoryLinkManagementInterfaceを挿入します。

protected $categoryLinkManagement;

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

コードの後半で、次の方法でカテゴリを割り当てます。

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

これにより、以前のすべてのカテゴリ割り当てが置き換えられます。既存のカテゴリ割り当てを保持したい場合は、次のようなものを使用します。

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

注意:リンク管理は、スケジュールされたインデクサーへの(製品属性の)カテゴリー割り当てを延期します。これは、商品に他の変更を加え、assignProductToCategories()の後で保存した場合

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

$ productにnull(新しく作成された製品の場合)または以前にその属性に割り当てられたカテゴリのみが含まれているため、カテゴリの割り当ては失われます。また、

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

assignProductToCategories()の直後は、上記と同じ理由で役に立ちません。可能な限り最新の時点でカテゴリーを割り当てるか(後で製品を保存しない場合)、または再度保存する前に手動で属性を割り当てます。

$product->setCategoryIds($categoryIds);

後者を使用することを選択した場合、おそらくsetCategoryIds()の使用のみにフォールバックできます。私はどちらのケース(assignProductToCategories + setCategoryIds + saveまたはsetCategoryIds only + save)のパフォーマンスへの影響もテストしていないため、コメントすることはできませんが、全体的な状況について言及することが重要だと思います。


こんにちは、@ Drelling、位置0の製品\ "41859 \"をカテゴリ8に保存できませんでした。エラーが発生しました
jafar pinjar

こんにちは@jafarpinjar、エラーメッセージに関してあなたが得たのはそれだけですか?これが発生した理由はいくつか考えられます。1。誤って$ product-> getSku()ではなく$ product-> getId()を使用しました。2。製品のURLキーが一意ではありません(エラーメッセージは3.特定の製品は、ID 8のカテゴリに既に割り当てられています
T. Dreiling

1. $ product-> getId()を使用できませんか?3.製品はすでにID 8-Tのカテゴリに割り当てられています。割り当てられている場合、削除できませんか?
jafar pinjar 2018年

1.いいえ、assignProductToCategories()にはIDではなく、明示的にSKUが必要です。それがエラーの場合は、代わりにSKUを使用して再試行してください。3.ああ、私はここで少し間違っていました。私が考えていたエラーは、$ categoryIdsに同じカテゴリが2回以上含まれる場合に発生します。実際には、カテゴリID 8を含めて、そのカテゴリに保持する必要があります。そうしないと、削除されます。これが、カテゴリから製品を削除する方法です。
T.ドレイリング

私が考えていたエラーは、$ categoryIdsに同じカテゴリが2回以上含まれる場合に発生します。それは不可能ですか?カテゴリIDは一意であるため、SKUをこのメソッドにのみ割り当てています。assignProductToCategoriesはIDではありません
jafar pinjar

5

製品をカテゴリに割り当て

 <?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);

カテゴリーから製品を削除

 <?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);

このエラーが発生しました。位置0の製品をカテゴリ8に保存できませんでした
jafar pinjar

@jafarpinjarこのエラーは他のカスタマイズに関連しています。Magentoの新規インストールでこのコードスニペットを確認すると、うまく機能します。このコードの実行を妨げているサードパーティのカスタマイズがあるかどうかを確認してください
chirag dodia

こんにちは@chirag dodia、いいえ、カスタムファイルでこのコードを使用し、ルートフォルダーに移動して実行しました。カスタマイズは使用されません
jafar pinjar

@jafarpinjarは新鮮な製品を試してみて、これが特定の製品に関連していることを確認してください。
chirag dodia 2018年

こんにちは@chiragさん、このエラーが発生しました。位置0の製品「41859」をカテゴリ8に保存できませんでした
jafar pinjar

0

質問の回答がすでにあったとしても、反復$this->getCategoryLinkManagement()->assignProductToCategories()が非常に遅いため、製品のグループをカテゴリに割り当てるより速い方法を追加したいと思います。

この代替方法では、製品のグループを割り当てるカテゴリをロードする必要があるためMagento\Catalog\Model\CategoryFactory、を挿入する必要がsetPostedProducts()あります。の配列を使用するカテゴリに製品のグループを設定できる['entity_id','position']ため、コード例は次のようになります。

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";
    }

これが誰かを助けることを願っています!


-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();

これは非常に重いリクエストであり、リンクマネージャーとは
対照的に
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.