I am writing a custom Magento 1.5.0.1 one page checkout for my site following the instructions on this site:
http://inchoo.net/ecommerce/magento/magentos-onepage-checkout-in-a-nutshell/
In summary, I am calling these functions in order:
$checkout = Mage::getSingleton(‘checkout/type_onepage’);
$checkout->saveCheckoutMethod(‘guest’);
$checkout->saveBilling($billingAddress, false);
$checkout->saveShipping($shippingAddress, false);
$checkout->saveShippingMethod(‘flatrate_flatrate’);
$checkout->savePayment(array(‘method’=>’checkmo’));
// Extra part not on the site but saw it in the original magento onpage checkout controller
$checkout->getQuote()->getPayment()->importData(array(‘method’=>’checkmo’));
//
$checkout->saveOrder();
// Extra part not on the site but saw it in the original magento onpage checkout controller
$checkout->getQuote()->save();
//
The problem is that when the code is first run, the shipping method is not being set, I get a error saying that the shipping method was not set. However, just refreshing the page makes the order go through.
One solution was that right after setting the shipping method with saveShippingMethod, checking if it was set with:
Mage::getSingleton('checkout/type_onepage')->getQuote()->getShippingAddress()->getShippingMethod();
Which 100% of the time it is not, then redirecting it back onto the same page, which on the 2nd run the shipping method is set...
this seems to be such a stupid magento bug! any ideas on how to fix it with this redirection (i.e. page refresh)?
Maybe it is me not being extremely expert about magento, but I'm pretty sure you have to use setShippingMethod($method) instead of saveShippingMethod($method) when creating an order, you can check more here.
Related
I have a problem with redirectReferrer()
When I add a product in cart, I do it with ajax (call : http://wwwww.ww/quickview/product/add).
Until here, everything is ok.
But, if I want to remove product from my cart, the deleteAction() redirect me to http://wwwww.ww/quickview/product/add with the method $this->_redirectReferer(Mage::getUrl('*/*'));
Is it possible to ignore a whole Controller or just an Action in _redirectReferer, without any modification in the deleteAction() ??
I tried this Mage::getSingleton('customer/session')->setNoReferer(true);, but it not seems to work..
Thank you.
PS: Magento CE 1.9.3
I discovered that is inside my controller (and action), that the referrer is setted ...
I return in JSON:
$this->getLayout()->createBlock('checkout/cart_sidebar')->setTemplate('checkout/cart/sidebar.phtml')->toHtml();
I think this is this part who cause my issue..
In Magento EE I need to redirect customers depending Origin country, browser lang and previous preference set in a cookie.
I have huge problems making it work with FPC.
I tryed to observe the controller_action_predispatch event, but FPC somehow caches my redirect instruction and customer is not redirected.
I then tried another solution: extending the run() method in Mage_Core_Model_App in order to perform operations before FPC starts to work.
Unfortunately, I don't know why, inside this method you can't access Mage::getModel(), Mage::helper(), Mage::getConfig() ecc
Can you help me please?
Thank you
I've recently been through exactly the same pain. You are on the right track;
controller_action_predispatch
Is the correct event to observe, and you can use this quite happily if you are redirecting to a category or product page with FPC enabled. The problem is the home page - which is a cms page. The cms page cache does not fire controller_action_predispatch. I got around this by adding this to my observer;
public function switchUser($event)
{
// CMS page bug, disable FPC to still use observer
$action = $event->getEvent()->getControllerAction();
if($action instanceof Mage_Cms_IndexController) {
$cache = Mage::app()->getCacheInstance();
$cache->banUse('full_page');
}
// do the rest of your code here
}
The blocks within the cms page will still cache so the page is still nippy, though obviously not as fast as it would be with full FPC enabled. Its a sound trade off in my opinion.
I need to know one thing regarding magento add-to-cart feature. On the product page there is a form which submits your command if you want to buy that product. I need to know the php page that's receiving and parsing the submitted data.
The action attribute of the form has a strange URL so I can't really see which php page is doing the job. (ie http://www.mysite.com/index.php/checkout/cart/add/uenc/aHR0cDovL3d3dy5wdWxzZWlyYXZpcnR1YWwuY29tLmJyL3Y4L25vdmEvaW5kZXgucGhwL3B1bHNlaXJhLWlkZW50aWZpY2FjYW8vcHVsc2VpcmFzLXBlcnNvbmFsaXphY2FvLWVtLXByZXRvL3B1bHNlaXJhcy1kZS1pZGVudGlmaWNhY2FjYW8tZW0tdHl2ZWsuaHRtbA,,/product/12/ )
The above URL hit:
app\code\core\Mage\Checkout\controllers\CartController.php
And function name is: public function addAction(), around 170 line
Hope it will help!
Take a look at the code inside:
app/code/core/Mage/Checkout/controllers/CartController.php
I have an observer watching the event sales_quote_item_set_product. In it, i am checking some conditions to make sure the item is still available. If it is not, i run this code:
Mage::helper('checkout/cart')->getCart()->removeItem($item->getId())->save();
Mage::getSingleton('message/session')->addError($item->getName() . ' is no longer available.');
The problem I'm having is if an item becomes unavailable and a guest is on a product view page, the cart says the item is in the cart, but the total for the cart is updated to reflect the product being removed. Also the error message is not displayed. If you go to another page or refresh the product view page the error message will display and the number of items in the cart will be correct.
So my thought is i need to run this code earlier in the execution cycle, but i have no idea what event i should be observing, or if i shouldn't be using an observer at all. I tried using sales_quote_load_after, but that caused a recursion error somehow. Can anyone tell me when/where i should run this code?
Another wild thought is could it be because i'm using database sessions instead of the file system?
The problem was that the error was being added after the messages block was rendered. I fixed it by adding a redirect to the cart page after the error was added.
$request = Mage::app()->getRequest();
if($request->getModuleName() != 'checkout' && $request->getControllerName() != 'cart' && $request->getActionName() != 'index') {
Mage::app()->getResponse()->setRedirect(Mage::getModel('core/url')->getUrl('checkout/cart/index'))
->sendResponse();
exit;
}
You didn't mention it, but this sounds like you're running code during an AJAX request. When you say
Mage::getSingleton('message/session')->addError($item->getName() . ' is no longer available.');
You're adding an error to Magento's session object. Every time a Magento page renders, it checks the session object for errors, and displays them all. This allows multiple developers to add multiple errors to the session, redirect Magento back to the original form.
This doesn't work during an ajax request, because (typically) the rendering process is skipped in lieu of a JSON object or simple, errorless HTML chunk being rendered (leaving the errors in the session).
Knowing what the full request cycle looks like (what's ajax, what's not) would help someone come up with a more concrete answer to your question.
I have not been able to figure this out for the life of me. I wanted to show the order review step(final step before processing the order) right away on the one page checkout in Magento. Any suggestions? Thanks all.
If you look at the bottom of onepage.phtml, you will see
<?php if($this->getActiveStep()): ?>
accordion.openSection('opc-<?php echo $this->getActiveStep() ?>');
<?php endif; ?>
which calls Mage_Checkout_Block_Onepage::getActiveStep() to determine which step to show first. You can override this by creating your own onepage.phtml in your theme and changing the block above to be:
accordion.openSection('opc-review');
However, the openSection function only executes if the target element ('opc-review') in this case, has a class of "allow" which is set by Magento's AJAX once the previous checkout steps are completed. You could manually add the "allow" class using prototype, but once you get the step to display, you'll see that it is empty, since the AJAX hasn't populated the content based on the previous steps as the previous steps haven't happened yet!
So... You could create a new block based on Cart.php and insert that into onepage.phtml using $this->getChildHtml('block-id') and the layout xml. You would need to insert it inside the ol#checkoutSteps as an li#opc-summary.section allow or something like that, and make the js change above to be accordion.openSection('opc-summary');
That's the best I can do at the moment for you. HTH,
JD