Whoever looked at the Magento source code or database in the context of orders, probably encountered the parameter $buyRequest in many methods or the option info_buyRequest in quote items and order items. Its purpose is not immediately obvious since it contains seemingly redundant information. Also it does not have its own model class, it’s just a Varien_Object and a serialized array when stored to the database.

Example:

mysql> select code,value from sales_flat_quote_item_option where option_id=2359; +-----------------+------------------------------------------------------------------------------------------------------------+ | code | value | +-----------------+------------------------------------------------------------------------------------------------------------+ | info_buyRequest | a:4:{s:4:"uenc";s:140:"[...],,";s:7:"product";s:4:"5000";s:15:"related_product";s:0:"";s:3:"qty";s:1:"1";} | +-----------------+------------------------------------------------------------------------------------------------------------+

In short: The $buyRequest object represents the customer request coming from a click on “Add to cart”, all related data can be derived from this object. It’s basically a generator for quote items. The minimal necessary data is thus the product id ( product ) and quantity ( qty ).

Where is the $buyRequest object needed?

For example it is created when you add a product to the wishlist, so that it can easily be transfered to the cart with the same configuration. When reconfiguring a product, i.e. editing it from the cart, the buyRequest is passed to the product view to preselect all options.

Also for recurring profiles and reordering the buyRequest objects get “reused” to generate a new order.

Use Cases

Some examples, when it is useful to deal with the buyRequest:

Programmatically create orders. See Mage_Sales_Model_Quote::addProduct()

See Automatically add complex products to the cart. See Mage_Checkout_Model_Cart::addProduct().

See Implementation of own product types. The buyRequest gets processed in Mage_Catalog_Model_Product_Type_Abstract::_prepareProduct() .

The buyRequest gets processed in . Manipulation of quote or wishlist items. See Mage_Sales_Model_Quote::updateItem() and Mage_Wishlist_Model_Wishlist::updateItem() . In my extension SSE_EditCustomOptions you can see how even custom options in orders can be changed retroactively, by manipulating the buyRequest objects. In the extension C4B_Freeproduct the buyRequest object is used to flag automatically added gifts so that they won’t get added to the cart again when reordering. That’s because there is no fieldset conversion from order items to quote Items when you reorder an order. That makes sense, since the price or other options might have changed in the meantime, so the quote shold be generated again based on request and product data.

See and . In my extension SSE_EditCustomOptions you can see how even custom options in orders can be changed retroactively, by manipulating the buyRequest objects. In the extension C4B_Freeproduct the buyRequest object is used to flag automatically added gifts so that they won’t get added to the cart again when reordering. That’s because there is no fieldset conversion from order items to quote Items when you reorder an order. That makes sense, since the price or other options might have changed in the meantime, so the quote shold be generated again based on request and product data. Flexible prices through configuration on the product page. Custom request parameters can be included in the price calculation. Andreas von Studnitz writes more about that topic in th article Umsetzung von flexiblen Preisen (German).

Which data can $buyRequest contain?

Besides product and qty it is bundle options for bundle products, configurable attributes for configurable products, selected links for downloadable products and custom options.

All product types

product : the product ID

: the product ID qty : Requested quantity. When the quantity in the quote item or wishlist item changes, it is adjusted here as well.

: Requested quantity. When the quantity in the quote item or wishlist item changes, it is adjusted here as well. original_qty : In case that the value of qty has changed, original_qty contains the originally requested quantity.

: In case that the value of qty has changed, original_qty contains the originally requested quantity. reset_count : is used for updating items in the cart and rather should have been called reset_qty. It gets set to true before adding the product to the quote if the quantity of a possibly existing quote item should be reset before adding the new quantity, i.e. the quantities should not be summed up. By default it gets set in Mage_Sales_Model_Quote::updateItem() . It gets checked in Mage_Sales_Model_Quote::addProductAdvanced() . Once set, reset_count gets saved as well without being relevant anymore.

: is used for updating items in the cart and rather should have been called reset_qty. It gets set to true before adding the product to the quote if the quantity of a possibly existing quote item should be reset before adding the new quantity, i.e. the quantities should not be summed up. By default it gets set in . It gets checked in . Once set, reset_count gets saved as well without being relevant anymore. Further request parameters from the add to cart form that are not relevant for the quote generation: related_product uenc form_key



Products with custom options

options : Array of custom options in the form:

option_id => value

: Array of custom options in the form: options_{$optionId}_file_action : Can contain the value „save_old“, if a previous file upload from existing configuration should be used (after reconfiguring an item with uploaded file in the cart)

: Can contain the value „save_old“, if a previous file upload from existing configuration should be used (after reconfiguring an item with uploaded file in the cart) _processing_params : One time parameters that are usually not saved but only needed temporarily. Array with additional data for custom options with attached file. It can have the following content: current_config : Current buyRequest object, see Mage_Catalog_Helper_Product::addParamsToBuyRequest() and Mage_Catalog_Model_Product_Option_Type_File::_getCurrentConfigFileInfo() files_prefix : Prefix for names of file inputs

: One time parameters that are usually not saved but only needed temporarily. Array with additional data for custom options with attached file. It can have the following content:

Grouped Products

super_group : (in buyRequest for the grouped product) Array with selected group products in the form

sub_product_id => qty

: (in buyRequest for the grouped product) Array with selected group products in the form super_product_config : (in buyRequest, that’s generated for each single product) Array in the Form

product_type => 'grouped'

product_id => group_product_id

Configurable Products

super_attribute : Array with the configured attributes in the form

attribute_id => value_id

Downloadable Products

links : Array with all link IDs, selected to buy. If links are not purchasable separately, it gets filled automatically with all links of the product.

Bundle Products

options : Array with the selected options in the form

option_id => selection_id[]

: Array with the selected options in the form bundle_option_qty : Array with quantities of the selected options in the form:

option_id => qty

Extendability: own data

Sometimes it can make sense to include own data in the $buyRequest object. Generally there are two cases how this is possible:

Programmatically added products: the buyRequest is passed to Mage_Sales_Model_Quote::addProduct() as second parameter. Interesting: the parameter can be a float as well, representing the quantity if there are no custom options or other data. The default value is „1“. Products regularly added to the cart: all inputs in the add to cart form are carried over to the buyRequest. So the form on the product page can be extended arbitrarily and all data is saved automatically.

Should the own buyRequest data have effect on product attributes or options, an observer on the event catalog_product_type_prepare_{$processMode}_options is a good choice, where $processMode is the validation mode and can be „full“ or„lite“. The „full“ mode is used when a product is regularly added to the cart and validates if all required options are set and the whole configuration is valid. In the „lite“ mode only options contained in the request are validated, it is used when adding a product to the wishlist, but also possible when creating an order from the backend. To process the data in any case you can register the observer for both events. Should there be validation you should differentiate the events of course.

The events are triggered in Mage_Catalog_Model_Product_Type_Abstract::_prepareOptions() and the following parameters are available:

transport : Transport object for all custom options (but no other options, for example bundle 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 .

: Transport object for all custom options (but no other options, for example bundle options), so you can change tehem in the observer. is an array in the form . Attention, transport itself is a object, not an instance of , as you might expect. So there are no getter and setter methods for . buy_request : The buyRequest object, you can read it here and still modify it as well.

: The buyRequest object, you can read it here and still modify it as well. product : The product that will be converted to a quote item later on. Here you can manipulate attributes or add them dynamically. But you still need to consider them in the conversion process. The event use for this, sales_quote_product_add_after , is triggered later only.

The diagram below shows, which methods process the buyRequest object when a product is added to the cart. Besides the events shown here, there are numerous other possibilities to access it in own extensions. As said before, the buyRequest is saved in quote item and order item like a custom option. For instance, the aforementioned article Umsetzung von flexiblen Preisen uses the event catalog_product_get_final_price to manipulate the price calculation and accesses the buyRequest option through the product.

Workflow: This is how the buyRequest object is processed during add to cart.