1

I am writing a program that is checking product data and updating where required.

My problem is that I can't save a Bundled Products Bundle Items linked product fields such as price, price_type, qty, default etc. I can create a new linked item as part of an option, but I can't save the edited linked item.

My question is:

How do I save a linked product field such as price within an option of the bundled items section for a bundled product?

My code so far:

<?php

namespace Vendor\Module\Process;

use Magento\Bundle\Api\ProductLinkManagementInterface;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ProductRepository;

class UpdateBundleProductLinks
{
    private ProductLinkManagementInterface $productLinkManagement;
    private ProductRepository $productRepository;

    public function __construct(
        ProductLinkManagementInterface $productLinkManagement,
        ProductRepository              $productRepository
    ) {
        $this->productLinkManagement = $productLinkManagement;
        $this->productRepository = $productRepository;
    }


    public function execute(Product $product, array $productData): void
    {
        $productLinks = $this->productLinkManagement->getChildren($product->getSku());

        /* Iterate over each item in the $productData array */
        foreach ($productData['bundle_items'] as $bundleItem) {
            /* $productData['bundle_items'] has array of each linked products data, price, qty, price_type etc. */

            /* Iterate over links to find the match */
            foreach ($productLinks as $link) {

                if ($link->getSku() == $bundleItem['sku']) {
                    $update = false;

                    /* Check if links data matches */
                    if ($link->getPrice() != $bundleItem['price']) {
                        $link->setPrice($bundleItem['price']);
                        $update = true;
                    }

                    /* Check all links attributes here also ... */

                    if ($update) {
                        /* THIS IS WHERE I AM HAVING ISSUES SAVING THE LINK CHANGED DATA */

                        $this->productLinkManagement->saveChild($product->getSku(), $link);

                        /* I have tried saving the product after this point also without success */
                        $this->productRepository->save($product);
                    }
                    break;
                }
            }

        }
    }
}


Image below shows the admin product page section that I am trying to edit and save.

enter image description here

2 Answers 2

0

Can you please try this code?

Class file path : vendor/magento/module-catalog/Api/ProductLinkManagementInterface.php Function : public function setProductLinks($sku, array $items);
This function accept sku and items array

<?php
namespace Vendor\Module\Process;

use Magento\Bundle\Api\ProductLinkManagementInterface;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ProductRepository;

class UpdateBundleProductLinks
{
    private ProductLinkManagementInterface $productLinkManagement;
    private ProductRepository $productRepository;

    public function __construct(
        ProductLinkManagementInterface $productLinkManagement,
        ProductRepository              $productRepository
    ) {
        $this->productLinkManagement = $productLinkManagement;
        $this->productRepository = $productRepository;
    }


    public function execute(Product $product, array $productData): void
    {
        $productLinks = $this->productLinkManagement->getChildren($product->getSku());

        /* Iterate over each item in the $productData array */
        foreach ($productData['bundle_items'] as $bundleItem) {
            /* $productData['bundle_items'] has array of each linked products data, price, qty, price_type etc. */

            /* Iterate over links to find the match */
            foreach ($productLinks as $link) {

                if ($link->getSku() == $bundleItem['sku']) {

                    /* Check if links data matches */
                    if ($link->getPrice() != $bundleItem['price']) {
                        $link->setPrice($bundleItem['price']);

                        /*
                        Class file path : vendor/magento/module-catalog/Api/ProductLinkManagementInterface.php
                        Function : public function setProductLinks($sku, array $items);
                        this fucntion accept sku and items in array
                        */
                        $this->productLinkManagement->setProductLinks($product->getSku(), $link);
                    }

                }
            }

        }
    }
}
1
  • 1
    This tried to set Related / Cross-Sell / Up-Sell product option links, not bundle product links. I am trying to save the products that are within the Bundle Items / Option / Product.
    – Fox
    Commented Sep 7, 2023 at 6:09
0

When updating the links as per the code I supplied, I was then using the $product variable further in my code and saving changes later on which was re-entering the old value. The solution I found is to reload the Product after $this->productLinkManagement->saveChild($product->getSku(), $link) and then return it.

Working Code:

<?php

namespace Vendor\Module\Process;

use Magento\Bundle\Api\ProductLinkManagementInterface;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ProductRepository;

class UpdateBundleProductLinks
{
    private ProductLinkManagementInterface $productLinkManagement;
    private ProductRepository $productRepository;

    public function __construct(
        ProductLinkManagementInterface $productLinkManagement,
        ProductRepository $productRepository
    ) {
        $this->productLinkManagement = $productLinkManagement;
        $this->productRepository = $productRepository;
    }


    public function execute(Product $product, array $productData): Product
    {
        $productLinks = $this->productLinkManagement->getChildren($product->getSku());
        $updated = false;

        /* Iterate over each item in the $productData array */
        foreach ($productData['bundle_items'] as $bundleItem) {

            foreach ($productLinks as $link) {

                if ($link->getSku() == $bundleItem['sku']) {
                    $update = false;

                    if ($link->getPrice() != $bundleItem['price']) {
                        $link->setPrice($bundleItem['price']);
                        $update = true;
                    }

                    /* Check all link attributes here ... */

                    if ($update) {
                        $this->productLinkManagement->saveChild($product->getSku(), $link);
                        $updated = true;
                    }
                    break;
                }
            }
        }
        if ($updated) {
            $product = $this->productRepository->get($product->getSku(), true, null, true);
        }
        return $product;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.