How to Add Dynamic Select Custom Options in Observer

custom-options

I want to set some options on certain products through an observer. I cannot use regular Custom Options saved to the product because they do not meet our requirement.

I am able to add field type options without problems using:

    $options = array(
        array(
            'title'     => $type->getDescription(),
            'type'      => 'field',
            'is_require'=> 0,
            'id'        => $type->getId(),
            'price'     => '20',
            'price_type'=> 'fixed',
            'sku'       => $type->getSku(),
            'sort_order'=> 0
        )
    );
    /*

        */
    // Unset options and declare new options
    $optionInstance = $product->getOptionInstance()->unsetOptions();
    $product->setHasOptions(true);

    if (count($options)) {
        foreach ($options as $option) {
            $optionModel = Mage::getModel('catalog/product_option')
                ->setProductId($product->getId())
                ->setStoreId($product->getStoreId())
                ->setId($option['id'])
                ->addData($option);
            $product->addOption($optionModel);
        }
    }

I have read every tutorial I can find on creating Custom Options programmatically. There seems to be several ways to do this, but this method was the only one that seems to work. If you answer and simply provide a link to some WordPress tutorial copied from some other site with unreadable code formatting and incorrect encoding, you will just be downvoted.

I want to add radio type options to this product. Everything I have found suggests this should be as simple as adding a values key to the option array:

    $options = array(
        array(
            'title'     => $type->getDescription(),
            'type'      => 'radio',
            'is_require'=> 0,
            'id'        => $type->getId(),
            'price'     => '20',
            'price_type'=> 'fixed',
            'sku'       => $type->getSku(),
            'sort_order'=> 0,
            'values'    => array(
                array(
                    'price' => '10',
                    'price_type' => 'fixed',
                    'sku' => 'some sku',
                    'title' => 'some title',
                    'id' => 3
                ),
                array(
                    'price' => '10',
                    'price_type' => 'fixed',
                    'sku' => 'some sku 2',
                    'title' => 'some title also',
                    'id' => 6
                )
            )
        )
    );

This flat out does not work. All I see in the frontend is a single radio input with 'None' as the title. Trying some different methods for adding the option to the product, sometimes I will see two radio inputs, the first says 'None' and the second input is the second value array.

I want to set radio/select options to a product while observing catalog_controller_product_view, how can this be done?

Best Answer

Ultimately, I relied on my instinct rather than on poorly written tutorials.

Instantiate new models for each option and each option's values. This is the key.

$product = $o->getEvent()->getProduct();
$optionModel = Mage::getModel('catalog/product_option')
    ->setTitle('My title')
    ->setProductId($product->getId())
    ->setStoreId($product->getStoreId())
    ->setId($myOptionId)
    ->setType('radio')
    ->setPrice(null)
    ->setPriceType(null)
    ->setSku($myOptionSku)
    ->setIsRequire(true);

$myValues = getModel('my_module/custom_model')->getCollection();

foreach ($myValues as $myValue) {
    $valueModel = Mage::getModel('catalog/product_option_value')
        ->setTitle($myValue->getDescription())
        ->setProduct($product)
        ->setOption($optionModel)
        ->setId($myValue->getId())
        ->setPrice($myValue->getMultiplier())
        ->setPriceType('fixed')
        ->setSku($myValue->getDescription());
    $optionModel->addValue($valueModel);
}
$product->setHasOptions(1);
$product->addOption($optionModel);
Related Topic