1: <?php
2: /**
3: * Magento
4: *
5: * NOTICE OF LICENSE
6: *
7: * This source file is subject to the Open Software License (OSL 3.0)
8: * that is bundled with this package in the file LICENSE.txt.
9: * It is also available through the world-wide-web at this URL:
10: * http://opensource.org/licenses/osl-3.0.php
11: * If you did not receive a copy of the license and are unable to
12: * obtain it through the world-wide-web, please send an email
13: * to license@magentocommerce.com so we can send you a copy immediately.
14: *
15: * DISCLAIMER
16: *
17: * Do not edit or add to this file if you wish to upgrade Magento to newer
18: * versions in the future. If you wish to customize Magento for your
19: * needs please refer to http://www.magentocommerce.com for more information.
20: *
21: * @category Mage
22: * @package Mage_Checkout
23: * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
24: * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25: */
26:
27: /**
28: * One page checkout processing model
29: */
30: class Mage_Checkout_Model_Type_Onepage
31: {
32: /**
33: * Checkout types: Checkout as Guest, Register, Logged In Customer
34: */
35: const METHOD_GUEST = 'guest';
36: const METHOD_REGISTER = 'register';
37: const METHOD_CUSTOMER = 'customer';
38:
39: /**
40: * Error message of "customer already exists"
41: *
42: * @var string
43: */
44: private $_customerEmailExistsMessage = '';
45:
46: /**
47: * @var Mage_Customer_Model_Session
48: */
49: protected $_customerSession;
50:
51: /**
52: * @var Mage_Checkout_Model_Session
53: */
54: protected $_checkoutSession;
55:
56: /**
57: * @var Mage_Sales_Model_Quote
58: */
59: protected $_quote = null;
60:
61: /**
62: * @var Mage_Checkout_Helper_Data
63: */
64: protected $_helper;
65:
66: /**
67: * Class constructor
68: * Set customer already exists message
69: */
70: public function __construct()
71: {
72: $this->_helper = Mage::helper('checkout');
73: $this->_customerEmailExistsMessage = Mage::helper('checkout')->__('There is already a customer registered using this email address. Please login using this email address or enter a different email address to register your account.');
74: $this->_checkoutSession = Mage::getSingleton('checkout/session');
75: $this->_customerSession = Mage::getSingleton('customer/session');
76: }
77:
78: /**
79: * Get frontend checkout session object
80: *
81: * @return Mage_Checkout_Model_Session
82: */
83: public function getCheckout()
84: {
85: return $this->_checkoutSession;
86: }
87:
88: /**
89: * Quote object getter
90: *
91: * @return Mage_Sales_Model_Quote
92: */
93: public function getQuote()
94: {
95: if ($this->_quote === null) {
96: return $this->_checkoutSession->getQuote();
97: }
98: return $this->_quote;
99: }
100:
101: /**
102: * Declare checkout quote instance
103: *
104: * @param Mage_Sales_Model_Quote $quote
105: * @return Mage_Checkout_Model_Type_Onepage
106: */
107: public function setQuote(Mage_Sales_Model_Quote $quote)
108: {
109: $this->_quote = $quote;
110: return $this;
111: }
112:
113: /**
114: * Get customer session object
115: *
116: * @return Mage_Customer_Model_Session
117: */
118: public function getCustomerSession()
119: {
120: return $this->_customerSession;
121: }
122:
123: /**
124: * Initialize quote state to be valid for one page checkout
125: *
126: * @return Mage_Checkout_Model_Type_Onepage
127: */
128: public function initCheckout()
129: {
130: $checkout = $this->getCheckout();
131: $customerSession = $this->getCustomerSession();
132: if (is_array($checkout->getStepData())) {
133: foreach ($checkout->getStepData() as $step=>$data) {
134: if (!($step==='login' || $customerSession->isLoggedIn() && $step==='billing')) {
135: $checkout->setStepData($step, 'allow', false);
136: }
137: }
138: }
139:
140: /**
141: * Reset multishipping flag before any manipulations with quote address
142: * addAddress method for quote object related on this flag
143: */
144: if ($this->getQuote()->getIsMultiShipping()) {
145: $this->getQuote()->setIsMultiShipping(false);
146: $this->getQuote()->save();
147: }
148:
149: /*
150: * want to load the correct customer information by assigning to address
151: * instead of just loading from sales/quote_address
152: */
153: $customer = $customerSession->getCustomer();
154: if ($customer) {
155: $this->getQuote()->assignCustomer($customer);
156: }
157: return $this;
158: }
159:
160: /**
161: * Get quote checkout method
162: *
163: * @return string
164: */
165: public function getCheckoutMethod()
166: {
167: if ($this->getCustomerSession()->isLoggedIn()) {
168: return self::METHOD_CUSTOMER;
169: }
170: if (!$this->getQuote()->getCheckoutMethod()) {
171: if ($this->_helper->isAllowedGuestCheckout($this->getQuote())) {
172: $this->getQuote()->setCheckoutMethod(self::METHOD_GUEST);
173: } else {
174: $this->getQuote()->setCheckoutMethod(self::METHOD_REGISTER);
175: }
176: }
177: return $this->getQuote()->getCheckoutMethod();
178: }
179:
180: /**
181: * Get quote checkout method
182: *
183: * @deprecated since 1.4.0.1
184: * @return string
185: */
186: public function getCheckoutMehod()
187: {
188: return $this->getCheckoutMethod();
189: }
190:
191: /**
192: * Specify checkout method
193: *
194: * @param string $method
195: * @return array
196: */
197: public function saveCheckoutMethod($method)
198: {
199: if (empty($method)) {
200: return array('error' => -1, 'message' => Mage::helper('checkout')->__('Invalid data.'));
201: }
202:
203: $this->getQuote()->setCheckoutMethod($method)->save();
204: $this->getCheckout()->setStepData('billing', 'allow', true);
205: return array();
206: }
207:
208: /**
209: * Get customer address by identifier
210: *
211: * @param int $addressId
212: * @return Mage_Customer_Model_Address
213: */
214: public function getAddress($addressId)
215: {
216: $address = Mage::getModel('customer/address')->load((int)$addressId);
217: $address->explodeStreetAddress();
218: if ($address->getRegionId()) {
219: $address->setRegion($address->getRegionId());
220: }
221: return $address;
222: }
223:
224: /**
225: * Save billing address information to quote
226: * This method is called by One Page Checkout JS (AJAX) while saving the billing information.
227: *
228: * @param array $data
229: * @param int $customerAddressId
230: * @return Mage_Checkout_Model_Type_Onepage
231: */
232: public function saveBilling($data, $customerAddressId)
233: {
234: if (empty($data)) {
235: return array('error' => -1, 'message' => Mage::helper('checkout')->__('Invalid data.'));
236: }
237:
238: $address = $this->getQuote()->getBillingAddress();
239: /* @var $addressForm Mage_Customer_Model_Form */
240: $addressForm = Mage::getModel('customer/form');
241: $addressForm->setFormCode('customer_address_edit')
242: ->setEntityType('customer_address')
243: ->setIsAjaxRequest(Mage::app()->getRequest()->isAjax());
244:
245: if (!empty($customerAddressId)) {
246: $customerAddress = Mage::getModel('customer/address')->load($customerAddressId);
247: if ($customerAddress->getId()) {
248: if ($customerAddress->getCustomerId() != $this->getQuote()->getCustomerId()) {
249: return array('error' => 1,
250: 'message' => Mage::helper('checkout')->__('Customer Address is not valid.')
251: );
252: }
253:
254: $address->importCustomerAddress($customerAddress)->setSaveInAddressBook(0);
255: $addressForm->setEntity($address);
256: $addressErrors = $addressForm->validateData($address->getData());
257: if ($addressErrors !== true) {
258: return array('error' => 1, 'message' => $addressErrors);
259: }
260: }
261: } else {
262: $addressForm->setEntity($address);
263: // emulate request object
264: $addressData = $addressForm->extractData($addressForm->prepareRequest($data));
265: $addressErrors = $addressForm->validateData($addressData);
266: if ($addressErrors !== true) {
267: return array('error' => 1, 'message' => array_values($addressErrors));
268: }
269: $addressForm->compactData($addressData);
270: //unset billing address attributes which were not shown in form
271: foreach ($addressForm->getAttributes() as $attribute) {
272: if (!isset($data[$attribute->getAttributeCode()])) {
273: $address->setData($attribute->getAttributeCode(), NULL);
274: }
275: }
276: $address->setCustomerAddressId(null);
277: // Additional form data, not fetched by extractData (as it fetches only attributes)
278: $address->setSaveInAddressBook(empty($data['save_in_address_book']) ? 0 : 1);
279: }
280:
281: // validate billing address
282: if (($validateRes = $address->validate()) !== true) {
283: return array('error' => 1, 'message' => $validateRes);
284: }
285:
286: $address->implodeStreetAddress();
287:
288: if (true !== ($result = $this->_validateCustomerData($data))) {
289: return $result;
290: }
291:
292: if (!$this->getQuote()->getCustomerId() && self::METHOD_REGISTER == $this->getQuote()->getCheckoutMethod()) {
293: if ($this->_customerEmailExists($address->getEmail(), Mage::app()->getWebsite()->getId())) {
294: return array('error' => 1, 'message' => $this->_customerEmailExistsMessage);
295: }
296: }
297:
298: if (!$this->getQuote()->isVirtual()) {
299: /**
300: * Billing address using otions
301: */
302: $usingCase = isset($data['use_for_shipping']) ? (int)$data['use_for_shipping'] : 0;
303:
304: switch ($usingCase) {
305: case 0:
306: $shipping = $this->getQuote()->getShippingAddress();
307: $shipping->setSameAsBilling(0);
308: break;
309: case 1:
310: $billing = clone $address;
311: $billing->unsAddressId()->unsAddressType();
312: $shipping = $this->getQuote()->getShippingAddress();
313: $shippingMethod = $shipping->getShippingMethod();
314:
315: // Billing address properties that must be always copied to shipping address
316: $requiredBillingAttributes = array('customer_address_id');
317:
318: // don't reset original shipping data, if it was not changed by customer
319: foreach ($shipping->getData() as $shippingKey => $shippingValue) {
320: if (!is_null($shippingValue) && !is_null($billing->getData($shippingKey))
321: && !isset($data[$shippingKey]) && !in_array($shippingKey, $requiredBillingAttributes)
322: ) {
323: $billing->unsetData($shippingKey);
324: }
325: }
326: $shipping->addData($billing->getData())
327: ->setSameAsBilling(1)
328: ->setSaveInAddressBook(0)
329: ->setShippingMethod($shippingMethod)
330: ->setCollectShippingRates(true);
331: $this->getCheckout()->setStepData('shipping', 'complete', true);
332: break;
333: }
334: }
335:
336: $this->getQuote()->collectTotals();
337: $this->getQuote()->save();
338:
339: if (!$this->getQuote()->isVirtual() && $this->getCheckout()->getStepData('shipping', 'complete') == true) {
340: //Recollect Shipping rates for shipping methods
341: $this->getQuote()->getShippingAddress()->setCollectShippingRates(true);
342: }
343:
344: $this->getCheckout()
345: ->setStepData('billing', 'allow', true)
346: ->setStepData('billing', 'complete', true)
347: ->setStepData('shipping', 'allow', true);
348:
349: return array();
350: }
351:
352: /**
353: * Validate customer data and set some its data for further usage in quote
354: * Will return either true or array with error messages
355: *
356: * @param array $data
357: * @return true|array
358: */
359: protected function _validateCustomerData(array $data)
360: {
361: /** @var $customerForm Mage_Customer_Model_Form */
362: $customerForm = Mage::getModel('customer/form');
363: $customerForm->setFormCode('checkout_register')
364: ->setIsAjaxRequest(Mage::app()->getRequest()->isAjax());
365:
366: $quote = $this->getQuote();
367: if ($quote->getCustomerId()) {
368: $customer = $quote->getCustomer();
369: $customerForm->setEntity($customer);
370: $customerData = $quote->getCustomer()->getData();
371: } else {
372: /* @var $customer Mage_Customer_Model_Customer */
373: $customer = Mage::getModel('customer/customer');
374: $customerForm->setEntity($customer);
375: $customerRequest = $customerForm->prepareRequest($data);
376: $customerData = $customerForm->extractData($customerRequest);
377: }
378:
379: $customerErrors = $customerForm->validateData($customerData);
380: if ($customerErrors !== true) {
381: return array(
382: 'error' => -1,
383: 'message' => implode(', ', $customerErrors)
384: );
385: }
386:
387: if ($quote->getCustomerId()) {
388: return true;
389: }
390:
391: $customerForm->compactData($customerData);
392:
393: if ($quote->getCheckoutMethod() == self::METHOD_REGISTER) {
394: // set customer password
395: $customer->setPassword($customerRequest->getParam('customer_password'));
396: $customer->setConfirmation($customerRequest->getParam('confirm_password'));
397: } else {
398: // spoof customer password for guest
399: $password = $customer->generatePassword();
400: $customer->setPassword($password);
401: $customer->setConfirmation($password);
402: // set NOT LOGGED IN group id explicitly,
403: // otherwise copyFieldset('customer_account', 'to_quote') will fill it with default group id value
404: $customer->setGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
405: }
406:
407: $result = $customer->validate();
408: if (true !== $result && is_array($result)) {
409: return array(
410: 'error' => -1,
411: 'message' => implode(', ', $result)
412: );
413: }
414:
415: if ($quote->getCheckoutMethod() == self::METHOD_REGISTER) {
416: // save customer encrypted password in quote
417: $quote->setPasswordHash($customer->encryptPassword($customer->getPassword()));
418: }
419:
420: // copy customer/guest email to address
421: $quote->getBillingAddress()->setEmail($customer->getEmail());
422:
423: // copy customer data to quote
424: Mage::helper('core')->copyFieldset('customer_account', 'to_quote', $customer, $quote);
425:
426: return true;
427: }
428:
429: /**
430: * Validate customer data and set some its data for further usage in quote
431: * Will return either true or array with error messages
432: *
433: * @deprecated since 1.4.0.1
434: * @param Mage_Sales_Model_Quote_Address $address
435: * @return true|array
436: */
437: protected function _processValidateCustomer(Mage_Sales_Model_Quote_Address $address)
438: {
439: // set customer date of birth for further usage
440: $dob = '';
441: if ($address->getDob()) {
442: $dob = Mage::app()->getLocale()->date($address->getDob(), null, null, false)->toString('yyyy-MM-dd');
443: $this->getQuote()->setCustomerDob($dob);
444: }
445:
446: // set customer tax/vat number for further usage
447: if ($address->getTaxvat()) {
448: $this->getQuote()->setCustomerTaxvat($address->getTaxvat());
449: }
450:
451: // set customer gender for further usage
452: if ($address->getGender()) {
453: $this->getQuote()->setCustomerGender($address->getGender());
454: }
455:
456: // invoke customer model, if it is registering
457: if (self::METHOD_REGISTER == $this->getQuote()->getCheckoutMethod()) {
458: // set customer password hash for further usage
459: $customer = Mage::getModel('customer/customer');
460: $this->getQuote()->setPasswordHash($customer->encryptPassword($address->getCustomerPassword()));
461:
462: // validate customer
463: foreach (array(
464: 'firstname' => 'firstname',
465: 'lastname' => 'lastname',
466: 'email' => 'email',
467: 'password' => 'customer_password',
468: 'confirmation' => 'confirm_password',
469: 'taxvat' => 'taxvat',
470: 'gender' => 'gender',
471: ) as $key => $dataKey) {
472: $customer->setData($key, $address->getData($dataKey));
473: }
474: if ($dob) {
475: $customer->setDob($dob);
476: }
477: $validationResult = $customer->validate();
478: if (true !== $validationResult && is_array($validationResult)) {
479: return array(
480: 'error' => -1,
481: 'message' => implode(', ', $validationResult)
482: );
483: }
484: } else if (self::METHOD_GUEST == $this->getQuote()->getCheckoutMethod()) {
485: $email = $address->getData('email');
486: if (!Zend_Validate::is($email, 'EmailAddress')) {
487: return array(
488: 'error' => -1,
489: 'message' => Mage::helper('checkout')->__('Invalid email address "%s"', $email)
490: );
491: }
492: }
493:
494: return true;
495: }
496:
497: /**
498: * Save checkout shipping address
499: *
500: * @param array $data
501: * @param int $customerAddressId
502: * @return Mage_Checkout_Model_Type_Onepage
503: */
504: public function saveShipping($data, $customerAddressId)
505: {
506: if (empty($data)) {
507: return array('error' => -1, 'message' => Mage::helper('checkout')->__('Invalid data.'));
508: }
509: $address = $this->getQuote()->getShippingAddress();
510:
511: /* @var $addressForm Mage_Customer_Model_Form */
512: $addressForm = Mage::getModel('customer/form');
513: $addressForm->setFormCode('customer_address_edit')
514: ->setEntityType('customer_address')
515: ->setIsAjaxRequest(Mage::app()->getRequest()->isAjax());
516:
517: if (!empty($customerAddressId)) {
518: $customerAddress = Mage::getModel('customer/address')->load($customerAddressId);
519: if ($customerAddress->getId()) {
520: if ($customerAddress->getCustomerId() != $this->getQuote()->getCustomerId()) {
521: return array('error' => 1,
522: 'message' => Mage::helper('checkout')->__('Customer Address is not valid.')
523: );
524: }
525:
526: $address->importCustomerAddress($customerAddress)->setSaveInAddressBook(0);
527: $addressForm->setEntity($address);
528: $addressErrors = $addressForm->validateData($address->getData());
529: if ($addressErrors !== true) {
530: return array('error' => 1, 'message' => $addressErrors);
531: }
532: }
533: } else {
534: $addressForm->setEntity($address);
535: // emulate request object
536: $addressData = $addressForm->extractData($addressForm->prepareRequest($data));
537: $addressErrors = $addressForm->validateData($addressData);
538: if ($addressErrors !== true) {
539: return array('error' => 1, 'message' => $addressErrors);
540: }
541: $addressForm->compactData($addressData);
542: // unset shipping address attributes which were not shown in form
543: foreach ($addressForm->getAttributes() as $attribute) {
544: if (!isset($data[$attribute->getAttributeCode()])) {
545: $address->setData($attribute->getAttributeCode(), NULL);
546: }
547: }
548:
549: $address->setCustomerAddressId(null);
550: // Additional form data, not fetched by extractData (as it fetches only attributes)
551: $address->setSaveInAddressBook(empty($data['save_in_address_book']) ? 0 : 1);
552: $address->setSameAsBilling(empty($data['same_as_billing']) ? 0 : 1);
553: }
554:
555: $address->implodeStreetAddress();
556: $address->setCollectShippingRates(true);
557:
558: if (($validateRes = $address->validate())!==true) {
559: return array('error' => 1, 'message' => $validateRes);
560: }
561:
562: $this->getQuote()->collectTotals()->save();
563:
564: $this->getCheckout()
565: ->setStepData('shipping', 'complete', true)
566: ->setStepData('shipping_method', 'allow', true);
567:
568: return array();
569: }
570:
571: /**
572: * Specify quote shipping method
573: *
574: * @param string $shippingMethod
575: * @return array
576: */
577: public function saveShippingMethod($shippingMethod)
578: {
579: if (empty($shippingMethod)) {
580: return array('error' => -1, 'message' => Mage::helper('checkout')->__('Invalid shipping method.'));
581: }
582: $rate = $this->getQuote()->getShippingAddress()->getShippingRateByCode($shippingMethod);
583: if (!$rate) {
584: return array('error' => -1, 'message' => Mage::helper('checkout')->__('Invalid shipping method.'));
585: }
586: $this->getQuote()->getShippingAddress()
587: ->setShippingMethod($shippingMethod);
588:
589: $this->getCheckout()
590: ->setStepData('shipping_method', 'complete', true)
591: ->setStepData('payment', 'allow', true);
592:
593: return array();
594: }
595:
596: /**
597: * Specify quote payment method
598: *
599: * @param array $data
600: * @return array
601: */
602: public function savePayment($data)
603: {
604: if (empty($data)) {
605: return array('error' => -1, 'message' => Mage::helper('checkout')->__('Invalid data.'));
606: }
607: $quote = $this->getQuote();
608: if ($quote->isVirtual()) {
609: $quote->getBillingAddress()->setPaymentMethod(isset($data['method']) ? $data['method'] : null);
610: } else {
611: $quote->getShippingAddress()->setPaymentMethod(isset($data['method']) ? $data['method'] : null);
612: }
613:
614: // shipping totals may be affected by payment method
615: if (!$quote->isVirtual() && $quote->getShippingAddress()) {
616: $quote->getShippingAddress()->setCollectShippingRates(true);
617: }
618:
619: $payment = $quote->getPayment();
620: $payment->importData($data);
621:
622: $quote->save();
623:
624: $this->getCheckout()
625: ->setStepData('payment', 'complete', true)
626: ->setStepData('review', 'allow', true);
627:
628: return array();
629: }
630:
631: /**
632: * Validate quote state to be integrated with one page checkout process
633: */
634: public function validate()
635: {
636: $quote = $this->getQuote();
637: if ($quote->getIsMultiShipping()) {
638: Mage::throwException(Mage::helper('checkout')->__('Invalid checkout type.'));
639: }
640:
641: if ($quote->getCheckoutMethod() == self::METHOD_GUEST && !$quote->isAllowedGuestCheckout()) {
642: Mage::throwException(Mage::helper('checkout')->__('Sorry, guest checkout is not enabled. Please try again or contact store owner.'));
643: }
644: }
645:
646: /**
647: * Prepare quote for guest checkout order submit
648: *
649: * @return Mage_Checkout_Model_Type_Onepage
650: */
651: protected function _prepareGuestQuote()
652: {
653: $quote = $this->getQuote();
654: $quote->setCustomerId(null)
655: ->setCustomerEmail($quote->getBillingAddress()->getEmail())
656: ->setCustomerIsGuest(true)
657: ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
658: return $this;
659: }
660:
661: /**
662: * Prepare quote for customer registration and customer order submit
663: *
664: * @return Mage_Checkout_Model_Type_Onepage
665: */
666: protected function _prepareNewCustomerQuote()
667: {
668: $quote = $this->getQuote();
669: $billing = $quote->getBillingAddress();
670: $shipping = $quote->isVirtual() ? null : $quote->getShippingAddress();
671:
672: //$customer = Mage::getModel('customer/customer');
673: $customer = $quote->getCustomer();
674: /* @var $customer Mage_Customer_Model_Customer */
675: $customerBilling = $billing->exportCustomerAddress();
676: $customer->addAddress($customerBilling);
677: $billing->setCustomerAddress($customerBilling);
678: $customerBilling->setIsDefaultBilling(true);
679: if ($shipping && !$shipping->getSameAsBilling()) {
680: $customerShipping = $shipping->exportCustomerAddress();
681: $customer->addAddress($customerShipping);
682: $shipping->setCustomerAddress($customerShipping);
683: $customerShipping->setIsDefaultShipping(true);
684: } else {
685: $customerBilling->setIsDefaultShipping(true);
686: }
687:
688: Mage::helper('core')->copyFieldset('checkout_onepage_quote', 'to_customer', $quote, $customer);
689: $customer->setPassword($customer->decryptPassword($quote->getPasswordHash()));
690: $customer->setPasswordHash($customer->hashPassword($customer->getPassword()));
691: $quote->setCustomer($customer)
692: ->setCustomerId(true);
693: }
694:
695: /**
696: * Prepare quote for customer order submit
697: *
698: * @return Mage_Checkout_Model_Type_Onepage
699: */
700: protected function _prepareCustomerQuote()
701: {
702: $quote = $this->getQuote();
703: $billing = $quote->getBillingAddress();
704: $shipping = $quote->isVirtual() ? null : $quote->getShippingAddress();
705:
706: $customer = $this->getCustomerSession()->getCustomer();
707: if (!$billing->getCustomerId() || $billing->getSaveInAddressBook()) {
708: $customerBilling = $billing->exportCustomerAddress();
709: $customer->addAddress($customerBilling);
710: $billing->setCustomerAddress($customerBilling);
711: }
712: if ($shipping && !$shipping->getSameAsBilling() &&
713: (!$shipping->getCustomerId() || $shipping->getSaveInAddressBook())) {
714: $customerShipping = $shipping->exportCustomerAddress();
715: $customer->addAddress($customerShipping);
716: $shipping->setCustomerAddress($customerShipping);
717: }
718:
719: if (isset($customerBilling) && !$customer->getDefaultBilling()) {
720: $customerBilling->setIsDefaultBilling(true);
721: }
722: if ($shipping && isset($customerShipping) && !$customer->getDefaultShipping()) {
723: $customerShipping->setIsDefaultShipping(true);
724: } else if (isset($customerBilling) && !$customer->getDefaultShipping()) {
725: $customerBilling->setIsDefaultShipping(true);
726: }
727: $quote->setCustomer($customer);
728: }
729:
730: /**
731: * Involve new customer to system
732: *
733: * @return Mage_Checkout_Model_Type_Onepage
734: */
735: protected function _involveNewCustomer()
736: {
737: $customer = $this->getQuote()->getCustomer();
738: if ($customer->isConfirmationRequired()) {
739: $customer->sendNewAccountEmail('confirmation', '', $this->getQuote()->getStoreId());
740: $url = Mage::helper('customer')->getEmailConfirmationUrl($customer->getEmail());
741: $this->getCustomerSession()->addSuccess(
742: Mage::helper('customer')->__('Account confirmation is required. Please, check your e-mail for confirmation link. To resend confirmation email please <a href="%s">click here</a>.', $url)
743: );
744: } else {
745: $customer->sendNewAccountEmail('registered', '', $this->getQuote()->getStoreId());
746: $this->getCustomerSession()->loginById($customer->getId());
747: }
748: return $this;
749: }
750:
751: /**
752: * Create order based on checkout type. Create customer if necessary.
753: *
754: * @return Mage_Checkout_Model_Type_Onepage
755: */
756: public function saveOrder()
757: {
758: $this->validate();
759: $isNewCustomer = false;
760: switch ($this->getCheckoutMethod()) {
761: case self::METHOD_GUEST:
762: $this->_prepareGuestQuote();
763: break;
764: case self::METHOD_REGISTER:
765: $this->_prepareNewCustomerQuote();
766: $isNewCustomer = true;
767: break;
768: default:
769: $this->_prepareCustomerQuote();
770: break;
771: }
772:
773: $service = Mage::getModel('sales/service_quote', $this->getQuote());
774: $service->submitAll();
775:
776: if ($isNewCustomer) {
777: try {
778: $this->_involveNewCustomer();
779: } catch (Exception $e) {
780: Mage::logException($e);
781: }
782: }
783:
784: $this->_checkoutSession->setLastQuoteId($this->getQuote()->getId())
785: ->setLastSuccessQuoteId($this->getQuote()->getId())
786: ->clearHelperData();
787:
788: $order = $service->getOrder();
789: if ($order) {
790: Mage::dispatchEvent('checkout_type_onepage_save_order_after',
791: array('order'=>$order, 'quote'=>$this->getQuote()));
792:
793: /**
794: * a flag to set that there will be redirect to third party after confirmation
795: * eg: paypal standard ipn
796: */
797: $redirectUrl = $this->getQuote()->getPayment()->getOrderPlaceRedirectUrl();
798: /**
799: * we only want to send to customer about new order when there is no redirect to third party
800: */
801: if (!$redirectUrl && $order->getCanSendNewEmailFlag()) {
802: try {
803: $order->sendNewOrderEmail();
804: } catch (Exception $e) {
805: Mage::logException($e);
806: }
807: }
808:
809: // add order information to the session
810: $this->_checkoutSession->setLastOrderId($order->getId())
811: ->setRedirectUrl($redirectUrl)
812: ->setLastRealOrderId($order->getIncrementId());
813:
814: // as well a billing agreement can be created
815: $agreement = $order->getPayment()->getBillingAgreement();
816: if ($agreement) {
817: $this->_checkoutSession->setLastBillingAgreementId($agreement->getId());
818: }
819: }
820:
821: // add recurring profiles information to the session
822: $profiles = $service->getRecurringPaymentProfiles();
823: if ($profiles) {
824: $ids = array();
825: foreach ($profiles as $profile) {
826: $ids[] = $profile->getId();
827: }
828: $this->_checkoutSession->setLastRecurringProfileIds($ids);
829: // TODO: send recurring profile emails
830: }
831:
832: Mage::dispatchEvent(
833: 'checkout_submit_all_after',
834: array('order' => $order, 'quote' => $this->getQuote(), 'recurring_profiles' => $profiles)
835: );
836:
837: return $this;
838: }
839:
840: /**
841: * Validate quote state to be able submitted from one page checkout page
842: *
843: * @deprecated after 1.4 - service model doing quote validation
844: * @return Mage_Checkout_Model_Type_Onepage
845: */
846: protected function validateOrder()
847: {
848: if ($this->getQuote()->getIsMultiShipping()) {
849: Mage::throwException(Mage::helper('checkout')->__('Invalid checkout type.'));
850: }
851:
852: if (!$this->getQuote()->isVirtual()) {
853: $address = $this->getQuote()->getShippingAddress();
854: $addressValidation = $address->validate();
855: if ($addressValidation !== true) {
856: Mage::throwException(Mage::helper('checkout')->__('Please check shipping address information.'));
857: }
858: $method= $address->getShippingMethod();
859: $rate = $address->getShippingRateByCode($method);
860: if (!$this->getQuote()->isVirtual() && (!$method || !$rate)) {
861: Mage::throwException(Mage::helper('checkout')->__('Please specify shipping method.'));
862: }
863: }
864:
865: $addressValidation = $this->getQuote()->getBillingAddress()->validate();
866: if ($addressValidation !== true) {
867: Mage::throwException(Mage::helper('checkout')->__('Please check billing address information.'));
868: }
869:
870: if (!($this->getQuote()->getPayment()->getMethod())) {
871: Mage::throwException(Mage::helper('checkout')->__('Please select valid payment method.'));
872: }
873: }
874:
875: /**
876: * Check if customer email exists
877: *
878: * @param string $email
879: * @param int $websiteId
880: * @return false|Mage_Customer_Model_Customer
881: */
882: protected function _customerEmailExists($email, $websiteId = null)
883: {
884: $customer = Mage::getModel('customer/customer');
885: if ($websiteId) {
886: $customer->setWebsiteId($websiteId);
887: }
888: $customer->loadByEmail($email);
889: if ($customer->getId()) {
890: return $customer;
891: }
892: return false;
893: }
894:
895: /**
896: * Get last order increment id by order id
897: *
898: * @return string
899: */
900: public function getLastOrderId()
901: {
902: $lastId = $this->getCheckout()->getLastOrderId();
903: $orderId = false;
904: if ($lastId) {
905: $order = Mage::getModel('sales/order');
906: $order->load($lastId);
907: $orderId = $order->getIncrementId();
908: }
909: return $orderId;
910: }
911:
912:
913: /**
914: * Enter description here...
915: *
916: * @return array
917: */
918: // public function saveOrder1()
919: // {
920: // $this->validateOrder();
921: // $billing = $this->getQuote()->getBillingAddress();
922: // if (!$this->getQuote()->isVirtual()) {
923: // $shipping = $this->getQuote()->getShippingAddress();
924: // }
925: //
926: // /*
927: // * Check if before this step checkout method was not defined use default values.
928: // * Related to issue with some browsers when checkout method was not saved during first step.
929: // */
930: // if (!$this->getQuote()->getCheckoutMethod()) {
931: // if (Mage::helper('checkout')->isAllowedGuestCheckout($this->getQuote(), $this->getQuote()->getStore())) {
932: // $this->getQuote()->setCheckoutMethod(Mage_Sales_Model_Quote::CHECKOUT_METHOD_GUEST);
933: // } else {
934: // $this->getQuote()->setCheckoutMethod(Mage_Sales_Model_Quote::CHECKOUT_METHOD_REGISTER);
935: // }
936: // }
937: //
938: // switch ($this->getQuote()->getCheckoutMethod()) {
939: // case Mage_Sales_Model_Quote::CHECKOUT_METHOD_GUEST:
940: // if (!$this->getQuote()->isAllowedGuestCheckout()) {
941: // Mage::throwException(Mage::helper('checkout')->__('Sorry, guest checkout is not enabled. Please try again or contact the store owner.'));
942: // }
943: // $this->getQuote()->setCustomerId(null)
944: // ->setCustomerEmail($billing->getEmail())
945: // ->setCustomerIsGuest(true)
946: // ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
947: // break;
948: //
949: // case Mage_Sales_Model_Quote::CHECKOUT_METHOD_REGISTER:
950: // $customer = Mage::getModel('customer/customer');
951: // /* @var $customer Mage_Customer_Model_Customer */
952: //
953: // $customerBilling = $billing->exportCustomerAddress();
954: // $customer->addAddress($customerBilling);
955: //
956: // if (!$this->getQuote()->isVirtual() && !$shipping->getSameAsBilling()) {
957: // $customerShipping = $shipping->exportCustomerAddress();
958: // $customer->addAddress($customerShipping);
959: // }
960: //
961: // if ($this->getQuote()->getCustomerDob() && !$billing->getCustomerDob()) {
962: // $billing->setCustomerDob($this->getQuote()->getCustomerDob());
963: // }
964: //
965: // if ($this->getQuote()->getCustomerTaxvat() && !$billing->getCustomerTaxvat()) {
966: // $billing->setCustomerTaxvat($this->getQuote()->getCustomerTaxvat());
967: // }
968: //
969: // if ($this->getQuote()->getCustomerGender() && !$billing->getCustomerGender()) {
970: // $billing->setCustomerGender($this->getQuote()->getCustomerGender());
971: // }
972: //
973: // Mage::helper('core')->copyFieldset('checkout_onepage_billing', 'to_customer', $billing, $customer);
974: //
975: // $customer->setPassword($customer->decryptPassword($this->getQuote()->getPasswordHash()));
976: // $customer->setPasswordHash($customer->hashPassword($customer->getPassword()));
977: //
978: // $this->getQuote()->setCustomer($customer);
979: // break;
980: //
981: // default:
982: // $customer = Mage::getSingleton('customer/session')->getCustomer();
983: //
984: // if (!$billing->getCustomerId() || $billing->getSaveInAddressBook()) {
985: // $customerBilling = $billing->exportCustomerAddress();
986: // $customer->addAddress($customerBilling);
987: // }
988: // if (!$this->getQuote()->isVirtual() &&
989: // ((!$shipping->getCustomerId() && !$shipping->getSameAsBilling()) ||
990: // (!$shipping->getSameAsBilling() && $shipping->getSaveInAddressBook()))) {
991: //
992: // $customerShipping = $shipping->exportCustomerAddress();
993: // $customer->addAddress($customerShipping);
994: // }
995: // $customer->setSavedFromQuote(true);
996: // $customer->save();
997: //
998: // $changed = false;
999: // if (isset($customerBilling) && !$customer->getDefaultBilling()) {
1000: // $customer->setDefaultBilling($customerBilling->getId());
1001: // $changed = true;
1002: // }
1003: // if (!$this->getQuote()->isVirtual() && isset($customerBilling) &&
1004: // !$customer->getDefaultShipping() && $shipping->getSameAsBilling()) {
1005: // $customer->setDefaultShipping($customerBilling->getId());
1006: // $changed = true;
1007: // }
1008: // elseif (!$this->getQuote()->isVirtual() && isset($customerShipping) && !$customer->getDefaultShipping()){
1009: // $customer->setDefaultShipping($customerShipping->getId());
1010: // $changed = true;
1011: // }
1012: //
1013: // if ($changed) {
1014: // $customer->save();
1015: // }
1016: // }
1017: //
1018: // $this->getQuote()->reserveOrderId();
1019: // $convertQuote = Mage::getModel('sales/convert_quote');
1020: // /* @var $convertQuote Mage_Sales_Model_Convert_Quote */
1021: // //$order = Mage::getModel('sales/order');
1022: // if ($this->getQuote()->isVirtual()) {
1023: // $order = $convertQuote->addressToOrder($billing);
1024: // }
1025: // else {
1026: // $order = $convertQuote->addressToOrder($shipping);
1027: // }
1028: // /* @var $order Mage_Sales_Model_Order */
1029: // $order->setBillingAddress($convertQuote->addressToOrderAddress($billing));
1030: //
1031: // if (!$this->getQuote()->isVirtual()) {
1032: // $order->setShippingAddress($convertQuote->addressToOrderAddress($shipping));
1033: // }
1034: //
1035: // $order->setPayment($convertQuote->paymentToOrderPayment($this->getQuote()->getPayment()));
1036: //
1037: // foreach ($this->getQuote()->getAllItems() as $item) {
1038: // $orderItem = $convertQuote->itemToOrderItem($item);
1039: // if ($item->getParentItem()) {
1040: // $orderItem->setParentItem($order->getItemByQuoteItemId($item->getParentItem()->getId()));
1041: // }
1042: // $order->addItem($orderItem);
1043: // }
1044: //
1045: // /**
1046: // * We can use configuration data for declare new order status
1047: // */
1048: // Mage::dispatchEvent('checkout_type_onepage_save_order', array('order'=>$order, 'quote'=>$this->getQuote()));
1049: // // check again, if customer exists
1050: // if ($this->getQuote()->getCheckoutMethod() == Mage_Sales_Model_Quote::CHECKOUT_METHOD_REGISTER) {
1051: // if ($this->_customerEmailExists($customer->getEmail(), Mage::app()->getWebsite()->getId())) {
1052: // Mage::throwException($this->_customerEmailExistsMessage);
1053: // }
1054: // }
1055: // $order->place();
1056: //
1057: // if ($this->getQuote()->getCheckoutMethod()==Mage_Sales_Model_Quote::CHECKOUT_METHOD_REGISTER) {
1058: // $customer->save();
1059: // $customerBillingId = $customerBilling->getId();
1060: // if (!$this->getQuote()->isVirtual()) {
1061: // $customerShippingId = isset($customerShipping) ? $customerShipping->getId() : $customerBillingId;
1062: // $customer->setDefaultShipping($customerShippingId);
1063: // }
1064: // $customer->setDefaultBilling($customerBillingId);
1065: // $customer->save();
1066: //
1067: // $this->getQuote()->setCustomerId($customer->getId());
1068: //
1069: // $order->setCustomerId($customer->getId());
1070: // Mage::helper('core')->copyFieldset('customer_account', 'to_order', $customer, $order);
1071: //
1072: // $billing->setCustomerId($customer->getId())->setCustomerAddressId($customerBillingId);
1073: // if (!$this->getQuote()->isVirtual()) {
1074: // $shipping->setCustomerId($customer->getId())->setCustomerAddressId($customerShippingId);
1075: // }
1076: //
1077: // try {
1078: // if ($customer->isConfirmationRequired()) {
1079: // $customer->sendNewAccountEmail('confirmation');
1080: // }
1081: // else {
1082: // $customer->sendNewAccountEmail();
1083: // }
1084: // } catch (Exception $e) {
1085: // Mage::logException($e);
1086: // }
1087: // }
1088: //
1089: // /**
1090: // * a flag to set that there will be redirect to third party after confirmation
1091: // * eg: paypal standard ipn
1092: // */
1093: // $redirectUrl = $this->getQuote()->getPayment()->getOrderPlaceRedirectUrl();
1094: // if(!$redirectUrl){
1095: // $order->setEmailSent(true);
1096: // }
1097: //
1098: // $order->save();
1099: //
1100: // Mage::dispatchEvent('checkout_type_onepage_save_order_after',
1101: // array('order'=>$order, 'quote'=>$this->getQuote()));
1102: //
1103: // /**
1104: // * need to have somelogic to set order as new status to make sure order is not finished yet
1105: // * quote will be still active when we send the customer to paypal
1106: // */
1107: //
1108: // $orderId = $order->getIncrementId();
1109: // $this->getCheckout()->setLastQuoteId($this->getQuote()->getId());
1110: // $this->getCheckout()->setLastOrderId($order->getId());
1111: // $this->getCheckout()->setLastRealOrderId($order->getIncrementId());
1112: // $this->getCheckout()->setRedirectUrl($redirectUrl);
1113: //
1114: // /**
1115: // * we only want to send to customer about new order when there is no redirect to third party
1116: // */
1117: // if(!$redirectUrl){
1118: // try {
1119: // $order->sendNewOrderEmail();
1120: // } catch (Exception $e) {
1121: // Mage::logException($e);
1122: // }
1123: // }
1124: //
1125: // if ($this->getQuote()->getCheckoutMethod(true)==Mage_Sales_Model_Quote::CHECKOUT_METHOD_REGISTER
1126: // && !Mage::getSingleton('customer/session')->isLoggedIn()) {
1127: // /**
1128: // * we need to save quote here to have it saved with Customer Id.
1129: // * so when loginById() executes checkout/session method loadCustomerQuote
1130: // * it would not create new quotes and merge it with old one.
1131: // */
1132: // $this->getQuote()->save();
1133: // if ($customer->isConfirmationRequired()) {
1134: // Mage::getSingleton('checkout/session')->addSuccess(Mage::helper('customer')->__('Account confirmation is required. Please, check your e-mail for confirmation link. To resend confirmation email please <a href="%s">click here</a>.', Mage::helper('customer')->getEmailConfirmationUrl($customer->getEmail())));
1135: // }
1136: // else {
1137: // Mage::getSingleton('customer/session')->loginById($customer->getId());
1138: // }
1139: // }
1140: //
1141: // //Setting this one more time like control flag that we haves saved order
1142: // //Must be checkout on success page to show it or not.
1143: // $this->getCheckout()->setLastSuccessQuoteId($this->getQuote()->getId());
1144: //
1145: // $this->getQuote()->setIsActive(false);
1146: // $this->getQuote()->save();
1147: //
1148: // return $this;
1149: // }
1150: //
1151: }
1152: