Im trying to show each price for custom option in cart-page and checkout-page.
so I have changed this file: app/code/core/Mage/Catalog/Helper/Product/Configuration.php
here at line 75
$options[] = array(
'label' => $option->getTitle(),
'value' => $group->getFormattedOptionValue($itemOption->getValue()),
'print_value' => $group->getPrintableOptionValue($itemOption->getValue()),
'option_id' => $option->getId(),
'option_type' => $option->getType(),
'custom_view' => $group->isCustomizedView(),
//##my changing
'my_price' => $option->getPrice()
);
but this works only with fields, not works when my custom option was a select-box or in radio-buttons.
can someone help, Thanks!
Open up your template file
app/design/frontend/default/theme/template/checkout/cart/item/default.phtml
Find the foreach loop:
<?php foreach ($_options as $_option) : ?>
Within that foreach loop, add this code:
<?php
$optionId = $_option['option_id'];
$product = $_item->getProduct();
$option = $product->getOptionById($optionId);
$itemOption = $_item->getOptionByCode('option_' . $option->getId());
$price = false;
foreach ($option->getValues() as $values) {
if ($values->getId() == $itemOption['value']) {
$price = $values->price;
}
}
if ($price !== false) {
echo Mage::helper('core')->currency($price);
}
?>
Not sure if you've solved your problem yet, but for reference here's what I did..
The custom option prices are only available from the product object, not from the item object (which is what's readily available from the cart/item/default.phtml template). You'll have to find the product id from the item ($_item->getProductId()) then load this product. From there you'll want to load the product options, iterate through the custom option select values (in my case) and pull out the price when the option value ids match from the product and item objects ( http://subesh.com.np/2009/12/custom-options-product-magento/ for more help ).
Hope this helps you get on your way :)
Related
I use the following script (inside a controller - action for now) for duplicating a product programatically.
public function indexAction()
{
$data = $this->getRequest()->getParams();
$product = Mage::getModel('catalog/product');
$_product = $product->loadByAttribute('sku',$data['prod_sku']);
$clone = $_product->duplicate();
$clone->setSku($data['new_sku']);
$clone->setUrlKey('foo-bar-1');
$qty = 99;
$is_in_stock = 1;
$stockArray = array(
'use_config_manage_stock' => 0,
'manage_stock' => 1,
'qty' => $qty,
'is_in_stock' => $is_in_stock,
);
$storeid=0; // your store id 0 is for default store id
Mage::getModel('catalog/product_status')->updateProductStatus($clone->getId(), $storeid, Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
$clone->setWebsiteIds(array(Mage::app()->getStore(true)->getWebsite()->getId()));
try{
$clone->getResource()->save($clone);
$stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($clone->getId());
foreach($stockArray as $key => $val){
$stockItem->setData($key, $val);
}
$stockItem->save();
} catch(Exception $e){
Mage::log($e->getMessage());
}
echo "new product ID is ".$clone->getId();
}
This works well and the product gets duplicated with supplied SKU and overwritten prices from a form.
I can see the product in product grid in admin panel.
Visibility is set to Catalog, Search
Product is in stock
Enabled and tagged to correct category and website.
Most probably, you can not see product on frontend, because it is not available in needed website. Provided code can be executed correctly only in admin area (in frontend controller "Warning: Invalid argument supplied for foreach() in app/code/core/Mage/Eav/Model/Entity/Abstract.php on line 1180" will be generated), so code: Mage::app()->getStore(true)->getWebsite()->getId() returned 0, that can not be correct website for frontend.
You should replace line:
$clone->setWebsiteIds(array(Mage::app()->getStore(true)->getWebsite()->getId()));
with
$clone->setWebsiteIds($_product->getWebsiteIds());
I have a custom attribute for the products, and lets say I have 3-4 products that have the same value on that attribute. So, now I want to load these 3 products and store them in an array. Here's what I do:
$all_products = array();
$count = 0;
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToSelect('ordernumber');
foreach($collection as $product)
{
$all_products[count] = array ('sku' => $product->getSku(), 'qty' => $this->getRequest()->get('qty'), 'size' => $product->getSize());
$count++;
}
return $all_products;
Note: ordernumber HAS a value, I just get it from another place.
Anyway, when I run it - I have no values. When I debug - the debugger terminates at $products[count] = ....
I tried loading a single product just by the custom attribute - Mage::...->loadByAttribute('ordernumber', $ordernumber); and it worked fine.
So, my guess is that I am not doing something correctly with the collection manipulation, or with the array, although, I saw some examples where I got the idea from.
What am I doing wrong?
Try it like this:
$all_products = array();
$count = 0;
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToSelect('ordernumber');
//add a filter if needed - uncomment the next 2 lines and adjust the value or $ordernumber
//$ordernumber = '123';
//$addAttributeToFilter('ordernumber', $ordernumber)
foreach($collection as $product)
{
$all_products[$count] = array ('sku' => $product->getSku(), 'qty' => $this->getRequest()->get('qty'), 'size' => $product->getSize());
$count++;
}
return $all_products;
I've been working on my first magento deploy. Got a pretty customized theme built up... tackling some of the non-standard customizations now:
One of my primary product types is an office chair which I have set up as a bundled product. There are many options available for this product type (about 100 fabric options, arm style, lumbar, headrest etc) and I need to be able to show an image for each of these on the catalog/product/view page.
Being a bundled product (and I'll refrain from any discussion about whether this was the right product type - we went around in circles debating between a configurable and a bundled) - each product is assembled from a number of simple products (as options). These simple products can have images uploaded to them, and I've done so. I now want to retrieve the urls to those from the media folder...
After some hunting - these seem to be the essential elements:
theme/../template/catalog/product/view/options.phtml
<?php $_options = Mage::helper('core')->decorateArray($this->getOptions()) ?>
<dl>
<?php foreach($_options as $_option): ?>
<?php echo $this->getOptionHtml($_option) ?>
<?php endforeach; ?>
</dl>
theme/../template/bundle/catalog/product/view/type/bundle/option/select.phtml
<?php /* #var $this Mage_Bundle_Block_Catalog_Product_View_Type_Bundle_Option_Select */ ?>
<?php $_option = $this->getOption(); ?>
<?php $_selections = $_option->getSelections(); ?>
I found finally found getSelections() in:
class Mage_Bundle_Model_Resource_Price_Index extends Mage_Core_Model_Resource_Db_Abstract
{ ...
/**
* Retrieve bundle options with selections and prices by product
*
* #param int $productId
* #return array
*/
public function getSelections($productId)
{
$options = array();
$read = $this->_getReadAdapter();
$select = $read->select()
->from(
array('option_table' => $this->getTable('bundle/option')),
array('option_id', 'required', 'type')
)
->join(
array('selection_table' => $this->getTable('bundle/selection')),
'selection_table.option_id=option_table.option_id',
array('selection_id', 'product_id', 'selection_price_type',
'selection_price_value', 'selection_qty', 'selection_can_change_qty')
)
->join(
array('e' => $this->getTable('catalog/product')),
'e.entity_id=selection_table.product_id AND e.required_options=0',
array()
)
->where('option_table.parent_id=:product_id');
$query = $read->query($select, array('product_id' => $productId));
while ($row = $query->fetch()) {
if (!isset($options[$row['option_id']])) {
$options[$row['option_id']] = array(
'option_id' => $row['option_id'],
'required' => $row['required'],
'type' => $row['type'],
'selections' => array()
);
}
$options[$row['option_id']]['selections'][$row['selection_id']] = array(
'selection_id' => $row['selection_id'],
'product_id' => $row['product_id'],
'price_type' => $row['selection_price_type'],
'price_value' => $row['selection_price_value'],
'qty' => $row['selection_qty'],
'can_change_qty' => $row['selection_can_change_qty']
);
}
return $options;
}
so we get back an array with selection_id, product_id, price_type etc... but nothing referring to the image url for that selection...
Given that:
class Mage_Catalog_Helper_Product extends Mage_Core_Helper_Url
{ ...
public function getImageUrl($product)
{
$url = false;
if (!$product->getImage()) {
$url = Mage::getDesign()->getSkinUrl('images/no_image.jpg');
}
elseif ($attribute = $product->getResource()->getAttribute('image')) {
$url = $attribute->getFrontend()->getUrl($product);
}
return $url;
}
I'm trying to build a js object with refs to each selection's image url kind of like so in theme/../template/bundle/catalog/product/view/type/bundle/option/select.phtml
var option_set_<?php echo $_option->getId() ?> = {};
<?php foreach ($_selections as $_selection): ?>
option_set_<?php echo $_option->getId() ?>._<?php echo $_selection->getSelectionId() ?> = '<?php echo $_selection->getImageUrl(); ?>';
<?php endforeach; ?>
But $_selection obviously isn't typed correctly because it just bounces me to the placeholder graphic.
Assuming these options can be typed as a Product (or somehow obtain the simple product from the selection_id, it seems like something like that can work. I'm not sure if that's exactly how I want to manage this feature, but if I can just get a stack of urls - then I'll be in business
Weirdly, the interwebs is basically silent on this subject. Apparently nobody needs to show images for their product options (or, rather, the only solutions are paid extensions - which will be a last resort).
How I can go about figuring this out?
Jesus tapdancing christ. Could Mage be any more complicated?
Update
Got this to work as such:
<?php echo $this->helper('catalog/image')->init($_selection, 'small_image')->resize(40,40); ?>
The answer I selected will also work fine, if anybody needs this fix.
The product_id in the $_selections represents the id of the selected simple product.
So all to do is:
take the product_id of the $_selections,
load the product by this product_id
give the resulting product object to Mage_Catalog_Helper_Product::getImageUrl.
I am working in a scenario I want to send Product selected Custom Option SKU in cart page have founded the array which is sent to cart in case of custom options.
Here is a Function called getProductOptions() in which Product Option Array is created and sent to cart. At this point, I want to send selected Custom Option SKU field to cart.
I have the following code:
public function getProductOptions()
{
$options = array();
if ($optionIds = $this->getItem()->getOptionByCode('option_ids')) {
$options = array();
foreach (explode(',', $optionIds->getValue()) as $optionId) {
if ($option = $this->getProduct()->getOptionById($optionId)) {
//echo $optionId;
echo "hhhhhhhhhhhhh";
//print_r( $option->getId());
//echo Mage::getModel('catalog/product')->getOptionSku($option);
//die();
//print_r( $option->getOptionSku());
//echo Mage_Catalog_Model_Product_Option_Type_Select::getOptionSku());
$quoteItemOption = $this->getItem()->getOptionByCode('option_' . $option->getId());
//echo $option->getQuoteItemOption($quoteItemOption);
$group = $option->groupFactory($option->getType())
->setOption($option)
->setQuoteItemOption($quoteItemOption);
$options[] = array(
'label' => $option->getTitle(),
'value' => $group->getFormattedOptionValue($quoteItemOption->getValue()),
'print_value' => $group->getPrintableOptionValue($quoteItemOption->getValue()),
'option_id' => $option->getId(),
'option_type' => $option->getType(),
'custom_view' => $group->isCustomizedView(),
'option_sku'=>//What should i call here to send Selected option SKU to this Array
);
}
}
if ($addOptions = $this->getItem()->getOptionByCode('additional_options')) {
$options = array_merge($options, unserialize($addOptions->getValue()));
}
}
return $options;
}
It looks like the bit you're missing is
'option_sku' => $this->getItem()->getSku()
Don't modify the block itself, just change the rendered template to add a for this field. Grab the data from the $_item variable, and echo it out to the user. That should require no modifications of the block.
I want to write a controller that finds the different options for a given product (eg. Large, Medium, Small, Red, Blue etc...).
Can anyone show me the code I would write into my controller?
Additional details
I'm getting closer, but I still can't figure it out. Here's the code I wrote in my controller
$db = Mage::getModel('catalog/product')->load($productId);
print_r($db->getOptions()); // returns an empty array
echo $db->getHasOptions(); // echos 1
But when I do the print_r() on the second line, the getOptions returns an empty array. The third line echo's the value 1, which means there SHOULD BE options.
Additional Details
I tried clockworkgeek's solution of $db->getProductOptions(), that returned nothing. I tried $db->getProductOptionsCollection(), and got this output
Array
(
[totalRecords] => 0
[items] => Array
(
)
)
What's wrong with my code such that it is not returning the allowable product options?
Instead of getOptions() please try getCustomOptions() or getProductOptionsCollection() or getProductOptionsCollection()->load().
Edit
I tried this on a product I knew had options.
<?php
require 'app/Mage.php';
Mage::app();
$product = Mage::getModel('catalog/product')->load($productId);
foreach ($product->getProductOptions() as $option) {
print_r($option->debug());
}
And got something like this:
Array
(
[option_id] => 37
[product_id] => 8
[type] => multidate
[is_require] => 1
[sku] =>
[image_size_x] => 0
[image_size_y] => 0
[sort_order] => 1
[default_title] => Dates
[title] => Dates
)
However, getOptions() also worked for me so I don't know what's going on.
Post-edit
The confusion was one of semantics. A simple product can have "custom options", they allow creation of a few form fields which are recorded as part of the order. A configurable product uses "associated products" to create a form with conditional fields.
For example you might be selling socks that are large-green, small-green or large-blue - but no small-blue ones. With a simple product you would have a field for large/small and a field for blue/green - which allows the customer to select small-blue and that is wrong.
So to find the component parts of a configurable you might do something like this:
if ($product->isConfigurable()) {
$configurable = $product->getTypeInstance();
$childProducts = $product->getUsedProducts($product);
foreach ($childProducts as $child) {
// You have a $child now
}
}
To find the equivalent of getOptions() you need this:
if ($product->isConfigurable()) {
$configurable = $product->getTypeInstance();
$attributes = $configurable->getConfigurableAttributes($product);
// $attributes is a Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Type_Configurable_Attribute_Collection
foreach ($attributes as $attribute) {
// $attribute is a Mage_Catalog_Model_Product_Type_Configurable_Attribute
print $attribute->getLabel();
}
}
Mage_Catalog_Model_Product_Type_Configurable_Attribute doesn't have much to reveal about itself.
The above solution is perfect and I solved my problem using it. I was
trying to display the colors on the list. Here is my solution
if ($_product->isConfigurable()) {
$configurable = $_product->getTypeInstance();
$childProducts = $configurable->getUsedProducts($_product);
foreach ($childProducts as $child) {
$sku = $child->getSku();
$skuarr = explode('-',$sku);
$col = trim($skuarr[1]);
?>
<span class="colorbar" style="background:<?php echo $col?>;" title="<?php echo $col?>"> </span>
}
}