Using code, how would we give a Magento item a one-time special price then add that item to the shopping cart?
The process is simple:
- Create an instance of the Magento product,
- give it a custom price by calling setSpecialPrice,
- then save the product instance (store must be running as the admin store).
- Next, grab the Magento cart object (a singleton),
- add the product instance to the cart,
- then save the cart.
In order to save the product after giving it a special price, the store must be running as what Magento calls the “admin store” (confusing terminology—think of it as meaning “running in admin mode”). If save is called while the store is running in its default mode (in Magento-speak, “running as the distro store”), the following error will occur:
Warning: Invalid argument supplied for foreach() in app\code\core\Mage\Eav\Model\Entity\Abstract.php on line 1068 #0 app\code\core\Mage\Eav\Model\Entity\Abstract.php(1068): mageCoreErrorHandler(2, 'Invalid argumen...', 'C:\Program File...', 1068, Array) #1 app\code\core\Mage\Eav\Model\Entity\Abstract.php(1012): Mage_Eav_Model_Entity_Abstract->_collectSaveData(Object(Mage_Catalog_Model_Product)) #2 app\code\core\Mage\Core\Model\Abstract.php(318): Mage_Eav_Model_Entity_Abstract->save(Object(Mage_Catalog_Model_Product)) #3 app\code\local\BenGribaudo\MyModule\controllers\IndexController.php(26): Mage_Core_Model_Abstract->save() #4 app\code\local\BenGribaudo\MyModule\controllers\IndexController.php(8): BenGribaudo_MyModule_IndexController->processAdd() #5 app\code\core\Mage\Core\Controller\Varien\Action.php(418): BenGribaudo_MyModule_IndexController->indexAction() #6 app\code\core\Mage\Core\Controller\Varien\Router\Standard.php(253): Mage_Core_Controller_Varien_Action->dispatch('index') #7 app\code\core\Mage\Core\Controller\Varien\Front.php(176): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http)) #8 app\code\core\Mage\Core\Model\App.php(340): Mage_Core_Controller_Varien_Front->dispatch() #9 app\Mage.php(627): Mage_Core_Model_App->run(Array) #10 index.php(80): Mage::run('', 'store') #11 {main}
After saving the product instance, be sure to switch the store back to normal (a.k.a. distro) mode before adding the product to the cart. Otherwise, the item just added to the cart will disappear out of the cart. (Most articles I’ve seen on this topic leave out this important step.)
Code Example
$product = Mage::getModel('catalog/product'); $product->load($productId); $product->setSpecialPrice($price); Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID); $product->save(); Mage::app()->setCurrentStore(Mage_Core_Model_App::DISTRO_STORE_ID); $cart = Mage::getSingleton('checkout/cart'); $cart->addProduct($product, array('qty' => $quantity)); $cart->save();
Update (7/22/14): I’ve not had time to test this but it sounds like a more robust way to switch store contexts is to store the current store ID ($storeId = Mage::app()->getStore()->getId();
) before changing to the admin store and then replacing the constant Mage_Core_Model_App::DISTRO_STORE_ID
on line 6 (above) with the saved store ID (Mage::app()->setCurrentStore($storeId);
). Thanks goes to a Magento Stack Exchange answer for this suggestion!
I’m trying to do this but for some reason the cost of the item is always the original when viewing the cart.
Even when I’ve sorted that am I right in thinking that you are changing the actual cost of the item I the system? Does this mean that if user 1 adds it to their cart at their special price, if user 2 then adds it at their special price then user 1 will have user 2’s price?
Thanks
John?
Hi ,
have an doubt its not about the above topic.
i have a product sets with custom options in magento and i have pulled the lowest price of the custom option and displayed. and now comes my doubt.
1. Products price to be 0(zero intially).
2. Must add the lowest price while adding it to cart and checking it out.
can this be done ??
Hi,
This doesn’t work for me. Can you tell me where to write this code exactly?
In a custom controller or model–something you’ll need to build. When the appropriate controller action is called, it will trigger the product’s addition to the cart.
Hi,
From where are you calling this function?
Is it not necessary to create any event observer?
The above is called from a custom module/extension–i.e. from either the controller or model of the custom extension.
I am a beginner to Magento.
Can you please explain as to how to set product price for a Group in Magento programatically. Is setGroupPrice a valid method? If yes, then how to use it?
Good question! I’m not sure of the answer off the top of my head. You might try posting the question on Magento’s boards or StackOverflow….
« When the appropriate controller action is called, it will trigger the product’s addition to the cart. »
Look at the event : checkout_cart_product_add_after
hello sir i want to know about the meanings of these lines
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
$product->save();
Mage::app()->setCurrentStore(Mage_Core_Model_App::DISTRO_STORE_ID)
what is ADMIN_STORE_ID and DISTRO_STORE_ID??
and how can i create these???
You could think of those lines as switching execution into an admin context, running the save method then switching back to regular store mode.
Mage_Core_Model_App::ADMIN_STORE_ID
andMage_Core_Model_App::DISTRO_STORE_ID
are constants defined in Magento’s source so you don’t need to create them.