I'm trying to programmatically add a custom option to a product, there are no errors being returned, but the custom option doesn't get added. I've tried a few methods to achieve this, without much luck.
Here's my code as it stands:
$product = $this->objectManager->get('Magento\Catalog\Model\Product')->load($productID);
$productOption = $this->objectManager->get('Magento\Catalog\Model\Product\Option');
$productOption->setProduct($product);
$productOption->setTitle('Text');
$productOption->setType('area');
$productOption->setIsRequire(1);
$productOption->setValues([
'title' => 'Text',
'price' => '1.00',
'max_characters' => '50',
'price_type' => 'fixed',
'sort_order' => '1'
]);
$product->addOption($productOption);
$product->save();
Any ideas what I'm doing wrong?
UPDATE
I've now tried a different method:
$product = $this->objectManager->get('Magento\Catalog\Model\Product')->load($productID);
$product->unsetOptions();
$product->setHasOptions(1);
$product->setCanSaveCustomOptions(true);
$product->getOptionInstance()->addOption([
'title' => 'Text',
'type' => 'area',
'is_require' => 1,
'values' => [
[
'title' => 'Text',
'price' => '1.00',
'price_type' => 'fixed',
'max_characters' => '50'
]
]
]);
But this gives me the following error:
[Magento\Framework\Validator\Exception] Invalid option value
However, I cannot figure out what's invalid.
-
Have you get any solution. I faced same issue while adding product custom option value ?Kirti Nariya– Kirti Nariya2019年10月31日 11:32:59 +00:00Commented Oct 31, 2019 at 11:32
-
magento.stackexchange.com/questions/292966/…Kirti Nariya– Kirti Nariya2019年11月01日 07:24:58 +00:00Commented Nov 1, 2019 at 7:24
3 Answers 3
You don't need to specify values for the option type you are trying to add. Please try example below.
/** @var \Magento\Catalog\Api\Data\ProductCustomOptionInterface $customOption */
$customOption = $this->objectManager->create('Magento\Catalog\Api\Data\ProductCustomOptionInterface');
$customOption->setTitle('Text')
->setType('area')
->setIsRequire(true)
->setSortOrder(1)
->setPrice(1.00)
->setPriceType('fixed')
->setMaxCharacters(50)
->setProductSku($product->getSku());
$customOptions[] = $customOption;
$product->setOptions($customOptions)->save();
Also, you can find a lot of examples on how to add products, attributes, options, etc in fixtures for integration tests. For instance, take a look in dev/tests/integration/testsuite/Magento/Catalog/_files
-
Got it working using your example. Do you know any examples for adding linked products for Bundle products?Karl– Karl2016年01月25日 17:03:31 +00:00Commented Jan 25, 2016 at 17:03
-
1Nice advice with tests! They can be much more up-to-date with current version of Magento (as there are a lot of updates these days).Bartosz Kubicki– Bartosz Kubicki2016年05月31日 12:04:06 +00:00Commented May 31, 2016 at 12:04
-
Hi Igor, I tried above but it is giving unable to handle request page. can you tell what should have gone wrong??Navin Bista– Navin Bista2017年01月11日 12:26:32 +00:00Commented Jan 11, 2017 at 12:26
-
magento.stackexchange.com/questions/293336/…Kirti Nariya– Kirti Nariya2019年10月22日 17:05:42 +00:00Commented Oct 22, 2019 at 17:05
-
magento.stackexchange.com/questions/292966/…Kirti Nariya– Kirti Nariya2019年11月01日 07:24:54 +00:00Commented Nov 1, 2019 at 7:24
Here is the another sample code that can import product custom options from array. The basic and required field are added in the code. You can add more field as you need. you can import all of type of custom options with this code. I have checked the code can update options attribute and prices also.
This is a sample array data
$datas = array(
array(
"sku" => "951391-1-1",
"attributes" => '[{"title":"Add \"I\'m a pro\" on the back title", "type":"checkbox", "is_require":"0", "sort_order":"1", "values":[{"title":"Add \"I\'m a pro\" on the back", "price":"2.000000", "price_type":"fixed", "sku":null, "sort_order":"1"}, {"title":"Add my name", "price":"6.000000", "price_type":"fixed", "sku":null, "sort_order":"2"}]}, {"title":"Add my name title", "type":"field", "is_require":"0", "sort_order":"2", "price":"0.000000", "price_type":"fixed"}, {"title":"Test area title", "type":"area", "is_require":"0", "sort_order":"3", "price":"16.000000", "price_type":"fixed"}, {"title":"Test file title", "type":"file", "is_require":"0", "sort_order":"5", "price":"4.000000", "price_type":"fixed"}, {"title":"Test dropdown title", "type":"drop_down", "is_require":"0", "sort_order":"6", "values":[{"title":"test dropdown 1", "price":"7.000000", "price_type":"fixed", "sku":null, "sort_order":"1"}, {"title":"test dropdown 2", "price":"8.000000", "price_type":"fixed", "sku":null, "sort_order":"2"}]}, {"title":"Test radio title", "type":"radio", "is_require":"0", "sort_order":"7", "values":[{"title":"Test radio1", "price":"9.000000", "price_type":"fixed", "sku":null, "sort_order":"1"}, {"title":"Test radio2", "price":"10.000000", "price_type":"fixed", "sku":null, "sort_order":"2"}]}, {"title":"Test multiselect title", "type":"multiple", "is_require":"0", "sort_order":"8", "values":[{"title":"Test m-select1", "price":"11.000000", "price_type":"fixed", "sku":null, "sort_order":"1"}, {"title":"Test m-select2", "price":"12.000000", "price_type":"fixed", "sku":null, "sort_order":"2"}]}, {"title":"test date title", "type":"date", "is_require":"0", "sort_order":"9", "price":"13.000000", "price_type":"fixed"}, {"title":"Test data-time title", "type":"date_time", "is_require":"0", "sort_order":"10", "price":"14.000000", "price_type":"fixed"}, {"title":"Test time title", "type":"time", "is_require":"0", "sort_order":"11", "price":"15.000000", "price_type":"fixed"}]'
)
);
This is the code
$options = array();
foreach ($datas as $data) {
$_product = $this->_objectManager->create('Magento\Catalog\Api\ProductRepositoryInterface')->get($data['sku'], true);
$options = json_decode($data['attributes'], true);
foreach ($options as $arrayOption) {
$isRequire = $arrayOption['is_require'] == 0 ? true : false;
$customOption = $this->_objectManager->create('Magento\Catalog\Api\Data\ProductCustomOptionInterface');
$customOption->setTitle($arrayOption['title'])
->setType($arrayOption['type'])
->setIsRequire($isRequire)
->setSortOrder($arrayOption['sort_order']);
if (!in_array($arrayOption['type'], array('drop_down', 'checkbox', 'radio', 'multiple'))) {
$customOption->setPrice($arrayOption['price'])
->setPriceType($arrayOption['price_type']);
} else {
$customOption->setValues($arrayOption['values']);
}
$customOption->setProductSku($_product->getSku());
$customOptions[] = $customOption;
$_product->setOptions($customOptions)->save();
}
}
I think it will help you. Thanks to Igor Melnykov
Without using the object manager
use Magento\Catalog\Api\Data\ProductCustomOptionInterface;
use Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory;
use Magento\Catalog\Api\Data\ProductCustomOptionValuesInterfaceFactory;
use Magento\Catalog\Api\Data\ProductCustomOptionValuesInterface;
use Magento\Catalog\Model\Config\Source\ProductPriceOptionsInterface;
class MyClass
{
public function __construct(
protected ProductCustomOptionInterfaceFactory $customOptionFactory,
protected ProductCustomOptionValuesInterfaceFactory $customOptionValuesFactory
) { }
public function execute($product)
{
/** @var \Magento\Catalog\Model\Product\Option $customOption */
$customOption = $this->customOptionFactory->create();
$customOption->setTitle('My Custom Option');
$customOption->setType(\Magento\Catalog\Model\Product\Option::OPTION_TYPE_CHECKBOX);
$customOption->setIsRequire(true);
$customOption->setSortOrder(1);
$customOption->setSku('my_custom_option');
$customOption->setProductSku($product->getSku());
/** @var \Magento\Catalog\Model\Product\Option\Value $value */
$value = $this->customOptionValuesFactory->create();
$value->setTitle('Chocolate');
$value->setPrice(0);
$value->setPriceType(ProductPriceOptionsInterface::VALUE_FIXED);
$value->setSku('choc');
$value->setSortOrder(1);
$customOption->addValue($value);
$product->setOptions([$customOption]);
$product->save();
}
}
Explore related questions
See similar questions with these tags.