Product options add an extra level of flexibility for customisation of Magento products, and are particularly useful when configurable products aren't appropriate. Setting custom product options in bulk, such as via an import script, is not currently possible with the Magento DataFlow system, and would be time consuming to do manually. We can create a script in PHP directly that solves this problem, and allows enough flexibility to use for any number of different data sources.

Like rating summaries, custom options are stored separately to the product object. The best way to set them is to first create an array with the data for the option:

$options = array();
$options[$sku] = array(
    'title' => 'Option Title',
    'type' => 'radio',
    'is_require' => 1,
    'sort_order' => 0,
    'values' => array()
);
$options[$sku]['values'][] = array(
    'title' => 'Option Value 1',
    'price' => 0.00,
    'price_type' => 'fixed',
    'sku' => '',
    'sort_order' => '1'
);
$options[$sku]['values'][] = array(
    'title' => 'Option Value 2',
    'price' => 89.00,
    'price_type' => 'fixed',
    'sku' => '',
    'sort_order' => '1'
);

Note that the $options array has been created in this way to allow for multiple products to be filled out at once. Simply change values for more SKUs. This array can be filled out however is most appropriate for your system. This could be from an XML-RPC connection to another service, dynamically calculated values, or read from a CSV file. The sample values used in the above example should map logically to the values presented in the Magento product editor interface.

Once the array of data is set up, the custom options can be added to a product like so:

foreach($options as $sku => $option) {
    $id = Mage::getModel('catalog/product')->getIdBySku($sku);
    $product = Mage::getModel('catalog/product')->load($id);
 
    if(!$product->getOptionsReadonly()) {
        $product->setProductOptions(array($option));
        $product->setCanSaveCustomOptions(true);
        $product->save();
    }
}

Using the above code you can add custom options to all the products defined in the array that was set up previously. With slight modifications, it can be used to pull values from other sources. If your catalogue includes a lot of products that require custom options then having a script to set these values automatically can save a great deal of time.

Comments

Hi there, really interested in this feature. But can't get it to work. I created a PHP file and put in the 2 codes:

<?php

$options = array();
$options[$sku] = array(
'title' => 'Cadeauverpakking?',
'type' => 'checkbox',
'is_require' => 1,
'sort_order' => 0,
'values' => array()
);

foreach($options as $sku => $option) {
$id = Mage::getModel('catalog/product')->getIdBySku($sku);
$product = Mage::getModel('catalog/product')->load($id);

if(!$product->getOptionsReadonly()) {
$product->setProductOptions(array($option));
$product->setCanSaveCustomOptions(true);
$product->save();
}
}

?>

------

But I get following error:

Fatal error: Class 'Mage' not found in /home/gift/....................

I put the .php in mydomain.com/hack/cpo.php

Could you help me out?

If you are running this as a standalone script, you will need to initialise the Magento environment first.

Put the following at the start of your PHP file:

==================

<?php

define("MAGE_BASE_DIR", '/path/to/magento');
require_once MAGE_BASE_DIR . '/app/Mage.php';

Mage::app(0);

==================

This should remove problems with the Mage class not being found.

Hi

I have been working with Magento for a couple of weeks now. Mostly been adding products and customers programmatically using own scripts.

I've been fighting a problem with storing configurable options for over a day and I have tried several tutorials, yours including.

The problem was that if I saved 3 products, with one configurable option in each, the save operation resulted in 1+2+3 configurable fields. That is, inside Mage_Catalog_Model_Product_Option::saveOptions(), the array returned by Mage_Catalog_Model_Product_Option::getOptions() was never emptied between each call to $product->save() so effectively I just re-saved the configurable option to each new product, always adding one more option.

After a lot of hair pulling and screming I found this line of code to work:

// called this during each iteration in the product save loop, just after $product->save()
// I also tried with $product->reset() but it did not work
$product->getOptionInstance()->unsetOptions();

I don't know if my solution is fail safe but after some testing it seems to work.

I have a related problem, although the saving is correct. When I go to admin panel and to product's page via Catalogue-> Manage Products, the custom option does not show on the custom options panel. It shows only if I add another one and hit save. Any ideas why this is happening?