Version Notes
-
Download this release
Release Info
Developer | Highstreet |
Extension | Highstreet |
Version | 1.7.0 |
Comparing to | |
See all releases |
Code changes from version 1.5.0 to 1.7.0
- app/code/local/Highstreet/Hsapi/Helper/Config/Account.php +408 -0
- app/code/local/Highstreet/Hsapi/Helper/Config/Api.php +30 -18
- app/code/local/Highstreet/Hsapi/Helper/Config/Cart.php +862 -0
- app/code/local/Highstreet/Hsapi/Helper/Config/Checkout.php +785 -0
- app/code/local/Highstreet/Hsapi/Helper/Config/Default.php +168 -0
- app/code/local/Highstreet/Hsapi/Helper/Config/Redirect.php +110 -0
- app/code/local/Highstreet/Hsapi/Model/Attributes.php +15 -9
- app/code/local/Highstreet/Hsapi/Model/CartObserver.php +14 -0
- app/code/local/Highstreet/Hsapi/Model/CheckoutV2.php +4 -4
- app/code/local/Highstreet/Hsapi/Model/Observer.php +11 -2
- app/code/local/Highstreet/Hsapi/Model/Products.php +140 -46
- app/code/local/Highstreet/Hsapi/Model/Session.php +40 -0
- app/code/local/Highstreet/Hsapi/Model/System/Config/Stores.php +19 -0
- app/code/local/Highstreet/Hsapi/controllers/AccountController.php +282 -0
- app/code/local/Highstreet/Hsapi/controllers/CartController.php +107 -0
- app/code/local/Highstreet/Hsapi/controllers/CheckoutController.php +45 -10
- app/code/local/Highstreet/Hsapi/controllers/CheckoutV3Controller.php +536 -0
- app/code/local/Highstreet/Hsapi/controllers/IndexController.php +19 -3
- app/code/local/Highstreet/Hsapi/controllers/RedirectController.php +37 -0
- app/code/local/Highstreet/Hsapi/etc/config.xml +55 -15
- app/code/local/Highstreet/Hsapi/etc/system.xml +74 -0
- app/code/local/Highstreet/SmartAppBanner/etc/config.xml +1 -1
- app/design/frontend/base/default/template/highstreet/native_smart_app_banner.phtml +1 -1
- app/design/frontend/base/default/template/highstreet/smart_app_banner.phtml +5 -15
- package.xml +5 -5
app/code/local/Highstreet/Hsapi/Helper/Config/Account.php
ADDED
@@ -0,0 +1,408 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Highstreet_HSAPI_module
|
5 |
+
*
|
6 |
+
* @package Highstreet_Hsapi
|
7 |
+
* @author Radovan Dodic (radovan.dodic@atessoft.rs) ~ AtesSoft
|
8 |
+
* @copyright Copyright (c) 2016 Highstreet
|
9 |
+
*/
|
10 |
+
class Highstreet_Hsapi_Helper_Config_Account extends Highstreet_Hsapi_Helper_Config_Default {
|
11 |
+
|
12 |
+
const INVALID = "invalid";
|
13 |
+
const MISSING = "missing";
|
14 |
+
const DUPLICATE = "duplicate";
|
15 |
+
|
16 |
+
public function getAddressStreetLines() {
|
17 |
+
return Mage::getStoreConfig('customer/address/street_lines');
|
18 |
+
}
|
19 |
+
|
20 |
+
public function getNewAccountEmailTemplate() {
|
21 |
+
return Mage::getStoreConfig('highstreet_hsapi/api/new_account_email_template');
|
22 |
+
}
|
23 |
+
|
24 |
+
public function getNewAccountEmailTemplateIsEnabled() {
|
25 |
+
return Mage::getStoreConfig('highstreet_hsapi/api/new_account_email_enabled');
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Populate array with address data
|
30 |
+
*
|
31 |
+
* @param object $address
|
32 |
+
* @return array
|
33 |
+
*/
|
34 |
+
public function getAddressData($address) {
|
35 |
+
$street = $address->getStreet();
|
36 |
+
// extract house number from first line of address
|
37 |
+
if (!isset($street[1]) && preg_match('/^([^\d]*[^\d\s]) *(\d.*)$/', $street[0], $pregResult)) {
|
38 |
+
$street[0] = trim($pregResult[1]);
|
39 |
+
$street[1] = $pregResult[2];
|
40 |
+
}
|
41 |
+
return array(
|
42 |
+
'id' => $address->getAddressId(),
|
43 |
+
'first_name' => $address->getFirstname(),
|
44 |
+
'last_name' => $address->getLastname(),
|
45 |
+
'company' => $address->getCompany(),
|
46 |
+
'street' => (is_array($street)) ? $street[0] : $street,
|
47 |
+
'house_number' => (isset($street[1]) && !empty($street[1])) ? $street[1] : null,
|
48 |
+
'addition' => (isset($street[2])) ? $street[2] : null,
|
49 |
+
'postal_code' => $address->getPostcode(),
|
50 |
+
'city' => $address->getCity(),
|
51 |
+
'state' => $address->getRegion(),
|
52 |
+
'country_id' => $address->getCountryId(),
|
53 |
+
'telephone' => (string) $address->getTelephone() . ' ',
|
54 |
+
);
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Find CustomerId from session hash
|
59 |
+
*
|
60 |
+
* @param string $authCode
|
61 |
+
* @return bool/string
|
62 |
+
*/
|
63 |
+
public function _getCustomerId($authCode) {
|
64 |
+
// instantiate session model first
|
65 |
+
$session = Mage::getSingleton('core/session');
|
66 |
+
// close session. the session model does not provide a method for this
|
67 |
+
session_write_close();
|
68 |
+
unset($_SESSION);
|
69 |
+
// open new session
|
70 |
+
$session->setSessionId($authCode);
|
71 |
+
$session->init('checkout', 'frontend');
|
72 |
+
|
73 |
+
return (isset($_SESSION['core']['visitor_data']['customer_id'])) ? $_SESSION['core']['visitor_data']['customer_id'] : false;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Get CustomerId from session
|
78 |
+
*
|
79 |
+
* @return bool/string
|
80 |
+
*/
|
81 |
+
public function _getCId() {
|
82 |
+
return Mage::helper('customer')->getCustomer()->getId();
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Get is user logged in, Magento requires valid "frontend" cookie
|
87 |
+
*
|
88 |
+
* @return bool/string
|
89 |
+
*/
|
90 |
+
public function isLoggedIn() {
|
91 |
+
return Mage::helper('customer')->isLoggedIn();
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Send corresponding email template
|
96 |
+
*
|
97 |
+
* @param object Mage_Customer_Model_Customer
|
98 |
+
*/
|
99 |
+
public function _sendEmailTemplate($customer) {
|
100 |
+
if ($this->getNewAccountEmailTemplateIsEnabled()) {
|
101 |
+
// send custom email
|
102 |
+
$template = $this->getNewAccountEmailTemplate();
|
103 |
+
$store_id = Mage::app()->getStore()->getStoreId();
|
104 |
+
$emailTemplate = Mage::getModel('core/email_template')->loadByCode($template);
|
105 |
+
|
106 |
+
//variables passed to template
|
107 |
+
$emailTemplateVariables = array(
|
108 |
+
'customer.email' => $customer->getEmail(),
|
109 |
+
);
|
110 |
+
|
111 |
+
$processedTemplate = $emailTemplate->getProcessedTemplate($emailTemplateVariables);
|
112 |
+
$emailTemplate->setSenderName(Mage::getStoreConfig('trans_email/ident_general/name'));
|
113 |
+
$emailTemplate->setSenderEmail(Mage::getStoreConfig('trans_email/ident_general/email'));
|
114 |
+
|
115 |
+
// subject is set inside email template
|
116 |
+
//$emailTemplate->setTemplateSubject("subject");
|
117 |
+
|
118 |
+
$emailTemplate->send($customer->getEmail(), $customer->getName(), $emailTemplateVariables);
|
119 |
+
} else {
|
120 |
+
// send default email
|
121 |
+
$customer->sendNewAccountEmail('registered', '', Mage::app()->getStore()->getId());
|
122 |
+
}
|
123 |
+
return $this;
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* checks required fields
|
128 |
+
*
|
129 |
+
* @param array $params
|
130 |
+
* @return bool
|
131 |
+
*/
|
132 |
+
public function _checkCreateAccountFields($params) {
|
133 |
+
|
134 |
+
$fields = array('email', 'first_name', 'last_name', 'password');
|
135 |
+
foreach ($fields as $field) {
|
136 |
+
if (!isset($params[$field])) {
|
137 |
+
$this->_fieldError(self::MISSING, $field);
|
138 |
+
return false;
|
139 |
+
} elseif (isset($params[$field]) && empty($params[$field])) {
|
140 |
+
$this->_fieldError(self::INVALID, $field);
|
141 |
+
return false;
|
142 |
+
} elseif ($field == 'email') {
|
143 |
+
if (!Zend_Validate::is($params[$field], 'EmailAddress')) {
|
144 |
+
$this->_fieldError(self::INVALID, $field, '"' . $params[$field] . '" is not a valid email');
|
145 |
+
return false;
|
146 |
+
}
|
147 |
+
$customer = Mage::getModel('customer/customer');
|
148 |
+
$customer->setWebsiteId(Mage::app()->getWebsite()->getId());
|
149 |
+
$customer->loadByEmail($params[$field]);
|
150 |
+
if ($customer->getId()) {
|
151 |
+
$this->_fieldError(self::DUPLICATE, $field, 'This customer email already exists');
|
152 |
+
return false;
|
153 |
+
}
|
154 |
+
}
|
155 |
+
}
|
156 |
+
return true;
|
157 |
+
}
|
158 |
+
|
159 |
+
public function checkIsEmailValid($email) {
|
160 |
+
return Zend_Validate::is($email, 'EmailAddress');
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* checks required fields for Update action
|
165 |
+
*
|
166 |
+
* @param array $params
|
167 |
+
* @return bool
|
168 |
+
*/
|
169 |
+
public function _checkUpdateAccountFields($params) {
|
170 |
+
|
171 |
+
foreach ($params as $key => $field) {
|
172 |
+
if ($key == 'address')
|
173 |
+
continue;
|
174 |
+
if (empty($params[$key])) {
|
175 |
+
$this->_fieldError(self::INVALID, $key);
|
176 |
+
return false;
|
177 |
+
}
|
178 |
+
if ($key == 'email' && !empty($params[$key])) {
|
179 |
+
if (!$this->checkIsEmailValid($params[$key])) {
|
180 |
+
$this->_fieldError(self::INVALID, 'email', '"' . $params[$key] . '" is not a valid email');
|
181 |
+
return false;
|
182 |
+
}
|
183 |
+
}
|
184 |
+
}
|
185 |
+
if (isset($params['address']) && !$this->_checkUpdateAccountAddressFields($params))
|
186 |
+
return false;
|
187 |
+
return true;
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* checks required address fields for Update action
|
192 |
+
*
|
193 |
+
* @param array $params
|
194 |
+
* @return bool
|
195 |
+
*/
|
196 |
+
public function _checkUpdateAccountAddressFields($params) {
|
197 |
+
|
198 |
+
$fields = array(
|
199 |
+
'id',
|
200 |
+
'first_name',
|
201 |
+
'last_name',
|
202 |
+
'company',
|
203 |
+
'street',
|
204 |
+
'house_number',
|
205 |
+
'addition',
|
206 |
+
'postal_code',
|
207 |
+
'city',
|
208 |
+
'state',
|
209 |
+
'country_id',
|
210 |
+
'telephone',
|
211 |
+
);
|
212 |
+
$missingFields = array(
|
213 |
+
'first_name',
|
214 |
+
'last_name',
|
215 |
+
'street',
|
216 |
+
'city',
|
217 |
+
'country_id',
|
218 |
+
'telephone',
|
219 |
+
);
|
220 |
+
|
221 |
+
foreach ($missingFields as $field) {
|
222 |
+
if (!isset($params['address'][$field])) {
|
223 |
+
$this->_fieldError(self::MISSING, $field, 'Fill in address ' . $field);
|
224 |
+
return false;
|
225 |
+
}
|
226 |
+
}
|
227 |
+
foreach ($fields as $field) {
|
228 |
+
if (isset($params['address'][$field]) && empty($params['address'][$field])) {
|
229 |
+
$this->_fieldError(self::INVALID, $field, 'Fill in address ' . $field);
|
230 |
+
return false;
|
231 |
+
}
|
232 |
+
}
|
233 |
+
return true;
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* sets body to json error
|
238 |
+
*
|
239 |
+
* @param string $code
|
240 |
+
* @param string $field
|
241 |
+
*/
|
242 |
+
public function _fieldError($code, $field, $message = false) {
|
243 |
+
$msg = ($message) ? $message : 'Fill in a ' . $field;
|
244 |
+
$this->_JSONencodeAndRespond(array("code" => $code, "field" => $field, 'message' => $msg));
|
245 |
+
return;
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* prepare customer data for json
|
250 |
+
*
|
251 |
+
* @param object $customer
|
252 |
+
* @return array
|
253 |
+
*/
|
254 |
+
public function getCustomerData($customer) {
|
255 |
+
$quote = $this->getCustomerQuote($customer->getEntityId());
|
256 |
+
return array(
|
257 |
+
'id' => $customer->getEntityId(),
|
258 |
+
'email' => $customer->getEmail(),
|
259 |
+
'handle' => $customer->getEmail(),
|
260 |
+
'first_name' => $customer->getFirstname(),
|
261 |
+
'last_name' => $customer->getLastname(),
|
262 |
+
'cart_id' => $quote->getId()
|
263 |
+
);
|
264 |
+
}
|
265 |
+
|
266 |
+
/**
|
267 |
+
* retreives customer last quote
|
268 |
+
*
|
269 |
+
* @param string $customerId
|
270 |
+
* @return object Mage_Sales_Model_Resource_Quote_Collection
|
271 |
+
*/
|
272 |
+
public function getCustomerQuote($customerId) {
|
273 |
+
|
274 |
+
/** @var Mage_Sales_Model_Resource_Quote_Collection $quoteCollection */
|
275 |
+
// Get cart_id
|
276 |
+
// reason for this approach: Magento CE1.7 and EE1.12 have bug where user can have 2 or more active quote's
|
277 |
+
// by this method we are retreiving latest active one
|
278 |
+
// there is no offical reported bug about this, but here its mentioned http://magento.stackexchange.com/questions/29621/how-can-registered-customer-have-two-active-quotes
|
279 |
+
|
280 |
+
$quoteCollection = Mage::getModel('sales/quote')->getCollection()
|
281 |
+
->addFieldToFilter('customer_id', $customerId)
|
282 |
+
->addOrder('updated_at');
|
283 |
+
$quote = $quoteCollection->getFirstItem();
|
284 |
+
return $quote;
|
285 |
+
}
|
286 |
+
|
287 |
+
/**
|
288 |
+
* fix for Magento street lines
|
289 |
+
* if address is in 1 line all params are combined
|
290 |
+
* if address is in 2 lines, house num, and addition are combined
|
291 |
+
* any other case will go unmodified
|
292 |
+
*
|
293 |
+
* @param array $params
|
294 |
+
* @return array $params
|
295 |
+
*/
|
296 |
+
public function fixStreetLines($params) {
|
297 |
+
$tempParams = $params;
|
298 |
+
$tempParams['address']['street'] = (isset($tempParams['address']['street'])) ? $tempParams['address']['street'] : '';
|
299 |
+
$tempParams['address']['house_number'] = (isset($tempParams['address']['house_number'])) ? $tempParams['address']['house_number'] : '';
|
300 |
+
$tempParams['address']['addition'] = (isset($tempParams['address']['addition'])) ? $tempParams['address']['addition'] : '';
|
301 |
+
switch ($this->getAddressStreetLines()) {
|
302 |
+
case 1:
|
303 |
+
$params['address']['street'] = $tempParams['address']['street'] .
|
304 |
+
' ' . $tempParams['address']['house_number'] .
|
305 |
+
' ' . $tempParams['address']['addition'];
|
306 |
+
$params['address']['house_number'] = '';
|
307 |
+
$params['address']['addition'] = '';
|
308 |
+
break;
|
309 |
+
case 2:
|
310 |
+
$params['address']['house_number'] = $tempParams['address']['house_number'] .
|
311 |
+
' ' . $tempParams['address']['addition'];
|
312 |
+
$params['address']['addition'] = '';
|
313 |
+
break;
|
314 |
+
}
|
315 |
+
return $params;
|
316 |
+
}
|
317 |
+
|
318 |
+
public function login($requestObject) {
|
319 |
+
$session = Mage::getSingleton('customer/session');
|
320 |
+
|
321 |
+
$success = false;
|
322 |
+
$message = "";
|
323 |
+
|
324 |
+
$loginArray = $requestObject->getParam('login');
|
325 |
+
|
326 |
+
$email = $loginArray["username"];
|
327 |
+
$password = $loginArray["password"];
|
328 |
+
$this->log($loginArray, 'User login');
|
329 |
+
if ($session->isLoggedIn()) {
|
330 |
+
$success = false;
|
331 |
+
$message = "hsapi.loginAction.success.already";
|
332 |
+
} else {
|
333 |
+
try {
|
334 |
+
if ($session->login($email, $password)) {
|
335 |
+
$success = true;
|
336 |
+
$message = "hsapi.loginAction.success";
|
337 |
+
}
|
338 |
+
} catch (Mage_Core_Exception $e) {
|
339 |
+
switch ($e->getCode()) {
|
340 |
+
case Mage_Customer_Model_Customer::EXCEPTION_EMAIL_NOT_CONFIRMED: { // E-mail not confirmed
|
341 |
+
$success = false;
|
342 |
+
$message = "hsapi.loginAction.error.activate";
|
343 |
+
break;
|
344 |
+
}
|
345 |
+
case Mage_Customer_Model_Customer::EXCEPTION_INVALID_EMAIL_OR_PASSWORD: { // E-mail or password wrong
|
346 |
+
$success = false;
|
347 |
+
$message = "hsapi.loginAction.error";
|
348 |
+
break;
|
349 |
+
}
|
350 |
+
default: {
|
351 |
+
$success = false;
|
352 |
+
$message = "hsapi.loginAction.error.fatal";
|
353 |
+
break;
|
354 |
+
}
|
355 |
+
}
|
356 |
+
} catch (Exception $e) {
|
357 |
+
$success = false;
|
358 |
+
$message = "hsapi.loginAction.error.fatal";
|
359 |
+
}
|
360 |
+
}
|
361 |
+
|
362 |
+
$response = array();
|
363 |
+
$response["success"] = $success;
|
364 |
+
$response["message"] = $message;
|
365 |
+
$responseCode = ($success) ? "200 OK" : "400 Bad Request";
|
366 |
+
$this->log($response, $responseCode);
|
367 |
+
$this->_JSONencodeAndRespond($response, $responseCode);
|
368 |
+
return;
|
369 |
+
}
|
370 |
+
|
371 |
+
public function logout() {
|
372 |
+
Mage::getSingleton('customer/session')->logout();
|
373 |
+
$this->_JSONencodeAndRespond(array("OK"), "200 OK");
|
374 |
+
return;
|
375 |
+
}
|
376 |
+
|
377 |
+
/**
|
378 |
+
* @return Mage_Customer_Model_Session
|
379 |
+
*/
|
380 |
+
public function getCustomer() {
|
381 |
+
return Mage::getSingleton('customer/session')->getCustomer();
|
382 |
+
}
|
383 |
+
|
384 |
+
/**
|
385 |
+
* @param string $string
|
386 |
+
* @return string
|
387 |
+
*/
|
388 |
+
public function escapeString($string) {
|
389 |
+
return Mage::helper('core')->htmlEscape($string);
|
390 |
+
}
|
391 |
+
|
392 |
+
/**
|
393 |
+
* @param string $string
|
394 |
+
* @return string base64encode
|
395 |
+
*/
|
396 |
+
public function b64e($string) {
|
397 |
+
return base64_encode($string);
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* @param string $string
|
402 |
+
* @return string base64decode
|
403 |
+
*/
|
404 |
+
public function b64d($string) {
|
405 |
+
return base64_decode($string);
|
406 |
+
}
|
407 |
+
|
408 |
+
}
|
app/code/local/Highstreet/Hsapi/Helper/Config/Api.php
CHANGED
@@ -8,10 +8,9 @@
|
|
8 |
*/
|
9 |
|
10 |
class Highstreet_Hsapi_Helper_Config_Api extends Mage_Core_Helper_Abstract {
|
11 |
-
const MIDDLEWARE_URL_SCHEME = "
|
12 |
-
const
|
13 |
const MIDDLEWARE_URL_ENVIRONMENT_PRODUCTION = "api";
|
14 |
-
const MIDDLEWARE_URL_HOST_PATH = "highstreetapp.com/hs-api/1.4";
|
15 |
const CHECKOUT_URL_FALLBACK = "checkout/cart";
|
16 |
|
17 |
public function alwaysAddSimpleProductsToCart() {
|
@@ -25,7 +24,8 @@ class Highstreet_Hsapi_Helper_Config_Api extends Mage_Core_Helper_Abstract {
|
|
25 |
}
|
26 |
|
27 |
public function storeIdentifier() {
|
28 |
-
$
|
|
|
29 |
return ($store_id === NULL) ? "" : $store_id;
|
30 |
}
|
31 |
|
@@ -64,22 +64,12 @@ class Highstreet_Hsapi_Helper_Config_Api extends Mage_Core_Helper_Abstract {
|
|
64 |
}
|
65 |
|
66 |
public function middlewareUrl() {
|
67 |
-
|
|
|
68 |
return NULL;
|
69 |
}
|
70 |
|
71 |
-
|
72 |
-
|
73 |
-
if ($this->environment() === 'staging') {
|
74 |
-
$url .= '.' . self::MIDDLEWARE_URL_ENVIRONMENT_STAGING;
|
75 |
-
} else {
|
76 |
-
$url .= '.' . self::MIDDLEWARE_URL_ENVIRONMENT_PRODUCTION;
|
77 |
-
}
|
78 |
-
|
79 |
-
$url .= '.' . self::MIDDLEWARE_URL_HOST_PATH;
|
80 |
-
|
81 |
-
|
82 |
-
return $url;
|
83 |
}
|
84 |
|
85 |
public function shouldShowNativeSmartbanner() {
|
@@ -99,4 +89,26 @@ class Highstreet_Hsapi_Helper_Config_Api extends Mage_Core_Helper_Abstract {
|
|
99 |
|
100 |
return ($data === NULL) ? array() : $data;
|
101 |
}
|
102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
*/
|
9 |
|
10 |
class Highstreet_Hsapi_Helper_Config_Api extends Mage_Core_Helper_Abstract {
|
11 |
+
const MIDDLEWARE_URL_SCHEME = "https://";
|
12 |
+
const MIDDLEWARE_URL_HOST_PATH = "api.highstreetapp.com/";
|
13 |
const MIDDLEWARE_URL_ENVIRONMENT_PRODUCTION = "api";
|
|
|
14 |
const CHECKOUT_URL_FALLBACK = "checkout/cart";
|
15 |
|
16 |
public function alwaysAddSimpleProductsToCart() {
|
24 |
}
|
25 |
|
26 |
public function storeIdentifier() {
|
27 |
+
$realStoreId = Mage::helper('highstreet_hsapi/config_default')->getStoreId();
|
28 |
+
$store_id = Mage::getStoreConfig('highstreet_hsapi/api/store_id', $realStoreId);
|
29 |
return ($store_id === NULL) ? "" : $store_id;
|
30 |
}
|
31 |
|
64 |
}
|
65 |
|
66 |
public function middlewareUrl() {
|
67 |
+
$hostAndUri = $this->middlewareHostAndUri();
|
68 |
+
if(!$hostAndUri) {
|
69 |
return NULL;
|
70 |
}
|
71 |
|
72 |
+
return self::MIDDLEWARE_URL_SCHEME . $hostAndUri;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
}
|
74 |
|
75 |
public function shouldShowNativeSmartbanner() {
|
89 |
|
90 |
return ($data === NULL) ? array() : $data;
|
91 |
}
|
92 |
+
|
93 |
+
public function storeOverride() {
|
94 |
+
return Mage::getStoreConfig('highstreet_hsapi/api/checkout_override_storeview');
|
95 |
+
}
|
96 |
+
|
97 |
+
public function middlewareHostAndUri() {
|
98 |
+
if ($this->storeIdentifier() == "") {
|
99 |
+
return NULL;
|
100 |
+
}
|
101 |
+
|
102 |
+
$url = $this->storeIdentifier();
|
103 |
+
|
104 |
+
if ($this->environment() === 'staging') {
|
105 |
+
$url .= '-staging';
|
106 |
+
}
|
107 |
+
|
108 |
+
$url .= '.' . self::MIDDLEWARE_URL_HOST_PATH;
|
109 |
+
|
110 |
+
|
111 |
+
return $url;
|
112 |
+
}
|
113 |
+
|
114 |
+
}
|
app/code/local/Highstreet/Hsapi/Helper/Config/Cart.php
ADDED
@@ -0,0 +1,862 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Highstreet_HSAPI_module
|
5 |
+
*
|
6 |
+
* @package Highstreet_Hsapi
|
7 |
+
* @author Radovan Dodic (radovan.dodic@atessoft.rs) ~ AtesSoft
|
8 |
+
* @copyright Copyright (c) 2016 Highstreet
|
9 |
+
*/
|
10 |
+
class Highstreet_Hsapi_Helper_Config_Cart extends Highstreet_Hsapi_Helper_Config_Account {
|
11 |
+
|
12 |
+
// Magento <= 1.7 does not have this const set up in Mage_Checkout_Helper_Cart
|
13 |
+
const COUPON_CODE_MAX_LENGTH = 255;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Constructor class
|
17 |
+
*/
|
18 |
+
public function __construct() {
|
19 |
+
parent::__construct();
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Retrieve shopping cart model object
|
24 |
+
*
|
25 |
+
* @return Mage_Checkout_Model_Cart
|
26 |
+
*/
|
27 |
+
public function _getCart() {
|
28 |
+
return Mage::getSingleton('checkout/cart');
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Get Cart helper object
|
33 |
+
*
|
34 |
+
* @return Mage_Checkout_Helper_Cart
|
35 |
+
*/
|
36 |
+
public function _getCartHelper() {
|
37 |
+
return Mage::helper('checkout/cart');
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Get checkout session model instance
|
42 |
+
*
|
43 |
+
* @return Mage_Checkout_Model_Session
|
44 |
+
*/
|
45 |
+
public function _getSession() {
|
46 |
+
return Mage::getSingleton('checkout/session');
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Get current active quote instance
|
51 |
+
*
|
52 |
+
* @return Mage_Sales_Model_Quote
|
53 |
+
*/
|
54 |
+
public function _getQuote() {
|
55 |
+
return $this->_getCart()->getQuote();
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* @return Mage_Checkout_Model_Type_Onepage
|
60 |
+
*/
|
61 |
+
public function _getOnepage() {
|
62 |
+
return Mage::getSingleton('checkout/type_onepage');
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Initialize cart
|
67 |
+
*/
|
68 |
+
public function cartInit() {
|
69 |
+
$this->_getCart()->init();
|
70 |
+
return;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Initialize product instance from request data
|
75 |
+
*
|
76 |
+
* @param string $pid
|
77 |
+
* @return Mage_Catalog_Model_Product || false
|
78 |
+
*/
|
79 |
+
public function _initProduct($pid) {
|
80 |
+
if ($pid) {
|
81 |
+
$product = Mage::getModel('catalog/product')
|
82 |
+
->setStoreId(Mage::app()->getStore()->getId())
|
83 |
+
->load($pid);
|
84 |
+
if ($product->getId()) {
|
85 |
+
return $product;
|
86 |
+
}
|
87 |
+
}
|
88 |
+
return false;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* returns etag
|
93 |
+
*
|
94 |
+
* @return string
|
95 |
+
*/
|
96 |
+
public function getCartEtag() {
|
97 |
+
if (!Mage::getSingleton('core/session')->getCartEtag())
|
98 |
+
$this->updateCartEtag();
|
99 |
+
return Mage::getSingleton('core/session')->getCartEtag();
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* generate etag and save to session
|
104 |
+
*/
|
105 |
+
public function updateCartEtag() {
|
106 |
+
$hash = bin2hex(mcrypt_create_iv(22, MCRYPT_DEV_URANDOM));
|
107 |
+
Mage::getSingleton('core/session')->setCartEtag($hash);
|
108 |
+
return;
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Add or Update product to Cart object (Quote)
|
113 |
+
*
|
114 |
+
* @param array $productData
|
115 |
+
* @param array $errors
|
116 |
+
* @return array $errors
|
117 |
+
*/
|
118 |
+
public function addOrUpdateProductToCart($productData, $errors) {
|
119 |
+
|
120 |
+
$params = array(
|
121 |
+
'qty' => $productData['quantity'],
|
122 |
+
'product' => $productData['product_id'],
|
123 |
+
'related_product' => '',
|
124 |
+
);
|
125 |
+
$cart = $this->_getCart();
|
126 |
+
if (!isset($productData['product_id']))
|
127 |
+
return $errors;
|
128 |
+
|
129 |
+
// init product by product_id
|
130 |
+
$product = $this->_initProduct($productData['product_id']);
|
131 |
+
// if product can not be loaded add to errors and exit function
|
132 |
+
if (!$product) {
|
133 |
+
$errors[] = $this->getErrorArrayForProduct($productData, "product_unavailable");
|
134 |
+
return $errors;
|
135 |
+
}
|
136 |
+
|
137 |
+
|
138 |
+
// only simple, simple from configurable are checked for qty, if needed qty is corrected
|
139 |
+
// bundles are only check if requested configuration can be added or not
|
140 |
+
$productAvailibiltyAndQty = $this->getProductAvailabilityAndQty($product, $productData);
|
141 |
+
if ($productAvailibiltyAndQty['qty'] == -1) { // out of stock, add error & exit function
|
142 |
+
$errors[] = $this->getErrorArrayForProduct($productData, "quantity_changed", $productAvailibiltyAndQty['error']);
|
143 |
+
return $errors;
|
144 |
+
} elseif ($productAvailibiltyAndQty['qty'] < $productData['quantity']) { // requested qty not available, add error & change qty
|
145 |
+
$errors[] = $this->getErrorArrayForProduct($productData, "quantity_changed", $productAvailibiltyAndQty['error']);
|
146 |
+
$params['qty'] = $productAvailibiltyAndQty['qty'];
|
147 |
+
}
|
148 |
+
|
149 |
+
|
150 |
+
if (isset($productData['configuration'])) { // add configurable options
|
151 |
+
$attributes = $this->getArrayOfAttributesForConfigProduct($productData['configuration']['attributes']);
|
152 |
+
$params['super_attribute'] = $attributes;
|
153 |
+
} else if (isset($productData['bundle_configuration'])) { // add bundle options
|
154 |
+
$bundle = array();
|
155 |
+
$bundleQty = array();
|
156 |
+
foreach ($productData['bundle_configuration'] as $b) {
|
157 |
+
$bundle[$b['option']] = $b['selection'];
|
158 |
+
$bundleQty[$b['option']] = $b['quantity'];
|
159 |
+
}
|
160 |
+
$params['bundle_option'] = $bundle;
|
161 |
+
$params['bundle_option_qty'] = $bundleQty;
|
162 |
+
}
|
163 |
+
|
164 |
+
// add or update product
|
165 |
+
try {
|
166 |
+
// set quote to be ready for changes
|
167 |
+
$cart->getQuote()->setTotalsCollectedFlag(false);
|
168 |
+
// check if quote item id is set and product exists in quote (update)
|
169 |
+
if (isset($productData['id']) && $item = $this->_getQuote()->getItemById($productData['id'])) {
|
170 |
+
// check if product has specific configuration, if its configurable or bundle
|
171 |
+
if ($product->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
|
172 |
+
// get simple ids
|
173 |
+
$oldSimpleId = $item->getOptionByCode('simple_product')->getProductId();
|
174 |
+
$newSimpleId = $productData['configuration']['child_product_id'];
|
175 |
+
|
176 |
+
// if there is no change in child product, update qty only
|
177 |
+
if ($oldSimpleId != $newSimpleId) {
|
178 |
+
// update buy_request data
|
179 |
+
if ($buyRequest = $item->getProduct()->getCustomOption('info_buyRequest')) {
|
180 |
+
$buyRequestArr = unserialize($buyRequest->getValue());
|
181 |
+
unset($buyRequestArr['super_attribute']);
|
182 |
+
foreach ($params['super_attribute'] as $key => $value) {
|
183 |
+
$buyRequestArr['super_attribute'][$key] = $value;
|
184 |
+
}
|
185 |
+
$buyRequest->setValue(serialize($buyRequestArr))->save();
|
186 |
+
}
|
187 |
+
|
188 |
+
// update simple product, id of new simple product
|
189 |
+
$item->getOptionByCode('simple_product')->setValue($newSimpleId)->setProductId($newSimpleId)->save();
|
190 |
+
|
191 |
+
// update attributes
|
192 |
+
if ($attr = $item->getOptionByCode('attributes')) {
|
193 |
+
foreach ($params['super_attribute'] as $key => $value) {
|
194 |
+
$attrArr[$key] = $value;
|
195 |
+
}
|
196 |
+
if (count($attrArr))
|
197 |
+
$attr->setValue(serialize($attrArr))->save();
|
198 |
+
}
|
199 |
+
|
200 |
+
// update product qty by old and new simple id
|
201 |
+
$item->getOptionByCode('product_qty_' . $oldSimpleId)->setProductId($newSimpleId)->setCode('product_qty_' . $newSimpleId)->setValue($params['qty'])->save();
|
202 |
+
} else {
|
203 |
+
$item->setQty($params['qty'])->save();
|
204 |
+
}
|
205 |
+
} else {
|
206 |
+
// simple product or bundle product or any other product
|
207 |
+
$item->setQty($params['qty'])->save();
|
208 |
+
}
|
209 |
+
$this->updateCartEtag();
|
210 |
+
} else {
|
211 |
+
// if adding new product, add temp_id to $params
|
212 |
+
if (isset($productData['temp_id']))
|
213 |
+
$params['temp_id'] = $productData['temp_id'];
|
214 |
+
$cart->addProduct($product, $params);
|
215 |
+
}
|
216 |
+
} catch (Exception $e) {
|
217 |
+
$this->logException($e, 'Adding / updating product to cart - Exception');
|
218 |
+
$this->log(array(
|
219 |
+
"Exception message" => $e->getMessage(),
|
220 |
+
"Product data" => $productData), 'Adding / updating product to cart');
|
221 |
+
}
|
222 |
+
return $errors;
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* checks product availability and qty
|
227 |
+
*
|
228 |
+
* @param Mage_Catalog_Model_Product
|
229 |
+
* @param array $productData
|
230 |
+
* @return array
|
231 |
+
*/
|
232 |
+
public function getProductAvailabilityAndQty($product, $productData) {
|
233 |
+
if ($product->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_SIMPLE) {
|
234 |
+
return $this->getSimpleProductAvailabilityAndQty($product, $productData['quantity']);
|
235 |
+
} elseif ($product->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
|
236 |
+
$simple_product = $this->_initProduct($productData['configuration']['child_product_id']);
|
237 |
+
if ($simple_product) {
|
238 |
+
return $this->getSimpleProductAvailabilityAndQty($simple_product, $productData['quantity']);
|
239 |
+
}
|
240 |
+
} elseif ($product->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
|
241 |
+
return $this->getBundleProductAvailabilityAndQty($product, $productData['quantity']);
|
242 |
+
}
|
243 |
+
|
244 |
+
// any other product return same input data
|
245 |
+
return array(
|
246 |
+
'error' => '',
|
247 |
+
'qty' => $productData['quantity']
|
248 |
+
);
|
249 |
+
}
|
250 |
+
|
251 |
+
/**
|
252 |
+
* checks salability of child products inside bundle product
|
253 |
+
*
|
254 |
+
* @param Mage_Catalog_Model_Product
|
255 |
+
* @param string $qty
|
256 |
+
* @return array
|
257 |
+
*/
|
258 |
+
public function getBundleProductAvailabilityAndQty($product, $qty) {
|
259 |
+
$returnArray = array(
|
260 |
+
'error' => '',
|
261 |
+
'qty' => $qty
|
262 |
+
);
|
263 |
+
$childrenIds = $product->getTypeInstance(true)->getChildrenIds($product->getId(), true);
|
264 |
+
$childBundleCollection = Mage::getModel('catalog/product')->getCollection()->addFieldToFilter('entity_id', $childrenIds);
|
265 |
+
foreach ($childBundleCollection as $childBundle) {
|
266 |
+
if (!$childBundle->isSalable()) {
|
267 |
+
$returnArray['error'] = "Product is not in stock";
|
268 |
+
$returnArray['qty'] = -1;
|
269 |
+
}
|
270 |
+
}
|
271 |
+
return $returnArray;
|
272 |
+
}
|
273 |
+
|
274 |
+
/**
|
275 |
+
* checks inventory of simple product
|
276 |
+
* checks if there is enough qty of product to be added
|
277 |
+
*
|
278 |
+
* @param Mage_Catalog_Model_Product
|
279 |
+
* @param string $qty
|
280 |
+
* @return array
|
281 |
+
*/
|
282 |
+
public function getSimpleProductAvailabilityAndQty($simple_product, $qty) {
|
283 |
+
$returnArray = array(
|
284 |
+
'error' => '',
|
285 |
+
'qty' => $qty
|
286 |
+
);
|
287 |
+
$itemInventory = Mage::getModel('cataloginventory/stock_item')->loadByProduct($simple_product);
|
288 |
+
$availableQuantity = $itemInventory->getQty() - $itemInventory->getMinQty();
|
289 |
+
$isInStock = (bool) $itemInventory->getIsInStock();
|
290 |
+
$isStockManaged = $itemInventory->getManageStock();
|
291 |
+
$backordersAllowed = $itemInventory->getBackorders();
|
292 |
+
if ($isStockManaged) {
|
293 |
+
if (!$isInStock) {
|
294 |
+
$returnArray['error'] = "Product is not in stock";
|
295 |
+
$returnArray['qty'] = -1;
|
296 |
+
} elseif (!$backordersAllowed && $qty > $availableQuantity) {
|
297 |
+
$returnArray['error'] = "Requested quantity is not available";
|
298 |
+
$returnArray['qty'] = $availableQuantity;
|
299 |
+
}
|
300 |
+
}
|
301 |
+
return $returnArray;
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* error array
|
306 |
+
*
|
307 |
+
* @param array $productData
|
308 |
+
* @param string $errorCode
|
309 |
+
* @return array
|
310 |
+
*/
|
311 |
+
public function getErrorArrayForProduct($productData = array(), $errorCode = "product_unavailable", $message = "Product is unavailable") {
|
312 |
+
return array(
|
313 |
+
"type" => "cart_item_error",
|
314 |
+
"code" => $errorCode,
|
315 |
+
"id" => (isset($productData['id'])) ? $productData['id'] : null,
|
316 |
+
"temp_id" => isset($productData['temp_id']) ? $productData['temp_id'] : null,
|
317 |
+
"message" => $message
|
318 |
+
);
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Converts config values to attribute ID's
|
323 |
+
*
|
324 |
+
* @param array $attributes
|
325 |
+
* @return array $attArray
|
326 |
+
*/
|
327 |
+
public function getArrayOfAttributesForConfigProduct($attributes) {
|
328 |
+
$attArray = array();
|
329 |
+
foreach ($attributes as $name => $value) {
|
330 |
+
$attribute = $this->getAttributeByCode($name);
|
331 |
+
$attributeId = $attribute['attribute_id'];
|
332 |
+
$attributeValueId = $value;
|
333 |
+
$attArray[$attributeId] = $attributeValueId;
|
334 |
+
}
|
335 |
+
return $attArray;
|
336 |
+
}
|
337 |
+
|
338 |
+
/**
|
339 |
+
* returns attribute filtered by frontend name
|
340 |
+
*
|
341 |
+
* @param string $name
|
342 |
+
* @return array $a
|
343 |
+
*/
|
344 |
+
public function getAttributeByName($name) {
|
345 |
+
$attr = Mage::getModel('eav/entity_attribute')->getCollection()->addFieldToFilter('frontend_label', $name);
|
346 |
+
$a = $attr->getData();
|
347 |
+
return $a[0];
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* returns attribute filtered by attribute code
|
352 |
+
*
|
353 |
+
* @param string $name
|
354 |
+
* @return array $a
|
355 |
+
*/
|
356 |
+
public function getAttributeByCode($name) {
|
357 |
+
$attr = Mage::getModel('eav/entity_attribute')->getCollection()->addFieldToFilter('attribute_code', $name);
|
358 |
+
$a = $attr->getData();
|
359 |
+
return $a[0];
|
360 |
+
}
|
361 |
+
|
362 |
+
/**
|
363 |
+
* returns id of specific attribute value
|
364 |
+
*
|
365 |
+
* @param string $attributeCode
|
366 |
+
* @param string $value
|
367 |
+
* @return string
|
368 |
+
*/
|
369 |
+
public function getAttributeValueId($attributeCode, $value) {
|
370 |
+
$attribute = Mage::getModel('eav/config')->getAttribute(Mage_Catalog_Model_Product::ENTITY, $attributeCode);
|
371 |
+
return $attribute->getSource()->getOptionId($value);
|
372 |
+
}
|
373 |
+
|
374 |
+
/**
|
375 |
+
* Empty customer's shopping cart
|
376 |
+
*/
|
377 |
+
public function _emptyShoppingCart() {
|
378 |
+
foreach ($this->_getQuote()->getAllItems() as $item) {
|
379 |
+
$this->_getQuote()->removeItem($item->getId());
|
380 |
+
}
|
381 |
+
}
|
382 |
+
|
383 |
+
/**
|
384 |
+
* remove items from cart that are not specified in JSON body
|
385 |
+
*/
|
386 |
+
public function _removeUspecifiedItemsFromCart($params) {
|
387 |
+
// quote item ID array setup
|
388 |
+
$q_ids = array();
|
389 |
+
if (isset($params['items'])) {
|
390 |
+
foreach ($params['items'] as $pItem) {
|
391 |
+
if (isset($pItem['id']))
|
392 |
+
$q_ids[] = $pItem['id'];
|
393 |
+
}
|
394 |
+
}
|
395 |
+
$this->log($q_ids, 'Item IDs NOT to be removed from cart');
|
396 |
+
foreach ($this->_getQuote()->getAllVisibleItems() as $item) {
|
397 |
+
// remove by quote id
|
398 |
+
if (!in_array($item->getId(), $q_ids)) {
|
399 |
+
$this->log('Removing Item ID: ' . $item->getId(), '_removeUspecifiedItemsFromCart');
|
400 |
+
$this->_getQuote()->removeItem($item->getId())->save();
|
401 |
+
}
|
402 |
+
}
|
403 |
+
}
|
404 |
+
|
405 |
+
/**
|
406 |
+
* Add Coupon code to cart object
|
407 |
+
*
|
408 |
+
* @param string $code
|
409 |
+
* @param array $errors
|
410 |
+
* @return array $errors
|
411 |
+
*/
|
412 |
+
public function addCouponCode($code, $errors) {
|
413 |
+
if (isset($code[0]['code']) && isset($code[0]['id'])) {
|
414 |
+
$couponCode = $code[0]['code'];
|
415 |
+
|
416 |
+
// generate error array if needed
|
417 |
+
$error = array(
|
418 |
+
"type" => "coupon_code_error",
|
419 |
+
"code" => "invalid_coupon",
|
420 |
+
"id" => $code[0]['id'],
|
421 |
+
"temp_id" => isset($code[0]['temp_id']) ? $code[0]['temp_id'] : 0,
|
422 |
+
"message" => "Invalid coupon code"
|
423 |
+
);
|
424 |
+
try {
|
425 |
+
$codeLength = strlen($couponCode);
|
426 |
+
$isCodeLengthValid = $codeLength && $codeLength <= Mage_Checkout_Helper_Cart::COUPON_CODE_MAX_LENGTH;
|
427 |
+
|
428 |
+
$this->_getQuote()->getShippingAddress()->setCollectShippingRates(true);
|
429 |
+
$this->_getQuote()->setCouponCode($isCodeLengthValid ? $couponCode : '');
|
430 |
+
if ($codeLength) {
|
431 |
+
if (!$isCodeLengthValid || $couponCode != $this->_getQuote()->getCouponCode()) {
|
432 |
+
$errors[] = $error;
|
433 |
+
} else {
|
434 |
+
$this->updateCartEtag();
|
435 |
+
}
|
436 |
+
}
|
437 |
+
} catch (Exception $e) {
|
438 |
+
$this->log(array(
|
439 |
+
"Exception message" => $e->getMessage(),
|
440 |
+
"Coupon code" => $code), 'Adding / updating coupon code');
|
441 |
+
$errors[] = $error;
|
442 |
+
}
|
443 |
+
}
|
444 |
+
return $errors;
|
445 |
+
}
|
446 |
+
|
447 |
+
/**
|
448 |
+
* Add ETag to header of response
|
449 |
+
*/
|
450 |
+
public function _setETagJSONencodeAndRespondonse($data, $responseCode, $numeric = true) {
|
451 |
+
$this->_response->setHeader('ETag', $this->getCartEtag());
|
452 |
+
$this->_JSONencodeAndRespond($data, $responseCode, $numeric);
|
453 |
+
}
|
454 |
+
|
455 |
+
/**
|
456 |
+
* Returns products from Cart
|
457 |
+
* If Configurable - finds relation attributes, and values
|
458 |
+
* if Bundle - finds child products, bundle option ID, option selection ID, as well as QTY of non visible cart product
|
459 |
+
*
|
460 |
+
* @param array $params
|
461 |
+
* @return array $productItems
|
462 |
+
*/
|
463 |
+
public function getProductsFromCart($params = array()) {
|
464 |
+
$productItems = array();
|
465 |
+
$quote = $this->_getQuote();
|
466 |
+
$items = $quote->getAllVisibleItems();
|
467 |
+
|
468 |
+
foreach ($items as $item) {
|
469 |
+
$tempArray = array(
|
470 |
+
'id' => $item->getItemId(), // product id in quote table
|
471 |
+
'temp_id' => $this->getProductTempId($item->getItemId(), $item->getProductId()),
|
472 |
+
'product_id' => $item->getProductId(),
|
473 |
+
'prices' => array(
|
474 |
+
'original' => $this->getItemPrice('original', $item),
|
475 |
+
'effective' => $this->getItemPrice('effective', $item),
|
476 |
+
'effective_tax_free' => $this->getItemPrice('effective_tax_free', $item),
|
477 |
+
'total' => $this->getItemPrice('total', $item),
|
478 |
+
),
|
479 |
+
'quantity' => $item->getQty()
|
480 |
+
);
|
481 |
+
|
482 |
+
if ($item->getProductType() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
|
483 |
+
$configurableAttributeCollection = $item->getProduct()->getTypeInstance()->getConfigurableAttributes();
|
484 |
+
$relationAttributes = array();
|
485 |
+
foreach ($configurableAttributeCollection as $attribute) {
|
486 |
+
$relationAttributes[] = $attribute->getProductAttribute()->getAttributeCode();
|
487 |
+
}
|
488 |
+
|
489 |
+
$simpleId = $item->getOptionByCode('simple_product')->getProduct()->getId();
|
490 |
+
$simple = Mage::getModel('catalog/product')->load($simpleId);
|
491 |
+
$confArray = array();
|
492 |
+
foreach ($relationAttributes as $att) {
|
493 |
+
$confArray[$att] = $simple->getResource()->getAttribute($att)->getFrontend()->getValue($simple);
|
494 |
+
}
|
495 |
+
|
496 |
+
$tempArray['configuration'] = array(
|
497 |
+
"child_product_id" => $simpleId
|
498 |
+
);
|
499 |
+
} else if ($item->getProductType() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
|
500 |
+
$bundled_product = new Mage_Catalog_Model_Product();
|
501 |
+
$bundled_product->load($item->getProductId());
|
502 |
+
|
503 |
+
$selectionCollection = $bundled_product->getTypeInstance(true)->getSelectionsCollection(
|
504 |
+
$bundled_product->getTypeInstance(true)->getOptionsIds($bundled_product), $bundled_product
|
505 |
+
);
|
506 |
+
|
507 |
+
$bundled_items = array();
|
508 |
+
foreach ($selectionCollection as $option) {
|
509 |
+
$bundled_items[$option->product_id] = array($option->option_id, $option->selection_id);
|
510 |
+
}
|
511 |
+
|
512 |
+
foreach ($item->getChildren() as $child) {
|
513 |
+
$product_id = $child->getData('product_id');
|
514 |
+
if (isset($bundled_items[$product_id])) {
|
515 |
+
$bundleItemsArray[] = array(
|
516 |
+
"option" => $bundled_items[$product_id][0],
|
517 |
+
"selection" => $bundled_items[$product_id][1],
|
518 |
+
"quantity" => $this->getQtyForChildItemInCart($product_id, $item->getItemId(), $this->_getQuote()),
|
519 |
+
);
|
520 |
+
}
|
521 |
+
}
|
522 |
+
$tempArray['bundle_configuration'] = $bundleItemsArray;
|
523 |
+
}
|
524 |
+
|
525 |
+
$productItems[] = $tempArray;
|
526 |
+
}
|
527 |
+
return $productItems;
|
528 |
+
}
|
529 |
+
|
530 |
+
/**
|
531 |
+
* get Quote Item price
|
532 |
+
*
|
533 |
+
* @param string $priceType
|
534 |
+
* @param Mage_Sales_Model_Quote_Item $_item
|
535 |
+
* @return float
|
536 |
+
*/
|
537 |
+
public function getItemPrice($priceType, $_item) {
|
538 |
+
$checkoutHelper = Mage::helper('checkout');
|
539 |
+
$taxHelper = Mage::helper('tax');
|
540 |
+
switch ($priceType) {
|
541 |
+
case 'original':
|
542 |
+
return $this->getOriginalProductPrice($_item);
|
543 |
+
break;
|
544 |
+
case 'effective':
|
545 |
+
return $checkoutHelper->getPriceInclTax($_item);
|
546 |
+
break;
|
547 |
+
case 'effective_tax_free':
|
548 |
+
return $_item->getCalculationPrice();
|
549 |
+
break;
|
550 |
+
case 'total':
|
551 |
+
// read setting from admin to show same as on desktop cart
|
552 |
+
if ($taxHelper->displayCartPriceExclTax()) {
|
553 |
+
return $_item->getRowTotal();
|
554 |
+
} else {
|
555 |
+
return $checkoutHelper->getSubtotalInclTax($_item);
|
556 |
+
};
|
557 |
+
break;
|
558 |
+
}
|
559 |
+
}
|
560 |
+
|
561 |
+
/**
|
562 |
+
* get product price from simple product
|
563 |
+
* this does not apply to bundle products
|
564 |
+
*
|
565 |
+
* @param Mage_Sales_Model_Quote_Item $item
|
566 |
+
* @return float
|
567 |
+
*/
|
568 |
+
public function getOriginalProductPrice($_item) {
|
569 |
+
$productId = $_item->getProduct()->getId();
|
570 |
+
// get simple product from configurable
|
571 |
+
if ($_item->getProduct()->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE && $simpleFromConfig = $_item->getOptionByCode('simple_product')->getProduct())
|
572 |
+
$productId = $simpleFromConfig->getId();
|
573 |
+
// reload product to get price without rules
|
574 |
+
$product = Mage::getModel('catalog/product')->load($productId);
|
575 |
+
|
576 |
+
if ($product->getTypeId() == 'bundle') {
|
577 |
+
return Mage::getModel('bundle/product_price')->getTotalPrices($product,'min',1);
|
578 |
+
}
|
579 |
+
|
580 |
+
return $product->getPrice();
|
581 |
+
}
|
582 |
+
|
583 |
+
/**
|
584 |
+
* get temp_id saved into Mage_Sales_Model_Quote_Item info_buyRequest
|
585 |
+
*
|
586 |
+
* @param int $item_id
|
587 |
+
* @param int $productId
|
588 |
+
* @return string
|
589 |
+
*/
|
590 |
+
public function getProductTempId($item_id, $productId) {
|
591 |
+
$temp_id = null;
|
592 |
+
try {
|
593 |
+
// using direct sql query to get custom Quote Item Options
|
594 |
+
// options are not available using getModel imidietely after saving quote
|
595 |
+
$itemOptionTableName = $this->getCoreResource()->getTableName('sales/quote_item_option');
|
596 |
+
$sql = "SELECT `value` FROM `" . $itemOptionTableName . "` WHERE `item_id` = :item_id AND `product_id` = :product_id";
|
597 |
+
// bind data to prevent SQL injections
|
598 |
+
$dataBind = array(
|
599 |
+
'item_id' => $item_id,
|
600 |
+
'product_id' => $productId
|
601 |
+
);
|
602 |
+
$buyRequest = $this->directDBRead()->fetchOne($sql, $dataBind);
|
603 |
+
} catch (Exception $e) {
|
604 |
+
$this->logException($e, 'getProductTempId');
|
605 |
+
return null;
|
606 |
+
}
|
607 |
+
if (isset($buyRequest)) {
|
608 |
+
$buyRequestArr = unserialize($buyRequest);
|
609 |
+
if (isset($buyRequestArr['temp_id'])) {
|
610 |
+
$temp_id = $buyRequestArr['temp_id'];
|
611 |
+
};
|
612 |
+
};
|
613 |
+
return $temp_id;
|
614 |
+
}
|
615 |
+
|
616 |
+
/**
|
617 |
+
* get coupon code from quote
|
618 |
+
*
|
619 |
+
* @return string
|
620 |
+
*/
|
621 |
+
public function getCouponCodes() {
|
622 |
+
$couponCodes = array();
|
623 |
+
if ($cc = $this->_getQuote()->getCouponCode()) {
|
624 |
+
$coupon = Mage::getModel('salesrule/coupon')->load($cc, 'code');
|
625 |
+
$couponCodes[] = array(
|
626 |
+
'id' => $coupon->getRuleId(),
|
627 |
+
'code' => $cc,
|
628 |
+
'temp_id' => "0"
|
629 |
+
);
|
630 |
+
}
|
631 |
+
return $couponCodes;
|
632 |
+
}
|
633 |
+
|
634 |
+
/**
|
635 |
+
* Get tax from quote
|
636 |
+
*
|
637 |
+
* @return bool true || false
|
638 |
+
*/
|
639 |
+
public function isTaxIncluded() {
|
640 |
+
$totals = $this->_getQuote()->getTotals();
|
641 |
+
return (isset($totals['tax']) && $totals['tax']->getValue()) ? true : false;
|
642 |
+
}
|
643 |
+
|
644 |
+
/**
|
645 |
+
* Get totals from quote
|
646 |
+
*
|
647 |
+
* @return array
|
648 |
+
*/
|
649 |
+
public function getTotals() {
|
650 |
+
$totals = $this->_getQuote()->getTotals();
|
651 |
+
|
652 |
+
// get tax calculation based on shipping address
|
653 |
+
$shipAddress = $this->_getQuote()->getShippingAddress();
|
654 |
+
$shippingFromTotals = (isset($totals['shipping']) && $totals['shipping']->getValue()) ? $totals['shipping']->getValue() : 0;
|
655 |
+
$shipping = ($shipAddress) ? $this->getShippingPrice($shipAddress) : $shippingFromTotals;
|
656 |
+
return array(
|
657 |
+
'discount' => (isset($totals['discount']) && $totals['discount']->getValue()) ? $totals['discount']->getValue() : 0,
|
658 |
+
'sub_total' => (isset($totals['subtotal']) && $totals['subtotal']->getValue()) ? $totals['subtotal']->getValue() : 0,
|
659 |
+
'tax' => (isset($totals['tax']) && $totals['tax']->getValue()) ? $totals['tax']->getValue() : 0,
|
660 |
+
'shipping' => ($shipping == 0 && !$shipAddress->getShippingMethod()) ? null : $shipping,
|
661 |
+
'grand_total' => (isset($totals['grand_total']) && $totals['grand_total']->getValue()) ? $totals['grand_total']->getValue() : 0,
|
662 |
+
);
|
663 |
+
}
|
664 |
+
|
665 |
+
/**
|
666 |
+
* Function finds difference between product id's in input json, and added products in cart, error products are excluded
|
667 |
+
*
|
668 |
+
* @param array $params
|
669 |
+
* @param array $errors
|
670 |
+
* @return array
|
671 |
+
*/
|
672 |
+
public function getMessages($params, $errors) {
|
673 |
+
$messages = array();
|
674 |
+
if (isset($params['items'])) {
|
675 |
+
$itemsIds = array();
|
676 |
+
foreach ($params['items'] as $item) {
|
677 |
+
array_push($itemsIds, $item['product_id']);
|
678 |
+
}
|
679 |
+
$countItems = count($params['items']);
|
680 |
+
$countCartItems = count($this->_getQuote()->getAllVisibleItems());
|
681 |
+
$countErrrorItems = 0;
|
682 |
+
foreach ($errors as $e) {
|
683 |
+
if ($e['type'] == 'cart_item_error')
|
684 |
+
$countErrrorItems++;
|
685 |
+
foreach ($itemsIds as $key => $value) {
|
686 |
+
if ($value == $e['id'])
|
687 |
+
unset($itemsIds[$key]);
|
688 |
+
}
|
689 |
+
}
|
690 |
+
$itemsInCartIds = array();
|
691 |
+
if ($countItems - $countErrrorItems < $countCartItems) {
|
692 |
+
$items = $this->_getQuote()->getAllVisibleItems();
|
693 |
+
foreach ($items as $item) {
|
694 |
+
array_push($itemsInCartIds, $item->getProductId());
|
695 |
+
}
|
696 |
+
$arrayDiff = array_merge(array_diff($itemsIds, $itemsInCartIds), array_diff($itemsInCartIds, $itemsIds));
|
697 |
+
if (count($arrayDiff)) {
|
698 |
+
foreach ($arrayDiff as $arrayDiffID) {
|
699 |
+
$productName = Mage::getModel('catalog/product')->load($arrayDiffID)->getName();
|
700 |
+
$messages[] = array(
|
701 |
+
"type" => "cart_message",
|
702 |
+
"code" => "bonus_product",
|
703 |
+
"message" => "Product '" . $productName . "' added to cart"
|
704 |
+
);
|
705 |
+
}
|
706 |
+
}
|
707 |
+
}
|
708 |
+
}
|
709 |
+
return $messages;
|
710 |
+
}
|
711 |
+
|
712 |
+
/**
|
713 |
+
* get Qty for child Item in cart / quote
|
714 |
+
* filter by product ID, Quote object, and parent Quote Item ID
|
715 |
+
*
|
716 |
+
* @param integer $productId
|
717 |
+
* @param integer $quoteItemId
|
718 |
+
* @param Mage_Sales_Model_Quote $quote
|
719 |
+
* @return integer
|
720 |
+
*/
|
721 |
+
public function getQtyForChildItemInCart($product_id, $quoteParentItemId, $quote) {
|
722 |
+
$salesQuoteItem = Mage::getModel('sales/quote_item')->getCollection()
|
723 |
+
->setQuote($quote)
|
724 |
+
->addFieldToFilter('quote_id', $this->_getQuote()->getId())
|
725 |
+
->addFieldToFilter('product_id', $product_id)
|
726 |
+
->addFieldToFilter('parent_item_id', $quoteParentItemId)
|
727 |
+
->getFirstItem();
|
728 |
+
return $salesQuoteItem->getQty();
|
729 |
+
}
|
730 |
+
|
731 |
+
/**
|
732 |
+
* save cart, update session - for create and update Cart
|
733 |
+
*/
|
734 |
+
public function saveCartAndQuote() {
|
735 |
+
$this->_getSession()->setCartWasUpdated(true);
|
736 |
+
$this->_getCart()->save();
|
737 |
+
$this->_getQuote()->setTotalsCollectedFlag(false);
|
738 |
+
$this->_getQuote()->collectTotals();
|
739 |
+
$this->_getQuote()->save();
|
740 |
+
}
|
741 |
+
|
742 |
+
/**
|
743 |
+
* get Coupon max length size
|
744 |
+
*/
|
745 |
+
public function getCouponMaxLenght() {
|
746 |
+
return self::COUPON_CODE_MAX_LENGTH;
|
747 |
+
}
|
748 |
+
|
749 |
+
/**
|
750 |
+
* assign quote item id to error
|
751 |
+
* used in case where new item has QTY error but quote item id is not known at time of error was generated
|
752 |
+
*/
|
753 |
+
public function assignQuoteItemIdToErrors($data, $params) {
|
754 |
+
foreach ($data['_errors'] as $key => $error) {
|
755 |
+
if ($error['id'] == null) {
|
756 |
+
foreach ($data['items'] as $item) {
|
757 |
+
if ($item['temp_id'] == $error['temp_id'])
|
758 |
+
$data['_errors'][$key]['id'] = $item['id'];
|
759 |
+
}
|
760 |
+
}
|
761 |
+
}
|
762 |
+
return $data;
|
763 |
+
}
|
764 |
+
|
765 |
+
/**
|
766 |
+
* clear unspecified items in input JSON from cart
|
767 |
+
* add products to quote
|
768 |
+
* add coupon code to quote
|
769 |
+
*
|
770 |
+
* @param array $params
|
771 |
+
* @param array $_errors
|
772 |
+
* @return array $_errors
|
773 |
+
*/
|
774 |
+
public function addProductsAndCouponsToQuote($params = array(), $_errors = array()) {
|
775 |
+
// remove items from cart that are not specified in input JSON
|
776 |
+
$this->_removeUspecifiedItemsFromCart($params);
|
777 |
+
|
778 |
+
// add procucts to cart
|
779 |
+
if (isset($params['items'])) {
|
780 |
+
foreach ($params['items'] as $item) {
|
781 |
+
$_errors = $this->addOrUpdateProductToCart($item, $_errors);
|
782 |
+
}
|
783 |
+
}
|
784 |
+
|
785 |
+
// add coupon codes
|
786 |
+
if (isset($params['coupon_codes'])) {
|
787 |
+
$_errors = $this->addCouponCode($params['coupon_codes'], $_errors);
|
788 |
+
}
|
789 |
+
|
790 |
+
return $_errors;
|
791 |
+
}
|
792 |
+
|
793 |
+
/**
|
794 |
+
* Check if we need to display shipping include tax
|
795 |
+
*
|
796 |
+
* @return bool
|
797 |
+
*/
|
798 |
+
public function displayShippingIncludeTax() {
|
799 |
+
return Mage::getSingleton('tax/config')->displayCartShippingInclTax();
|
800 |
+
}
|
801 |
+
|
802 |
+
/**
|
803 |
+
* Get shipping price from shipping address
|
804 |
+
*
|
805 |
+
* @param Mage_Sales_Model_Quote_Address $shipping
|
806 |
+
* @return float
|
807 |
+
*/
|
808 |
+
public function getShippingPrice($shipAddress) {
|
809 |
+
if ($this->displayShippingIncludeTax() && $shipAddress->getShippingInclTax()) {
|
810 |
+
return $shipAddress->getShippingInclTax();
|
811 |
+
} elseif ($shipAddress->getShippingAmount()) {
|
812 |
+
return $shipAddress->getShippingAmount();
|
813 |
+
}
|
814 |
+
return 0;
|
815 |
+
}
|
816 |
+
|
817 |
+
/**
|
818 |
+
* Checks item messages added by Mage_CatalogInventory_Model_Observer::checkQuoteItemQty()
|
819 |
+
* if item has same message as added by observer, error is added to error array, and item is removed from cart
|
820 |
+
*
|
821 |
+
* @param array $errors
|
822 |
+
* @return array $errors
|
823 |
+
*/
|
824 |
+
public function checkAndUpdateCartInventory($errors) {
|
825 |
+
// get original message text via cataloginventory helper in case it is translated or changed
|
826 |
+
$outOfStockMessage = Mage::helper('cataloginventory')->__('This product is currently out of stock.');
|
827 |
+
foreach ($this->_getQuote()->getAllVisibleItems() as $item) {
|
828 |
+
$itemMessage = $item->getMessage();
|
829 |
+
if ($itemMessage == $outOfStockMessage) {
|
830 |
+
$errors[] = $this->getErrorArrayForProduct(array('id' => $item->getId()));
|
831 |
+
$this->log('Removing Item ID: ' . $item->getId(), 'checkAndUpdateCartInventory');
|
832 |
+
$this->_getQuote()->removeItem($item->getId())->save();
|
833 |
+
} elseif ($itemMessage) { // if any other message is set, qty not available
|
834 |
+
// for all products except bundle we can check available qty
|
835 |
+
if ($item->getProduct()->getTypeId() != Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
|
836 |
+
$productAvailableQty = $this->getProductAvailableQtyByQuoteItem($item);
|
837 |
+
$errors[] = $this->getErrorArrayForProduct(array('id' => $item->getId()), 'quantity_changed', "Requested quantity is not available");
|
838 |
+
$this->log('QTY Changed Item ID: ' . $item->getId() . ', old' . $item->getQty() . '/new' . $productAvailableQty, 'checkAndUpdateCartInventory');
|
839 |
+
$item->setQty($productAvailableQty)->save();
|
840 |
+
} else {
|
841 |
+
// for budle product we display error and keep product in cart
|
842 |
+
$errors[] = $this->getErrorArrayForProduct(array('id' => $item->getId()), 'product_unavailable', "Requested quantity is not available");
|
843 |
+
$this->log('QTY Unavailable Item ID: ' . $item->getId() . ', qty' . $item->getQty(), 'checkAndUpdateCartInventory');
|
844 |
+
}
|
845 |
+
}
|
846 |
+
}
|
847 |
+
return $errors;
|
848 |
+
}
|
849 |
+
|
850 |
+
public function getProductAvailableQtyByQuoteItem($item) {
|
851 |
+
if ($item->getProduct()->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
|
852 |
+
$simple_id = $item->getOptionByCode('simple_product')->getProduct()->getId();
|
853 |
+
$simple_product = $this->_initProduct($simple_id);
|
854 |
+
return Mage::getModel('cataloginventory/stock_item')->loadByProduct($simple_product)->getQty();
|
855 |
+
} else {
|
856 |
+
$product = $this->_initProduct($item->getProduct()->getId());
|
857 |
+
return Mage::getModel('cataloginventory/stock_item')->loadByProduct($simple_product)->getQty();
|
858 |
+
}
|
859 |
+
return $item->getQty();
|
860 |
+
}
|
861 |
+
|
862 |
+
}
|
app/code/local/Highstreet/Hsapi/Helper/Config/Checkout.php
ADDED
@@ -0,0 +1,785 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Highstreet_HSAPI_module
|
5 |
+
*
|
6 |
+
* @package Highstreet_Hsapi
|
7 |
+
* @author Radovan Dodic (radovan.dodic@atessoft.rs) ~ AtesSoft
|
8 |
+
* @copyright Copyright (c) 2016 Highstreet
|
9 |
+
*/
|
10 |
+
class Highstreet_Hsapi_Helper_Config_Checkout extends Highstreet_Hsapi_Helper_Config_Account {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Constructor class
|
14 |
+
*/
|
15 |
+
public function __construct() {
|
16 |
+
parent::__construct();
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Returns onepage object model
|
21 |
+
*
|
22 |
+
* @return object Mage_Checkout_Type_Onepage
|
23 |
+
*/
|
24 |
+
public function _getOnepage() {
|
25 |
+
return Mage::getSingleton('checkout/type_onepage');
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @return Mage_Customer_Model_Session
|
30 |
+
*/
|
31 |
+
public function _getSession() {
|
32 |
+
return Mage::getSingleton('customer/session');
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @return Mage_Checkout_Model_Session
|
37 |
+
*/
|
38 |
+
public function _getCheckoutSession() {
|
39 |
+
return Mage::getSingleton('checkout/session');
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @return Highstreet_Hsapi_Helper_Config_Cart
|
44 |
+
*/
|
45 |
+
public function _getCartHelper() {
|
46 |
+
return Mage::helper('highstreet_hsapi/config_cart');
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Set billing address to quote object
|
51 |
+
*
|
52 |
+
* @param array $address
|
53 |
+
*/
|
54 |
+
public function setBillingAddressToQuote($address) {
|
55 |
+
|
56 |
+
$data = array(
|
57 |
+
"address_id" => (isset($address['id']) && is_numeric($address['id'])) ? $address['id'] : null,
|
58 |
+
"city" => $address['city'],
|
59 |
+
"company" => @$address['company'],
|
60 |
+
"firstname" => $address['first_name'],
|
61 |
+
"lastname" => $address['last_name'],
|
62 |
+
"email" => @$address['email'],
|
63 |
+
"country_id" => $address['country_id'],
|
64 |
+
"region_id" => @$address['state'],
|
65 |
+
"postcode" => @$address['postal_code'],
|
66 |
+
"street" => array($address['street'], @$address['house_number'], @$address['addition']),
|
67 |
+
"telephone" => (string) trim($address['telephone']),
|
68 |
+
);
|
69 |
+
|
70 |
+
$result = $this->_getOnepage()->saveBilling($data, $data['address_id']);
|
71 |
+
if (isset($result['error'])) {
|
72 |
+
$this->log($result, 'Save Billing address');
|
73 |
+
}
|
74 |
+
|
75 |
+
if ($address['use_same_for_shipping']) {
|
76 |
+
$this->setShippingAddressToQuote($data, true);
|
77 |
+
}
|
78 |
+
return;
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Set shipping address to quote object
|
83 |
+
*
|
84 |
+
* @param object $quote
|
85 |
+
* @param array $address
|
86 |
+
* @param bool $as_billing
|
87 |
+
* @return object $quote
|
88 |
+
*/
|
89 |
+
public function setShippingAddressToQuote($address, $as_billing = false) {
|
90 |
+
if ($as_billing) {
|
91 |
+
$data = $address;
|
92 |
+
$data["same_as_billing"] = 1;
|
93 |
+
} else {
|
94 |
+
$data = $this->getAddressDataFromArray($address);
|
95 |
+
$data["same_as_billing"] = 0;
|
96 |
+
$data["address_id"] = (is_numeric($data["address_id"])) ? $address['id'] : null;
|
97 |
+
}
|
98 |
+
if (isset($data))
|
99 |
+
$data['telephone'] = trim($data['telephone']);
|
100 |
+
$result = $this->_getOnepage()->saveShipping($data, $data['address_id']);
|
101 |
+
if (isset($result['error'])) {
|
102 |
+
$this->log($result, 'Save Shipping address');
|
103 |
+
}
|
104 |
+
return;
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Populate array with errors
|
109 |
+
*
|
110 |
+
* @param array $data
|
111 |
+
* @param array $invalidFields
|
112 |
+
* @param array $missingFields
|
113 |
+
* @return array
|
114 |
+
*/
|
115 |
+
public function checkMissingInvalidFields($data, $invalidFields = array(), $missingFields = array()) {
|
116 |
+
$nonRequiredFields = array('coupon_codes', 'tax_included');
|
117 |
+
$errorArray = array();
|
118 |
+
foreach (array_keys($data, null) as $key) {
|
119 |
+
if (in_array($key, $nonRequiredFields))
|
120 |
+
continue;
|
121 |
+
$errorArray[] = array(
|
122 |
+
"code" => "missing",
|
123 |
+
"field" => $key,
|
124 |
+
);
|
125 |
+
}
|
126 |
+
foreach ($invalidFields as $invalidField) {
|
127 |
+
$errorArray[] = array(
|
128 |
+
"code" => "invalid",
|
129 |
+
"field" => $invalidField,
|
130 |
+
);
|
131 |
+
}
|
132 |
+
|
133 |
+
// already defined missing fields by controller
|
134 |
+
foreach ($missingFields as $missingField) {
|
135 |
+
$errorArray[] = array(
|
136 |
+
"code" => "missing",
|
137 |
+
"field" => $missingField,
|
138 |
+
);
|
139 |
+
}
|
140 |
+
|
141 |
+
$data['_errors'] = $errorArray;
|
142 |
+
return $data;
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Populate array with address data
|
147 |
+
*
|
148 |
+
* @param array $address
|
149 |
+
* @return array
|
150 |
+
*/
|
151 |
+
public function getAddressDataFromArray($address) {
|
152 |
+
return array(
|
153 |
+
"address_id" => @$address['id'],
|
154 |
+
"city" => @$address['city'],
|
155 |
+
"company" => @$address['company'],
|
156 |
+
"firstname" => @$address['first_name'],
|
157 |
+
"lastname" => @$address['last_name'],
|
158 |
+
"country_id" => @$address['country_id'],
|
159 |
+
"region_id" => @$address['state'],
|
160 |
+
"postcode" => @$address['postal_code'],
|
161 |
+
"street" => array(@$address['street'], @$address['house_number'], @$address['addition']),
|
162 |
+
"telephone" => (string) trim(@$address['telephone']) . ' '
|
163 |
+
);
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* check required default magento address fields
|
168 |
+
*
|
169 |
+
* @param array $address
|
170 |
+
* @param bool $asBool
|
171 |
+
* @param array $missing
|
172 |
+
* @param string $type
|
173 |
+
* @return array
|
174 |
+
*/
|
175 |
+
public function checkRequiredAddressFields($address, $asBool = false, $missing = array(), $type = 'billing_address') {
|
176 |
+
$requiredFields = array('first_name', 'last_name', 'street', 'city', 'country_id', 'telephone');
|
177 |
+
foreach ($requiredFields as $rfield) {
|
178 |
+
if (!isset($address[$rfield]) || $address[$rfield] == null || $address[$rfield] == 'null') {
|
179 |
+
if ($asBool)
|
180 |
+
return false;
|
181 |
+
$missing[] = $type;
|
182 |
+
return $missing;
|
183 |
+
//$missing[] = $type . '_' . $rfield;
|
184 |
+
}
|
185 |
+
}
|
186 |
+
if ($asBool)
|
187 |
+
return true;
|
188 |
+
return $missing;
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* check is shipping method valid
|
193 |
+
*
|
194 |
+
* @param string $shipping_method
|
195 |
+
* @return bool true | false
|
196 |
+
*/
|
197 |
+
public function checkIsShippingMethodValid($shipping_method) {
|
198 |
+
$shipping_method = $this->escapeString($shipping_method);
|
199 |
+
// if address is set, use different method of retrieving shipping methods
|
200 |
+
$cart = Mage::getSingleton('checkout/cart');
|
201 |
+
$address = $cart->getQuote()->getShippingAddress();
|
202 |
+
if ($address->getQuoteId() && $address->getFirstname()) {
|
203 |
+
$methods = $this->getShippingMethods($address, $cart->getQuote(), true);
|
204 |
+
} else {
|
205 |
+
$methods = $this->getAllShippingMethods(true);
|
206 |
+
}
|
207 |
+
foreach ($methods as $sh_method) {
|
208 |
+
if (isset($sh_method['code'])) {
|
209 |
+
if ($shipping_method == $sh_method['code'])
|
210 |
+
return true;
|
211 |
+
}
|
212 |
+
}
|
213 |
+
return false;
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* returns array for JSON with ALL shipping methods
|
218 |
+
*
|
219 |
+
* @return array
|
220 |
+
*/
|
221 |
+
public function getAllShippingMethods($asArray = false) {
|
222 |
+
$jsonMethods = array();
|
223 |
+
$methods = array();
|
224 |
+
$activeCarriers = Mage::getSingleton('shipping/config')->getActiveCarriers();
|
225 |
+
$activeMethods = array();
|
226 |
+
foreach ($activeCarriers as $carrierCode => $carrierModel) {
|
227 |
+
$m = array(
|
228 |
+
'type' => 'option',
|
229 |
+
'title' => Mage::getStoreConfig('carriers/' . $carrierCode . '/title'),
|
230 |
+
'code' => $carrierCode,
|
231 |
+
'price' => 0, //hardcoded for now
|
232 |
+
);
|
233 |
+
if ($carrierMethods = $carrierModel->getAllowedMethods()) {
|
234 |
+
$options = array();
|
235 |
+
foreach ($carrierMethods as $methodCode => $method) {
|
236 |
+
$code = $carrierCode . '_' . $methodCode;
|
237 |
+
$o = array(
|
238 |
+
'type' => 'option',
|
239 |
+
'title' => Mage::getStoreConfig('carriers/' . $carrierCode . '/title'),
|
240 |
+
'code' => $code,
|
241 |
+
'price' => 0, //hardcoded for now
|
242 |
+
);
|
243 |
+
$options[] = $o;
|
244 |
+
if ($asArray)
|
245 |
+
$activeMethods[] = $o;
|
246 |
+
}
|
247 |
+
|
248 |
+
$m['options'] = $options;
|
249 |
+
//$carrierTitle = Mage::getStoreConfig('carriers/' . $carrierCode . '/title');
|
250 |
+
}
|
251 |
+
$methods[] = $m;
|
252 |
+
}
|
253 |
+
if ($asArray)
|
254 |
+
return $activeMethods;
|
255 |
+
$jsonMethods['shipping_methods'] = $methods;
|
256 |
+
return $jsonMethods;
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* returns array for JSON with shipping methods dependent on address
|
261 |
+
*
|
262 |
+
* @return array
|
263 |
+
*/
|
264 |
+
public function getShippingMethods($address, $quote, $asArray = false) {
|
265 |
+
$sp = array();
|
266 |
+
$quote = $this->_getOnepage()->getQuote();
|
267 |
+
$quote->getShippingAddress()->collectShippingRates();
|
268 |
+
foreach ($quote->getShippingAddress()->getGroupedAllShippingRates() as $rates) {
|
269 |
+
foreach ($rates as $rate) {
|
270 |
+
if ($rate instanceof Mage_Shipping_Model_Rate_Result_Error) {
|
271 |
+
$errors[$rate->getCarrierTitle()] = 1;
|
272 |
+
} else {
|
273 |
+
if ($address->getFreeShipping()) {
|
274 |
+
$price = 0;
|
275 |
+
} else {
|
276 |
+
$price = $rate->getPrice();
|
277 |
+
}
|
278 |
+
if ($price) {
|
279 |
+
// get shipping method default price with tax helper, with or without tax
|
280 |
+
if ($this->_getCartHelper()->displayShippingIncludeTax()) {
|
281 |
+
$price = $quote->getStore()->convertPrice(Mage::helper('tax')->getShippingPrice($price, null, $address));
|
282 |
+
} else {
|
283 |
+
$price = $quote->getStore()->convertPrice(Mage::helper('tax')->getShippingPrice($price, null, $address, true));
|
284 |
+
}
|
285 |
+
}
|
286 |
+
|
287 |
+
$sp[$rate->getCarrier()][] = array(
|
288 |
+
'label' => $rate->getMethodTitle(),
|
289 |
+
'carrier' => $rate->getCarrierTitle(),
|
290 |
+
'code' => $rate->getCarrier() . '_' . $rate->getMethod(),
|
291 |
+
'price' => $price,
|
292 |
+
);
|
293 |
+
}
|
294 |
+
}
|
295 |
+
}
|
296 |
+
$options = array();
|
297 |
+
// creating array ready for json output
|
298 |
+
foreach ($sp as $key => $mt) {
|
299 |
+
$carrierCode = $key;
|
300 |
+
foreach ($mt as $mt_key => $method) {
|
301 |
+
$code = $method['code'];
|
302 |
+
$optionsArray = array(
|
303 |
+
'type' => 'option',
|
304 |
+
'title' => $method['label'],
|
305 |
+
'code' => $method['code'],
|
306 |
+
'price' => $method['price'],
|
307 |
+
);
|
308 |
+
if (strstr($carrierCode, "postnl") !== false && $this->isPostNLDeliveryDaysEnabled()) {
|
309 |
+
$postNLOptionsRaw = $this->getPostNlDeliveryOptions($address);
|
310 |
+
if (count($postNLOptionsRaw)) {
|
311 |
+
$optionsArray['options'] = $this->convertPostNLResponseToSubOptions($postNLOptionsRaw, $method['price']);
|
312 |
+
}
|
313 |
+
}
|
314 |
+
$options[] = $optionsArray;
|
315 |
+
}
|
316 |
+
}
|
317 |
+
if ($asArray)
|
318 |
+
return $options;
|
319 |
+
$jsonMethods['shipping_methods'] = $options;
|
320 |
+
return $jsonMethods;
|
321 |
+
}
|
322 |
+
|
323 |
+
/**
|
324 |
+
* get PostNl delivery day
|
325 |
+
*
|
326 |
+
* @return bool
|
327 |
+
*/
|
328 |
+
public function isPostNLDeliveryDaysEnabled() {
|
329 |
+
return (bool) Mage::getStoreConfig('postnl/delivery_options/enable_delivery_days');
|
330 |
+
}
|
331 |
+
|
332 |
+
/**
|
333 |
+
* convert raw data from postNl extension to custom format
|
334 |
+
*
|
335 |
+
* @param object $postNLOptionsRaw
|
336 |
+
* @param float $price
|
337 |
+
* @return array
|
338 |
+
*/
|
339 |
+
public function convertPostNLResponseToSubOptions($postNLOptionsRaw, $price = 0) {
|
340 |
+
$response = array();
|
341 |
+
foreach ($postNLOptionsRaw as $postNLDate) {
|
342 |
+
foreach ($postNLDate->Timeframes->TimeframeTimeFrame as $timeframes) {
|
343 |
+
//var_dump($option->Timeframes->TimeframeTimeFrame);die;
|
344 |
+
$timeFrom = date('H:i', strtotime($timeframes->From));
|
345 |
+
$timeTo = date('H:i', strtotime($timeframes->To));
|
346 |
+
$response[] = array(
|
347 |
+
'type' => 'option',
|
348 |
+
'title' => 'Op ' . $postNLDate->Date . ' tussen ' . $timeFrom . ' to ' . $timeTo,
|
349 |
+
'code' => $this->getPostNLCode($timeframes->Options->string[0], $postNLDate->Date, $timeframes->From, $timeframes->To),
|
350 |
+
'price' => $price,
|
351 |
+
'default' => false
|
352 |
+
);
|
353 |
+
}
|
354 |
+
}
|
355 |
+
return $response;
|
356 |
+
}
|
357 |
+
|
358 |
+
/**
|
359 |
+
* convert postnl array to base64 string
|
360 |
+
*
|
361 |
+
* @return string base64_encode
|
362 |
+
*/
|
363 |
+
public function getPostNLCode($delivery, $date, $from, $to, $costIncl = 0, $costExcl = 0) {
|
364 |
+
// taxconfig code taken from DeliveryOptionsController
|
365 |
+
$taxConfig = Mage::getSingleton('tax/config');
|
366 |
+
$costs = ($taxConfig->shippingPriceIncludesTax()) ? $costIncl : $costExcl;
|
367 |
+
|
368 |
+
// array structure is same as function saveDeliveryOption from PostNl DeliveryOptionsController expects
|
369 |
+
$jsonArray = array(
|
370 |
+
'type' => $this->translatePostNL($delivery),
|
371 |
+
'date' => $date,
|
372 |
+
'from' => $from,
|
373 |
+
'to' => $to,
|
374 |
+
'costs' => $costs
|
375 |
+
);
|
376 |
+
return $this->b64e(json_encode($jsonArray));
|
377 |
+
}
|
378 |
+
|
379 |
+
/**
|
380 |
+
* manual translate for PostNL delivery type
|
381 |
+
*
|
382 |
+
* @param string $string
|
383 |
+
* @return string
|
384 |
+
*/
|
385 |
+
public function translatePostNL($string) {
|
386 |
+
return ($string == "Evening") ? "Avond" : "Overdag";
|
387 |
+
}
|
388 |
+
|
389 |
+
/**
|
390 |
+
* returns array for JSON with ALL active payment methods filtered by country set by shipping address
|
391 |
+
*
|
392 |
+
* @return array
|
393 |
+
*/
|
394 |
+
public function getAllPaymentMethods($asArray = false) {
|
395 |
+
$jsonMethods = array();
|
396 |
+
$methods = array();
|
397 |
+
$model = new Mage_Checkout_Block_Onepage_Payment_Methods();
|
398 |
+
$quote = Mage::getSingleton('checkout/cart')->getQuote();
|
399 |
+
$selectedPaymentMethod;
|
400 |
+
try {
|
401 |
+
$selectedPaymentMethod = $quote->getPayment()->getData('method');
|
402 |
+
} catch (Exception $e) {
|
403 |
+
$this->logException($e, 'Get payment method');
|
404 |
+
$this->_JSONencodeAndRespond(array("title" => "Error", "content" => $e->getMessage()));
|
405 |
+
return;
|
406 |
+
}
|
407 |
+
foreach ($model->getMethods() as $method) {
|
408 |
+
$methodTitle = $method->getTitle();
|
409 |
+
$methodCode = $method->getCode();
|
410 |
+
if ($methodCode == "paypal_express") { // PayPal. Has logo and strange label text, override
|
411 |
+
$methodTitle = "PayPal";
|
412 |
+
}
|
413 |
+
$m = array(
|
414 |
+
'type' => 'option',
|
415 |
+
'title' => $method->getTitle(),
|
416 |
+
'code' => $methodCode,
|
417 |
+
'price' => $this->getPaymentMethodPrice($methodCode),
|
418 |
+
// Payment fee (price) is not available for standard payment methods, for extensions this need to be individualy coded
|
419 |
+
'image' => null,
|
420 |
+
'options' => $this->_getSuboptionsForPaymentMethod($methodCode),
|
421 |
+
);
|
422 |
+
$methods[] = $m;
|
423 |
+
}
|
424 |
+
if ($asArray)
|
425 |
+
return $methods;
|
426 |
+
$jsonMethods['payment_methods'] = $methods;
|
427 |
+
|
428 |
+
return $jsonMethods;
|
429 |
+
}
|
430 |
+
|
431 |
+
/**
|
432 |
+
* get payment price, used for external payment methods (buckaroo, Adyen...)
|
433 |
+
*
|
434 |
+
* @param string $methodCode
|
435 |
+
* @return float
|
436 |
+
*/
|
437 |
+
public function getPaymentMethodPrice($methodCode) {
|
438 |
+
if (strstr($methodCode, 'buckaroo'))
|
439 |
+
return $this->getBuckarooFee($methodCode);
|
440 |
+
if ($methodCode == "adyen_ideal")
|
441 |
+
return $this->getAdyenIdealFee($methodCode);
|
442 |
+
return 0;
|
443 |
+
}
|
444 |
+
|
445 |
+
/**
|
446 |
+
* returns JSON with ALL active payment methods, methods that are enabled in backend
|
447 |
+
*
|
448 |
+
* @return string JSON
|
449 |
+
*/
|
450 |
+
public function getAllActivePaymentMethods($asArray = false) {
|
451 |
+
$jsonMethods = array();
|
452 |
+
$methods = array();
|
453 |
+
$allActivePaymentMethods = Mage::getModel('payment/config')->getActiveMethods();
|
454 |
+
foreach ($allActivePaymentMethods as $paymentCode => $paymentModel) {
|
455 |
+
$paymentTitle = Mage::getStoreConfig('payment/' . $paymentCode . '/title');
|
456 |
+
if (strstr($paymentCode, 'buckaroo') && !strstr($paymentCode, 'lightbox') && !Mage::getStoreConfig('buckaroo/' . $paymentCode . '/active'))
|
457 |
+
continue;
|
458 |
+
$m = array(
|
459 |
+
'type' => 'option',
|
460 |
+
'title' => $paymentTitle,
|
461 |
+
'code' => $paymentCode,
|
462 |
+
'price' => (strstr($paymentCode, 'buckaroo')) ? $this->getBuckarooFee($paymentCode) : 0,
|
463 |
+
// Payment fee (price) is not available for standard payment methods, for extensions this need to be individualy coded
|
464 |
+
'image' => null,
|
465 |
+
'options' => ($ideal_options = $this->_getSuboptionsForPaymentMethod($paymentCode)) ? $ideal_options : array(),
|
466 |
+
);
|
467 |
+
$methods[] = $m;
|
468 |
+
}
|
469 |
+
if ($asArray)
|
470 |
+
return $methods;
|
471 |
+
$jsonMethods['payment_methods'] = $methods;
|
472 |
+
$this->_JSONencodeAndRespond($jsonMethods, "200 OK");
|
473 |
+
return;
|
474 |
+
}
|
475 |
+
|
476 |
+
/**
|
477 |
+
* returns JSON with ALL enabled shipping countries
|
478 |
+
*
|
479 |
+
* @return string JSON
|
480 |
+
*/
|
481 |
+
public function getShippingCountries() {
|
482 |
+
$countryArray = array();
|
483 |
+
|
484 |
+
$countryList = Mage::getModel('directory/country')->getResourceCollection()
|
485 |
+
->loadByStore()
|
486 |
+
->toOptionArray(true);
|
487 |
+
foreach ($countryList as $country) {
|
488 |
+
if ($country['label'] == '' || $country['value'] == '')
|
489 |
+
continue;
|
490 |
+
$c = array(
|
491 |
+
"name" => $country['label'],
|
492 |
+
"code" => $country['value'],
|
493 |
+
"states" => $this->getStatesOfCountry($country['value']),
|
494 |
+
);
|
495 |
+
$countryArray[] = $c;
|
496 |
+
}
|
497 |
+
$this->_JSONencodeAndRespond($countryArray, "200 OK");
|
498 |
+
return;
|
499 |
+
}
|
500 |
+
|
501 |
+
/**
|
502 |
+
* returns array with all states
|
503 |
+
*
|
504 |
+
* @param string ISO country code, example "NL", "US"
|
505 |
+
* @return array
|
506 |
+
*/
|
507 |
+
public function getStatesOfCountry($country) {
|
508 |
+
$stateArray = Mage::getModel('directory/country')->load($country)->getRegions();
|
509 |
+
$st = array();
|
510 |
+
if (count($stateArray) > 0) {
|
511 |
+
foreach ($stateArray as $state) {
|
512 |
+
$st[] = array(
|
513 |
+
'code' => $state->getData('code'),
|
514 |
+
'name' => $state->getData('name')
|
515 |
+
);
|
516 |
+
}
|
517 |
+
return $st;
|
518 |
+
} else {
|
519 |
+
return array();
|
520 |
+
}
|
521 |
+
}
|
522 |
+
|
523 |
+
/**
|
524 |
+
* returns subsoptions
|
525 |
+
* used for Buckaroo method IDEAL, and Adyen IDEAL
|
526 |
+
*
|
527 |
+
* @param string $method
|
528 |
+
* @return array/bool
|
529 |
+
*/
|
530 |
+
public function _getSuboptionsForPaymentMethod($method) {
|
531 |
+
$options = array();
|
532 |
+
if ($method === "buckaroo3extended_ideal") {
|
533 |
+
$options = $this->getBuckarooPaymentSuboptions($method);
|
534 |
+
} elseif ($method === "adyen_ideal") {
|
535 |
+
$options = $this->getAdyenPaymentSuboptions($method);
|
536 |
+
}
|
537 |
+
return $options;
|
538 |
+
}
|
539 |
+
|
540 |
+
/**
|
541 |
+
* returns Adyen Ideal payment suboptions
|
542 |
+
*
|
543 |
+
* @param string $method
|
544 |
+
* @return array
|
545 |
+
*/
|
546 |
+
public function getAdyenPaymentSuboptions($method) {
|
547 |
+
$options = array();
|
548 |
+
$issuerList = $this->getAdyenIssuers();
|
549 |
+
$price = $this->getAdyenIdealFee($method);
|
550 |
+
foreach ($issuerList as $issuer => $issuerDetails) {
|
551 |
+
// logo code from Adyen_Payment_Block_Form_Ideal
|
552 |
+
$_bankFile = strtoupper(str_replace(" ", '', $issuerDetails['label']));
|
553 |
+
$logo = Mage::getDesign()->getSkinUrl("images/adyen/$_bankFile.png");
|
554 |
+
$option = array();
|
555 |
+
$option["type"] = "option";
|
556 |
+
$option["price"] = $price;
|
557 |
+
$option["title"] = $issuerDetails['label'];
|
558 |
+
$option["code"] = $issuer;
|
559 |
+
$option["image"] = $logo;
|
560 |
+
$options[] = $option;
|
561 |
+
}
|
562 |
+
return $options;
|
563 |
+
}
|
564 |
+
|
565 |
+
/**
|
566 |
+
* gets JSON issuer list for ideal, and converts it to specific array
|
567 |
+
*
|
568 |
+
* @return array
|
569 |
+
*/
|
570 |
+
public function getAdyenIssuers() {
|
571 |
+
$storeId = $this->getStoreId();
|
572 |
+
$json_issuers = Mage::getStoreConfig("payment/adyen_ideal/issuers", $storeId);
|
573 |
+
// code partially taken from Adyen_Payment_Model_Adyen_Ideal
|
574 |
+
$issuerData = json_decode($json_issuers, true);
|
575 |
+
$issuers = array();
|
576 |
+
if (!$issuerData) {
|
577 |
+
return $issuers;
|
578 |
+
}
|
579 |
+
foreach ($issuerData as $issuer) {
|
580 |
+
$issuers[(string) $issuer['issuerId'] . " "] = array(
|
581 |
+
'label' => $issuer['name']
|
582 |
+
);
|
583 |
+
}
|
584 |
+
ksort($issuers);
|
585 |
+
return $issuers;
|
586 |
+
}
|
587 |
+
|
588 |
+
/**
|
589 |
+
* returns Buckaroo Ideal payment suboptions
|
590 |
+
*
|
591 |
+
* @param string $method
|
592 |
+
* @return array
|
593 |
+
*/
|
594 |
+
public function getBuckarooPaymentSuboptions($method) {
|
595 |
+
$options = array();
|
596 |
+
|
597 |
+
$session = Mage::getSingleton('checkout/session');
|
598 |
+
$sessionValue = $session->getData('buckaroo3extended_ideal_BPE_Issuer');
|
599 |
+
$buckarooIdealModel = new TIG_Buckaroo3Extended_Block_PaymentMethods_Ideal_Checkout_Form();
|
600 |
+
$issuerList = $buckarooIdealModel->getIssuerList();
|
601 |
+
|
602 |
+
$price = $this->getBuckarooFee($method);
|
603 |
+
foreach ($issuerList as $issuer => $issuerDetails) {
|
604 |
+
$option = array();
|
605 |
+
$optionChecked = false;
|
606 |
+
if (!empty($sessionValue) && array_key_exists($sessionValue, $issuerList)) {
|
607 |
+
if ($issuer == $sessionValue) {
|
608 |
+
$optionChecked = true;
|
609 |
+
}
|
610 |
+
}
|
611 |
+
$option["type"] = "option";
|
612 |
+
$option["price"] = $price;
|
613 |
+
$option["title"] = $issuerDetails['name'];
|
614 |
+
$option["code"] = $issuer;
|
615 |
+
$option["image"] = $issuerDetails['logo'];
|
616 |
+
$options[] = $option;
|
617 |
+
}
|
618 |
+
return $options;
|
619 |
+
}
|
620 |
+
|
621 |
+
/**
|
622 |
+
* returns Buckaroo payment fee from magento configuration
|
623 |
+
*
|
624 |
+
* @param string $method
|
625 |
+
* @return string $price
|
626 |
+
*/
|
627 |
+
public function getBuckarooFee($method) {
|
628 |
+
$xpath = 'buckaroo/' . $method . '/payment_fee';
|
629 |
+
$price = (Mage::getStoreConfig($xpath)) ? Mage::getStoreConfig($xpath) : 0;
|
630 |
+
return $price;
|
631 |
+
}
|
632 |
+
|
633 |
+
/**
|
634 |
+
* returns Adyen payment fee from magento configuration
|
635 |
+
*
|
636 |
+
* @param string $method
|
637 |
+
* @return string $price
|
638 |
+
*/
|
639 |
+
public function getAdyenIdealFee($method) {
|
640 |
+
$xpath = 'payment/' . $method . '/fee';
|
641 |
+
$price = (Mage::getStoreConfig($xpath)) ? Mage::getStoreConfig($xpath) : 0;
|
642 |
+
return $price;
|
643 |
+
}
|
644 |
+
|
645 |
+
/**
|
646 |
+
* returns true if shipping address is same as billing
|
647 |
+
*
|
648 |
+
* @param Mage_Sales_Model_Quote_Address $shipping
|
649 |
+
* @return bool
|
650 |
+
*/
|
651 |
+
public function sameAsBilling($shipping) {
|
652 |
+
return (bool) $shipping->getData('same_as_billing');
|
653 |
+
}
|
654 |
+
|
655 |
+
/**
|
656 |
+
* returns shiping method in specific array
|
657 |
+
*
|
658 |
+
* @param string $method
|
659 |
+
* @return array
|
660 |
+
*/
|
661 |
+
public function getShippingMethod($method) {
|
662 |
+
if (is_array($method) && isset($method['code'])) {
|
663 |
+
$method = $method['code'];
|
664 |
+
}
|
665 |
+
if ($method) {
|
666 |
+
return array(
|
667 |
+
'code' => $method,
|
668 |
+
'options' => ($this->_getSession()->getPostNLData()) ? array('code' => $this->_getSession()->getPostNLData()) : null,
|
669 |
+
);
|
670 |
+
}
|
671 |
+
return null;
|
672 |
+
}
|
673 |
+
|
674 |
+
/**
|
675 |
+
* returns payment method in specific array
|
676 |
+
*
|
677 |
+
* @param string $method
|
678 |
+
* @return array
|
679 |
+
*/
|
680 |
+
public function getPaymentMethod($method) {
|
681 |
+
if (strstr($method, 'buckaroo3extended')) {
|
682 |
+
return $this->getPaymentMethodBuckarooArray($method);
|
683 |
+
} elseif (strstr($method, 'adyen_ideal')) {
|
684 |
+
return $this->getPaymentMethodAdyenArray($method);
|
685 |
+
} else {
|
686 |
+
return array(
|
687 |
+
'code' => $method,
|
688 |
+
'options' => null,
|
689 |
+
);
|
690 |
+
}
|
691 |
+
}
|
692 |
+
|
693 |
+
/**
|
694 |
+
* returns options array for Buckaroo method
|
695 |
+
*
|
696 |
+
* @param string $method
|
697 |
+
* @return array
|
698 |
+
*/
|
699 |
+
public function getPaymentMethodBuckarooArray($method) {
|
700 |
+
$issuer = $this->_getCheckoutSession()->getData('additionalFields');
|
701 |
+
$code = (isset($issuer) && isset($issuer['Issuer'])) ? $issuer['Issuer'] : null;
|
702 |
+
return array(
|
703 |
+
'code' => $method,
|
704 |
+
'options' => array(array(
|
705 |
+
'code' => $code
|
706 |
+
))
|
707 |
+
);
|
708 |
+
}
|
709 |
+
|
710 |
+
/**
|
711 |
+
* returns options array for Adyen_Ideal method
|
712 |
+
*
|
713 |
+
* @param string $method
|
714 |
+
* @return array
|
715 |
+
*/
|
716 |
+
public function getPaymentMethodAdyenArray($method) {
|
717 |
+
$quote = $this->_getCartHelper()->_getQuote();
|
718 |
+
$code = ($quote->getPayment()->getPoNumber()) ? $quote->getPayment()->getPoNumber() : null;
|
719 |
+
return array(
|
720 |
+
'code' => $method,
|
721 |
+
'options' => array(array(
|
722 |
+
'code' => (string) $code . " "
|
723 |
+
))
|
724 |
+
);
|
725 |
+
}
|
726 |
+
|
727 |
+
public function getPostNlDeliveryOptions($address) {
|
728 |
+
$street = $address->getStreet();
|
729 |
+
$postNlOptions = array();
|
730 |
+
$cif = Mage::getModel('postnl_deliveryoptions/cif');
|
731 |
+
if ($cif) {
|
732 |
+
$housenumber = "1"; //default to 1.
|
733 |
+
if (Mage::getStoreConfig('customer/address/street_lines') == 1) {
|
734 |
+
$st = (is_array($street)) ? $street[0] : $street;
|
735 |
+
preg_match('([0-9]+)', $st, $matches);
|
736 |
+
if (isset($matches) && count($matches) > 0) {
|
737 |
+
$housenumber = $matches[0];
|
738 |
+
}
|
739 |
+
} else {
|
740 |
+
if (is_array($street) && isset($street[1]))
|
741 |
+
$housenumber = $street[1];
|
742 |
+
}
|
743 |
+
$postNlOptions = $cif->setStoreId(Mage::app()->getStore()->getId())
|
744 |
+
->getDeliveryTimeframes(array(
|
745 |
+
'postcode' => str_replace(" ", "", $address->getPostcode()), // Postcode
|
746 |
+
'housenumber' => $housenumber,
|
747 |
+
'deliveryDate' => date('d-m-Y', strtotime('+ 1 day')), // Set delivery day to tomorrow
|
748 |
+
'country' => $address->getCountryId(),
|
749 |
+
));
|
750 |
+
}
|
751 |
+
return $postNlOptions;
|
752 |
+
}
|
753 |
+
|
754 |
+
/**
|
755 |
+
* check is payment method valid
|
756 |
+
*
|
757 |
+
* @param string $payment_method
|
758 |
+
* @return bool
|
759 |
+
*/
|
760 |
+
public function checkIsPaymentMethodValid($payment_method) {
|
761 |
+
$payment_method = $this->escapeString($payment_method);
|
762 |
+
$validPaymentMethods = $this->getAllPaymentMethods(true);
|
763 |
+
foreach ($validPaymentMethods as $method) {
|
764 |
+
if ($method['code'] == $payment_method)
|
765 |
+
return true;
|
766 |
+
}
|
767 |
+
return false;
|
768 |
+
}
|
769 |
+
|
770 |
+
/**
|
771 |
+
* add additional options to payment array, before its saved
|
772 |
+
*
|
773 |
+
* @param array $payment
|
774 |
+
* @param array $params
|
775 |
+
* @return array $payment
|
776 |
+
*/
|
777 |
+
public function addAdditionalPaymentOptions($payment, $params) {
|
778 |
+
if ($params['payment_method']['code'] == "adyen_ideal" && isset($params['payment_method']['options']['code'])) {
|
779 |
+
$trimmed = trim((string) $params['payment_method']['options']['code']);
|
780 |
+
$payment["adyen_ideal_type"] = (string) $trimmed;
|
781 |
+
}
|
782 |
+
return $payment;
|
783 |
+
}
|
784 |
+
|
785 |
+
}
|
app/code/local/Highstreet/Hsapi/Helper/Config/Default.php
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Highstreet_HSAPI_module
|
5 |
+
*
|
6 |
+
* @package Highstreet_Hsapi
|
7 |
+
* @author Radovan Dodic (radovan.dodic@atessoft.rs) ~ AtesSoft
|
8 |
+
* @copyright Copyright (c) 2016 Highstreet
|
9 |
+
*/
|
10 |
+
class Highstreet_Hsapi_Helper_Config_Default extends Mage_Core_Helper_Abstract {
|
11 |
+
|
12 |
+
const LOG_FILE = "Highstreet_HSAPI.log";
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Constructor class
|
16 |
+
*/
|
17 |
+
public function __construct() {
|
18 |
+
$this->_response = Mage::app()->getResponse();
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* JSON validation
|
23 |
+
*
|
24 |
+
* @param string $json
|
25 |
+
* @return boolen
|
26 |
+
*/
|
27 |
+
public function isJSONValid($json) {
|
28 |
+
$json_array = $this->_JSONtoArray($json);
|
29 |
+
return (is_array($json_array)) ? true : false;
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Sets the proper headers
|
34 |
+
*/
|
35 |
+
public function _setHeader($responseCode) {
|
36 |
+
Mage::getSingleton('core/session')->setLastStoreCode(Mage::app()->getStore()->getCode());
|
37 |
+
header_remove('Pragma'); // removes 'no-cache' header
|
38 |
+
$this->_response->setHeader('Content-Type', 'application/json', true);
|
39 |
+
if ($responseCode) {
|
40 |
+
$this->_response->setHeader('HTTP/1.1', $responseCode);
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Sets headers and body with proper JSON encoding
|
46 |
+
*/
|
47 |
+
public function _JSONencodeAndRespond($data, $responseCode = "400 Bad Request", $numeric_check = true) {
|
48 |
+
$this->_setHeader($responseCode);
|
49 |
+
if ($numeric_check === FALSE || version_compare(PHP_VERSION, '5.3.3', '<')) {
|
50 |
+
$this->_response->setBody(json_encode($data));
|
51 |
+
} else {
|
52 |
+
$this->_response->setBody(json_encode($data, JSON_NUMERIC_CHECK));
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* checks request
|
58 |
+
*
|
59 |
+
*
|
60 |
+
* @param object $request
|
61 |
+
* @param array $methods
|
62 |
+
* @return bool
|
63 |
+
*/
|
64 |
+
public function _checkIsRequestValid($request, $methods = array('POST', 'GET', 'PUT', 'PATCH'), $checkBody = true) {
|
65 |
+
if (!in_array($_SERVER['REQUEST_METHOD'], $methods)) {
|
66 |
+
$this->_JSONencodeAndRespond(array("title" => "Error", "content" => "Wrong method"));
|
67 |
+
return false;
|
68 |
+
} elseif (strtolower($request->getHeader('Content-Type')) != 'application/json' && $_SERVER['REQUEST_METHOD'] == 'POST') {
|
69 |
+
$this->_JSONencodeAndRespond(array("title" => "Error", "content" => "Wrong media type"));
|
70 |
+
return false;
|
71 |
+
} elseif (!$this->isJSONValid($request->getRawBody()) && $_SERVER['REQUEST_METHOD'] == 'POST' && $checkBody) {
|
72 |
+
$this->_JSONencodeAndRespond(array("title" => "Error", "content" => "No JSON body"));
|
73 |
+
return false;
|
74 |
+
}
|
75 |
+
return true;
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* converts raw json to array
|
80 |
+
*
|
81 |
+
* @param string $raw_json
|
82 |
+
* @return array
|
83 |
+
*/
|
84 |
+
public function _JSONtoArray($raw_json) {
|
85 |
+
try {
|
86 |
+
$this->log($raw_json, 'JSON to decode');
|
87 |
+
$decodedJson = Mage::helper('core')->jsonDecode($raw_json);
|
88 |
+
} catch (Exception $e) {
|
89 |
+
$this->log($e->getMessage(), 'JSON decoding failed');
|
90 |
+
return;
|
91 |
+
}
|
92 |
+
return $decodedJson;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* HSAPI logger
|
97 |
+
*
|
98 |
+
* @param array | string $data
|
99 |
+
* @param string $message
|
100 |
+
* @param int $level
|
101 |
+
*
|
102 |
+
* Log levels:
|
103 |
+
* 0 - Emergency: system is unusable
|
104 |
+
* 1 - Alert: action must be taken immediately
|
105 |
+
* 2 - Critical: critical conditions
|
106 |
+
* 3 - Error: error conditions
|
107 |
+
* 4 - Warning: warning conditions
|
108 |
+
* 5 - Notice: normal but significant condition
|
109 |
+
* 6 - Informational: informational messages
|
110 |
+
* 7 - Debug: debug messages
|
111 |
+
*/
|
112 |
+
public function log($data = array(), $message = '', $level = Zend_Log::DEBUG) {
|
113 |
+
if ($this->isLogEnabled()) {
|
114 |
+
$dataToLog = array('message' => $message, 'data' => $data);
|
115 |
+
Mage::log($dataToLog, $level, self::LOG_FILE, true);
|
116 |
+
}
|
117 |
+
return;
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Exception logger
|
122 |
+
*
|
123 |
+
* @param Exception $e
|
124 |
+
* @param string $message
|
125 |
+
*/
|
126 |
+
public function logException(Exception $e, $message = '') {
|
127 |
+
$logData = array(
|
128 |
+
"Exception message" => $e->getMessage(),
|
129 |
+
"Exception" => "\n" . $e->__toString());
|
130 |
+
$this->log($logData, $message);
|
131 |
+
return;
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* returns setting from admin
|
136 |
+
*/
|
137 |
+
public function isLogEnabled() {
|
138 |
+
return Mage::getStoreConfig('highstreet_hsapi/developer/log_enabled');
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Use for direct DB access in read mode
|
143 |
+
*
|
144 |
+
* @return Mage_Core_Model_Resource getConnection
|
145 |
+
*/
|
146 |
+
public function directDBRead() {
|
147 |
+
return $this->getCoreResource()->getConnection('core_read');
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Use for direct resource functions
|
152 |
+
*
|
153 |
+
* @return Mage_Core_Model_Resource
|
154 |
+
*/
|
155 |
+
public function getCoreResource() {
|
156 |
+
return Mage::getSingleton('core/resource');
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Get current store id
|
161 |
+
*
|
162 |
+
* @return int
|
163 |
+
*/
|
164 |
+
public function getStoreId() {
|
165 |
+
return Mage::app()->getStore()->getStoreId();
|
166 |
+
}
|
167 |
+
|
168 |
+
}
|
app/code/local/Highstreet/Hsapi/Helper/Config/Redirect.php
ADDED
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Highstreet_HSAPI_module
|
5 |
+
*
|
6 |
+
* @package Highstreet_Hsapi
|
7 |
+
* @author Radovan Dodic (radovan.dodic@atessoft.rs) ~ AtesSoft
|
8 |
+
* @copyright Copyright (c) 2016 Highstreet
|
9 |
+
*/
|
10 |
+
class Highstreet_Hsapi_Helper_Config_Redirect extends Highstreet_Hsapi_Helper_Config_Checkout {
|
11 |
+
|
12 |
+
const BASE_PATH = "/hsapi/";
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Constructor class
|
16 |
+
*/
|
17 |
+
public function __construct() {
|
18 |
+
parent::__construct();
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Get decoded path and set session cookies
|
23 |
+
*
|
24 |
+
* @param object $requestObject
|
25 |
+
* @param bool $redirectType (true = external, false = redirect)
|
26 |
+
* @return string
|
27 |
+
*/
|
28 |
+
public function getPathAndSetCookies($requestObject, $redirectType = true) {
|
29 |
+
$pathHash = $requestObject->getParam('path', false);
|
30 |
+
$sessionHash = $requestObject->getParam('session', false);
|
31 |
+
$tid = $requestObject->getParam('tid', false);
|
32 |
+
|
33 |
+
if (!$pathHash && !$redirectType) {
|
34 |
+
$this->_fieldError(Highstreet_Hsapi_Helper_Config_Account::MISSING, 'path');
|
35 |
+
return false;
|
36 |
+
}
|
37 |
+
if (!$tid && $redirectType) {
|
38 |
+
$this->_fieldError(Highstreet_Hsapi_Helper_Config_Account::MISSING, 'tid');
|
39 |
+
return false;
|
40 |
+
}
|
41 |
+
|
42 |
+
if (!$sessionHash) {
|
43 |
+
$this->_fieldError(Highstreet_Hsapi_Helper_Config_Account::MISSING, 'session');
|
44 |
+
return false;
|
45 |
+
}
|
46 |
+
|
47 |
+
try {
|
48 |
+
$decodedSessionJson = base64_decode($sessionHash);
|
49 |
+
$paramsSession = $this->_JSONtoArray($decodedSessionJson);
|
50 |
+
if (!$redirectType)
|
51 |
+
$decodedPath = base64_decode($pathHash);
|
52 |
+
} catch (Exception $e) {
|
53 |
+
$this->logException($e, 'Redirect base64decode');
|
54 |
+
$this->_JSONencodeAndRespond(array("title" => "Error", "content" => $e->getMessage()), "200 OK");
|
55 |
+
return false;
|
56 |
+
}
|
57 |
+
|
58 |
+
if (!isset($paramsSession['frontend'])) {
|
59 |
+
$this->_fieldError(Highstreet_Hsapi_Helper_Config_Account::MISSING, 'frontend');
|
60 |
+
return false;
|
61 |
+
}
|
62 |
+
if (!$redirectType && !isset($decodedPath)) {
|
63 |
+
$this->_fieldError(Highstreet_Hsapi_Helper_Config_Account::MISSING, 'path');
|
64 |
+
return false;
|
65 |
+
}
|
66 |
+
|
67 |
+
$sessionCookie = $paramsSession['frontend'];
|
68 |
+
|
69 |
+
// try to init session by cookie/session ID
|
70 |
+
try {
|
71 |
+
$session = Mage::getSingleton('core/session');
|
72 |
+
// close session. the session model does not provide a method for this
|
73 |
+
session_write_close();
|
74 |
+
unset($_SESSION);
|
75 |
+
// open new session
|
76 |
+
$session->setSessionId($sessionCookie);
|
77 |
+
$session->init('frontend', 'checkout');
|
78 |
+
} catch (Exception $e) {
|
79 |
+
$this->logException($e, 'Set Cookie Action - setting session cookie');
|
80 |
+
$this->_JSONencodeAndRespond(array("title" => "Error", "content" => $e->getMessage()), "200 OK");
|
81 |
+
return false;
|
82 |
+
}
|
83 |
+
|
84 |
+
// if this is external checkout, we set TID to session, and get checkout url from config or helper
|
85 |
+
if ($redirectType) {
|
86 |
+
$session->setHsTid($tid);
|
87 |
+
$decodedPath = $this->getRedirectUrl();
|
88 |
+
}
|
89 |
+
|
90 |
+
// set cookie
|
91 |
+
$cookie = Mage::getSingleton('core/cookie');
|
92 |
+
$cookie->set('frontend', $sessionCookie, time() + 3600, '/');
|
93 |
+
if (isset($paramsSession['frontend_cid']))
|
94 |
+
$cookie->set('frontend_cid', $paramsSession['frontend_cid'], time() + 3600, '/');
|
95 |
+
|
96 |
+
return $decodedPath;
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* get redirect url for external checkout
|
101 |
+
*
|
102 |
+
* @return string
|
103 |
+
*/
|
104 |
+
public function getRedirectUrl() {
|
105 |
+
// get redirect url from API helper
|
106 |
+
$urlFromHelper = Mage::helper('highstreet_hsapi/config_api')->checkoutRedirectUrl();
|
107 |
+
return ($urlFromHelper) ? $urlFromHelper : Mage::helper('checkout/url')->getCheckoutUrl();
|
108 |
+
}
|
109 |
+
|
110 |
+
}
|
app/code/local/Highstreet/Hsapi/Model/Attributes.php
CHANGED
@@ -50,20 +50,23 @@ class Highstreet_Hsapi_Model_Attributes extends Mage_Core_Model_Abstract
|
|
50 |
* @param null $code
|
51 |
* @return bool
|
52 |
*/
|
53 |
-
public function getAttribute($code=null)
|
54 |
{
|
55 |
if(null != $code){
|
56 |
-
if (array_key_exists($code, $this->_cachedAttributes)) {
|
57 |
return $this->_cachedAttributes[$code];
|
58 |
} else {
|
59 |
-
$attribute = $this->_extractResponse($this->_getAttribute($code));
|
60 |
|
61 |
$response = array();
|
62 |
if (array_key_exists('attributes', $attribute) && count($attribute['attributes']) > 0) {
|
63 |
$response = $attribute['attributes'][0];
|
64 |
}
|
65 |
|
66 |
-
$
|
|
|
|
|
|
|
67 |
return $response;
|
68 |
}
|
69 |
}
|
@@ -107,9 +110,10 @@ class Highstreet_Hsapi_Model_Attributes extends Mage_Core_Model_Abstract
|
|
107 |
/**
|
108 |
* Extract the correct formatted array from the attribute data
|
109 |
* @param $attributes
|
|
|
110 |
* @return array|bool
|
111 |
*/
|
112 |
-
private function _extractResponse($attributes)
|
113 |
{
|
114 |
|
115 |
if(!is_array($attributes)){
|
@@ -127,10 +131,12 @@ class Highstreet_Hsapi_Model_Attributes extends Mage_Core_Model_Abstract
|
|
127 |
$result['type'] = $attribute['frontend_input'];
|
128 |
|
129 |
//Get the optionValues for this attribute
|
130 |
-
$
|
131 |
-
|
132 |
-
|
133 |
-
|
|
|
|
|
134 |
|
135 |
//we need to push to respond as a json array without index
|
136 |
array_push($response['attributes'], $result);
|
50 |
* @param null $code
|
51 |
* @return bool
|
52 |
*/
|
53 |
+
public function getAttribute($code=null,$includeOptions=true)
|
54 |
{
|
55 |
if(null != $code){
|
56 |
+
if (array_key_exists($code, $this->_cachedAttributes) && $includeOptions) {
|
57 |
return $this->_cachedAttributes[$code];
|
58 |
} else {
|
59 |
+
$attribute = $this->_extractResponse($this->_getAttribute($code), $includeOptions);
|
60 |
|
61 |
$response = array();
|
62 |
if (array_key_exists('attributes', $attribute) && count($attribute['attributes']) > 0) {
|
63 |
$response = $attribute['attributes'][0];
|
64 |
}
|
65 |
|
66 |
+
if ($includeOptions) {
|
67 |
+
$this->_cachedAttributes[$code] = $response;
|
68 |
+
}
|
69 |
+
|
70 |
return $response;
|
71 |
}
|
72 |
}
|
110 |
/**
|
111 |
* Extract the correct formatted array from the attribute data
|
112 |
* @param $attributes
|
113 |
+
* @param $includeOptions
|
114 |
* @return array|bool
|
115 |
*/
|
116 |
+
private function _extractResponse($attributes, $includeOptions=true)
|
117 |
{
|
118 |
|
119 |
if(!is_array($attributes)){
|
131 |
$result['type'] = $attribute['frontend_input'];
|
132 |
|
133 |
//Get the optionValues for this attribute
|
134 |
+
if ($includeOptions) {
|
135 |
+
$result['options'] = $this->_getAttributeOptionValues(
|
136 |
+
$attribute['attribute_id'],
|
137 |
+
$attribute['default_value']
|
138 |
+
);
|
139 |
+
}
|
140 |
|
141 |
//we need to push to respond as a json array without index
|
142 |
array_push($response['attributes'], $result);
|
app/code/local/Highstreet/Hsapi/Model/CartObserver.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Highstreet_Hsapi_Model_CartObserver {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Listener for the cart or quote changes
|
7 |
+
* updates session etag with hashed timestamp
|
8 |
+
*/
|
9 |
+
public function cartEtagUpdate($observer) {
|
10 |
+
Mage::helper('highstreet_hsapi/config_cart')->updateCartEtag();
|
11 |
+
return;
|
12 |
+
}
|
13 |
+
|
14 |
+
}
|
app/code/local/Highstreet/Hsapi/Model/CheckoutV2.php
CHANGED
@@ -230,8 +230,8 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
|
|
230 |
} else {
|
231 |
$response["error"] = -1;
|
232 |
}
|
233 |
-
|
234 |
-
if ($billingAddressData["firstname"] !== null) {
|
235 |
$billingAddressResponse = array();
|
236 |
|
237 |
$billingAddressResponse["email"] = $billingAddressData["email"];
|
@@ -343,7 +343,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
|
|
343 |
$actualQuantity = $requestedQuantity; //actual qty is what we are going to add
|
344 |
|
345 |
//adjust actual quantity if we are requesting more than in stock
|
346 |
-
$availableQuantity = $itemInventory->getQty();
|
347 |
$isInStock = $itemInventory->getIsInStock();
|
348 |
$isStockManaged = $itemInventory->getManageStock();
|
349 |
$backordersAllowed = $itemInventory->getBackorders();
|
@@ -747,7 +747,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
|
|
747 |
$responseRate["carrierTitle"] = $rate->getCarrierTitle();
|
748 |
$responseRate["carrierCode"] = $rate->getCode();
|
749 |
|
750 |
-
$responseRate["method"] = $rate->getMethod();
|
751 |
$responseRate["methodTitle"] = $rate->getMethodTitle();
|
752 |
$responseRate["methodDescription"] = $rate->getMethodDescription();
|
753 |
$responseRate["price"] = $price;
|
230 |
} else {
|
231 |
$response["error"] = -1;
|
232 |
}
|
233 |
+
|
234 |
+
if (isset($billingAddressData["firstname"]) && $billingAddressData["firstname"] !== null) {
|
235 |
$billingAddressResponse = array();
|
236 |
|
237 |
$billingAddressResponse["email"] = $billingAddressData["email"];
|
343 |
$actualQuantity = $requestedQuantity; //actual qty is what we are going to add
|
344 |
|
345 |
//adjust actual quantity if we are requesting more than in stock
|
346 |
+
$availableQuantity = $itemInventory->getQty() - $itemInventory->getMinQty();
|
347 |
$isInStock = $itemInventory->getIsInStock();
|
348 |
$isStockManaged = $itemInventory->getManageStock();
|
349 |
$backordersAllowed = $itemInventory->getBackorders();
|
747 |
$responseRate["carrierTitle"] = $rate->getCarrierTitle();
|
748 |
$responseRate["carrierCode"] = $rate->getCode();
|
749 |
|
750 |
+
$responseRate["method"] = $rate->getMethod() . " ";
|
751 |
$responseRate["methodTitle"] = $rate->getMethodTitle();
|
752 |
$responseRate["methodDescription"] = $rate->getMethodDescription();
|
753 |
$responseRate["price"] = $price;
|
app/code/local/Highstreet/Hsapi/Model/Observer.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
class Highstreet_Hsapi_Model_Observer {
|
4 |
|
5 |
-
|
6 |
|
7 |
/**
|
8 |
* Listener for the sales_quote_merge_before event
|
@@ -48,15 +48,24 @@ class Highstreet_Hsapi_Model_Observer {
|
|
48 |
$order->addStatusHistoryComment($this->_orderCommentTest . Mage::getSingleton('checkout/session')->getHsTid())
|
49 |
->setIsVisibleOnFront(false)
|
50 |
->setIsCustomerNotified(false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
$order->save();
|
52 |
} catch (Exception $e) {}
|
|
|
|
|
53 |
}
|
54 |
}
|
55 |
|
56 |
/**
|
57 |
* Private function used to communicate orders to the Highstreet middleware
|
58 |
*/
|
59 |
-
|
60 |
if ($order->getQuoteId() > 0) {
|
61 |
|
62 |
// Check if this order identifies as a HS order trough the earlier added comment
|
2 |
|
3 |
class Highstreet_Hsapi_Model_Observer {
|
4 |
|
5 |
+
protected $_orderCommentTest = "Order made via the Highstreet app. Data identifier: ";
|
6 |
|
7 |
/**
|
8 |
* Listener for the sales_quote_merge_before event
|
48 |
$order->addStatusHistoryComment($this->_orderCommentTest . Mage::getSingleton('checkout/session')->getHsTid())
|
49 |
->setIsVisibleOnFront(false)
|
50 |
->setIsCustomerNotified(false);
|
51 |
+
|
52 |
+
//Override the store (if filled in)
|
53 |
+
$configHelper = Mage::helper('highstreet_hsapi/config_api');
|
54 |
+
$storeId = $configHelper->storeOverride();
|
55 |
+
if($storeId && $storeId != -1) {
|
56 |
+
$order->setStoreId($storeId);
|
57 |
+
}
|
58 |
$order->save();
|
59 |
} catch (Exception $e) {}
|
60 |
+
|
61 |
+
|
62 |
}
|
63 |
}
|
64 |
|
65 |
/**
|
66 |
* Private function used to communicate orders to the Highstreet middleware
|
67 |
*/
|
68 |
+
protected function _communicateOrderEvent($order, $status = '') {
|
69 |
if ($order->getQuoteId() > 0) {
|
70 |
|
71 |
// Check if this order identifies as a HS order trough the earlier added comment
|
app/code/local/Highstreet/Hsapi/Model/Products.php
CHANGED
@@ -11,9 +11,13 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
11 |
const MEDIA_PATH = '/media/';
|
12 |
const PRODUCTS_MEDIA_PATH = '/media/catalog/product';
|
13 |
const NO_IMAGE_PATH = 'no_selection';
|
14 |
-
const RANGE_FALLBACK_RANGE =
|
|
|
15 |
const SPECIAL_PRICE_FROM_DATE_FALLBACK = "1970-01-01 00:00:00";
|
16 |
|
|
|
|
|
|
|
17 |
protected $_attributesModel = null;
|
18 |
|
19 |
public function __construct() {
|
@@ -137,16 +141,18 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
137 |
|
138 |
$collection = $catalogSearchModelCollection;
|
139 |
} else {
|
140 |
-
|
141 |
// initialize
|
142 |
$collection = Mage::getModel('catalog/product')->getCollection();
|
143 |
-
$collection->addStoreFilter();
|
144 |
-
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
|
145 |
-
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
|
146 |
-
|
147 |
}
|
148 |
|
149 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
|
151 |
|
152 |
$categoryNotSet = false;
|
@@ -158,7 +164,7 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
158 |
|
159 |
$category = Mage::getModel('catalog/category')->load($categoryId);
|
160 |
if ($category->getId() === NULL) {
|
161 |
-
return
|
162 |
}
|
163 |
|
164 |
// apply search
|
@@ -174,6 +180,10 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
174 |
$range = array(0, self::RANGE_FALLBACK_RANGE);
|
175 |
}
|
176 |
|
|
|
|
|
|
|
|
|
177 |
$collection->getSelect()->limit($range[1], $range[0]);
|
178 |
|
179 |
$attributesArray = array();
|
@@ -193,39 +203,12 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
193 |
|
194 |
//apply filters
|
195 |
if(!empty($filters)) {
|
196 |
-
|
197 |
-
if (array_key_exists('attribute', $filter)) {
|
198 |
-
foreach ($filter as $operator => $condition) {
|
199 |
-
if ($operator != 'attribute') {
|
200 |
-
$collection->addAttributeToFilter(array(array('attribute' => $filter['attribute'], $operator => $condition)));
|
201 |
-
}
|
202 |
-
}
|
203 |
-
}
|
204 |
-
}
|
205 |
}
|
206 |
|
207 |
// Add 'out of stock' filter, if preffered
|
208 |
if (!Mage::getStoreConfig('cataloginventory/options/show_out_of_stock')) {
|
209 |
Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collection);
|
210 |
-
|
211 |
-
// Make a better fix for this. At this time this seems impossible, this doesn't work:
|
212 |
-
// $collection->addAttributeToFilter('is_salable', array('eq' => 1));
|
213 |
-
// Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collection); // Another popular suggestion around the web, crashes the app for now and 'under water' does the same as l:276
|
214 |
-
// For now we look trough all the configurable products in the collection of a certain category and filter out the unneded products
|
215 |
-
$collectionConfigurable = Mage::getResourceModel('catalog/product_collection')->addAttributeToFilter('type_id', array('eq' => 'configurable'));
|
216 |
-
$collectionConfigurable->addCategoryFilter($category);
|
217 |
-
|
218 |
-
$outOfStockConfis = array();
|
219 |
-
foreach ($collectionConfigurable as $_configurableproduct) {
|
220 |
-
$product = Mage::getModel('catalog/product')->load($_configurableproduct->getId());
|
221 |
-
if (!$product->getData('is_salable')) {
|
222 |
-
$outOfStockConfis[] = $product->getId();
|
223 |
-
}
|
224 |
-
}
|
225 |
-
|
226 |
-
if (count($outOfStockConfis) > 0) {
|
227 |
-
$collection->addAttributeToFilter('entity_id', array('nin' => $outOfStockConfis));
|
228 |
-
}
|
229 |
}
|
230 |
|
231 |
// Apply type filter, we only want Simple and Configurable and Bundle products in our API
|
@@ -241,7 +224,7 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
241 |
* Format result array
|
242 |
*/
|
243 |
$products = array('products' => array());
|
244 |
-
|
245 |
// If range requests no products to be returned, return no products. The limit() doesn't take 0 for an answer
|
246 |
if ($range[1] > 0) {
|
247 |
if (!$hideAttributes) {
|
@@ -319,6 +302,10 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
319 |
$range = array(0, self::RANGE_FALLBACK_RANGE);
|
320 |
}
|
321 |
|
|
|
|
|
|
|
|
|
322 |
$collection->getSelect()->limit($range[1], $range[0]);
|
323 |
|
324 |
// Add 'out of stock' filter, if preffered
|
@@ -543,11 +530,8 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
543 |
$result = $controller->createBlock($filterBlockName)->setLayer($layer)->setAttributeModel($attribute)->init();
|
544 |
$options = array();
|
545 |
foreach($result->getItems() as $option) {
|
546 |
-
|
547 |
-
$
|
548 |
-
|
549 |
-
$count = $option->getData('count');
|
550 |
-
array_push($options, array('value' => $option->getValue(), 'title' => $title, 'product_count' => $count));
|
551 |
}
|
552 |
|
553 |
if (count($options) > 1) {
|
@@ -571,6 +555,27 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
571 |
*/
|
572 |
/***********************************/
|
573 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
574 |
/**
|
575 |
* Gets count for given collection. Function made for easier subclassing
|
576 |
*
|
@@ -649,6 +654,76 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
649 |
return $collection;
|
650 |
}
|
651 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
652 |
/**
|
653 |
*
|
654 |
* Gets attributes of a given product object.
|
@@ -872,11 +947,17 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
872 |
|
873 |
// SEE: Mage_Catalog_Block_Product_View_Attributes
|
874 |
$controller = Mage::app()->getLayout();
|
875 |
-
$block = $controller->createBlock('
|
876 |
|
877 |
// Same function as used by the layouting
|
878 |
-
foreach ($block->getAdditionalData() as $
|
879 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
880 |
}
|
881 |
|
882 |
$additionalAttributeData['inline_value'] = $html;
|
@@ -888,6 +969,17 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
888 |
continue;
|
889 |
}
|
890 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
891 |
$attributeObject = $resProduct->getResource()->getAttribute($attribute);
|
892 |
|
893 |
if ($attributeObject !== false) {
|
@@ -1078,9 +1170,11 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
1078 |
|
1079 |
$output = array();
|
1080 |
|
1081 |
-
|
|
|
1082 |
$imageData = $value->getData();
|
1083 |
|
|
|
1084 |
if ($this->_shouldExcludeImageFromMediaGallery($imageData["file"], $resProduct)) {
|
1085 |
continue;
|
1086 |
}
|
@@ -1129,4 +1223,4 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
1129 |
"special_from_date", "special_to_date", "special_price", "is_salable");
|
1130 |
}
|
1131 |
|
1132 |
-
}
|
11 |
const MEDIA_PATH = '/media/';
|
12 |
const PRODUCTS_MEDIA_PATH = '/media/catalog/product';
|
13 |
const NO_IMAGE_PATH = 'no_selection';
|
14 |
+
const RANGE_FALLBACK_RANGE = 20;
|
15 |
+
const RANGE_LIMIT = 100;
|
16 |
const SPECIAL_PRICE_FROM_DATE_FALLBACK = "1970-01-01 00:00:00";
|
17 |
|
18 |
+
const PRODUCTS_ERROR_NOT_FOUND = 404;
|
19 |
+
const PRODUCTS_ERROR_OUT_OF_RANGE = 403;
|
20 |
+
|
21 |
protected $_attributesModel = null;
|
22 |
|
23 |
public function __construct() {
|
141 |
|
142 |
$collection = $catalogSearchModelCollection;
|
143 |
} else {
|
|
|
144 |
// initialize
|
145 |
$collection = Mage::getModel('catalog/product')->getCollection();
|
|
|
|
|
|
|
|
|
146 |
}
|
147 |
|
148 |
|
149 |
+
$collection->addStoreFilter()
|
150 |
+
->addMinimalPrice()
|
151 |
+
->addFinalPrice()
|
152 |
+
->addTaxPercents()
|
153 |
+
->distinct(true);
|
154 |
+
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
|
155 |
+
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
|
156 |
|
157 |
|
158 |
$categoryNotSet = false;
|
164 |
|
165 |
$category = Mage::getModel('catalog/category')->load($categoryId);
|
166 |
if ($category->getId() === NULL) {
|
167 |
+
return self::PRODUCTS_ERROR_NOT_FOUND;
|
168 |
}
|
169 |
|
170 |
// apply search
|
180 |
$range = array(0, self::RANGE_FALLBACK_RANGE);
|
181 |
}
|
182 |
|
183 |
+
if ($range[1] > self::RANGE_LIMIT) {
|
184 |
+
return self::PRODUCTS_ERROR_OUT_OF_RANGE;
|
185 |
+
}
|
186 |
+
|
187 |
$collection->getSelect()->limit($range[1], $range[0]);
|
188 |
|
189 |
$attributesArray = array();
|
203 |
|
204 |
//apply filters
|
205 |
if(!empty($filters)) {
|
206 |
+
$collection = $this->_filterProductsCollection($collection, $filters);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
}
|
208 |
|
209 |
// Add 'out of stock' filter, if preffered
|
210 |
if (!Mage::getStoreConfig('cataloginventory/options/show_out_of_stock')) {
|
211 |
Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collection);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
}
|
213 |
|
214 |
// Apply type filter, we only want Simple and Configurable and Bundle products in our API
|
224 |
* Format result array
|
225 |
*/
|
226 |
$products = array('products' => array());
|
227 |
+
|
228 |
// If range requests no products to be returned, return no products. The limit() doesn't take 0 for an answer
|
229 |
if ($range[1] > 0) {
|
230 |
if (!$hideAttributes) {
|
302 |
$range = array(0, self::RANGE_FALLBACK_RANGE);
|
303 |
}
|
304 |
|
305 |
+
if ($range[1] > self::RANGE_LIMIT) {
|
306 |
+
return self::PRODUCTS_ERROR_OUT_OF_RANGE;
|
307 |
+
}
|
308 |
+
|
309 |
$collection->getSelect()->limit($range[1], $range[0]);
|
310 |
|
311 |
// Add 'out of stock' filter, if preffered
|
530 |
$result = $controller->createBlock($filterBlockName)->setLayer($layer)->setAttributeModel($attribute)->init();
|
531 |
$options = array();
|
532 |
foreach($result->getItems() as $option) {
|
533 |
+
|
534 |
+
array_push($options, $this->getFilterOptionValue($option));
|
|
|
|
|
|
|
535 |
}
|
536 |
|
537 |
if (count($options) > 1) {
|
555 |
*/
|
556 |
/***********************************/
|
557 |
|
558 |
+
/**
|
559 |
+
* Returns a formatted object for a given option item
|
560 |
+
* Made for subclassing
|
561 |
+
*
|
562 |
+
* @param $optionItem
|
563 |
+
* @return array
|
564 |
+
*
|
565 |
+
*/
|
566 |
+
protected function getFilterOptionValue($optionItem = null) {
|
567 |
+
if (!$optionItem) {
|
568 |
+
return;
|
569 |
+
}
|
570 |
+
|
571 |
+
$title = str_replace('<span class="price">', "", $optionItem->getLabel());
|
572 |
+
$title = str_replace('</span>', "", $title);
|
573 |
+
|
574 |
+
$count = $optionItem->getData('count');
|
575 |
+
|
576 |
+
return array('value' => $optionItem->getValue(), 'title' => $title, 'product_count' => $count);
|
577 |
+
}
|
578 |
+
|
579 |
/**
|
580 |
* Gets count for given collection. Function made for easier subclassing
|
581 |
*
|
654 |
return $collection;
|
655 |
}
|
656 |
|
657 |
+
/**
|
658 |
+
* Joins tables for attributes and adds given filters
|
659 |
+
* Inspired by the applyFilterToCollection function by the class Mage_Catalog_Model_Resource_Layer_Filter_Attribute
|
660 |
+
*
|
661 |
+
* @param mixed Collection
|
662 |
+
* @param array filters
|
663 |
+
* @return mixed Collection
|
664 |
+
*
|
665 |
+
*/
|
666 |
+
protected function _filterProductsCollection ($collection = null, $filters = array()) {
|
667 |
+
if ($collection === null || count($filters) <= 0) {
|
668 |
+
return $collection;
|
669 |
+
}
|
670 |
+
|
671 |
+
foreach ($filters as $filter) {
|
672 |
+
if (array_key_exists('attribute', $filter)) {
|
673 |
+
|
674 |
+
if ($filter['attribute'] === 'price') {
|
675 |
+
foreach ($filter as $operator => $value) {
|
676 |
+
if ($operator != 'attribute') {
|
677 |
+
$collection->addAttributeToFilter(array(array('attribute' => $filter['attribute'], $operator => $value)));
|
678 |
+
}
|
679 |
+
}
|
680 |
+
} else {
|
681 |
+
$attributeObject = $this->_attributesModel->getAttribute($filter['attribute'], false);
|
682 |
+
$resource = Mage::getSingleton('core/resource');
|
683 |
+
$connection = $resource->getConnection('default_read');
|
684 |
+
$tableAlias = $filter['attribute'] . '_idx';
|
685 |
+
$conditions = array(
|
686 |
+
"{$tableAlias}.entity_id = e.entity_id",
|
687 |
+
$connection->quoteInto("{$tableAlias}.attribute_id = ?", $attributeObject['id']),
|
688 |
+
$connection->quoteInto("{$tableAlias}.store_id = ?", $collection->getStoreId())
|
689 |
+
);
|
690 |
+
|
691 |
+
foreach ($filter as $operator => $filterValue) {
|
692 |
+
if ($operator != 'attribute') {
|
693 |
+
if (is_array($filterValue)) {
|
694 |
+
|
695 |
+
$whereString = "(";
|
696 |
+
$i = 0;
|
697 |
+
foreach ($filterValue as $value) {
|
698 |
+
if ($i >= count($filterValue)-1) {
|
699 |
+
$whereString .= $connection->quoteInto("{$tableAlias}.value = ?", $value);
|
700 |
+
} else {
|
701 |
+
$whereString .= $connection->quoteInto("{$tableAlias}.value = ?", $value) . ' OR ';
|
702 |
+
}
|
703 |
+
$i++;
|
704 |
+
}
|
705 |
+
$whereString .= ")";
|
706 |
+
|
707 |
+
array_push($conditions, $whereString);
|
708 |
+
|
709 |
+
} else {
|
710 |
+
array_push($conditions, $connection->quoteInto("{$tableAlias}.value = ?", $filterValue));
|
711 |
+
}
|
712 |
+
}
|
713 |
+
}
|
714 |
+
|
715 |
+
$collection->getSelect()->join(
|
716 |
+
array($tableAlias => $resource->getTableName('catalog/product_index_eav')),
|
717 |
+
implode(' AND ', $conditions),
|
718 |
+
array()
|
719 |
+
);
|
720 |
+
}
|
721 |
+
}
|
722 |
+
}
|
723 |
+
|
724 |
+
return $collection;
|
725 |
+
}
|
726 |
+
|
727 |
/**
|
728 |
*
|
729 |
* Gets attributes of a given product object.
|
947 |
|
948 |
// SEE: Mage_Catalog_Block_Product_View_Attributes
|
949 |
$controller = Mage::app()->getLayout();
|
950 |
+
$block = $controller->createBlock('catalog/product_view_attributes');
|
951 |
|
952 |
// Same function as used by the layouting
|
953 |
+
foreach ($block->getAdditionalData() as $attributeData) {
|
954 |
+
|
955 |
+
if ($attributeData['value'] === Mage::helper('catalog')->__('No') || $attributeData['value'] === Mage::helper('catalog')->__('N/A')) {
|
956 |
+
continue;
|
957 |
+
}
|
958 |
+
|
959 |
+
|
960 |
+
$html .= "<p><strong>".$attributeData['label'].":</strong></br>".$attributeData['value']."</p>";
|
961 |
}
|
962 |
|
963 |
$additionalAttributeData['inline_value'] = $html;
|
969 |
continue;
|
970 |
}
|
971 |
|
972 |
+
if ($attribute === "tax_price") {
|
973 |
+
$additionalAttributeData = array();
|
974 |
+
$additionalAttributeData['title'] = "Price with tax";
|
975 |
+
$additionalAttributeData['code'] = "tax_price";
|
976 |
+
$additionalAttributeData['type'] = "number";
|
977 |
+
$additionalAttributeData['inline_value'] = Mage::helper('tax')->getPrice($resProduct, $resProduct->getFinalPrice(), true);
|
978 |
+
$response[] = $additionalAttributeData;
|
979 |
+
|
980 |
+
continue;
|
981 |
+
}
|
982 |
+
|
983 |
$attributeObject = $resProduct->getResource()->getAttribute($attribute);
|
984 |
|
985 |
if ($attributeObject !== false) {
|
1170 |
|
1171 |
$output = array();
|
1172 |
|
1173 |
+
$resProduct = Mage::getModel('catalog/product')->load($productId);
|
1174 |
+
foreach ($resProduct->getMediaGalleryImages()->getItems() as $key => $value) {
|
1175 |
$imageData = $value->getData();
|
1176 |
|
1177 |
+
$resProduct = false;
|
1178 |
if ($this->_shouldExcludeImageFromMediaGallery($imageData["file"], $resProduct)) {
|
1179 |
continue;
|
1180 |
}
|
1223 |
"special_from_date", "special_to_date", "special_price", "is_salable");
|
1224 |
}
|
1225 |
|
1226 |
+
}
|
app/code/local/Highstreet/Hsapi/Model/Session.php
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Highstreet_Hsapi_Model_Session extends Mage_Core_Model_Session {
|
4 |
+
|
5 |
+
protected $_externalRoute = array("hsapi/checkoutV3/external", "hsapi/redirect/setCookie");
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Configure and start session
|
9 |
+
*
|
10 |
+
* @param string $sessionName
|
11 |
+
* @return Mage_Core_Model_Session_Abstract_Varien
|
12 |
+
*/
|
13 |
+
public function start($sessionName = null) {
|
14 |
+
if ($this->strstr_array($this->_externalRoute, $_SERVER['REQUEST_URI']) !== false) {
|
15 |
+
$_SESSION['frontend'] = array();
|
16 |
+
}
|
17 |
+
parent::start($sessionName);
|
18 |
+
return $this;
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* strstr function for searching arrays
|
23 |
+
*
|
24 |
+
* @param array || string $routes
|
25 |
+
* @param string $url
|
26 |
+
* @return strstr
|
27 |
+
*/
|
28 |
+
public function strstr_array($routes, $url) {
|
29 |
+
if (!is_array($routes)) {
|
30 |
+
return strstr($url, $routes);
|
31 |
+
}
|
32 |
+
foreach ($routes as $route) {
|
33 |
+
if (strstr($url, $route)) {
|
34 |
+
return $route;
|
35 |
+
}
|
36 |
+
}
|
37 |
+
return false;
|
38 |
+
}
|
39 |
+
|
40 |
+
}
|
app/code/local/Highstreet/Hsapi/Model/System/Config/Stores.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Highstreet_Hsapi_Model_System_Config_Stores {
|
4 |
+
public function toOptionArray()
|
5 |
+
{
|
6 |
+
$stores = Mage::app()->getStores();
|
7 |
+
$options = array();
|
8 |
+
$options[] = array('value' => "-1",'label' => Mage::helper('highstreet_hsapi')->__('Current store'));
|
9 |
+
foreach ($stores as $store) {
|
10 |
+
$storeCode = $store->getCode();
|
11 |
+
$storeId = $store->getId();
|
12 |
+
|
13 |
+
$options[] = array('value' => $storeId,'label' => $storeCode);
|
14 |
+
|
15 |
+
}
|
16 |
+
|
17 |
+
return $options;
|
18 |
+
}
|
19 |
+
}
|
app/code/local/Highstreet/Hsapi/controllers/AccountController.php
ADDED
@@ -0,0 +1,282 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Highstreet_HSAPI_module
|
5 |
+
*
|
6 |
+
* @package Highstreet_Hsapi
|
7 |
+
* @author Radovan Dodic (radovan.dodic@atessoft.rs) ~ AtesSoft
|
8 |
+
* @copyright Copyright (c) 2016 Highstreet
|
9 |
+
*/
|
10 |
+
class Highstreet_Hsapi_AccountController extends Mage_Core_Controller_Front_Action {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @return Highstreet_Hsapi_Helper_Config_Account
|
14 |
+
*/
|
15 |
+
private function _getHelper() {
|
16 |
+
return Mage::helper('highstreet_hsapi/config_account');
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @return Highstreet_Hsapi_Helper_Config_Checkout
|
21 |
+
*/
|
22 |
+
private function _getCheckoutHelper() {
|
23 |
+
return Mage::helper('highstreet_hsapi/config_checkout');
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* detects request method
|
28 |
+
* method: POST, GET, PATCH
|
29 |
+
* body: JSON
|
30 |
+
* Content-Type: application/json
|
31 |
+
*/
|
32 |
+
public function indexAction() {
|
33 |
+
$method = $_SERVER['REQUEST_METHOD'];
|
34 |
+
if (!$this->_getHelper()->_checkIsRequestValid($this->getRequest())) {
|
35 |
+
return;
|
36 |
+
} else {
|
37 |
+
switch ($method) {
|
38 |
+
case 'POST':
|
39 |
+
$this->createUser();
|
40 |
+
break;
|
41 |
+
case 'GET':
|
42 |
+
$this->viewUser();
|
43 |
+
break;
|
44 |
+
case 'PATCH':
|
45 |
+
$this->updateUser();
|
46 |
+
break;
|
47 |
+
}
|
48 |
+
}
|
49 |
+
return;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Create Magento user
|
54 |
+
* method: POST
|
55 |
+
* body: JSON
|
56 |
+
* Content-Type: application/json
|
57 |
+
*/
|
58 |
+
protected function createUser() {
|
59 |
+
$request = $this->getRequest();
|
60 |
+
$params = $this->_getHelper()->_JSONtoArray($request->getRawBody());
|
61 |
+
if (!$this->_getHelper()->_checkCreateAccountFields($params))
|
62 |
+
return;
|
63 |
+
|
64 |
+
// create Magento user
|
65 |
+
$websiteId = Mage::app()->getWebsite()->getId();
|
66 |
+
$store = Mage::app()->getStore();
|
67 |
+
$email = (isset($params['email'])) ? $params['email'] : $params['handle'];
|
68 |
+
|
69 |
+
$customer = Mage::getModel("customer/customer");
|
70 |
+
$customer->setWebsiteId($websiteId)
|
71 |
+
->setStore($store)
|
72 |
+
->setFirstname($params['first_name'])
|
73 |
+
->setLastname($params['last_name'])
|
74 |
+
->setEmail($email)
|
75 |
+
->setPassword($params['password']);
|
76 |
+
try {
|
77 |
+
$customer->save();
|
78 |
+
$customer->setConfirmation(null);
|
79 |
+
$customer->save();
|
80 |
+
$this->_getHelper()->_sendEmailTemplate($customer);
|
81 |
+
} catch (Exception $e) {
|
82 |
+
$this->_getHelper()->logException($e, 'Customer save');
|
83 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => $e->getMessage()));
|
84 |
+
return;
|
85 |
+
}
|
86 |
+
$this->_getHelper()->_JSONencodeAndRespond(array(
|
87 |
+
"id" => $customer->getId(),
|
88 |
+
"email" => $customer->getEmail(),
|
89 |
+
'handle' => $customer->getEmail(),
|
90 |
+
'first_name' => $customer->getFirstname(),
|
91 |
+
'last_name' => $customer->getLastname(),
|
92 |
+
), "201 Created");
|
93 |
+
return;
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* checks Authorization from header
|
98 |
+
* not used function !!!
|
99 |
+
* @return bool/string
|
100 |
+
*/
|
101 |
+
protected function _checkAuth() {
|
102 |
+
if ($this->getRequest()->getHeader('Authorization') == '') {
|
103 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => "No authorization code"), "401 Unauthorized");
|
104 |
+
return false;
|
105 |
+
}
|
106 |
+
return substr($this->getRequest()->getHeader('Authorization'), 7);
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* View Magento user data
|
111 |
+
* Validate user from session token and session files
|
112 |
+
* method: GET
|
113 |
+
* body: JSON
|
114 |
+
* Content-Type: application/json
|
115 |
+
* Authorization: frontend cookie, Magento authorization
|
116 |
+
*/
|
117 |
+
protected function viewUser() {
|
118 |
+
if ($this->_getHelper()->isLoggedIn()) {
|
119 |
+
if ($customerId = $this->_getHelper()->_getCId()) {
|
120 |
+
$customer = Mage::getModel('customer/customer')->load($customerId);
|
121 |
+
|
122 |
+
$data = $this->_getHelper()->getCustomerData($customer);
|
123 |
+
|
124 |
+
// get Primary Billing Address
|
125 |
+
$primaryBillingAddress = $customer->getPrimaryBillingAddress();
|
126 |
+
if ($primaryBillingAddress) {
|
127 |
+
$address = $this->_getHelper()->getAddressData($primaryBillingAddress);
|
128 |
+
} else {
|
129 |
+
$addresses = $customer->getAddresses();
|
130 |
+
if (count($addresses)) {
|
131 |
+
foreach ($addresses as $adr) {
|
132 |
+
$address = $this->_getHelper()->getAddressData($adr);
|
133 |
+
// only first address
|
134 |
+
continue;
|
135 |
+
}
|
136 |
+
}
|
137 |
+
}
|
138 |
+
$data['address'] = (isset($address)) ? $address : array();
|
139 |
+
} else {
|
140 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => "Session expired"), "401 Unauthorized");
|
141 |
+
return;
|
142 |
+
}
|
143 |
+
} else {
|
144 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => "Session expired"), "401 Unauthorized");
|
145 |
+
return;
|
146 |
+
}
|
147 |
+
$this->_getHelper()->_JSONencodeAndRespond($data, "200 OK");
|
148 |
+
return;
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Update Magento user data
|
153 |
+
* Validate user from session token and session files
|
154 |
+
* method: PATCH
|
155 |
+
* body: JSON
|
156 |
+
* Content-Type: application/json
|
157 |
+
* Authorization: Bearer valid_token
|
158 |
+
*/
|
159 |
+
protected function updateUser() {
|
160 |
+
if ($this->_getHelper()->isLoggedIn()) {
|
161 |
+
if ($customerId = $this->_getHelper()->_getCId()) {
|
162 |
+
$customer = Mage::getModel('customer/customer')->load($customerId);
|
163 |
+
$params = $this->_getHelper()->_JSONtoArray($this->getRequest()->getRawBody());
|
164 |
+
|
165 |
+
if (!$this->_getHelper()->_checkUpdateAccountFields($params))
|
166 |
+
return;
|
167 |
+
|
168 |
+
$userChanged = false;
|
169 |
+
// update user FirstName if needed
|
170 |
+
if (isset($params['first_name'])) {
|
171 |
+
$customer->setFirstname($params['first_name']);
|
172 |
+
$userChanged = true;
|
173 |
+
}
|
174 |
+
// update user LasttName if needed
|
175 |
+
if (isset($params['last_name'])) {
|
176 |
+
$customer->setLastname($params['last_name']);
|
177 |
+
$userChanged = true;
|
178 |
+
}
|
179 |
+
// update user email if needed
|
180 |
+
if (isset($params['email'])) {
|
181 |
+
$customer->setEmail($params['email']);
|
182 |
+
$userChanged = true;
|
183 |
+
}
|
184 |
+
|
185 |
+
// update customer if any field is changed - less SQL resources in use
|
186 |
+
if ($userChanged) {
|
187 |
+
try {
|
188 |
+
$customer->save();
|
189 |
+
} catch (Exception $e) {
|
190 |
+
$this->_getHelper()->logException($e, 'Customer update');
|
191 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => $e->getMessage()));
|
192 |
+
return;
|
193 |
+
}
|
194 |
+
}
|
195 |
+
|
196 |
+
// update or add address if address is set in json
|
197 |
+
if (isset($params['address'])) {
|
198 |
+
if (isset($params['address']['id']) && is_numeric($params['address']['id'])) {
|
199 |
+
$address = Mage::getModel('customer/address')->load($params['address']['id']);
|
200 |
+
if ($address->getId()) {
|
201 |
+
$address->setId($params['address']['id']);
|
202 |
+
} else {
|
203 |
+
// if address ID is invalidor missing, we assume user is adding new default address
|
204 |
+
$address->setIsDefaultBilling('1')
|
205 |
+
->setIsDefaultShipping('1');
|
206 |
+
}
|
207 |
+
} else {
|
208 |
+
// if address ID is invalidor missing, we assume user is adding new default address
|
209 |
+
$address = Mage::getModel("customer/address");
|
210 |
+
$address->setIsDefaultBilling('1')
|
211 |
+
->setIsDefaultShipping('1');
|
212 |
+
}
|
213 |
+
// fix for diffrent street line settings
|
214 |
+
$params = $this->_getHelper()->fixStreetLines($params);
|
215 |
+
|
216 |
+
$address->setCustomerId($customerId)
|
217 |
+
->setFirstname($params['address']['first_name'])
|
218 |
+
->setLastname($params['address']['last_name'])
|
219 |
+
->setCountryId($params['address']['country_id'])
|
220 |
+
->setCity($params['address']['city'])
|
221 |
+
->setTelephone($params['address']['telephone'])
|
222 |
+
->setStreet(
|
223 |
+
array(
|
224 |
+
'0' => $params['address']['street'],
|
225 |
+
'1' => $params['address']['house_number'],
|
226 |
+
'2' => $params['address']['addition']
|
227 |
+
))
|
228 |
+
->setSaveInAddressBook('1');
|
229 |
+
if (isset($params['address']['postal_code']))
|
230 |
+
$address->setPostcode($params['address']['postal_code']);
|
231 |
+
if (isset($params['address']['state']))
|
232 |
+
$address->setRegion($params['address']['state']);
|
233 |
+
if (isset($params['address']['company']))
|
234 |
+
$address->setCompany($params['address']['company']);
|
235 |
+
|
236 |
+
try {
|
237 |
+
$address->save();
|
238 |
+
} catch (Exception $e) {
|
239 |
+
$this->_getHelper()->logException($e, 'Address add / update');
|
240 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => $e->getMessage()));
|
241 |
+
return;
|
242 |
+
}
|
243 |
+
} // endif address is set
|
244 |
+
} else {
|
245 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => "Session expired"), "401 Unauthorized");
|
246 |
+
return;
|
247 |
+
}
|
248 |
+
} else {
|
249 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => "Session expired"), "401 Unauthorized");
|
250 |
+
return;
|
251 |
+
}
|
252 |
+
|
253 |
+
$data = $this->_getHelper()->getCustomerData($customer);
|
254 |
+
if (isset($params['address'])) {
|
255 |
+
$addressArray = $this->_getHelper()->getAddressData($address);
|
256 |
+
$data['address'] = $addressArray;
|
257 |
+
}
|
258 |
+
$this->_getHelper()->_JSONencodeAndRespond($data, "200 OK");
|
259 |
+
return;
|
260 |
+
}
|
261 |
+
|
262 |
+
/**
|
263 |
+
* Logout action
|
264 |
+
*/
|
265 |
+
public function logoutAction() {
|
266 |
+
$this->_getHelper()->logout();
|
267 |
+
return;
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* Logs the user in. Gets the parameters "email" and "password" from POST
|
272 |
+
*
|
273 |
+
* @author Tim Wachter
|
274 |
+
*
|
275 |
+
*/
|
276 |
+
public function loginAction() {
|
277 |
+
$requestObject = Mage::app()->getRequest();
|
278 |
+
$this->_getHelper()->login($requestObject);
|
279 |
+
return;
|
280 |
+
}
|
281 |
+
|
282 |
+
}
|
app/code/local/Highstreet/Hsapi/controllers/CartController.php
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Highstreet_HSAPI_module
|
5 |
+
*
|
6 |
+
* @package Highstreet_Hsapi
|
7 |
+
* @author Radovan Dodic (radovan.dodic@atessoft.rs) ~ AtesSoft
|
8 |
+
* @copyright Copyright (c) 2016 Highstreet
|
9 |
+
*/
|
10 |
+
class Highstreet_Hsapi_CartController extends Mage_Core_Controller_Front_Action {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @return Highstreet_Hsapi_Helper_Config_Cart
|
14 |
+
*/
|
15 |
+
private function _getHelper() {
|
16 |
+
return Mage::helper('highstreet_hsapi/config_cart');
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* detects request method
|
21 |
+
* method: POST, GET, PATCH
|
22 |
+
* body: JSON
|
23 |
+
* Content-Type: application/json
|
24 |
+
*/
|
25 |
+
public function indexAction() {
|
26 |
+
$method = $_SERVER['REQUEST_METHOD'];
|
27 |
+
$request = $this->getRequest();
|
28 |
+
$_errors = array();
|
29 |
+
if (!$this->_getHelper()->_checkIsRequestValid($request)) {
|
30 |
+
return;
|
31 |
+
} else {
|
32 |
+
// initialize cart before everything
|
33 |
+
if ($method == "POST")
|
34 |
+
$this->_getHelper()->cartInit();
|
35 |
+
$response = "200 OK";
|
36 |
+
if ($method == 'PUT') {
|
37 |
+
$etag = $request->getHeader('If-Match');
|
38 |
+
if ($etag && $etag != $this->_getHelper()->getCartEtag()) {
|
39 |
+
$response = "412 Precondition failed";
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
// check if there are some unavailable products, and remove them
|
44 |
+
if ($method == "GET")
|
45 |
+
$_errors = $this->_getHelper()->checkAndUpdateCartInventory($_errors);
|
46 |
+
|
47 |
+
$params = $this->_getHelper()->_JSONtoArray($request->getRawBody());
|
48 |
+
|
49 |
+
// add products and coupon codes if method is POST or PUT
|
50 |
+
if (count($params) && ($method == "POST" || $method == "PUT"))
|
51 |
+
$_errors = $this->_getHelper()->addProductsAndCouponsToQuote($params);
|
52 |
+
|
53 |
+
$this->_getHelper()->saveCartAndQuote();
|
54 |
+
|
55 |
+
// get data for JSON
|
56 |
+
$data = $this->_getData($_errors, $params, $method);
|
57 |
+
|
58 |
+
// assign quote item id to errors
|
59 |
+
$data = $this->_getHelper()->assignQuoteItemIdToErrors($data, $params);
|
60 |
+
|
61 |
+
// log data if logger is enabled
|
62 |
+
if ($this->_getHelper()->isLogEnabled()) {
|
63 |
+
$this->_getHelper()->log(array(
|
64 |
+
"Response code" => $response,
|
65 |
+
"Method" => $method,
|
66 |
+
"Data" => $data), 'Cart indexAction');
|
67 |
+
}
|
68 |
+
|
69 |
+
$this->_getHelper()->_JSONencodeAndRespond($data, $response);
|
70 |
+
}
|
71 |
+
return;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* get $data array
|
76 |
+
*
|
77 |
+
* @param array $_errors
|
78 |
+
* @param array $params
|
79 |
+
* @param string $method
|
80 |
+
* @return array
|
81 |
+
*/
|
82 |
+
protected function _getData($_errors = array(), $params = array(), $method) {
|
83 |
+
$request = $this->getRequest();
|
84 |
+
$cart = $this->_getHelper()->_getCart();
|
85 |
+
$data = array();
|
86 |
+
|
87 |
+
// add etag to body
|
88 |
+
$data['cart_etag'] = Mage::helper('highstreet_hsapi/config_cart')->getCartEtag();
|
89 |
+
// add quote id
|
90 |
+
$data['id'] = $this->_getHelper()->_getQuote()->getId();
|
91 |
+
// add errors
|
92 |
+
$data['_errors'] = $_errors;
|
93 |
+
// add messages
|
94 |
+
$data['_messages'] = array();
|
95 |
+
// add products
|
96 |
+
$data['items'] = $this->_getHelper()->getProductsFromCart($params);
|
97 |
+
// add coupon code
|
98 |
+
$data['coupon_codes'] = $this->_getHelper()->getCouponCodes();
|
99 |
+
// add tax included
|
100 |
+
$data['tax_included'] = $this->_getHelper()->isTaxIncluded();
|
101 |
+
// add totals
|
102 |
+
$data['totals'] = $this->_getHelper()->getTotals();
|
103 |
+
|
104 |
+
return $data;
|
105 |
+
}
|
106 |
+
|
107 |
+
}
|
app/code/local/Highstreet/Hsapi/controllers/CheckoutController.php
CHANGED
@@ -151,9 +151,18 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
|
|
151 |
if (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1) {
|
152 |
$result['goto_section'] = 'shipping_method';
|
153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
$result['update_section'] = array(
|
155 |
'name' => 'shipping-method',
|
156 |
-
'data' => $
|
157 |
);
|
158 |
|
159 |
$result['allow_sections'] = array('shipping');
|
@@ -180,11 +189,20 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
|
|
180 |
|
181 |
$result = $this->getOnepage()->saveShipping($data, $customerAddressId);
|
182 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
if (!isset($result['error'])) {
|
184 |
$result['goto_section'] = 'shipping_method';
|
185 |
$result['update_section'] = array(
|
186 |
'name' => 'shipping-method',
|
187 |
-
'data' => $
|
188 |
);
|
189 |
}
|
190 |
$this->_JSONencodeAndRespond($result);
|
@@ -207,13 +225,20 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
|
|
207 |
$this->getOnepage()->getQuote()->collectTotals();
|
208 |
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
|
209 |
|
210 |
-
$
|
211 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
|
213 |
-
$result['goto_section'] = 'payment';
|
214 |
$result['update_section'] = array(
|
215 |
'name' => 'payment-method',
|
216 |
-
'data' => $
|
217 |
);
|
218 |
}
|
219 |
$this->getOnepage()->getQuote()->collectTotals()->save();
|
@@ -401,7 +426,7 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
|
|
401 |
return Mage::getSingleton('checkout/type_onepage');
|
402 |
}
|
403 |
|
404 |
-
|
405 |
$shippingMethods = array();
|
406 |
|
407 |
$shouldGetPostNL = true;
|
@@ -412,10 +437,18 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
|
|
412 |
|
413 |
$cif = Mage::getModel('postnl_deliveryoptions/cif');
|
414 |
if ($cif) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
415 |
$postNlOptions = $cif->setStoreId(Mage::app()->getStore()->getId())
|
416 |
->getDeliveryTimeframes(array(
|
417 |
'postcode' => str_replace(" ", "", $shippingAddressData["postcode"]), // Postcode
|
418 |
-
'housenumber' =>
|
419 |
'deliveryDate' => date('d-m-Y', strtotime('+ 1 day')), // Set delivery day to tomorrow
|
420 |
));
|
421 |
} else {
|
@@ -447,6 +480,7 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
|
|
447 |
$shippingMethod['price'] = $_rate->getData('price');
|
448 |
$shippingMethod['code'] = $_rate->getCode();
|
449 |
$shippingMethod['checked'] = $checked;
|
|
|
450 |
|
451 |
if (strstr($_rate->getCode(), "postnl") !== false) {
|
452 |
$shippingMethod['sub_options'] = $postNlOptions;
|
@@ -460,7 +494,7 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
|
|
460 |
return $shippingMethods;
|
461 |
}
|
462 |
|
463 |
-
|
464 |
$paymentMethods = array();
|
465 |
|
466 |
$model = new Mage_Checkout_Block_Onepage_Payment_Methods();
|
@@ -491,6 +525,7 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
|
|
491 |
$object["checked"] = $checked;
|
492 |
|
493 |
$object["sub_options"] = $this->_getSuboptionsForPaymentMethod($method);
|
|
|
494 |
|
495 |
$paymentMethods[] = $object;
|
496 |
}
|
@@ -624,11 +659,11 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
|
|
624 |
protected function _JSONencodeAndRespond($data, $numericCheck = true) {
|
625 |
//set response body
|
626 |
$this->_setHeader();
|
627 |
-
if ($
|
628 |
$this->getResponse()->setBody(json_encode($data));
|
629 |
} else {
|
630 |
$this->getResponse()->setBody(json_encode($data, JSON_NUMERIC_CHECK));
|
631 |
}
|
632 |
|
633 |
}
|
634 |
-
}
|
151 |
if (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1) {
|
152 |
$result['goto_section'] = 'shipping_method';
|
153 |
|
154 |
+
$shippingMethods = $this->_getShippingMethods();
|
155 |
+
|
156 |
+
Mage::dispatchEvent(
|
157 |
+
'highstreet_hsapi_checkout_shipping_methods_after',
|
158 |
+
array(
|
159 |
+
'shipping_methods' => &$shippingMethods,
|
160 |
+
'quote' => $this->getOnepage()->getQuote(),
|
161 |
+
'request' => $this->getRequest()));
|
162 |
+
|
163 |
$result['update_section'] = array(
|
164 |
'name' => 'shipping-method',
|
165 |
+
'data' => $shippingMethods
|
166 |
);
|
167 |
|
168 |
$result['allow_sections'] = array('shipping');
|
189 |
|
190 |
$result = $this->getOnepage()->saveShipping($data, $customerAddressId);
|
191 |
|
192 |
+
$shippingMethods = $this->_getShippingMethods();
|
193 |
+
|
194 |
+
Mage::dispatchEvent(
|
195 |
+
'highstreet_hsapi_checkout_shipping_methods_after',
|
196 |
+
array(
|
197 |
+
'shipping_methods' => &$shippingMethods,
|
198 |
+
'quote' => $this->getOnepage()->getQuote(),
|
199 |
+
'request' => $this->getRequest()));
|
200 |
+
|
201 |
if (!isset($result['error'])) {
|
202 |
$result['goto_section'] = 'shipping_method';
|
203 |
$result['update_section'] = array(
|
204 |
'name' => 'shipping-method',
|
205 |
+
'data' => $shippingMethods
|
206 |
);
|
207 |
}
|
208 |
$this->_JSONencodeAndRespond($result);
|
225 |
$this->getOnepage()->getQuote()->collectTotals();
|
226 |
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
|
227 |
|
228 |
+
$result['goto_section'] = 'payment';
|
229 |
|
230 |
+
$paymentMethods = $this->_getPaymentMethods();
|
231 |
+
|
232 |
+
Mage::dispatchEvent(
|
233 |
+
'highstreet_hsapi_checkout_payment_methods_after',
|
234 |
+
array(
|
235 |
+
'payment_methods' => &$paymentMethods,
|
236 |
+
'quote' => $this->getOnepage()->getQuote(),
|
237 |
+
'request' => $this->getRequest()));
|
238 |
|
|
|
239 |
$result['update_section'] = array(
|
240 |
'name' => 'payment-method',
|
241 |
+
'data' => $paymentMethods
|
242 |
);
|
243 |
}
|
244 |
$this->getOnepage()->getQuote()->collectTotals()->save();
|
426 |
return Mage::getSingleton('checkout/type_onepage');
|
427 |
}
|
428 |
|
429 |
+
protected function _getShippingMethods() {
|
430 |
$shippingMethods = array();
|
431 |
|
432 |
$shouldGetPostNL = true;
|
437 |
|
438 |
$cif = Mage::getModel('postnl_deliveryoptions/cif');
|
439 |
if ($cif) {
|
440 |
+
|
441 |
+
preg_match('([0-9]+)', $shippingAddressData["street"], $matches);
|
442 |
+
$housenumber = 1; //default to 1.
|
443 |
+
if(isset($matches) && count($matches) > 0) {
|
444 |
+
$housenumber = $matches[0];
|
445 |
+
}
|
446 |
+
|
447 |
+
|
448 |
$postNlOptions = $cif->setStoreId(Mage::app()->getStore()->getId())
|
449 |
->getDeliveryTimeframes(array(
|
450 |
'postcode' => str_replace(" ", "", $shippingAddressData["postcode"]), // Postcode
|
451 |
+
'housenumber' => $housenumber,
|
452 |
'deliveryDate' => date('d-m-Y', strtotime('+ 1 day')), // Set delivery day to tomorrow
|
453 |
));
|
454 |
} else {
|
480 |
$shippingMethod['price'] = $_rate->getData('price');
|
481 |
$shippingMethod['code'] = $_rate->getCode();
|
482 |
$shippingMethod['checked'] = $checked;
|
483 |
+
$shippingMethod['custom_fields'] = array();
|
484 |
|
485 |
if (strstr($_rate->getCode(), "postnl") !== false) {
|
486 |
$shippingMethod['sub_options'] = $postNlOptions;
|
494 |
return $shippingMethods;
|
495 |
}
|
496 |
|
497 |
+
protected function _getPaymentMethods() {
|
498 |
$paymentMethods = array();
|
499 |
|
500 |
$model = new Mage_Checkout_Block_Onepage_Payment_Methods();
|
525 |
$object["checked"] = $checked;
|
526 |
|
527 |
$object["sub_options"] = $this->_getSuboptionsForPaymentMethod($method);
|
528 |
+
$object["custom_fields"] = array();
|
529 |
|
530 |
$paymentMethods[] = $object;
|
531 |
}
|
659 |
protected function _JSONencodeAndRespond($data, $numericCheck = true) {
|
660 |
//set response body
|
661 |
$this->_setHeader();
|
662 |
+
if ($numericCheck === FALSE || version_compare(PHP_VERSION, '5.3.3', '<')) {
|
663 |
$this->getResponse()->setBody(json_encode($data));
|
664 |
} else {
|
665 |
$this->getResponse()->setBody(json_encode($data, JSON_NUMERIC_CHECK));
|
666 |
}
|
667 |
|
668 |
}
|
669 |
+
}
|
app/code/local/Highstreet/Hsapi/controllers/CheckoutV3Controller.php
ADDED
@@ -0,0 +1,536 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Highstreet_HSAPI_module
|
5 |
+
*
|
6 |
+
* @package Highstreet_Hsapi
|
7 |
+
* @author Radovan Dodic (radovan.dodic@atessoft.rs) ~ AtesSoft
|
8 |
+
* @copyright Copyright (c) 2016 Highstreet
|
9 |
+
*/
|
10 |
+
class Highstreet_Hsapi_CheckoutV3Controller extends Mage_Core_Controller_Front_Action {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* detects request method
|
14 |
+
* method: POST, GET, PATCH
|
15 |
+
* body: JSON
|
16 |
+
* Content-Type: application/json
|
17 |
+
*/
|
18 |
+
public function indexAction() {
|
19 |
+
$method = $_SERVER['REQUEST_METHOD'];
|
20 |
+
if (!$this->_getHelper()->_checkIsRequestValid($this->getRequest())) {
|
21 |
+
return;
|
22 |
+
} else {
|
23 |
+
switch ($method) {
|
24 |
+
case 'POST':
|
25 |
+
$this->createCheckoutSession();
|
26 |
+
break;
|
27 |
+
case 'GET':
|
28 |
+
$this->viewCheckoutSession();
|
29 |
+
break;
|
30 |
+
case 'PATCH':
|
31 |
+
$this->updateCheckoutSession();
|
32 |
+
break;
|
33 |
+
}
|
34 |
+
}
|
35 |
+
return;
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* returns shipping methods
|
40 |
+
* method: GET
|
41 |
+
* body: JSON
|
42 |
+
* Content-Type: application/json
|
43 |
+
*/
|
44 |
+
public function shipping_methodsAction() {
|
45 |
+
$method = $_SERVER['REQUEST_METHOD'];
|
46 |
+
if (!$this->_getHelper()->_checkIsRequestValid($this->getRequest())) {
|
47 |
+
return;
|
48 |
+
}
|
49 |
+
$cart = Mage::getSingleton('checkout/cart');
|
50 |
+
$address = $cart->getQuote()->getShippingAddress();
|
51 |
+
if ($address->getQuoteId() && $address->getFirstname()) {
|
52 |
+
$jsonMethods = $this->_getHelper()->getShippingMethods($address, $cart->getQuote());
|
53 |
+
} else {
|
54 |
+
$jsonMethods = $this->_getHelper()->getAllShippingMethods();
|
55 |
+
}
|
56 |
+
|
57 |
+
Mage::dispatchEvent(
|
58 |
+
'highstreet_hsapi_checkoutV3_shipping_methods_after', array(
|
59 |
+
'shipping_methods' => &$jsonMethods,
|
60 |
+
'quote' => $this->_getOnepage()->getQuote(),
|
61 |
+
'request' => $this->getRequest()
|
62 |
+
)
|
63 |
+
);
|
64 |
+
$this->_getHelper()->_JSONencodeAndRespond($jsonMethods, "200 OK");
|
65 |
+
return;
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* returns payment methods
|
70 |
+
* method: GET
|
71 |
+
* body: JSON
|
72 |
+
* Content-Type: application/json
|
73 |
+
*/
|
74 |
+
public function payment_methodsAction() {
|
75 |
+
$method = $_SERVER['REQUEST_METHOD'];
|
76 |
+
if (!$this->_getHelper()->_checkIsRequestValid($this->getRequest())) {
|
77 |
+
return;
|
78 |
+
}
|
79 |
+
$paymentMethods = $this->_getHelper()->getAllPaymentMethods();
|
80 |
+
|
81 |
+
Mage::dispatchEvent(
|
82 |
+
'highstreet_hsapi_checkoutV3_payment_methods_after', array(
|
83 |
+
'payment_methods' => &$paymentMethods,
|
84 |
+
'quote' => $this->_getOnepage()->getQuote(),
|
85 |
+
'request' => $this->getRequest()
|
86 |
+
)
|
87 |
+
);
|
88 |
+
|
89 |
+
$this->_getHelper()->_JSONencodeAndRespond($paymentMethods, "200 OK");
|
90 |
+
return;
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* returns shipping countries
|
95 |
+
* method: GET
|
96 |
+
* body: JSON
|
97 |
+
* Content-Type: application/json
|
98 |
+
*/
|
99 |
+
public function shipping_countriesAction() {
|
100 |
+
$method = $_SERVER['REQUEST_METHOD'];
|
101 |
+
if (!$this->_getHelper()->_checkIsRequestValid($this->getRequest())) {
|
102 |
+
return;
|
103 |
+
}
|
104 |
+
|
105 |
+
$this->_getHelper()->getShippingCountries();
|
106 |
+
return;
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* @return Highstreet_Hsapi_Helper_Config_Checkout
|
111 |
+
*/
|
112 |
+
private function _getHelper() {
|
113 |
+
return Mage::helper('highstreet_hsapi/config_checkout');
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* @return Highstreet_Hsapi_Helper_Config_Redirect
|
118 |
+
*/
|
119 |
+
private function _getRedirectHelper() {
|
120 |
+
return Mage::helper('highstreet_hsapi/config_redirect');
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* @return Highstreet_Hsapi_Helper_Config_Cart
|
125 |
+
*/
|
126 |
+
private function _getCartHelper() {
|
127 |
+
return Mage::helper('highstreet_hsapi/config_cart');
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* @return Mage_Checkout_Model_Type_Onepage
|
132 |
+
*/
|
133 |
+
protected function _getOnepage() {
|
134 |
+
return Mage::getSingleton('checkout/type_onepage');
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* @return Mage_Customer_Model_Session
|
139 |
+
*/
|
140 |
+
protected function _getSession() {
|
141 |
+
return Mage::getSingleton('customer/session');
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* @return Mage_Checkout_Model_Session
|
146 |
+
*/
|
147 |
+
protected function _getCheckoutSession() {
|
148 |
+
return Mage::getSingleton('checkout/session');
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Update checkout session
|
153 |
+
* method: PATCH
|
154 |
+
* Content-Type: application/json
|
155 |
+
*/
|
156 |
+
protected function updateCheckoutSession() {
|
157 |
+
$request = $this->getRequest();
|
158 |
+
if (!$this->_getHelper()->_checkIsRequestValid($request, array('PATCH'))) {
|
159 |
+
return;
|
160 |
+
}
|
161 |
+
$quote = $this->_getOnepage()->getQuote();
|
162 |
+
$params = $this->_getHelper()->_JSONtoArray($request->getRawBody());
|
163 |
+
$invalidFields = array();
|
164 |
+
$missingFields = array();
|
165 |
+
|
166 |
+
//email is set only if customer is not logged in... Logged customers already have email preset.
|
167 |
+
if (isset($params['email']) && !$this->_getHelper()->isLoggedIn()) {
|
168 |
+
try {
|
169 |
+
$email = $params['email'];
|
170 |
+
if ($this->_getHelper()->checkIsEmailValid($email)) {
|
171 |
+
$quote->setCustomerEmail($params['email']);
|
172 |
+
$quote->save();
|
173 |
+
} else {
|
174 |
+
$invalidFields[] = 'email';
|
175 |
+
}
|
176 |
+
} catch (Exception $e) {
|
177 |
+
$this->_getHelper()->logException($e, 'Unable to set Email address');
|
178 |
+
$error = $this->__('Unable to set Email address');
|
179 |
+
}
|
180 |
+
if (isset($error)) {
|
181 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => $error), "200 OK");
|
182 |
+
return;
|
183 |
+
}
|
184 |
+
}
|
185 |
+
|
186 |
+
// set billing address
|
187 |
+
if (isset($params['addresses']['billing_address']) && $params['addresses']['billing_address'] != null && $params['addresses']['billing_address'] != 'null') {
|
188 |
+
if (!$quote->getCustomerEmail()) {
|
189 |
+
$error = $this->__('Please fill in email address');
|
190 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => $error), "200 OK");
|
191 |
+
return;
|
192 |
+
}
|
193 |
+
try {
|
194 |
+
$billingAddress = $params['addresses']['billing_address'];
|
195 |
+
$billingAddress['use_same_for_shipping'] = (isset($params['addresses']['shipping_address']) && $params['addresses']['shipping_address'] != null && $params['addresses']['shipping_address'] != 'null') ? 0 : 1;
|
196 |
+
if ($quote->getCustomerEmail())
|
197 |
+
$billingAddress['email'] = $quote->getCustomerEmail();
|
198 |
+
if ($this->_getHelper()->checkRequiredAddressFields($billingAddress, true)) {
|
199 |
+
$this->_getHelper()->setBillingAddressToQuote($billingAddress);
|
200 |
+
// save with billing info
|
201 |
+
$quote->save();
|
202 |
+
// save again after calculating new totals
|
203 |
+
$quote->collectTotals();
|
204 |
+
if ($billingAddress['use_same_for_shipping'])
|
205 |
+
$quote->getShippingAddress()->setCollectShippingRates(true);
|
206 |
+
$quote->save();
|
207 |
+
} else {
|
208 |
+
$invalidFields[] = "billing_address";
|
209 |
+
if ($params['addresses']['shipping_address'] == null || $params['addresses']['shipping_address'] == 'null')
|
210 |
+
$invalidFields[] = "shipping_address";
|
211 |
+
}
|
212 |
+
} catch (Exception $e) {
|
213 |
+
$this->_getHelper()->logException($e, 'Unable to set Billing address');
|
214 |
+
$error = $this->__('Unable to set Billing address');
|
215 |
+
}
|
216 |
+
if (isset($error)) {
|
217 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => $error), "200 OK");
|
218 |
+
return;
|
219 |
+
}
|
220 |
+
}
|
221 |
+
// set shipping address
|
222 |
+
if (isset($params['addresses']['shipping_address']) && $params['addresses']['shipping_address'] != null && $params['addresses']['shipping_address'] != 'null') {
|
223 |
+
if (!$quote->getCustomerEmail()) {
|
224 |
+
$error = $this->__('Please fill in email address');
|
225 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => $error), "200 OK");
|
226 |
+
return;
|
227 |
+
}
|
228 |
+
try {
|
229 |
+
$shipping_address = $params['addresses']['shipping_address'];
|
230 |
+
if ($quote->getCustomerEmail())
|
231 |
+
$shipping_address['email'] = $quote->getCustomerEmail();
|
232 |
+
if ($this->_getHelper()->checkRequiredAddressFields($shipping_address, true)) {
|
233 |
+
$this->_getHelper()->setShippingAddressToQuote($shipping_address);
|
234 |
+
// save
|
235 |
+
$quote->save();
|
236 |
+
// save again after calculating new totals
|
237 |
+
$quote->collectTotals();
|
238 |
+
$quote->getShippingAddress()->setCollectShippingRates(true)->save();
|
239 |
+
} else {
|
240 |
+
$invalidFields[] = "shipping_address";
|
241 |
+
}
|
242 |
+
} catch (Exception $e) {
|
243 |
+
$this->_getHelper()->logException($e, 'Unable to set Billing address');
|
244 |
+
$error = $this->__('Unable to set Shipping address');
|
245 |
+
}
|
246 |
+
if (isset($error)) {
|
247 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => $error), "200 OK");
|
248 |
+
return;
|
249 |
+
}
|
250 |
+
}
|
251 |
+
|
252 |
+
|
253 |
+
// set shipping method - depends on shipping address
|
254 |
+
if (isset($params['shipping_method']) && $params['shipping_method'] != 'null' && $params['shipping_method'] != null) {
|
255 |
+
try {
|
256 |
+
$this->_getSession()->setPostNLData(null);
|
257 |
+
$shippingMethod = $params['shipping_method'];
|
258 |
+
if ($this->_getHelper()->checkIsShippingMethodValid($shippingMethod['code'])) {
|
259 |
+
if ($quote->getShippingAddress()->getSameAsBilling() || $quote->getShippingAddress()->getFirstname()) {
|
260 |
+
// check if shipping is postNl and it has suboption set
|
261 |
+
if (strstr($shippingMethod['code'], "postnl") && isset($shippingMethod['options']['code'])) {
|
262 |
+
$postNLdata = json_decode($this->_getHelper()->b64d($shippingMethod['options']['code']), true);
|
263 |
+
$this->_getSession()->setPostNLData($shippingMethod['options']['code']);
|
264 |
+
// code taken from PostNl controller DeliveryOptionsController
|
265 |
+
/** @var TIG_PostNL_Model_DeliveryOptions_Service $service */
|
266 |
+
$service = Mage::getModel('postnl_deliveryoptions/service');
|
267 |
+
$service->saveDeliveryOption($postNLdata);
|
268 |
+
}
|
269 |
+
$quote->getShippingAddress()->setCollectShippingRates(true)->collectShippingRates();
|
270 |
+
$result = $this->_getOnepage()->saveShippingMethod($shippingMethod['code']);
|
271 |
+
if ($result) {
|
272 |
+
$error = $this->__('Unable to set shipping method');
|
273 |
+
}
|
274 |
+
$quote->collectTotals()->save();
|
275 |
+
} else {
|
276 |
+
$error = $this->__('Unable to set shipping method without shipping address');
|
277 |
+
}
|
278 |
+
} else {
|
279 |
+
$invalidFields[] = 'shipping_method';
|
280 |
+
}
|
281 |
+
} catch (Exception $e) {
|
282 |
+
$this->_getHelper()->logException($e, 'Unable to set shipping method');
|
283 |
+
$error = $this->__('Unable to set shipping method');
|
284 |
+
}
|
285 |
+
if (isset($error)) {
|
286 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => $error), "200 OK");
|
287 |
+
return;
|
288 |
+
}
|
289 |
+
}
|
290 |
+
|
291 |
+
// set coupon codes
|
292 |
+
if (isset($params['coupon_codes']) && $params['coupon_codes'] != 'null' && $params['coupon_codes'] != null) {
|
293 |
+
try {
|
294 |
+
if (isset($params['coupon_codes'][0]['code']) && strlen($params['coupon_codes'][0]['code']) <= $this->_getCartHelper()->getCouponMaxLenght()) {
|
295 |
+
$couponCode = $params['coupon_codes'][0]['code'];
|
296 |
+
$oCoupon = Mage::getModel('salesrule/coupon')->load($couponCode, 'code');
|
297 |
+
if ($oCoupon->getRuleId()) {
|
298 |
+
$quote = Mage::getSingleton('checkout/cart')->getQuote();
|
299 |
+
$quote->getShippingAddress()->setCollectShippingRates(true);
|
300 |
+
$quote->setCouponCode($couponCode)
|
301 |
+
->collectTotals()
|
302 |
+
->save();
|
303 |
+
}
|
304 |
+
if ($couponCode != $quote->getCouponCode()) {
|
305 |
+
$invalidFields[] = 'coupon_codes';
|
306 |
+
} else {
|
307 |
+
$this->_getCartHelper()->updateCartEtag();
|
308 |
+
}
|
309 |
+
} else {
|
310 |
+
$invalidFields[] = 'coupon_codes';
|
311 |
+
}
|
312 |
+
} catch (Exception $e) {
|
313 |
+
$this->_getHelper()->logException($e, 'Unable to set coupon code');
|
314 |
+
$error = $this->__('Unable to set coupon code');
|
315 |
+
}
|
316 |
+
if (isset($error)) {
|
317 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => $error), "200 OK");
|
318 |
+
return;
|
319 |
+
}
|
320 |
+
} elseif (isset($params['coupon_codes']) && $params['coupon_codes'] == null) {
|
321 |
+
// remove coupon codes
|
322 |
+
$quote = Mage::getSingleton('checkout/cart')->getQuote();
|
323 |
+
$quote->getShippingAddress()->setCollectShippingRates(true);
|
324 |
+
$quote->setCouponCode(null)
|
325 |
+
->collectTotals()
|
326 |
+
->save();
|
327 |
+
}
|
328 |
+
|
329 |
+
// set payment method
|
330 |
+
if (isset($params['payment_method']) && isset($params['payment_method']['code'])) {
|
331 |
+
try {
|
332 |
+
$payment = array('method' => $params['payment_method']['code']);
|
333 |
+
if ($this->_getHelper()->checkIsPaymentMethodValid($payment['method'])) {
|
334 |
+
// add additionl payment options, example: Adyen_Ideal bank id
|
335 |
+
$payment = $this->_getHelper()->addAdditionalPaymentOptions($payment, $params);
|
336 |
+
$result = $this->_getOnepage()->savePayment($payment);
|
337 |
+
if (isset($result['error'])) {
|
338 |
+
Mage::log($result);
|
339 |
+
$invalidFields[] = 'payment_method';
|
340 |
+
} else {
|
341 |
+
// set options to session like Buckaroo BPE Issuer
|
342 |
+
if (isset($params['payment_method']['options']['code'])) {
|
343 |
+
$this->_getCheckoutSession()->setData('additionalFields', array('Issuer' => $params['payment_method']['options']['code']));
|
344 |
+
}
|
345 |
+
}
|
346 |
+
} else {
|
347 |
+
$invalidFields[] = 'payment_method';
|
348 |
+
}
|
349 |
+
} catch (Exception $e) {
|
350 |
+
$this->_getHelper()->logException($e, 'Unable to set Payment Method');
|
351 |
+
$error = $this->__('Unable to set Payment Method.');
|
352 |
+
}
|
353 |
+
if (isset($error)) {
|
354 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => $error), "200 OK");
|
355 |
+
return;
|
356 |
+
}
|
357 |
+
}
|
358 |
+
|
359 |
+
|
360 |
+
$this->viewCheckoutSession('200 OK', $invalidFields, $missingFields);
|
361 |
+
return;
|
362 |
+
}
|
363 |
+
|
364 |
+
/**
|
365 |
+
* View checkout session
|
366 |
+
* method: GET
|
367 |
+
* Content-Type: application/json
|
368 |
+
* @param string $response
|
369 |
+
* @param array $invalidFields
|
370 |
+
* @param array $missingFields
|
371 |
+
* @return json
|
372 |
+
*/
|
373 |
+
protected function viewCheckoutSession($response = "200 OK", $invalidFields = array(), $missingFields = array()) {
|
374 |
+
// call function saveCartAndQuote() just in case so collectTotals is calculated
|
375 |
+
$this->_getCartHelper()->saveCartAndQuote();
|
376 |
+
$request = $this->getRequest();
|
377 |
+
$quote = $this->_getOnepage()->getQuote();
|
378 |
+
$billAddress = $quote->getBillingAddress();
|
379 |
+
$shipAddress = $quote->getShippingAddress();
|
380 |
+
//populate fields
|
381 |
+
$data = array(
|
382 |
+
"id" => $quote->getId(),
|
383 |
+
"cart_etag" => Mage::helper('highstreet_hsapi/config_cart')->getCartEtag(),
|
384 |
+
"email" => $quote->getCustomerEmail(),
|
385 |
+
"payment_method" => ($quote->getPayment()->getMethod()) ? $this->_getHelper()->getPaymentMethod($quote->getPayment()->getMethod()) : null,
|
386 |
+
"shipping_method" => ($shipAddress->getQuoteId() && $shipAddress->getShippingMethod()) ? $this->_getHelper()->getShippingMethod($shipAddress->getShippingMethod()) : null,
|
387 |
+
"coupon_codes" => ($quote->getCouponCode()) ? array(array('code' => $quote->getCouponCode())) : array(),
|
388 |
+
"addresses" => array(
|
389 |
+
"billing_address" => ($billAddress->getQuoteId() && $billAddress->getFirstname()) ? $this->_getHelper()->getAddressData($billAddress) : null,
|
390 |
+
"shipping_address" => ($shipAddress->getQuoteId() && !$shipAddress->getSameAsBilling() && $shipAddress->getFirstname()) ? $this->_getHelper()->getAddressData($shipAddress) : null,
|
391 |
+
),
|
392 |
+
"tax_included" => ($shipAddress && $shipAddress->getTaxAmount()) ? true : false,
|
393 |
+
"totals" => $this->_getCartHelper()->getTotals(),
|
394 |
+
);
|
395 |
+
|
396 |
+
// shipping and billing address missing errors
|
397 |
+
if ($data['addresses']['billing_address'] == null)
|
398 |
+
$missingFields[] = "billing_address";
|
399 |
+
if (($data['addresses']['billing_address'] == null && $data['addresses']['shipping_address'] == null) || ($data['addresses']['shipping_address'] == null && !$shipAddress->getSameAsBilling()) || ($data['addresses']['shipping_address'] == null && in_array('shipping_address', $invalidFields)))
|
400 |
+
$missingFields[] = "shipping_address";
|
401 |
+
// check missing fields
|
402 |
+
$data = $this->_getHelper()->checkMissingInvalidFields($data, $invalidFields, $missingFields);
|
403 |
+
// log data if logging is enabled
|
404 |
+
if ($this->_getHelper()->isLogEnabled()) {
|
405 |
+
$this->_getHelper()->log(array(
|
406 |
+
"Response code" => $response,
|
407 |
+
"Data array for JSON" => $data), 'View checkout session');
|
408 |
+
}
|
409 |
+
$this->_getHelper()->_JSONencodeAndRespond($data, $response);
|
410 |
+
return;
|
411 |
+
}
|
412 |
+
|
413 |
+
/**
|
414 |
+
* Create checkout session
|
415 |
+
* method: POST
|
416 |
+
* Content-Type: application/json
|
417 |
+
*/
|
418 |
+
protected function createCheckoutSession() {
|
419 |
+
//Can be used to determine elsewhere in the code whether this is a checkout session initiated in the app.
|
420 |
+
Mage::getSingleton('checkout/session')->setIsHighstreetCheckoutSession(true);
|
421 |
+
|
422 |
+
|
423 |
+
$request = $this->getRequest();
|
424 |
+
if (!$this->_getHelper()->_checkIsRequestValid($request, array('POST'))) {
|
425 |
+
return;
|
426 |
+
}
|
427 |
+
$quote = $this->_getOnepage()->getQuote();
|
428 |
+
$params = $this->_getHelper()->_JSONtoArray($request->getRawBody());
|
429 |
+
if (!isset($params['cart_id']) || $params['cart_id'] != $quote->getId()) {
|
430 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => "cart_id is not set or do not match"));
|
431 |
+
return;
|
432 |
+
}
|
433 |
+
if (!isset($params['cart_etag']) || $params['cart_etag'] != Mage::helper('highstreet_hsapi/config_cart')->getCartEtag()) {
|
434 |
+
$this->_getHelper()->_JSONencodeAndRespond(array("title" => "Error", "content" => "cart_etag is not set or do not match"), "409"); // or 412 ???
|
435 |
+
return;
|
436 |
+
}
|
437 |
+
|
438 |
+
$customer = $this->_getSession()->getCustomer();
|
439 |
+
$isLoggedIn = $this->_getSession()->isLoggedIn();
|
440 |
+
|
441 |
+
if ($isLoggedIn) {
|
442 |
+
$defaultBillingAddressId = $customer->getDefaultBilling();
|
443 |
+
$defaultShippingAddressId = $customer->getDefaultShipping();
|
444 |
+
if ($defaultBillingAddressId > 0) {
|
445 |
+
$billingAddress = $customer->getAddressById($defaultBillingAddressId);
|
446 |
+
// if email is not pre set, do it now
|
447 |
+
if (!$this->_getOnepage()->getQuote()->getCustomerEmail() && $customer->getEmail())
|
448 |
+
$this->_getOnepage()->getQuote()->setCustomerEmail($customer->getEmail());
|
449 |
+
$this->_getOnepage()->getQuote()->getBillingAddress()->importCustomerAddress($billingAddress);
|
450 |
+
$this->_getOnepage()->getQuote()->getShippingAddress()->importCustomerAddress($billingAddress);
|
451 |
+
$this->_getOnepage()->getQuote()->getShippingAddress()->setSameAsBilling(1);
|
452 |
+
$this->_getOnepage()->getQuote()->getShippingAddress()->setCollectShippingRates(true);
|
453 |
+
if ($defaultBillingAddressId != $defaultShippingAddressId) {
|
454 |
+
$shippingAddress = $customer->getAddressById($defaultShippingAddressId);
|
455 |
+
$this->_getOnepage()->getQuote()->getShippingAddress()->importCustomerAddress($shippingAddress);
|
456 |
+
$this->_getOnepage()->getQuote()->getShippingAddress()->setSameAsBilling(0);
|
457 |
+
$this->_getOnepage()->getQuote()->getShippingAddress()->setCollectShippingRates(true);
|
458 |
+
}
|
459 |
+
}
|
460 |
+
$quote->setCheckoutMethod('customer')->save();
|
461 |
+
} else {
|
462 |
+
$quote->setCheckoutMethod('guest')->save();
|
463 |
+
}
|
464 |
+
$this->viewCheckoutSession();
|
465 |
+
return;
|
466 |
+
}
|
467 |
+
|
468 |
+
/**
|
469 |
+
* Finalize checkout and create order
|
470 |
+
* method: POST
|
471 |
+
* body: tid
|
472 |
+
* Content-Type: application/json
|
473 |
+
*/
|
474 |
+
public function finalizeAction() {
|
475 |
+
$request = $this->getRequest();
|
476 |
+
if (!$this->_getHelper()->_checkIsRequestValid($request, array('POST'))) {
|
477 |
+
return;
|
478 |
+
}
|
479 |
+
$params = $this->_getHelper()->_JSONtoArray($request->getRawBody());
|
480 |
+
if (!isset($params['tid'])) {
|
481 |
+
$this->_getHelper()->_fieldError(Highstreet_Hsapi_Helper_Config_Account::MISSING, 'tid');
|
482 |
+
return;
|
483 |
+
}
|
484 |
+
Mage::getSingleton('checkout/session')->setHsTid($params['tid']);
|
485 |
+
$result = array();
|
486 |
+
$quote = $this->_getOnepage()->getQuote();
|
487 |
+
try {
|
488 |
+
$quote->collectTotals()->save();
|
489 |
+
$this->_getOnepage()->saveOrder();
|
490 |
+
$redirectUrl = $this->_getOnepage()->getCheckout()->getRedirectUrl();
|
491 |
+
} catch (Mage_Payment_Model_Info_Exception $e) {
|
492 |
+
$this->_getHelper()->logException($e, 'Finalize Checkout - Mage_Payment_Model_Info_Exception');
|
493 |
+
// if payment method is not valid return ViewCheckout session with all missing fields
|
494 |
+
$this->viewCheckoutSession('400 Bad Request');
|
495 |
+
return;
|
496 |
+
} catch (Mage_Core_Exception $e) {
|
497 |
+
$this->_getHelper()->logException($e, 'Finalize Checkout - Mage_Core_Exception');
|
498 |
+
Mage::helper('checkout')->sendPaymentFailedEmail($this->_getOnepage()->getQuote(), $e->getMessage());
|
499 |
+
// if payment method via Core functions is not valid return ViewCheckout session with all missing fields
|
500 |
+
$this->viewCheckoutSession('400 Bad Request');
|
501 |
+
return;
|
502 |
+
} catch (Exception $e) {
|
503 |
+
// if anything goes wrong, return proccessing error, log exception
|
504 |
+
$this->_getHelper()->logException($e, 'Finalize Checkout');
|
505 |
+
Mage::helper('checkout')->sendPaymentFailedEmail($this->_getOnepage()->getQuote(), $e->getMessage());
|
506 |
+
$this->_getHelper()->_JSONencodeAndRespond($this->__('There was an error processing your order. Please contact us or try again later.'), "400 Bad Request");
|
507 |
+
return;
|
508 |
+
}
|
509 |
+
$this->_getOnepage()->getQuote()->save();
|
510 |
+
$result['hpp'] = null;
|
511 |
+
if (isset($redirectUrl)) {
|
512 |
+
$result['hpp'] = $redirectUrl;
|
513 |
+
}
|
514 |
+
|
515 |
+
$this->_getHelper()->_JSONencodeAndRespond($result, "200 Ok");
|
516 |
+
}
|
517 |
+
|
518 |
+
/**
|
519 |
+
* External checkout
|
520 |
+
* method: POST
|
521 |
+
* POST_param: tid
|
522 |
+
* POST_param: session
|
523 |
+
* Content-Type: application/json
|
524 |
+
*/
|
525 |
+
public function externalAction() {
|
526 |
+
$requestObject = Mage::app()->getRequest();
|
527 |
+
|
528 |
+
// get decoded path from reuest and set cookies
|
529 |
+
$decodedPath = $this->_getRedirectHelper()->getPathAndSetCookies($requestObject);
|
530 |
+
|
531 |
+
// redirect to web checkout
|
532 |
+
if ($decodedPath)
|
533 |
+
Mage::app()->getResponse()->setRedirect($redirectUrl)->sendResponse();
|
534 |
+
}
|
535 |
+
|
536 |
+
}
|
app/code/local/Highstreet/Hsapi/controllers/IndexController.php
CHANGED
@@ -104,6 +104,7 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
104 |
"magento_version" => (string)Mage::getVersion(),
|
105 |
"environment" => $configApi->environment(),
|
106 |
"storefront" => Mage::app()->getStore()->getCode(),
|
|
|
107 |
"attributes_sort_order_setting_raw" => $configApi->attributesSortOrderRaw()));
|
108 |
}
|
109 |
|
@@ -301,9 +302,12 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
301 |
$requestObject->getParam('include_configuration_details'),
|
302 |
$requestObject->getParam('include_media_gallery'));
|
303 |
|
304 |
-
if ($products ==
|
305 |
$this->_respondWith404();
|
306 |
return false;
|
|
|
|
|
|
|
307 |
}
|
308 |
|
309 |
$this->_JSONencodeAndRespond($products);
|
@@ -321,6 +325,11 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
321 |
$productObjects = array();
|
322 |
if ($requestObject->getParam('ids') != "") {
|
323 |
$idsArray = explode(',', $requestObject->getParam('ids'));
|
|
|
|
|
|
|
|
|
|
|
324 |
|
325 |
foreach ($idsArray as $value) {
|
326 |
$productObject = Mage::getModel('catalog/product')->load($value);
|
@@ -369,8 +378,8 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
369 |
$requestObject->getParam('include_configuration_details'),
|
370 |
$requestObject->getParam('include_media_gallery'));
|
371 |
|
372 |
-
if ($response ==
|
373 |
-
$this->
|
374 |
return false;
|
375 |
}
|
376 |
|
@@ -468,6 +477,13 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
468 |
return;
|
469 |
}
|
470 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
471 |
protected function _respondWith404()
|
472 |
{
|
473 |
$this->getResponse()->setHeader('HTTP/1.1','404 Not Found');
|
104 |
"magento_version" => (string)Mage::getVersion(),
|
105 |
"environment" => $configApi->environment(),
|
106 |
"storefront" => Mage::app()->getStore()->getCode(),
|
107 |
+
"street_line_number" => Mage::getStoreConfig('customer/address/street_lines'),
|
108 |
"attributes_sort_order_setting_raw" => $configApi->attributesSortOrderRaw()));
|
109 |
}
|
110 |
|
302 |
$requestObject->getParam('include_configuration_details'),
|
303 |
$requestObject->getParam('include_media_gallery'));
|
304 |
|
305 |
+
if ($products == $model::PRODUCTS_ERROR_NOT_FOUND) {
|
306 |
$this->_respondWith404();
|
307 |
return false;
|
308 |
+
} else if ($products == $model::PRODUCTS_ERROR_OUT_OF_RANGE) {
|
309 |
+
$this->_respondWith403();
|
310 |
+
return false;
|
311 |
}
|
312 |
|
313 |
$this->_JSONencodeAndRespond($products);
|
325 |
$productObjects = array();
|
326 |
if ($requestObject->getParam('ids') != "") {
|
327 |
$idsArray = explode(',', $requestObject->getParam('ids'));
|
328 |
+
if (count($idsArray) >= Highstreet_Hsapi_Model_Products::RANGE_LIMIT) {
|
329 |
+
$this->_JSONencodeAndRespond(array());
|
330 |
+
return false;
|
331 |
+
}
|
332 |
+
|
333 |
|
334 |
foreach ($idsArray as $value) {
|
335 |
$productObject = Mage::getModel('catalog/product')->load($value);
|
378 |
$requestObject->getParam('include_configuration_details'),
|
379 |
$requestObject->getParam('include_media_gallery'));
|
380 |
|
381 |
+
if ($response == $productsModel::PRODUCTS_ERROR_OUT_OF_RANGE) {
|
382 |
+
$this->_respondWith403();
|
383 |
return false;
|
384 |
}
|
385 |
|
477 |
return;
|
478 |
}
|
479 |
|
480 |
+
protected function _respondWith403()
|
481 |
+
{
|
482 |
+
$this->getResponse()->setHeader('HTTP/1.1','403 Forbidden');
|
483 |
+
$this->getResponse()->sendHeaders();
|
484 |
+
return;
|
485 |
+
}
|
486 |
+
|
487 |
protected function _respondWith404()
|
488 |
{
|
489 |
$this->getResponse()->setHeader('HTTP/1.1','404 Not Found');
|
app/code/local/Highstreet/Hsapi/controllers/RedirectController.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Highstreet_HSAPI_module
|
5 |
+
*
|
6 |
+
* @package Highstreet_Hsapi
|
7 |
+
* @author Radovan Dodic (radovan.dodic@atessoft.rs) ~ AtesSoft
|
8 |
+
* @copyright Copyright (c) 2016 Highstreet
|
9 |
+
*/
|
10 |
+
class Highstreet_Hsapi_RedirectController extends Mage_Core_Controller_Front_Action {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @return Highstreet_Hsapi_Helper_Config_Redirect
|
14 |
+
*/
|
15 |
+
private function _getHelper() {
|
16 |
+
return Mage::helper('highstreet_hsapi/config_redirect');
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* External checkout
|
21 |
+
* method: POST
|
22 |
+
* POST_param: tid
|
23 |
+
* POST_param: session
|
24 |
+
* Content-Type: application/json
|
25 |
+
*/
|
26 |
+
public function setCookieAction() {
|
27 |
+
$requestObject = Mage::app()->getRequest();
|
28 |
+
|
29 |
+
// get decoded path from reuest and set cookies
|
30 |
+
$decodedPath = $this->_getHelper()->getPathAndSetCookies($requestObject, false);
|
31 |
+
|
32 |
+
// redirect to web checkout
|
33 |
+
if ($decodedPath)
|
34 |
+
Mage::app()->getResponse()->setRedirect($decodedPath)->sendResponse();
|
35 |
+
}
|
36 |
+
|
37 |
+
}
|
app/code/local/Highstreet/Hsapi/etc/config.xml
CHANGED
@@ -1,17 +1,17 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<!--
|
3 |
/**
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
<config>
|
12 |
<modules>
|
13 |
<Highstreet_Hsapi>
|
14 |
-
<version>1.
|
15 |
</Highstreet_Hsapi>
|
16 |
</modules>
|
17 |
<frontend>
|
@@ -30,6 +30,11 @@
|
|
30 |
<highstreet_hsapi>
|
31 |
<class>Highstreet_Hsapi_Model</class>
|
32 |
</highstreet_hsapi>
|
|
|
|
|
|
|
|
|
|
|
33 |
</models>
|
34 |
<helpers>
|
35 |
<highstreet_hsapi>
|
@@ -48,8 +53,8 @@
|
|
48 |
</setup>
|
49 |
</highstreet_hsapi_setup>
|
50 |
</resources>
|
51 |
-
<events>
|
52 |
-
|
53 |
<observers>
|
54 |
<highstreet_hsapi_merge_quote>
|
55 |
<type>singleton</type>
|
@@ -57,8 +62,8 @@
|
|
57 |
<method>mergeQuote</method>
|
58 |
</highstreet_hsapi_merge_quote>
|
59 |
</observers>
|
60 |
-
|
61 |
-
|
62 |
<observers>
|
63 |
<highstreet_hsapi_sales_order_place_after>
|
64 |
<class>Highstreet_Hsapi_Model_Observer</class>
|
@@ -77,12 +82,47 @@
|
|
77 |
<sales_order_invoice_cancel>
|
78 |
<observers>
|
79 |
<highstreet_hsapi_sales_order_invoice_cancel>
|
80 |
-
|
81 |
-
|
82 |
</highstreet_hsapi_sales_order_invoice_cancel>
|
83 |
</observers>
|
84 |
</sales_order_invoice_cancel>
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
</global>
|
87 |
<adminhtml>
|
88 |
<acl>
|
1 |
<?xml version="1.0"?>
|
2 |
<!--
|
3 |
/**
|
4 |
+
* Highstreet_HSAPI_module
|
5 |
+
*
|
6 |
+
* @package Highstreet_Hsapi
|
7 |
+
* @author Tim Wachter (tim@touchwonders.com) ~ Touchwonders
|
8 |
+
* @copyright Copyright (c) 2015 Touchwonders b.v. (http://www.touchwonders.com/)
|
9 |
+
*/
|
10 |
+
-->
|
11 |
<config>
|
12 |
<modules>
|
13 |
<Highstreet_Hsapi>
|
14 |
+
<version>1.7.0</version>
|
15 |
</Highstreet_Hsapi>
|
16 |
</modules>
|
17 |
<frontend>
|
30 |
<highstreet_hsapi>
|
31 |
<class>Highstreet_Hsapi_Model</class>
|
32 |
</highstreet_hsapi>
|
33 |
+
<core>
|
34 |
+
<rewrite>
|
35 |
+
<session>Highstreet_Hsapi_Model_Session</session>
|
36 |
+
</rewrite>
|
37 |
+
</core>
|
38 |
</models>
|
39 |
<helpers>
|
40 |
<highstreet_hsapi>
|
53 |
</setup>
|
54 |
</highstreet_hsapi_setup>
|
55 |
</resources>
|
56 |
+
<events>
|
57 |
+
<sales_quote_merge_before>
|
58 |
<observers>
|
59 |
<highstreet_hsapi_merge_quote>
|
60 |
<type>singleton</type>
|
62 |
<method>mergeQuote</method>
|
63 |
</highstreet_hsapi_merge_quote>
|
64 |
</observers>
|
65 |
+
</sales_quote_merge_before>
|
66 |
+
<sales_order_place_after>
|
67 |
<observers>
|
68 |
<highstreet_hsapi_sales_order_place_after>
|
69 |
<class>Highstreet_Hsapi_Model_Observer</class>
|
82 |
<sales_order_invoice_cancel>
|
83 |
<observers>
|
84 |
<highstreet_hsapi_sales_order_invoice_cancel>
|
85 |
+
<class>Highstreet_Hsapi_Model_Observer</class>
|
86 |
+
<method>salesOrderInvoiceCancel</method>
|
87 |
</highstreet_hsapi_sales_order_invoice_cancel>
|
88 |
</observers>
|
89 |
</sales_order_invoice_cancel>
|
90 |
+
<!-- eTag update to quote and session object -->
|
91 |
+
<checkout_cart_product_add_after>
|
92 |
+
<observers>
|
93 |
+
<highstreet_hsapi_cart_etag_update>
|
94 |
+
<type>singleton</type>
|
95 |
+
<class>Highstreet_Hsapi_Model_CartObserver</class>
|
96 |
+
<method>cartEtagUpdate</method>
|
97 |
+
</highstreet_hsapi_cart_etag_update>
|
98 |
+
</observers>
|
99 |
+
</checkout_cart_product_add_after>
|
100 |
+
<sales_quote_remove_item>
|
101 |
+
<observers>
|
102 |
+
<highstreet_hsapi_cart_etag_update_remove>
|
103 |
+
<type>singleton</type>
|
104 |
+
<class>Highstreet_Hsapi_Model_CartObserver</class>
|
105 |
+
<method>cartEtagUpdate</method>
|
106 |
+
</highstreet_hsapi_cart_etag_update_remove>
|
107 |
+
</observers>
|
108 |
+
</sales_quote_remove_item>
|
109 |
+
<checkout_cart_update_items_after>
|
110 |
+
<observers>
|
111 |
+
<highstreet_hsapi_cart_etag_update_update>
|
112 |
+
<type>singleton</type>
|
113 |
+
<class>Highstreet_Hsapi_Model_CartObserver</class>
|
114 |
+
<method>cartEtagUpdate</method>
|
115 |
+
</highstreet_hsapi_cart_etag_update_update>
|
116 |
+
</observers>
|
117 |
+
</checkout_cart_update_items_after>
|
118 |
+
</events>
|
119 |
+
<default>
|
120 |
+
<highstreet_hsapi>
|
121 |
+
<api>
|
122 |
+
<checkout_override_storeview><![CDATA[-1]]></checkout_override_storeview>
|
123 |
+
</api>
|
124 |
+
</highstreet_hsapi>
|
125 |
+
</default>
|
126 |
</global>
|
127 |
<adminhtml>
|
128 |
<acl>
|
app/code/local/Highstreet/Hsapi/etc/system.xml
CHANGED
@@ -19,6 +19,14 @@
|
|
19 |
<show_in_website>1</show_in_website>
|
20 |
<show_in_store>1</show_in_store>
|
21 |
<fields>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
<store_id>
|
23 |
<label>Store identifier</label>
|
24 |
<comment>Your store identifier, e.g. your brand name</comment>
|
@@ -114,6 +122,15 @@
|
|
114 |
<show_in_website>1</show_in_website>
|
115 |
<show_in_store>1</show_in_store>
|
116 |
</checkout_redirect_url>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
<attribute_sort_order translate="label">
|
118 |
<label>Adjust the product sort order</label>
|
119 |
<comment>JSON encoded string, formatted as {"attribute_name":"sortorder",...}</comment>
|
@@ -123,8 +140,65 @@
|
|
123 |
<show_in_website>1</show_in_website>
|
124 |
<show_in_store>1</show_in_store>
|
125 |
</attribute_sort_order>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
</fields>
|
127 |
</api>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
</groups>
|
129 |
</highstreet_hsapi>
|
130 |
</sections>
|
19 |
<show_in_website>1</show_in_website>
|
20 |
<show_in_store>1</show_in_store>
|
21 |
<fields>
|
22 |
+
<heading_general>
|
23 |
+
<label><![CDATA[General Configuration]]></label>
|
24 |
+
<frontend_model>adminhtml/system_config_form_field_heading</frontend_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 |
+
</heading_general>
|
30 |
<store_id>
|
31 |
<label>Store identifier</label>
|
32 |
<comment>Your store identifier, e.g. your brand name</comment>
|
122 |
<show_in_website>1</show_in_website>
|
123 |
<show_in_store>1</show_in_store>
|
124 |
</checkout_redirect_url>
|
125 |
+
<checkout_override_storeview translate="label">
|
126 |
+
<label>The store view in which the orders should be saved</label>
|
127 |
+
<frontend_type>select</frontend_type>
|
128 |
+
<source_model>highstreet_hsapi/system_config_stores</source_model>
|
129 |
+
<sort_order>92</sort_order>
|
130 |
+
<show_in_default>1</show_in_default>
|
131 |
+
<show_in_website>1</show_in_website>
|
132 |
+
<show_in_store>1</show_in_store>
|
133 |
+
</checkout_override_storeview>
|
134 |
<attribute_sort_order translate="label">
|
135 |
<label>Adjust the product sort order</label>
|
136 |
<comment>JSON encoded string, formatted as {"attribute_name":"sortorder",...}</comment>
|
140 |
<show_in_website>1</show_in_website>
|
141 |
<show_in_store>1</show_in_store>
|
142 |
</attribute_sort_order>
|
143 |
+
<heading_account>
|
144 |
+
<label><![CDATA[New Account Configuration]]></label>
|
145 |
+
<frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
|
146 |
+
<sort_order>110</sort_order>
|
147 |
+
<show_in_default>1</show_in_default>
|
148 |
+
<show_in_website>1</show_in_website>
|
149 |
+
<show_in_store>1</show_in_store>
|
150 |
+
</heading_account>
|
151 |
+
<new_account_email_enabled>
|
152 |
+
<label>Send Custom New Account Email Template</label>
|
153 |
+
<show_in_default>1</show_in_default>
|
154 |
+
<show_in_website>1</show_in_website>
|
155 |
+
<show_in_store>1</show_in_store>
|
156 |
+
<sort_order>119</sort_order>
|
157 |
+
<frontend_type>select</frontend_type>
|
158 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
159 |
+
</new_account_email_enabled>
|
160 |
+
<new_account_email_template>
|
161 |
+
<label>New Account Email Template</label>
|
162 |
+
<show_in_default>1</show_in_default>
|
163 |
+
<show_in_website>1</show_in_website>
|
164 |
+
<show_in_store>1</show_in_store>
|
165 |
+
<sort_order>120</sort_order>
|
166 |
+
<frontend_type>select</frontend_type>
|
167 |
+
<source_model>adminhtml/system_config_source_email_template</source_model>
|
168 |
+
<depends>
|
169 |
+
<new_account_email_enabled>1</new_account_email_enabled>
|
170 |
+
</depends>
|
171 |
+
</new_account_email_template>
|
172 |
</fields>
|
173 |
</api>
|
174 |
+
<developer>
|
175 |
+
<label>Developer</label>
|
176 |
+
<frontend_type>text</frontend_type>
|
177 |
+
<sort_order>50</sort_order>
|
178 |
+
<show_in_default>1</show_in_default>
|
179 |
+
<show_in_website>1</show_in_website>
|
180 |
+
<show_in_store>1</show_in_store>
|
181 |
+
<fields>
|
182 |
+
<heading_general>
|
183 |
+
<label><![CDATA[Developer Options]]></label>
|
184 |
+
<frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
|
185 |
+
<sort_order>1</sort_order>
|
186 |
+
<show_in_default>1</show_in_default>
|
187 |
+
<show_in_website>1</show_in_website>
|
188 |
+
<show_in_store>1</show_in_store>
|
189 |
+
</heading_general>
|
190 |
+
<log_enabled translate="label">
|
191 |
+
<label>Enable Logging</label>
|
192 |
+
<comment>var/log/Highstreet_HSAPI.log</comment>
|
193 |
+
<frontend_type>select</frontend_type>
|
194 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
195 |
+
<sort_order>30</sort_order>
|
196 |
+
<show_in_default>1</show_in_default>
|
197 |
+
<show_in_website>1</show_in_website>
|
198 |
+
<show_in_store>1</show_in_store>
|
199 |
+
</log_enabled>
|
200 |
+
</fields>
|
201 |
+
</developer>
|
202 |
</groups>
|
203 |
</highstreet_hsapi>
|
204 |
</sections>
|
app/code/local/Highstreet/SmartAppBanner/etc/config.xml
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
<modules>
|
6 |
|
7 |
<Highstreet_SmartAppBanner>
|
8 |
-
<version>1.
|
9 |
</Highstreet_SmartAppBanner>
|
10 |
|
11 |
</modules>
|
5 |
<modules>
|
6 |
|
7 |
<Highstreet_SmartAppBanner>
|
8 |
+
<version>1.7.0</version>
|
9 |
</Highstreet_SmartAppBanner>
|
10 |
|
11 |
</modules>
|
app/design/frontend/base/default/template/highstreet/native_smart_app_banner.phtml
CHANGED
@@ -11,7 +11,7 @@ if ($configHelper->nativeSmartbannerAppUrl() != "") {
|
|
11 |
$product = Mage::registry('current_product');
|
12 |
$deeplink .= $product ? "products/" . $product->getId() . "/" : "";
|
13 |
|
14 |
-
$searchQuery = Mage::app()->getRequest()->getParam('q');
|
15 |
$deeplink .= $searchQuery ? "search/" . $searchQuery . "/" : "";
|
16 |
|
17 |
if ($deeplink === $configHelper->nativeSmartbannerAppUrl() . "://") {
|
11 |
$product = Mage::registry('current_product');
|
12 |
$deeplink .= $product ? "products/" . $product->getId() . "/" : "";
|
13 |
|
14 |
+
$searchQuery = $this->escapeHtml(Mage::app()->getRequest()->getParam('q'));
|
15 |
$deeplink .= $searchQuery ? "search/" . $searchQuery . "/" : "";
|
16 |
|
17 |
if ($deeplink === $configHelper->nativeSmartbannerAppUrl() . "://") {
|
app/design/frontend/base/default/template/highstreet/smart_app_banner.phtml
CHANGED
@@ -36,7 +36,7 @@ $content->category = $category ? $category->getId() : null;
|
|
36 |
$product = Mage::registry('current_product');
|
37 |
$content->product = $product ? $product->getId() : null;
|
38 |
|
39 |
-
$content->query = Mage::app()->getRequest()->getParam('q'
|
40 |
|
41 |
$content->version = Mage::getConfig()->getModuleConfig('Highstreet_SmartAppBanner')->version;
|
42 |
|
@@ -54,23 +54,13 @@ if ( in_array($config->module, $module_blacklist)
|
|
54 |
|
55 |
// Construct javascript url
|
56 |
$configHelper = Mage::helper('highstreet_hsapi/config_api');
|
57 |
-
$middleWareUrl = $configHelper->
|
58 |
-
$base_url = $middleWareUrl . "
|
59 |
-
$
|
60 |
-
$params = base64_url_encode(
|
61 |
|
62 |
$js_url = "${base_url}/${params}";
|
63 |
|
64 |
-
/**
|
65 |
-
* Returns an encrypted & utf8-encoded string
|
66 |
-
*/
|
67 |
-
function encrypt($pure_string, $encryption_key) {
|
68 |
-
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
|
69 |
-
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
|
70 |
-
$encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH, $encryption_key, utf8_encode($pure_string), MCRYPT_MODE_ECB, $iv);
|
71 |
-
return trim($encrypted_string);
|
72 |
-
}
|
73 |
-
|
74 |
/**
|
75 |
* Returns base64 url-safe encoded string
|
76 |
*/
|
36 |
$product = Mage::registry('current_product');
|
37 |
$content->product = $product ? $product->getId() : null;
|
38 |
|
39 |
+
$content->query = $this->escapeHtml(Mage::app()->getRequest()->getParam('q'));
|
40 |
|
41 |
$content->version = Mage::getConfig()->getModuleConfig('Highstreet_SmartAppBanner')->version;
|
42 |
|
54 |
|
55 |
// Construct javascript url
|
56 |
$configHelper = Mage::helper('highstreet_hsapi/config_api');
|
57 |
+
$middleWareUrl = '//' . $configHelper->middlewareHostAndUri();
|
58 |
+
$base_url = $middleWareUrl . "smartbanner";
|
59 |
+
$base_url = str_replace(Highstreet_Hsapi_Helper_Config_Api::MIDDLEWARE_URL_SCHEME, "//", $base_url); // Replace the scheme with '//' so that the browser always decides if this resource needs to be loaded over SSL or not
|
60 |
+
$params = base64_url_encode(json_encode($config));
|
61 |
|
62 |
$js_url = "${base_url}/${params}";
|
63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
/**
|
65 |
* Returns base64 url-safe encoded string
|
66 |
*/
|
package.xml
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Highstreet</name>
|
4 |
-
<version>1.
|
5 |
<stability>stable</stability>
|
6 |
<license>-</license>
|
7 |
<channel>community</channel>
|
@@ -10,10 +10,10 @@
|
|
10 |
<description>The extension provides read-only access to the catalog (products and categories) by providing a simple API for the app. 
|
11 |
This extension does not modify or affect the Magento installation, nor does it change any catalog data.</description>
|
12 |
<notes>-</notes>
|
13 |
-
<authors><author><name>
|
14 |
-
<date>
|
15 |
-
<time>
|
16 |
-
<contents><target name="magelocal"><dir name="Highstreet"><dir name="Hsapi"><dir name="Helper"><dir name="Config"><file name="Api.php" hash="
|
17 |
<compatible/>
|
18 |
<dependencies><required><php><min>5.0.0.0</min><max>6.0.0.0</max></php></required></dependencies>
|
19 |
</package>
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Highstreet</name>
|
4 |
+
<version>1.7.0</version>
|
5 |
<stability>stable</stability>
|
6 |
<license>-</license>
|
7 |
<channel>community</channel>
|
10 |
<description>The extension provides read-only access to the catalog (products and categories) by providing a simple API for the app. 
|
11 |
This extension does not modify or affect the Magento installation, nor does it change any catalog data.</description>
|
12 |
<notes>-</notes>
|
13 |
+
<authors><author><name>Highstreet</name><user>highstreet</user><email>support@highstreetapp.com</email></author></authors>
|
14 |
+
<date>2017-02-16</date>
|
15 |
+
<time>14:47:43</time>
|
16 |
+
<contents><target name="magelocal"><dir name="Highstreet"><dir name="Hsapi"><dir name="Helper"><dir name="Config"><file name="Account.php" hash="fa740f2a49c830f48919c1823faa5022"/><file name="Api.php" hash="50d19b77b4958e58644a9304ab21a786"/><file name="Cart.php" hash="a4211d5986579352de27c7e31fcae739"/><file name="Checkout.php" hash="310edf6ea6b9fa81c92dfcc6664c2f94"/><file name="Default.php" hash="4b6cbde6ed60ac786ebc32d1997992b2"/><file name="Redirect.php" hash="b0b754f3821bdf2078e9d0ca393af850"/></dir><file name="Data.php" hash="c0a9f7313e8487f10c40be73dbe34e2a"/><file name="Encryption.php" hash="c381845a0bb22e460abac657ac96cd8b"/></dir><dir name="Model"><file name="Attributes.php" hash="3c4f6880fd8352b1343bc2c5abc6a19b"/><file name="CartObserver.php" hash="2eb6be637f5c78f49d8ed618e4e52337"/><file name="Categories.php" hash="46b5f643165efdcaaab8a77f51b126f8"/><file name="CheckoutV2.php" hash="9c9741f632ac60567d26fd8ac7d9d899"/><file name="Observer.php" hash="b272c33ca23a30375c31f4f37be7e962"/><file name="Products.php" hash="9e43f10be77a646b1bf2986a1cb9180a"/><file name="SearchSuggestions.php" hash="7bed3efaf5af19276a4fbb7d6aade83f"/><file name="Session.php" hash="a21f63dc8b6a78492378022d63c8190b"/><dir name="System"><dir name="Config"><file name="Environment.php" hash="5ef07d78cf67bc47be1a64e54ff643ec"/><file name="Stores.php" hash="0812f9942274c0a8f605391f697c0265"/></dir></dir></dir><dir name="controllers"><file name="AccountController.php" hash="ef2e81bdf9139a25560773aea58789a5"/><file name="CartController.php" hash="44c1694e920c3c47c9c8a216c3c3270e"/><file name="CheckoutController.php" hash="2363b1d849ba2347ae59c1e9498cb74c"/><file name="CheckoutV3Controller.php" hash="550813c044d594ee9b9095bc5e97bccf"/><file name="IndexController.php" hash="135da479e6146d6868e60469e745450d"/><file name="RedirectController.php" hash="c058db20643ea870f7da552f2888faf7"/></dir><dir name="etc"><file name="config.xml" hash="b5c48be2cfe4a0a9c9d54559ca6dba8d"/><file name="system.xml" hash="a33c1ef938f3e453d677f8adc45ce8d1"/></dir></dir><dir name="SmartAppBanner"><dir name="etc"><file name="config.xml" hash="83360f37f88541b874382d832fd0a76b"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Highstreet_Api.xml" hash="97e586a7ef0a274d4f0fda883c646f31"/><file name="Highstreet_SmartAppBanner.xml" hash="c739b442a3907d7d7414d0abfd0efaf2"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="highstreet"><file name="smart_app_banner.xml" hash="ed1ad1737439e221c8ca1e0daa0ccd1b"/></dir></dir><dir name="template"><dir name="highstreet"><file name="native_smart_app_banner.phtml" hash="fb9a44823ca7e074ed924b1b6706a0d3"/><file name="smart_app_banner.phtml" hash="dc5f8cf40b4c42a05095744c96afe816"/></dir></dir></dir></dir></dir></target></contents>
|
17 |
<compatible/>
|
18 |
<dependencies><required><php><min>5.0.0.0</min><max>6.0.0.0</max></php></required></dependencies>
|
19 |
</package>
|