набор связанных/продаваемых продуктов программно работает только для 1 продукта


Я пытаюсь обновить продукты программно, и у меня возникли проблемы с разделом "Связанные/продажи".

Он обновляется только с последним артикулом продукта . Поэтому, если я пытаюсь связать 3 продукта с родительским, как в примере ниже, в соответствующем разделе для продукта появится только последний parent_sku.

$linkDataAll = [];
$skuLinks = "9780500420584,9780500544679,9780500650936";
$skuLinks = explode(",",$skuLinks);

foreach($skuLinks as $skuLink) {
  //check first that the product exist
  $linkedProduct = $this->productFactory->create()->loadByAttribute("sku",$skuLink);
  if($linkedProduct) {
    $linkData = $this->productLinks //Magento\Catalog\Api\Data\ProductLinkInterface
                    ->setSku("parent_sku")
                    ->setLinkedProductSku($skuLink)
                    ->setLinkType("related");
    $linkDataAll[] = $linkData;
  }

}
if($linkDataAll) {
  print(count($linkDataAll)); //gives 3
  $product->setProductLinks($linkDataAll);
}
$product->save();
Author: Claudiu Creanga, 2016-09-14

4 answers

Эта часть вызвала вашу проблему, если вы создали этот объект, превышающий размер цикла foreach, это означает, что он является "глобальным" объектом. Итак, нам нужно создать новый объект внутри цикла.

$linkData = $productLinks //Magento\Catalog\Api\Data\ProductLinkInterface

Это должно выглядеть так:

 /** @var \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinks **/
$linkData = $productLinks->create();

Подробнее смотрите здесь Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper::setProductLinks

Программно устанавливайте связанные продукты Magento 2

 11
Author: Khoa TruongDinh, 2016-09-15 09:00:04

Вы всегда редактируете один и тот же объект.
$this->productLinks является объектом, поэтому он передается по ссылке.
$linkData ( что совпадает с $this->productLinks) всегда является ссылкой на один и тот же объект.
Таким образом, $linkDataAll в вашем случае будет массивом из 3 элементов, но все они будут указывать на один и тот же объект.
При первом входе в цикл вы добавляете некоторые свойства в $this->productLinks и добавляете его в массив $linkDataAll.
Во втором цикле вы добавляете некоторые свойства к тому же объекту $this->productLinks и добавляете его снова в массив, но таким образом ваш первый элемент в массиве будет изменен.

Простым решением было бы заменить

$linkData = $this->productLinks->setSku("parent_sku")....

С

$linkData = clone $this->productLinks;
$linkData->setSku("parent_sku")....
 1
Author: Marius, 2016-09-15 08:59:36

Вам нужно добавить метод setPosition в $productlinks

foreach($skuLinks as $n $skuLink) {
    // ...
    $this->productLinks
        ->setSku("parent_sku")
        ->setLinkedProductSku($skuLink)
        ->setLinkType("related")
        ->setPosition($n + 1);
    // ...
}
 1
Author: Hello.World, 2018-03-21 16:34:23

Использовать \Magento\Каталог\Api\Productlinkmanagementинтерфейс $Productlink Управление

Перед:

if($linkDataAll) {
  print(count($linkDataAll)); //gives 3
  $product->setProductLinks($linkDataAll);
}
$product->save();

После:

$this->productLinkManagement->setProductLinks("parent_sku", $linkDataAll);
 0
Author: Alexander Bobylev, 2020-05-27 05:48:52