8

I am listening to the sales_quote_save_before event to notice when an item is added to the cart. Once its fired, I iterate through the items options like this:

$quote = $observer->getEvent()->getQuote();

foreach ($quote->getAllItems() as $item) {
    $options = $item->getProduct()->getTypeInstance(true)->getOrderOptions($item->getProduct());

    foreach($options['options'] as $option) {

         if($option['label'] == 'myOptionA') {
              // Here I want to change the selected value for the option  
         }
     }
}

As you see, as soon as a certain option (myOptionA in the example) is reached, I want to change the selected option. So lets say myOptionA is a drop down and has 4 possible values. In case value 1 is selected, I want to set value 4 for that item. So when the cart is finished loading it should have value 4 for myOptionA. Not just its name, but its price as well. How could I do that?

2
  • CMIIW, this loop gives you the available values, not the selected one. To get the actual custom option that have been set, parse $array_sku = explode('-', $item->getSku()); Obviously, the first is the SKU of the actual product $sku = reset($array_sku); Do not have a solution yet to get the data. Jun 24, 2014 at 11:58
  • The key bit I am looking at is being able to set the price of the option's value. I've been looking at this some for the last few days and I'm not seeing an obvious way to set the value's price. It almost seems like the quote item needs to have options removed and then rebuilt from the request.
    – pspahn
    Dec 19, 2014 at 21:44

2 Answers 2

8

You could write an observer for the event catalog_product_type_prepare_full_options instead, which is the last event in the add to cart process before the product is actually added to the cart and after the custom options are prepared.

In the observer you have the following parameters available:

  • transport: Transport object for all custom options, so you can change tehem in the observer. transport->options is an array in the form option_id => option_value. Attention, transport itself is a stdClass object, not an instance of Varien_Object, as you might expect. So there are no getter and setter methods for transport->options.
  • product: The product that will be converted to a quote item later on.
  • buy_request: The buyRequest object, you can read it here and still modify it as well. It's a Varien_Object that contains amongst others:

    • product: The product id
    • options: Array of custom options in the form:

      option_id => value
      

Source and more info: info_buyRequest reference

So your observer might look like this:

$transport = $observer->getTransport();
if (isset($transport->options[OPTION_A_ID]) && $transport->options[OPTION_A_ID] == 1) {
    $transport->options[OPTION_A_ID] = 4;
}

$buyRequest= $observer->getBuyRequest();
$buyRequestOptions = $buyRequest->getOptions();
if (isset($buyRequestOptions[OPTION_A_ID]) && $buyRequestOptions[OPTION_A_ID] == 1) {
    $buyRequestOptions[OPTION_A_ID] = 4;
}
$buyRequest->setOptions($buyRequestOptions);

The first part (changing $transport) is relevant to actually change the value of option OPTION_A_ID. The second part (changing $buyRequest) is optional, it will just delete all traces of the value that the customer selected and if he reorders the order, the new value will be immediately selected because the buy request gets "executed" with the changed parameters. You have to decide, if that's what you want.

2
  • The same event may be used for magento 2 for similar purpose. Feb 7, 2017 at 13:49
  • it's not working in magento2 Feb 7, 2018 at 11:55
0

If you have set up your attribute via the code, i.e. using an install script - you'll find your attribute as a column under the sales_flat_quote_item.

If it is there, then having access to the $item variable, you should be able to use magic methods pertaining to your attribute:

// column name my_option
$item->setMyOption("value"); // to set the value
$item->getMyOption(); // to get the value

If this is the case, then you should be able to simplify the code as follows:

$quote = $observer->getEvent()->getQuote();
foreach ($quote->getAllItems() as $item) {
    $item->setMyOptionA("New Value");
    $item->save();
}

As mentioned, this solution will pertain only to those quote item attributes set up programatically.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.