Programmatically Setting a Magento Item’s Price When Adding It to Cart

,

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!

11 thoughts on “Programmatically Setting a Magento Item’s Price When Adding It to Cart

  1. John

    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?

    Reply
  2. Naveen

    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 ??

    Reply
    1. Ben

      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.

      Reply
    1. Ben

      The above is called from a custom module/extension–i.e. from either the controller or model of the custom extension.

      Reply
    1. Ben

      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….

      Reply
  3. Guicara

    « 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

    Reply
  4. nikhil

    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???

    Reply
    1. Ben Gribaudo Post author

      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 and Mage_Core_Model_App::DISTRO_STORE_ID are constants defined in Magento’s source so you don’t need to create them.

      Reply

Leave a Reply to Ben Cancel reply

Your email address will not be published. Required fields are marked *