0

[-- Edited below --]

I'm adding custom options programmatically when the product_prepare_save event is called. If it is the second custom option, everything works as expected, if it is the first, it will not appear.
However, it will appear when I add another custom option afterwards. I'm suspecting that I'm not saving the product correctly, but I can't find out why / how.

Here's the (shortened) function registered with the event observer:

    $event = $observer->getEvent();
    $request = $event->getRequest();
    $post = $request->getPost();

    $optionstoadd = array();
    if($post['newoptions']) {
        $optionstoadd = $post['newoptions'];
    }

    $currentProduct = $observer->getProduct();
    $currentProduct->setHasOptions(true);

    foreach ($optionstoadd as $optionId) {
        if($optionId == "") {
            continue;
        }
        $product = Mage::getModel('catalog/product')->load(Mage::getModel('catalog/product_option')->load($optionId)->getProductId());
        $option = $product->getOptionById($optionId);

        $data = array(...);

        $currentProduct->getOptionInstance()->addOption($data);
    }

EDIT: I have found out that setHasOptions(true); has no effect. I just cannot figure out why though. Also, the option itself is showing up in the database.

0

Answer was really simple to be honest. I blame Magento's somewhat bad documentation though. I have no idea how new developers are supposed to understand the system when the documentation barely repeats the name of the functions and says nothing about what they do.

Coming to the point: Somewhere down the line, far below the place where product_prepare_save is dispatched, the product model calls the function setHasOptions() itself, which is rather annoying if you're not aware of it.

protected function _beforeSave() in Mage_Catalog_Model_Product:

    /**
     * Set true, if any
     * Set false, ONLY if options have been affected by Options tab and Type instance tab
     */
    if ($hasOptions || (bool)$this->getTypeHasOptions()) {
        $this->setHasOptions(true);
        if ($hasRequiredOptions || (bool)$this->getTypeHasRequiredOptions()) {
            $this->setRequiredOptions(true);
        } elseif ($this->canAffectOptions()) {
            $this->setRequiredOptions(false);
        }
    } elseif ($this->canAffectOptions()) {
        $this->setHasOptions(false);
        $this->setRequiredOptions(false);
    }
    parent::_beforeSave(); 

tl;dr

My solution is to register another event (product_save_before) and call setHasOptions() there because this event is dispatched after the model calls setHasOptions() as described above.

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.