2

Using Magento 2.1.1. I have to add some bundle products programatically. Any post on stack doesn't work for me.

Here is my code - it adds bundle products with some options and every option should has only one selection. Althought it seems to work and options and selections are present in admin, saving from admin brakes product totally what indicates it was not added properly. If anyone has some working script for that please share.

Some example data:

$product['children'] = [
                        'name' => ['id' => 1345, 
                                   'license_extended_can_change_qty' => 1
                                  ], 
                                  ....
                       ];

Functions converting data to migrate for arrays used for adding bundle items:

private function prepareBundleOptionsMap($product)
{
    $bundle_options_map = array();

    foreach ($product['children'] as $childName => $childId) {
        $child_map = [
            'title' => $childName,
            'default_title' => $childName,
            'type' => 'select',
            'required' => 1,
            'delete' => '',
        ];

        $bundle_options_map[] = $child_map;
    }

    return $bundle_options_map;
}



private function prepareBundleSelectionsMap($product)
    {
    $bundle_selections_map = array();


    foreach ($product['children'] as $childName => $childData) {
        $child_map = [[
            'product_id' => $childData['id'],
            'selection_qty' => 1,
            'selection_can_change_qty' => $childData['license_extended_can_change_qty'],
            'delete' => '',
            'user_defined' => $childData['license_extended_can_change_qty']
        ]];

        $bundle_selections_map[] = $child_map;

        if ($childData['status'] == Status::STATUS_DISABLED) {
            $this->_logger->addInfo(__(' Bundle ' . $product['title'] . ' - one of children is disabled: ' . $childData['name']));
        }
    }

    return $bundle_selections_map;
}

And fragment of bigger script using above methods:

$bundle_options_map = $this->prepareBundleOptionsMap($migrated_product);
$bundle_selections_map = $this->prepareBundleSelectionsMap($migrated_product);

    $product->setBundleOptionsData($bundle_options_map);
    $product->setBundleSelectionsData($bundle_selections_map);

    if ($product->getBundleOptionsData()) {
        $options = [];
        foreach ($product->getBundleOptionsData() as $key => $optionData) {
            if (!(bool)$optionData['delete']) {
                $option = $this->optionFactory->create(['data' => $optionData]);
                $option->setSku($product->getSku());
                $option->setOptionId(null);

                $links = [];
                $bundleLinks = $product->getBundleSelectionsData();
                if (!empty($bundleLinks[$key])) {
                    foreach ($bundleLinks[$key] as $linkData) {
                        if (!(bool)$linkData['delete']) {
                            $link = $this->linkFactory->create(['data' => $linkData]);
                            $linkProduct = $this->productRepository->getById($linkData['product_id']);
                            $link->setSku($linkProduct->getSku());
                            $link->setQty($linkData['selection_qty']);
                            $link->setCanChangeQuantity($linkData['selection_can_change_qty']);
                            $links[] = $link;
                        }
                    }
                    $option->setProductLinks($links);
                    $options[] = $option;
                }
            }
        }
        $extension = $product->getExtensionAttributes();
        $extension->setBundleProductOptions($options);
        $product->setExtensionAttributes($extension);
        $product->save();
    }
0

The key here was not to use $product->save(), but instead save product via vendor/magento/module-catalog/Model/ProductRepository.php::save() method. It caused for me some issue with saving images programatically, so I haven't use it before. It turned out that my saving images was also deprecated - so preferably this script more or less should work, just with this little change.

Using deprecated save() product bundle options will collapse totally when later it would be saved from adminhtml.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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