FI_Checkout - Version 1.2.0

Version Notes

- Refactored javascript.
- Fixed minor bugs with region field.
- Refactored PHP code, implemented new model which handles all session's changes.
- Implemented ability to specify default shipping method.
- Implemented ability to specify default payment method.
- Implemented auto refresh when payment method is changed.

Version 1.2.0 released
2013/03/20
Version number: 1.2.0
Stability: stable
Compatibility: 1.5, 1.6, 1.6.0.0, 1.6.1, 1.6.2.0, 1.7

Download this release

Release Info

Developer Sergiy Stotskiy
Extension FI_Checkout
Version 1.2.0
Comparing to
See all releases


Code changes from version 1.0.3 to 1.2.0

Files changed (27) hide show
  1. app/code/{local → community}/FI/Checkout/Block/Block.php +0 -0
  2. app/code/community/FI/Checkout/Block/Block/Info.php +275 -0
  3. app/code/{local → community}/FI/Checkout/Block/Newsletter.php +0 -0
  4. app/code/{local → community}/FI/Checkout/Block/Payment/Methods.php +0 -0
  5. app/code/{local → community}/FI/Checkout/Helper/Data.php +144 -98
  6. app/code/community/FI/Checkout/Model/Observer.php +97 -0
  7. app/code/community/FI/Checkout/Model/Order.php +196 -0
  8. app/code/{local → community}/FI/Checkout/Model/Page.php +0 -0
  9. app/code/{local → community}/FI/Checkout/Model/Resource/Countries.php +76 -59
  10. app/code/{local → community}/FI/Checkout/Model/Source.php +0 -31
  11. app/code/community/FI/Checkout/Model/Source/PaymentMethods.php +22 -0
  12. app/code/community/FI/Checkout/Model/Source/ShippingMethods.php +14 -0
  13. app/code/{local → community}/FI/Checkout/Model/Subscriber.php +0 -0
  14. app/code/{local → community}/FI/Checkout/controllers/CheckoutController.php +111 -316
  15. app/code/{local → community}/FI/Checkout/etc/config.xml +9 -1
  16. app/code/{local → community}/FI/Checkout/etc/system.xml +13 -6
  17. app/code/{local → community}/FI/Checkout/sql/fi_checkout_setup/mysql4-install-1.0.0.php +0 -0
  18. app/code/local/FI/Checkout/Block/Block/Info.php +0 -270
  19. app/code/local/FI/Checkout/Model/Observer.php +0 -50
  20. app/design/frontend/default/default/template/freaks/checkout/block.phtml +1 -1
  21. app/design/frontend/default/default/template/freaks/checkout/block/info.phtml +8 -8
  22. app/design/frontend/default/default/template/freaks/checkout/payment.phtml +1 -1
  23. app/design/frontend/default/default/template/freaks/checkout/payment_methods.phtml +2 -2
  24. app/design/frontend/default/default/template/freaks/checkout/shipping/available.phtml +2 -2
  25. app/etc/modules/FI_Checkout.xml +1 -1
  26. package.xml +15 -12
  27. skin/frontend/default/default/js/freaks_checkout.js +2 -45
app/code/{local → community}/FI/Checkout/Block/Block.php RENAMED
File without changes
app/code/community/FI/Checkout/Block/Block/Info.php ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Zero Step Checkout user information block
4
+ *
5
+ * @category FI
6
+ * @package FI_Checkout
7
+ * @author Sergiy Stotskiy <sergiy.stotskiy@freaksidea.com>
8
+ */
9
+ class FI_Checkout_Block_Block_Info extends Mage_Checkout_Block_Onepage_Abstract
10
+ {
11
+ /**
12
+ * Customer shipping address
13
+ *
14
+ * @var Mage_Sales_Model_Quote_Address
15
+ */
16
+ protected $_address;
17
+
18
+ /**
19
+ * Customer virtual order. Saved in session
20
+ *
21
+ * @var FI_Checkout_Model_Order
22
+ */
23
+ protected $_order;
24
+
25
+ /**
26
+ * Constructor. Set block template.
27
+ * Set user values to block. Update addresses
28
+ */
29
+ protected function _construct()
30
+ {
31
+ $this->_order = $this->helper('fi_checkout')->buildSessionOrder();
32
+ $this->setTemplate('freaks/checkout/block/info.phtml');
33
+
34
+ if ($this->isCustomerLoggedIn()) {
35
+ $this->_fillInWithCustomer();
36
+ }
37
+ $this->_fillInWithSession();
38
+ $this->_syncQuoteAddresses();
39
+ }
40
+
41
+ /**
42
+ * Fill block values with logged in customer info
43
+ *
44
+ * @return void
45
+ */
46
+ protected function _fillInWithCustomer()
47
+ {
48
+ $customer = $this->getCustomer();
49
+ $address = $this->getAddress();
50
+
51
+ $this->addData(array(
52
+ 'address_id' => $address->getCustomerAddressId(),
53
+ 'customer_email' => $customer->getEmail(),
54
+ 'customer_region' => $address->getRegion(),
55
+ 'customer_city' => $address->getCity(),
56
+ 'customer_building' => $address->getStreet(2),
57
+ 'customer_room' => $address->getStreet(3),
58
+ 'customer_phone' => $address->getTelephone(),
59
+ 'customer_zip' => $address->getPostcode()
60
+ ));
61
+ }
62
+
63
+ /**
64
+ * Fill block values with customer session information
65
+ *
66
+ * @return void
67
+ */
68
+ protected function _fillInWithSession()
69
+ {
70
+ $customer = $this->_order->getCustomer();
71
+ $address = $this->_order->getAddress();
72
+
73
+ $this->addData(array_filter(array(
74
+ 'customer_email' => $customer->getEmail(),
75
+ 'customer_region' => $address->getRegion(),
76
+ 'customer_city' => $address->getCity(),
77
+ 'customer_building' => $address->getStreet(1),
78
+ 'customer_room' => $address->getStreet(2),
79
+ 'customer_phone' => $address->getTelephone(),
80
+ 'customer_zip' => $address->getPostcode(),
81
+ 'customer_note' => $customer->getNote()
82
+ )));
83
+ }
84
+
85
+ /**
86
+ * Gets customer address if customer is logged in,
87
+ * otherwise creates new one
88
+ *
89
+ * @return Mage_Sales_Model_Quote_Address
90
+ */
91
+ protected function _getOrCreateAddress()
92
+ {
93
+ if ($this->isCustomerLoggedIn()) {
94
+ return $this->getQuote()->getShippingAddress();
95
+ } else {
96
+ return Mage::getModel('sales/quote_address');
97
+ }
98
+ }
99
+
100
+ protected function _importCustomerAddressTo(Mage_Sales_Model_Quote_Address $address)
101
+ {
102
+ $customerAddress = $this->getCustomer()->getPrimaryShippingAddress();
103
+ if ($customerAddress) {
104
+ $address->importCustomerAddress($customerAddress)
105
+ ->setSaveInAddressBook(0);
106
+ }
107
+ }
108
+
109
+ protected function _syncQuoteAddresses()
110
+ {
111
+ $billingAddress = $this->getQuote()->getBillingAddress();
112
+ $this->_order->exportAddressTo($billingAddress);
113
+ $billingAddress->implodeStreetAddress();
114
+
115
+ $this->_order->exportAddressTo($this->getAddress());
116
+ $this->getAddress()->implodeStreetAddress();
117
+ }
118
+
119
+ /**
120
+ * Return shipping address
121
+ *
122
+ * @return Mage_Sales_Model_Quote_Address
123
+ */
124
+ public function getAddress()
125
+ {
126
+ if (!$this->_address) {
127
+ $this->_address = $this->_getOrCreateAddress();
128
+ $this->isCustomerLoggedIn() && $this->_importCustomerAddressTo($this->_address);
129
+ }
130
+
131
+ return $this->_address;
132
+ }
133
+
134
+ /**
135
+ * Return customer full name
136
+ *
137
+ * @return string
138
+ */
139
+ public function getCustomerName()
140
+ {
141
+ return $this->isCustomerLoggedIn()
142
+ ? $this->getFirstname() . ' ' . $this->getLastname()
143
+ : $this->_order->getCustomerName();
144
+ }
145
+
146
+ /**
147
+ * Return Customer Address First Name
148
+ * If Sales Quote Address First Name is not defined - return Customer First Name
149
+ *
150
+ * @return string
151
+ */
152
+ public function getFirstname()
153
+ {
154
+ $firstname = $this->getAddress()->getFirstname();
155
+ if (empty($firstname) && $this->getCustomer()) {
156
+ $firstname = $this->getCustomer()->getFirstname();
157
+ }
158
+ return $firstname;
159
+ }
160
+
161
+ /**
162
+ * Return Customer Address Last Name
163
+ * If Sales Quote Address Last Name is not defined - return Customer Last Name
164
+ *
165
+ * @return string
166
+ */
167
+ public function getLastname()
168
+ {
169
+ $lastname = $this->getAddress()->getLastname();
170
+ if (empty($lastname) && $this->getCustomer()) {
171
+ return $this->getCustomer()->getLastname();
172
+ }
173
+ return $lastname;
174
+ }
175
+
176
+ /**
177
+ * Return address street
178
+ *
179
+ * @return string
180
+ */
181
+ public function getStreet()
182
+ {
183
+ if ($this->isCustomerLoggedIn()) {
184
+ $street = $this->getAddress()->getStreet(1);
185
+ } else {
186
+ $street = $this->_order->getAddress()->getStreet();
187
+ if (is_array($street)) {
188
+ $street = reset($street);
189
+ }
190
+ }
191
+
192
+ return $street;
193
+ }
194
+
195
+ /**
196
+ * Return customer location (country, region, city)
197
+ *
198
+ * @return string
199
+ */
200
+ public function getCustomerLocation()
201
+ {
202
+ $location = $this->_collectCustomerLocation();
203
+ return join(', ', array_filter($location));
204
+ }
205
+
206
+ protected function _collectCustomerLocation()
207
+ {
208
+ $location = array();
209
+ $address = $this->getAddress();
210
+
211
+ if (!$this->helper('fi_checkout')->useOnlyDefaultCountry()) {
212
+ $location[] = $address->getCountryModel()->getName();
213
+ }
214
+ if ($address->getRegionId()) {
215
+ $location[] = $address->getRegionModel()->getName();
216
+ } elseif ($address->getRegion()) {
217
+ $location[] = $address->getRegion();
218
+ }
219
+ $location[] = $address->getCity();
220
+ return $location;
221
+ }
222
+
223
+ /**
224
+ * Return location help message based on configuration
225
+ *
226
+ * @see FI_Checkout_Helper_Data::useOnlyDefaultCountry
227
+ * @return string
228
+ */
229
+ public function getLocationHelp()
230
+ {
231
+ if ($this->helper('fi_checkout')->useOnlyDefaultCountry()) {
232
+ return $this->__('City');
233
+ } else {
234
+ return $this->__('Country, Region, City (e.g. Ukraine, Kyiv, Kyiv)');
235
+ }
236
+ }
237
+
238
+ /**
239
+ * Return country select box block
240
+ *
241
+ * @param string $type
242
+ * @return Mage_Core_Block_Html_Select
243
+ */
244
+ public function getCountryBlock($type = 'shipping')
245
+ {
246
+ $countryId = $this->getAddress()->getCountryId();
247
+ if (!$countryId) {
248
+ $countryId = $this->helper('fi_checkout')->getDefaultCountryId();
249
+ }
250
+ $select = $this->getLayout()->createBlock('core/html_select')
251
+ ->setTitle($this->helper('checkout')->__('Country'))
252
+ ->setClass('validate-select non-storable')
253
+ ->setValue($countryId)
254
+ ->setOptions($this->getCountryOptions());
255
+
256
+ return $select;
257
+ }
258
+
259
+ /**
260
+ * Return region select box block
261
+ *
262
+ * @param string $type
263
+ * @return Mage_Core_Block_Html_Select
264
+ */
265
+ public function getRegionBlock()
266
+ {
267
+ $select = $this->getLayout()->createBlock('core/html_select')
268
+ ->setTitle($this->helper('checkout')->__('State/Province'))
269
+ ->setClass('required-entry validate-state non-storable')
270
+ ->setValue($this->getAddress()->getRegionId())
271
+ ->setOptions($this->getRegionCollection()->toOptionArray());
272
+
273
+ return $select;
274
+ }
275
+ }
app/code/{local → community}/FI/Checkout/Block/Newsletter.php RENAMED
File without changes
app/code/{local → community}/FI/Checkout/Block/Payment/Methods.php RENAMED
File without changes
app/code/{local → community}/FI/Checkout/Helper/Data.php RENAMED
@@ -12,6 +12,8 @@ class FI_Checkout_Helper_Data extends Mage_Core_Helper_Abstract
12
  /**
13
  * Xml configuration pathes
14
  */
 
 
15
  const XML_PATH_DEFAULT_COUNTRY = 'checkout/easyco/default_country';
16
  const XML_PATH_DEFAULT_REGION = 'checkout/easyco/default_region';
17
  const XML_PATH_DEFAULT_CITY = 'checkout/easyco/default_city';
@@ -24,14 +26,7 @@ class FI_Checkout_Helper_Data extends Mage_Core_Helper_Abstract
24
  const XML_PATH_SHOW_NEWSLETTER = 'checkout/easyco/show_newsletter';
25
  const XML_PATH_NEWSLETTER_SEND_SUCCESS_EMAIL = 'checkout/easyco/newsletter_send_success';
26
  const XML_PATH_NEWSLETTER_SEND_REQUEST_EMAIL = 'checkout/easyco/newsletter_send_request';
27
-
28
- protected
29
- /**
30
- * List of specific address fields
31
- *
32
- * @var array
33
- */
34
- $_copyAddressFields = array('country_id', 'region', 'region_id', 'city', 'postcode');
35
 
36
  /**
37
  * Return attribute options
@@ -50,7 +45,7 @@ class FI_Checkout_Helper_Data extends Mage_Core_Helper_Abstract
50
  ->getAllOptions($withEmpty);
51
 
52
  $set = array();
53
- foreach ($data as &$row) {
54
  $set[$row['value']] = $row['label'];
55
  }
56
 
@@ -64,12 +59,15 @@ class FI_Checkout_Helper_Data extends Mage_Core_Helper_Abstract
64
  */
65
  public function getDefaultShippingAddress()
66
  {
67
- return array(
68
- 'country_id' => $this->getDefaultCountry(),
69
  'region' => $this->getDefaultRegion(),
70
  'region_id' => null,
71
  'city' => $this->getDefaultCity()
72
  );
 
 
 
73
  }
74
 
75
  /**
@@ -86,21 +84,6 @@ class FI_Checkout_Helper_Data extends Mage_Core_Helper_Abstract
86
  return $text;
87
  }
88
 
89
- /**
90
- * Copy specific fields from one address to another
91
- *
92
- * @param Mage_Sales_Model_Quote_Address $from
93
- * @param $to
94
- * @return Mage_Sales_Model_Quote_Address
95
- */
96
- public function copyAddress(Mage_Sales_Model_Quote_Address $from, Mage_Sales_Model_Quote_Address $to)
97
- {
98
- foreach ($this->_copyAddressFields as $field) {
99
- $to->setData($field, $from->getData($field));
100
- }
101
- return $to;
102
- }
103
-
104
  /**
105
  * Return default city
106
  *
@@ -126,7 +109,7 @@ class FI_Checkout_Helper_Data extends Mage_Core_Helper_Abstract
126
  *
127
  * @return string
128
  */
129
- public function getDefaultCountry()
130
  {
131
  return Mage::getStoreConfig(self::XML_PATH_DEFAULT_COUNTRY);
132
  }
@@ -201,65 +184,6 @@ class FI_Checkout_Helper_Data extends Mage_Core_Helper_Abstract
201
  return $this->getLocationType() == FI_Checkout_Model_Source::LOCATION_ONE;
202
  }
203
 
204
- /**
205
- * Return address information stored in session.
206
- * If session is empty, return default shipping information.
207
- *
208
- * @return array
209
- */
210
- public function getAddressInfo()
211
- {
212
- $session = Mage::getSingleton('customer/session');
213
- $data = $session->getShippingInfo();
214
-
215
- return $data;
216
- }
217
-
218
- /**
219
- * Update Shipping Address based on session and default config values.
220
- *
221
- * @param Varien_Object $address
222
- * @return Varien_Object
223
- */
224
- public function updateAddress(Varien_Object $address)
225
- {
226
- $data = $this->getAddressInfo();
227
- if (!($data || $address->getCountryId() || $address->getCity())) {
228
- $data = $this->getDefaultShippingAddress();
229
- }
230
-
231
- $shippingMethod = Mage::getSingleton('customer/session')->getShippingMethod();
232
- if ($shippingMethod) {
233
- $address->setShippingMethod($shippingMethod)
234
- ->setCollectShippingRates(true);
235
- }
236
-
237
- if (is_array($data)) {
238
- $address->addData($data);
239
- }
240
- return $address;
241
- }
242
-
243
- /**
244
- * Auto assign shipping method if there is only one available method
245
- *
246
- * @param Mage_Sales_Model_Quote_Address $address
247
- * @return FI_Checkout_Helper_Data
248
- */
249
- public function autoAssignShippingMethod(Mage_Sales_Model_Quote_Address $address)
250
- {
251
- $rates = $address->collectShippingRates()->getGroupedAllShippingRates();
252
- if (is_array($rates) && count($rates) == 1 && count(reset($rates)) == 1) {
253
- $rate = reset($rates);
254
- $rate = reset($rate);
255
- if (is_object($rate)) {
256
- $address->setShippingMethod($rate->getCode());
257
- }
258
- }
259
- $address->setCollectShippingRates(true);
260
- return $this;
261
- }
262
-
263
  /**
264
  * Check posibility to place order
265
  *
@@ -289,30 +213,26 @@ class FI_Checkout_Helper_Data extends Mage_Core_Helper_Abstract
289
  /**
290
  * Return password based on choosen type
291
  *
292
- * @param array $data user information
293
  * @return string
294
  */
295
- public function getPassword($data)
296
  {
297
  $password = '';
298
  switch ($this->getPasswordType()) {
299
  case FI_Checkout_Model_Source::PASSWORD_FIELD:
300
- if (!empty($data['password'])) {
301
- $password = $data['password'];
302
- }
303
  break;
304
  case FI_Checkout_Model_Source::PASSWORD_PHONE:
305
- if (!empty($data['address']['telephone'])) {
306
- $password = $data['address']['telephone'];
307
- $plen = strlen($password);
308
- if ($plen < 6) {
309
- $password .= $this->generateRandomKey(6 - $plen);
310
- }
311
  }
312
  break;
313
  }
314
 
315
- return $password ? $password : $this->generateRandomKey(8);
316
  }
317
 
318
  /**
@@ -426,4 +346,130 @@ class FI_Checkout_Helper_Data extends Mage_Core_Helper_Abstract
426
  }
427
  return true;
428
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
429
  }
12
  /**
13
  * Xml configuration pathes
14
  */
15
+ const XML_PATH_DEFAULT_SHIPPING_METHOD = 'checkout/easyco/default_shipping_method';
16
+ const XML_PATH_DEFAULT_PAYMENT_METHOD = 'checkout/easyco/default_payment_method';
17
  const XML_PATH_DEFAULT_COUNTRY = 'checkout/easyco/default_country';
18
  const XML_PATH_DEFAULT_REGION = 'checkout/easyco/default_region';
19
  const XML_PATH_DEFAULT_CITY = 'checkout/easyco/default_city';
26
  const XML_PATH_SHOW_NEWSLETTER = 'checkout/easyco/show_newsletter';
27
  const XML_PATH_NEWSLETTER_SEND_SUCCESS_EMAIL = 'checkout/easyco/newsletter_send_success';
28
  const XML_PATH_NEWSLETTER_SEND_REQUEST_EMAIL = 'checkout/easyco/newsletter_send_request';
29
+ const XML_PATH_UPDATE_TOTALS_WHEN_PAYMENT_CHANGED = 'checkout/easyco/update_totals_when_payment_changed';
 
 
 
 
 
 
 
30
 
31
  /**
32
  * Return attribute options
45
  ->getAllOptions($withEmpty);
46
 
47
  $set = array();
48
+ foreach ($data as $row) {
49
  $set[$row['value']] = $row['label'];
50
  }
51
 
59
  */
60
  public function getDefaultShippingAddress()
61
  {
62
+ $address = array(
63
+ 'country_id' => $this->getDefaultCountryId(),
64
  'region' => $this->getDefaultRegion(),
65
  'region_id' => null,
66
  'city' => $this->getDefaultCity()
67
  );
68
+
69
+ $address['location'] = join(', ', array($address['country_id'], $address['region'], $address['city']));
70
+ return $this->parseLocationOf(new Varien_Object($address));
71
  }
72
 
73
  /**
84
  return $text;
85
  }
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  /**
88
  * Return default city
89
  *
109
  *
110
  * @return string
111
  */
112
+ public function getDefaultCountryId()
113
  {
114
  return Mage::getStoreConfig(self::XML_PATH_DEFAULT_COUNTRY);
115
  }
184
  return $this->getLocationType() == FI_Checkout_Model_Source::LOCATION_ONE;
185
  }
186
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  /**
188
  * Check posibility to place order
189
  *
213
  /**
214
  * Return password based on choosen type
215
  *
216
+ * @param Varien_Object $customer
217
  * @return string
218
  */
219
+ public function getPasswordFor(Varien_Object $customer)
220
  {
221
  $password = '';
222
  switch ($this->getPasswordType()) {
223
  case FI_Checkout_Model_Source::PASSWORD_FIELD:
224
+ $passwod = $customer->getPassword();
 
 
225
  break;
226
  case FI_Checkout_Model_Source::PASSWORD_PHONE:
227
+ $password = $customer->getAddress()->getTelephone();
228
+ $size = strlen($password);
229
+ if ($size < 6) {
230
+ $password .= $this->generateRandomKey(6 - $size);
 
 
231
  }
232
  break;
233
  }
234
 
235
+ return empty($password) ? $this->generateRandomKey(8) : $password;
236
  }
237
 
238
  /**
346
  }
347
  return true;
348
  }
349
+
350
+ public function explodeLocation($location)
351
+ {
352
+ if ($this->useOnlyDefaultCountry()) {
353
+ $location = $this->getDefaultCountryId() . ',' . $location;
354
+ }
355
+ $location = array_map('trim', explode(',', $location));
356
+ return $location + array_fill(0, 3, null);
357
+ }
358
+
359
+ /**
360
+ * Parse address information according to the config
361
+ *
362
+ * @param Varien_Object $address
363
+ * @return array
364
+ */
365
+ public function parseLocationOf(Varien_Object $address)
366
+ {
367
+ $earth = Mage::getResourceModel('fi_checkout/countries');
368
+ $data = array(
369
+ 'country_id' => null,
370
+ 'region' => null,
371
+ 'region_id' => null,
372
+ 'city' => null,
373
+ 'postcode' => $address->getData('postcode')
374
+ );
375
+
376
+ if ($this->isLocationAsOneField()) {
377
+ list($country, $region, $city) = $this->explodeLocation($address->getData('location'));
378
+
379
+ if (!empty($country)) {
380
+ $data['country_id'] = $earth->getCountryCodeByName($country);
381
+
382
+ if (!empty($region)) {
383
+ $data['city'] = $data['region'] = $region;
384
+ }
385
+
386
+ if (!empty($city)) {
387
+ $data['city'] = $city;
388
+ }
389
+ }
390
+ } else {
391
+ $data['country_id'] = $address->getData('country_id');
392
+ $data['region'] = $address->getData('region');
393
+ $data['region_id'] = $address->getData('region_id');
394
+ $data['city'] = $address->getData('city');
395
+ }
396
+
397
+ if ($this->useOnlyDefaultCountry() || empty($data['country_id'])) {
398
+ $data['country_id'] = $this->getDefaultCountryId();
399
+ }
400
+
401
+ if (!empty($data['region']) && empty($data['region_id'])) {
402
+ $data['region_id'] = $earth->getRegionIdByName(trim($data['region']), $data['country_id']);
403
+ if ($data['region_id']) {
404
+ $data['region'] = null;
405
+ }
406
+ }
407
+
408
+ return $data;
409
+ }
410
+
411
+ /**
412
+ * Prepare address information from request
413
+ *
414
+ * @param FI_Checkout_Model_Order $order
415
+ * @return array
416
+ */
417
+ public function extractAddressFrom(FI_Checkout_Model_Order $order)
418
+ {
419
+ $address = $order->assembleAddress();
420
+
421
+ if (!$order->getCustomer()->getIsLoggedIn()) {
422
+ $password = $this->getPasswordFor($order->getCustomer());
423
+ $address['customer_password'] = $password;
424
+ $address['confirm_password'] = $password;
425
+ }
426
+ return $address;
427
+ }
428
+
429
+ public function getDefaultShippingMethod()
430
+ {
431
+ return Mage::getStoreConfig(self::XML_PATH_DEFAULT_SHIPPING_METHOD);
432
+ }
433
+
434
+ public function getDefaultPaymentMethod()
435
+ {
436
+ return Mage::getStoreConfig(self::XML_PATH_DEFAULT_PAYMENT_METHOD);
437
+ }
438
+
439
+ public function shouldUpdateTotalsWhenPaymentChanged()
440
+ {
441
+ return Mage::getStoreConfigFlag(self::XML_PATH_UPDATE_TOTALS_WHEN_PAYMENT_CHANGED);
442
+ }
443
+
444
+ public function buildSessionOrder()
445
+ {
446
+ $session = Mage::getSingleton('customer/session');
447
+ $order = Mage::getModel('fi_checkout/order')->setSession($session);
448
+ if ($order->getAddress()->isEmpty()) {
449
+ if ($session->isLoggedIn()) {
450
+ $order->setAddress($session->getCustomer()->getPrimaryShippingAddress()->getData());
451
+ } else {
452
+ $order->setAddress($this->getDefaultShippingAddress());
453
+ }
454
+ }
455
+
456
+ if (!$order->getPayment()->getMethod()) {
457
+ $order->setPaymentMethod($this->getDefaultPaymentMethod());
458
+ }
459
+ if (!$order->getShippingMethod()) {
460
+ $order->setShippingMethod($this->getDefaultShippingMethod());
461
+ }
462
+ return $order;
463
+ }
464
+
465
+ public function getActivePaymentMethods()
466
+ {
467
+ $methods = array();
468
+ foreach (Mage::getStoreConfig('payment') as $code => $config) {
469
+ if (Mage::getStoreConfigFlag('payment/' . $code . '/active')) {
470
+ $methods[$code] = $config['title'];
471
+ }
472
+ }
473
+ return $methods;
474
+ }
475
  }
app/code/community/FI/Checkout/Model/Observer.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Zero Step Checkout observer model
4
+ *
5
+ * @category FI
6
+ * @package FI_Checkout
7
+ * @author Sergiy Stotskiy <sergiy.stotskiy@freaksidea.com>
8
+ */
9
+ class FI_Checkout_Model_Observer
10
+ {
11
+ /**
12
+ * Restore shipping method from session or auto assign if there is only one available method.
13
+ * Listen event sales_quote_collect_totals_before
14
+ *
15
+ * @param Varien_Event_Observer $observer
16
+ * @return FI_Checkout_Model_Observer
17
+ */
18
+ public function collectTotalsBefore(Varien_Event_Observer $observer)
19
+ {
20
+ $quote = $observer->getEvent()->getQuote();
21
+ $address = $quote->getShippingAddress();
22
+
23
+ Mage::helper('fi_checkout')->buildSessionOrder()
24
+ ->exportAddressTo($address)
25
+ ->detectShippingMethodFor($address)
26
+ ->exportAddressTo($address)
27
+ ->exportPaymentTo($quote->getPayment())
28
+ ;
29
+ return $this;
30
+ }
31
+
32
+ /**
33
+ * Add user comment to order.
34
+ * Listen event checkout_type_onepage_save_order
35
+ *
36
+ * @param Varien_Event_Observer $observer
37
+ * @return FI_Checkout_Model_Observer
38
+ */
39
+ public function addOrderComment(Varien_Event_Observer $observer)
40
+ {
41
+ $order = $observer->getEvent()->getOrder();
42
+ $request = Mage::app()->getRequest();
43
+
44
+ $data = $request->getParam('user');
45
+ if (!empty($data['note'])) {
46
+ $comment = strip_tags($data['note']);
47
+ if (!empty($comment)) {
48
+ $order->setCustomerNote($comment);
49
+ }
50
+ }
51
+ return $this;
52
+ }
53
+
54
+ /**
55
+ * Create invoice if possible to process zero sub total
56
+ * Listen event checkout_submit_all_after
57
+ *
58
+ * @param Varien_Event_Observer $observer
59
+ * @return FI_Checkout_Model_Observer
60
+ */
61
+ public function tryToProcessOrder(Varien_Event_Observer $observer)
62
+ {
63
+ $helper = Mage::helper("payment");
64
+ $order = $observer->getEvent()->getOrder();
65
+ $storeId = $order->getStoreId();
66
+ $zeroSubTotalPaymentAction = $helper->getZeroSubTotalPaymentAutomaticInvoice($storeId);
67
+
68
+ if ($helper->isZeroSubTotal($storeId)
69
+ && $order->getGrandTotal() == 0
70
+ && $zeroSubTotalPaymentAction == Mage_Payment_Model_Method_Abstract::ACTION_AUTHORIZE_CAPTURE
71
+ && $helper->getZeroSubTotalOrderStatus($storeId) == 'pending'
72
+ ) {
73
+ $invoice = $this->_buildInvoiceFor($order);
74
+ $invoice->getOrder()->setIsInProcess(true);
75
+ $invoice->save();
76
+ }
77
+ return $this;
78
+ }
79
+
80
+ /**
81
+ * Create invoice
82
+ *
83
+ * @param Mage_Sales_Model_Order $order
84
+ * @return Mage_Sales_Model_Order_Invoice
85
+ */
86
+ protected function _buildInvoiceFor($order)
87
+ {
88
+ $items = array();
89
+ foreach ($order->getAllItems() as $item) {
90
+ $items[$item->getId()] = $item->getQtyOrdered();
91
+ }
92
+ $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice($items);
93
+ $invoice->setEmailSent(true)->register();
94
+
95
+ return $invoice;
96
+ }
97
+ }
app/code/community/FI/Checkout/Model/Order.php ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FI_Checkout_Model_Order
4
+ {
5
+ protected
6
+ $_scopeName = 'fi_order',
7
+ $_storage,
8
+ $_customer,
9
+ $_address,
10
+ $_payment,
11
+ $_session;
12
+
13
+ public function __construct() {
14
+ $this->_address = new Varien_Object();
15
+ $this->_customer = new Varien_Object();
16
+ $this->_payment = new Varien_Object();
17
+ $this->_storage = new Varien_Object();
18
+ }
19
+
20
+ protected function _getStorage()
21
+ {
22
+ return $this->_storage->setData($this->_getResource()->getData($this->_scopeName));
23
+ }
24
+
25
+ protected function _getResource()
26
+ {
27
+ return $this->_session;
28
+ }
29
+
30
+ public function setSession(Mage_Customer_Model_Session $session)
31
+ {
32
+ $this->_session = $session;
33
+ return $this;
34
+ }
35
+
36
+ public function __call($method, $args)
37
+ {
38
+ $storage = $this->_getStorage();
39
+ $result = call_user_func_array(array($storage, $method), $args);
40
+ $this->_getResource()->setData($this->_scopeName, $storage->getData());
41
+ return $result;
42
+ }
43
+
44
+ public function setData($key, $value = null)
45
+ {
46
+ $storage = $this->_getStorage();
47
+ if (is_array($key)) {
48
+ $storage->addData($key);
49
+ } else {
50
+ $storage->setData($key, $value);
51
+ }
52
+ $this->_getResource()->setData($this->_scopeName, $storage->getData());
53
+ return $this;
54
+ }
55
+
56
+ public function getData($key, $index = null)
57
+ {
58
+ return $this->_getStorage()->getData($key, $index);
59
+ }
60
+
61
+ public function getAddress()
62
+ {
63
+ if ($this->_address->getData() != $this->getData('user/address')) {
64
+ $this->_address->addData($this->getData('user/address'));
65
+ }
66
+ return $this->_address;
67
+ }
68
+
69
+ public function setAddress($address)
70
+ {
71
+ $fields = array('country_id', 'region', 'region_id', 'city', 'postcode', 'street', 'telephone');
72
+ $address = array_intersect_key($address, array_flip($fields));
73
+
74
+ $customer = $this->getCustomer()->setAddress($address)->getData();
75
+ $this->setData('user', $customer);
76
+ return $this;
77
+ }
78
+
79
+ public function getCustomer()
80
+ {
81
+ if ($this->_customer->getData() != $this->getData('user')) {
82
+ $this->_customer->addData($this->getData('user'));
83
+ }
84
+ $this->_customer->setIsLoggedIn($this->_getResource()->isLoggedIn())
85
+ ->setAddress($this->getAddress());
86
+ return $this->_customer;
87
+ }
88
+
89
+ public function getPayment()
90
+ {
91
+ if ($this->_payment->getData() != $this->getData('payment')) {
92
+ $this->_payment->addData($this->getData('payment'));
93
+ }
94
+ return $this->_payment;
95
+ }
96
+
97
+ public function setPaymentMethod($method)
98
+ {
99
+ $payment = $this->getPayment()->setMethod($method)->getData();
100
+ $this->setData('payment', $payment);
101
+ return $this;
102
+ }
103
+
104
+ public function getCustomerName()
105
+ {
106
+ return $this->getCustomer()->getName();
107
+ }
108
+
109
+ public function drop()
110
+ {
111
+ $this->_customer = null;
112
+ $this->_address = null;
113
+ $this->_payment = null;
114
+ $this->_storage = null;
115
+ $this->_getResource()->unsetData($this->_scopeName);
116
+ }
117
+
118
+ /**
119
+ * Update Shipping Address based on session and default config values.
120
+ *
121
+ * @param Mage_Sales_Model_Quote_Address $address
122
+ * @return FI_Checkout_Model_Order
123
+ */
124
+ public function exportAddressTo(Mage_Sales_Model_Quote_Address $address)
125
+ {
126
+ $shippingMethod = $this->getShippingMethod();
127
+ if ($shippingMethod) {
128
+ $address->setShippingMethod($shippingMethod)
129
+ ->setCollectShippingRates(true);
130
+ }
131
+
132
+ $orderAddress = $this->getData('user/address');
133
+ if (is_array($orderAddress)) {
134
+ unset($orderAddress['location']);
135
+ $address->addData($orderAddress);
136
+ }
137
+ return $this;
138
+ }
139
+
140
+ /**
141
+ * Auto assign shipping method if there is only one available method
142
+ *
143
+ * @param Mage_Sales_Model_Quote_Address $address
144
+ * @return FI_Checkout_Model_Order
145
+ */
146
+ public function detectShippingMethodFor(Mage_Sales_Model_Quote_Address $address)
147
+ {
148
+ $rates = $address->collectShippingRates()->getGroupedAllShippingRates();
149
+ if (is_array($rates) && count($rates) == 1 && count(reset($rates)) == 1) {
150
+ $rate = reset($rates);
151
+ $rate = reset($rate);
152
+ if (is_object($rate)) {
153
+ $this->setShippingMethod($rate->getCode());
154
+ }
155
+ }
156
+ return $this;
157
+ }
158
+
159
+ public function updateAddressWith($data)
160
+ {
161
+ $newAddress = $this->getAddress()->addData($data)->getData();
162
+ $this->setAddress($newAddress);
163
+ return $this;
164
+ }
165
+
166
+ public function assembleAddress()
167
+ {
168
+ $address = $this->getData('user/address');
169
+ $address['id'] = $this->getAddress()->getId();
170
+ unset($address['location']);
171
+
172
+ $fullName = trim($this->getCustomerName());
173
+ $fullName = array_filter(explode(' ', $fullName, 2), 'trim') + array_fill(0, 2, null);
174
+ list($address['firstname'], $address['lastname']) = $fullName;
175
+
176
+ $address['email'] = $this->getCustomer()->getEmail();
177
+ $address['use_for_shipping'] = true;
178
+ return $address;
179
+ }
180
+
181
+ public function exportPaymentTo(Mage_Sales_Model_Quote_Payment $payment)
182
+ {
183
+ $resource = $this->getPayment();
184
+ if (!$resource->getMethod()) {
185
+ return $this;
186
+ }
187
+
188
+ $countryId = $this->getAddress()->getCountryId();
189
+ $payment->setMethod($resource->getMethod());
190
+ $method = $payment->getMethodInstance();
191
+ if (!$method->isAvailable($payment->getQuote()) || !$method->canUseForCountry($countryId)) {
192
+ $payment->unsMethod();
193
+ }
194
+ return $this;
195
+ }
196
+ }
app/code/{local → community}/FI/Checkout/Model/Page.php RENAMED
File without changes
app/code/{local → community}/FI/Checkout/Model/Resource/Countries.php RENAMED
@@ -68,73 +68,25 @@ class FI_Checkout_Model_Resource_Countries extends Mage_Directory_Model_Mysql4_C
68
  * @param int $limit
69
  * @return array
70
  */
71
- public function filter($location, $limit = 15)
72
  {
73
- $result = array();
74
- $helper = Mage::helper('core/string');
75
- $location = explode(',', $location);
76
- $location = array_map('trim', $location);
77
- $countries = Mage::app()->getLocale()
78
- ->getCountryTranslationList();
79
-
80
- if (empty($location[0])) {
81
- return $result;
82
- }
83
 
84
- $checkoutHelper = Mage::helper('fi_checkout');
85
- if (empty($location[1])) {
86
- $i = 0;
87
- $exp = $checkoutHelper->lowerCase($location[0]);
88
- foreach ($countries as $code => $name) {
89
- $title = $checkoutHelper->lowerCase($name);
90
- if ($helper->strpos($title, $exp) !== false) {
91
- $result[] = $name;
92
- $i++;
93
- if ($i == $limit) {
94
- break;
95
- }
96
- }
97
- }
98
  }
99
 
100
- if (empty($result) && empty($location[2])) {
101
- if (empty($location[1])) {
102
- $location[1] = $location[0];
103
- }
104
- $location[0] = $checkoutHelper->lowerCase($location[0]);
105
- $countries = array_flip(array_map(array($checkoutHelper, 'lowerCase'), $countries));
106
- if (isset($countries[$location[0]])) {
107
- $countryCode = $countries[$location[0]];
108
- } else {
109
- $countryCode = $checkoutHelper->getDefaultCountry();
110
- }
111
-
112
- $adapter = $this->getSelect()->getAdapter();
113
- $select = $adapter->select()
114
- ->from(array('r' => $this->_regionTable), 'default_name')
115
- ->joinLeft(
116
- array('rn' => $this->_regionNameTable),
117
- $adapter->quote('rn.region_id = r.region_id AND locale = ?', Mage::app()->getLocale()->getLocaleCode()),
118
- array('name')
119
- )
120
- ->where('r.country_id = ?', $countryCode)
121
- ->where('IF(name, name, default_name) LIKE ?', '%' . $location[1] . '%')
122
- ->limit($limit);
123
-
124
- $result = $adapter->fetchAll($select);
125
- foreach ($result as &$row) {
126
- $row = $row['name'] ? $row['name'] : $row['default_name'];
127
- }
128
  }
129
 
130
- if (empty($result) && empty($location[3])) {
131
- if (empty($location[2])) {
132
- $location[2] = $location[1];
133
- }
134
- // city autocomplete
135
  }
136
 
137
- return $result;
 
138
  }
139
 
140
  /**
@@ -163,4 +115,69 @@ class FI_Checkout_Model_Resource_Countries extends Mage_Directory_Model_Mysql4_C
163
  $row = $adapter->fetchRow($select);
164
  return empty($row['region_id']) ? null : $row['region_id'];
165
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  }
68
  * @param int $limit
69
  * @return array
70
  */
71
+ public function search($location, $limit = 15)
72
  {
73
+ list($countryName, $regionName, $cityName) = $location;
 
 
 
 
 
 
 
 
 
74
 
75
+ if (empty($countryName)) {
76
+ return array();
 
 
 
 
 
 
 
 
 
 
 
 
77
  }
78
 
79
+ if (empty($regionName)) {
80
+ $term = $this->_downcase($countryName);
81
+ return $this->_searchOverCountries($term, $limit);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  }
83
 
84
+ if (empty($cityName)) {
85
+ return $this->_searchOverRegions($regionName, $countryName, $limit);
 
 
 
86
  }
87
 
88
+ // no autocomplete for city
89
+ return array();
90
  }
91
 
92
  /**
115
  $row = $adapter->fetchRow($select);
116
  return empty($row['region_id']) ? null : $row['region_id'];
117
  }
118
+
119
+ public function getCountryCodeByName($countryName)
120
+ {
121
+ $countries = array_flip(array_map(array($this, '_downcase'), $this->_getAllCountries()));
122
+
123
+ $countryName = $this->_downcase($countryName);
124
+ if (isset($countries[$countryName])) {
125
+ return $countries[$countryName];
126
+ } else {
127
+ return Mage::helper('fi_checkout')->getDefaultCountryId();
128
+ }
129
+ }
130
+
131
+ protected function _searchOverCountries($term, $limit)
132
+ {
133
+ $countryNames = array();
134
+ $helper = Mage::helper('core/string');
135
+
136
+ $i = 0;
137
+ foreach ($this->_getAllCountries() as $code => $name) {
138
+ $title = $this->_downcase($name);
139
+ if ($helper->strpos($title, $term) !== false) {
140
+ $countryNames[] = $name;
141
+ $i++;
142
+ if ($i == $limit) {
143
+ break;
144
+ }
145
+ }
146
+ }
147
+ return $countryNames;
148
+ }
149
+
150
+ protected function _searchOverRegions($term, $countryName, $limit)
151
+ {
152
+ $countryCode = $this->getCountryCodeByName($countryName);
153
+
154
+ $adapter = $this->getSelect()->getAdapter();
155
+ $select = $adapter->select()
156
+ ->from(array('r' => $this->_regionTable), 'default_name')
157
+ ->joinLeft(
158
+ array('rn' => $this->_regionNameTable),
159
+ $adapter->quote('rn.region_id = r.region_id AND locale = ?', Mage::app()->getLocale()->getLocaleCode()),
160
+ array('name')
161
+ )
162
+ ->where('r.country_id = ?', $countryCode)
163
+ ->where('IF(name, name, default_name) LIKE ?', '%' . $term . '%')
164
+ ->limit($limit);
165
+
166
+ $regions = array();
167
+ $result = $adapter->fetchAll($select);
168
+ foreach ($result as $row) {
169
+ $regions[] = $row['name'] ? $row['name'] : $row['default_name'];
170
+ }
171
+ return $regions;
172
+ }
173
+
174
+ protected function _getAllCountries()
175
+ {
176
+ return Mage::app()->getLocale()->getCountryTranslationList();
177
+ }
178
+
179
+ private function _downcase($string)
180
+ {
181
+ return Mage::helper('fi_checkout')->lowerCase($string);
182
+ }
183
  }
app/code/{local → community}/FI/Checkout/Model/Source.php RENAMED
@@ -68,35 +68,4 @@ class FI_Checkout_Model_Source
68
  self::CHECKBOX_CHECKED => Mage::helper('fi_checkout')->__('Visible, Checked')
69
  );
70
  }
71
-
72
- /**
73
- * Return enabled payment methods exclude "googlecheckout"
74
- *
75
- * @return array
76
- */
77
- public function getPaymentMethods()
78
- {
79
- $data = Mage::helper('fi_checkout')->getEnabledPaymentMethods();
80
- unset($data['googlecheckout']);
81
- $result = array();
82
- foreach ($data as $row) {
83
- $result[$row['value']] = $row['label'];
84
- }
85
- return $result;
86
- }
87
-
88
- /**
89
- * Return enabled shipping methods exclude "googlecheckout"
90
- *
91
- * @return array
92
- */
93
- public function getShippingMethods()
94
- {
95
- $data = Mage::helper('fi_checkout')->getEnabledShippingCarriers();
96
- $data = array_flip($data);
97
- unset($data['googlecheckout']);
98
- $data = array_flip($data);
99
-
100
- return $data;
101
- }
102
  }
68
  self::CHECKBOX_CHECKED => Mage::helper('fi_checkout')->__('Visible, Checked')
69
  );
70
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  }
app/code/community/FI/Checkout/Model/Source/PaymentMethods.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class FI_Checkout_Model_Source_PaymentMethods
3
+ {
4
+ /**
5
+ * Return enabled payment methods
6
+ *
7
+ * @return array
8
+ */
9
+ public function toOptionArray()
10
+ {
11
+ $methods = array(array('value'=>'', 'label'=>''));
12
+ $payments = Mage::getSingleton('payment/config')->getActiveMethods();
13
+ foreach ($payments as $paymentCode=>$paymentModel) {
14
+ $paymentTitle = Mage::getStoreConfig('payment/'.$paymentCode.'/title');
15
+ $methods[$paymentCode] = array(
16
+ 'label' => $paymentTitle,
17
+ 'value' => $paymentCode,
18
+ );
19
+ }
20
+ return $methods;
21
+ }
22
+ }
app/code/community/FI/Checkout/Model/Source/ShippingMethods.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class FI_Checkout_Model_Source_ShippingMethods extends Mage_Adminhtml_Model_System_Config_Source_Shipping_Allmethods
3
+ {
4
+ /**
5
+ * Return enabled shipping methods
6
+ *
7
+ * @return array
8
+ */
9
+ public function toOptionArray($showActive = false)
10
+ {
11
+ return parent::toOptionArray(true);
12
+ }
13
+
14
+ }
app/code/{local → community}/FI/Checkout/Model/Subscriber.php RENAMED
File without changes
app/code/{local → community}/FI/Checkout/controllers/CheckoutController.php RENAMED
@@ -25,25 +25,6 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
25
  return $this;
26
  }
27
 
28
- /* @var $_order Mage_Sales_Model_Order */
29
- protected $_order;
30
-
31
- /**
32
- * Get Order by quoteId
33
- *
34
- * @return Mage_Sales_Model_Order
35
- */
36
- protected function _getOrder()
37
- {
38
- if (is_null($this->_order)) {
39
- $this->_order = Mage::getModel('sales/order')->load($this->getOnepage()->getQuote()->getId(), 'quote_id');
40
- if (!$this->_order->getId()) {
41
- throw new Mage_Payment_Model_Info_Exception(Mage::helper('core')->__("Can not create invoice. Order was not found."));
42
- }
43
- }
44
- return $this->_order;
45
- }
46
-
47
  /**
48
  * Set specific headers if session expired and send response
49
  *
@@ -92,7 +73,7 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
92
  * @param mixed $result
93
  * @return FI_Checkout_CheckoutController
94
  */
95
- protected function _processError($result)
96
  {
97
  if (isset($result['error'])) {
98
  $message = $result['message'];
@@ -107,11 +88,11 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
107
  /**
108
  * Subscribe customer to newsletter
109
  *
110
- * @param array $data customer information
111
  * @param bool $isWantSubscribe
112
  * @return bool
113
  */
114
- protected function _subscribeCustomer($data, $isWantSubscribe)
115
  {
116
  $helper = Mage::helper('fi_checkout');
117
  if (!$isWantSubscribe
@@ -123,7 +104,7 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
123
 
124
  $ownerId = Mage::getModel('customer/customer')
125
  ->setWebsiteId(Mage::app()->getStore()->getWebsiteId())
126
- ->loadByEmail($data['email'])
127
  ->getId();
128
 
129
  $session = $this->_getSession();
@@ -134,80 +115,10 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
134
  $status = Mage::getModel('fi_checkout/subscriber')
135
  ->setIsSendSuccessEmail($helper->isNeedSendNewsletterEmail('success'))
136
  ->setIsSendRequestEmail($helper->isNeedSendNewsletterEmail('request'))
137
- ->subscribe($data['email']);
138
  return Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED == $status;
139
  }
140
 
141
- /**
142
- * Prepare address information from request
143
- *
144
- * @param array $data
145
- * @return array
146
- */
147
- protected function _prepareAddress($data)
148
- {
149
- $address = $data['address'];
150
- if (empty($address['id'])) {
151
- $address['id'] = false;
152
- }
153
- if (isset($data['name'])) {
154
- $name = explode(' ', trim($data['name']), 2);
155
- $name = array_filter($name, 'trim');
156
- } else {
157
- $customer = $this->_getSession()->getCustomer();
158
- $name = array(
159
- $customer->getFirstname(),
160
- $customer->getLastname()
161
- );
162
- $data['email'] = $customer->getEmail();
163
- if (empty($address['telephone']) && $customer->getPrimaryShippingAddress()) {
164
- $address['telephone'] = $customer->getPrimaryShippingAddress()->getTelephone();
165
- }
166
- }
167
-
168
- $address['firstname'] = trim($name[0]);
169
- $address['lastname'] = trim(isset($name[1]) ? $name[1] : '');
170
- $address['email'] = $data['email'];
171
-
172
- if (!$this->_getSession()->isLoggedIn()) {
173
- $password = Mage::helper('fi_checkout')->getPassword($data);
174
- $address['customer_password'] = $password;
175
- $address['confirm_password'] = $password;
176
- }
177
- $address['use_for_shipping'] = true;
178
-
179
- $request = new Varien_Object($address);
180
- if (!empty($address['location'])) {
181
- $request->setData('value', $address['location']);
182
- }
183
- $locData = $this->_parseAddress($request);
184
- $address['country_id'] = $locData['country_id'];
185
- $address['region_id'] = $locData['region_id'];
186
- $address['region'] = $locData['region'];
187
- $address['city'] = $locData['city'];
188
- $address['postcode'] = $locData['postcode'];
189
-
190
- return $address;
191
- }
192
-
193
- /**
194
- * Create invoice
195
- *
196
- * @return Mage_Sales_Model_Order_Invoice
197
- */
198
- protected function _initInvoice()
199
- {
200
- $items = array();
201
- foreach ($this->_getOrder()->getAllItems() as $item) {
202
- $items[$item->getId()] = $item->getQtyOrdered();
203
- }
204
- /* @var $invoice Mage_Sales_Model_Service_Order */
205
- $invoice = Mage::getModel('sales/service_order', $this->_getOrder())->prepareInvoice($items);
206
- $invoice->setEmailSent(true)->register();
207
-
208
- return $invoice;
209
- }
210
-
211
  /**
212
  * Place order. Check for billing agreements and zero subtotal
213
  */
@@ -219,7 +130,7 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
219
  $result['success'] = false;
220
  $result['error'] = true;
221
  $result['message'] = Mage::helper('checkout')->__('Please agree to all the terms and conditions before placing the order.');
222
- $this->_processError($result);
223
  return;
224
  }
225
  }
@@ -233,19 +144,67 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
233
  }
234
 
235
  $this->getOnepage()->saveOrder();
 
236
 
237
- $storeId = Mage::app()->getStore()->getId();
238
- $paymentHelper = Mage::helper("payment");
239
- $zeroSubTotalPaymentAction = $paymentHelper->getZeroSubTotalPaymentAutomaticInvoice($storeId);
240
- if ($paymentHelper->isZeroSubTotal($storeId)
241
- && $this->_getOrder()->getGrandTotal() == 0
242
- && $zeroSubTotalPaymentAction == Mage_Payment_Model_Method_Abstract::ACTION_AUTHORIZE_CAPTURE
243
- && $paymentHelper->getZeroSubTotalOrderStatus($storeId) == 'pending'
244
- ) {
245
- $invoice = $this->_initInvoice();
246
- $invoice->getOrder()->setIsInProcess(true);
247
- $invoice->save();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  }
 
 
 
 
 
 
249
  }
250
 
251
  /**
@@ -258,16 +217,29 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
258
  return Mage::getSingleton('fi_checkout/page');
259
  }
260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  /**
262
  * Customer login action.
263
  * Set before_auth_url to session and forwards to Mage_Customer_AccountController::loginPost
264
  */
265
  public function loginAction()
266
  {
267
- $this->_getSession()->setBeforeAuthUrl(Mage::getUrl('checkout/cart'))
268
- ->setCheckoutUser(array())
269
- ->unsShippingInfo()
270
- ->unsShippingMethod();
271
  $this->_forward('loginPost', 'account', 'customer');
272
  }
273
 
@@ -284,12 +256,8 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
284
  return;
285
  }
286
 
287
- $helper = Mage::helper('fi_checkout');
288
- if ($helper->useOnlyDefaultCountry()) {
289
- $location = $helper->getDefaultCountry() . ',' . $location;
290
- }
291
-
292
- $items = Mage::getResourceModel('fi_checkout/countries')->filter($location);
293
 
294
  return $this->getResponse()->setBody($this->getLayout()
295
  ->createBlock('core/template')
@@ -309,38 +277,19 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
309
  public function updateAction()
310
  {
311
  $request = $this->getRequest();
312
- if (!$request->isPost()
313
- || !$request->getParam('type')
314
- || !$request->getParam('value')
315
- || $this->_expireAjax()
316
- ) {
317
  return $this;
318
  }
319
 
320
- $blocks = array();
321
-
322
- $type = explode(',', $request->getParam('type'));
323
- $type = array_flip($type);
324
-
325
- if (isset($type['shipping'])) {
326
- $data = $this->_parseAddress(new Varien_Object($request->getParams()));
327
- if ($data) {
328
- $this->_getSession()->setShippingInfo($data);
329
- }
330
- }
331
- $this->_syncAddress($this->_getSession()->getShippingInfo());
332
-
333
- $shippingMethod = $request->getPost('shipping_method', $this->_getSession()->getShippingMethod());
334
- if ($shippingMethod) {
335
- $this->_getSession()->setShippingMethod($shippingMethod);
336
- }
337
 
338
- $this->_syncAddress(array('shipping_method' => $shippingMethod));
 
339
 
340
- $this->getLayout()->getUpdate()
341
- ->load('fi_checkout_update');
342
- $this->getLayout()->generateXml()
343
- ->generateBlocks();
344
 
345
  if (isset($type['shipping'])) {
346
  $blocks['shipping'] = $this->getLayout()
@@ -355,7 +304,7 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
355
  }
356
 
357
  if (isset($type['totals'])) {
358
- $this->getOnepage()->getQuote()->collectTotals();
359
  $blocks['totals'] = $this->getLayout()
360
  ->getBlock('checkout.cart.totals')
361
  ->toHtml();
@@ -394,126 +343,6 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
394
  $this->getResponse()->setBody($html);
395
  }
396
 
397
- /**
398
- * Update shipping/billing address information
399
- *
400
- * @param array $data
401
- * @return FI_Checkout_CheckoutController
402
- */
403
- protected function _syncAddress($data)
404
- {
405
- if (!is_array($data)) {
406
- return $this;
407
- }
408
-
409
- $address = $this->getOnepage()->getQuote()
410
- ->getShippingAddress();
411
-
412
- if (!empty($data['shipping_method'])) {
413
- $address->setShippingMethod($data['shipping_method']);
414
- unset($data['shipping_method']);
415
- }
416
-
417
- if ($data) {
418
- $address->addData($data);
419
-
420
- $this->getOnepage()->getQuote()
421
- ->getBillingAddress()
422
- ->addData($data);
423
- }
424
-
425
- return $this;
426
- }
427
-
428
- /**
429
- * Parse address information from request
430
- *
431
- * @param Varien_Object $request
432
- * @return array
433
- */
434
- protected function _parseAddress($request)
435
- {
436
- $helper = Mage::helper('fi_checkout');
437
- $data = array(
438
- 'country_id' => null,
439
- 'region' => null,
440
- 'region_id' => null,
441
- 'city' => null
442
- );
443
-
444
- if ($helper->isLocationAsOneField()) {
445
- $loc = $request->getData('value');
446
- if ($helper->useOnlyDefaultCountry()) {
447
- $loc = $helper->getDefaultCountry() . ',' . $loc;
448
- }
449
- $loc = explode(',', $loc);
450
- $loc = array_map('trim', $loc);
451
-
452
- if (!empty($loc[0])) {
453
- $loc[0] = $helper->lowerCase($loc[0]);
454
- $countries = array_flip(array_map(
455
- array($helper, 'lowerCase'),
456
- Mage::app()->getLocale()->getCountryTranslationList()
457
- ));
458
-
459
- if (!$helper->useOnlyDefaultCountry() && isset($countries[$loc[0]])) {
460
- $data['country_id'] = $countries[$loc[0]];
461
- } else {
462
- $data['country_id'] = $helper->getDefaultCountry();
463
- }
464
-
465
- if (!empty($loc[1])) {
466
- $data['city'] = $data['region'] = $loc[1];
467
- }
468
-
469
- if (!empty($loc[2])) {
470
- $data['city'] = $loc[2];
471
- }
472
- }
473
- } else {
474
- $data['country_id'] = $request->getData('country_id');
475
- if ($helper->useOnlyDefaultCountry() || empty($data['country_id'])) {
476
- $data['country_id'] = $helper->getDefaultCountry();
477
- }
478
-
479
- $data['region'] = $request->getData('region');
480
- $data['city'] = $request->getData('city');
481
- }
482
-
483
- $data['postcode'] = $request->getData('postcode');
484
- if (!empty($data['region'])) {
485
- $data['region_id'] = Mage::getResourceModel('fi_checkout/countries')
486
- ->getRegionIdByName(trim($data['region']), $data['country_id']);
487
- if ($data['region_id']) {
488
- $data['region'] = null;
489
- }
490
- }
491
-
492
- return $data;
493
- }
494
-
495
- /**
496
- * Set response in special format
497
- *
498
- * @param Varien_Object $response
499
- * @return FI_Checkout_CheckoutController
500
- */
501
- protected function _response(Varien_Object $response)
502
- {
503
- if ($response->hasErrorMessage()) {
504
- $errorHtml = $this->getLayout()
505
- ->createBlock('core/messages')
506
- ->addError($response->getErrorMessage())
507
- ->getGroupedHtml();
508
-
509
- $response->setErrorMessage($errorHtml);
510
- }
511
-
512
- $this->getResponse()->setBody($response->toJson());
513
-
514
- return $this;
515
- }
516
-
517
  /**
518
  * Place order action. Listen for POST requests only
519
  *
@@ -525,62 +354,30 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
525
  $data = $this->getRequest()->getPost('user');
526
  if (!$this->getRequest()->isPost() || !$data || $this->_expireAjax()) {
527
  $response->setRedirect(Mage::getUrl('checkout/cart'));
528
- return $this->_response($response);
529
  }
530
 
 
 
 
 
 
 
 
531
  $session = $this->_getSession();
532
  $hasError = false;
533
- $quote = $this->getOnepage()->getQuote();
534
- $session->setCheckoutUser($data);
535
-
536
- if (!$quote->validateMinimumAmount()) {
537
- $error = Mage::getStoreConfig('sales/minimum_order/error_message');
538
- $response->setErrorMessage($error);
539
- return $this->_response($response);
540
- }
541
 
542
  try {
543
- // save checkout method
544
  if ($session->isLoggedIn()) {
545
  $quote->setCheckoutMethod(Mage_Checkout_Model_Type_Onepage::METHOD_CUSTOMER);
546
- } elseif (empty($data['address']['id'])) {
547
  $quote->setCheckoutMethod(Mage_Checkout_Model_Type_Onepage::METHOD_REGISTER);
548
  }
549
- $this->getOnepage()->initCheckout();
550
-
551
- // save addresses
552
- $data['address'] = $this->_prepareAddress($data);
553
- $result = $this->getOnepage()->saveBilling($data['address'], $data['address']['id']);
554
- $this->_processError($result);
555
 
556
- $this->_subscribeCustomer($data['address'], $this->getRequest()->getPost('subscribe', false));
557
-
558
- // save shipping method
559
- $shippingMethod = $this->getRequest()->getPost('shipping_method');
560
- if (!$quote->getIsVirtual() && empty($shippingMethod)) {
561
- $this->_processError(array(
562
- 'error' => -1,
563
- 'message' => Mage::helper('checkout')->__('Invalid shipping method.')
564
- ));
565
- }
566
-
567
- /**
568
- * Addresses has been validated in saveBilling method,
569
- * so we are disabled validation
570
- */
571
- $quote->getShippingAddress()
572
- ->setShippingMethod($shippingMethod)
573
- ->setSaveInAddressBook(!$session->getCustomer() || !$session->getCustomer()->getDefaultShipping())
574
- ->setShouldIgnoreValidation(true);
575
-
576
- $quote->getBillingAddress()
577
- ->setSaveInAddressBook(!$session->getCustomer() || !$session->getCustomer()->getDefaultBilling())
578
- ->setShouldIgnoreValidation(true);
579
-
580
- Mage::dispatchEvent('checkout_controller_onepage_save_shipping_method', array(
581
- 'request' => $this->getRequest(),
582
- 'quote' => $quote
583
- ));
584
 
585
  $quote->setTotalsCollectedFlag(false)
586
  ->collectTotals();
@@ -592,7 +389,7 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
592
  $redirectUrl = $quote->getPayment()->getCheckoutRedirectUrl();
593
  if ($redirectUrl) {
594
  $response->setRedirect($redirectUrl);
595
- return $this->_response($response);
596
  }
597
 
598
  // save order
@@ -602,9 +399,7 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
602
  ->getRedirectUrl();
603
 
604
  $quote->setIsActive(!empty($redirectUrl))->save();
605
-
606
- $session->setCheckoutUser(array())
607
- ->unsShippingInfo();
608
  } catch (Mage_Core_Exception $e) {
609
  $hasError = true;
610
  $response->setErrorMessage($e->getMessage());
@@ -614,14 +409,14 @@ class FI_Checkout_CheckoutController extends Mage_Checkout_Controller_Action
614
  $response->setErrorMessage(Mage::helper('checkout')->__('Unable to process your order. Please try again later'));
615
  }
616
 
617
- if (!$redirectUrl && !$hasError) {
618
- $redirectUrl = Mage::getUrl('*/*/success');
619
  }
620
 
621
  $response->setError($hasError)
622
  ->setSuccess(!$hasError)
623
  ->setRedirect($redirectUrl);
624
- $this->_response($response);
625
 
626
  Mage::dispatchEvent('controller_action_postdispatch_checkout_onepage_saveOrder', array(
627
  'controller_action' => $this
25
  return $this;
26
  }
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  /**
29
  * Set specific headers if session expired and send response
30
  *
73
  * @param mixed $result
74
  * @return FI_Checkout_CheckoutController
75
  */
76
+ protected function _validate($result)
77
  {
78
  if (isset($result['error'])) {
79
  $message = $result['message'];
88
  /**
89
  * Subscribe customer to newsletter
90
  *
91
+ * @param Varien_Object $customer
92
  * @param bool $isWantSubscribe
93
  * @return bool
94
  */
95
+ protected function _subscribeCustomer($customer, $isWantSubscribe)
96
  {
97
  $helper = Mage::helper('fi_checkout');
98
  if (!$isWantSubscribe
104
 
105
  $ownerId = Mage::getModel('customer/customer')
106
  ->setWebsiteId(Mage::app()->getStore()->getWebsiteId())
107
+ ->loadByEmail($customer->getEmail())
108
  ->getId();
109
 
110
  $session = $this->_getSession();
115
  $status = Mage::getModel('fi_checkout/subscriber')
116
  ->setIsSendSuccessEmail($helper->isNeedSendNewsletterEmail('success'))
117
  ->setIsSendRequestEmail($helper->isNeedSendNewsletterEmail('request'))
118
+ ->subscribe($customer->getEmail());
119
  return Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED == $status;
120
  }
121
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  /**
123
  * Place order. Check for billing agreements and zero subtotal
124
  */
130
  $result['success'] = false;
131
  $result['error'] = true;
132
  $result['message'] = Mage::helper('checkout')->__('Please agree to all the terms and conditions before placing the order.');
133
+ $this->_validate($result);
134
  return;
135
  }
136
  }
144
  }
145
 
146
  $this->getOnepage()->saveOrder();
147
+ }
148
 
149
+ /**
150
+ * Set response in special format
151
+ *
152
+ * @param Varien_Object $response
153
+ * @return FI_Checkout_CheckoutController
154
+ */
155
+ protected function _respondWith(Varien_Object $response)
156
+ {
157
+ if ($response->hasErrorMessage()) {
158
+ $errorHtml = $this->getLayout()
159
+ ->createBlock('core/messages')
160
+ ->addError($response->getErrorMessage())
161
+ ->getGroupedHtml();
162
+
163
+ $response->setErrorMessage($errorHtml);
164
+ }
165
+
166
+ $this->getResponse()->setBody($response->toJson());
167
+
168
+ return $this;
169
+ }
170
+
171
+ protected function _saveAddressesFor($sessionOrder)
172
+ {
173
+ $quote = $this->getOnepage()->getQuote();
174
+ $address = Mage::helper('fi_checkout')->extractAddressFrom($sessionOrder);
175
+ $result = $this->getOnepage()->saveBilling($address, $address['id']);
176
+ $this->_validate($result);
177
+
178
+ $session = $this->_getSession();
179
+ /**
180
+ * Addresses are validated in saveBilling method,
181
+ * so we are disabled validation
182
+ */
183
+ $quote->getShippingAddress()
184
+ ->setSaveInAddressBook(!$session->getCustomer() || !$session->getCustomer()->getDefaultShipping())
185
+ ->setShouldIgnoreValidation(true);
186
+
187
+ $quote->getBillingAddress()
188
+ ->setSaveInAddressBook(!$session->getCustomer() || !$session->getCustomer()->getDefaultBilling())
189
+ ->setShouldIgnoreValidation(true);
190
+ }
191
+
192
+ protected function _saveShippingMethod()
193
+ {
194
+ $quote = $this->getOnepage()->getQuote();
195
+ $method = $this->getRequest()->getPost('shipping_method');
196
+ if (!$quote->getIsVirtual() && empty($method)) {
197
+ $this->_validate(array(
198
+ 'error' => true,
199
+ 'message' => Mage::helper('checkout')->__('Invalid shipping method.')
200
+ ));
201
  }
202
+
203
+ $quote->getShippingAddress()->setShippingMethod($method);
204
+ Mage::dispatchEvent('checkout_controller_onepage_save_shipping_method', array(
205
+ 'request' => $this->getRequest(),
206
+ 'quote' => $quote
207
+ ));
208
  }
209
 
210
  /**
217
  return Mage::getSingleton('fi_checkout/page');
218
  }
219
 
220
+ protected function _buildSessionOrder()
221
+ {
222
+ $request = $this->getRequest();
223
+ $helper = Mage::helper('fi_checkout');
224
+ $order = $helper->buildSessionOrder()->setData(array_filter(array(
225
+ 'payment' => $request->getPost('payment'),
226
+ 'user' => $request->getPost('user'),
227
+ 'shipping_method' => $request->getPost('shipping_method'),
228
+ )));
229
+
230
+ $address = $helper->parseLocationOf($order->getAddress());
231
+ $order->updateAddressWith($address);
232
+ return $order;
233
+ }
234
+
235
  /**
236
  * Customer login action.
237
  * Set before_auth_url to session and forwards to Mage_Customer_AccountController::loginPost
238
  */
239
  public function loginAction()
240
  {
241
+ $this->_buildSessionOrder()->drop();
242
+ $this->_getSession()->setBeforeAuthUrl(Mage::getUrl('checkout/cart'));
 
 
243
  $this->_forward('loginPost', 'account', 'customer');
244
  }
245
 
256
  return;
257
  }
258
 
259
+ $location = Mage::helper('fi_checkout')->explodeLocation($location);
260
+ $items = Mage::getResourceModel('fi_checkout/countries')->search($location);
 
 
 
 
261
 
262
  return $this->getResponse()->setBody($this->getLayout()
263
  ->createBlock('core/template')
277
  public function updateAction()
278
  {
279
  $request = $this->getRequest();
280
+ if (!$request->isPost() || !$request->getParam('type') || $this->_expireAjax()) {
 
 
 
 
281
  return $this;
282
  }
283
 
284
+ $quote = $this->getOnepage()->getQuote();
285
+ $sessionOrder = $this->_buildSessionOrder();
286
+ $sessionOrder->exportPaymentTo($quote->getPayment());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
 
288
+ $blocks = array();
289
+ $type = array_flip(explode(',', $request->getParam('type')));
290
 
291
+ $this->getLayout()->getUpdate()->load('fi_checkout_update');
292
+ $this->getLayout()->generateXml()->generateBlocks();
 
 
293
 
294
  if (isset($type['shipping'])) {
295
  $blocks['shipping'] = $this->getLayout()
304
  }
305
 
306
  if (isset($type['totals'])) {
307
+ $quote->collectTotals();
308
  $blocks['totals'] = $this->getLayout()
309
  ->getBlock('checkout.cart.totals')
310
  ->toHtml();
343
  $this->getResponse()->setBody($html);
344
  }
345
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
  /**
347
  * Place order action. Listen for POST requests only
348
  *
354
  $data = $this->getRequest()->getPost('user');
355
  if (!$this->getRequest()->isPost() || !$data || $this->_expireAjax()) {
356
  $response->setRedirect(Mage::getUrl('checkout/cart'));
357
+ return $this->_respondWith($response);
358
  }
359
 
360
+ $quote = $this->getOnepage()->getQuote();
361
+ if (!$quote->validateMinimumAmount()) {
362
+ $response->setErrorMessage(Mage::getStoreConfig('sales/minimum_order/error_message'));
363
+ return $this->_respondWith($response);
364
+ }
365
+
366
+ $sessionOrder = $this->_buildSessionOrder();
367
  $session = $this->_getSession();
368
  $hasError = false;
 
 
 
 
 
 
 
 
369
 
370
  try {
 
371
  if ($session->isLoggedIn()) {
372
  $quote->setCheckoutMethod(Mage_Checkout_Model_Type_Onepage::METHOD_CUSTOMER);
373
+ } elseif (!$sessionOrder->getAddress()->getId()) {
374
  $quote->setCheckoutMethod(Mage_Checkout_Model_Type_Onepage::METHOD_REGISTER);
375
  }
 
 
 
 
 
 
376
 
377
+ $this->getOnepage()->initCheckout();
378
+ $this->_saveAddressesFor($sessionOrder);
379
+ $this->_subscribeCustomer($sessionOrder->getCustomer(), $this->getRequest()->getPost('subscribe', false));
380
+ $this->_saveShippingMethod();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381
 
382
  $quote->setTotalsCollectedFlag(false)
383
  ->collectTotals();
389
  $redirectUrl = $quote->getPayment()->getCheckoutRedirectUrl();
390
  if ($redirectUrl) {
391
  $response->setRedirect($redirectUrl);
392
+ return $this->_respondWith($response);
393
  }
394
 
395
  // save order
399
  ->getRedirectUrl();
400
 
401
  $quote->setIsActive(!empty($redirectUrl))->save();
402
+ $sessionOrder->drop();
 
 
403
  } catch (Mage_Core_Exception $e) {
404
  $hasError = true;
405
  $response->setErrorMessage($e->getMessage());
409
  $response->setErrorMessage(Mage::helper('checkout')->__('Unable to process your order. Please try again later'));
410
  }
411
 
412
+ if (empty($redirectUrl)) {
413
+ $redirectUrl = $hasError ? '' : Mage::getUrl('*/*/success');
414
  }
415
 
416
  $response->setError($hasError)
417
  ->setSuccess(!$hasError)
418
  ->setRedirect($redirectUrl);
419
+ $this->_respondWith($response);
420
 
421
  Mage::dispatchEvent('controller_action_postdispatch_checkout_onepage_saveOrder', array(
422
  'controller_action' => $this
app/code/{local → community}/FI/Checkout/etc/config.xml RENAMED
@@ -9,7 +9,7 @@
9
  <config>
10
  <modules>
11
  <FI_Checkout>
12
- <version>1.0.0</version>
13
  </FI_Checkout>
14
  </modules>
15
  <global>
@@ -75,6 +75,14 @@
75
  </fi_checkout>
76
  </observers>
77
  </checkout_type_onepage_save_order>
 
 
 
 
 
 
 
 
78
  </events>
79
  </frontend>
80
  <default>
9
  <config>
10
  <modules>
11
  <FI_Checkout>
12
+ <version>1.1.0</version>
13
  </FI_Checkout>
14
  </modules>
15
  <global>
75
  </fi_checkout>
76
  </observers>
77
  </checkout_type_onepage_save_order>
78
+ <checkout_submit_all_after>
79
+ <observers>
80
+ <fi_checkout>
81
+ <class>fi_checkout/observer</class>
82
+ <method>tryToProcessOrder</method>
83
+ </fi_checkout>
84
+ </observers>
85
+ </checkout_submit_all_after>
86
  </events>
87
  </frontend>
88
  <default>
app/code/{local → community}/FI/Checkout/etc/system.xml RENAMED
@@ -18,26 +18,24 @@
18
  <show_in_website>1</show_in_website>
19
  <show_in_store>0</show_in_store>
20
  <fields>
21
- <!--
22
  <default_payment_method>
23
  <label>Default Payment Method</label>
24
  <frontend_type>select</frontend_type>
25
- <source_model>adminhtml/system_config_source_payment_allowedmethods</source_model>
26
  <sort_order>1</sort_order>
27
  <show_in_default>1</show_in_default>
28
  <show_in_website>1</show_in_website>
29
  <show_in_store>1</show_in_store>
30
  </default_payment_method>
31
  <default_shipping_method>
32
- <label>Default Payment Method</label>
33
  <frontend_type>select</frontend_type>
34
- <source_model>adminhtml/system_config_source_shipping_allowedmethods</source_model>
35
  <sort_order>2</sort_order>
36
  <show_in_default>1</show_in_default>
37
  <show_in_website>1</show_in_website>
38
  <show_in_store>1</show_in_store>
39
  </default_shipping_method>
40
- -->
41
  <default_country translate="label">
42
  <label>Default Country</label>
43
  <frontend_type>select</frontend_type>
@@ -64,7 +62,7 @@
64
  <show_in_store>1</show_in_store>
65
  </default_city>
66
  <use_default_country translate="label">
67
- <label>Checkout Only For Default Country</label>
68
  <frontend_type>select</frontend_type>
69
  <source_model>adminhtml/system_config_source_yesno</source_model>
70
  <sort_order>20</sort_order>
@@ -127,6 +125,15 @@
127
  <show_in_website>1</show_in_website>
128
  <show_in_store>0</show_in_store>
129
  </newsletter_send_request>
 
 
 
 
 
 
 
 
 
130
  </fields>
131
  </easyco>
132
  </groups>
18
  <show_in_website>1</show_in_website>
19
  <show_in_store>0</show_in_store>
20
  <fields>
 
21
  <default_payment_method>
22
  <label>Default Payment Method</label>
23
  <frontend_type>select</frontend_type>
24
+ <source_model>fi_checkout/source_paymentMethods</source_model>
25
  <sort_order>1</sort_order>
26
  <show_in_default>1</show_in_default>
27
  <show_in_website>1</show_in_website>
28
  <show_in_store>1</show_in_store>
29
  </default_payment_method>
30
  <default_shipping_method>
31
+ <label>Default Shipping Method</label>
32
  <frontend_type>select</frontend_type>
33
+ <source_model>fi_checkout/source_shippingMethods</source_model>
34
  <sort_order>2</sort_order>
35
  <show_in_default>1</show_in_default>
36
  <show_in_website>1</show_in_website>
37
  <show_in_store>1</show_in_store>
38
  </default_shipping_method>
 
39
  <default_country translate="label">
40
  <label>Default Country</label>
41
  <frontend_type>select</frontend_type>
62
  <show_in_store>1</show_in_store>
63
  </default_city>
64
  <use_default_country translate="label">
65
+ <label>Checkout only for Default Country</label>
66
  <frontend_type>select</frontend_type>
67
  <source_model>adminhtml/system_config_source_yesno</source_model>
68
  <sort_order>20</sort_order>
125
  <show_in_website>1</show_in_website>
126
  <show_in_store>0</show_in_store>
127
  </newsletter_send_request>
128
+ <update_totals_when_payment_changed>
129
+ <label>Update Totals when Payment Method is Changed</label>
130
+ <frontend_type>select</frontend_type>
131
+ <source_model>adminhtml/system_config_source_yesno</source_model>
132
+ <sort_order>50</sort_order>
133
+ <show_in_default>1</show_in_default>
134
+ <show_in_website>1</show_in_website>
135
+ <show_in_store>0</show_in_store>
136
+ </update_totals_when_payment_changed>
137
  </fields>
138
  </easyco>
139
  </groups>
app/code/{local → community}/FI/Checkout/sql/fi_checkout_setup/mysql4-install-1.0.0.php RENAMED
File without changes
app/code/local/FI/Checkout/Block/Block/Info.php DELETED
@@ -1,270 +0,0 @@
1
- <?php
2
- /**
3
- * Zero Step Checkout user information block
4
- *
5
- * @category FI
6
- * @package FI_Checkout
7
- * @author Sergiy Stotskiy <sergiy.stotskiy@freaksidea.com>
8
- */
9
- class FI_Checkout_Block_Block_Info extends Mage_Checkout_Block_Onepage_Shipping
10
- {
11
- /**
12
- * Information about user stored in session
13
- *
14
- * @var Varien_Object
15
- */
16
- protected $_user;
17
-
18
- /**
19
- * Constructor. Set block template.
20
- * Set user values to block. Update addresses
21
- */
22
- protected function _construct()
23
- {
24
- $this->setTemplate('freaks/checkout/block/info.phtml');
25
-
26
- $user = $this->getCustomerInfo();
27
- $streetIndex = 2;
28
-
29
- if ($this->isCustomerLoggedIn()) {
30
- $customer = $this->getCustomer();
31
- $address = $this->getAddress();
32
- $additional = $user->getAddress();
33
-
34
- if (is_array($additional) && !empty($additional)) {
35
- $address->addData(array_filter($additional));
36
- }
37
- $customer->setNote($user->getNote());
38
- } else {
39
- $customer = $user;
40
- $address = new Varien_Object($customer->getAddress());
41
- $streetIndex--;
42
- $this->helper('fi_checkout')->updateAddress($address);
43
- }
44
-
45
- $this->setCustomerEmail($customer->getEmail())
46
- ->setCustomerRegion($address->getRegion())
47
- ->setCustomerCity($address->getCity())
48
- ->setCustomerBuilding($address->getStreet($streetIndex))
49
- ->setCustomerRoom($address->getStreet($streetIndex + 1))
50
- ->setCustomerNote($customer->getNote())
51
- ->setCustomerPhone($address->getTelephone())
52
- ->setCustomerZip($address->getPostcode());
53
-
54
- $this->_updateAddress();
55
- }
56
-
57
- /**
58
- * Return customer full name
59
- *
60
- * @return string
61
- */
62
- public function getCustomerName()
63
- {
64
- return $this->isCustomerLoggedIn()
65
- ? $this->getFirstname() . ' ' . $this->getLastname()
66
- : $this->getCustomerInfo()->getName();
67
- }
68
-
69
- /**
70
- * Return Customer Address First Name
71
- * If Sales Quote Address First Name is not defined - return Customer First Name
72
- *
73
- * @return string
74
- */
75
- public function getFirstname()
76
- {
77
- $firstname = $this->getAddress()->getFirstname();
78
- if (empty($firstname) && $this->getQuote()->getCustomer()) {
79
- return $this->getQuote()->getCustomer()->getFirstname();
80
- }
81
- return $firstname;
82
- }
83
-
84
- /**
85
- * Return Customer Address Last Name
86
- * If Sales Quote Address Last Name is not defined - return Customer Last Name
87
- *
88
- * @return string
89
- */
90
- public function getLastname()
91
- {
92
- $lastname = $this->getAddress()->getLastname();
93
- if (empty($lastname) && $this->getQuote()->getCustomer()) {
94
- return $this->getQuote()->getCustomer()->getLastname();
95
- }
96
- return $lastname;
97
- }
98
-
99
- /**
100
- * Return address street
101
- *
102
- * @return string
103
- */
104
- public function getStreet()
105
- {
106
- if ($this->isCustomerLoggedIn()) {
107
- $street1 = $this->getAddress()->getStreet(1);
108
- } else {
109
- $street1 = '';
110
- $address = $this->getCustomerInfo()->getAddress();
111
- if (!empty($address['street']) && is_array($address['street'])) {
112
- $street1 = reset($address['street']);
113
- }
114
- }
115
-
116
- return $street1;
117
- }
118
-
119
- /**
120
- * Return address id
121
- *
122
- * @return int
123
- */
124
- public function getAddressId()
125
- {
126
- $addressId = $this->getAddress()->getCustomerAddressId();
127
- if (empty($addressId)) {
128
- $address = $this->getCustomer()->getPrimaryShippingAddress();
129
- if ($address) {
130
- $addressId = $address->getId();
131
- }
132
- }
133
- return $addressId;
134
- }
135
-
136
- /**
137
- * Return customer information stored in session
138
- *
139
- * @return Varien_Object
140
- */
141
- public function getCustomerInfo()
142
- {
143
- if ($this->_user) {
144
- return $this->_user;
145
- }
146
- $data = Mage::getSingleton('customer/session')->getCheckoutUser();
147
-
148
- $this->_user = new Varien_Object($data);
149
- return $this->_user;
150
- }
151
-
152
- /**
153
- * Return address. If address object is empty import customer address into it
154
- *
155
- * @return Mage_Sales_Quote_Address
156
- */
157
- public function getAddress()
158
- {
159
- $address = parent::getAddress();
160
- if ($this->isCustomerLoggedIn() && !$address->getEmail()) {
161
- $customerAddress = $this->getCustomer()->getPrimaryShippingAddress();
162
- if (is_object($customerAddress)) {
163
- $address->importCustomerAddress($customerAddress)
164
- ->setSaveInAddressBook(0);
165
- }
166
- }
167
-
168
- return $address;
169
- }
170
-
171
- /**
172
- * Return customer location (country, region, city)
173
- *
174
- * @return string
175
- */
176
- public function getCustomerLocation()
177
- {
178
- $address = $this->getCustomerInfo()->getAddress();
179
- if (!empty($address['location'])) {
180
- return $address['location'];
181
- }
182
-
183
- $address = $this->getAddress();
184
-
185
- if (!$this->helper('fi_checkout')->useOnlyDefaultCountry()) {
186
- $location[] = $address->getCountryModel()->getName();
187
- }
188
- if ($address->getRegionId()) {
189
- $location[] = $address->getRegionModel()->getName();
190
- } elseif ($address->getRegion()) {
191
- $location[] = $address->getRegion();
192
- }
193
- $location[] = $address->getCity();
194
-
195
- return join(', ', array_filter($location));
196
- }
197
-
198
- /**
199
- * Return location help message based on configuration
200
- *
201
- * @see FI_Checkout_Helper_Data::useOnlyDefaultCountry
202
- * @return string
203
- */
204
- public function getLocationHelp()
205
- {
206
- if ($this->helper('fi_checkout')->useOnlyDefaultCountry()) {
207
- return $this->__('City');
208
- } else {
209
- return $this->__('Country, Region, City (e.g. Ukraine, Kyiv, Kyiv)');
210
- }
211
- }
212
-
213
- /**
214
- * Update addresses with session values
215
- *
216
- * @return FI_Checkout_Block_Block_Info
217
- */
218
- protected function _updateAddress()
219
- {
220
- $shipping = $this->helper('fi_checkout')
221
- ->updateAddress($this->getAddress())
222
- ->implodeStreetAddress();
223
-
224
- $billing = $this->getQuote()->getBillingAddress();
225
- if ($billing) {
226
- $this->helper('fi_checkout')
227
- ->copyAddress($shipping, $billing)
228
- ->implodeStreetAddress();
229
- }
230
- return $this;
231
- }
232
-
233
- /**
234
- * Return country select box block
235
- *
236
- * @param string $type
237
- * @return Mage_Core_Block_Html_Select
238
- */
239
- public function getCountryBlock($type = 'shipping')
240
- {
241
- $countryId = $this->getAddress()->getCountryId();
242
- if (!$countryId) {
243
- $countryId = Mage::helper('fi_checkout')->getDefaultCountry();
244
- }
245
- $select = $this->getLayout()->createBlock('core/html_select')
246
- ->setTitle($this->helper('checkout')->__('Country'))
247
- ->setClass('validate-select')
248
- ->setValue($countryId)
249
- ->setOptions($this->getCountryOptions());
250
-
251
- return $select;
252
- }
253
-
254
- /**
255
- * Return region select box block
256
- *
257
- * @param string $type
258
- * @return Mage_Core_Block_Html_Select
259
- */
260
- public function getRegionBlock()
261
- {
262
- $select = $this->getLayout()->createBlock('core/html_select')
263
- ->setTitle($this->helper('checkout')->__('State/Province'))
264
- ->setClass('required-entry validate-state')
265
- ->setValue($this->getAddress()->getRegionId())
266
- ->setOptions($this->getRegionCollection()->toOptionArray());
267
-
268
- return $select;
269
- }
270
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/FI/Checkout/Model/Observer.php DELETED
@@ -1,50 +0,0 @@
1
- <?php
2
- /**
3
- * Zero Step Checkout observer model
4
- *
5
- * @category FI
6
- * @package FI_Checkout
7
- * @author Sergiy Stotskiy <sergiy.stotskiy@freaksidea.com>
8
- */
9
- class FI_Checkout_Model_Observer
10
- {
11
- /**
12
- * Restore shipping method from session or auto assign if there is only one available method.
13
- * Listen event sales_quote_collect_totals_before
14
- *
15
- * @param Varien_Event_Observer $observer
16
- * @return FI_Checkout_Model_Observer
17
- */
18
- public function collectTotalsBefore(Varien_Event_Observer $observer)
19
- {
20
- $helper = Mage::helper('fi_checkout');
21
- $quote = $observer->getEvent()->getQuote();
22
- $address = $quote->getShippingAddress();
23
-
24
- $helper->updateAddress($address);
25
- $helper->autoAssignShippingMethod($address);
26
- return $this;
27
- }
28
-
29
- /**
30
- * Add user comment to order.
31
- * Listen event checkout_type_onepage_save_order
32
- *
33
- * @param Varien_Event_Observer $observer
34
- * @return FI_Checkout_Model_Observer
35
- */
36
- public function addOrderComment(Varien_Event_Observer $observer)
37
- {
38
- $order = $observer->getEvent()->getOrder();
39
- $request = Mage::app()->getRequest();
40
-
41
- $data = $request->getParam('user');
42
- if ($data && !empty($data['note'])) {
43
- $comment = strip_tags($data['note']);
44
- if (!empty($comment)) {
45
- $order->setCustomerNote($comment);
46
- }
47
- }
48
- return $this;
49
- }
50
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/default/default/template/freaks/checkout/block.phtml CHANGED
@@ -2,7 +2,7 @@
2
  <div id="checkout-block" class="<?php echo $this->helper('fi_checkout')->isLocationAsOneField() ? 'join-address' : 'split-address' ?>">
3
  <ul class="infos-menus">
4
  <li <?php if (!$isLoggedIn): ?> class="current"<?php endif ?>><a href="#new-user"><?php echo $this->__('New User') ?></a></li>
5
- <li <?php if ($isLoggedIn): ?> class="current"<?php endif ?>><a href="#login"><?php echo $this->__('Registered') ?></a></li>
6
  <li class="clear"></li>
7
  </ul>
8
  <div class="clear"></div>
2
  <div id="checkout-block" class="<?php echo $this->helper('fi_checkout')->isLocationAsOneField() ? 'join-address' : 'split-address' ?>">
3
  <ul class="infos-menus">
4
  <li <?php if (!$isLoggedIn): ?> class="current"<?php endif ?>><a href="#new-user"><?php echo $this->__('New User') ?></a></li>
5
+ <li <?php if ($isLoggedIn): ?> class="current"<?php endif ?>><a href="#<?php echo $isLoggedIn ? 'registered-user' : 'login' ?>"><?php echo $this->__('Registered') ?></a></li>
6
  <li class="clear"></li>
7
  </ul>
8
  <div class="clear"></div>
app/design/frontend/default/default/template/freaks/checkout/block/info.phtml CHANGED
@@ -3,27 +3,27 @@ $isLoggedIn = $this->getFilled() && $this->isCustomerLoggedIn();
3
  $prefix = $isLoggedIn ? 'logged' : 'new';
4
  $isLocationAsOneField = $this->helper('fi_checkout')->isLocationAsOneField();
5
  ?>
6
- <form id="<?php echo $isLoggedIn ? 'checkout-login-form' : 'new-user-form' ?>" action="<?php echo $this->getUrl('fi_order/checkout/place') ?>" method="post">
7
  <div class="col2-set">
8
  <div class="col-1 user-general">
9
  <p class="required">* <?php echo $this->__('Required Fields') ?></p>
10
  <div class="field">
11
  <label><?php echo $this->__('Name') ?>*</label>
12
- <input type="text" class="input-text required-entry<?php echo $isLoggedIn ? ' disabled' : '' ?>" name="user[name]" value="<?php echo $this->htmlEscape($this->getCustomerName()) ?>" <?php if ($isLoggedIn): ?> disabled="disabled"<?php endif ?> <?php if ($isLoggedIn): ?> disabled="disabled"<?php endif ?> />
13
  </div>
14
  <div class="field relative">
15
  <label><?php echo $this->__('Telephone') ?>*</label>
16
- <input type="text" class="input-text required-entry<?php echo $isLoggedIn && $this->getCustomerPhone() ? ' disabled' : '' ?>" name="user[address][telephone]" value="<?php echo $this->htmlEscape($this->getCustomerPhone()) ?>" <?php if ($isLoggedIn && $this->getCustomerPhone()): ?> disabled="disabled"<?php endif ?> />
17
  </div>
18
  <div class="field">
19
  <label><?php echo $this->__('E-mail') ?>*</label>
20
- <input type="text" class="validate-email input-text required-entry<?php echo $isLoggedIn ? ' disabled' : '' ?>" name="user[email]" value="<?php echo $this->htmlEscape($this->getCustomerEmail()) ?>" <?php if ($isLoggedIn): ?> disabled="disabled"<?php endif ?> />
21
  </div>
22
  <?php if (!$isLoggedIn): ?>
23
  <?php if ($this->helper('fi_checkout')->canShowPasswordField()): ?>
24
  <div class="field">
25
  <label><?php echo $this->helper('checkout')->__('Password') ?>*</label>
26
- <input type="password" class="input-text validate-password" name="user[password]" />
27
  </div>
28
  <?php elseif ($this->helper('fi_checkout')->isPasswordAsTelephone()): ?>
29
  <span class="note">* <?php echo $this->__('Telephone number will be your password.') ?></span>
@@ -70,7 +70,7 @@ $isLocationAsOneField = $this->helper('fi_checkout')->isLocationAsOneField();
70
  <p class="help"><?php echo $this->helper('checkout')->__('Country') ?>*</p>
71
  </div>
72
  <div class="f-left relative hidden-select no-mr">
73
- <input type="text" name="user[address][region]" class="input-text required-entry fake-title" value="<?php echo $this->htmlEscape($this->getCustomerRegion()) ?>" />
74
  <?php $select = $this->getRegionBlock()->setName('user[address][region_id]') ?>
75
  <?php echo $select->getHtml() ?>
76
  <p class="help"><?php echo $select->getTitle()?>*</p>
@@ -78,11 +78,11 @@ $isLocationAsOneField = $this->helper('fi_checkout')->isLocationAsOneField();
78
  <?php endif ?>
79
  <div class="clear"></div>
80
  <div class="f-left">
81
- <input type="text" name="user[address][postcode]" class="input-text postcode" value="<?php echo $this->htmlEscape($this->getCustomerZip()) ?>" />
82
  <p class="help"><?php echo $this->helper('checkout')->__('Zip/Post') ?></p>
83
  </div>
84
  <div class="f-left no-mr">
85
- <input type="text" name="user[address][city]" class="input-text required-entry w-244" value="<?php echo $this->htmlEscape($this->getAddress()->getCity()) ?>" />
86
  <p class="help"><?php echo $this->helper('checkout')->__('City') ?>*</p>
87
  </div>
88
  </div>
3
  $prefix = $isLoggedIn ? 'logged' : 'new';
4
  $isLocationAsOneField = $this->helper('fi_checkout')->isLocationAsOneField();
5
  ?>
6
+ <form id="<?php echo $isLoggedIn ? 'registered-user-form' : 'new-user-form' ?>" action="<?php echo $this->getUrl('fi_order/checkout/place') ?>" method="post" name="user_info">
7
  <div class="col2-set">
8
  <div class="col-1 user-general">
9
  <p class="required">* <?php echo $this->__('Required Fields') ?></p>
10
  <div class="field">
11
  <label><?php echo $this->__('Name') ?>*</label>
12
+ <input type="text" class="input-text required-entry<?php echo $isLoggedIn ? ' disabled' : '' ?>" name="user[name]" value="<?php echo $this->htmlEscape($this->getCustomerName()) ?>" <?php if ($isLoggedIn): ?> readonly="readonly"<?php endif ?> />
13
  </div>
14
  <div class="field relative">
15
  <label><?php echo $this->__('Telephone') ?>*</label>
16
+ <input type="text" class="input-text required-entry<?php echo $isLoggedIn && $this->getCustomerPhone() ? ' disabled' : '' ?>" name="user[address][telephone]" value="<?php echo $this->htmlEscape($this->getCustomerPhone()) ?>" <?php if ($isLoggedIn && $this->getCustomerPhone()): ?> readonly="readonly"<?php endif ?> />
17
  </div>
18
  <div class="field">
19
  <label><?php echo $this->__('E-mail') ?>*</label>
20
+ <input type="text" class="validate-email input-text required-entry<?php echo $isLoggedIn ? ' disabled' : '' ?>" name="user[email]" value="<?php echo $this->htmlEscape($this->getCustomerEmail()) ?>" <?php if ($isLoggedIn): ?> readonly="readonly"<?php endif ?> />
21
  </div>
22
  <?php if (!$isLoggedIn): ?>
23
  <?php if ($this->helper('fi_checkout')->canShowPasswordField()): ?>
24
  <div class="field">
25
  <label><?php echo $this->helper('checkout')->__('Password') ?>*</label>
26
+ <input type="password" class="input-text validate-password non-storable" name="user[password]" />
27
  </div>
28
  <?php elseif ($this->helper('fi_checkout')->isPasswordAsTelephone()): ?>
29
  <span class="note">* <?php echo $this->__('Telephone number will be your password.') ?></span>
70
  <p class="help"><?php echo $this->helper('checkout')->__('Country') ?>*</p>
71
  </div>
72
  <div class="f-left relative hidden-select no-mr">
73
+ <input type="text" name="user[address][region]" class="input-text required-entry fake-title non-storable" value="<?php echo $this->htmlEscape($this->getCustomerRegion()) ?>" tabindex="-1" />
74
  <?php $select = $this->getRegionBlock()->setName('user[address][region_id]') ?>
75
  <?php echo $select->getHtml() ?>
76
  <p class="help"><?php echo $select->getTitle()?>*</p>
78
  <?php endif ?>
79
  <div class="clear"></div>
80
  <div class="f-left">
81
+ <input type="text" name="user[address][postcode]" class="input-text postcode non-storable" value="<?php echo $this->htmlEscape($this->getCustomerZip()) ?>" />
82
  <p class="help"><?php echo $this->helper('checkout')->__('Zip/Post') ?></p>
83
  </div>
84
  <div class="f-left no-mr">
85
+ <input type="text" name="user[address][city]" class="input-text required-entry w-244" value="<?php echo $this->htmlEscape($this->getCustomerCity()) ?>" />
86
  <p class="help"><?php echo $this->helper('checkout')->__('City') ?>*</p>
87
  </div>
88
  </div>
app/design/frontend/default/default/template/freaks/checkout/payment.phtml CHANGED
@@ -1,7 +1,7 @@
1
  <div id="payment-methods" class="discount">
2
  <h2><?php echo $this->__('Choose Payment Method') ?>*</h2>
3
  <div>
4
- <div id="payment-form" data-action="<?php echo $this->getUrl('fi_order/checkout/update') ?>">
5
  <?php echo $this->getChildHtml('methods') ?>
6
  </div>
7
  </div>
1
  <div id="payment-methods" class="discount">
2
  <h2><?php echo $this->__('Choose Payment Method') ?>*</h2>
3
  <div>
4
+ <div id="payment-form" data-action="<?php echo $this->getUrl('fi_order/checkout/update') ?>" data-update-totals="<?php echo $this->helper('fi_checkout')->shouldUpdateTotalsWhenPaymentChanged() ?>">
5
  <?php echo $this->getChildHtml('methods') ?>
6
  </div>
7
  </div>
app/design/frontend/default/default/template/freaks/checkout/payment_methods.phtml CHANGED
@@ -5,9 +5,9 @@
5
  <?php $verifyUrl = $this->getVerifyCcUrl($_method) ?>
6
  <dt>
7
  <?php if ($count > 1): ?>
8
- <input id="p_method_<?php echo $_code ?>" value="<?php echo $_code ?>" type="radio" name="payment[method]" title="<?php echo $this->htmlEscape($_method->getTitle()) ?>"<?php if($this->getSelectedMethodCode()==$_code): ?> checked="checked"<?php endif; ?> class="radio validate-one-required-by-name" data-action="<?php echo $verifyUrl ?>" />
9
  <?php else: ?>
10
- <span class="no-display"><input id="p_method_<?php echo $_code ?>" value="<?php echo $_code ?>" type="radio" name="payment[method]" checked="checked" class="radio" data-action="<?php echo $verifyUrl ?>" /></span>
11
  <?php endif; ?>
12
  <label for="p_method_<?php echo $_code ?>"><?php echo $this->getMethodTitle($_method) ?> <?php echo $this->getMethodLabelAfterHtml($_method) ?></label>
13
  </dt>
5
  <?php $verifyUrl = $this->getVerifyCcUrl($_method) ?>
6
  <dt>
7
  <?php if ($count > 1): ?>
8
+ <input id="p_method_<?php echo $_code ?>" value="<?php echo $_code ?>" type="radio" name="payment[method]" title="<?php echo $this->htmlEscape($_method->getTitle()) ?>"<?php if($this->getSelectedMethodCode()==$_code): ?> checked="checked"<?php endif; ?> class="radio validate-one-required-by-name non-storable" data-action="<?php echo $verifyUrl ?>" />
9
  <?php else: ?>
10
+ <span class="no-display"><input id="p_method_<?php echo $_code ?>" value="<?php echo $_code ?>" type="radio" name="payment[method]" checked="checked" class="radio non-storable" data-action="<?php echo $verifyUrl ?>" /></span>
11
  <?php endif; ?>
12
  <label for="p_method_<?php echo $_code ?>"><?php echo $this->getMethodTitle($_method) ?> <?php echo $this->getMethodLabelAfterHtml($_method) ?></label>
13
  </dt>
app/design/frontend/default/default/template/freaks/checkout/shipping/available.phtml CHANGED
@@ -11,9 +11,9 @@
11
  <ul class="messages"><li class="error-msg"><ul><li><?php echo $_rate->getErrorMessage() ?></li></ul></li></ul>
12
  <?php else: ?>
13
  <?php if ($_sole) : ?>
14
- <span class="no-display"><input class="validate-one-required-by-name" name="shipping_method" type="radio" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>" checked="checked" /></span>
15
  <?php else: ?>
16
- <input class="validate-one-required-by-name" name="shipping_method" type="radio" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio"/>
17
  <?php endif; ?>
18
  <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $_rate->getMethodTitle() ?>
19
  <?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
11
  <ul class="messages"><li class="error-msg"><ul><li><?php echo $_rate->getErrorMessage() ?></li></ul></li></ul>
12
  <?php else: ?>
13
  <?php if ($_sole) : ?>
14
+ <span class="no-display"><input class="validate-one-required-by-name non-storable" name="shipping_method" type="radio" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>" checked="checked" /></span>
15
  <?php else: ?>
16
+ <input class="validate-one-required-by-name non-storable" name="shipping_method" type="radio" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio"/>
17
  <?php endif; ?>
18
  <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $_rate->getMethodTitle() ?>
19
  <?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
app/etc/modules/FI_Checkout.xml CHANGED
@@ -3,7 +3,7 @@
3
  <modules>
4
  <FI_Checkout>
5
  <active>true</active>
6
- <codePool>local</codePool>
7
  </FI_Checkout>
8
  </modules>
9
  </config>
3
  <modules>
4
  <FI_Checkout>
5
  <active>true</active>
6
+ <codePool>community</codePool>
7
  </FI_Checkout>
8
  </modules>
9
  </config>
package.xml CHANGED
@@ -1,26 +1,29 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>FI_Checkout</name>
4
- <version>1.0.3</version>
5
  <stability>stable</stability>
6
- <license uri="http://atmagex.com/license-agreement">FreaksIdea License Agreement</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>0 Step Checkout provide One Page Checkout functionality for Magento, combine all the steps for checkout (including shopping cart) into one page only. It will made the checkout process much simpler. </summary>
10
- <description>0 Step Checkout provide One Page Checkout functionality for Magento, combine all the steps for checkout (including shopping cart) into one page only. It will made the checkout process much simpler. To get more information please visit http://atmagex.com/0-step-checkout-magento.html</description>
11
- <notes>- Refactored javascript code using pattern builder to make it easily support and customized.&#xD;
12
- - Fixed few bugs with wrong logic. &#xD;
13
- - Refactored PHP code, put all process that used customer session into helper. It makes some parts of code shared between different parts of the extension.&#xD;
 
 
 
14
  &#xD;
15
- Version 1.0 released&#xD;
16
- 2012/05/16&#xD;
17
- Version number: 1.0&#xD;
18
  Stability: stable&#xD;
19
  Compatibility: 1.5, 1.6, 1.6.0.0, 1.6.1, 1.6.2.0, 1.7</notes>
20
  <authors><author><name>Sergiy Stotskiy</name><user>sergiy_stotskiy</user><email>sergiy.stotskiy@freaksidea.com</email></author></authors>
21
- <date>2012-06-09</date>
22
- <time>22:08:52</time>
23
- <contents><target name="magelocal"><dir name="FI"><dir name="Checkout"><dir name="Block"><dir name="Block"><file name="Info.php" hash="af7479d20f4510feaf02f14173521892"/></dir><file name="Block.php" hash="e96feb1510b4bdc5ba4513e7f98490cf"/><file name="Newsletter.php" hash="19d5938be8caac3eb661fb1f45af66f3"/><dir name="Payment"><file name="Methods.php" hash="c42b6ba6678ab68312fba904cc01e2c1"/></dir></dir><dir name="Helper"><file name="Data.php" hash="97f92a65c8f3df8a5c080e7c0d3008a5"/></dir><dir name="Model"><file name="Observer.php" hash="2576097aec72d2589096fabca98be7d4"/><file name="Page.php" hash="2d8eb0a98862271c6d4f654ccf639a50"/><dir name="Resource"><file name="Countries.php" hash="75f44d3714df682941dfe9a6c7f0b440"/></dir><file name="Source.php" hash="d1984805586e356ad6e974220f1e9b2c"/><file name="Subscriber.php" hash="e0d4206673e616a136322537264f03cf"/></dir><dir name="controllers"><file name="CheckoutController.php" hash="5721f388bb522481f8629b0917b78546"/></dir><dir name="etc"><file name="config.xml" hash="ee654172d7b4ff7c4708b21243e10bd4"/><file name="system.xml" hash="d9274eefe2f17c13c39988a67c7f66fa"/></dir><dir name="sql"><dir name="fi_checkout_setup"><file name="mysql4-install-1.0.0.php" hash="1f0f6b7d41cff2569cde4c724f2909b4"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="default"><dir name="default"><dir name="layout"><dir name="freaks"><file name="checkout.xml" hash="3b565b258eae1f7dda4d80d9ee281642"/></dir></dir><dir name="template"><dir name="freaks"><file name="autocomplete.phtml" hash="bce316a1d37a91ed952bdb3fb87998bc"/><dir name="checkout"><file name="agreements.phtml" hash="72495b7d2cf6632a9ac9d266d045a3d8"/><dir name="block"><file name="info.phtml" hash="4efd83bfd4e6d1b5ae7a05916612742c"/></dir><file name="block.phtml" hash="cb8d320fd05e9d919c504acbb14ea8da"/><dir name="centinel"><file name="authentication.phtml" hash="fe87fdc373fe0cdbcc25141f5e2696c7"/><file name="complete.phtml" hash="83f6e30a7445f8b8b8c343e9fa02b983"/></dir><file name="coupon.phtml" hash="b70b6766d72d16c2357f29453a386b98"/><file name="link.phtml" hash="e12f971b4ab1cb43bb252bada257f2af"/><file name="newsletter.phtml" hash="ecd6f19fcf11b41bedcf18cf0cdbee44"/><file name="payment.phtml" hash="6cac0f89dc309fc687b9ba711625906a"/><file name="payment_methods.phtml" hash="95f5a59dad96bac448da16cd53990508"/><dir name="shipping"><file name="available.phtml" hash="8ef4a692108627fc337f9ebafd0d221f"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="FI_Checkout.xml" hash="ecc17aa69a43cdbb28610c3636963482"/></dir></target><target name="mageskin"><dir name="frontend"><dir name="default"><dir name="default"><dir name="css"><file name="freaks.css" hash="1b66a0f2df69524c4af78385711024c4"/></dir><dir name="js"><file name="freaks_checkout.js" hash="b54d8d784c71878146411f6f4d3c40e1"/></dir><dir name="images"><dir name="fi"><file name="button.jpg" hash="fcdf2df5b1c714a7c39c61a1be387033"/><file name="loader-old.gif" hash="cf46f7db4c452ea2a94d33eabca8ba93"/><file name="loader.gif" hash="7b9776076d5fceef4993b55c9383dedd"/><file name="popup_arrow-blue.gif" hash="051e0d2ab1f2ef9df98c347b1d7c1a24"/><file name="popup_arrow-white.gif" hash="86a112b675b3a9ed5168d4309170d732"/><file name="select-loader-old.gif" hash="55ded965cfe6095ed8c49f9f980de32a"/><file name="select-loader.gif" hash="a045769166b4cad098ffe7d5aefe95e9"/><file name="select-tip.gif" hash="196ba8fe47100e603ffdd731b6d47d90"/></dir></dir></dir></dir></dir></target></contents>
24
  <compatible/>
25
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
26
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>FI_Checkout</name>
4
+ <version>1.2.0</version>
5
  <stability>stable</stability>
6
+ <license uri="http://www.opensource.org/licenses/MIT">MIT License</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>0 Step Checkout provide One Page Checkout functionality for Magento, combine all the steps for checkout (including shopping cart) into one page only. It will made the checkout process much simpler. </summary>
10
+ <description>0 Step Checkout provide One Page Checkout functionality for Magento, combine all the steps for checkout (including shopping cart) into one page only. It will made the checkout process much simpler. To get more information please visit http://ex.freaksidea.com/0-step-checkout-magento.html</description>
11
+ <notes>- Refactored javascript.&#xD;
12
+ - Fixed minor bugs with region field. &#xD;
13
+ - Refactored PHP code, implemented new model which handles all session's changes.&#xD;
14
+ - Implemented ability to specify default shipping method.&#xD;
15
+ - Implemented ability to specify default payment method.&#xD;
16
+ - Implemented auto refresh when payment method is changed.&#xD;
17
  &#xD;
18
+ Version 1.2.0 released&#xD;
19
+ 2013/03/20&#xD;
20
+ Version number: 1.2.0&#xD;
21
  Stability: stable&#xD;
22
  Compatibility: 1.5, 1.6, 1.6.0.0, 1.6.1, 1.6.2.0, 1.7</notes>
23
  <authors><author><name>Sergiy Stotskiy</name><user>sergiy_stotskiy</user><email>sergiy.stotskiy@freaksidea.com</email></author></authors>
24
+ <date>2013-03-23</date>
25
+ <time>15:47:37</time>
26
+ <contents><target name="magecommunity"><dir name="FI"><dir name="Checkout"><dir name="Block"><dir name="Block"><file name="Info.php" hash="cb00486b8a465e1f76c8891d18cdf959"/></dir><file name="Block.php" hash="e96feb1510b4bdc5ba4513e7f98490cf"/><file name="Newsletter.php" hash="19d5938be8caac3eb661fb1f45af66f3"/><dir name="Payment"><file name="Methods.php" hash="c42b6ba6678ab68312fba904cc01e2c1"/></dir></dir><dir name="Helper"><file name="Data.php" hash="12b966cc74f16149afad82fd636c72eb"/></dir><dir name="Model"><file name="Observer.php" hash="e8e5db2033b58b953bf1ad456022fb12"/><file name="Order.php" hash="c11f5e4d2402f1d910ee869fb4e2274c"/><file name="Page.php" hash="2d8eb0a98862271c6d4f654ccf639a50"/><dir name="Resource"><file name="Countries.php" hash="0913ec95198690e5cb81ec8fe4208307"/></dir><dir name="Source"><file name="PaymentMethods.php" hash="151bcf53d0a59172f8a72299133b4555"/><file name="ShippingMethods.php" hash="c682744b99466d3046b53a8d5a63e965"/></dir><file name="Source.php" hash="dac7c0a50d7b28753c39021d425e6bc0"/><file name="Subscriber.php" hash="e0d4206673e616a136322537264f03cf"/></dir><dir name="controllers"><file name="CheckoutController.php" hash="7741fbf951df9bdb5c96c0877d8e2d0d"/></dir><dir name="etc"><file name="config.xml" hash="bfea8524d21a0c54314d15776c8f42b9"/><file name="system.xml" hash="17332eeed4a0ee3663fa5c0ab77dbebb"/></dir><dir name="sql"><dir name="fi_checkout_setup"><file name="mysql4-install-1.0.0.php" hash="1f0f6b7d41cff2569cde4c724f2909b4"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="default"><dir name="default"><dir name="layout"><dir name="freaks"><file name="checkout.xml" hash="3b565b258eae1f7dda4d80d9ee281642"/></dir></dir><dir name="template"><dir name="freaks"><file name="autocomplete.phtml" hash="bce316a1d37a91ed952bdb3fb87998bc"/><dir name="checkout"><file name="agreements.phtml" hash="72495b7d2cf6632a9ac9d266d045a3d8"/><dir name="block"><file name="info.phtml" hash="93c8cef1bfabceef5c9d0356bb6ce183"/></dir><file name="block.phtml" hash="1c172112b2272a41a6ffce4985c791d0"/><dir name="centinel"><file name="authentication.phtml" hash="fe87fdc373fe0cdbcc25141f5e2696c7"/><file name="complete.phtml" hash="83f6e30a7445f8b8b8c343e9fa02b983"/></dir><file name="coupon.phtml" hash="b70b6766d72d16c2357f29453a386b98"/><file name="link.phtml" hash="e12f971b4ab1cb43bb252bada257f2af"/><file name="newsletter.phtml" hash="ecd6f19fcf11b41bedcf18cf0cdbee44"/><file name="payment.phtml" hash="cd4215089b3d7a8b90ee63ab01992a42"/><file name="payment_methods.phtml" hash="422e71395d2e99ffa74dd9649046a28b"/><dir name="shipping"><file name="available.phtml" hash="d48bc2c689d7e5b3fa68bcbaddfae4b4"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="FI_Checkout.xml" hash="0843e490529db978b5c4a16aa9b820d9"/></dir></target><target name="mageskin"><dir name="frontend"><dir name="default"><dir name="default"><dir name="js"><file name="freaks_checkout.js" hash="16f56a11e3bf209d9407bc151e6bad42"/></dir><dir name="css"><file name="freaks.css" hash="1b66a0f2df69524c4af78385711024c4"/></dir><dir name="images"><dir name="fi"><file name="button.jpg" hash="fcdf2df5b1c714a7c39c61a1be387033"/><file name="loader-old.gif" hash="cf46f7db4c452ea2a94d33eabca8ba93"/><file name="loader.gif" hash="7b9776076d5fceef4993b55c9383dedd"/><file name="popup_arrow-blue.gif" hash="051e0d2ab1f2ef9df98c347b1d7c1a24"/><file name="popup_arrow-white.gif" hash="86a112b675b3a9ed5168d4309170d732"/><file name="select-loader-old.gif" hash="55ded965cfe6095ed8c49f9f980de32a"/><file name="select-loader.gif" hash="a045769166b4cad098ffe7d5aefe95e9"/><file name="select-tip.gif" hash="196ba8fe47100e603ffdd731b6d47d90"/></dir></dir></dir></dir></dir></target></contents>
27
  <compatible/>
28
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
29
  </package>
skin/frontend/default/default/js/freaks_checkout.js CHANGED
@@ -1,52 +1,9 @@
1
  /**
2
- * Zero Step Checkout frontend controller
3
  *
4
  * @category FI
5
  * @package FI_Checkout
6
  * @author Sergiy Stotskiy <sergiy.stotskiy@freaksidea.com>
7
  * @copyright Copyright (c) 2012 Sergiy Stotskiy (http://freaksidea.com)
8
  */
9
-
10
- /**
11
- * Storage plugin
12
- * Provides a simple interface for storing data such as user preferences.
13
- * Storage is useful for saving and retreiving data from the user's browser.
14
- * For newer browsers, localStorage is used.
15
- * If localStorage isn't supported, then cookies are used instead.
16
- * Retrievable data is limited to the same domain as this file.
17
- *
18
- * Usage:
19
- * This plugin extends jQuery by adding itself as a static method.
20
- * $.Storage - is the class name, which represents the user's data store, whether it's cookies or local storage.
21
- * <code>if ($.Storage)</code> will tell you if the plugin is loaded.
22
- * $.Storage.set("name", "value") - Stores a named value in the data store.
23
- * $.Storage.set({"name1":"value1", "name2":"value2", etc}) - Stores multiple name/value pairs in the data store.
24
- * $.Storage.get("name") - Retrieves the value of the given name from the data store.
25
- * $.Storage.remove("name") - Permanently deletes the name/value pair from the data store.
26
- *
27
- * @author Dave Schindler
28
- * @modified by Sergiy Stotskiy
29
- *
30
- * Distributed under the MIT License
31
- *
32
- * Copyright (c) 2010 Dave Schindler
33
- *
34
- * Permission is hereby granted, free of charge, to any person obtaining a copy
35
- * of this software and associated documentation files (the "Software"), to deal
36
- * in the Software without restriction, including without limitation the rights
37
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
38
- * copies of the Software, and to permit persons to whom the Software is
39
- * furnished to do so, subject to the following conditions:
40
- *
41
- * The above copyright notice and this permission notice shall be included in
42
- * all copies or substantial portions of the Software.
43
- *
44
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
48
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
50
- * THE SOFTWARE.
51
- */
52
- eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(4($){5 b=11 4L.1t!==\'2V\';4 4K(n,v){5 c;6(11 n==="2k"&&11 v==="2k"){1t[n]=v;7 q}B 6(11 n==="4G"&&11 v==="2V"){D(c I n){6(n.4F(c)){1t[c]=n[c]}}7 q}7 C}4 2w(n,v){5 a,e,c;a=m 5E();a.5D(a.5B()+5w);e="; 5v="+a.5t();6(11 n==="2k"&&11 v==="2k"){J.2x=n+"="+v+e+"; 4z=/";7 q}B 6(11 n==="4G"&&11 v==="2V"){D(c I n){6(n.4F(c)){J.2x=c+"="+n[c]+e+"; 4z=/"}}7 q}7 C}4 4y(n){7 1t[n]}4 4x(n){5 a,24,i,c;a=n+"=";24=J.2x.4v(\';\');D(i=0;i<24.F;i++){c=24[i];1r(c.5m(0)===\' \'){c=c.4l(1,c.F)}6(c.54(a)===0){7 c.4l(a.F,c.F)}}7 10}4 4f(n){1J{4O 1t[n]}1G(e){1t[n]=\'\'}}4 4e(n){7 2w(n,"",-1)}$.N={4c:b?4K:2w,1F:b?4y:4x,1m:b?4f:4e}})(3b);2f.r.4b=4(a){6(J.4a){5 e=J.4a(\'5C\');e.5u(a,q,q);7 3.5r(e)}6(J.45){5 e=J.45();7 3.5o(\'5l\'+a,e)}};5 2H=1h.1f();2H.r={1j:4(b,c){3.21=10;3.u={};3.X=3b.5d({2n:\'1x\',39:\'1w\'},c||{});6(!b){7 C}3.1k=$(b);5 d=3;3.1k.o(\'14\',4(e){5 a=19.8(e);6(a.1H.2s()!=\'a\'){7 q}d.2y(a.O.1I(a.O.2q(\'#\')+1));19.2E(e)})},2y:4(a){5 b=3.42(a);6(b.1i&&b.A&&b.1i!=3.1Q()){5 c={1i:3.1Q(),A:3.40()};c.A.W();c.1i.1c(3.X.2n);$(b.1i.12).Y(3.X.2n);$(b.A).1e();6(3.21&&3.21.1K){3.21({1L:c,1x:b})}}},1Q:4(){6(3.1k){7 3.1k.t(\'.\'+3.X.2n)[0]}7 10},40:4(){5 a=3.1Q().3Z(),1g=a.O.1I(a.O.2q(\'#\')+1);7 $(3.1k.12).t(3.X.39+\'.\'+1g)[0]},42:4(b){5 c=$(3.1k.12).t(3.X.39+\'.\'+b)[0],3e=\'\';3.1k.t(\'a\').Q(4(e){5 a=e.O.1I(e.O.2q(\'#\')+1);6(a==b){3e=e;7 C}});7{1i:3e,A:c}},3Y:4(a,b){3.u[a]=b;7 3},3X:4(a){7 3.u[a]},3k:4(){7 3.u},1b:4(){5 a=3.1Q();6(!a){7 10}5 b=a.3Z(),1g=b.O.1I(b.O.2q(\'#\')+1);7 3.u[1g]}};p=1h.1f();p.N=3b.N;p.r=m 1o();p.r.1j=(4(c){7 4(a,b){c.1K(3,a,b);3.3W=a;6(3.9){3.2z();3.9.o(\'13\',3.13.1l(3,\'4Y\'));3.1a={};3.2e=C;3.4U=10}}})(1o.r.1j);p.r.1y=4(a){7 3.3W+\'-\'+a};p.r.2K=4(a){5 i=a.F,2d=\'\';1r(i--){2d=3.1y(a[i]);6(p.N.1F(2d)){p.N.1m(2d)}}7 3};p.r.2z=4(){5 b=3,2N=4(e){5 a=$(3),n=a&&a.1H&&a.1H.2s();6(n!=\'K\'&&n!=\'t\'&&n!=\'4Q\'){a=a.t(\'K\')[0]}p.N.4c(b.1y(a.T),a.l)};1A.2b(3.9).Q(4(e){5 v=p.N.1F(b.1y(e.T));6(v){6(e.E==\'1u\'||e.E==\'35\'){6(e.l==v){e.36=q}}B 6(!e.l){e.l=v}B{p.N.1m(b.1y(e.T))}}6(e.E==\'1u\'||e.E==\'35\'){$(e).w().o(\'14\',2N)}B{$(e).o(\'17\',2N)}});7 3};p.r.13=4(c,d){5 e=3.1N();6(e){5 f=3,3d=3.9,1P=4(a){5 b=f.1y(a.T);6(p.N.1F(b)){p.N.1m(b)}},3Q=4(a){6(a.P||(a.E==\'1u\'||a.E==\'35\')&&!a.36){7}5 b=3d[a.T];6(!b){b=m 2f(\'K\');b.E=\'1q\';b.T=a.T;3d.5U(b)}b.l=a.l};1A.2b(3.9).Q(1P);6(3.2e){D(5 g I 3.1a){5 h=3.1a[g];1A.2b(h.9).Q(1P).Q(3Q)}}6(c==\'3L\'){3.1X()}B 6(c==\'5n\'){3.9.13()}}7 e};p.r.1X=4(){7 m 1D.20(3.9.1v(\'22\'),{Z:3.9.1v(\'Z\'),1C:1A.3J(3.9,q),25:(4(a){1J{5 b=a.26.2I()}1G(e){7}6(b.3H){1B.O=b.3H}B 6(b.2L){5 c=3.9.1s(\'16.3G\');6(c){c.w().2P(c)}3.9.2Q({58:b.2L});3.9.w(1).55()}3.9.1E(\'9:3E\',b)}).1l(3)})};p.r.1N=4(){5 a=3.1Y&&3.1Y.1U();6(a&&3.2e){D(5 b I 3.1a){5 c=3.1a[b];a=a&&c.1Y&&c.1Y.1U();6(!a){3D}}}7 a};p.r.3C=4(a){6(a.9){3.2e=q;3.1a[a.9.1g]=a}7 3};p.r.4P=4(){7 3.1a};p.r.30=4(a){7 3.1a[a]};5 23=1h.1f({1j:4(a){3.8=a;6(3.8){3.32();3.2R(q)}},2R:4(c){5 d=4(e,a){5 b=$(3).1s(\'K[E="34"]\');6(3.3A>=0&&3.l!=0){b.l=3.G[3.3A].5K}B 6(!a){b.l=\'\';p.N.1m(b.9.1g+\'-\'+b.T)}6(!a){b.1E(\'23:17\',{5k:e})}};3.8.o(\'17\',d);d.1K(3.8,10,c);7 3},32:4(a){6(a){5 b=3.8;b.2Q({3v:a});3.8=b.1d();b.w().2P(b);3.2R()}6(!3.8.5b(\'50\').F){3.8.P=q;3.8.W()}B{3.8.P=C;3.8.1e()}7 3},3c:4(a){6(3.8){5 b=3.8.1s(\'K[E="34"]\');b.o(\'23:17\',a.1l(3))}7 3},2o:4(c,d,f){d=d||\'l\';f=f||\'K-18\';5 g={},1S=3;c&&c.o(\'17\',4(e){5 b=1S.8.1s(\'K[E="34"]\');g[d]=3.l;b.Y(f);b.P=q;m 1D.20(3.12.1v(\'2r-22\'),{Z:\'1F\',1C:g,25:4(a){b.1c(f);b.P=C;1S.32(a.26)}})});7 3}});5 3q=1h.1f(1D.4V,{3p:4(){6(3.G.1W)3.8.Y(3.G.1W)},3m:4(){6(3.G.1W)3.8.1c(3.G.1W)},47:4(){3.5a=q;3.5s=C;3.3p();3.G.1C=44(3.G.3n)+\'=\'+44(3.8.l);6(3.G.3o){3.G.1C+=\'&\'+3.G.3o}m 1D.20(3.1p,3.G);3i(3.3m.1l(3),56)},3c:4(b){19.o(3.8,\'17\',(4(e){6(3.3h){5c(3.3h)}5 a=3;3.3h=3i(4(){b.1K(a,e)},5q)}).3r(3));7 3},3s:4(a){19.o(3.8.1d(a),\'14\',(4(e){19.2E(e);3.47()}).3r(3));7 3},5R:4(a){5 b=\'\';6(3.G.t){5 c=$(a).t(\'.\'+3.G.t)||[];6(c.F>0)b=2f.4M(c[0],3.G.t)}B{b=2f.4N(a,\'4R\')}5 d=3.8.l.4v(/\\s*,\\s*/);6(b!=d[d.F-2]){d[d.F-1]=b}3.8.l=d.3t(\', \');3.59=3.8.l;3.8.3u();3.8.4b(\'17\')}});5 S=1h.1f({1j:4(a){3.2l=\'\';3.H={};3.3w(a)},3x:4(){7 3.37()!=10},3w:4(a){D(5 i I a){6(a[i]){3.H[i]=a[i]}}7 3},3y:4(){5 a=\'\';D(5 b I 3.H){5 c=3.H[b];6(a=c.1v(\'2r-22\')){3D}}7 a},37:4(){6(3.2l){7 3.2l}7 3.2l=3.3y()},3z:4(a){D(5 b I 3.H){5 c=a[b],R=3.H[b];6(c){6(R.1H.2s()==\'3B\'){R.2Q({3v:c});3.H[b]=R.1d();R.w().2P(R);R=3.H[b]}B{R.2Z(c)}}R.w().1c(\'18\');R.V({2X:\'\',1n:\'2S\'})}},3F:4(a){5 b=a.26;1J{b=b.2I();3.3z(b);$(J.2a).1E(\'2O:2J\',{3I:3})}1G(e){}},2F:4(a){5 b=[];6(a){5 c=3.H[a];c.V({2X:c.3K()+\'2g\',1n:\'1q\'});$(c.12).Y(\'18\');b.27(a)}B{D(5 a I 3.H){5 c=3.H[a];c.V({2X:c.3K()+\'2g\',1n:\'1q\'});$(c.12).Y(\'18\');b.27(a)}}7 b},1X:4(a){7 m 1D.20(3.37(),{Z:\'3M\',1C:a,25:3.3F.1l(3),5z:4(){1B.O=1B.O}})},5J:4(a){7 3.H[a]||10},3N:4(a,b){5 c=3.H[a];3.2F(a);b=b||{};b.E=a;7 3.1X(b)},3O:4(a){5 b=3.2F();a=a||{};a.E=b.3t(\',\');7 3.1X(a)},3P:4(a){5 b=3.1T(a);6(b){b.1s(\'.29\').1e()}},3R:4(a){5 b=$(a);6(b){b.1s(\'.29\').W()}},1T:4(b){5 c=$(b);6(c){c.Y(\'P\');c.P=q;c.w(\'16\').t(\'3S\').Q(4(a){6(a!=c.12){a.V({1n:\'1q\'})}})}7 c},2c:4(b){5 c=$(b);6(c){c.1c(\'P\');c.P=C;c.w(\'16\').t(\'3S\').Q(4(a){6(a!=c.12){a.V({1n:\'2S\'})}})}7 c},3T:4(){5 c=3;7 4(){5 a=[\'1V\',\'3U\',\'2C\',\'3V\'],i=a.F,8=3.8||3,X={l:8.l};6(8.l.53()&&8.l!=\'0\'){1r(i--){5 b=8.9[\'z[L][\'+a[i]+\']\'];6(b&&b.l){X[a[i]]=b.l}}c.3O(X);c.1T(\'1Z-1R\')}}}});S.2T=4(a,b){5 c=a&&a.1H.2s();7 c==\'K\'&&a.E==b};5 41=1h.1f({1j:4(a){3.8=a;3.2p=\'\';3.31()},43:4(){7 3.2p},2G:4(){7 3.8&&3.8.t(\'K[E="1u"]:36\')[0]},3l:4(){5 a=3.2G();7 a?a.l:\'\'},2m:4(){7 $(\'5p\'+3.2p)},2B:4(a,b){5 c=1A.2b(a),i=c.F;1r(i--){c[i].P=!b}a[b?\'1e\':\'W\']();7 3},2A:4(a){5 b=3.2m();6(b){3.2B(b,a)}7 3},46:4(a){3.2p=a;5 b=3.2m();$(b||J.2a).1E(\'M-Z:5V\',{5A:a});7 3},2v:4(a){3.2A(C);3.46(a);3.2A(q)},31:4(){5 b=3;6(3.8){3.2v(3.3l());3.8.t(\'.9-5G\').Q(4(a){b.2B(a,a.48!=0)})}7 3}});5 49=1h.1f({1j:4(a){3.8=a;3.1N=C;6(3.8){5 b=3.8.w().t(\'a.1z-5O\')[0],1S=3;b.o(\'14\',4(e){$(3).w().W();19.2E(e);1S.8.1E(\'2i:33\')})}},1U:4(c,d){5 f=3;f.8.V({1n:\'1q\'});f.8.w().Y(\'18\');f.8.w().V({4d:\'2W\'});7 m 1D.20(c,{Z:\'3M\',1C:d,25:4(a){1J{5 b=a.26.2I()}1G(e){7}f.8.2Z(b.2U);f.8.V({1n:\'2S\'});f.8.w().1c(\'18\');6(b.1p){f.29(b.1p)}B{f.2t()}}})},4g:4(){3.8.w().W()},29:4(a){5 b=3.8.t(\'4h\')[0];b.4S=a;7 3},4T:4(x,y){6(3.8){3.8.w().V({4W:x+\'2g\',4X:y+\'2g\'})}7 3},4i:4(){7 3.1N},2t:4(){6(3.8){3i((4(){3.8.w().W()}).1l(3),4Z);3.1N=q;3.8.1E(\'2i:2t\')}}});5 4j=1h.1f({51:4(a,b){6(!a.9){7 C}5 c=$(a.9[b]);6(!c||!c.1d(\'.1z\')){7 C}c.o(\'3u\',4(){$(3).1d(\'.1z\').1e()});c.o(\'52\',4(){$(3).1d(\'.1z\').W()});7 c},4k:4(a,b,d){5 f=m 2H(a),1O=\'\';f.21=4(e){6(e.1L.A.2u(\'m-z\')&&!e.1x.A.2u(\'m-z\')){e.1L.A.1e().Y(\'1q-1O\');e.1L.A.1d(\'1w.4m\').V({4d:\'2W\'})}B 6(e.1x.A.2u(\'m-z\')){e.1x.A.1c(\'1q-1O\');e.1x.A.1d(\'1w.4m\').W()}5 c=$(e.1L.A),16=c.t(\'16.3G\')[0];16&&16.W()};D(5 g I b){f.3Y(g,m p(b[g]))}5 h=f.1b();6(h&&d){D(5 i I d){h.3C(d[i])}}6(1O=(1B.57||\' \').1I(1)){f.2y(1O)}7 f},4n:4(b){5 c=m 1o(b);c.13=4(a){6(a){$(3.9[\'4o\']).1c(\'4p-4q\');$(3.9[\'1m\']).l="1"}B{$(3.9[\'4o\']).Y(\'4p-4q\');$(3.9[\'1m\']).l="0"}7 1o.r.13.1K(3)};6(c.9){c.9.t(\'1i\').Q(4(a){a.o(\'14\',4(){c.13(3.T==\'33\')})})}},4r:4(a){5 i=a.F,u={};1r(i--){u[a[i]]=m p(a[i])}7 u},1P:4(a,b){5 c=\'\',9=\'\';D(c I a){9=a[c];6(9.2K&&!9.9){9.2K(b)}}},4s:4(c,d,e){5 f=10;6(c){f=m 3q(c.1s(\'K[1g]\'),c,c.12.1v(\'2r-22\'),{3n:\'1B\',1W:\'K-18\',5e:2,5f:4(a,b){5g.5h(b,{5i:0.15})}});f.3s(\'a.t-5j\')}B 6(e){f=m 23($(e[d.4t]));f.2o($(e[d.2o]),\'1V\',\'K-18\')}7 f},4u:4(a,b,c){6(!c){7}5 k=a.F,28=\'\';1r(k--){28=$(c[\'z[L][\'+a[k]+\']\']);6(28){28.o(\'17\',b)}}},4w:4(b,c){5 d=b.1b()&&b.1b().30(\'M-9\'),1M=[],i=0,u=b.3k(),2M=[];D(5 k I u){6(u[k].9){1M.27(u[k].9.1g);2M.27(k)}}i=1M.F;1r(i--){5 f=$$(\'#\'+1M[i]+\' 1w.2h-4A\')[0];5 g=m S({2h:f,M:d.9,3j:c});6(f){f.o(\'14\',4(e){5 a=19.8(e);6(!S.2T(a,\'1u\')){7 q}g.3N(\'3j\',{4B:a.l,l:a.l});g.1T(\'1Z-1R\')})}6(g.3x()){5 h=b.3X(2M[i]).9,3g=g.3T();5 j=3.4s($$(\'#\'+1M[i]+\' 1w.5x\')[0],{4t:\'z[L][5y]\',2o:\'z[L][1V]\'},h);j&&j.3c(3g);3.4u([\'1V\',\'2C\'],3g,h)}}$(J.2a).o(\'2O:2J\',4(a){d.2z();a.4C.3I.2c(\'1Z-1R\')});7 g},4D:4(b,c){5 d=m 41(b),U=m 49(c);6(d.8){d.8.o(\'14\',4(e){5 a=19.8(e);6(!S.2T(a,\'1u\')){7 q}6(d.43()!=a.l){d.2v(a.l);U.4g()}});$(J.2a).o(\'2O:2J\',4(){d.31()})}6(U.8){5 f=4(){S.r.2c(\'1Z-1R\')};U.8.o(\'2i:2t\',f);U.8.o(\'2i:33\',f)}7{M:d,U:U}},4E:4(d,f,g,h){6(!d){7 C}5 i=f.1b()&&f.1b().30(\'M-9\');d.o(\'14\',4(e){5 a=g.M.2G(),38=q,1p=\'\';6(a){1p=a.1v(\'2r-22\');6(1p&&!g.U.4i()){5 b=1A.3J(g.M.2m(),q);b[a.T]=a.l;6(i.1Y.1U()){g.U.1U(1p,b);S.r.1T(3)}38=C}}6(38&&f.1b().13(\'3L\')){S.r.3P(3)}});5 j=f.1b();6(j.9){j.9.o(\'9:3E\',4(b){S.r.3R(d);5 c=b.4C;6(c.2L){S.r.2c(d)}6(!c.2Y){7 q}A.w().1e();A.2Z(c.2Y.2U);1J{c.2Y.2U.5F()}1G(e){A.t(\'4h\').Q(4(a){6(!a.48){a.o(\'3a\',a.1e.1l(a))}})}})}7 q}});$(J).o(\'5H:5I\',4(){5 a=m 4j(),u=a.4r([\'M-9\']);u[\'2h-Z-3a\']=m 1o(\'2h-Z-3a\');u[\'2j-4H\']=m 1o(\'2j-4H\');u[\'4I-9\']=m 1o(\'4I-9\');5 b=a.4k($$(\'#2j-2W 16.5M-5N\')[0],{\'m-z\':\'m-z-9\',\'4J\':\'2j-4J-9\'},u);5 c=b.3k();D(5 i I c){u[i]=c[i]}a.4n(\'5P-5Q-9\');a.1P(u,[\'M[Z]\',\'4B\',\'z[L][1V]\',\'z[L][3U]\',\'z[L][1B]\',\'z[L][2C]\',\'z[L][3f][0]\',\'z[L][3f][1]\',\'z[L][3f][2]\',\'z[L][3V]\']);a.4w(b,$(\'5S-5T-3j-3B\'));5 d=$$(\'#M-1z 1w.1z-A\')[0],2D=a.4D($(\'M-4A\'),d);a.4E($(\'1Z-1R\'),b,2D,d);4L.5L=2D.U})',62,368,'|||this|function|var|if|return|element|form||||||||||||value|new||observe|RestorableForm|true|prototype||select|forms||up|||user|content|else|false|for|type|length|options|sections|in|document|input|address|payment|Storage|href|disabled|each|section|fiCheckoutViewModel|name|centinel|setStyle|hide|params|addClassName|method|null|typeof|parentNode|submit|click||ul|change|loading|Event|embededForms|getCurrentForm|removeClassName|next|show|create|id|Class|button|initialize|tabsBlock|bind|remove|visibility|VarienForm|url|hidden|while|previous|localStorage|radio|getAttribute|div|current|getKey|popup|Form|location|parameters|Ajax|fire|get|catch|nodeName|substr|try|call|prev|ids|isValid|tab|clearStorage|getCurrentTab|order|self|disableButton|validate|country_id|indicator|request|validator|place|Request|onChangeTab|action|fiSelectBox|ca|onComplete|responseText|push|el|process|body|getElements|enableButton|key|hasEmbededForms|Element|px|shipping|fiCentinel|checkout|string|updateUrl|getAdditionalForm|currentClassName|dependsOn|currentMethod|lastIndexOf|data|toLowerCase|success|hasClassName|switchMethod|wc|cookie|setCurrentTab|restoreValues|showAdditionalForm|enableFormElements|postcode|model|stop|waiting|getCurrentMethodElement|FreaksTabs|evalJSON|updated|clearValues|error_message|aliases|fn|fiCheckout|removeChild|insert|addSelectObserver|visible|isElement|html|undefined|block|height|update_section|update|getEmbededForm|restore|render|cancel|text|checkbox|checked|getUrl|result|contentTagName|load|Object|addChangeListener|mainForm|tabBtn|street|listener|changeTimeout|setTimeout|totals|getTabForms|findCurrentMethod|stopIndicator|paramName|defaultParams|startIndicator|FreaksSelectBox|bindAsEventListener|addShowResults|join|focus|after|createSections|isActive|findUrl|updateView|selectedIndex|table|addEmbededForm|break|has_response|ajaxCallback|messages|redirect|viewModel|serialize|getHeight|ajax|post|updateSection|updateAll|processing|addElements|stopProcessing|li|getChangeListener|region|city|formId|getTabForm|setTabForm|firstDescendant|getCurrentContent|fiPaymentViewModel|getTab|getCurrentMethod|encodeURIComponent|createEventObject|setMethod|showResults|offsetWidth|fiCentinelViewModel|createEvent|triggerEvent|set|display|dc|dls|idle|iframe|isSuccessfull|fiPage|createTabs|substring|overlay|createDiscount|coupon_code|required|entry|createForms|getLocationBox|box|observeAddressFields|split|createCheckout|rc|rls|path|methods|shipping_method|memo|wakeUpPayment|send|hasOwnProperty|object|agreements|newsletter|login|wls|window|collectTextNodes|collectTextNodesIgnoreClass|delete|getEmbededForms|textarea|informal|src|moveElement|responsePopup|Autocompleter|top|left|none|2000|option|addFieldPopup|blur|strip|indexOf|scrollTo|1500|hash|before|oldElementValue|hasFocus|getElementsByTagName|clearTimeout|extend|minChars|onShow|Effect|Appear|duration|tip|event|on|charAt|normal|fireEvent|payment_form_|100|dispatchEvent|changed|toGMTString|initEvent|expires|31536000000|autocomplete|region_id|onFailure|method_code|getTime|HTMLEvents|setTime|Date|evalScripts|list|dom|loaded|getSection|innerHTML|CentinelAuthenticateController|infos|menus|close|discount|coupon|updateElement|shopping|cart|appendChild|switched'.split('|'),0,{}))
1
  /**
2
+ * 0 Step Checkout frontend controller
3
  *
4
  * @category FI
5
  * @package FI_Checkout
6
  * @author Sergiy Stotskiy <sergiy.stotskiy@freaksidea.com>
7
  * @copyright Copyright (c) 2012 Sergiy Stotskiy (http://freaksidea.com)
8
  */
9
+ (function(e){var g=typeof window.localStorage!=="undefined";function h(k,i){var j;if(typeof k==="string"&&typeof i==="string"){localStorage[k]=i;return true}else{if(typeof k==="object"&&typeof i==="undefined"){for(j in k){if(k.hasOwnProperty(j)){localStorage[j]=k[j]}}return true}}return false}function b(m,i){var j,k,l;j=new Date();j.setTime(j.getTime()+31536000000);k="; expires="+j.toGMTString();if(typeof m==="string"&&typeof i==="string"){document.cookie=m+"="+i+k+"; path=/";return true}else{if(typeof m==="object"&&typeof i==="undefined"){for(l in m){if(m.hasOwnProperty(l)){document.cookie=l+"="+m[l]+k+"; path=/"}}return true}}return false}function d(i){return localStorage[i]}function c(o){var m,j,k,l;m=o+"=";j=document.cookie.split(";");for(k=0;k<j.length;k++){l=j[k];while(l.charAt(0)===" "){l=l.substring(1,l.length)}if(l.indexOf(m)===0){return l.substring(m.length,l.length)}}return null}function f(j){try{delete localStorage[j]}catch(i){localStorage[j]=""}}function a(i){return b(i,"",-1)}e.Storage={set:g?h:b,get:g?d:c,remove:g?f:a}})(Object);Element.prototype.triggerEvent=function(a){if(document.createEvent){var b=document.createEvent("HTMLEvents");b.initEvent(a,true,true);return this.dispatchEvent(b)}if(document.createEventObject){var b=document.createEventObject();return this.fireEvent("on"+a,b)}};var FreaksTabs=Class.create();FreaksTabs.prototype={initialize:function(c,b){this.onChangeTab=null;this.forms={};this.params=Object.extend({currentClassName:"current",contentTagName:"div"},b||{});if(!c){return false}this.tabsBlock=$(c);var a=this;this.tabsBlock.observe("click",function(f){var d=Event.element(f);if(d.nodeName.toLowerCase()!="a"){return true}a.setCurrentTab(d.href.substr(d.href.lastIndexOf("#")+1));Event.stop(f)})},setCurrentTab:function(c){var b=this.getTab(c);if(b.button&&b.content&&b.button!=this.getCurrentTab()){var a={button:this.getCurrentTab(),content:this.getCurrentContent()};a.content.hide();a.button.removeClassName(this.params.currentClassName);$(b.button.parentNode).addClassName(this.params.currentClassName);$(b.content).show();if(this.onChangeTab&&this.onChangeTab.call){this.onChangeTab({prev:a,current:b})}}},getCurrentTab:function(){if(this.tabsBlock){return this.tabsBlock.select("."+this.params.currentClassName)[0]}return null},getCurrentContent:function(){var a=this.getCurrentTab().firstDescendant(),b=a.href.substr(a.href.lastIndexOf("#")+1);return $(this.tabsBlock.parentNode).select(this.params.contentTagName+"."+b)[0]},getTab:function(c){var a=$(this.tabsBlock.parentNode).select(this.params.contentTagName+"."+c)[0],b="";this.tabsBlock.select("a").each(function(d){var f=d.href.substr(d.href.lastIndexOf("#")+1);if(f==c){b=d;return false}});return{button:b,content:a}},setTabForm:function(b,a){this.forms[b]=a;return this},getTabForm:function(a){return this.forms[a]},getTabForms:function(){return this.forms},getCurrentForm:function(){var b=this.getCurrentTab();if(!b){return null}var a=b.firstDescendant(),c=a.href.substr(a.href.lastIndexOf("#")+1);return this.forms[c]}};RestorableForm=Class.create();RestorableForm.Storage=Object.Storage;RestorableForm.prototype=new VarienForm();RestorableForm.prototype.initialize=(function(a){return function(c,b){a.call(this,c,b);this.formId=c;if(this.form){this.restoreValues();this.form.observe("submit",this.submit.bindAsEventListener(this));this.embededForms={};this.hasEmbededForms=false;this.responsePopup=null}}})(VarienForm.prototype.initialize);RestorableForm.prototype.getKey=function(a){return this.formId+"-"+a};RestorableForm.prototype.clearValues=function(c){var b=c.length,a="";while(b--){a=this.getKey(c[b]);if(RestorableForm.Storage.get(a)){RestorableForm.Storage.remove(a)}}return this};RestorableForm.prototype.restoreValues=function(){var a=this,b=function(d){var c=$(this),f=c&&c.nodeName&&c.nodeName.toLowerCase();if(f!="input"&&f!="select"&&f!="textarea"){c=c.select("input")[0]}RestorableForm.Storage.set(a.getKey(c.name),c.value)};Form.getElements(this.form).each(function(d){if(d.hasClassName("non-storable")){return true}var c=RestorableForm.Storage.get(a.getKey(d.name));if(c){if(d.type=="radio"||d.type=="checkbox"){if(d.value==c){d.checked=true}}else{d.value=c}}if(d.type=="radio"||d.type=="checkbox"){d.up().observe("click",b)}else{d.observe("change",b)}});return this};RestorableForm.prototype.submit=function(c,b){var g=this.isValid();if(g){var h=this,a=this.form,d=function(k){var j=h.getKey(k.name);if(RestorableForm.Storage.get(j)){RestorableForm.Storage.remove(j)}},f=function(j){if(j.disabled||(j.type=="radio"||j.type=="checkbox")&&!j.checked){return}var k=a[j.name];if(!k){k=new Element("input");k.type="hidden";k.name=j.name;a.appendChild(k)}k.value=j.value};Form.getElements(this.form).each(d);if(this.hasEmbededForms){for(var e in this.embededForms){var i=this.embededForms[e];Form.getElements(i.form).each(d).each(f)}}if(c){this.request()}else{this.form.submit()}}return g};RestorableForm.prototype.request=function(){return new Ajax.Request(this.form.getAttribute("action"),{method:this.form.getAttribute("method"),parameters:Form.serialize(this.form,true),onComplete:(function(b){try{var a=b.responseText.evalJSON()}catch(c){return}if(a.redirect){location.href=a.redirect}else{if(a.error_message){var d=this.form.previous("ul.messages");if(d){d.up().removeChild(d)}this.form.insert({before:a.error_message});this.form.up(1).scrollTo()}}this.form.fire("form:has_response",a)}).bind(this)})};RestorableForm.prototype.isValid=function(){var b=this.validator&&this.validator.validate();if(b&&this.hasEmbededForms){for(var c in this.embededForms){var a=this.embededForms[c];b=b&&a.validator&&a.validator.validate();if(!b){break}}}return b};RestorableForm.prototype.addEmbededForm=function(a){if(a.form){this.hasEmbededForms=true;this.embededForms[a.form.id]=a}return this};RestorableForm.prototype.getEmbededForms=function(){return this.embededForms};RestorableForm.prototype.getEmbededForm=function(a){return this.embededForms[a]};var fiSelectBox=Class.create({initialize:function(a){this.element=$(a);if(this.element){this.clearInputValueIfNotInList();this.render();this.addSelectObserver(true)}},clearInputValueIfNotInList:function(){var b=$(this.element).previous('input[type="text"]'),a=b.value.strip().replace(/"/g,'\\"');if(this.element.select("option").length&&!this.element.select('option:contains("'+a+'")').length){b.value=""}},addSelectObserver:function(a){var b=function(d,c){var f=$(this).previous('input[type="text"]');if(this.selectedIndex>=0&&this.value!=0){f.value=this.options[this.selectedIndex].innerHTML}else{if(!c){f.value=""}}if(!c){f.fire("fiSelectBox:change",{event:d})}};this.element.observe("change",b);b.call(this.element,null,a);return this},render:function(a){if(a){var b=this.element;b.insert({after:a});this.element=b.next();b.up().removeChild(b);this.addSelectObserver()}if(!this.element.getElementsByTagName("option").length){this.element.disabled=true;this.element.hide()}else{this.element.disabled=false;this.element.show()}return this},addChangeListener:function(a){if(this.element){var b=this.element.previous('input[type="text"]');b.observe("fiSelectBox:change",a.bind(this))}return this},dependsOn:function(b,d,c){d=d||"value";c=c||"input-loading";var e={},a=this;b&&b.observe("change",function(g){var f=a.element.previous('input[type="text"]');e[d]=this.value;f.addClassName(c);f.value="";f.disabled=true;new Ajax.Request(this.parentNode.getAttribute("data-action"),{method:"get",parameters:e,onComplete:function(h){f.removeClassName(c);f.disabled=false;a.render(h.responseText)}})});return this}});var FreaksAutocompleter=Class.create(Ajax.Autocompleter,{startIndicator:function(){if(this.options.indicator){this.element.addClassName(this.options.indicator)}},stopIndicator:function(){if(this.options.indicator){this.element.removeClassName(this.options.indicator)}},showResults:function(){this.hasFocus=true;this.changed=false;this.startIndicator();this.options.parameters=encodeURIComponent(this.options.paramName)+"="+encodeURIComponent(this.element.value);if(this.options.defaultParams){this.options.parameters+="&"+this.options.defaultParams}new Ajax.Request(this.url,this.options);setTimeout(this.stopIndicator.bind(this),1500)},addChangeListener:function(a){Event.observe(this.element,"change",(function(c){if(this.changeTimeout){clearTimeout(this.changeTimeout)}var b=this;this.changeTimeout=setTimeout(function(){a.call(b,c)},100)}).bindAsEventListener(this));return this},addShowResults:function(a){Event.observe(this.element.next(a),"click",(function(b){Event.stop(b);this.showResults()}).bindAsEventListener(this));return this},updateElement:function(d){var c="";if(this.options.select){var a=$(d).select("."+this.options.select)||[];if(a.length>0){c=Element.collectTextNodes(a[0],this.options.select)}}else{c=Element.collectTextNodesIgnoreClass(d,"informal")}var b=this.element.value.split(/\s*,\s*/);if(c!=b[b.length-2]){b[b.length-1]=c}this.element.value=b.join(", ");this.oldElementValue=this.element.value;this.element.focus();this.element.triggerEvent("change")}});var fiCheckoutViewModel=Class.create({initialize:function(a){this.updateUrl="";this.sections={};this.requests={};this.createSections(a)},isActive:function(){return this.getUrl()!=null},createSections:function(b){for(var a in b){if(b[a]){this.sections[a]=b[a]}}return this},findUrl:function(){var a="";for(var b in this.sections){var c=this.sections[b];if(a=c.getAttribute("data-action")){break}}return a},getUrl:function(){if(this.updateUrl){return this.updateUrl}return this.updateUrl=this.findUrl()},updateView:function(d){for(var b in this.sections){var a=d[b],c=this.sections[b];if(a){if(c.nodeName.toLowerCase()=="table"){c.insert({after:a});this.sections[b]=c.next();c.up().removeChild(c);c=this.sections[b]}else{c.update(a)}}c.up().removeClassName("loading");c.setStyle({height:"",visibility:"visible"})}},ajaxCallback:function(b){var a=b.responseText;try{a=a.evalJSON();this.updateView(a);$(document).fire("fiCheckout:updated",{viewModel:this})}catch(c){}},waiting:function(b){var a=[];if(b){var c=this.sections[b];c.setStyle({height:c.getHeight()+"px",visibility:"hidden"});$(c.parentNode).addClassName("loading");a.push(b)}else{for(var b in this.sections){var c=this.sections[b];c.setStyle({height:c.getHeight()+"px",visibility:"hidden"});$(c.parentNode).addClassName("loading");a.push(b)}}return a},request:function(b,a){return new Ajax.Request(this.getUrl(),{method:"post",parameters:b,onComplete:a?a.bind(this):this.ajaxCallback.bind(this),onFailure:function(){location.href=location.href}})},sendOnceFor:function(a,b){if(this.requests[a]){this.requests[a].transport.abort()}this.requests[a]=this.request(b,function(){delete this.requests[a];this.ajaxCallback.apply(this,arguments)});return this.requests[a]},getSection:function(a){return this.sections[a]||null},updateSection:function(a,c){var b=this.sections[a];this.waiting(a);c=c||{};c.type=a;return this.sendOnceFor(a,c)},updateAll:function(b){var a=this.waiting();b=b||{};b.type=a.join(",");return this.sendOnceFor(b.type,b)},processing:function(b){var a=this.disableButton(b);if(a){a.previous(".process").show()}},stopProcessing:function(b){var a=$(b);if(a){a.previous(".process").hide()}},disableButton:function(b){var a=$(b);if(a){a.addClassName("disabled");a.disabled=true;a.up("ul").select("li").each(function(c){if(c!=a.parentNode){c.setStyle({visibility:"hidden"})}})}return a},enableButton:function(b){var a=$(b);if(a){a.removeClassName("disabled");a.disabled=false;a.up("ul").select("li").each(function(c){if(c!=a.parentNode){c.setStyle({visibility:"visible"})}})}return a},getChangeListener:function(){var a=this;return function(){var b=["country_id","region","postcode","city"],d=b.length,c=this.element||this,f={};if(c.value.strip()&&c.value!="0"){f[c.name]=c.value;while(d--){var e=c.form["user[address]["+b[d]+"]"];if(e&&e.value){f[e.name]=e.value}}a.updateAll(f);a.disableButton("place-order")}}}});fiCheckoutViewModel.isElement=function(b,a){var c=b&&b.nodeName.toLowerCase();return c=="input"&&b.type==a};var fiPaymentViewModel=Class.create({initialize:function(a){this.element=a;this.currentMethod="";this.restore()},getCurrentMethod:function(){return this.currentMethod},getCurrentMethodElement:function(){return this.element&&this.element.select('input[type="radio"]:checked')[0]},findCurrentMethod:function(){var a=this.getCurrentMethodElement();return a?a.value:""},getAdditionalForm:function(){return $("payment_form_"+this.currentMethod)},enableFormElements:function(d,a){var c=Form.getElements(d),b=c.length;while(b--){c[b].disabled=!a}d[a?"show":"hide"]();return this},showAdditionalForm:function(a){var b=this.getAdditionalForm();if(b){this.enableFormElements(b,a)}return this},setMethod:function(b){this.currentMethod=b;var a=this.getAdditionalForm();$(a||document.body).fire("payment-method:switched",{method_code:b});return this},switchMethod:function(a){this.showAdditionalForm(false);this.setMethod(a);this.showAdditionalForm(true)},restore:function(){var a=this;if(this.element){this.switchMethod(this.findCurrentMethod());this.element.select(".form-list").each(function(b){a.enableFormElements(b,b.offsetWidth!=0)})}return this}});var fiCentinelViewModel=Class.create({initialize:function(c){this.element=c;this.isValid=false;if(this.element){var b=this.element.up().select("a.popup-close")[0],a=this;b.observe("click",function(d){$(this).up().hide();Event.stop(d);a.element.fire("fiCentinel:cancel")})}},validate:function(b,c){var a=this;a.element.setStyle({visibility:"hidden"});a.element.up().addClassName("loading");a.element.up().setStyle({display:"block"});return new Ajax.Request(b,{method:"post",parameters:c,onComplete:function(f){try{var d=f.responseText.evalJSON()}catch(g){return}a.element.update(d.html);a.element.setStyle({visibility:"visible"});a.element.up().removeClassName("loading");if(d.url){a.process(d.url)}else{a.success()}}})},idle:function(){this.element.up().hide()},process:function(a){var b=this.element.select("iframe")[0];b.src=a;return this},moveElement:function(a,b){if(this.element){this.element.up().setStyle({top:a+"px",left:b+"px"})}return this},isSuccessfull:function(){return this.isValid},resetValidation:function(){this.isValid=false;return this},success:function(){if(this.element){setTimeout((function(){this.element.up().hide()}).bind(this),2000);this.isValid=true;this.element.fire("fiCentinel:success")}}});var fiPage=Class.create({addFieldPopup:function(a,c){if(!a.form){return false}var b=$(a.form[c]);if(!b||!b.next(".popup")){return false}b.observe("focus",function(){$(this).next(".popup").show()});b.observe("blur",function(){$(this).next(".popup").hide()});return b},createTabs:function(d,h,a){var c=new FreaksTabs(d),e="";c.onChangeTab=function(j){if(j.prev.content.hasClassName("new-user")&&!j.current.content.hasClassName("new-user")){j.prev.content.show().addClassName("hidden-tab");j.prev.content.next("div.overlay").setStyle({display:"block"})}else{j.current.content.removeClassName("hidden-tab");j.current.content.next("div.overlay").hide()}var k=$(j.prev.content),i=k.select("ul.messages")[0];i&&i.hide()};for(var b in h){c.setTabForm(b,new RestorableForm(h[b]))}var f=c.getCurrentForm();if(f&&a){for(var g in a){f.addEmbededForm(a[g])}}if(e=(location.hash||" ").substr(1)){c.setCurrentTab(e)}return c},createDiscount:function(b){var a=new VarienForm(b);a.submit=function(c){if(c){$(this.form.coupon_code).removeClassName("required-entry");$(this.form.remove).value="1"}else{$(this.form.coupon_code).addClassName("required-entry");$(this.form.remove).value="0"}return VarienForm.prototype.submit.call(this)};if(a.form){a.form.select("button").each(function(c){c.observe("click",function(){a.submit(this.name=="cancel")})})}},createForms:function(c){var b=c.length,a={};while(b--){a[c[b]]=new RestorableForm(c[b])}return a},clearStorage:function(b,a){var d="",c="";for(d in b){c=b[d];if(c.clearValues&&!c.form){c.clearValues(a)}}},getLocationBox:function(d,a,c){var b=null;if(d){b=new FreaksAutocompleter(d.previous("input[id]"),d,d.parentNode.getAttribute("data-action"),{paramName:"location",indicator:"input-loading",minChars:2,onShow:function(e,f){Effect.Appear(f,{duration:0.15})}});b.addShowResults("a.select-tip")}else{if(c){b=new fiSelectBox($(c[a.box]));b.dependsOn($(c[a.dependsOn]),"country_id","input-loading")}}return b},observeAddressFields:function(a,e,d){if(!d){return}var b=a.length,c="";while(b--){c=$(d["user[address]["+a[b]+"]"]);if(c){c.observe("change",e)}}},createCheckout:function(c,b){var a=this;var d=c.getCurrentForm().getEmbededForm("payment-form");$$('form[name="user_info"]').each(function(h){var f=h.select("div.shipping-methods")[0];var e=new fiCheckoutViewModel({shipping:f,payment:d.form,totals:b});if(f){f.observe("click",function(k){var j=Event.element(k);if(!fiCheckoutViewModel.isElement(j,"radio")){return true}this.updateSection("totals",{shipping_method:j.value});this.disableButton("place-order")}.bindAsEventListener(e))}if(e.isActive()){var i=e.getChangeListener();var g=a.getLocationBox(h.select("div.autocomplete")[0],{box:"user[address][region_id]",dependsOn:"user[address][country_id]"},h);g&&g.addChangeListener(i);a.observeAddressFields(["country_id","postcode"],i,h)}if(d&&d.form&&d.form.getAttribute("data-update-totals")){d.form.observe("click",function(j){var k=Event.element(j);if(!fiCheckoutViewModel.isElement(k,"radio")){return true}params={};params[k.name]=k.value;this.updateSection("totals",params);this.disableButton("place-order")}.bindAsEventListener(e))}});$(document).observe("fiCheckout:updated",function(e){d.restoreValues();e.memo.viewModel.enableButton("place-order")})},wakeUpPayment:function(d,c){var a=new fiPaymentViewModel(d),e=new fiCentinelViewModel(c);if(a.element){a.element.observe("click",function(g){var f=Event.element(g);if(!fiCheckoutViewModel.isElement(f,"radio")){return true}if(a.getCurrentMethod()!=f.value){a.switchMethod(f.value);e.idle()}});$(document).observe("fiCheckout:updated",function(){a.restore()})}if(e.element){var b=function(){fiCheckoutViewModel.prototype.enableButton("place-order")};e.element.observe("fiCentinel:success",b);e.element.observe("fiCentinel:cancel",b)}return{payment:a,centinel:e}},send:function(b,d,c,a){if(!b){return false}var f=d.getCurrentForm()&&d.getCurrentForm().getEmbededForm("payment-form");b.observe("click",function(i){var k=c.payment.getCurrentMethodElement(),g=true,h="";if(k){h=k.getAttribute("data-action");if(h&&!c.centinel.isSuccessfull()){var j=Form.serialize(c.payment.getAdditionalForm(),true);j[k.name]=k.value;if(f.validator.validate()){c.centinel.validate(h,j);fiCheckoutViewModel.prototype.disableButton(this)}g=false}}if(g&&d.getCurrentForm().submit(true)){fiCheckoutViewModel.prototype.processing(this)}});var e=d.getCurrentForm();if(e.form){e.form.observe("form:has_response",function(h){fiCheckoutViewModel.prototype.stopProcessing(b);var g=h.memo;if(g.error_message){c.centinel.resetValidation();fiCheckoutViewModel.prototype.enableButton(b)}if(!g.update_section){return true}content.up().show();content.update(g.update_section.html);try{g.update_section.html.evalScripts()}catch(i){content.select("iframe").each(function(j){if(!j.offsetWidth){j.observe("load",j.show.bind(j))}})}})}return true}});Validator.prototype.test=(function(a){return function(c,d){var b=a.apply(this,arguments);if(this.options.onElementValidate){this.options.onElementValidate.call(this,b,d)}return b}})(Validator.prototype.test);Object.extend(Validation.get("validate-state").options,{onElementValidate:function(a,b){var c=$(b).previous('input[type="text"]');if(a){c.removeClassName("validation-failed").addClassName("validation-passed")}else{c.addClassName("validation-failed").revemoClassName("validation-passed")}}});$(document).observe("dom:loaded",function(){var e=new fiPage(),a=e.createForms(["payment-form","shipping-method-load"]),f=new VarienForm("checkout-login-form");a["checkout-agreements"]=new VarienForm("checkout-agreements");a["newsletter-form"]=new VarienForm("newsletter-form");var c=e.createTabs($$("#checkout-block ul.infos-menus")[0],{"new-user":"new-user-form","registered-user":"registered-user-form"},a);e.createDiscount("discount-coupon-form");e.createCheckout(c,$("shopping-cart-totals-table"));var d=$$("#payment-popup div.popup-content")[0],b=e.wakeUpPayment($("payment-methods"),d);e.send($("place-order"),c,b,d);window.CentinelAuthenticateController=b.centinel});