18

I'm working on creating a custom option for my products automatically any time a product is created. What I've got so far is an observer that fires on the catalog_product_save_before event and runs the following code:

    //check that we haven't made the option already
    $options = $product->getProductOptions();
    foreach ($options as $option) {
        if ($option['title'] == 'Auto Date & Time' && $option['type'] == 'date_time' && !$option['is_delete']) {
            //we've already added the option
            return;
        }
    }
    $options[] = array(
        'title' => $product->getDateLabel(),
        'type' => 'date_time',
        'is_require' => 1,
        'sort_order' => 0,
        'is_delete' => '',
        'previous_type' => '',
        'previous_group' => '',
        'price' => '0.00',
        'price_type' => 'fixed',
        'sku' => ''
    );
    $product->setProductOptions($options);
    $product->setCanSaveCustomOptions(true);
    //this line doesnt make sense here, but it works ... kinda
    $product->save();

If I leave the $product->save() in, I wind up with 2 custom options being created, even though I've check to verify the 2nd time the event fires the return statement is called in the foreach loop.

If I take it out. No custom options are created.

Can someone tell me what I'm doing wrong?
I'm working with Magento 1.7

  • Hi,since you are using the catalog_product_save_before event you would not need to call the ->save, as the product woudl save after the event is completed. What happens if you remove that save call in your observer? – ProxiBlue Oct 17 '13 at 8:43
  • If I remove the call to save() no custom options are created. – Jason Neumann Oct 21 '13 at 15:29
12

Until I find the exact problem here is the solution. Instead catalog_product_save_before use the event catalog_product_prepare_save. The downside of this is that the prepare_save event is dispatched only when saving a product from the admin interface or the API. So if you are saving from a custom code this won't get triggered unless you trigger it manually.

I have a hunch that the problem has something to do with the Mage_Catalog_Model_Product::_beforeSave() method. In there there is some processing of the custom options.
But catalog_product_save_before is dispatched after this processing occurs, so while the custom options are processed in Mage_Catalog_Model_Product::_beforeSave() they are actually empty because the event didn't fire yet so they are not added.
If you move the line parent::_beforeSave(); in the method I mentioned at the top of the method, the options are added (still twice, but they are added). I will post more when/if I find the problem.

[EDIT]
Found it. I was somehow right in the lines above.
Like I said the problem is that catalog_product_save_before is dispatched after the custom options are processed. but this is why it doesn't work.
The custom options are saved in Mage_Catalog_Model_Product::_afterSave() by this code:

$this->getOptionInstance()->setProduct($this)
            ->saveOptions();

But $this->getOptionInstance() is populated with options in _beforeSave when the options array is empty in your case. Hence...nothing to save.
If you still want to use the catalog_product_save_before here is the code that should work.

//check that we haven't made the option already
$options = $product->getOptions();
if ($options){
    foreach ($options as $option) {
        if ($option['title'] == 'Auto Date & Time' && $option['type'] == 'date_time' && !$option['is_delete']) {
            //we've already added the option
            return;
        }
    }
}
$option = array(
    'title' => 'Auto Date & Time',
    'type' => 'date_time',
    'is_require' => 1,
    'sort_order' => 0,
    'is_delete' => '',
    'previous_type' => '',
    'previous_group' => '',
    'price' => '0.00',
    'price_type' => 'fixed',
    'sku' => ''
);
//don't use it like this because it has no effect
//$product->setProductOptions($options);
$product->setCanSaveCustomOptions(true);
//use it this way. Populate `$product->getOptionInstance()` directly
$product->getOptionInstance()->addOption($option);
//don't forget to state that the product has custom options
$product->setHasOptions(true);
  • Hello @Marius may i use catalog_product_prepare_save instead of catalog_product_save_before and how can i updated option if any changes required. – Zaheerabbas Dec 17 '13 at 8:32
0

I just had the same problem, the answer from marius worked great. It took me some time to figure out how to update a custom option though. With the knowledge that $product->getOptionInstance()->addOption() works for saving an option, and setting "is_delete" to 1 removes a option on saving, I came up with this code:

$oldOptions = $product->getOptionInstance()->getOptions();
foreach ($oldOptions as $key => $option){
    if($option['title'] == "Custom Option Title") {
        $oldOptions[$key]['is_delete'] = 1;                 
        $product->getOptionInstance()->addOption($oldOptions[$key]);
    }
}

After deleting you can add your updated custom option with this code:

$newOption = array(
    'title' => "Custom Option Title",
    'type' => 'radio',
    'is_require' => 1,
    'sort_order' => 20,
    'values' => array(
        array(
            'title' => "Value 1 Title",
            'price' => 42.00,
            'price_type' => 'fixed',
            'sku' => "",
            'sort_order' => '1'
        ),
        array(
            'title' => "Value 2 Title",
            'price' => 50,
            'price_type' => 'percent',
            'sku' => "",
            'sort_order' => '2'
        )
    )
);
$product->getOptionInstance()->addOption($newOption);
0

To create custom option in magento while saving product these is very easy steps.

   $product = Mage::getModel("catalog/product")->load($productid);

    $options[] = array(
            'title' => 'Pet',
            'type' => 'field',
            'is_require' => 0,
            'sort_order' => 0,
        );
    $options[] = array(
            'title' => 'Date',
            'type' => 'field',
            'is_require' => 1,
            'sort_order' => 2,
        );

    $product->setProductOptions(($options));
    $product->setCanSaveCustomOptions(true);
    $product->save();`

If there is already custom option created then you can delete it by following code

$product = Mage::getModel("catalog/product")->load($productid);

    $customOptions = $product->getOptions();

    foreach ($customOptions as $option) {
        $option->delete();
    }

    $product->setHasOptions(0);
    $product->save();

Thanks

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.