1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27:
28: class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action
29: {
30: protected $_sectionUpdateFunctions = array(
31: 'payment-method' => '_getPaymentMethodsHtml',
32: 'shipping-method' => '_getShippingMethodsHtml',
33: 'review' => '_getReviewHtml',
34: );
35:
36:
37: protected $_order;
38:
39: 40: 41:
42: public function preDispatch()
43: {
44: parent::preDispatch();
45: $this->_preDispatchValidateCustomer();
46:
47: $checkoutSessionQuote = Mage::getSingleton('checkout/session')->getQuote();
48: if ($checkoutSessionQuote->getIsMultiShipping()) {
49: $checkoutSessionQuote->setIsMultiShipping(false);
50: $checkoutSessionQuote->removeAllAddresses();
51: }
52:
53: if(!$this->_canShowForUnregisteredUsers()){
54: $this->norouteAction();
55: $this->setFlag('',self::FLAG_NO_DISPATCH,true);
56: return;
57: }
58:
59: return $this;
60: }
61:
62: protected function _ajaxRedirectResponse()
63: {
64: $this->getResponse()
65: ->setHeader('HTTP/1.1', '403 Session Expired')
66: ->setHeader('Login-Required', 'true')
67: ->sendResponse();
68: return $this;
69: }
70:
71: 72: 73: 74: 75:
76: protected function _expireAjax()
77: {
78: if (!$this->getOnepage()->getQuote()->hasItems()
79: || $this->getOnepage()->getQuote()->getHasError()
80: || $this->getOnepage()->getQuote()->getIsMultiShipping()) {
81: $this->_ajaxRedirectResponse();
82: return true;
83: }
84: $action = $this->getRequest()->getActionName();
85: if (Mage::getSingleton('checkout/session')->getCartWasUpdated(true)
86: && !in_array($action, array('index', 'progress'))) {
87: $this->_ajaxRedirectResponse();
88: return true;
89: }
90:
91: return false;
92: }
93:
94: 95: 96: 97: 98:
99: protected function _getShippingMethodsHtml()
100: {
101: $layout = $this->getLayout();
102: $update = $layout->getUpdate();
103: $update->load('checkout_onepage_shippingmethod');
104: $layout->generateXml();
105: $layout->generateBlocks();
106: $output = $layout->getOutput();
107: return $output;
108: }
109:
110: 111: 112: 113: 114:
115: protected function _getPaymentMethodsHtml()
116: {
117: $layout = $this->getLayout();
118: $update = $layout->getUpdate();
119: $update->load('checkout_onepage_paymentmethod');
120: $layout->generateXml();
121: $layout->generateBlocks();
122: $output = $layout->getOutput();
123: return $output;
124: }
125:
126: protected function _getAdditionalHtml()
127: {
128: $layout = $this->getLayout();
129: $update = $layout->getUpdate();
130: $update->load('checkout_onepage_additional');
131: $layout->generateXml();
132: $layout->generateBlocks();
133: $output = $layout->getOutput();
134: Mage::getSingleton('core/translate_inline')->processResponseBody($output);
135: return $output;
136: }
137:
138: 139: 140: 141: 142:
143: protected function _getReviewHtml()
144: {
145: return $this->getLayout()->getBlock('root')->toHtml();
146: }
147:
148: 149: 150: 151: 152:
153: public function getOnepage()
154: {
155: return Mage::getSingleton('checkout/type_onepage');
156: }
157:
158: 159: 160:
161: public function indexAction()
162: {
163: if (!Mage::helper('checkout')->canOnepageCheckout()) {
164: Mage::getSingleton('checkout/session')->addError($this->__('The onepage checkout is disabled.'));
165: $this->_redirect('checkout/cart');
166: return;
167: }
168: $quote = $this->getOnepage()->getQuote();
169: if (!$quote->hasItems() || $quote->getHasError()) {
170: $this->_redirect('checkout/cart');
171: return;
172: }
173: if (!$quote->validateMinimumAmount()) {
174: $error = Mage::getStoreConfig('sales/minimum_order/error_message') ?
175: Mage::getStoreConfig('sales/minimum_order/error_message') :
176: Mage::helper('checkout')->__('Subtotal must exceed minimum order amount');
177:
178: Mage::getSingleton('checkout/session')->addError($error);
179: $this->_redirect('checkout/cart');
180: return;
181: }
182: Mage::getSingleton('checkout/session')->setCartWasUpdated(false);
183: Mage::getSingleton('customer/session')->setBeforeAuthUrl(Mage::getUrl('*/*/*', array('_secure'=>true)));
184: $this->getOnepage()->initCheckout();
185: $this->loadLayout();
186: $this->_initLayoutMessages('customer/session');
187: $this->getLayout()->getBlock('head')->setTitle($this->__('Checkout'));
188: $this->renderLayout();
189: }
190:
191: 192: 193:
194: public function progressAction()
195: {
196: if ($this->_expireAjax()) {
197: return;
198: }
199: $this->loadLayout(false);
200: $this->renderLayout();
201: }
202:
203: public function shippingMethodAction()
204: {
205: if ($this->_expireAjax()) {
206: return;
207: }
208: $this->loadLayout(false);
209: $this->renderLayout();
210: }
211:
212: public function reviewAction()
213: {
214: if ($this->_expireAjax()) {
215: return;
216: }
217: $this->loadLayout(false);
218: $this->renderLayout();
219: }
220:
221: 222: 223:
224: public function successAction()
225: {
226: $session = $this->getOnepage()->getCheckout();
227: if (!$session->getLastSuccessQuoteId()) {
228: $this->_redirect('checkout/cart');
229: return;
230: }
231:
232: $lastQuoteId = $session->getLastQuoteId();
233: $lastOrderId = $session->getLastOrderId();
234: $lastRecurringProfiles = $session->getLastRecurringProfileIds();
235: if (!$lastQuoteId || (!$lastOrderId && empty($lastRecurringProfiles))) {
236: $this->_redirect('checkout/cart');
237: return;
238: }
239:
240: $session->clear();
241: $this->loadLayout();
242: $this->_initLayoutMessages('checkout/session');
243: Mage::dispatchEvent('checkout_onepage_controller_success_action', array('order_ids' => array($lastOrderId)));
244: $this->renderLayout();
245: }
246:
247: public function failureAction()
248: {
249: $lastQuoteId = $this->getOnepage()->getCheckout()->getLastQuoteId();
250: $lastOrderId = $this->getOnepage()->getCheckout()->getLastOrderId();
251:
252: if (!$lastQuoteId || !$lastOrderId) {
253: $this->_redirect('checkout/cart');
254: return;
255: }
256:
257: $this->loadLayout();
258: $this->renderLayout();
259: }
260:
261:
262: public function getAdditionalAction()
263: {
264: $this->getResponse()->setBody($this->_getAdditionalHtml());
265: }
266:
267: 268: 269:
270: public function getAddressAction()
271: {
272: if ($this->_expireAjax()) {
273: return;
274: }
275: $addressId = $this->getRequest()->getParam('address', false);
276: if ($addressId) {
277: $address = $this->getOnepage()->getAddress($addressId);
278:
279: if (Mage::getSingleton('customer/session')->getCustomer()->getId() == $address->getCustomerId()) {
280: $this->getResponse()->setHeader('Content-type', 'application/x-json');
281: $this->getResponse()->setBody($address->toJson());
282: } else {
283: $this->getResponse()->setHeader('HTTP/1.1','403 Forbidden');
284: }
285: }
286: }
287:
288: 289: 290:
291: public function saveMethodAction()
292: {
293: if ($this->_expireAjax()) {
294: return;
295: }
296: if ($this->getRequest()->isPost()) {
297: $method = $this->getRequest()->getPost('method');
298: $result = $this->getOnepage()->saveCheckoutMethod($method);
299: $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
300: }
301: }
302:
303: 304: 305:
306: public function saveBillingAction()
307: {
308: if ($this->_expireAjax()) {
309: return;
310: }
311: if ($this->getRequest()->isPost()) {
312:
313:
314: $data = $this->getRequest()->getPost('billing', array());
315: $customerAddressId = $this->getRequest()->getPost('billing_address_id', false);
316:
317: if (isset($data['email'])) {
318: $data['email'] = trim($data['email']);
319: }
320: $result = $this->getOnepage()->saveBilling($data, $customerAddressId);
321:
322: if (!isset($result['error'])) {
323:
324: if ($this->getOnepage()->getQuote()->isVirtual()) {
325: $result['goto_section'] = 'payment';
326: $result['update_section'] = array(
327: 'name' => 'payment-method',
328: 'html' => $this->_getPaymentMethodsHtml()
329: );
330: } elseif (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1) {
331: $result['goto_section'] = 'shipping_method';
332: $result['update_section'] = array(
333: 'name' => 'shipping-method',
334: 'html' => $this->_getShippingMethodsHtml()
335: );
336:
337: $result['allow_sections'] = array('shipping');
338: $result['duplicateBillingInfo'] = 'true';
339: } else {
340: $result['goto_section'] = 'shipping';
341: }
342: }
343:
344: $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
345: }
346: }
347:
348: 349: 350:
351: public function saveShippingAction()
352: {
353: if ($this->_expireAjax()) {
354: return;
355: }
356: if ($this->getRequest()->isPost()) {
357: $data = $this->getRequest()->getPost('shipping', array());
358: $customerAddressId = $this->getRequest()->getPost('shipping_address_id', false);
359: $result = $this->getOnepage()->saveShipping($data, $customerAddressId);
360:
361: if (!isset($result['error'])) {
362: $result['goto_section'] = 'shipping_method';
363: $result['update_section'] = array(
364: 'name' => 'shipping-method',
365: 'html' => $this->_getShippingMethodsHtml()
366: );
367: }
368: $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
369: }
370: }
371:
372: 373: 374:
375: public function saveShippingMethodAction()
376: {
377: if ($this->_expireAjax()) {
378: return;
379: }
380: if ($this->getRequest()->isPost()) {
381: $data = $this->getRequest()->getPost('shipping_method', '');
382: $result = $this->getOnepage()->saveShippingMethod($data);
383: 384: 385:
386: if(!$result) {
387: Mage::dispatchEvent('checkout_controller_onepage_save_shipping_method',
388: array('request'=>$this->getRequest(),
389: 'quote'=>$this->getOnepage()->getQuote()));
390: $this->getOnepage()->getQuote()->collectTotals();
391: $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
392:
393: $result['goto_section'] = 'payment';
394: $result['update_section'] = array(
395: 'name' => 'payment-method',
396: 'html' => $this->_getPaymentMethodsHtml()
397: );
398: }
399: $this->getOnepage()->getQuote()->collectTotals()->save();
400: $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
401: }
402: }
403:
404: 405: 406: 407: 408:
409: public function savePaymentAction()
410: {
411: if ($this->_expireAjax()) {
412: return;
413: }
414: try {
415: if (!$this->getRequest()->isPost()) {
416: $this->_ajaxRedirectResponse();
417: return;
418: }
419:
420:
421: $result = array();
422: $data = $this->getRequest()->getPost('payment', array());
423: $result = $this->getOnepage()->savePayment($data);
424:
425:
426: $redirectUrl = $this->getOnepage()->getQuote()->getPayment()->getCheckoutRedirectUrl();
427: if (empty($result['error']) && !$redirectUrl) {
428: $this->loadLayout('checkout_onepage_review');
429: $result['goto_section'] = 'review';
430: $result['update_section'] = array(
431: 'name' => 'review',
432: 'html' => $this->_getReviewHtml()
433: );
434: }
435: if ($redirectUrl) {
436: $result['redirect'] = $redirectUrl;
437: }
438: } catch (Mage_Payment_Exception $e) {
439: if ($e->getFields()) {
440: $result['fields'] = $e->getFields();
441: }
442: $result['error'] = $e->getMessage();
443: } catch (Mage_Core_Exception $e) {
444: $result['error'] = $e->getMessage();
445: } catch (Exception $e) {
446: Mage::logException($e);
447: $result['error'] = $this->__('Unable to set Payment Method.');
448: }
449: $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
450: }
451:
452: 453: 454: 455: 456:
457: protected function _getOrder()
458: {
459: if (is_null($this->_order)) {
460: $this->_order = Mage::getModel('sales/order')->load($this->getOnepage()->getQuote()->getId(), 'quote_id');
461: if (!$this->_order->getId()) {
462: throw new Mage_Payment_Model_Info_Exception(Mage::helper('core')->__("Can not create invoice. Order was not found."));
463: }
464: }
465: return $this->_order;
466: }
467:
468: 469: 470: 471: 472:
473: protected function _initInvoice()
474: {
475: $items = array();
476: foreach ($this->_getOrder()->getAllItems() as $item) {
477: $items[$item->getId()] = $item->getQtyOrdered();
478: }
479:
480: $invoice = Mage::getModel('sales/service_order', $this->_getOrder())->prepareInvoice($items);
481: $invoice->setEmailSent(true)->register();
482:
483: Mage::register('current_invoice', $invoice);
484: return $invoice;
485: }
486:
487: 488: 489:
490: public function saveOrderAction()
491: {
492: if ($this->_expireAjax()) {
493: return;
494: }
495:
496: $result = array();
497: try {
498: if ($requiredAgreements = Mage::helper('checkout')->getRequiredAgreementIds()) {
499: $postedAgreements = array_keys($this->getRequest()->getPost('agreement', array()));
500: if ($diff = array_diff($requiredAgreements, $postedAgreements)) {
501: $result['success'] = false;
502: $result['error'] = true;
503: $result['error_messages'] = $this->__('Please agree to all the terms and conditions before placing the order.');
504: $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
505: return;
506: }
507: }
508: if ($data = $this->getRequest()->getPost('payment', false)) {
509: $this->getOnepage()->getQuote()->getPayment()->importData($data);
510: }
511: $this->getOnepage()->saveOrder();
512:
513: $redirectUrl = $this->getOnepage()->getCheckout()->getRedirectUrl();
514: $result['success'] = true;
515: $result['error'] = false;
516: } catch (Mage_Payment_Model_Info_Exception $e) {
517: $message = $e->getMessage();
518: if( !empty($message) ) {
519: $result['error_messages'] = $message;
520: }
521: $result['goto_section'] = 'payment';
522: $result['update_section'] = array(
523: 'name' => 'payment-method',
524: 'html' => $this->_getPaymentMethodsHtml()
525: );
526: } catch (Mage_Core_Exception $e) {
527: Mage::logException($e);
528: Mage::helper('checkout')->sendPaymentFailedEmail($this->getOnepage()->getQuote(), $e->getMessage());
529: $result['success'] = false;
530: $result['error'] = true;
531: $result['error_messages'] = $e->getMessage();
532:
533: if ($gotoSection = $this->getOnepage()->getCheckout()->getGotoSection()) {
534: $result['goto_section'] = $gotoSection;
535: $this->getOnepage()->getCheckout()->setGotoSection(null);
536: }
537:
538: if ($updateSection = $this->getOnepage()->getCheckout()->getUpdateSection()) {
539: if (isset($this->_sectionUpdateFunctions[$updateSection])) {
540: $updateSectionFunction = $this->_sectionUpdateFunctions[$updateSection];
541: $result['update_section'] = array(
542: 'name' => $updateSection,
543: 'html' => $this->$updateSectionFunction()
544: );
545: }
546: $this->getOnepage()->getCheckout()->setUpdateSection(null);
547: }
548: } catch (Exception $e) {
549: Mage::logException($e);
550: Mage::helper('checkout')->sendPaymentFailedEmail($this->getOnepage()->getQuote(), $e->getMessage());
551: $result['success'] = false;
552: $result['error'] = true;
553: $result['error_messages'] = $this->__('There was an error processing your order. Please contact us or try again later.');
554: }
555: $this->getOnepage()->getQuote()->save();
556: 557: 558: 559:
560: if (isset($redirectUrl)) {
561: $result['redirect'] = $redirectUrl;
562: }
563:
564: $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
565: }
566:
567: 568: 569: 570: 571: 572:
573: protected function _filterPostData($data)
574: {
575: $data = $this->_filterDates($data, array('dob'));
576: return $data;
577: }
578:
579: 580: 581: 582: 583:
584: protected function _canShowForUnregisteredUsers()
585: {
586: return Mage::getSingleton('customer/session')->isLoggedIn()
587: || $this->getRequest()->getActionName() == 'index'
588: || Mage::helper('checkout')->isAllowedGuestCheckout($this->getOnepage()->getQuote())
589: || !Mage::helper('checkout')->isCustomerMustBeLogged();
590: }
591: }
592: