You can access them in sales_flat_order_item
, in the column you originally believed them to be in.
The data in product_options
is serialized, so if you unserialize it you end up with something like:
array(6) {
["info_buyRequest"]=>
array(5) {
["uenc"]=>
string(56) "aHR0cDovLzEyNy4wLjAuMS90ZXN0LWNhdGVnb3J5L3Rlc3QuaHRtbA,,"
["product"]=>
string(1) "1"
["related_product"]=>
string(0) ""
["options"]=>
array(2) {
[2]=>
string(1) "2"
[1]=>
array(1) {
[0]=>
string(1) "1"
}
}
["qty"]=>
string(1) "1"
}
["options"]=>
array(2) {
[0]=>
array(7) {
["label"]=>
string(25) "Custom Option for Product"
["value"]=>
string(16) "Custom Option 1 "
["print_value"]=>
string(16) "Custom Option 1 "
["option_id"]=>
string(1) "2"
["option_type"]=>
string(9) "drop_down"
["option_value"]=>
string(1) "2"
["custom_view"]=>
bool(false)
}
[1]=>
array(7) {
["label"]=>
string(27) "Custom Option for Product 2"
["value"]=>
string(15) "Custom Option 3"
["print_value"]=>
string(15) "Custom Option 3"
["option_id"]=>
string(1) "1"
["option_type"]=>
string(8) "checkbox"
["option_value"]=>
string(1) "1"
["custom_view"]=>
bool(false)
}
}
["giftcard_lifetime"]=>
NULL
["giftcard_is_redeemable"]=>
int(0)
["giftcard_email_template"]=>
NULL
["giftcard_type"]=>
NULL
}
As you can see, if you grabbed options
from that array, you would be able to loop through the options on the product, including their ID's.
You can get the information for a specific option a few ways, direct SQL is the least advisable, however it does give you an idea of how the options are stored within Magento.
Direct SQL to pull options and most of their information:
SELECT
_cpo.product_id,
_cpo.type,
_cpo.is_require,
_cpo.sku AS catalog_product_option_sku,
_cpo.file_extension,
_cpo.image_size_x,
_cpo.image_size_y,
_cpo.sort_order AS catalog_product_option_sort_order,
_cpop.price,
_cpop.price_type,
_cpot.title,
_cpotp.price,
_cpotp.price_type,
_cpott.title,
_cpotv.sku
FROM catalog_product_option _cpo
LEFT JOIN catalog_product_option_price _cpop ON (_cpop.option_id = _cpo.option_id )
LEFT JOIN catalog_product_option_title _cpot ON (_cpot.option_id = _cpo.option_id )
LEFT JOIN catalog_product_option_type_value _cpotv ON (_cpotv.option_id = _cpo.option_id )
LEFT JOIN catalog_product_option_type_price _cpotp ON (_cpotp.option_type_id = _cpotv.option_type_id )
LEFT JOIN catalog_product_option_type_title _cpott ON (_cpott.option_type_id = _cpotv.option_type_id )
WHERE _cpo.option_id = **OPTION_ID**
The above should give you an idea of the structure of the options in Magento.
I would suggest getting these options within Magento though, which can be accomplished by doing something similar to:
$order = Mage::getModel('sales/order')->load(**ORDER_ID**);
$items = $order->getAllVisibleItems();
foreach ($items as $item):
$options = $item->getProductOptions();
foreach ($options as $option):
//$option contains the option information for item
endforeach;
endforeach;
$option will contain something similar to:
array(5) {
["uenc"]=>
string(56) "aHR0cDovLzEyNy4wLjAuMS90ZXN0LWNhdGVnb3J5L3Rlc3QuaHRtbA,,"
["product"]=>
string(1) "1"
["related_product"]=>
string(0) ""
["options"]=>
array(2) {
[2]=>
string(1) "2"
[1]=>
array(1) {
[0]=>
string(1) "1"
}
}
["qty"]=>
string(1) "1"
}
array(2) {
[0]=>
array(7) {
["label"]=>
string(25) "Custom Option for Product"
["value"]=>
string(16) "Custom Option 1 "
["print_value"]=>
string(16) "Custom Option 1 "
["option_id"]=>
string(1) "2"
["option_type"]=>
string(9) "drop_down"
["option_value"]=>
string(1) "2"
["custom_view"]=>
bool(false)
}
[1]=>
array(7) {
["label"]=>
string(27) "Custom Option for Product 2"
["value"]=>
string(15) "Custom Option 3"
["print_value"]=>
string(15) "Custom Option 3"
["option_id"]=>
string(1) "1"
["option_type"]=>
string(8) "checkbox"
["option_value"]=>
string(1) "1"
["custom_view"]=>
bool(false)
}
}
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);
Best Answer
I've done something similar but not quite. Maybe it helps.
my task was to have a checkbox on each product page called
gift wrap
. If checked then, the sales team would know to wrap the product (they only had a single wrapping option).So I did this in order to be able to port the
wrap
checkbox value from product to quote to order. (I could have used a custom option but it's ugly to add one option to a few thousand products).I had an observer for the event
sales_convert_quote_item_to_order_item
.I've rewritten the
Mage_Catalog_Helper_Product_Configuration::getCustomOptions
helper in order to tell Magento that my option is important and should treat it separatelyFor the same reason I've rewritten
Mage_Sales_Block_Order_Item_Renderer_Default::getItemOptions
so my option will be displayed in the cartand the admin name column for the order items grid:
[EDIT]
It seams I missed something. I only implemented the option to add a giftwrap once the product is in the cart.
But I think you can use the same code in an event prior or after adding the item to the cart.
That's it. I hope you can get something useful out of it.