Version Notes
The new complete Highstreet extension
Download this release
Release Info
Developer | Christian Apers |
Extension | Highstreet |
Version | 1.1.0 |
Comparing to | |
See all releases |
Code changes from version 1.0.1 to 1.1.0
- app/code/local/Highstreet/Hsapi/Helper/Config.php +0 -68
- app/code/local/Highstreet/Hsapi/Helper/Config/Api.php +77 -0
- app/code/local/Highstreet/Hsapi/Helper/Data.php +8 -2
- app/code/local/Highstreet/Hsapi/Helper/Encryption.php +67 -0
- app/code/local/Highstreet/Hsapi/Model/Categories.php +7 -22
- app/code/local/Highstreet/Hsapi/Model/Checkout.php +51 -30
- app/code/local/Highstreet/Hsapi/Model/CheckoutV2.php +802 -0
- app/code/local/Highstreet/Hsapi/Model/Images.php +5 -1
- app/code/local/Highstreet/Hsapi/Model/Observer.php +49 -6
- app/code/local/Highstreet/Hsapi/Model/Products.php +379 -284
- app/code/local/Highstreet/Hsapi/Model/System/Config/Environment.php +17 -0
- app/code/local/Highstreet/Hsapi/controllers/.DS_Store +0 -0
- app/code/local/Highstreet/Hsapi/controllers/CheckoutController.php +630 -0
- app/code/local/Highstreet/Hsapi/controllers/IndexController.php +177 -37
- app/code/local/Highstreet/Hsapi/etc/.DS_Store +0 -0
- app/code/local/Highstreet/Hsapi/etc/Configuration.json +0 -1
- app/code/local/Highstreet/Hsapi/etc/config.xml +44 -13
- app/code/local/Highstreet/Hsapi/etc/system.xml +103 -0
- app/code/local/Highstreet/SmartAppBanner/etc/config.xml +26 -0
- app/design/frontend/base/default/layout/highstreet/smart_app_banner.xml +12 -0
- app/design/frontend/base/default/template/highstreet/native_smart_app_banner.phtml +28 -0
- app/design/frontend/base/default/template/highstreet/smart_app_banner.phtml +91 -0
- app/etc/modules/Highstreet_SmartAppBanner.xml +14 -0
- app/locale/de_DE/Highstreet_Hsapi.csv +72 -0
- package.xml +6 -6
app/code/local/Highstreet/Hsapi/Helper/Config.php
DELETED
@@ -1,68 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Highstreet_HSAPI_module
|
4 |
-
*
|
5 |
-
* @package Highstreet_Hsapi
|
6 |
-
* @author Tim Wachter (tim@touchwonders.com) ~ Touchwonders
|
7 |
-
* @copyright Copyright (c) 2013 Touchwonders b.v. (http://www.touchwonders.com/)
|
8 |
-
*/
|
9 |
-
|
10 |
-
class Highstreet_Hsapi_Helper_Config extends Mage_Core_Helper_Abstract
|
11 |
-
{
|
12 |
-
const HAS_COUPON_CODES_ENABLES = "has_coupon_codes_enabled";
|
13 |
-
const FILTERS_CATEGORIES = "filters_categories";
|
14 |
-
const ALWAYS_ADD_SIMPLE_PRODUCTS_TO_CART = "always_add_simple_products_to_cart";
|
15 |
-
const CHECKOUT_URL = "checkout_url";
|
16 |
-
const CHECKOUT_URL_FALLBACK = "checkout/onepage";
|
17 |
-
const HAS_NEW_CHECKOUT = "new_checkout";
|
18 |
-
const SHIPPING_METHODS_TEMPLATE_PATH = "shipping_methods_template_path";
|
19 |
-
const SHIPPING_METHODS_TEMPLATE_PATH_FALLBACK = "highstreet/checkout/checkout/shipping_method/available.phtml";
|
20 |
-
|
21 |
-
|
22 |
-
public function hasCouponCodeEnabled() {
|
23 |
-
$configurations = $this->_getConfigurations();
|
24 |
-
return $configurations[self::HAS_COUPON_CODES_ENABLES];
|
25 |
-
}
|
26 |
-
|
27 |
-
public function filtersCategories() {
|
28 |
-
$configurations = $this->_getConfigurations();
|
29 |
-
return $configurations[self::FILTERS_CATEGORIES];
|
30 |
-
}
|
31 |
-
|
32 |
-
public function alwaysAddSimpleProductsToCart() {
|
33 |
-
$configurations = $this->_getConfigurations();
|
34 |
-
$addSimpleProducts = $configurations[self::ALWAYS_ADD_SIMPLE_PRODUCTS_TO_CART];
|
35 |
-
return ($addSimpleProducts === NULL) ? false : $addSimpleProducts;
|
36 |
-
}
|
37 |
-
|
38 |
-
public function checkoutUrl() {
|
39 |
-
$configurations = $this->_getConfigurations();
|
40 |
-
$checkoutUrl = $configurations[self::CHECKOUT_URL];
|
41 |
-
return ($checkoutUrl === NULL) ? self::CHECKOUT_URL_FALLBACK : $checkoutUrl;
|
42 |
-
}
|
43 |
-
|
44 |
-
public function hasNewCheckout() {
|
45 |
-
$configurations = $this->_getConfigurations();
|
46 |
-
$hasNewCheckout = $configurations[self::HAS_NEW_CHECKOUT];
|
47 |
-
return ($hasNewCheckout === NULL) ? false : $hasNewCheckout;
|
48 |
-
}
|
49 |
-
|
50 |
-
public function shippingMethodsTemplatePath() {
|
51 |
-
$configurations = $this->_getConfigurations();
|
52 |
-
$shippingMethodsTemplatePath = $configurations[self::SHIPPING_METHODS_TEMPLATE_PATH];
|
53 |
-
return ($shippingMethodsTemplatePath === NULL) ? self::SHIPPING_METHODS_TEMPLATE_PATH_FALLBACK : $shippingMethodsTemplatePath;
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Loads the configuration JSON and returns an array of
|
58 |
-
*
|
59 |
-
* @return array Array of the settings
|
60 |
-
*/
|
61 |
-
private function _getConfigurations() {
|
62 |
-
$file = file_get_contents(Mage::getBaseDir('code') . "/local/Highstreet/Hsapi/etc/Configuration.json");
|
63 |
-
return json_decode($file, true);
|
64 |
-
}
|
65 |
-
}
|
66 |
-
|
67 |
-
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/code/local/Highstreet/Hsapi/Helper/Config/Api.php
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Highstreet_HSAPI_module
|
4 |
+
*
|
5 |
+
* @package Highstreet_Hsapi
|
6 |
+
* @author Tim Wachter (tim@touchwonders.com) ~ Touchwonders
|
7 |
+
* @copyright Copyright (c) 2015 Touchwonders b.v. (http://www.touchwonders.com/)
|
8 |
+
*/
|
9 |
+
|
10 |
+
class Highstreet_Hsapi_Helper_Config_Api extends Mage_Core_Helper_Abstract {
|
11 |
+
const MIDDLEWARE_URL_SCHEME = "http://";
|
12 |
+
const MIDDLEWARE_URL_ENVIRONMENT_STAGING = "api-dev";
|
13 |
+
const MIDDLEWARE_URL_ENVIRONMENT_PRODUCTION = "api";
|
14 |
+
const MIDDLEWARE_URL_HOST_PATH = "highstreetapp.com/hs-api/1.4";
|
15 |
+
|
16 |
+
public function alwaysAddSimpleProductsToCart() {
|
17 |
+
$alwaysAddSimpleProductsToCart = Mage::getStoreConfig('highstreet_hsapi/api/always_add_simple_products');
|
18 |
+
return ($alwaysAddSimpleProductsToCart === NULL) ? false : (bool)$alwaysAddSimpleProductsToCart;
|
19 |
+
}
|
20 |
+
|
21 |
+
public function shippingInCartDisabled() {
|
22 |
+
$shippingInCartDisabled = Mage::getStoreConfig('highstreet_hsapi/api/shipping_in_cart');
|
23 |
+
return ($shippingInCartDisabled === NULL) ? false : (bool)$shippingInCartDisabled;
|
24 |
+
}
|
25 |
+
|
26 |
+
public function storeIdentifier() {
|
27 |
+
$store_id = Mage::getStoreConfig('highstreet_hsapi/api/store_id');
|
28 |
+
return ($store_id === NULL) ? "" : $store_id;
|
29 |
+
}
|
30 |
+
|
31 |
+
public function environment() {
|
32 |
+
$environment = Mage::getStoreConfig('highstreet_hsapi/api/environment');
|
33 |
+
return ($environment === NULL) ? "staging" : $environment;
|
34 |
+
}
|
35 |
+
|
36 |
+
public function nativeSmartbannerActive() {
|
37 |
+
return (bool) Mage::getStoreConfig('highstreet_hsapi/api/smartbanner_native_active');
|
38 |
+
}
|
39 |
+
|
40 |
+
public function nativeSmartbannerAppId() {
|
41 |
+
$app_id = Mage::getStoreConfig('highstreet_hsapi/api/smartbanner_native_app_id');
|
42 |
+
return ($app_id === NULL) ? "" : $app_id;
|
43 |
+
}
|
44 |
+
|
45 |
+
public function nativeSmartbannerAppUrl() {
|
46 |
+
$app_url = Mage::getStoreConfig('highstreet_hsapi/api/smartbanner_native_app_url');
|
47 |
+
return ($app_url === NULL) ? "" : $app_url;
|
48 |
+
}
|
49 |
+
|
50 |
+
public function nativeSmartbannerAppName() {
|
51 |
+
$app_name = Mage::getStoreConfig('highstreet_hsapi/api/smartbanner_native_app_name');
|
52 |
+
return ($app_name === NULL) ? "" : $app_name;
|
53 |
+
}
|
54 |
+
|
55 |
+
public function middlewareUrl() {
|
56 |
+
if ($this->storeIdentifier() == "") {
|
57 |
+
return NULL;
|
58 |
+
}
|
59 |
+
|
60 |
+
$url = self::MIDDLEWARE_URL_SCHEME . $this->storeIdentifier();
|
61 |
+
|
62 |
+
if ($this->environment() === 'staging') {
|
63 |
+
$url .= '.' . self::MIDDLEWARE_URL_ENVIRONMENT_STAGING;
|
64 |
+
} else {
|
65 |
+
$url .= '.' . self::MIDDLEWARE_URL_ENVIRONMENT_PRODUCTION;
|
66 |
+
}
|
67 |
+
|
68 |
+
$url .= '.' . self::MIDDLEWARE_URL_HOST_PATH;
|
69 |
+
|
70 |
+
|
71 |
+
return $url;
|
72 |
+
}
|
73 |
+
|
74 |
+
public function shouldShowNativeSmartbanner() {
|
75 |
+
return ($this->nativeSmartbannerActive() && $this->nativeSmartbannerAppId() != "");
|
76 |
+
}
|
77 |
+
}
|
app/code/local/Highstreet/Hsapi/Helper/Data.php
CHANGED
@@ -11,6 +11,7 @@ class Highstreet_Hsapi_Helper_Data extends Mage_Core_Helper_Abstract
|
|
11 |
{
|
12 |
/**
|
13 |
* Return single request param. This returns the key as we have rest url
|
|
|
14 |
* @param $params
|
15 |
*
|
16 |
* @return bool|int|string
|
@@ -18,8 +19,13 @@ class Highstreet_Hsapi_Helper_Data extends Mage_Core_Helper_Abstract
|
|
18 |
public function extractRequestParam($params)
|
19 |
{
|
20 |
if($this->requestHasParams($params)){
|
21 |
-
foreach($params as $key => $value){
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
23 |
}
|
24 |
}
|
25 |
return false;
|
11 |
{
|
12 |
/**
|
13 |
* Return single request param. This returns the key as we have rest url
|
14 |
+
* Ignores params with three underscores in them
|
15 |
* @param $params
|
16 |
*
|
17 |
* @return bool|int|string
|
19 |
public function extractRequestParam($params)
|
20 |
{
|
21 |
if($this->requestHasParams($params)){
|
22 |
+
foreach ($params as $key => $value) {
|
23 |
+
// Magento internal parameters use underscores to differentiate themselves
|
24 |
+
// if we want to pass a specific storefront we need to send the parameter '___store'
|
25 |
+
// this messes with the attributes call, so ignore these params
|
26 |
+
if (strstr($key, "___") === false) {
|
27 |
+
return $key;
|
28 |
+
}
|
29 |
}
|
30 |
}
|
31 |
return false;
|
app/code/local/Highstreet/Hsapi/Helper/Encryption.php
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Highstreet_HSAPI_module
|
4 |
+
*
|
5 |
+
* @package Highstreet_Hsapi
|
6 |
+
* @author Tim Wachter (tim@touchwonders.com) ~ Touchwonders
|
7 |
+
* @copyright Copyright (c) 2015 Touchwonders b.v. (http://www.touchwonders.com/)
|
8 |
+
*/
|
9 |
+
|
10 |
+
class Highstreet_Hsapi_Helper_Encryption extends Mage_Core_Helper_Abstract {
|
11 |
+
private $quoteIdHashSalt = "yw14dhejnr";
|
12 |
+
private $hmacEncryptionKey = "5JbqhKdBGtV8J4PH82cm5YDr5f8b4Rbk";
|
13 |
+
|
14 |
+
public function hashQuoteId($quoteId = 0) {
|
15 |
+
return md5($quoteId . $this->quoteIdHashSalt);
|
16 |
+
}
|
17 |
+
|
18 |
+
public function APISignatureStringIsValid() {
|
19 |
+
$givenAPISignature = $_SERVER['HTTP_X_API_SIGNATURE'];
|
20 |
+
$signatureString = $this->_getSignatureString();
|
21 |
+
$encryptedString = $this->_SHA256EncryptString($signatureString);
|
22 |
+
|
23 |
+
return ($givenAPISignature !== NULL && $givenAPISignature === $encryptedString);
|
24 |
+
}
|
25 |
+
|
26 |
+
private function _getSignatureString() {
|
27 |
+
$serverMethod = $_SERVER['REQUEST_METHOD'];
|
28 |
+
if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
|
29 |
+
$serverScheme = 'https';
|
30 |
+
} else {
|
31 |
+
$serverScheme = 'http';
|
32 |
+
}
|
33 |
+
$serverHost = $_SERVER['HTTP_HOST'];
|
34 |
+
$serverPort = $_SERVER['SERVER_PORT'];
|
35 |
+
$serverUri = $_SERVER['REQUEST_URI'];
|
36 |
+
|
37 |
+
$urlComponents = explode('?', $serverUri);
|
38 |
+
|
39 |
+
$serverUri = $urlComponents[0];
|
40 |
+
|
41 |
+
$params = array();
|
42 |
+
if (count($urlComponents) >= 1) {
|
43 |
+
$params = $urlComponents[1];
|
44 |
+
parse_str($params, $params);
|
45 |
+
}
|
46 |
+
|
47 |
+
ksort($params);
|
48 |
+
foreach ($params as $key => $value) {
|
49 |
+
$paramString .= $key . '=' . urlencode($value);
|
50 |
+
|
51 |
+
if (array_search($key, array_keys($params)) < count($params)-1) {
|
52 |
+
$paramString .= '&';
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
$string = $serverMethod . $serverScheme . $serverHost . ':' . $serverPort . $serverUri . $paramString;
|
57 |
+
|
58 |
+
return $string;
|
59 |
+
}
|
60 |
+
|
61 |
+
private function _SHA256EncryptString($string) {
|
62 |
+
return hash_hmac('sha256', $string, $this->hmacEncryptionKey);
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
|
67 |
+
|
app/code/local/Highstreet/Hsapi/Model/Categories.php
CHANGED
@@ -32,6 +32,7 @@ class Highstreet_Hsapi_Model_Categories extends Mage_Core_Model_Abstract
|
|
32 |
$category = array();
|
33 |
$category['id'] = $categoryId;
|
34 |
$category['title'] = $categoryObject->getData('name');
|
|
|
35 |
|
36 |
if ($categoryObject->getImage()) {
|
37 |
$imageUrl = self::CATEGORY_MEDIA_PATH . $categoryObject->getImage();
|
@@ -45,29 +46,20 @@ class Highstreet_Hsapi_Model_Categories extends Mage_Core_Model_Abstract
|
|
45 |
// category children
|
46 |
$children = $this->getChildrenCollectionForCategoryId($categoryId);
|
47 |
|
48 |
-
$config = Mage::helper('highstreet_hsapi/config');
|
49 |
-
$filtersCategories = $config->filtersCategories();
|
50 |
-
|
51 |
if ($children->count() > 0) {
|
52 |
$category['children'] = array();
|
53 |
|
54 |
foreach ($children as $child) {
|
55 |
-
if ($filtersCategories) {
|
56 |
-
if ($child->getData('level') == 2 && // Top Category Level
|
57 |
-
$child->getData('include_in_menu') == 0) {
|
58 |
-
continue;
|
59 |
-
}
|
60 |
-
}
|
61 |
-
|
62 |
if ($child->getImage()) {
|
63 |
$childImageUrl = self::CATEGORY_MEDIA_PATH . $child->getImage();
|
64 |
} else {
|
65 |
$childImageUrl = '';
|
66 |
}
|
67 |
array_push($category['children'], array(
|
68 |
-
'id'
|
69 |
-
'title'
|
70 |
-
'image'
|
|
|
71 |
));
|
72 |
}
|
73 |
}
|
@@ -113,21 +105,14 @@ class Highstreet_Hsapi_Model_Categories extends Mage_Core_Model_Abstract
|
|
113 |
}
|
114 |
$category['image'] = $imageUrl;
|
115 |
|
116 |
-
$category['
|
117 |
|
118 |
-
$
|
119 |
-
$filtersCategories = $config->filtersCategories();
|
120 |
|
121 |
// category children
|
122 |
$category['children'] = array();
|
123 |
if ($children->count() > 0) {
|
124 |
foreach ($children as $child) {
|
125 |
-
if ($filtersCategories) {
|
126 |
-
if ($child->getData('level') == 2 && // Top Category Level
|
127 |
-
$child->getData('include_in_menu') == 0) {
|
128 |
-
continue;
|
129 |
-
}
|
130 |
-
}
|
131 |
|
132 |
$childRepresentation = $this->getCategoryTree($child->getData('entity_id'));
|
133 |
|
32 |
$category = array();
|
33 |
$category['id'] = $categoryId;
|
34 |
$category['title'] = $categoryObject->getData('name');
|
35 |
+
$category['include_in_menu'] = (bool)$categoryObject->getData('include_in_menu');
|
36 |
|
37 |
if ($categoryObject->getImage()) {
|
38 |
$imageUrl = self::CATEGORY_MEDIA_PATH . $categoryObject->getImage();
|
46 |
// category children
|
47 |
$children = $this->getChildrenCollectionForCategoryId($categoryId);
|
48 |
|
|
|
|
|
|
|
49 |
if ($children->count() > 0) {
|
50 |
$category['children'] = array();
|
51 |
|
52 |
foreach ($children as $child) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
if ($child->getImage()) {
|
54 |
$childImageUrl = self::CATEGORY_MEDIA_PATH . $child->getImage();
|
55 |
} else {
|
56 |
$childImageUrl = '';
|
57 |
}
|
58 |
array_push($category['children'], array(
|
59 |
+
'id' => $child->getData('entity_id'),
|
60 |
+
'title' => $child->getData('name'),
|
61 |
+
'image' => $childImageUrl,
|
62 |
+
'include_in_menu'=> (bool)$child->getData('include_in_menu')
|
63 |
));
|
64 |
}
|
65 |
}
|
105 |
}
|
106 |
$category['image'] = $imageUrl;
|
107 |
|
108 |
+
$category['include_in_menu'] = (bool)$categoryObject->getData('include_in_menu');
|
109 |
|
110 |
+
$category['product_count'] = $productCollection->count();
|
|
|
111 |
|
112 |
// category children
|
113 |
$category['children'] = array();
|
114 |
if ($children->count() > 0) {
|
115 |
foreach ($children as $child) {
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
|
117 |
$childRepresentation = $this->getCategoryTree($child->getData('entity_id'));
|
118 |
|
app/code/local/Highstreet/Hsapi/Model/Checkout.php
CHANGED
@@ -105,12 +105,24 @@ class Highstreet_Hsapi_Model_Checkout extends Mage_Core_Model_Abstract
|
|
105 |
|
106 |
$response["quote"] = array_values($this->getProductsInQuote($quote,$products));
|
107 |
|
108 |
-
$this->addAddressToQuoteIfNeeded($quote);
|
109 |
//Shipping carries
|
110 |
$response['selected_shipping_method'] = $this->getSelectedShippingMethod($quote);
|
111 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
$response["totals"] = $this->getQuoteTotals($quote);
|
113 |
|
|
|
114 |
|
115 |
return $response;
|
116 |
|
@@ -125,12 +137,9 @@ class Highstreet_Hsapi_Model_Checkout extends Mage_Core_Model_Abstract
|
|
125 |
$responseQuote = array();
|
126 |
|
127 |
|
128 |
-
|
129 |
-
$quoteItems =
|
130 |
-
|
131 |
-
$quoteItems[$quoteItem->getId()] = $quoteItem;
|
132 |
-
}
|
133 |
-
|
134 |
|
135 |
|
136 |
//loop through the requested products
|
@@ -234,8 +243,9 @@ class Highstreet_Hsapi_Model_Checkout extends Mage_Core_Model_Abstract
|
|
234 |
}
|
235 |
|
236 |
|
237 |
-
if($quoteItem)
|
238 |
-
|
|
|
239 |
|
240 |
|
241 |
|
@@ -255,13 +265,23 @@ class Highstreet_Hsapi_Model_Checkout extends Mage_Core_Model_Abstract
|
|
255 |
|
256 |
|
257 |
}
|
|
|
|
|
|
|
|
|
|
|
258 |
|
259 |
foreach($quoteItems as $quoteItem) {
|
|
|
|
|
|
|
260 |
if(count($quoteItem->getChildren()) > 0)
|
261 |
continue;
|
262 |
|
263 |
$productInQuote = $this->getProductInQuoteResponse($quoteItem);
|
264 |
$responseQuote[] = $productInQuote;
|
|
|
|
|
265 |
}
|
266 |
|
267 |
|
@@ -286,6 +306,11 @@ class Highstreet_Hsapi_Model_Checkout extends Mage_Core_Model_Abstract
|
|
286 |
$quantity = $quoteItem ? $quoteItem->getQty() : 0;
|
287 |
|
288 |
$productInQuote["finalPrice"] = $quantity > 0 ? $product->getFinalPrice($quantity) : $product->getFinalPrice();
|
|
|
|
|
|
|
|
|
|
|
289 |
$productInQuote["quantity"] = $quantity;
|
290 |
|
291 |
return $productInQuote;
|
@@ -328,21 +353,8 @@ class Highstreet_Hsapi_Model_Checkout extends Mage_Core_Model_Abstract
|
|
328 |
return $responseTotals;
|
329 |
}
|
330 |
|
331 |
-
private function addAddressToQuoteIfNeeded(&$quote) {
|
332 |
-
$address = $quote->getShippingAddress();
|
333 |
-
|
334 |
-
if(!$address->getCountryId()) {
|
335 |
-
$address->setCity("Utrecht")
|
336 |
-
->setCountryId("NL")
|
337 |
-
->setPostcode("3512NT")
|
338 |
-
->setCollectShippingRates(true);
|
339 |
-
$quote->setShippingAddress($address);
|
340 |
-
}
|
341 |
-
}
|
342 |
-
|
343 |
private function getSelectedShippingMethod($quote) {
|
344 |
$quoteShippingAddress = $quote->getShippingAddress();
|
345 |
-
$quoteShippingAddress->collectTotals(); //to make sure all available shipping methods are listed
|
346 |
|
347 |
$quoteShippingAddress->collectShippingRates()->save(); //collect the rates
|
348 |
|
@@ -359,7 +371,7 @@ class Highstreet_Hsapi_Model_Checkout extends Mage_Core_Model_Abstract
|
|
359 |
$responseCarriers = array();
|
360 |
|
361 |
$quoteShippingAddress = $quote->getShippingAddress();
|
362 |
-
|
363 |
|
364 |
$quoteShippingAddress->collectShippingRates()->save(); //collect the rates
|
365 |
$groupedRates = $quoteShippingAddress->getGroupedAllShippingRates();
|
@@ -402,19 +414,28 @@ class Highstreet_Hsapi_Model_Checkout extends Mage_Core_Model_Abstract
|
|
402 |
return $product;
|
403 |
|
404 |
}
|
405 |
-
|
406 |
private function _getParentProduct($product) {
|
407 |
-
$config = Mage::helper('highstreet_hsapi/
|
408 |
if ($config->alwaysAddSimpleProductsToCart()) {
|
409 |
return null;
|
410 |
}
|
411 |
|
412 |
$parentIds = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
|
413 |
-
|
414 |
-
|
415 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
416 |
}
|
417 |
-
|
|
|
418 |
}
|
419 |
|
420 |
private function _getConfiguration($product,$parent) {
|
105 |
|
106 |
$response["quote"] = array_values($this->getProductsInQuote($quote,$products));
|
107 |
|
|
|
108 |
//Shipping carries
|
109 |
$response['selected_shipping_method'] = $this->getSelectedShippingMethod($quote);
|
110 |
+
|
111 |
+
$config = Mage::helper('highstreet_hsapi/config_api');
|
112 |
+
|
113 |
+
//Some stores don't want to return the shipping methods in the cart (that is: when the selected_shipping_method is not set yet)
|
114 |
+
//e.g. PME doesn't want this for performance optimization, everytime the cart is openend the magento backend will connect to Paazl, which is quite expensive.
|
115 |
+
//Therefore they one return shipping info once the user acutally a has selected a shipping method.
|
116 |
+
//For PME we also know that shipping is always free, so the rewriter add 'price: 0' to the response.
|
117 |
+
if ($config->shippingInCartDisabled() && $response['selected_shipping_method'] === null) {
|
118 |
+
$response['shipping'] = array();
|
119 |
+
} else {
|
120 |
+
$response['shipping'] = array_values($this->getShippingMethods($quote, $response['selected_shipping_method']));
|
121 |
+
}
|
122 |
+
|
123 |
$response["totals"] = $this->getQuoteTotals($quote);
|
124 |
|
125 |
+
|
126 |
|
127 |
return $response;
|
128 |
|
137 |
$responseQuote = array();
|
138 |
|
139 |
|
140 |
+
$quoteItemsAlreadyAdded = array();
|
141 |
+
$quoteItems = $quote->getAllItems();
|
142 |
+
|
|
|
|
|
|
|
143 |
|
144 |
|
145 |
//loop through the requested products
|
243 |
}
|
244 |
|
245 |
|
246 |
+
if($quoteItem) {
|
247 |
+
$quoteItemsAlreadyAdded[] = $quoteItem->getProduct()->getId();
|
248 |
+
}
|
249 |
|
250 |
|
251 |
|
265 |
|
266 |
|
267 |
}
|
268 |
+
|
269 |
+
//explicit save for PME plugin and refetch quoteitems. For Amasty Free product plugin
|
270 |
+
$quote->collectTotals()->save();
|
271 |
+
$quoteItems = $quote->getAllItems();
|
272 |
+
|
273 |
|
274 |
foreach($quoteItems as $quoteItem) {
|
275 |
+
if(in_array($quoteItem->getProduct()->getId(),$quoteItemsAlreadyAdded))
|
276 |
+
continue;
|
277 |
+
|
278 |
if(count($quoteItem->getChildren()) > 0)
|
279 |
continue;
|
280 |
|
281 |
$productInQuote = $this->getProductInQuoteResponse($quoteItem);
|
282 |
$responseQuote[] = $productInQuote;
|
283 |
+
|
284 |
+
$quoteItemsAlreadyAdded[] = $quoteItem->getProduct()->getId();
|
285 |
}
|
286 |
|
287 |
|
306 |
$quantity = $quoteItem ? $quoteItem->getQty() : 0;
|
307 |
|
308 |
$productInQuote["finalPrice"] = $quantity > 0 ? $product->getFinalPrice($quantity) : $product->getFinalPrice();
|
309 |
+
|
310 |
+
//The custom price is set by the Amasty - Auto Add Promo Items extension. The extra free product has a custom price, and if it is set we should use that price.
|
311 |
+
//This price is already used (automatically) in the total calculations
|
312 |
+
if($quoteItem->getCustomPrice() !== null)
|
313 |
+
$productInQuote["finalPrice"] = $quoteItem->getCustomPrice();
|
314 |
$productInQuote["quantity"] = $quantity;
|
315 |
|
316 |
return $productInQuote;
|
353 |
return $responseTotals;
|
354 |
}
|
355 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
356 |
private function getSelectedShippingMethod($quote) {
|
357 |
$quoteShippingAddress = $quote->getShippingAddress();
|
|
|
358 |
|
359 |
$quoteShippingAddress->collectShippingRates()->save(); //collect the rates
|
360 |
|
371 |
$responseCarriers = array();
|
372 |
|
373 |
$quoteShippingAddress = $quote->getShippingAddress();
|
374 |
+
|
375 |
|
376 |
$quoteShippingAddress->collectShippingRates()->save(); //collect the rates
|
377 |
$groupedRates = $quoteShippingAddress->getGroupedAllShippingRates();
|
414 |
return $product;
|
415 |
|
416 |
}
|
417 |
+
|
418 |
private function _getParentProduct($product) {
|
419 |
+
$config = Mage::helper('highstreet_hsapi/config_api');
|
420 |
if ($config->alwaysAddSimpleProductsToCart()) {
|
421 |
return null;
|
422 |
}
|
423 |
|
424 |
$parentIds = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
|
425 |
+
|
426 |
+
foreach ($parentIds as $value) {
|
427 |
+
$product = Mage::getModel('catalog/product')->load($value);
|
428 |
+
|
429 |
+
// Same check as in Products.php:656
|
430 |
+
// Checks if a parent product is enabled
|
431 |
+
if ($product && $product->getId() !== null &&
|
432 |
+
($product->getData('status') == Mage_Catalog_Model_Product_Status::STATUS_ENABLED || $product->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_ENABLED ||
|
433 |
+
$product->getData('status') == "Ingeschakeld" || $product->getStatus() == "Ingeschakeld")) {
|
434 |
+
return $product;
|
435 |
+
}
|
436 |
}
|
437 |
+
|
438 |
+
return null;
|
439 |
}
|
440 |
|
441 |
private function _getConfiguration($product,$parent) {
|
app/code/local/Highstreet/Hsapi/Model/CheckoutV2.php
ADDED
@@ -0,0 +1,802 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Highstreet_API_module
|
4 |
+
*
|
5 |
+
* @package Highstreet_Api
|
6 |
+
* @author Tim Wachter (tim@touchwonders.com)
|
7 |
+
* @copyright Copyright (c) 2014 Touchwonders (http://www.touchwonders.com/)
|
8 |
+
*/
|
9 |
+
class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
|
10 |
+
{
|
11 |
+
private $_errorCodes = array();
|
12 |
+
private $_errorMessages = array();
|
13 |
+
private $_productIdsNotAdded = array();
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Fills the current session with cart data. This session automatically gets set trough the Magento models, this also inserts the current data in the database e.d.
|
17 |
+
* The array should have the following format:
|
18 |
+
* {"products":[{"sku":"product_sku_1", "qty":5}, {"sku":"product_sku_2", "qty":9}, {"sku":"product_sku_3", "qty":32}, {"sku":"product_sku_4", "qty":3}, {"sku":"product_sku_5", "qty":1}]}
|
19 |
+
* With this format we will lateron be able to extend it for configurable products
|
20 |
+
*
|
21 |
+
* @param array An array of product SKU's to fill the cart
|
22 |
+
*/
|
23 |
+
public function fillCartWithProductsAndQuantities($products = false) {
|
24 |
+
if (!$products) {
|
25 |
+
return;
|
26 |
+
}
|
27 |
+
|
28 |
+
|
29 |
+
Mage::getSingleton('checkout/session')->setQuoteId(null);
|
30 |
+
|
31 |
+
|
32 |
+
$cart = Mage::getModel('checkout/cart');
|
33 |
+
$cart->init();
|
34 |
+
$cart->truncate(); // Reset cart everytime this function is called
|
35 |
+
$quote = $cart->getQuote();
|
36 |
+
|
37 |
+
|
38 |
+
//add products
|
39 |
+
$this->getProductsInQuote($quote,$products,false);
|
40 |
+
|
41 |
+
$cart->save();
|
42 |
+
$quote->save();
|
43 |
+
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
|
44 |
+
}
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Can retrieve an existing quote, or create a new (temporary) quote with the given objects
|
49 |
+
* Purpose of this method is to return all products that exist in the cart, all shipping information and the totals
|
50 |
+
*
|
51 |
+
* @param array An array of product SKU's to fill the cart. Format identical to fillCartWithProductsAndQuantities
|
52 |
+
* @param quote_id (optional) The quote_id for which you would like to return the information
|
53 |
+
*/
|
54 |
+
public function getQuoteWithProductsAndQuantities($products = false, $quote_id = -1) {
|
55 |
+
if ($products === false && $quote_id == -1) {
|
56 |
+
return;
|
57 |
+
}
|
58 |
+
|
59 |
+
$response = array();
|
60 |
+
|
61 |
+
Mage::getSingleton('checkout/session')->setQuoteId(null);
|
62 |
+
|
63 |
+
|
64 |
+
$quote = null;
|
65 |
+
|
66 |
+
if($quote_id == -1) {
|
67 |
+
$cart = Mage::getModel('checkout/cart');
|
68 |
+
$cart->init();
|
69 |
+
$cart->truncate(); // Reset cart everytime this function is called
|
70 |
+
$quote = $cart->getQuote();
|
71 |
+
} else {
|
72 |
+
$quote = Mage::getModel('sales/quote')->load($quote_id);
|
73 |
+
if(!$quote->getId()) {
|
74 |
+
return null;
|
75 |
+
}
|
76 |
+
}
|
77 |
+
|
78 |
+
if($products) {
|
79 |
+
$this->getProductsInQuote($quote,$products);
|
80 |
+
}
|
81 |
+
|
82 |
+
|
83 |
+
//Shipping carries
|
84 |
+
$response['selected_shipping_method'] = $this->getSelectedShippingMethod($quote);
|
85 |
+
|
86 |
+
|
87 |
+
|
88 |
+
$config = Mage::helper('highstreet_hsapi/config_api');
|
89 |
+
|
90 |
+
//Some stores don't want to return the shipping methods in the cart (that is: when the selected_shipping_method is not set yet)
|
91 |
+
//e.g. PME doesn't want this for performance optimization, everytime the cart is openend the magento backend will connect to Paazl, which is quite expensive.
|
92 |
+
//Therefore they one return shipping info once the user acutally a has selected a shipping method.
|
93 |
+
//For PME we also know that shipping is always free, so the rewriter add 'price: 0' to the response.
|
94 |
+
if ($config->shippingInCartDisabled() && $response['selected_shipping_method'] === null) {
|
95 |
+
$response['shipping'] = array();
|
96 |
+
} else {
|
97 |
+
$response['shipping'] = array_values($this->getShippingMethods($quote, $response['selected_shipping_method']));
|
98 |
+
}
|
99 |
+
|
100 |
+
|
101 |
+
|
102 |
+
$response["totals"] = $this->getQuoteTotals($quote);
|
103 |
+
|
104 |
+
$quoteItems = $quote->getAllVisibleItems();
|
105 |
+
|
106 |
+
$responseQuote = array();
|
107 |
+
|
108 |
+
foreach($quoteItems as $quoteItem) {
|
109 |
+
$product_hash = $this->_getQuoteItemHash($quoteItem);
|
110 |
+
$responseQuote[] = array_merge($this->getProductInQuoteResponse($quoteItem),$this->_getErrorForProduct($product_hash));
|
111 |
+
}
|
112 |
+
|
113 |
+
foreach($this->_productIdsNotAdded as $product_hash) {
|
114 |
+
$responseQuote[] = array_merge(array("quantity" => 0,"hash" => $product_hash),$this->_getErrorForProduct($product_hash));
|
115 |
+
|
116 |
+
}
|
117 |
+
|
118 |
+
$response["quote"] = $responseQuote;
|
119 |
+
|
120 |
+
|
121 |
+
return $response;
|
122 |
+
|
123 |
+
|
124 |
+
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Retrieves order information
|
129 |
+
*
|
130 |
+
* @param Object Order object
|
131 |
+
* @param string Status, overwrites the status if needed
|
132 |
+
* @param int Quote_id, fallback quote_id for error when the order object is empty
|
133 |
+
* @param bool Overwrite total due, needed for the `sales_order_invoice_pay` because here the total due is still filled in but the order is actually paid fully
|
134 |
+
* @return array Object with information about the order
|
135 |
+
*/
|
136 |
+
|
137 |
+
public function getOrderInformationFromOrderObject ($order, $quote_id, $status = '') {
|
138 |
+
// We use 'loadByIdWithoutStore' instead of 'load' because if this event gets triggered by a status update from the admin backend the 'admin storefront' gets set, which doesn't have any quotes.
|
139 |
+
$quote = Mage::getModel('sales/quote')->loadByIdWithoutStore($order->getQuoteId());
|
140 |
+
|
141 |
+
if ($quote === false || $quote->getId() == false || $order === false || $order->getId() == false) {
|
142 |
+
return array("error" => 1, "state" => "quote not found", "quote_id" => $quote_id);
|
143 |
+
}
|
144 |
+
|
145 |
+
if ($status == '') {
|
146 |
+
if ($order->getData('total_due') < 1) {
|
147 |
+
$status = 'PAYMENT_SUCCESS';
|
148 |
+
} else {
|
149 |
+
$status = 'PAYMENT_DUE';
|
150 |
+
}
|
151 |
+
}
|
152 |
+
|
153 |
+
$response = array();
|
154 |
+
|
155 |
+
$response['order_id'] = $quote->getData('reserved_order_id');
|
156 |
+
$response['quote_id'] = $quote->getData('entity_id');
|
157 |
+
$response['error'] = 0;
|
158 |
+
$response['state'] = "success";
|
159 |
+
$response['remote_ip'] = $quote->getData('remote_ip');
|
160 |
+
$response['currency'] = $quote->getData('quote_currency_code');
|
161 |
+
$response['invoice_state'] = $order->getData('status');
|
162 |
+
$response['order_status'] = $status;
|
163 |
+
|
164 |
+
|
165 |
+
// Get totals
|
166 |
+
$totals = array();
|
167 |
+
$totals['total_due'] = $order->getData('total_due');
|
168 |
+
$totals['grand_total'] = $order->getData('grand_total');
|
169 |
+
$totals['discount_amount'] = $order->getData('discount_amount');
|
170 |
+
$totals['tax_amount'] = $order->getData('tax_amount');
|
171 |
+
$totals['shipping_amount'] = $order->getData('shipping_amount');
|
172 |
+
$response['totals'] = $totals;
|
173 |
+
|
174 |
+
$response['products'] = array();
|
175 |
+
foreach ($quote->getAllVisibleItems() as $product) {
|
176 |
+
array_push($response['products'], $this->getProductInQuoteResponse($product));
|
177 |
+
}
|
178 |
+
|
179 |
+
return $response;
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Gives all the information to make the checkout work from the initial loading of the page.
|
184 |
+
*/
|
185 |
+
|
186 |
+
public function getStartData() {
|
187 |
+
$customerSession = Mage::getSingleton('customer/session');
|
188 |
+
$customer = $customerSession->getCustomer();
|
189 |
+
$isLoggedIn = $customerSession->isLoggedIn();
|
190 |
+
|
191 |
+
$accountAddressFound = false;
|
192 |
+
|
193 |
+
$billingAddressData = array();
|
194 |
+
$shippingAddressData = array();
|
195 |
+
|
196 |
+
if ($isLoggedIn) {
|
197 |
+
$defaultBillingAddressId = $customer->getDefaultBilling();
|
198 |
+
$defaultShippingAddressId = $customer->getDefaultShipping();
|
199 |
+
|
200 |
+
if ($defaultBillingAddressId > 0) {
|
201 |
+
$accountAddressFound = true;
|
202 |
+
|
203 |
+
$billingAddress = $customer->getAddressById($defaultBillingAddressId);
|
204 |
+
$billingAddressData = $billingAddress->getData();
|
205 |
+
$billingAddressData["email"] = $customer->getEmail();
|
206 |
+
|
207 |
+
if ($defaultBillingAddressId != $defaultShippingAddressId) {
|
208 |
+
$shippingAddress = $customer->getAddressById($defaultShippingAddressId);
|
209 |
+
$shippingAddressData = $shippingAddress->getData();
|
210 |
+
}
|
211 |
+
}
|
212 |
+
}
|
213 |
+
|
214 |
+
$session = Mage::getSingleton('checkout/session');
|
215 |
+
$quote = $session->getQuote();
|
216 |
+
|
217 |
+
if (!$isLoggedIn || !$accountAddressFound) {
|
218 |
+
$billingAddress = $quote->getBillingAddress();
|
219 |
+
$billingAddressData = $billingAddress->getData();
|
220 |
+
$shippingAddress = $quote->getShippingAddress();
|
221 |
+
$shippingAddressData = $shippingAddress->getData();
|
222 |
+
}
|
223 |
+
|
224 |
+
$response = array();
|
225 |
+
|
226 |
+
$response["is_logged_in"] = Mage::getSingleton('customer/session')->isLoggedIn();
|
227 |
+
$response["quote_id"] = $quote->getEntityId();
|
228 |
+
$response["coupon_code"] = $quote->getCouponCode();
|
229 |
+
|
230 |
+
if ($quote->getItemsCount() > 0) {
|
231 |
+
$response["error"] = 0;
|
232 |
+
} else {
|
233 |
+
$response["error"] = -1;
|
234 |
+
}
|
235 |
+
|
236 |
+
if ($billingAddressData["firstname"] !== null) {
|
237 |
+
$billingAddressResponse = array();
|
238 |
+
|
239 |
+
$billingAddressResponse["email"] = $billingAddressData["email"];
|
240 |
+
$billingAddressResponse["firstname"] = $billingAddressData["firstname"];
|
241 |
+
$billingAddressResponse["lastname"] = $billingAddressData["lastname"];
|
242 |
+
$billingAddressResponse["telephone"] = (string) $billingAddressData["telephone"];
|
243 |
+
$billingAddressResponse["street"] = $billingAddress->getStreet();
|
244 |
+
$billingAddressResponse["postcode"] = $billingAddressData["postcode"];
|
245 |
+
$billingAddressResponse["city"] = $billingAddressData["city"];
|
246 |
+
$billingAddressResponse["country_id"] = $billingAddressData["country_id"];
|
247 |
+
|
248 |
+
$response["billing_address"] = $billingAddressResponse;
|
249 |
+
|
250 |
+
$shippingAddressResponse = array();
|
251 |
+
if ($shippingAddressData["firstname"] !== null) {
|
252 |
+
$shippingAddressResponse["firstname"] = $shippingAddressData["firstname"];
|
253 |
+
$shippingAddressResponse["lastname"] = $shippingAddressData["lastname"];
|
254 |
+
$shippingAddressResponse["telephone"] = (string) $shippingAddressData["telephone"];
|
255 |
+
$shippingAddressResponse["street"] = $shippingAddress->getStreet();
|
256 |
+
$shippingAddressResponse["postcode"] = $shippingAddressData["postcode"];
|
257 |
+
$shippingAddressResponse["city"] = $shippingAddressData["city"];
|
258 |
+
$shippingAddressResponse["country_id"] = $shippingAddressData["country_id"];
|
259 |
+
|
260 |
+
if (!$this->_billingAndShippingAddressesAreTheSame($response["billing_address"], $shippingAddressResponse)) {
|
261 |
+
$response["shipping_address"] = $shippingAddressResponse;
|
262 |
+
} else {
|
263 |
+
$response["shipping_address"] = array();
|
264 |
+
}
|
265 |
+
} else {
|
266 |
+
$response["shipping_address"] = array();
|
267 |
+
}
|
268 |
+
} else {
|
269 |
+
$response["billing_address"] = array();
|
270 |
+
$response["shipping_address"] = array();
|
271 |
+
}
|
272 |
+
|
273 |
+
return $response;
|
274 |
+
}
|
275 |
+
|
276 |
+
|
277 |
+
|
278 |
+
//Helpers below
|
279 |
+
|
280 |
+
private function getProductsInQuote($quote,$products = null,$capAmount = true) {
|
281 |
+
$responseQuote = array();
|
282 |
+
|
283 |
+
|
284 |
+
|
285 |
+
|
286 |
+
//loop through the requested products
|
287 |
+
foreach ($products as $key => $value) {
|
288 |
+
$product_id = $value["product_id"];
|
289 |
+
$product_hash = $this->_getQuoteItemRequestHash($value);
|
290 |
+
|
291 |
+
if (empty($product_id)) {
|
292 |
+
continue;
|
293 |
+
}
|
294 |
+
|
295 |
+
|
296 |
+
$errorMessage = null;
|
297 |
+
|
298 |
+
try {
|
299 |
+
$product = $this->loadProduct($product_id);
|
300 |
+
} catch (Exception $e) {
|
301 |
+
$errorMessage = $e->getMessage();
|
302 |
+
$product = null;
|
303 |
+
}
|
304 |
+
|
305 |
+
if ($product === null || !$product->getId()) {
|
306 |
+
$this->_reportErrorForProduct($product_hash,400,$errorMessage);
|
307 |
+
continue;
|
308 |
+
}
|
309 |
+
|
310 |
+
//input variables
|
311 |
+
$requestedQuantity = ($product->getStatus() != Mage_Catalog_Model_Product_Status::STATUS_ENABLED) ? 0 : $value["quantity"];
|
312 |
+
$configuration = array_key_exists("configuration", $value) ? $value["configuration"] : null;
|
313 |
+
$bundle_selections = array_key_exists("bundle_selections", $value) ? $value["bundle_selections"] : null;
|
314 |
+
$simple_product = null;
|
315 |
+
$quoteItem = null;
|
316 |
+
|
317 |
+
$quote_item_additional_info = null; //additional info that should be stored in the quote item
|
318 |
+
|
319 |
+
if($product->getTypeId() == 'simple') {
|
320 |
+
$simple_product = $product;
|
321 |
+
} else if($product->getTypeId() == 'configurable') {
|
322 |
+
$simple_product = $this->loadProduct($value['simple_product_id']);
|
323 |
+
|
324 |
+
//if 'alwaysAddSimpleProductsToCart' is set, then we add the simple product of a configurable product to the cart
|
325 |
+
$config = Mage::helper('highstreet_hsapi/config_api');
|
326 |
+
if($config->alwaysAddSimpleProductsToCart()) {
|
327 |
+
$quote_item_additional_info = array("parent_product_id" => $product_id);
|
328 |
+
$product = $simple_product;
|
329 |
+
}
|
330 |
+
}
|
331 |
+
|
332 |
+
if($simple_product !== null) {
|
333 |
+
$quoteItem = $quote->getItemByProduct($simple_product);
|
334 |
+
}
|
335 |
+
|
336 |
+
|
337 |
+
//Check for inventory (only for simple and configurable)
|
338 |
+
|
339 |
+
$actualQuantity = 0;
|
340 |
+
if($simple_product !== null && $capAmount) {
|
341 |
+
|
342 |
+
$itemInventory = Mage::getModel('cataloginventory/stock_item')->loadByProduct($simple_product);
|
343 |
+
|
344 |
+
|
345 |
+
$actualQuantity = $requestedQuantity; //actual qty is what we are going to add
|
346 |
+
|
347 |
+
//adjust actual quantity if we are requesting more than in stock
|
348 |
+
$availableQuantity = $itemInventory->getQty();
|
349 |
+
$isInStock = $itemInventory->getIsInStock();
|
350 |
+
$isStockManaged = $itemInventory->getManageStock();
|
351 |
+
$backordersAllowed = $itemInventory->getBackorders();
|
352 |
+
|
353 |
+
|
354 |
+
if($isStockManaged) {
|
355 |
+
|
356 |
+
if(!$isInStock) {
|
357 |
+
$this->_reportErrorForProduct($product_hash,101,"Product is not in stock");
|
358 |
+
$actualQuantity = 0;
|
359 |
+
} else {
|
360 |
+
//in stock, but should we cap it?
|
361 |
+
if(!$backordersAllowed && $requestedQuantity > $availableQuantity) {
|
362 |
+
$actualQuantity = $availableQuantity; //cap
|
363 |
+
$this->_reportErrorForProduct($product_hash,102,"Requested quantity is not available, added ".(int)$actualQuantity." instead of ".$requestedQuantity ." products with id ".$value["id"]." to the cart",false);
|
364 |
+
//product can be added, but with a lower quantity
|
365 |
+
//Note: even though the actualQuantity might be set to 0, we still do not return a 101, because a qty of 0 does not necessarily make a product out of stock
|
366 |
+
//"Qty for Item's Status to Become Out of Stock" might be a negative integer
|
367 |
+
}
|
368 |
+
|
369 |
+
}
|
370 |
+
|
371 |
+
}
|
372 |
+
|
373 |
+
} else {
|
374 |
+
$actualQuantity = $requestedQuantity;
|
375 |
+
|
376 |
+
}
|
377 |
+
|
378 |
+
|
379 |
+
|
380 |
+
|
381 |
+
//add to cart
|
382 |
+
|
383 |
+
|
384 |
+
try {
|
385 |
+
|
386 |
+
|
387 |
+
if($quoteItem) { //adjust existing entry
|
388 |
+
|
389 |
+
$quoteItem->setQty($actualQuantity);
|
390 |
+
} else { //or add new entry (but of course only when qty > 0)
|
391 |
+
|
392 |
+
if($actualQuantity > 0) { //do this check because the app might request a quantity of 0 for a product. If you call the function below with $actualQuantity = 0, it will still add one product to the cart
|
393 |
+
|
394 |
+
|
395 |
+
//simple
|
396 |
+
if($product->getTypeId() == 'simple') {
|
397 |
+
$quoteItem = $quote->addProduct($product,new Varien_Object(array("qty" => $actualQuantity)));
|
398 |
+
}
|
399 |
+
|
400 |
+
if($product->getTypeId() == 'configurable') {
|
401 |
+
|
402 |
+
$requestConfiguration = array();
|
403 |
+
foreach($configuration as $configuration_option) {
|
404 |
+
$attributeCode = $configuration_option['attribute_code'];
|
405 |
+
$attribute = Mage::getModel('eav/config')->getAttribute('catalog_product', $attributeCode);
|
406 |
+
|
407 |
+
$requestConfiguration[$attribute->getId()] = $configuration_option['attribute_value'];
|
408 |
+
}
|
409 |
+
|
410 |
+
$configurations = array('super_attribute' => $requestConfiguration);
|
411 |
+
$options = array_merge(array("qty" => $actualQuantity),$configurations);
|
412 |
+
$quoteItem = $quote->addProduct($product,new Varien_Object($options));
|
413 |
+
|
414 |
+
}
|
415 |
+
|
416 |
+
if($product->getTypeId() == 'bundle') {
|
417 |
+
$bundle_option = array();
|
418 |
+
$bundle_option_qty = array();
|
419 |
+
|
420 |
+
foreach($bundle_selections as $bundle_selection) {
|
421 |
+
$option_id = $bundle_selection["option_id"];
|
422 |
+
$bundle_option[$option_id] = $bundle_selection["selection_ids"];
|
423 |
+
if($bundle_selection["quantity"])
|
424 |
+
$bundle_option_qty[$option_id] = $bundle_selection["quantity"];
|
425 |
+
|
426 |
+
}
|
427 |
+
|
428 |
+
$options = array("qty" => $actualQuantity, "bundle_option" => $bundle_option,"bundle_option_qty" => $bundle_option_qty );
|
429 |
+
|
430 |
+
|
431 |
+
$quoteItem = $quote->addProduct($product,new Varien_Object($options));
|
432 |
+
}
|
433 |
+
|
434 |
+
$parentQuoteItem = $quoteItem->getParentItem();
|
435 |
+
if($parentQuoteItem) {
|
436 |
+
$quoteItem = $parentQuoteItem;
|
437 |
+
}
|
438 |
+
|
439 |
+
if($quote_item_additional_info) {
|
440 |
+
$quoteItem->setAdditionalData(json_encode($quote_item_additional_info));
|
441 |
+
}
|
442 |
+
|
443 |
+
|
444 |
+
} else {
|
445 |
+
if (!in_array($product_hash,$this->_productIdsNotAdded)) {
|
446 |
+
$this->_productIdsNotAdded[] = $product_hash;
|
447 |
+
}
|
448 |
+
}
|
449 |
+
}
|
450 |
+
|
451 |
+
|
452 |
+
|
453 |
+
|
454 |
+
} catch (Exception $e) {
|
455 |
+
$this->_reportErrorForProduct($product_hash,400,$e->getMessage());
|
456 |
+
|
457 |
+
|
458 |
+
}
|
459 |
+
|
460 |
+
|
461 |
+
|
462 |
+
}
|
463 |
+
|
464 |
+
|
465 |
+
}
|
466 |
+
|
467 |
+
private function _reportErrorForProduct($product_hash,$errorCode,$errorMessage,$notAdded = true) {
|
468 |
+
$this->_errorCodes[$product_hash] = $errorCode;
|
469 |
+
$this->_errorMessages[$product_hash] = $errorMessage;
|
470 |
+
|
471 |
+
if($notAdded) {
|
472 |
+
$this->_productIdsNotAdded[] = $product_hash;
|
473 |
+
}
|
474 |
+
}
|
475 |
+
|
476 |
+
private function _getErrorForProduct($product_hash) {
|
477 |
+
$response = array();
|
478 |
+
$response["errorCode"] = 0;
|
479 |
+
$response["errorMessage"] = null;
|
480 |
+
|
481 |
+
if (array_key_exists($product_hash, $this->_errorCodes)) {
|
482 |
+
$response["errorCode"] = $this->_errorCodes[$product_hash];
|
483 |
+
}
|
484 |
+
|
485 |
+
if (array_key_exists($product_hash, $this->_errorMessages)) {
|
486 |
+
$response["errorMessage"] = $this->_errorMessages[$product_hash];
|
487 |
+
}
|
488 |
+
|
489 |
+
return $response;
|
490 |
+
}
|
491 |
+
|
492 |
+
|
493 |
+
|
494 |
+
private function getProductInQuoteResponse($quoteItem = null) {
|
495 |
+
|
496 |
+
$product = $quoteItem->getProduct();
|
497 |
+
$parent_product_id = $this->_getQuoteItemParentProductId($quoteItem);
|
498 |
+
|
499 |
+
|
500 |
+
$productInQuote = array();
|
501 |
+
$productInQuote["product_id"] = $parent_product_id ? $parent_product_id : $product->getId();
|
502 |
+
|
503 |
+
$productInQuote["name"] = $product->getName();
|
504 |
+
$productInQuote["sku"] = $product->getSku();
|
505 |
+
|
506 |
+
|
507 |
+
|
508 |
+
$quantity = $quoteItem ? $quoteItem->getQty() : 0;
|
509 |
+
|
510 |
+
$productInQuote["finalPrice"] = $quoteItem->getPriceInclTax();
|
511 |
+
$productInQuote["tax"] = $quoteItem->getPriceInclTax() - $quoteItem->getPrice();
|
512 |
+
|
513 |
+
//The custom price is set by the Amasty - Auto Add Promo Items extension. The extra free product has a custom price, and if it is set we should use that price.
|
514 |
+
//This price is already used (automatically) in the total calculations
|
515 |
+
if($quoteItem->getCustomPrice() !== null) {
|
516 |
+
$productInQuote["finalPrice"] = $quoteItem->getCustomPrice();
|
517 |
+
}
|
518 |
+
|
519 |
+
|
520 |
+
$productInQuote["quantity"] = $quantity;
|
521 |
+
|
522 |
+
|
523 |
+
$productInQuote["hash"] = $this->_getQuoteItemHash($quoteItem);
|
524 |
+
|
525 |
+
|
526 |
+
return $productInQuote;
|
527 |
+
}
|
528 |
+
|
529 |
+
private function _getQuoteItemHash($quoteItem) {
|
530 |
+
$product = $quoteItem->getProduct();
|
531 |
+
|
532 |
+
$hash = null;
|
533 |
+
|
534 |
+
$parent_product_id = $this->_getQuoteItemParentProductId($quoteItem);
|
535 |
+
|
536 |
+
|
537 |
+
$type = $product->getTypeId();
|
538 |
+
|
539 |
+
if($type == 'simple') {
|
540 |
+
if($parent_product_id == null) {
|
541 |
+
$hash = $product->getId();
|
542 |
+
} else {
|
543 |
+
//actually a configurable product, but the child was added instead of the parent
|
544 |
+
$hash = $parent_product_id . ":" . $product->getId();
|
545 |
+
}
|
546 |
+
}
|
547 |
+
|
548 |
+
if($type == 'configurable') {
|
549 |
+
$children = $quoteItem->getChildren();
|
550 |
+
$childQuoteItem = current($children);
|
551 |
+
if ($childQuoteItem)
|
552 |
+
$hash = $product->getId() . ":" . $childQuoteItem->getProduct()->getId();
|
553 |
+
else
|
554 |
+
$hash = $product->getId();
|
555 |
+
|
556 |
+
}
|
557 |
+
|
558 |
+
if($type == 'bundle') {
|
559 |
+
$hash = $product->getId().":";
|
560 |
+
|
561 |
+
$options = $product->getTypeInstance(true)->getOrderOptions($product);
|
562 |
+
|
563 |
+
$bundle_option = $options["info_buyRequest"]["bundle_option"];
|
564 |
+
ksort($bundle_option);
|
565 |
+
|
566 |
+
|
567 |
+
$hashElements = array();
|
568 |
+
|
569 |
+
foreach($bundle_option as $option_id => $selection_ids) {
|
570 |
+
|
571 |
+
if (!is_array($selection_ids))
|
572 |
+
$selection_ids = array($selection_ids);
|
573 |
+
|
574 |
+
|
575 |
+
$quantity = round($options["info_buyRequest"]["bundle_option_qty"][$option_id]);
|
576 |
+
|
577 |
+
sort($selection_ids);
|
578 |
+
$selection_ids_string = implode(",",$selection_ids);
|
579 |
+
$hashElements[] = "($option_id,[$selection_ids_string],$quantity)";
|
580 |
+
|
581 |
+
}
|
582 |
+
|
583 |
+
$hash .= '['.implode(",",$hashElements).']';
|
584 |
+
|
585 |
+
|
586 |
+
|
587 |
+
}
|
588 |
+
|
589 |
+
if($parent_product_id) {
|
590 |
+
$type = 'configurable'; //the product is actually a configurable product
|
591 |
+
}
|
592 |
+
|
593 |
+
return $type."-".$hash;
|
594 |
+
|
595 |
+
|
596 |
+
}
|
597 |
+
|
598 |
+
private function _compareBundleSelection($a, $b) {
|
599 |
+
if ($a["option_id"] == $b["option_id"]) {
|
600 |
+
return 0;
|
601 |
+
}
|
602 |
+
return ($a["option_id"] < $b["option_id"]) ? -1 : 1;
|
603 |
+
}
|
604 |
+
|
605 |
+
private function _getQuoteItemRequestHash($quoteItemRequest) {
|
606 |
+
|
607 |
+
$hash = null;
|
608 |
+
$type = 'simple';
|
609 |
+
if(array_key_exists('simple_product_id', $quoteItemRequest)) {
|
610 |
+
$type = 'configurable';
|
611 |
+
}
|
612 |
+
if(array_key_exists('bundle_selections', $quoteItemRequest)) {
|
613 |
+
$type = 'bundle';
|
614 |
+
}
|
615 |
+
|
616 |
+
if($type == 'simple') {
|
617 |
+
$hash = $quoteItemRequest['product_id'];
|
618 |
+
}
|
619 |
+
|
620 |
+
if($type == 'configurable') {
|
621 |
+
$hash = $quoteItemRequest['product_id'] . ":" . $quoteItemRequest['simple_product_id'];
|
622 |
+
}
|
623 |
+
|
624 |
+
if($type == 'bundle') {
|
625 |
+
$hash = $quoteItemRequest['product_id'].":";
|
626 |
+
|
627 |
+
|
628 |
+
$hashElements = array();
|
629 |
+
|
630 |
+
$selections = $quoteItemRequest["bundle_selections"];
|
631 |
+
|
632 |
+
|
633 |
+
usort($selections,array($this,"_compareBundleSelection"));
|
634 |
+
|
635 |
+
|
636 |
+
foreach($selections as $bundle_selection) {
|
637 |
+
$option_id = $bundle_selection["option_id"];
|
638 |
+
$selection_ids = $bundle_selection["selection_ids"];
|
639 |
+
sort($selection_ids);
|
640 |
+
$quantity = $bundle_selection["quantity"];
|
641 |
+
|
642 |
+
$selection_ids_string = implode(",",$selection_ids);
|
643 |
+
$hashElements[] = "($option_id,[$selection_ids_string],$quantity)";
|
644 |
+
}
|
645 |
+
|
646 |
+
|
647 |
+
$hash .= '['.implode(",",$hashElements).']';
|
648 |
+
|
649 |
+
|
650 |
+
|
651 |
+
}
|
652 |
+
|
653 |
+
return $type."-".$hash;
|
654 |
+
|
655 |
+
|
656 |
+
}
|
657 |
+
|
658 |
+
private function _getQuoteItemParentProductId($quoteItem) {
|
659 |
+
$additionalInfo = $quoteItem->getAdditionalData();
|
660 |
+
if($additionalInfo) {
|
661 |
+
$json = json_decode($additionalInfo,true);
|
662 |
+
return $json['parent_product_id'];
|
663 |
+
}
|
664 |
+
return null;
|
665 |
+
}
|
666 |
+
|
667 |
+
private function getQuoteTotals($quote) {
|
668 |
+
|
669 |
+
|
670 |
+
$quote->save()->collectTotals(); //required to fetch the totals
|
671 |
+
|
672 |
+
//Totals
|
673 |
+
$totals = $quote->getTotals(); //Total object
|
674 |
+
$subtotal = $totals["subtotal"]->getValue(); //Subtotal value
|
675 |
+
$grandtotal = $totals["grand_total"]->getValue(); //Grandtotal value
|
676 |
+
|
677 |
+
$discount = 0;
|
678 |
+
if(isset($totals['discount']) && $totals['discount']->getValue()) {
|
679 |
+
$discount = $totals['discount']->getValue(); //Discount value if applied
|
680 |
+
}
|
681 |
+
$tax = 0;
|
682 |
+
if(isset($totals['tax']) && $totals['tax']->getValue()) {
|
683 |
+
$tax = $totals['tax']->getValue(); //Tax value if present
|
684 |
+
}
|
685 |
+
|
686 |
+
$totalItemsInCart = 0;
|
687 |
+
foreach($quote->getAllVisibleItems() as $quoteItem) {
|
688 |
+
$totalItemsInCart++;
|
689 |
+
}
|
690 |
+
|
691 |
+
|
692 |
+
$responseTotals = array();
|
693 |
+
$responseTotals["totalItemsInCart"] = $totalItemsInCart;
|
694 |
+
$responseTotals["subtotal"] = $subtotal;
|
695 |
+
$responseTotals["grandtotal"] = $grandtotal;
|
696 |
+
$responseTotals["discount"] = $discount;
|
697 |
+
$responseTotals["tax"] = $tax;
|
698 |
+
|
699 |
+
return $responseTotals;
|
700 |
+
}
|
701 |
+
|
702 |
+
|
703 |
+
|
704 |
+
private function getSelectedShippingMethod($quote) {
|
705 |
+
$quoteShippingAddress = $quote->getShippingAddress();
|
706 |
+
$quoteShippingAddress->collectTotals(); //to make sure all available shipping methods are listed
|
707 |
+
|
708 |
+
$quoteShippingAddress->collectShippingRates()->save(); //collect the rates
|
709 |
+
|
710 |
+
$chosenShippingMethod = $quoteShippingAddress->getShippingMethod();
|
711 |
+
|
712 |
+
if ($chosenShippingMethod === "") {
|
713 |
+
$chosenShippingMethod = null;
|
714 |
+
}
|
715 |
+
|
716 |
+
return $chosenShippingMethod;
|
717 |
+
}
|
718 |
+
|
719 |
+
private function getShippingMethods($quote, $selectedShippingMethod) {
|
720 |
+
$responseCarriers = array();
|
721 |
+
|
722 |
+
$quoteShippingAddress = $quote->getShippingAddress();
|
723 |
+
$quoteShippingAddress->collectTotals(); //to make sure all available shipping methods are listed
|
724 |
+
|
725 |
+
$quoteShippingAddress->collectShippingRates()->save(); //collect the rates
|
726 |
+
$groupedRates = $quoteShippingAddress->getGroupedAllShippingRates();
|
727 |
+
|
728 |
+
foreach ($groupedRates as $carrierCode => $rates ) {
|
729 |
+
foreach ($rates as $rate) {
|
730 |
+
$price = $rate->getPrice();
|
731 |
+
if ($rate->getCode() == $selectedShippingMethod) {
|
732 |
+
$quoteShippingAddress->setShippingMethod($selectedShippingMethod);
|
733 |
+
$quote->collectTotals()->save();
|
734 |
+
|
735 |
+
$price = $quoteShippingAddress->getShippingInclTax();
|
736 |
+
}
|
737 |
+
|
738 |
+
$responseRate = array();
|
739 |
+
$responseRate["carrier"] = $rate->getCarrier();
|
740 |
+
$responseRate["carrierTitle"] = $rate->getCarrierTitle();
|
741 |
+
$responseRate["carrierCode"] = $rate->getCode();
|
742 |
+
|
743 |
+
$responseRate["method"] = $rate->getMethod();
|
744 |
+
$responseRate["methodTitle"] = $rate->getMethodTitle();
|
745 |
+
$responseRate["methodDescription"] = $rate->getMethodDescription();
|
746 |
+
$responseRate["price"] = $price;
|
747 |
+
$responseCarriers[] = $responseRate;
|
748 |
+
}
|
749 |
+
}
|
750 |
+
|
751 |
+
return $responseCarriers;
|
752 |
+
}
|
753 |
+
|
754 |
+
private function loadProduct($productId = null) {
|
755 |
+
if(!$productId)
|
756 |
+
return null;
|
757 |
+
|
758 |
+
$productModel = Mage::getModel('catalog/product');
|
759 |
+
$product = $productModel->load($productId);
|
760 |
+
if (!$product->getId())
|
761 |
+
return null; //product does not exist
|
762 |
+
|
763 |
+
return $product;
|
764 |
+
|
765 |
+
}
|
766 |
+
|
767 |
+
private function _getParentProduct($product) {
|
768 |
+
$config = Mage::helper('highstreet_hsapi/config_api');
|
769 |
+
if ($config->alwaysAddSimpleProductsToCart()) {
|
770 |
+
return null;
|
771 |
+
}
|
772 |
+
|
773 |
+
$parentIds = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
|
774 |
+
$parent = null;
|
775 |
+
if(isset($parentIds[0])){
|
776 |
+
$parent = Mage::getModel('catalog/product')->load($parentIds[0]);
|
777 |
+
}
|
778 |
+
|
779 |
+
if($parent->getId() === null)
|
780 |
+
return null;
|
781 |
+
|
782 |
+
return $parent;
|
783 |
+
}
|
784 |
+
|
785 |
+
/**
|
786 |
+
* Convenience method, compares 2 formatted address arrays
|
787 |
+
*/
|
788 |
+
private function _billingAndShippingAddressesAreTheSame($billingAddressArray = array(), $shippingAddressArray = array()) {
|
789 |
+
if (count($billingAddressArray) == 0 || count($shippingAddressArray) == 0) {
|
790 |
+
return true;
|
791 |
+
}
|
792 |
+
|
793 |
+
return (($billingAddressArray["firstname"] == $shippingAddressArray["firstname"]) &&
|
794 |
+
($billingAddressArray["lastname"] == $shippingAddressArray["lastname"]) &&
|
795 |
+
($billingAddressArray["telephone"] == $shippingAddressArray["telephone"]) &&
|
796 |
+
($billingAddressArray["street"] == $shippingAddressArray["street"]) &&
|
797 |
+
($billingAddressArray["postcode"] == $shippingAddressArray["postcode"]) &&
|
798 |
+
($billingAddressArray["city"] == $shippingAddressArray["city"]));
|
799 |
+
}
|
800 |
+
|
801 |
+
|
802 |
+
}
|
app/code/local/Highstreet/Hsapi/Model/Images.php
CHANGED
@@ -27,7 +27,11 @@ class Highstreet_Hsapi_Model_Images extends Mage_Core_Model_Abstract
|
|
27 |
|
28 |
$originalSize = $image->getOriginalSize();
|
29 |
if ($size) {
|
30 |
-
|
|
|
|
|
|
|
|
|
31 |
|
32 |
if (!empty($width) && !empty($height)) {
|
33 |
$image->resize($width, $height);
|
27 |
|
28 |
$originalSize = $image->getOriginalSize();
|
29 |
if ($size) {
|
30 |
+
|
31 |
+
$explodedSize = explode('x', $size);
|
32 |
+
if (count($explodedSize) > 1) {
|
33 |
+
list($width, $height) = $explodedSize;
|
34 |
+
}
|
35 |
|
36 |
if (!empty($width) && !empty($height)) {
|
37 |
$image->resize($width, $height);
|
app/code/local/Highstreet/Hsapi/Model/Observer.php
CHANGED
@@ -1,22 +1,65 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
{
|
|
|
4 |
public function __construct()
|
5 |
{
|
6 |
}
|
|
|
7 |
public function mergeQuote($observer)
|
8 |
{
|
9 |
$event = $observer->getEvent();
|
10 |
$quote = $event->getQuote();
|
11 |
-
exec("echo Quote".$quote->getId()." > /tmp/bla");
|
12 |
|
13 |
foreach ($quote->getAllItems() as $item) {
|
14 |
$quote->removeItem($item->getId());
|
15 |
}
|
16 |
|
17 |
}
|
18 |
-
|
19 |
|
20 |
-
}
|
21 |
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<?php
|
2 |
+
|
3 |
+
class Highstreet_Hsapi_Model_Observer {
|
4 |
+
|
5 |
public function __construct()
|
6 |
{
|
7 |
}
|
8 |
+
|
9 |
public function mergeQuote($observer)
|
10 |
{
|
11 |
$event = $observer->getEvent();
|
12 |
$quote = $event->getQuote();
|
|
|
13 |
|
14 |
foreach ($quote->getAllItems() as $item) {
|
15 |
$quote->removeItem($item->getId());
|
16 |
}
|
17 |
|
18 |
}
|
|
|
19 |
|
|
|
20 |
|
21 |
+
public function salesOrderInvoicePay(Varien_Event_Observer $observer) {
|
22 |
+
$checkoutModel = Mage::getModel('highstreet_hsapi/checkoutV2');
|
23 |
+
$order = $observer->getEvent()->getInvoice()->getOrder();
|
24 |
+
$this->_communicateOrderEvent($order, '');
|
25 |
+
}
|
26 |
+
|
27 |
+
|
28 |
+
public function salesOrderInvoiceCancel(Varien_Event_Observer $observer) {
|
29 |
+
$checkoutModel = Mage::getModel('highstreet_hsapi/checkoutV2');
|
30 |
+
$order = $observer->getEvent()->getInvoice()->getOrder();
|
31 |
+
$this->_communicateOrderEvent($order, 'PAYMENT_CANCELED');
|
32 |
+
}
|
33 |
+
|
34 |
+
|
35 |
+
private function _communicateOrderEvent($order, $status = '') {
|
36 |
+
if ($order->getQuoteId() > 0) {
|
37 |
+
$encryptionHelper = Mage::helper('highstreet_hsapi/encryption');
|
38 |
+
$quoteIdHash = $encryptionHelper->hashQuoteId($order->getQuoteId());
|
39 |
+
|
40 |
+
$isHighstreetOrder = false;
|
41 |
+
foreach ($order->getStatusHistoryCollection(true) as $comment) {
|
42 |
+
if (strstr($comment->getData('comment'), $quoteIdHash) !== false) {
|
43 |
+
$isHighstreetOrder = true;
|
44 |
+
break;
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
$configHelper = Mage::helper('highstreet_hsapi/config_api');
|
49 |
+
$middleWareUrl = $configHelper->middlewareUrl();
|
50 |
+
|
51 |
+
if ($isHighstreetOrder && $middleWareUrl !== NULL) {
|
52 |
+
$checkoutModel = Mage::getModel('highstreet_hsapi/checkoutV2');
|
53 |
+
$data = $checkoutModel->getOrderInformationFromOrderObject($order, $order->getQuoteId(), $status);
|
54 |
+
|
55 |
+
$ch = curl_init($middleWareUrl . "/orders/" . $order->getQuoteId());
|
56 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
|
57 |
+
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
|
58 |
+
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); // Time CURL takes to wait for a connection to our server, 0 is indefinitely
|
59 |
+
curl_setopt($ch, CURLOPT_TIMEOUT, 15); // Maximum time CURL takes to execute
|
60 |
+
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_NUMERIC_CHECK));
|
61 |
+
$output = curl_exec($ch);
|
62 |
+
}
|
63 |
+
}
|
64 |
+
}
|
65 |
+
}
|
app/code/local/Highstreet/Hsapi/Model/Products.php
CHANGED
@@ -8,12 +8,6 @@
|
|
8 |
*/
|
9 |
class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
10 |
{
|
11 |
-
/**
|
12 |
-
* @var bool
|
13 |
-
*/
|
14 |
-
private $_addConfigurableAttributes = false;
|
15 |
-
private $_addConfigurations = false;
|
16 |
-
|
17 |
const PRODUCTS_MEDIA_PATH = '/media/catalog/product';
|
18 |
const NO_IMAGE_PATH = 'no_selection';
|
19 |
const RANGE_FALLBACK_RANGE = 100;
|
@@ -22,49 +16,86 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
22 |
/**
|
23 |
* Gets a single product for a given productId and attributes
|
24 |
*
|
25 |
-
* @param
|
26 |
-
* @param string Attributes, string of attributes straight from the URL
|
|
|
|
|
27 |
* @return array Product
|
28 |
*/
|
29 |
-
public function getSingleProduct($
|
30 |
{
|
31 |
-
if (!$
|
32 |
-
return
|
33 |
}
|
34 |
-
|
35 |
-
$product = Mage::getModel('catalog/product')->load($productId);
|
36 |
|
37 |
-
return $this->_getProductAttributes($
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
* Gets products with attributes for given order, range, filters, search and categoryId
|
42 |
*
|
43 |
-
* @param string Attributes, string of attributes straight from the URL
|
44 |
-
* @param string Child product attributes, string of attributes for the child products, comma sepperated
|
45 |
* @param string Order, order for the products
|
46 |
* @param string Range of products. Must formatted like "0,10" where 0 is the offset and 10 is the count
|
47 |
* @param string Search string for filtering on keywords
|
48 |
* @param integer CategoryId, category id of the category which will be used to filter
|
|
|
|
|
|
|
|
|
49 |
* @return array Product
|
50 |
*/
|
51 |
-
public function getProductsForResponse($
|
52 |
{
|
53 |
-
$addGalleryImages = false;
|
54 |
$searching = !empty($search);
|
55 |
|
|
|
56 |
// get attributes
|
57 |
-
if (!empty($
|
58 |
-
$attributesArray = explode(',', $
|
59 |
-
|
60 |
-
if(in_array('configurable_attributes',$attributesArray)){
|
61 |
-
$this->_addConfigurableAttributes = true;
|
62 |
-
}
|
63 |
-
if(in_array('configurations',$attributesArray)){
|
64 |
-
$this->_addConfigurations = true;
|
65 |
-
}
|
66 |
}
|
67 |
|
|
|
|
|
68 |
// get order
|
69 |
if (!empty($order)) {
|
70 |
$order = explode(',', $order);
|
@@ -125,7 +156,12 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
125 |
$categoryId = Mage::app()->getStore()->getRootCategoryId();
|
126 |
$categoryNotSet = true;
|
127 |
}
|
|
|
128 |
$category = Mage::getModel('catalog/category')->load($categoryId);
|
|
|
|
|
|
|
|
|
129 |
// apply search
|
130 |
if ($categoryId && !$categoryNotSet) {
|
131 |
$collection->addCategoryFilter($category);
|
@@ -135,27 +171,14 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
135 |
$range = explode(',', $range);
|
136 |
}
|
137 |
|
138 |
-
if (!
|
139 |
-
$
|
140 |
-
} else {
|
141 |
-
$collection->getSelect()->limit(self::RANGE_FALLBACK_RANGE);
|
142 |
-
}
|
143 |
-
|
144 |
-
// apply attributes
|
145 |
-
if (!empty($attributesArray)) {
|
146 |
-
foreach ($attributesArray as $attribute) {
|
147 |
-
$collection->addAttributeToSelect($attribute);
|
148 |
-
if ($attribute == 'media_gallery') {
|
149 |
-
$addGalleryImages = true;
|
150 |
-
}
|
151 |
-
}
|
152 |
}
|
153 |
-
else {
|
154 |
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
|
160 |
//apply filters
|
161 |
if(!empty($filters)) {
|
@@ -169,10 +192,9 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
169 |
}
|
170 |
}
|
171 |
}
|
172 |
-
|
173 |
|
174 |
-
// Apply type filter, we only want Simple and Configurable products in our API
|
175 |
-
$collection->addAttributeToFilter('type_id', array('simple', 'configurable'));
|
176 |
|
177 |
// apply order
|
178 |
if (!empty($order)) {
|
@@ -217,12 +239,6 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
217 |
}
|
218 |
}
|
219 |
|
220 |
-
|
221 |
-
// Add media gallery to collection we cant do this in an earlier stage because it gives really strange results (filter not working, range not working!)
|
222 |
-
if ($addGalleryImages) {
|
223 |
-
$this->_addMediaGalleryAttributeToCollection($collection);
|
224 |
-
}
|
225 |
-
|
226 |
if (!isset($productCount)) {
|
227 |
// get total product count
|
228 |
$productCount = $collection->getSize();
|
@@ -232,13 +248,22 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
232 |
*/
|
233 |
$products = array('products' => array());
|
234 |
|
235 |
-
|
236 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
237 |
}
|
238 |
|
239 |
-
$
|
240 |
-
|
241 |
-
|
|
|
|
|
242 |
$products['product_count'] = $productCount;
|
243 |
|
244 |
$rangeLength = $range[1];
|
@@ -257,14 +282,16 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
257 |
* Gets products for a set of product id's
|
258 |
*
|
259 |
* @param array productIds, product id's to filter on
|
260 |
-
* @param string
|
261 |
-
* @param string Child products attributes, comma seperated string of attributes for the child products
|
262 |
* @param string range, formatted range string
|
|
|
|
|
|
|
263 |
* @return array Array of products
|
264 |
*
|
265 |
*/
|
266 |
|
267 |
-
public function getProductsFilteredByProductIds($productIds = false, $
|
268 |
|
269 |
$products = array('products' => array());
|
270 |
|
@@ -274,34 +301,33 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
274 |
return $products;
|
275 |
}
|
276 |
|
|
|
277 |
$collection = Mage::getModel('catalog/product')->getCollection()->addAttributeToFilter('entity_id', array('in' => $productIds));
|
278 |
|
279 |
// get attributes
|
280 |
-
if (!empty($
|
281 |
-
$attributesArray = explode(',', $
|
282 |
}
|
283 |
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
$collection->addAttributeToSelect($attribute);
|
288 |
-
}
|
289 |
-
} else {
|
290 |
-
// select all attributes
|
291 |
-
$collection->addAttributeToSelect('*');
|
292 |
-
$this->_addMediaGalleryAttributeToCollection($collection);
|
293 |
-
}
|
294 |
|
295 |
if (!empty($range)) {
|
296 |
$range = explode(',', $range);
|
297 |
-
$collection->getSelect()->limit($range[1], $range[0]);
|
298 |
}
|
299 |
|
|
|
|
|
|
|
|
|
|
|
|
|
300 |
// Add 'out of stock' filter, if preffered
|
301 |
if (!Mage::getStoreConfig('cataloginventory/options/show_out_of_stock')) {
|
302 |
Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collection);
|
303 |
|
304 |
-
// For comments, see :
|
305 |
$collectionConfigurable = Mage::getResourceModel('catalog/product_collection')->addAttributeToFilter('type_id', array('eq' => 'configurable'));
|
306 |
$collectionConfigurable->addAttributeToFilter('entity_id', array('in' => $productIds));
|
307 |
|
@@ -321,11 +347,15 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
321 |
/**
|
322 |
* Format result array
|
323 |
*/
|
324 |
-
|
325 |
-
|
|
|
|
|
|
|
|
|
326 |
}
|
327 |
|
328 |
-
$products['product_count'] = $collection->getSize()
|
329 |
|
330 |
$rangeLength = $range[1];
|
331 |
if ($rangeLength > count($products["products"])) {
|
@@ -338,20 +368,19 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
338 |
}
|
339 |
|
340 |
/**
|
341 |
-
* Gets a batch of products for a given comma sepperated productIds
|
342 |
*
|
343 |
-
* @param
|
344 |
-
* @param string Attributes, string of attributes, comma sepperated
|
345 |
-
* @param
|
|
|
346 |
* @return array Product
|
347 |
*/
|
348 |
|
349 |
-
public function getBatchProducts($
|
350 |
-
$idsArray = explode(',', $ids);
|
351 |
-
|
352 |
$products = array();
|
353 |
-
foreach ($
|
354 |
-
$products[] = $this->_getProductAttributes(
|
355 |
}
|
356 |
|
357 |
return $products;
|
@@ -380,8 +409,11 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
380 |
$products = $simple_collection;
|
381 |
} else if($product->getTypeId() == 'simple'){
|
382 |
$products[] = $product;
|
|
|
|
|
|
|
383 |
} else {
|
384 |
-
return;
|
385 |
}
|
386 |
|
387 |
|
@@ -399,14 +431,16 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
399 |
*
|
400 |
* @param string Type, type of related products, can either be 'cross-sell', 'up-sell' or empty, in which case it will return 'regular' related products
|
401 |
* @param int productId, id used for base of related products
|
402 |
-
* @param string Attributes, comma seperated string of attributes
|
403 |
-
* @param string Child products attributes, comma seperated string of attributes for the child products
|
404 |
* @param string range, formatted range string
|
|
|
|
|
|
|
405 |
* @return array Array of product ids
|
406 |
*
|
407 |
*/
|
408 |
|
409 |
-
public function getRelatedProducts($type, $productId = false, $
|
410 |
if (!$productId) {
|
411 |
return;
|
412 |
}
|
@@ -419,7 +453,7 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
419 |
$productIds = $this->getRelatedProductIds($productId);
|
420 |
}
|
421 |
|
422 |
-
return $this->getProductsFilteredByProductIds($productIds, $
|
423 |
|
424 |
}
|
425 |
|
@@ -505,31 +539,38 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
505 |
|
506 |
$layer = Mage::getModel('catalog/layer');
|
507 |
|
508 |
-
//$layered_nav = $this->getLayout()->createBlock('catalog/layer_view');
|
509 |
-
$layered_nav = Highstreet_Hsapi_IndexController::getLayout()->createBlock('catalog/layer_view');
|
510 |
-
$filters = $layered_nav->getFilters();
|
511 |
$category = Mage::getModel('catalog/category')->load($categoryId);
|
512 |
$layer->setCurrentCategory($category);
|
|
|
513 |
$attributes = $layer->getFilterableAttributes('price');
|
514 |
$resultFilters = array();
|
515 |
foreach ($attributes as $attribute) {
|
516 |
-
|
517 |
if ($attribute->getAttributeCode() == 'price') {
|
518 |
$filterBlockName = 'catalog/layer_filter_price';
|
519 |
} else {
|
520 |
$filterBlockName = 'catalog/layer_filter_attribute';
|
521 |
}
|
522 |
-
|
523 |
-
$result =
|
524 |
$options = array();
|
525 |
foreach($result->getItems() as $option) {
|
526 |
-
$
|
527 |
-
$
|
528 |
|
529 |
$count = $option->getData('count');
|
530 |
-
array_push($options, array('
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
531 |
}
|
532 |
-
array_push($resultFilters, array($attribute->getAttributeCode() => $options));
|
533 |
}
|
534 |
|
535 |
return $resultFilters;
|
@@ -540,56 +581,176 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
540 |
* Gets attributes of a given product object.
|
541 |
*
|
542 |
* @param Mage_Catalog_Model_Product ResProduct, a product object
|
543 |
-
* @param string
|
544 |
-
* @param
|
|
|
545 |
* @return array Array with information about the product, according to the Attributes array param
|
546 |
*
|
547 |
*/
|
548 |
|
549 |
-
private function _getProductAttributes($resProduct = false, $
|
550 |
if (!$resProduct) {
|
551 |
return null;
|
552 |
}
|
553 |
|
|
|
554 |
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
559 |
}
|
560 |
-
|
561 |
|
562 |
-
|
563 |
-
|
564 |
-
|
|
|
|
|
|
|
|
|
565 |
|
566 |
-
//always set final price to the special price field
|
567 |
-
if ($attribute === "special_price" || $attribute === "final_price") {
|
568 |
-
$product[$attribute] = $resProduct->getFinalPrice(1);
|
569 |
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
574 |
continue;
|
575 |
}
|
576 |
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
$
|
581 |
-
$
|
|
|
|
|
|
|
|
|
582 |
}
|
583 |
|
584 |
-
|
585 |
-
|
586 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
587 |
}
|
588 |
}
|
589 |
-
|
590 |
}
|
591 |
|
592 |
-
|
593 |
$product['id'] = $resProduct->getId();
|
594 |
|
595 |
|
@@ -603,87 +764,99 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
603 |
$product["special_price"] = null;
|
604 |
}
|
605 |
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
if (in_array("is_salable", $attributes)) {
|
610 |
-
$product["is_salable"] = $resProduct->getData('is_salable');
|
611 |
-
}
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
if(in_array('configurable_attributes',$attributes)){
|
616 |
-
$this->_addConfigurableAttributes = true;
|
617 |
}
|
618 |
|
619 |
-
|
620 |
-
|
|
|
|
|
621 |
}
|
622 |
|
623 |
-
if($resProduct->getTypeId() == 'configurable'){
|
624 |
$conf = Mage::getModel('catalog/product_type_configurable')->setProduct($resProduct);
|
625 |
|
626 |
//build the configuration_attributes array
|
627 |
$configurableAttributes = $conf->getConfigurableAttributesAsArray($resProduct);
|
628 |
|
629 |
$tmpConfigurableAttributes = array();
|
630 |
-
foreach($configurableAttributes as $attribute)
|
631 |
-
{
|
632 |
array_push($tmpConfigurableAttributes,$attribute['attribute_code']);
|
633 |
-
//array_push($simpleCollectionAttributes,$attribute['attribute_code']);
|
634 |
-
}
|
635 |
-
if($this->_addConfigurableAttributes == true){
|
636 |
-
$product['configurable_attributes'] = $tmpConfigurableAttributes;
|
637 |
}
|
638 |
|
|
|
|
|
639 |
//build the configuration_attributes array if we want to display these
|
640 |
-
|
|
|
|
|
|
|
641 |
|
642 |
-
|
643 |
-
|
644 |
-
->
|
645 |
-
|
646 |
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
if(!$child_product_attributes)
|
653 |
-
$child_product_attributes = "entity_id,created_at,description,special_price,updated_at,image,sku,short_description,price,manufacturer";
|
654 |
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
|
|
|
|
|
|
659 |
|
660 |
-
|
661 |
-
$configuration = array();
|
662 |
|
|
|
|
|
663 |
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
669 |
|
670 |
-
|
671 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
672 |
}
|
|
|
673 |
}
|
674 |
|
675 |
-
|
|
|
|
|
676 |
}
|
677 |
|
678 |
$this->_convertProductDates($product);
|
679 |
|
680 |
$product = $this->_setImagePaths($product);
|
681 |
|
682 |
-
//media gallery
|
683 |
-
if(array_key_exists("media_gallery", $product)) {
|
684 |
-
$product["media_gallery"] = $this->_getMediaGalleryImagesForProductID($product["id"]);
|
685 |
-
}
|
686 |
-
|
687 |
return $product;
|
688 |
}
|
689 |
|
@@ -715,58 +888,6 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
715 |
|
716 |
}
|
717 |
|
718 |
-
/**
|
719 |
-
* Load media gallery in collection
|
720 |
-
*/
|
721 |
-
private function _addMediaGalleryAttributeToCollection(Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection $_productCollection) {
|
722 |
-
|
723 |
-
if (count($_productCollection == 0))
|
724 |
-
return $_productCollection;
|
725 |
-
|
726 |
-
$_mediaGalleryAttributeId = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'media_gallery')->getAttributeId();
|
727 |
-
$_read = Mage::getSingleton('core/resource')->getConnection('catalog_read');
|
728 |
-
|
729 |
-
$_mediaGalleryData = $_read->fetchAll('
|
730 |
-
SELECT
|
731 |
-
main.entity_id, `main`.`value_id`, `main`.`value` AS `file`,
|
732 |
-
`value`.`label`, `value`.`position`, `value`.`disabled`, `default_value`.`label` AS `label_default`,
|
733 |
-
`default_value`.`position` AS `position_default`,
|
734 |
-
`default_value`.`disabled` AS `disabled_default`
|
735 |
-
FROM `catalog_product_entity_media_gallery` AS `main`
|
736 |
-
LEFT JOIN `catalog_product_entity_media_gallery_value` AS `value`
|
737 |
-
ON main.value_id=value.value_id AND value.store_id=' . Mage::app()->getStore()->getId() . '
|
738 |
-
LEFT JOIN `catalog_product_entity_media_gallery_value` AS `default_value`
|
739 |
-
ON main.value_id=default_value.value_id AND default_value.store_id=0
|
740 |
-
WHERE (
|
741 |
-
main.attribute_id = ' . $_read->quote($_mediaGalleryAttributeId) . ')
|
742 |
-
AND (main.entity_id IN (' . $_read->quote($_productCollection->getAllIds()) . '))
|
743 |
-
ORDER BY IF(value.position IS NULL, default_value.position, value.position) ASC
|
744 |
-
');
|
745 |
-
|
746 |
-
|
747 |
-
$_mediaGalleryByProductId = array();
|
748 |
-
foreach ($_mediaGalleryData as $_galleryImage) {
|
749 |
-
$k = $_galleryImage['entity_id'];
|
750 |
-
unset($_galleryImage['entity_id']);
|
751 |
-
if (!isset($_mediaGalleryByProductId[$k])) {
|
752 |
-
$_mediaGalleryByProductId[$k] = array();
|
753 |
-
}
|
754 |
-
$_galleryImage['file'] = self::PRODUCTS_MEDIA_PATH . $_galleryImage['file'];
|
755 |
-
$_mediaGalleryByProductId[$k][] = $_galleryImage;
|
756 |
-
}
|
757 |
-
unset($_mediaGalleryData);
|
758 |
-
|
759 |
-
foreach ($_productCollection as &$_product) {
|
760 |
-
$_productId = $_product->getData('entity_id');
|
761 |
-
if (isset($_mediaGalleryByProductId[$_productId])) {
|
762 |
-
$_product->setData('media_gallery', array('images' => $_mediaGalleryByProductId[$_productId]));
|
763 |
-
}
|
764 |
-
}
|
765 |
-
unset($_mediaGalleryByProductId);
|
766 |
-
|
767 |
-
return $_productCollection;
|
768 |
-
}
|
769 |
-
|
770 |
/**
|
771 |
* Gets stock (voorraad) information about a certain product
|
772 |
*
|
@@ -793,32 +914,6 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
793 |
return $stockinfo;
|
794 |
}
|
795 |
|
796 |
-
/**
|
797 |
-
* Gets system attributes. This function is used when there are no attributes give as a param in the URL of the API call
|
798 |
-
*
|
799 |
-
* @return array Array with attribute names
|
800 |
-
*/
|
801 |
-
|
802 |
-
private function _getSystemAttributes() {
|
803 |
-
|
804 |
-
$entityTypeId = Mage::getModel('catalog/product')->getResource()->getEntityType()->getId();
|
805 |
-
|
806 |
-
// get only system attributes
|
807 |
-
$attributes = Mage::getResourceModel('eav/entity_attribute_collection')
|
808 |
-
->setEntityTypeFilter($entityTypeId)
|
809 |
-
->addFieldToFilter('main_table.is_user_defined', 0)
|
810 |
-
->addFieldToFilter('additional_table.is_visible', 1);
|
811 |
-
|
812 |
-
$attributeNames = array();
|
813 |
-
|
814 |
-
foreach($attributes as $attribute) {
|
815 |
-
$attributeNames[] = $attribute->getName();
|
816 |
-
}
|
817 |
-
|
818 |
-
return $attributeNames;
|
819 |
-
}
|
820 |
-
|
821 |
-
|
822 |
/**
|
823 |
* Sets the image paths properly with the relative path.
|
824 |
*
|
@@ -829,29 +924,19 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
829 |
if (!$product) {
|
830 |
return $product;
|
831 |
}
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
$product['thumbnail'] = self::PRODUCTS_MEDIA_PATH . $product['thumbnail'];
|
844 |
-
else
|
845 |
-
$product['thumbnail'] = null;
|
846 |
-
}
|
847 |
-
|
848 |
-
if (array_key_exists('small_image', $product) && !strstr($product['small_image'], self::PRODUCTS_MEDIA_PATH)) {
|
849 |
-
if($product['small_image'] != self::NO_IMAGE_PATH)
|
850 |
-
$product['small_image'] = self::PRODUCTS_MEDIA_PATH . $product['small_image'];
|
851 |
-
else
|
852 |
-
$product['small_image'] = null;
|
853 |
}
|
854 |
-
|
855 |
return $product;
|
856 |
}
|
857 |
|
@@ -880,9 +965,19 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
|
880 |
$output[] = $imageData;
|
881 |
}
|
882 |
|
883 |
-
return
|
884 |
}
|
885 |
|
886 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
887 |
|
888 |
}
|
8 |
*/
|
9 |
class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
|
10 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
const PRODUCTS_MEDIA_PATH = '/media/catalog/product';
|
12 |
const NO_IMAGE_PATH = 'no_selection';
|
13 |
const RANGE_FALLBACK_RANGE = 100;
|
16 |
/**
|
17 |
* Gets a single product for a given productId and attributes
|
18 |
*
|
19 |
+
* @param object Product object for the product to be gotten
|
20 |
+
* @param string Additional Attributes, string of attributes straight from the URL
|
21 |
+
* @param bool include_configuration_details, weather to include child products in the product object and configurable attributes (For both configurable products and bundled products)
|
22 |
+
* @param bool include_media_gallery, weather to include the media gallery in the product object
|
23 |
* @return array Product
|
24 |
*/
|
25 |
+
public function getSingleProduct($productObject = false, $additional_attributes, $include_configuration_details, $include_media_gallery)
|
26 |
{
|
27 |
+
if (!$productObject) {
|
28 |
+
return null;
|
29 |
}
|
|
|
|
|
30 |
|
31 |
+
return $this->_getProductAttributes($productObject, $additional_attributes, $include_configuration_details, $include_media_gallery);
|
32 |
+
}
|
33 |
+
|
34 |
+
public function productHasBeenModifiedSince($productObject = false, $since) {
|
35 |
+
if (!is_numeric($since)) {
|
36 |
+
if (($since = strtotime($since)) === false) {
|
37 |
+
return true; // String to time failed to convert, return the product as if it was modified
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
if (!$productObject) {
|
42 |
+
return false;
|
43 |
+
}
|
44 |
+
|
45 |
+
if (strtotime($productObject->getUpdatedAt()) >= $since) {
|
46 |
+
return true;
|
47 |
+
}
|
48 |
+
|
49 |
+
if ($productObject->getTypeId() == 'configurable') {
|
50 |
+
$conf = Mage::getModel('catalog/product_type_configurable')->setProduct($productObject);
|
51 |
+
$simple_collection = $conf->getUsedProductCollection()
|
52 |
+
->addAttributeToSelect(array('updated_at'));
|
53 |
+
|
54 |
+
foreach ($simple_collection as $product) {
|
55 |
+
if (strtotime($product->getUpdatedAt()) >= $since) {
|
56 |
+
return true;
|
57 |
+
}
|
58 |
+
}
|
59 |
+
} elseif ($productObject->getTypeId() == 'bundle') {
|
60 |
+
$bundleProduct = Mage::getModel('bundle/product_type')->setProduct($productObject);
|
61 |
+
$bundleProducts = $bundleProduct->getSelectionsCollection($bundleProduct->getOptionsIds());
|
62 |
+
|
63 |
+
foreach ($bundleProducts as $product) {
|
64 |
+
if (strtotime($product->getUpdatedAt()) >= $since) {
|
65 |
+
return true;
|
66 |
+
}
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
return false;
|
71 |
}
|
72 |
|
73 |
/**
|
74 |
* Gets products with attributes for given order, range, filters, search and categoryId
|
75 |
*
|
76 |
+
* @param string Additional Attributes, string of attributes straight from the URL
|
|
|
77 |
* @param string Order, order for the products
|
78 |
* @param string Range of products. Must formatted like "0,10" where 0 is the offset and 10 is the count
|
79 |
* @param string Search string for filtering on keywords
|
80 |
* @param integer CategoryId, category id of the category which will be used to filter
|
81 |
+
* @param boolean Hide attributes, only returns product ID's (vastly improving the speed of the API)
|
82 |
+
* @param boolean Hide filters, hides filters if set to true
|
83 |
+
* @param bool include_configuration_details, weather to include child products in the product object and configurable attributes (For both configurable products and bundled products)
|
84 |
+
* @param bool include_media_gallery, weather to include the media gallery in the product object
|
85 |
* @return array Product
|
86 |
*/
|
87 |
+
public function getProductsForResponse($additional_attributes, $order, $range, $filters, $search, $categoryId, $hideAttributes, $hideFilters, $include_configuration_details, $include_media_gallery)
|
88 |
{
|
|
|
89 |
$searching = !empty($search);
|
90 |
|
91 |
+
$attributesArray = array();
|
92 |
// get attributes
|
93 |
+
if (!empty($additional_attributes)) {
|
94 |
+
$attributesArray = explode(',', $additional_attributes);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
}
|
96 |
|
97 |
+
$attributesArray = array_merge($attributesArray, $this->_getCoreAttributes());
|
98 |
+
|
99 |
// get order
|
100 |
if (!empty($order)) {
|
101 |
$order = explode(',', $order);
|
156 |
$categoryId = Mage::app()->getStore()->getRootCategoryId();
|
157 |
$categoryNotSet = true;
|
158 |
}
|
159 |
+
|
160 |
$category = Mage::getModel('catalog/category')->load($categoryId);
|
161 |
+
if ($category->getId() === NULL) {
|
162 |
+
return array();
|
163 |
+
}
|
164 |
+
|
165 |
// apply search
|
166 |
if ($categoryId && !$categoryNotSet) {
|
167 |
$collection->addCategoryFilter($category);
|
171 |
$range = explode(',', $range);
|
172 |
}
|
173 |
|
174 |
+
if (!is_array($range)) {
|
175 |
+
$range = array(0, self::RANGE_FALLBACK_RANGE);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
}
|
|
|
177 |
|
178 |
+
$collection->getSelect()->limit($range[1], $range[0]);
|
179 |
+
|
180 |
+
// apply attributes
|
181 |
+
$collection->addAttributeToSelect($attributesArray);
|
182 |
|
183 |
//apply filters
|
184 |
if(!empty($filters)) {
|
192 |
}
|
193 |
}
|
194 |
}
|
|
|
195 |
|
196 |
+
// Apply type filter, we only want Simple and Configurable and Bundle products in our API
|
197 |
+
$collection->addAttributeToFilter('type_id', array('simple', 'configurable', 'bundle'));
|
198 |
|
199 |
// apply order
|
200 |
if (!empty($order)) {
|
239 |
}
|
240 |
}
|
241 |
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
if (!isset($productCount)) {
|
243 |
// get total product count
|
244 |
$productCount = $collection->getSize();
|
248 |
*/
|
249 |
$products = array('products' => array());
|
250 |
|
251 |
+
// If range requests no products to be returned, return no products. The limit() doesn't take 0 for an answer
|
252 |
+
if ($range[1] > 0) {
|
253 |
+
if (!$hideAttributes) {
|
254 |
+
foreach($collection as $product) {
|
255 |
+
array_push($products['products'], $this->_getProductAttributes($product, $additional_attributes, $include_configuration_details, $include_media_gallery));
|
256 |
+
}
|
257 |
+
} else {
|
258 |
+
$products['products'] = $collection->getAllIds($range[1], $range[0]);
|
259 |
+
}
|
260 |
}
|
261 |
|
262 |
+
$products['filters'] = array();
|
263 |
+
if (!$hideFilters) {
|
264 |
+
$products['filters'] = $this->getFilters($categoryId);
|
265 |
+
}
|
266 |
+
|
267 |
$products['product_count'] = $productCount;
|
268 |
|
269 |
$rangeLength = $range[1];
|
282 |
* Gets products for a set of product id's
|
283 |
*
|
284 |
* @param array productIds, product id's to filter on
|
285 |
+
* @param string additional_attributes, comma seperated string of attributes
|
|
|
286 |
* @param string range, formatted range string
|
287 |
+
* @param boolean Hide Attributes, only returns product ID's (vastly improving the speed of the API)
|
288 |
+
* @param bool include_configuration_details, weather to include child products in the product object and configurable attributes (For both configurable products and bundled products)
|
289 |
+
* @param bool include_media_gallery, weather to include the media gallery in the product object
|
290 |
* @return array Array of products
|
291 |
*
|
292 |
*/
|
293 |
|
294 |
+
public function getProductsFilteredByProductIds($productIds = false, $additional_attributes, $range, $hideAttributes, $include_configuration_details, $include_media_gallery) {
|
295 |
|
296 |
$products = array('products' => array());
|
297 |
|
301 |
return $products;
|
302 |
}
|
303 |
|
304 |
+
|
305 |
$collection = Mage::getModel('catalog/product')->getCollection()->addAttributeToFilter('entity_id', array('in' => $productIds));
|
306 |
|
307 |
// get attributes
|
308 |
+
if (!empty($additional_attributes)) {
|
309 |
+
$attributesArray = explode(',', $additional_attributes);
|
310 |
}
|
311 |
|
312 |
+
$attributesArray = array_merge($attributesArray, $this->_getCoreAttributes());
|
313 |
+
|
314 |
+
$collection->addAttributeToSelect($attributesArray);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
315 |
|
316 |
if (!empty($range)) {
|
317 |
$range = explode(',', $range);
|
|
|
318 |
}
|
319 |
|
320 |
+
if (!is_array($range)) {
|
321 |
+
$range = array(0, self::RANGE_FALLBACK_RANGE);
|
322 |
+
}
|
323 |
+
|
324 |
+
$collection->getSelect()->limit($range[1], $range[0]);
|
325 |
+
|
326 |
// Add 'out of stock' filter, if preffered
|
327 |
if (!Mage::getStoreConfig('cataloginventory/options/show_out_of_stock')) {
|
328 |
Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collection);
|
329 |
|
330 |
+
// For comments, see :222
|
331 |
$collectionConfigurable = Mage::getResourceModel('catalog/product_collection')->addAttributeToFilter('type_id', array('eq' => 'configurable'));
|
332 |
$collectionConfigurable->addAttributeToFilter('entity_id', array('in' => $productIds));
|
333 |
|
347 |
/**
|
348 |
* Format result array
|
349 |
*/
|
350 |
+
if (!$hideAttributes) {
|
351 |
+
foreach($collection as $product) {
|
352 |
+
array_push($products['products'], $this->_getProductAttributes($product, $additional_attributes, $include_configuration_details, $include_media_gallery));
|
353 |
+
}
|
354 |
+
} else {
|
355 |
+
$products['products'] = $collection->getAllIds();
|
356 |
}
|
357 |
|
358 |
+
$products['product_count'] = $collection->getSize();
|
359 |
|
360 |
$rangeLength = $range[1];
|
361 |
if ($rangeLength > count($products["products"])) {
|
368 |
}
|
369 |
|
370 |
/**
|
371 |
+
* Gets a batch of products for a given comma sepperated productIds and attributes
|
372 |
*
|
373 |
+
* @param array ProductObjects, array of Magento product Objects
|
374 |
+
* @param string Additional Attributes, string of attributes, comma sepperated
|
375 |
+
* @param bool include_configuration_details, weather to include child products in the product object and configurable attributes (For both configurable products and bundled products)
|
376 |
+
* @param bool include_media_gallery, weather to include the media gallery in the product object
|
377 |
* @return array Product
|
378 |
*/
|
379 |
|
380 |
+
public function getBatchProducts($productObjects, $additional_attributes, $include_configuration_details, $include_media_gallery) {
|
|
|
|
|
381 |
$products = array();
|
382 |
+
foreach ($productObjects as $productObject) {
|
383 |
+
$products[] = $this->_getProductAttributes($productObject, $additional_attributes, $include_configuration_details, $include_media_gallery);
|
384 |
}
|
385 |
|
386 |
return $products;
|
409 |
$products = $simple_collection;
|
410 |
} else if($product->getTypeId() == 'simple'){
|
411 |
$products[] = $product;
|
412 |
+
} else if($product->getTypeId() == 'bundle'){
|
413 |
+
$bundleProduct = Mage::getModel('bundle/product_type')->setProduct($product);
|
414 |
+
$products = $bundleProduct->getSelectionsCollection($bundleProduct->getOptionsIds());
|
415 |
} else {
|
416 |
+
return;
|
417 |
}
|
418 |
|
419 |
|
431 |
*
|
432 |
* @param string Type, type of related products, can either be 'cross-sell', 'up-sell' or empty, in which case it will return 'regular' related products
|
433 |
* @param int productId, id used for base of related products
|
434 |
+
* @param string Additonal Attributes, comma seperated string of attributes
|
|
|
435 |
* @param string range, formatted range string
|
436 |
+
* @param boolean Hide attributes, only return product ID's (vastly improving the speed of the API)
|
437 |
+
* @param bool include_configuration_details, weather to include child products in the product object and configurable attributes (For both configurable products and bundled products)
|
438 |
+
* @param bool include_media_gallery, weather to include the media gallery in the product object
|
439 |
* @return array Array of product ids
|
440 |
*
|
441 |
*/
|
442 |
|
443 |
+
public function getRelatedProducts($type, $productId = false, $additional_attributes, $range, $hideAttributes, $include_configuration_details, $include_media_gallery) {
|
444 |
if (!$productId) {
|
445 |
return;
|
446 |
}
|
453 |
$productIds = $this->getRelatedProductIds($productId);
|
454 |
}
|
455 |
|
456 |
+
return $this->getProductsFilteredByProductIds($productIds, $additional_attributes, $range, $hideAttributes, $include_configuration_details, $include_media_gallery);
|
457 |
|
458 |
}
|
459 |
|
539 |
|
540 |
$layer = Mage::getModel('catalog/layer');
|
541 |
|
|
|
|
|
|
|
542 |
$category = Mage::getModel('catalog/category')->load($categoryId);
|
543 |
$layer->setCurrentCategory($category);
|
544 |
+
$controller = @Mage_Core_Controller_Front_Action::getLayout();
|
545 |
$attributes = $layer->getFilterableAttributes('price');
|
546 |
$resultFilters = array();
|
547 |
foreach ($attributes as $attribute) {
|
|
|
548 |
if ($attribute->getAttributeCode() == 'price') {
|
549 |
$filterBlockName = 'catalog/layer_filter_price';
|
550 |
} else {
|
551 |
$filterBlockName = 'catalog/layer_filter_attribute';
|
552 |
}
|
553 |
+
|
554 |
+
$result = $controller->createBlock($filterBlockName)->setLayer($layer)->setAttributeModel($attribute)->init();
|
555 |
$options = array();
|
556 |
foreach($result->getItems() as $option) {
|
557 |
+
$title = str_replace('<span class="price">', "", $option->getLabel());
|
558 |
+
$title = str_replace('</span>', "", $title);
|
559 |
|
560 |
$count = $option->getData('count');
|
561 |
+
array_push($options, array('value' => $option->getValue(), 'title' => $title, 'product_count' => $count));
|
562 |
+
}
|
563 |
+
|
564 |
+
if (count($options) > 0) {
|
565 |
+
array_push($resultFilters,
|
566 |
+
array(
|
567 |
+
'title' => $attribute->getData('frontend_label'),
|
568 |
+
'type' => $attribute->getFrontendInput(),
|
569 |
+
'code' => $attribute->getAttributeCode(),
|
570 |
+
'options' => $options
|
571 |
+
)
|
572 |
+
);
|
573 |
}
|
|
|
574 |
}
|
575 |
|
576 |
return $resultFilters;
|
581 |
* Gets attributes of a given product object.
|
582 |
*
|
583 |
* @param Mage_Catalog_Model_Product ResProduct, a product object
|
584 |
+
* @param string Additional_attributes, an string of attributes to get for the product, comma delimited
|
585 |
+
* @param bool include_configuration_details, weather to include child products in the product object and configurable attributes (For both configurable products and bundled products). Default value is fale
|
586 |
+
* @param bool include_media_gallery, weather to include the media gallery in the product object. Default value is fale
|
587 |
* @return array Array with information about the product, according to the Attributes array param
|
588 |
*
|
589 |
*/
|
590 |
|
591 |
+
private function _getProductAttributes($resProduct = false, $additional_attributes = nil, $include_configuration_details = false, $include_media_gallery = false) {
|
592 |
if (!$resProduct) {
|
593 |
return null;
|
594 |
}
|
595 |
|
596 |
+
$product = array();
|
597 |
|
598 |
+
$attributes = $this->_getCoreAttributes();
|
599 |
+
|
600 |
+
foreach ($attributes as $attribute) {
|
601 |
+
//always set final price to the special price field
|
602 |
+
if ($attribute === "special_price" || $attribute === "final_price") {
|
603 |
+
$product[$attribute] = $resProduct->getFinalPrice(1);
|
604 |
+
|
605 |
+
if ($product[$attribute] === false) {
|
606 |
+
$product[$attribute] = null;
|
607 |
+
}
|
608 |
+
|
609 |
+
continue;
|
610 |
+
}
|
611 |
+
|
612 |
+
if ($attribute === "is_salable") {
|
613 |
+
$product["is_salable"] = (bool)$resProduct->getData('is_salable');
|
614 |
+
continue;
|
615 |
+
}
|
616 |
+
|
617 |
+
// Translate this into an array of "translations" if we run into more problems
|
618 |
+
$fieldName = $attribute;
|
619 |
+
if ($attribute == "type") {
|
620 |
+
$attribute = "type_id";
|
621 |
+
$fieldName = "type";
|
622 |
+
}
|
623 |
+
|
624 |
+
if ($resProduct->getResource()->getAttribute($attribute)) {
|
625 |
+
$value = $resProduct->getResource()->getAttribute($attribute)->getFrontend()->getValue($resProduct);
|
626 |
+
$product[$fieldName] = $value;
|
627 |
+
}
|
628 |
}
|
|
|
629 |
|
630 |
+
$product['images'] = array();
|
631 |
+
$product['images']['small_image'] = $product['small_image'];
|
632 |
+
$product['images']['image'] = $product['image'];
|
633 |
+
$product['images']['thumbnail'] = $product['thumbnail'];
|
634 |
+
unset($product['small_image']);
|
635 |
+
unset($product['image']);
|
636 |
+
unset($product['thumbnail']);
|
637 |
|
|
|
|
|
|
|
638 |
|
639 |
+
if (!empty($additional_attributes)) {
|
640 |
+
$additionalAttributesArray = explode(',', $additional_attributes);
|
641 |
+
}
|
642 |
|
643 |
+
$product['attribute_values'] = array(); // Make sure to always return an object for this key
|
644 |
+
// if additional attributes specified
|
645 |
+
if (!empty($additionalAttributesArray) && count($additionalAttributesArray) > 0) {
|
646 |
+
$attributesModel = Mage::getModel('highstreet_hsapi/attributes');
|
647 |
+
|
648 |
+
foreach ($additionalAttributesArray as $attribute) {
|
649 |
+
if ($attribute == "media_gallery") {
|
650 |
continue;
|
651 |
}
|
652 |
|
653 |
+
if ($attribute === "share_url") {
|
654 |
+
$additionalAttributeData = array();
|
655 |
+
$additionalAttributeData['title'] = "Share url";
|
656 |
+
$additionalAttributeData['code'] = "share_url";
|
657 |
+
$additionalAttributeData['type'] = "url";
|
658 |
+
$additionalAttributeData['inline_value'] = $resProduct->getProductUrl();
|
659 |
+
$product['attribute_values'][] = $additionalAttributeData;
|
660 |
+
|
661 |
+
continue;
|
662 |
}
|
663 |
|
664 |
+
$attributeObject = $resProduct->getResource()->getAttribute($attribute);
|
665 |
+
|
666 |
+
if ($attributeObject !== false) {
|
667 |
+
$readableAttributeValue = $attributeObject->getFrontend()->getValue($resProduct); // 'frontend' value, human readable value
|
668 |
+
|
669 |
+
$attributesData = $attributesModel->getAttribute($attribute);
|
670 |
+
|
671 |
+
if ($attributesData['title'] == null ||
|
672 |
+
$attributesData['code'] == null ||
|
673 |
+
$attributeObject->getFrontendInput() == null) {
|
674 |
+
continue;
|
675 |
+
}
|
676 |
+
|
677 |
+
// Pre-make attribute object to be put into json
|
678 |
+
$additionalAttributeData = array();
|
679 |
+
$additionalAttributeData['title'] = $attributesData['title'];
|
680 |
+
$additionalAttributeData['code'] = $attributesData['code'];
|
681 |
+
$additionalAttributeData['type'] = $attributeObject->getFrontendInput();
|
682 |
+
|
683 |
+
// Switch statement from /app/code/core/Mage/Catalog/Model/Product/Attribute/Api.php:301
|
684 |
+
// Gets all attribute types and fill in the value field of the attribute object
|
685 |
+
switch ($attributesData['type']) {
|
686 |
+
case 'text':
|
687 |
+
case 'textarea':
|
688 |
+
case 'price':
|
689 |
+
$additionalAttributeData['inline_value'] = $readableAttributeValue;
|
690 |
+
break;
|
691 |
+
case 'date':
|
692 |
+
if ($readableAttributeValue == null) {
|
693 |
+
$additionalAttributeData['inline_value'] = null;
|
694 |
+
} else {
|
695 |
+
$additionalAttributeData['inline_value'] = strtotime($readableAttributeValue);
|
696 |
+
}
|
697 |
+
|
698 |
+
$additionalAttributeData['raw_value'] = $readableAttributeValue;
|
699 |
+
break;
|
700 |
+
case 'boolean':
|
701 |
+
$attributeMethod = "get" . uc_words($attribute);
|
702 |
+
$idAttributeValue = $resProduct->$attributeMethod();
|
703 |
+
$additionalAttributeData['raw_value'] = $readableAttributeValue;
|
704 |
+
$additionalAttributeData['inline_value'] = ($idAttributeValue == 1 ? true : false);
|
705 |
+
break;
|
706 |
+
case 'select':
|
707 |
+
case 'multiselect':
|
708 |
+
$hasFoundValue = false;
|
709 |
+
$additionalAttributeData['value'] = array();
|
710 |
+
|
711 |
+
$mutliSelectValues = $resProduct->getAttributeText($attribute); // Get values for multiselect type (array)
|
712 |
+
|
713 |
+
// Loop trough select options of attribute
|
714 |
+
foreach ($attributesData['options'] as $key => $value) {
|
715 |
+
if (($value->title === $readableAttributeValue && $attributesData['type'] === 'select') || // If attribute type is single select option, check title
|
716 |
+
((is_array($mutliSelectValues) && in_array($value->title, $mutliSelectValues) || ($value->title === $mutliSelectValues)) &&
|
717 |
+
$attributesData['type'] === 'multiselect') // If attribute type is multi select option, check if value is in array of possible options or equal to the title
|
718 |
+
) {
|
719 |
+
$attributeValueObject = array();
|
720 |
+
$attributeValueObject['id'] = $value->value;
|
721 |
+
$attributeValueObject['title'] = $value->title;
|
722 |
+
$attributeValueObject['sort_hint'] = $value->sort_hint;
|
723 |
+
$additionalAttributeData['value'][] = $attributeValueObject;
|
724 |
+
$hasFoundValue = true;
|
725 |
+
|
726 |
+
if ($attributesData['type'] === 'select') {
|
727 |
+
break; // single select option doesn't have to loop trough all possibilities
|
728 |
+
}
|
729 |
+
}
|
730 |
+
}
|
731 |
+
|
732 |
+
// If type is select and there is only one element, return the element as an object and not an array with 1 object
|
733 |
+
if ($attributesData['type'] == 'select' && count($additionalAttributeData['value']) == 1) {
|
734 |
+
$additionalAttributeData['value'] = $additionalAttributeData['value'][0];
|
735 |
+
}
|
736 |
+
|
737 |
+
// No value was found, make value field in attribute object null
|
738 |
+
if (!$hasFoundValue) {
|
739 |
+
$additionalAttributeData['value'] = null;
|
740 |
+
}
|
741 |
+
break;
|
742 |
+
default:
|
743 |
+
if ($readableAttributeValue != null) {
|
744 |
+
$additionalAttributeData['inline_value'] = $readableAttributeValue;
|
745 |
+
}
|
746 |
+
break;
|
747 |
+
}
|
748 |
+
|
749 |
+
$product['attribute_values'][] = $additionalAttributeData;
|
750 |
}
|
751 |
}
|
|
|
752 |
}
|
753 |
|
|
|
754 |
$product['id'] = $resProduct->getId();
|
755 |
|
756 |
|
764 |
$product["special_price"] = null;
|
765 |
}
|
766 |
|
767 |
+
|
768 |
+
if ($resProduct->getTypeId() == 'bundle') {
|
769 |
+
$product["price"] = Mage::getModel('bundle/product_price')->getTotalPrices($resProduct,'min',1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
770 |
}
|
771 |
|
772 |
+
|
773 |
+
if ($include_media_gallery) {
|
774 |
+
$mediaGalleryValue = $this->_getMediaGalleryImagesForProductID($product["id"]);
|
775 |
+
$product['media_gallery'] = $mediaGalleryValue;
|
776 |
}
|
777 |
|
778 |
+
if($resProduct->getTypeId() == 'configurable' && $include_configuration_details){
|
779 |
$conf = Mage::getModel('catalog/product_type_configurable')->setProduct($resProduct);
|
780 |
|
781 |
//build the configuration_attributes array
|
782 |
$configurableAttributes = $conf->getConfigurableAttributesAsArray($resProduct);
|
783 |
|
784 |
$tmpConfigurableAttributes = array();
|
785 |
+
foreach($configurableAttributes as $attribute) {
|
|
|
786 |
array_push($tmpConfigurableAttributes,$attribute['attribute_code']);
|
|
|
|
|
|
|
|
|
787 |
}
|
788 |
|
789 |
+
$product['configurable_attributes'] = $tmpConfigurableAttributes;
|
790 |
+
|
791 |
//build the configuration_attributes array if we want to display these
|
792 |
+
$product['child_products'] = array();
|
793 |
+
$simple_collection = $conf->getUsedProductCollection()
|
794 |
+
->addAttributeToSelect('*')
|
795 |
+
->addFilterByRequiredOptions();
|
796 |
|
797 |
+
foreach($simple_collection as $simple_product){
|
798 |
+
if(!Mage::getStoreConfig('cataloginventory/options/show_out_of_stock')
|
799 |
+
&& !$simple_product->isSaleable())
|
800 |
+
continue;
|
801 |
|
802 |
+
$resProduct = Mage::getModel('catalog/product')->load($simple_product->getId());
|
803 |
+
if ($resProduct->getData('status') == Mage_Catalog_Model_Product_Status::STATUS_DISABLED || $resProduct->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_DISABLED ||
|
804 |
+
$resProduct->getData('status') == "Uitgeschakeld" || $resProduct->getStatus() == "Uitgeschakeld") {
|
805 |
+
continue;
|
806 |
+
}
|
|
|
|
|
807 |
|
808 |
+
$simpleProductAdditionalAttributesArray = $product['configurable_attributes']; // A configurable product always has a configuration so 'configurable_attributes' is always filled
|
809 |
+
if (!empty($additionalAttributesArray) && count($additionalAttributesArray) > 0) { // If we want to get additional attributes, merge them
|
810 |
+
$simpleProductAdditionalAttributesArray = array_merge($additionalAttributesArray, $simpleProductAdditionalAttributesArray);
|
811 |
+
}
|
812 |
+
|
813 |
+
$simpleProductAdditionalAttributesArray = array_unique($simpleProductAdditionalAttributesArray); // Make sure that we don't get multiple of the same attributes
|
814 |
+
$simpleProductAdditionalAttributesString = implode($simpleProductAdditionalAttributesArray, ',');
|
815 |
|
816 |
+
$simpleProductObject = $this->_getProductAttributes($resProduct, $simpleProductAdditionalAttributesString, $include_configuration_details, $include_media_gallery);
|
|
|
817 |
|
818 |
+
array_push($product['child_products'], (object)$simpleProductObject);
|
819 |
+
}
|
820 |
|
821 |
+
unset($tmpConfigurableAttributes);
|
822 |
+
}
|
823 |
+
|
824 |
+
if($resProduct->getTypeId() == 'bundle' && $include_configuration_details) {
|
825 |
+
$bundleProduct = Mage::getModel('bundle/product_type')->setProduct($resProduct);
|
826 |
+
$bundles = $bundleProduct->getOptionsCollection()->getData();
|
827 |
+
foreach($bundles as $bundle) {
|
828 |
+
|
829 |
+
$children = $bundleProduct->getSelectionsCollection(array($bundle['option_id']));
|
830 |
+
foreach($children as $child) {
|
831 |
+
|
832 |
+
|
833 |
+
$childRes['position'] = $child->getPosition();
|
834 |
+
$childRes['selection_id'] = $child->getSelectionId();
|
835 |
+
$childRes['selection_qty'] = $child->getSelectionQty();
|
836 |
+
$childRes['selection_can_change_qty'] = $child->getSelectionCanChangeQty();
|
837 |
+
$childRes['is_default'] = $child->getIsDefault();
|
838 |
|
839 |
+
//flinders-specific, but should not throw an error when not implemented
|
840 |
+
$childRes['selection_thumbnail'] = $child->getSelectionThumbnail();
|
841 |
+
$childRes['selection_modified_name'] = $child->getSelectionModifiedname();
|
842 |
+
|
843 |
+
$bundledProductAdditionalAttributesString = implode($additionalAttributesArray, ',');
|
844 |
+
|
845 |
+
$childRes['product'] = $this->_getProductAttributes($child, $bundledProductAdditionalAttributesString, $include_configuration_details, $include_media_gallery);
|
846 |
+
$bundle['children'][] = $childRes;
|
847 |
}
|
848 |
+
$product['bundles'][] = $bundle;
|
849 |
}
|
850 |
|
851 |
+
|
852 |
+
|
853 |
+
|
854 |
}
|
855 |
|
856 |
$this->_convertProductDates($product);
|
857 |
|
858 |
$product = $this->_setImagePaths($product);
|
859 |
|
|
|
|
|
|
|
|
|
|
|
860 |
return $product;
|
861 |
}
|
862 |
|
888 |
|
889 |
}
|
890 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
891 |
/**
|
892 |
* Gets stock (voorraad) information about a certain product
|
893 |
*
|
914 |
return $stockinfo;
|
915 |
}
|
916 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
917 |
/**
|
918 |
* Sets the image paths properly with the relative path.
|
919 |
*
|
924 |
if (!$product) {
|
925 |
return $product;
|
926 |
}
|
927 |
+
|
928 |
+
foreach ($product['images'] as $key => $value) {
|
929 |
+
if (!strstr($value, self::PRODUCTS_MEDIA_PATH)) {
|
930 |
+
if($value != self::NO_IMAGE_PATH && $value != null) {
|
931 |
+
$value = self::PRODUCTS_MEDIA_PATH . $value;
|
932 |
+
} else {
|
933 |
+
$value = null;
|
934 |
+
}
|
935 |
+
}
|
936 |
+
|
937 |
+
$product['images'][$key] = $value;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
938 |
}
|
939 |
+
|
940 |
return $product;
|
941 |
}
|
942 |
|
965 |
$output[] = $imageData;
|
966 |
}
|
967 |
|
968 |
+
return $output;
|
969 |
}
|
970 |
|
971 |
+
/**
|
972 |
+
* Returns an array of all core attributes
|
973 |
+
*
|
974 |
+
* @return array Array of attributes
|
975 |
+
*/
|
976 |
+
private function _getCoreAttributes () {
|
977 |
+
return array("entity_id", "sku", "type", "created_at", "updated_at",
|
978 |
+
"name", "news_from_date", "news_to_date", "price",
|
979 |
+
"image", "small_image", "thumbnail",
|
980 |
+
"special_from_date", "special_to_date", "special_price", "is_salable");
|
981 |
+
}
|
982 |
|
983 |
}
|
app/code/local/Highstreet/Hsapi/Model/System/Config/Environment.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Highstreet_Hsapi_Model_System_Config_Environment {
|
4 |
+
public function toOptionArray()
|
5 |
+
{
|
6 |
+
return array(
|
7 |
+
array(
|
8 |
+
'value' => 'staging',
|
9 |
+
'label' => 'Staging',
|
10 |
+
),
|
11 |
+
array(
|
12 |
+
'value' => 'production',
|
13 |
+
'label' => 'Production',
|
14 |
+
),
|
15 |
+
);
|
16 |
+
}
|
17 |
+
}
|
app/code/local/Highstreet/Hsapi/controllers/.DS_Store
DELETED
Binary file
|
app/code/local/Highstreet/Hsapi/controllers/CheckoutController.php
ADDED
@@ -0,0 +1,630 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Highstreet_HSAPI_module
|
4 |
+
*
|
5 |
+
* @package Highstreet_Hsapi
|
6 |
+
* @author Tim Wachter (tim@touchwonders.com) ~ Touchwonders
|
7 |
+
* @copyright Copyright (c) 2014 Touchwonders b.v. (http://www.touchwonders.com/)
|
8 |
+
*/
|
9 |
+
|
10 |
+
class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Action
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Coupon constants
|
14 |
+
**/
|
15 |
+
const COUPON_SUCCESS_REPLACE = "{coupon_code}";
|
16 |
+
const COUPON_CODE_FATAL = -1;
|
17 |
+
const COUPON_CODE_ERROR = 1;
|
18 |
+
const COUPON_CODE_SUCCESS = 0;
|
19 |
+
const COUPON_CODE_MAX_LENGTH = 255;
|
20 |
+
|
21 |
+
|
22 |
+
public function indexAction() {
|
23 |
+
return false;
|
24 |
+
}
|
25 |
+
|
26 |
+
|
27 |
+
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Gives all the information to make the checkout work from the initial loading of the page.
|
31 |
+
*/
|
32 |
+
public function startAction() {
|
33 |
+
$checkoutModel = Mage::getModel('highstreet_hsapi/checkoutV2');
|
34 |
+
|
35 |
+
$this->_JSONencodeAndRespond($checkoutModel->getStartData());
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Countries action. Returns the available countries for the checkout
|
40 |
+
*/
|
41 |
+
public function countriesAction() {
|
42 |
+
$countryCollection = Mage::getSingleton('directory/country')->getResourceCollection()->loadByStore();
|
43 |
+
$options = $countryCollection->toOptionArray();
|
44 |
+
$returnOptions = array();
|
45 |
+
foreach ($options as $key => $value) {
|
46 |
+
$value['value'] = trim($value['value']);
|
47 |
+
$value['label'] = trim($value['label']);
|
48 |
+
if (empty($value['value']) === false &&
|
49 |
+
empty($value['label']) === false) {
|
50 |
+
$returnOptions[] = array("name" => $value['label'], "code" => $value['value']);
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
$this->_JSONencodeAndRespond($returnOptions);
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Logout action
|
59 |
+
*/
|
60 |
+
public function logoutAction() {
|
61 |
+
Mage::getSingleton('customer/session')->logout();
|
62 |
+
$this->_JSONencodeAndRespond(array("OK"));
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Logs the user in. Gets the parameters "email" and "password" from POST
|
67 |
+
*
|
68 |
+
* @author Tim Wachter
|
69 |
+
*
|
70 |
+
*/
|
71 |
+
public function loginAction() {
|
72 |
+
$session = Mage::getSingleton('customer/session');
|
73 |
+
|
74 |
+
$success = false;
|
75 |
+
$message = "";
|
76 |
+
|
77 |
+
$requestObject = Mage::app()->getRequest();
|
78 |
+
|
79 |
+
$loginArray = $requestObject->getParam('login');
|
80 |
+
|
81 |
+
$email = $loginArray["username"];
|
82 |
+
$password = $loginArray["password"];
|
83 |
+
|
84 |
+
if ($session->isLoggedIn()) {
|
85 |
+
$success = false;
|
86 |
+
$message = "Je bent al ingelogd.";
|
87 |
+
} else {
|
88 |
+
try {
|
89 |
+
if ($session->login($email, $password)) {
|
90 |
+
$success = true;
|
91 |
+
$message = "Je bent succesvol ingelogd.";
|
92 |
+
}
|
93 |
+
} catch (Mage_Core_Exception $e) {
|
94 |
+
switch ($e->getCode()) {
|
95 |
+
case Mage_Customer_Model_Customer::EXCEPTION_EMAIL_NOT_CONFIRMED: { // E-mail not confirmed
|
96 |
+
$success = false;
|
97 |
+
$message = "Je account is nog niet geactiveerd. Je moet je account activeren voordat je kunt inloggen.";
|
98 |
+
break;
|
99 |
+
}
|
100 |
+
case Mage_Customer_Model_Customer::EXCEPTION_INVALID_EMAIL_OR_PASSWORD: { // E-mail or password wrong
|
101 |
+
$success = false;
|
102 |
+
$message = "De combinatie van het ingegeven e-mailadres en wachtwoord is onjuist.";
|
103 |
+
break;
|
104 |
+
}
|
105 |
+
default: {
|
106 |
+
$success = false;
|
107 |
+
$message = "Er heeft zich een onbekende fout voorgedaan. Probeer het later nog eens.";
|
108 |
+
break;
|
109 |
+
}
|
110 |
+
}
|
111 |
+
} catch (Exception $e) {
|
112 |
+
$success = false;
|
113 |
+
$message = "Er heeft zich een onbekende fout voorgedaan. Probeer het later nog eens.";
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
$response = array();
|
118 |
+
$response["success"] = $success;
|
119 |
+
$response["message"] = $message;
|
120 |
+
|
121 |
+
$this->_JSONencodeAndRespond($response);
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Re-used from Mage_Checkout_OnepageController:348
|
126 |
+
*/
|
127 |
+
public function saveMethodAction() {
|
128 |
+
$method = $this->getRequest()->getPost('method');
|
129 |
+
$result = $this->getOnepage()->saveCheckoutMethod($method);
|
130 |
+
$this->_JSONencodeAndRespond($result);
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Largely re-used from Mage_Checkout_OnepageController:363
|
135 |
+
*/
|
136 |
+
public function saveBillingAction() {
|
137 |
+
$data = $this->getRequest()->getPost('billing', array());
|
138 |
+
$customerAddressId = $this->getRequest()->getPost('billing_address_id', false);
|
139 |
+
|
140 |
+
if (isset($data['email'])) {
|
141 |
+
$data['email'] = trim($data['email']);
|
142 |
+
}
|
143 |
+
$result = $this->getOnepage()->saveBilling($data, $customerAddressId);
|
144 |
+
|
145 |
+
if (!isset($result['error'])) {
|
146 |
+
if (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1) {
|
147 |
+
$result['goto_section'] = 'shipping_method';
|
148 |
+
|
149 |
+
$result['update_section'] = array(
|
150 |
+
'name' => 'shipping-method',
|
151 |
+
'data' => $this->_getShippingMethods()
|
152 |
+
);
|
153 |
+
|
154 |
+
$result['allow_sections'] = array('shipping');
|
155 |
+
$result['duplicateBillingInfo'] = 'true';
|
156 |
+
} else {
|
157 |
+
$result['goto_section'] = 'shipping';
|
158 |
+
}
|
159 |
+
}
|
160 |
+
|
161 |
+
$this->_JSONencodeAndRespond($result);
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Largely re-used from Mage_Checkout_OnepageController:405
|
166 |
+
*/
|
167 |
+
public function saveShippingAction()
|
168 |
+
{
|
169 |
+
$data = $this->getRequest()->getPost('shipping', array());
|
170 |
+
$customerAddressId = $this->getRequest()->getPost('shipping_address_id', false);
|
171 |
+
$result = $this->getOnepage()->saveShipping($data, $customerAddressId);
|
172 |
+
|
173 |
+
if (!isset($result['error'])) {
|
174 |
+
$result['goto_section'] = 'shipping_method';
|
175 |
+
$result['update_section'] = array(
|
176 |
+
'name' => 'shipping-method',
|
177 |
+
'data' => $this->_getShippingMethods()
|
178 |
+
);
|
179 |
+
}
|
180 |
+
$this->_JSONencodeAndRespond($result);
|
181 |
+
}
|
182 |
+
|
183 |
+
/**
|
184 |
+
* Largely re-used from Mage_Checkout_OnepageController:429
|
185 |
+
*/
|
186 |
+
public function saveShippingMethodAction()
|
187 |
+
{
|
188 |
+
$data = $this->getRequest()->getPost('shipping_method', '');
|
189 |
+
$result = $this->getOnepage()->saveShippingMethod($data);
|
190 |
+
// $result will contain error data if shipping method is empty
|
191 |
+
if (!$result) {
|
192 |
+
Mage::dispatchEvent(
|
193 |
+
'checkout_controller_onepage_save_shipping_method',
|
194 |
+
array(
|
195 |
+
'request' => $this->getRequest(),
|
196 |
+
'quote' => $this->getOnepage()->getQuote()));
|
197 |
+
$this->getOnepage()->getQuote()->collectTotals();
|
198 |
+
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
|
199 |
+
|
200 |
+
$paymentMethods = array();
|
201 |
+
|
202 |
+
|
203 |
+
$result['goto_section'] = 'payment';
|
204 |
+
$result['update_section'] = array(
|
205 |
+
'name' => 'payment-method',
|
206 |
+
'data' => $this->_getPaymentMethods()
|
207 |
+
);
|
208 |
+
}
|
209 |
+
$this->getOnepage()->getQuote()->collectTotals()->save();
|
210 |
+
$this->_JSONencodeAndRespond($result);
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Adds a coupon to the quote.
|
215 |
+
* Code is partially duplicated from couponPostAction in the Mage_Checkout_CartController
|
216 |
+
*
|
217 |
+
* @author Tim Wachter
|
218 |
+
*
|
219 |
+
*/
|
220 |
+
public function addCouponAction() {
|
221 |
+
$quote = Mage::getModel('checkout/cart')->getQuote();
|
222 |
+
|
223 |
+
// Shopping cart is empty
|
224 |
+
// The checkout should fire a restart
|
225 |
+
if (!$quote->getItemsCount()) {
|
226 |
+
$this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_FATAL, "message" => $this->__('hsapi.addCouponAction.error.fatal')));
|
227 |
+
return;
|
228 |
+
}
|
229 |
+
|
230 |
+
$couponCode = (string) $this->getRequest()->getParam('coupon_code');
|
231 |
+
if ($this->getRequest()->getParam('remove') == 1) {
|
232 |
+
$couponCode = '';
|
233 |
+
}
|
234 |
+
$oldCouponCode = $quote->getCouponCode();
|
235 |
+
|
236 |
+
// No coupon code given
|
237 |
+
if (!strlen($couponCode) && !strlen($oldCouponCode)) {
|
238 |
+
$this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_ERROR, "message" => $this->__('hsapi.addCouponAction.error.invalid')));
|
239 |
+
return;
|
240 |
+
}
|
241 |
+
|
242 |
+
try {
|
243 |
+
$codeLength = strlen($couponCode);
|
244 |
+
|
245 |
+
if ($codeLength >= self::COUPON_CODE_MAX_LENGTH) {
|
246 |
+
$this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_ERROR, "message" => $this->__('hsapi.addCouponAction.error.length') . self::COUPON_CODE_MAX_LENGTH));
|
247 |
+
return;
|
248 |
+
}
|
249 |
+
|
250 |
+
$quote->setCouponCode($couponCode)
|
251 |
+
->collectTotals() // Makes sure that the totals are recalculated with the new discount. Without this the coupon simply gets added, but not calculated in the price
|
252 |
+
->save();
|
253 |
+
|
254 |
+
if ($codeLength) {
|
255 |
+
if ($couponCode == $quote->getCouponCode()) { // Code was successfully added
|
256 |
+
$message = str_replace(self::COUPON_SUCCESS_REPLACE, $this->getRequest()->getParam('coupon_code'), $this->__('hsapi.addCouponAction.success'));
|
257 |
+
$this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_SUCCESS, "message" => $message));
|
258 |
+
return;
|
259 |
+
} else { // Code was not valid
|
260 |
+
$this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_ERROR, "message" => $this->__('hsapi.addCouponAction.error.invalid')));
|
261 |
+
return;
|
262 |
+
}
|
263 |
+
} else {
|
264 |
+
$message = str_replace(self::COUPON_SUCCESS_REPLACE, $this->getRequest()->getParam('coupon_code'), $this->__('hsapi.addCouponAction.success.removed'));
|
265 |
+
$this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_SUCCESS, "message" => $message));
|
266 |
+
return;
|
267 |
+
}
|
268 |
+
|
269 |
+
} catch (Mage_Core_Exception $e) {
|
270 |
+
$this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_FATAL, "message" => $this->__('hsapi.addCouponAction.error.fatal')));
|
271 |
+
return;
|
272 |
+
} catch (Exception $e) {
|
273 |
+
$this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_FATAL, "message" => $this->__('hsapi.addCouponAction.error.fatal')));
|
274 |
+
return;
|
275 |
+
}
|
276 |
+
|
277 |
+
$this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_FATAL, "message" => $this->__('hsapi.addCouponAction.error.fatal')));
|
278 |
+
return;
|
279 |
+
}
|
280 |
+
|
281 |
+
/**
|
282 |
+
* Largely re-used from Mage_Checkout_OnepageController:463
|
283 |
+
*/
|
284 |
+
public function savePaymentAction()
|
285 |
+
{
|
286 |
+
try {
|
287 |
+
$data = $this->getRequest()->getPost('payment', array());
|
288 |
+
$result = $this->getOnepage()->savePayment($data);
|
289 |
+
|
290 |
+
// get section and redirect data
|
291 |
+
$redirectUrl = $this->getOnepage()->getQuote()->getPayment()->getCheckoutRedirectUrl();
|
292 |
+
if (empty($result['error']) && !$redirectUrl) {
|
293 |
+
$result['goto_section'] = 'review';
|
294 |
+
$result['update_section'] = array(
|
295 |
+
'name' => 'review',
|
296 |
+
'data' => $this->_getReviewData()
|
297 |
+
);
|
298 |
+
}
|
299 |
+
if ($redirectUrl) {
|
300 |
+
$result['redirect'] = $redirectUrl;
|
301 |
+
}
|
302 |
+
} catch (Mage_Payment_Exception $e) {
|
303 |
+
if ($e->getFields()) {
|
304 |
+
$result['fields'] = $e->getFields();
|
305 |
+
}
|
306 |
+
$result['error'] = $e->getMessage();
|
307 |
+
} catch (Mage_Core_Exception $e) {
|
308 |
+
$result['error'] = $e->getMessage();
|
309 |
+
} catch (Exception $e) {
|
310 |
+
Mage::logException($e);
|
311 |
+
$result['error'] = $this->__('Unable to set Payment Method.');
|
312 |
+
}
|
313 |
+
$this->_JSONencodeAndRespond($result, false);
|
314 |
+
}
|
315 |
+
|
316 |
+
/**
|
317 |
+
* Largely re-used from Mage_Checkout_OnepageController:543
|
318 |
+
*/
|
319 |
+
public function saveOrderAction() {
|
320 |
+
$result = array();
|
321 |
+
try {
|
322 |
+
$requiredAgreements = Mage::helper('checkout')->getRequiredAgreementIds();
|
323 |
+
if ($requiredAgreements) {
|
324 |
+
$postedAgreements = array_keys($this->getRequest()->getPost('agreement', array()));
|
325 |
+
$diff = array_diff($requiredAgreements, $postedAgreements);
|
326 |
+
if ($diff) {
|
327 |
+
$result['success'] = false;
|
328 |
+
$result['error'] = true;
|
329 |
+
$result['error_messages'] = $this->__('Please agree to all the terms and conditions before placing the order.');
|
330 |
+
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
|
331 |
+
return;
|
332 |
+
}
|
333 |
+
}
|
334 |
+
|
335 |
+
if ($data = $this->getRequest()->getPost('payment', false)) {
|
336 |
+
$this->getOnepage()->getQuote()->getPayment()->importData($data);
|
337 |
+
}
|
338 |
+
$this->getOnepage()->saveOrder();
|
339 |
+
|
340 |
+
// In the saveOrder function (^^^) in the file /app/code/core/Mage/Checkout/Model/Type/Onepage.php:767 the order is finalized and saved.
|
341 |
+
// On line 796 the "LastSuccessQuoteId" value is set in the session of the user
|
342 |
+
// We can read this value to create a hash from it and insert it in the comment.
|
343 |
+
// Later on we re-use this hash to check if a specific order was a Highstreet order
|
344 |
+
// On line 823 the "LastRealOderId" value is set in the session of the user
|
345 |
+
// We can read this value to get the order ID and insert a comment in the order.
|
346 |
+
// This comment in the order is absolutely crucial for the order tracking of Highstreet.
|
347 |
+
|
348 |
+
try {
|
349 |
+
$checkoutSession = Mage::getSingleton('checkout/session');
|
350 |
+
$orderId = $checkoutSession->getLastRealOrderId();
|
351 |
+
$quoteId = $checkoutSession->getLastSuccessQuoteId();
|
352 |
+
if ($orderId > 0 && $quoteId > 0) {
|
353 |
+
$encryptionHelper = Mage::helper('highstreet_hsapi/encryption');
|
354 |
+
$quoteIdHash = $encryptionHelper->hashQuoteId($quoteId);
|
355 |
+
|
356 |
+
$order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
|
357 |
+
$order->addStatusHistoryComment('Order made via the Highstreet app. Quote hash:' . $quoteIdHash)
|
358 |
+
->setIsVisibleOnFront(false)
|
359 |
+
->setIsCustomerNotified(false);
|
360 |
+
$order->save();
|
361 |
+
}
|
362 |
+
} catch (Exception $e) {}
|
363 |
+
|
364 |
+
$redirectUrl = $this->getOnepage()->getCheckout()->getRedirectUrl();
|
365 |
+
$result['success'] = true;
|
366 |
+
$result['error'] = false;
|
367 |
+
} catch (Mage_Payment_Model_Info_Exception $e) {
|
368 |
+
$message = $e->getMessage();
|
369 |
+
if (!empty($message)) {
|
370 |
+
$result['error_messages'] = $message;
|
371 |
+
}
|
372 |
+
$result['goto_section'] = 'payment';
|
373 |
+
$result['update_section'] = array(
|
374 |
+
'name' => 'payment-method',
|
375 |
+
'html' => $this->_getPaymentMethodsHtml()
|
376 |
+
);
|
377 |
+
} catch (Mage_Core_Exception $e) {
|
378 |
+
Mage::logException($e);
|
379 |
+
Mage::helper('checkout')->sendPaymentFailedEmail($this->getOnepage()->getQuote(), $e->getMessage());
|
380 |
+
$result['success'] = false;
|
381 |
+
$result['error'] = true;
|
382 |
+
$result['error_messages'] = $e->getMessage();
|
383 |
+
|
384 |
+
$gotoSection = $this->getOnepage()->getCheckout()->getGotoSection();
|
385 |
+
if ($gotoSection) {
|
386 |
+
$result['goto_section'] = $gotoSection;
|
387 |
+
$this->getOnepage()->getCheckout()->setGotoSection(null);
|
388 |
+
}
|
389 |
+
$updateSection = $this->getOnepage()->getCheckout()->getUpdateSection();
|
390 |
+
if ($updateSection) {
|
391 |
+
if (isset($this->_sectionUpdateFunctions[$updateSection])) {
|
392 |
+
$updateSectionFunction = $this->_sectionUpdateFunctions[$updateSection];
|
393 |
+
$result['update_section'] = array(
|
394 |
+
'name' => $updateSection,
|
395 |
+
'html' => $this->$updateSectionFunction()
|
396 |
+
);
|
397 |
+
}
|
398 |
+
$this->getOnepage()->getCheckout()->setUpdateSection(null);
|
399 |
+
}
|
400 |
+
} catch (Exception $e) {
|
401 |
+
Mage::logException($e);
|
402 |
+
Mage::helper('checkout')->sendPaymentFailedEmail($this->getOnepage()->getQuote(), $e->getMessage());
|
403 |
+
$result['success'] = false;
|
404 |
+
$result['error'] = true;
|
405 |
+
$result['error_messages'] = $this->__('There was an error processing your order. Please contact us or try again later.');
|
406 |
+
}
|
407 |
+
$this->getOnepage()->getQuote()->save();
|
408 |
+
/**
|
409 |
+
* when there is redirect to third party, we don't want to save order yet.
|
410 |
+
* we will save the order in return action.
|
411 |
+
*/
|
412 |
+
if (isset($redirectUrl)) {
|
413 |
+
$result['redirect'] = $redirectUrl;
|
414 |
+
}
|
415 |
+
|
416 |
+
$this->_JSONencodeAndRespond($result);
|
417 |
+
}
|
418 |
+
|
419 |
+
private function getOnepage() {
|
420 |
+
return Mage::getSingleton('checkout/type_onepage');
|
421 |
+
}
|
422 |
+
|
423 |
+
private function _getShippingMethods() {
|
424 |
+
$shippingMethods = array();
|
425 |
+
|
426 |
+
$shouldGetPostNL = true;
|
427 |
+
$postNlOptions = array();
|
428 |
+
try {
|
429 |
+
$quote = Mage::getSingleton('checkout/session')->getQuote(); // Get quote for filled in address data
|
430 |
+
$shippingAddressData = $quote->getShippingAddress()->getData();
|
431 |
+
|
432 |
+
$cif = Mage::getModel('postnl_deliveryoptions/cif');
|
433 |
+
if ($cif) {
|
434 |
+
$postNlOptions = $cif->setStoreId(Mage::app()->getStore()->getId())
|
435 |
+
->getDeliveryTimeframes(array(
|
436 |
+
'postcode' => str_replace(" ", "", $shippingAddressData["postcode"]), // Postcode
|
437 |
+
'housenumber' => ereg_replace("[^0-9]", "", $shippingAddressData["street"]), // Extract housenumber from street field
|
438 |
+
'deliveryDate' => date('d-m-Y', strtotime('+ 1 day')), // Set delivery day to tomorrow
|
439 |
+
));
|
440 |
+
} else {
|
441 |
+
$shouldGetPostNL = false;
|
442 |
+
}
|
443 |
+
} catch (Exception $e) {
|
444 |
+
$shouldGetPostNL = false;
|
445 |
+
}
|
446 |
+
|
447 |
+
$quote = Mage::getSingleton('checkout/cart')->getQuote();
|
448 |
+
foreach ($quote->getShippingAddress()->getGroupedAllShippingRates() as $_rates) {
|
449 |
+
foreach ($_rates as $_rate){
|
450 |
+
$checked = false;
|
451 |
+
|
452 |
+
$shippingMethod;
|
453 |
+
try {
|
454 |
+
$shippingMethod = $quote->getShippingAddress()->getShippingMethod();
|
455 |
+
} catch (Exception $e) {}
|
456 |
+
|
457 |
+
if (!empty($shippingMethod) && $_rate->getCode() === $shippingMethod) {
|
458 |
+
$checked = true;
|
459 |
+
}
|
460 |
+
|
461 |
+
$shippingMethod = array();
|
462 |
+
$shippingMethod['title'] = $_rate->getMethodTitle();
|
463 |
+
$shippingMethod['price'] = $_rate->getData('price');
|
464 |
+
$shippingMethod['code'] = $_rate->getCode();
|
465 |
+
$shippingMethod['checked'] = $checked;
|
466 |
+
|
467 |
+
if (strstr($_rate->getCode(), "postnl") !== false) {
|
468 |
+
$shippingMethod['sub_options'] = $postNlOptions;
|
469 |
+
}
|
470 |
+
|
471 |
+
$shippingMethods[] = $shippingMethod;
|
472 |
+
|
473 |
+
}
|
474 |
+
}
|
475 |
+
|
476 |
+
return $shippingMethods;
|
477 |
+
}
|
478 |
+
|
479 |
+
private function _getPaymentMethods() {
|
480 |
+
$paymentMethods = array();
|
481 |
+
|
482 |
+
$model = new Mage_Checkout_Block_Onepage_Payment_Methods();
|
483 |
+
|
484 |
+
$quote = Mage::getSingleton('checkout/cart')->getQuote();
|
485 |
+
$selectedPaymentMethod;
|
486 |
+
try {
|
487 |
+
$selectedPaymentMethod = $quote->getPayment()->getData('method');
|
488 |
+
} catch (Exception $e) {}
|
489 |
+
|
490 |
+
foreach ($model->getMethods() as $method) {
|
491 |
+
$object = array();
|
492 |
+
$code = $method->getCode();
|
493 |
+
|
494 |
+
$methodTitle = $method->getTitle();
|
495 |
+
if ($code == "paypal_express") { // PayPal. Has logo and strange label text, override
|
496 |
+
$methodTitle = "PayPal";
|
497 |
+
}
|
498 |
+
|
499 |
+
$checked = false;
|
500 |
+
|
501 |
+
if (!empty($selectedPaymentMethod) && $selectedPaymentMethod == $code) {
|
502 |
+
$checked = true;
|
503 |
+
}
|
504 |
+
|
505 |
+
$object["title"] = $methodTitle;
|
506 |
+
$object["code"] = $code;
|
507 |
+
$object["checked"] = $checked;
|
508 |
+
|
509 |
+
if ($code === "buckaroo3extended_ideal") {
|
510 |
+
$session = Mage::getSingleton('checkout/session');
|
511 |
+
$sessionValue = $session->getData('buckaroo3extended_ideal_BPE_Issuer');
|
512 |
+
$buckarooIdealModel = new TIG_Buckaroo3Extended_Block_PaymentMethods_Ideal_Checkout_Form();
|
513 |
+
$issuerList = $buckarooIdealModel->getIssuerList();
|
514 |
+
|
515 |
+
foreach ($issuerList as $issuer => $issuerDetails) {
|
516 |
+
$option = array();
|
517 |
+
$optionChecked = false;
|
518 |
+
if (!empty($sessionValue) && array_key_exists($sessionValue, $issuerList)) {
|
519 |
+
if ($issuer == $sessionValue) {
|
520 |
+
$optionChecked = true;
|
521 |
+
}
|
522 |
+
}
|
523 |
+
|
524 |
+
$option["checked"] = $optionChecked;
|
525 |
+
$option["title"] = $issuerDetails['name'];
|
526 |
+
$option["code"] = $issuer;
|
527 |
+
$option["image"] = $issuerDetails['logo'];
|
528 |
+
$object["sub_options"][] = $option;
|
529 |
+
}
|
530 |
+
}
|
531 |
+
|
532 |
+
$paymentMethods[] = $object;
|
533 |
+
}
|
534 |
+
|
535 |
+
return $paymentMethods;
|
536 |
+
}
|
537 |
+
|
538 |
+
private function _getReviewData() {
|
539 |
+
$session = Mage::getSingleton('checkout/session');
|
540 |
+
$quote = $session->getQuote();
|
541 |
+
$billingAddress = $quote->getBillingAddress();
|
542 |
+
$shippingAddress = $quote->getShippingAddress();
|
543 |
+
$billingAddressData = $billingAddress->getData();
|
544 |
+
$shippingAddressData = $shippingAddress->getData();
|
545 |
+
|
546 |
+
$response = array();
|
547 |
+
|
548 |
+
// Billing address information
|
549 |
+
$billing_address = array();
|
550 |
+
$billing_address["email"] = $quote->getCustomerEmail();
|
551 |
+
$billing_address["firstname"] = $billingAddressData["firstname"];
|
552 |
+
$billing_address["lastname"] = $billingAddressData["lastname"];
|
553 |
+
$billing_address["telephone"] = (string) $billingAddressData["telephone"];
|
554 |
+
$billing_address["street"] = $billingAddressData["street"];
|
555 |
+
$billing_address["postcode"] = $billingAddressData["postcode"];
|
556 |
+
$billing_address["city"] = $billingAddressData["city"];
|
557 |
+
|
558 |
+
$response["billing_address"] = $billing_address;
|
559 |
+
|
560 |
+
// Shipping address information
|
561 |
+
$shipping_address = array();
|
562 |
+
$shipping_address["firstname"] = $shippingAddressData["firstname"];
|
563 |
+
$shipping_address["lastname"] = $shippingAddressData["lastname"];
|
564 |
+
$shipping_address["telephone"] = (string) $shippingAddressData["telephone"];
|
565 |
+
$shipping_address["street"] = $shippingAddressData["street"];
|
566 |
+
$shipping_address["postcode"] = $shippingAddressData["postcode"];
|
567 |
+
$shipping_address["city"] = $shippingAddressData["city"];
|
568 |
+
|
569 |
+
if (!$this->_billingAndShippingAddressesAreTheSame($response["billing_address"], $shipping_address)) {
|
570 |
+
$response["shipping_address"] = $shipping_address;
|
571 |
+
} else {
|
572 |
+
$response["shipping_address"] = array();
|
573 |
+
}
|
574 |
+
|
575 |
+
|
576 |
+
// Shipping method information
|
577 |
+
$response["shipping_method"]["name"] = $shippingAddress->getShippingDescription();
|
578 |
+
|
579 |
+
// Payment method information
|
580 |
+
$response["payment_method"]["name"] = $quote->getPayment()->getMethodInstance()->getTitle();
|
581 |
+
$response["payment_method"]["coupon_code"] = $quote->getCouponCode();
|
582 |
+
|
583 |
+
|
584 |
+
return $response;
|
585 |
+
}
|
586 |
+
|
587 |
+
/**
|
588 |
+
* Conveinience method, compares 2 formatted address arrays
|
589 |
+
*/
|
590 |
+
private function _billingAndShippingAddressesAreTheSame($billingAddressArray = array(), $shippingAddressArray = array()) {
|
591 |
+
if (count($billingAddressArray) == 0 || count($shippingAddressArray) == 0) {
|
592 |
+
return true;
|
593 |
+
}
|
594 |
+
|
595 |
+
if ($billingAddressArray["firstname"] !== $shippingAddressArray["firstname"] ||
|
596 |
+
$billingAddressArray["lastname"] !== $shippingAddressArray["lastname"] ||
|
597 |
+
$billingAddressArray["telephone"] !== $shippingAddressArray["telephone"] ||
|
598 |
+
$billingAddressArray["street"] !== $shippingAddressArray["street"] ||
|
599 |
+
$billingAddressArray["postcode"] !== $shippingAddressArray["postcode"] ||
|
600 |
+
$billingAddressArray["city"] !== $shippingAddressArray["city"]) {
|
601 |
+
return false;
|
602 |
+
} else {
|
603 |
+
return true;
|
604 |
+
}
|
605 |
+
}
|
606 |
+
|
607 |
+
/**
|
608 |
+
* Sets the proper headers
|
609 |
+
*/
|
610 |
+
private function _setHeader()
|
611 |
+
{
|
612 |
+
Mage::getSingleton('core/session')->setLastStoreCode(Mage::app()->getStore()->getCode());
|
613 |
+
header_remove('Pragma'); // removes 'no-cache' header
|
614 |
+
$this->getResponse()->setHeader('Content-Type','application/json', true);
|
615 |
+
}
|
616 |
+
|
617 |
+
/**
|
618 |
+
* Sets headers and body with proper JSON encoding
|
619 |
+
*/
|
620 |
+
private function _JSONencodeAndRespond($data, $numericCheck = true) {
|
621 |
+
//set response body
|
622 |
+
$this->_setHeader();
|
623 |
+
if ($numericCheck) {
|
624 |
+
$this->getResponse()->setBody(json_encode($data, JSON_NUMERIC_CHECK));
|
625 |
+
} else {
|
626 |
+
$this->getResponse()->setBody(json_encode($data));
|
627 |
+
}
|
628 |
+
|
629 |
+
}
|
630 |
+
}
|
app/code/local/Highstreet/Hsapi/controllers/IndexController.php
CHANGED
@@ -83,7 +83,24 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
83 |
}
|
84 |
|
85 |
public function pingAction() {
|
86 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
}
|
88 |
|
89 |
/**
|
@@ -130,32 +147,36 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
130 |
public function checkoutAction() {
|
131 |
$requestObject = Mage::app()->getRequest();
|
132 |
$data = json_decode($requestObject->getParam('products'), true);
|
|
|
|
|
|
|
133 |
|
134 |
-
|
135 |
-
$
|
|
|
136 |
|
137 |
-
$locale = Mage::app()->getLocale()->getLocaleCode();
|
138 |
-
|
139 |
$country = $requestObject->getParam('country');
|
140 |
-
$
|
141 |
-
|
|
|
142 |
|
143 |
-
|
144 |
-
|
145 |
-
$
|
|
|
|
|
146 |
}
|
147 |
|
148 |
-
|
149 |
|
150 |
$urlOptions = array();
|
151 |
if (!empty($_SERVER['HTTPS'])) { // Server is not HTTPS
|
152 |
$urlOptions['_secure'] = TRUE;
|
153 |
}
|
154 |
|
155 |
-
$
|
156 |
-
$checkoutUrl = $config->checkoutUrl();
|
157 |
|
158 |
-
|
159 |
}
|
160 |
|
161 |
|
@@ -169,6 +190,17 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
169 |
|
170 |
}
|
171 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
|
173 |
public function postCart() {
|
174 |
$requestObject = Mage::app()->getRequest();
|
@@ -181,6 +213,17 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
181 |
|
182 |
}
|
183 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
public function getCart() {
|
185 |
$requestObject = Mage::app()->getRequest();
|
186 |
$quote_id = $requestObject->getParam('quote_id');
|
@@ -195,6 +238,22 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
195 |
$this->_JSONencodeAndRespond($cart);
|
196 |
|
197 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
}
|
199 |
|
200 |
/**
|
@@ -204,12 +263,26 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
204 |
{
|
205 |
$requestObject = Mage::app()->getRequest();
|
206 |
$model = Mage::getModel('highstreet_hsapi/products');
|
207 |
-
|
208 |
-
$id = $requestObject->getParam('id');
|
209 |
-
$attributes = $requestObject->getParam('attributes');
|
210 |
-
$child_product_attributes = $requestObject->getParam('child_product_attributes');
|
211 |
|
212 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
|
214 |
if ($response == null) {
|
215 |
$this->_respondWith404();
|
@@ -249,13 +322,16 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
249 |
$requestObject = Mage::app()->getRequest();
|
250 |
$model = Mage::getModel('highstreet_hsapi/products');
|
251 |
|
252 |
-
$products = $model->getProductsForResponse($requestObject->getParam('
|
253 |
-
$requestObject->getParam('child_product_attributes'),
|
254 |
$requestObject->getParam('order'),
|
255 |
$requestObject->getParam('range'),
|
256 |
$requestObject->getParam('filter'),
|
257 |
$requestObject->getParam('search'),
|
258 |
-
$requestObject->getParam('id')
|
|
|
|
|
|
|
|
|
259 |
|
260 |
if ($products == null) {
|
261 |
$this->_respondWith404();
|
@@ -273,16 +349,35 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
273 |
{
|
274 |
$requestObject = Mage::app()->getRequest();
|
275 |
$model = Mage::getModel('highstreet_hsapi/products');
|
276 |
-
|
277 |
-
$products = $model->getBatchProducts($requestObject->getParam('ids'),
|
278 |
-
$requestObject->getParam('attributes'),
|
279 |
-
$requestObject->getParam('child_product_attributes'));
|
280 |
|
281 |
-
|
282 |
-
|
283 |
-
|
|
|
|
|
|
|
284 |
}
|
285 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
286 |
$this->_JSONencodeAndRespond($products);
|
287 |
}
|
288 |
|
@@ -296,9 +391,11 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
296 |
|
297 |
$response = $productsModel->getRelatedProducts($requestObject->getParam('type'),
|
298 |
$requestObject->getParam('id'),
|
299 |
-
$requestObject->getParam('
|
300 |
-
$requestObject->getParam('
|
301 |
-
$requestObject->getParam('
|
|
|
|
|
302 |
|
303 |
if ($response == null) {
|
304 |
$this->_respondWith404();
|
@@ -337,13 +434,11 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
337 |
/** @var $params */
|
338 |
$params = $helper->extractRequestParam(Mage::app()->getRequest()->getParams());
|
339 |
|
340 |
-
if(is_string($params))
|
341 |
-
{
|
342 |
//get Single Attribute
|
343 |
$attributes = $attributesModel->getAttribute($params);
|
344 |
$responseBody = $attributes;
|
345 |
-
}
|
346 |
-
else{
|
347 |
//Get all attributes
|
348 |
$attributes = $attributesModel->getAttributes();
|
349 |
$responseBody = $attributes;
|
@@ -377,10 +472,48 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
377 |
|
378 |
$this->_JSONencodeAndRespond($response, FALSE);
|
379 |
}
|
380 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
381 |
/**
|
382 |
* Header and http functions
|
383 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
384 |
private function _respondWith404()
|
385 |
{
|
386 |
$this->getResponse()->setHeader('HTTP/1.1','404 Not Found');
|
@@ -388,6 +521,13 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
|
|
388 |
return;
|
389 |
}
|
390 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
391 |
/**
|
392 |
* Sets the proper headers
|
393 |
*/
|
83 |
}
|
84 |
|
85 |
public function pingAction() {
|
86 |
+
$configApi = Mage::helper('highstreet_hsapi/config_api');
|
87 |
+
$this->_JSONencodeAndRespond("OK");
|
88 |
+
}
|
89 |
+
|
90 |
+
public function infoAction() {
|
91 |
+
$encryptionHelper = Mage::helper('highstreet_hsapi/encryption');
|
92 |
+
if (!$encryptionHelper->APISignatureStringIsValid()) {
|
93 |
+
$this->_respondWith401();
|
94 |
+
return;
|
95 |
+
}
|
96 |
+
|
97 |
+
$configApi = Mage::helper('highstreet_hsapi/config_api');
|
98 |
+
$this->_JSONencodeAndRespond(array("status" => "OK",
|
99 |
+
"identifer" => $configApi->storeIdentifier(),
|
100 |
+
"version" => (string)Mage::getConfig()->getNode()->modules->Highstreet_Hsapi->version,
|
101 |
+
"magento_version" => (string)Mage::getVersion(),
|
102 |
+
"environment" => $configApi->environment(),
|
103 |
+
"storefront" => Mage::app()->getStore()->getCode()));
|
104 |
}
|
105 |
|
106 |
/**
|
147 |
public function checkoutAction() {
|
148 |
$requestObject = Mage::app()->getRequest();
|
149 |
$data = json_decode($requestObject->getParam('products'), true);
|
150 |
+
$country = $requestObject->getParam('country');
|
151 |
+
return $this->_postCheckout($data["checkout"],$country);
|
152 |
+
}
|
153 |
|
154 |
+
public function checkout_v2Action() {
|
155 |
+
$requestObject = Mage::app()->getRequest();
|
156 |
+
$data = json_decode($requestObject->getParam('items'), true);
|
157 |
|
|
|
|
|
158 |
$country = $requestObject->getParam('country');
|
159 |
+
return $this->_postCheckout($data,$country,true);
|
160 |
+
|
161 |
+
}
|
162 |
|
163 |
+
private function _postCheckout($items,$country = null,$v2 = false) {
|
164 |
+
if($v2) {
|
165 |
+
$checkoutModel = Mage::getModel('highstreet_hsapi/checkoutV2');
|
166 |
+
} else {
|
167 |
+
$checkoutModel = Mage::getModel('highstreet_hsapi/checkout');
|
168 |
}
|
169 |
|
170 |
+
$checkoutModel->fillCartWithProductsAndQuantities($items);
|
171 |
|
172 |
$urlOptions = array();
|
173 |
if (!empty($_SERVER['HTTPS'])) { // Server is not HTTPS
|
174 |
$urlOptions['_secure'] = TRUE;
|
175 |
}
|
176 |
|
177 |
+
$checkoutModel = Mage::getModel('highstreet_hsapi/checkoutV2');
|
|
|
178 |
|
179 |
+
$this->_JSONencodeAndRespond($checkoutModel->getStartData());
|
180 |
}
|
181 |
|
182 |
|
190 |
|
191 |
}
|
192 |
|
193 |
+
public function cart_v2Action() {
|
194 |
+
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
195 |
+
return $this->postCart_v2();
|
196 |
+
}
|
197 |
+
else if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
198 |
+
return $this->getCart_v2();
|
199 |
+
}
|
200 |
+
|
201 |
+
}
|
202 |
+
|
203 |
+
|
204 |
|
205 |
public function postCart() {
|
206 |
$requestObject = Mage::app()->getRequest();
|
213 |
|
214 |
}
|
215 |
|
216 |
+
public function postCart_v2() {
|
217 |
+
$requestObject = Mage::app()->getRequest();
|
218 |
+
$data = json_decode($requestObject->getParam('items'), true);
|
219 |
+
|
220 |
+
$checkoutModel = Mage::getModel('highstreet_hsapi/checkoutV2');
|
221 |
+
$cart = $checkoutModel->getQuoteWithProductsAndQuantities($data);
|
222 |
+
|
223 |
+
$this->_JSONencodeAndRespond($cart);
|
224 |
+
|
225 |
+
}
|
226 |
+
|
227 |
public function getCart() {
|
228 |
$requestObject = Mage::app()->getRequest();
|
229 |
$quote_id = $requestObject->getParam('quote_id');
|
238 |
$this->_JSONencodeAndRespond($cart);
|
239 |
|
240 |
|
241 |
+
}
|
242 |
+
|
243 |
+
public function getCart_v2() {
|
244 |
+
$requestObject = Mage::app()->getRequest();
|
245 |
+
$quote_id = $requestObject->getParam('quote_id');
|
246 |
+
if(!$quote_id) {
|
247 |
+
$this->_respondWith404();
|
248 |
+
return false;
|
249 |
+
}
|
250 |
+
|
251 |
+
$checkoutModel = Mage::getModel('highstreet_hsapi/checkoutV2');
|
252 |
+
$cart = $checkoutModel->getQuoteWithProductsAndQuantities(null,$quote_id);
|
253 |
+
|
254 |
+
$this->_JSONencodeAndRespond($cart);
|
255 |
+
|
256 |
+
|
257 |
}
|
258 |
|
259 |
/**
|
263 |
{
|
264 |
$requestObject = Mage::app()->getRequest();
|
265 |
$model = Mage::getModel('highstreet_hsapi/products');
|
|
|
|
|
|
|
|
|
266 |
|
267 |
+
$productObject = Mage::getModel('catalog/product')->load($requestObject->getParam('id'));
|
268 |
+
|
269 |
+
if (!$productObject->getId()) {
|
270 |
+
$this->_respondWith404();
|
271 |
+
return false;
|
272 |
+
}
|
273 |
+
|
274 |
+
if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) && $_SERVER["HTTP_IF_MODIFIED_SINCE"] !== NULL) {
|
275 |
+
if (!$model->productHasBeenModifiedSince($productObject, $_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
|
276 |
+
$this->_respondWith304();
|
277 |
+
return false;
|
278 |
+
}
|
279 |
+
}
|
280 |
+
|
281 |
+
$response = $model->getSingleProduct($productObject,
|
282 |
+
$requestObject->getParam('additional_attributes'),
|
283 |
+
$requestObject->getParam('include_configuration_details'),
|
284 |
+
$requestObject->getParam('include_media_gallery'));
|
285 |
+
|
286 |
|
287 |
if ($response == null) {
|
288 |
$this->_respondWith404();
|
322 |
$requestObject = Mage::app()->getRequest();
|
323 |
$model = Mage::getModel('highstreet_hsapi/products');
|
324 |
|
325 |
+
$products = $model->getProductsForResponse($requestObject->getParam('additional_attributes'),
|
|
|
326 |
$requestObject->getParam('order'),
|
327 |
$requestObject->getParam('range'),
|
328 |
$requestObject->getParam('filter'),
|
329 |
$requestObject->getParam('search'),
|
330 |
+
$requestObject->getParam('id'),
|
331 |
+
$requestObject->getParam('hide_attributes'),
|
332 |
+
$requestObject->getParam('hide_filters'),
|
333 |
+
$requestObject->getParam('include_configuration_details'),
|
334 |
+
$requestObject->getParam('include_media_gallery'));
|
335 |
|
336 |
if ($products == null) {
|
337 |
$this->_respondWith404();
|
349 |
{
|
350 |
$requestObject = Mage::app()->getRequest();
|
351 |
$model = Mage::getModel('highstreet_hsapi/products');
|
|
|
|
|
|
|
|
|
352 |
|
353 |
+
$idsArray = explode(',', $requestObject->getParam('ids'));
|
354 |
+
$productObjects = array();
|
355 |
+
|
356 |
+
foreach ($idsArray as $value) {
|
357 |
+
$productObject = Mage::getModel('catalog/product')->load($value);
|
358 |
+
$productObjects[] = $productObject;
|
359 |
}
|
360 |
|
361 |
+
if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) && $_SERVER["HTTP_IF_MODIFIED_SINCE"] !== NULL) {
|
362 |
+
$productHasChanged = false;
|
363 |
+
|
364 |
+
foreach ($productObjects as $productObject) {
|
365 |
+
if ($model->productHasBeenModifiedSince($productObject, $_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
|
366 |
+
$productHasChanged = true;
|
367 |
+
}
|
368 |
+
}
|
369 |
+
|
370 |
+
if (!$productHasChanged) {
|
371 |
+
$this->_respondWith304();
|
372 |
+
return false;
|
373 |
+
}
|
374 |
+
}
|
375 |
+
|
376 |
+
$products = $model->getBatchProducts($productObjects,
|
377 |
+
$requestObject->getParam('additional_attributes'),
|
378 |
+
$requestObject->getParam('include_configuration_details'),
|
379 |
+
$requestObject->getParam('include_media_gallery'));
|
380 |
+
|
381 |
$this->_JSONencodeAndRespond($products);
|
382 |
}
|
383 |
|
391 |
|
392 |
$response = $productsModel->getRelatedProducts($requestObject->getParam('type'),
|
393 |
$requestObject->getParam('id'),
|
394 |
+
$requestObject->getParam('additional_attributes'),
|
395 |
+
$requestObject->getParam('range'),
|
396 |
+
$requestObject->getParam('hide_attributes'),
|
397 |
+
$requestObject->getParam('include_configuration_details'),
|
398 |
+
$requestObject->getParam('include_media_gallery'));
|
399 |
|
400 |
if ($response == null) {
|
401 |
$this->_respondWith404();
|
434 |
/** @var $params */
|
435 |
$params = $helper->extractRequestParam(Mage::app()->getRequest()->getParams());
|
436 |
|
437 |
+
if (is_string($params)) {
|
|
|
438 |
//get Single Attribute
|
439 |
$attributes = $attributesModel->getAttribute($params);
|
440 |
$responseBody = $attributes;
|
441 |
+
} else {
|
|
|
442 |
//Get all attributes
|
443 |
$attributes = $attributesModel->getAttributes();
|
444 |
$responseBody = $attributes;
|
472 |
|
473 |
$this->_JSONencodeAndRespond($response, FALSE);
|
474 |
}
|
475 |
+
|
476 |
+
public function getOrderAction () {
|
477 |
+
$encryptionHelper = Mage::helper('highstreet_hsapi/encryption');
|
478 |
+
if (!$encryptionHelper->APISignatureStringIsValid()) {
|
479 |
+
$this->_respondWith401();
|
480 |
+
return;
|
481 |
+
}
|
482 |
+
|
483 |
+
$requestObject = Mage::app()->getRequest();
|
484 |
+
|
485 |
+
$quoteIds = array();
|
486 |
+
if ($requestObject->getParam('quote_id') != null) {
|
487 |
+
$quoteIds[] = $requestObject->getParam('quote_id');
|
488 |
+
}
|
489 |
+
|
490 |
+
if ($requestObject->getParam('quote_ids') != null) {
|
491 |
+
$quoteIds = array_merge($quoteIds, explode(',', $requestObject->getParam('quote_ids')));
|
492 |
+
}
|
493 |
+
|
494 |
+
$checkoutModel = Mage::getModel('highstreet_hsapi/checkoutV2');
|
495 |
+
|
496 |
+
$response = array();
|
497 |
+
foreach ($quoteIds as $quoteId) {
|
498 |
+
$quote = Mage::getModel('sales/quote')->loadByIdWithoutStore($quoteId);
|
499 |
+
$order = Mage::getModel('sales/order')->loadByIncrementId($quote->getData('reserved_order_id'));
|
500 |
+
|
501 |
+
$response[] = $checkoutModel->getOrderInformationFromOrderObject($order, $quoteId);
|
502 |
+
}
|
503 |
+
|
504 |
+
$this->_JSONencodeAndRespond($response);
|
505 |
+
}
|
506 |
+
|
507 |
/**
|
508 |
* Header and http functions
|
509 |
*/
|
510 |
+
private function _respondWith304()
|
511 |
+
{
|
512 |
+
$this->getResponse()->setHeader('HTTP/1.1','304 Not Modified');
|
513 |
+
$this->getResponse()->sendHeaders();
|
514 |
+
return;
|
515 |
+
}
|
516 |
+
|
517 |
private function _respondWith404()
|
518 |
{
|
519 |
$this->getResponse()->setHeader('HTTP/1.1','404 Not Found');
|
521 |
return;
|
522 |
}
|
523 |
|
524 |
+
private function _respondWith401()
|
525 |
+
{
|
526 |
+
$this->getResponse()->setHeader('HTTP/1.1','401 Unauthorized');
|
527 |
+
$this->getResponse()->sendHeaders();
|
528 |
+
return;
|
529 |
+
}
|
530 |
+
|
531 |
/**
|
532 |
* Sets the proper headers
|
533 |
*/
|
app/code/local/Highstreet/Hsapi/etc/.DS_Store
DELETED
Binary file
|
app/code/local/Highstreet/Hsapi/etc/Configuration.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
{}
|
|
app/code/local/Highstreet/Hsapi/etc/config.xml
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
<config>
|
12 |
<modules>
|
13 |
<Highstreet_Hsapi>
|
14 |
-
<version>1.
|
15 |
</Highstreet_Hsapi>
|
16 |
</modules>
|
17 |
<frontend>
|
@@ -33,13 +33,7 @@
|
|
33 |
</Highstreet_Hsapi>
|
34 |
</modules>
|
35 |
</translate>
|
36 |
-
|
37 |
-
<updates>
|
38 |
-
<hsapi>
|
39 |
-
<file>highstreet/checkout.xml</file>
|
40 |
-
</hsapi>
|
41 |
-
</updates>
|
42 |
-
</layout>
|
43 |
</frontend>
|
44 |
<global>
|
45 |
<models>
|
@@ -64,8 +58,8 @@
|
|
64 |
</setup>
|
65 |
</highstreet_hsapi_setup>
|
66 |
</resources>
|
67 |
-
<events>
|
68 |
-
|
69 |
<observers>
|
70 |
<highstreet_hsapi_merge_quote>
|
71 |
<type>singleton</type>
|
@@ -73,7 +67,44 @@
|
|
73 |
<method>mergeQuote</method>
|
74 |
</highstreet_hsapi_merge_quote>
|
75 |
</observers>
|
76 |
-
|
77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
</global>
|
79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
<config>
|
12 |
<modules>
|
13 |
<Highstreet_Hsapi>
|
14 |
+
<version>1.4.3</version>
|
15 |
</Highstreet_Hsapi>
|
16 |
</modules>
|
17 |
<frontend>
|
33 |
</Highstreet_Hsapi>
|
34 |
</modules>
|
35 |
</translate>
|
36 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
</frontend>
|
38 |
<global>
|
39 |
<models>
|
58 |
</setup>
|
59 |
</highstreet_hsapi_setup>
|
60 |
</resources>
|
61 |
+
<events>
|
62 |
+
<sales_quote_merge_before>
|
63 |
<observers>
|
64 |
<highstreet_hsapi_merge_quote>
|
65 |
<type>singleton</type>
|
67 |
<method>mergeQuote</method>
|
68 |
</highstreet_hsapi_merge_quote>
|
69 |
</observers>
|
70 |
+
</sales_quote_merge_before>
|
71 |
+
<sales_order_invoice_pay>
|
72 |
+
<observers>
|
73 |
+
<highstreet_hsapi_sales_order_invoice_pay>
|
74 |
+
<class>Highstreet_Hsapi_Model_Observer</class>
|
75 |
+
<method>salesOrderInvoicePay</method>
|
76 |
+
</highstreet_hsapi_sales_order_invoice_pay>
|
77 |
+
</observers>
|
78 |
+
</sales_order_invoice_pay>
|
79 |
+
<sales_order_invoice_cancel>
|
80 |
+
<observers>
|
81 |
+
<highstreet_hsapi_sales_order_invoice_cancel>
|
82 |
+
<class>Highstreet_Hsapi_Model_Observer</class>
|
83 |
+
<method>salesOrderInvoiceCancel</method>
|
84 |
+
</highstreet_hsapi_sales_order_invoice_cancel>
|
85 |
+
</observers>
|
86 |
+
</sales_order_invoice_cancel>
|
87 |
+
</events>
|
88 |
</global>
|
89 |
+
<adminhtml>
|
90 |
+
<acl>
|
91 |
+
<resources>
|
92 |
+
<admin>
|
93 |
+
<children>
|
94 |
+
<system>
|
95 |
+
<children>
|
96 |
+
<config>
|
97 |
+
<children>
|
98 |
+
<highstreet_hsapi>
|
99 |
+
<title>Highstreet</title>
|
100 |
+
</highstreet_hsapi>
|
101 |
+
</children>
|
102 |
+
</config>
|
103 |
+
</children>
|
104 |
+
</system>
|
105 |
+
</children>
|
106 |
+
</admin>
|
107 |
+
</resources>
|
108 |
+
</acl>
|
109 |
+
</adminhtml>
|
110 |
+
</config>
|
app/code/local/Highstreet/Hsapi/etc/system.xml
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<sections>
|
4 |
+
<highstreet_hsapi module="highstreet_hsapi">
|
5 |
+
<label>Highstreet</label>
|
6 |
+
<class>highstreet-section</class>
|
7 |
+
<tab>service</tab>
|
8 |
+
<frontend_type>text</frontend_type>
|
9 |
+
<sort_order>1000</sort_order>
|
10 |
+
<show_in_default>1</show_in_default>
|
11 |
+
<show_in_website>1</show_in_website>
|
12 |
+
<show_in_store>1</show_in_store>
|
13 |
+
<groups>
|
14 |
+
<api>
|
15 |
+
<label>Configuration</label>
|
16 |
+
<frontend_type>text</frontend_type>
|
17 |
+
<sort_order>20</sort_order>
|
18 |
+
<show_in_default>1</show_in_default>
|
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>
|
25 |
+
<frontend_type>text</frontend_type>
|
26 |
+
<sort_order>10</sort_order>
|
27 |
+
<show_in_default>1</show_in_default>
|
28 |
+
<show_in_website>1</show_in_website>
|
29 |
+
<show_in_store>1</show_in_store>
|
30 |
+
</store_id>
|
31 |
+
<environment>
|
32 |
+
<label>Environment</label>
|
33 |
+
<comment></comment>
|
34 |
+
<frontend_type>select</frontend_type>
|
35 |
+
<source_model>highstreet_hsapi/system_config_environment</source_model>
|
36 |
+
<sort_order>20</sort_order>
|
37 |
+
<show_in_default>1</show_in_default>
|
38 |
+
<show_in_website>1</show_in_website>
|
39 |
+
<show_in_store>1</show_in_store>
|
40 |
+
</environment>
|
41 |
+
<shipping_in_cart translate="label">
|
42 |
+
<label>Hide shipping methods in cart API call</label>
|
43 |
+
<comment></comment>
|
44 |
+
<frontend_type>select</frontend_type>
|
45 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
46 |
+
<sort_order>30</sort_order>
|
47 |
+
<show_in_default>1</show_in_default>
|
48 |
+
<show_in_website>1</show_in_website>
|
49 |
+
<show_in_store>1</show_in_store>
|
50 |
+
</shipping_in_cart>
|
51 |
+
<always_add_simple_products translate="label">
|
52 |
+
<label>Always add simple products to the cart</label>
|
53 |
+
<comment></comment>
|
54 |
+
<frontend_type>select</frontend_type>
|
55 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
56 |
+
<sort_order>40</sort_order>
|
57 |
+
<show_in_default>1</show_in_default>
|
58 |
+
<show_in_website>1</show_in_website>
|
59 |
+
<show_in_store>1</show_in_store>
|
60 |
+
</always_add_simple_products>
|
61 |
+
<smartbanner_native_active translate="label">
|
62 |
+
<label>Enable the native Apple smart banner</label>
|
63 |
+
<comment></comment>
|
64 |
+
<frontend_type>select</frontend_type>
|
65 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
66 |
+
<sort_order>50</sort_order>
|
67 |
+
<show_in_default>1</show_in_default>
|
68 |
+
<show_in_website>1</show_in_website>
|
69 |
+
<show_in_store>1</show_in_store>
|
70 |
+
</smartbanner_native_active>
|
71 |
+
<smartbanner_native_app_id translate="label">
|
72 |
+
<label>App store id</label>
|
73 |
+
<comment></comment>
|
74 |
+
<frontend_type>text</frontend_type>
|
75 |
+
<sort_order>60</sort_order>
|
76 |
+
<show_in_default>1</show_in_default>
|
77 |
+
<show_in_website>1</show_in_website>
|
78 |
+
<show_in_store>1</show_in_store>
|
79 |
+
</smartbanner_native_app_id>
|
80 |
+
<smartbanner_native_app_url translate="label">
|
81 |
+
<label>Url scheme for universal links</label>
|
82 |
+
<comment></comment>
|
83 |
+
<frontend_type>text</frontend_type>
|
84 |
+
<sort_order>70</sort_order>
|
85 |
+
<show_in_default>1</show_in_default>
|
86 |
+
<show_in_website>1</show_in_website>
|
87 |
+
<show_in_store>1</show_in_store>
|
88 |
+
</smartbanner_native_app_url>
|
89 |
+
<smartbanner_native_app_name translate="label">
|
90 |
+
<label>App name used to display in iOS search results</label>
|
91 |
+
<comment></comment>
|
92 |
+
<frontend_type>text</frontend_type>
|
93 |
+
<sort_order>80</sort_order>
|
94 |
+
<show_in_default>1</show_in_default>
|
95 |
+
<show_in_website>1</show_in_website>
|
96 |
+
<show_in_store>1</show_in_store>
|
97 |
+
</smartbanner_native_app_name>
|
98 |
+
</fields>
|
99 |
+
</api>
|
100 |
+
</groups>
|
101 |
+
</highstreet_hsapi>
|
102 |
+
</sections>
|
103 |
+
</config>
|
app/code/local/Highstreet/SmartAppBanner/etc/config.xml
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
|
3 |
+
<config>
|
4 |
+
|
5 |
+
<modules>
|
6 |
+
|
7 |
+
<Highstreet_SmartAppBanner>
|
8 |
+
<version>1.3.1</version>
|
9 |
+
</Highstreet_SmartAppBanner>
|
10 |
+
|
11 |
+
</modules>
|
12 |
+
|
13 |
+
|
14 |
+
<frontend>
|
15 |
+
|
16 |
+
<layout>
|
17 |
+
<updates>
|
18 |
+
<Highstreet_SmartAppBanner>
|
19 |
+
<file>highstreet/smart_app_banner.xml</file>
|
20 |
+
</Highstreet_SmartAppBanner>
|
21 |
+
</updates>
|
22 |
+
</layout>
|
23 |
+
|
24 |
+
</frontend>
|
25 |
+
|
26 |
+
</config>
|
app/design/frontend/base/default/layout/highstreet/smart_app_banner.xml
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
|
3 |
+
<layout version="1.2.0">
|
4 |
+
<default>
|
5 |
+
<reference name="head">
|
6 |
+
<block type="core/template" name="native_smart_app_banner" template="highstreet/native_smart_app_banner.phtml" />
|
7 |
+
</reference>
|
8 |
+
<reference name="before_body_end">
|
9 |
+
<block type="page/html_header" name="smart_app_banner" template="highstreet/smart_app_banner.phtml" />
|
10 |
+
</reference>
|
11 |
+
</default>
|
12 |
+
</layout>
|
app/design/frontend/base/default/template/highstreet/native_smart_app_banner.phtml
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
$configHelper = Mage::helper('highstreet_hsapi/config_api');
|
4 |
+
|
5 |
+
if ($configHelper->nativeSmartbannerAppUrl() != "") {
|
6 |
+
$deeplink = $configHelper->nativeSmartbannerAppUrl() . "://";
|
7 |
+
|
8 |
+
$category = Mage::registry('current_category');
|
9 |
+
$deeplink .= $category ? "categories/" . $category->getId() . "/" : "";
|
10 |
+
|
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 ($configHelper->shouldShowNativeSmartbanner()) {
|
18 |
+
$metaTag = '<meta name="apple-itunes-app" content="app-id=' . $configHelper->nativeSmartbannerAppId();
|
19 |
+
$metaTag .= ', app-argument=' . $deeplink;
|
20 |
+
$metaTag .= '"/>';
|
21 |
+
|
22 |
+
echo $metaTag;
|
23 |
+
}
|
24 |
+
|
25 |
+
echo '<meta property="al:ios:app_name" content="' . $configHelper->nativeSmartbannerAppName() . '">';
|
26 |
+
echo '<meta property="al:ios:app_store_id" content="' . $configHelper->nativeSmartbannerAppId() . '">';
|
27 |
+
echo '<meta property="al:ios:url" content="' . $deeplink . '">';
|
28 |
+
}
|
app/design/frontend/base/default/template/highstreet/smart_app_banner.phtml
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Template for smart-app-banner
|
4 |
+
*/
|
5 |
+
|
6 |
+
$website = Mage::app()->getWebsite()->getCode();
|
7 |
+
|
8 |
+
$configHelper = Mage::helper('highstreet_hsapi/config_api');
|
9 |
+
|
10 |
+
$id = $configHelper->storeIdentifier();
|
11 |
+
|
12 |
+
if ($id == "") { // No id set == no smartbanner
|
13 |
+
return;
|
14 |
+
}
|
15 |
+
|
16 |
+
// Request config
|
17 |
+
$config = new stdClass();
|
18 |
+
|
19 |
+
$config->store = Mage::app()->getStore()->getCode();
|
20 |
+
$config->host = $_SERVER['HTTP_HOST'];
|
21 |
+
|
22 |
+
$request = $this->getRequest();
|
23 |
+
$config->module = $request ? strtolower($request->getModuleName()) : '';
|
24 |
+
$config->controller = $request ? strtolower($request->getControllerName()) : '';
|
25 |
+
|
26 |
+
$config->locale = Mage::app()->getLocale()->getLocaleCode();
|
27 |
+
|
28 |
+
|
29 |
+
|
30 |
+
// Content config
|
31 |
+
$content = new stdClass();
|
32 |
+
|
33 |
+
$category = Mage::registry('current_category');
|
34 |
+
$content->category = $category ? $category->getId() : null;
|
35 |
+
|
36 |
+
$product = Mage::registry('current_product');
|
37 |
+
$content->product = $product ? $product->getId() : null;
|
38 |
+
|
39 |
+
$content->query = Mage::app()->getRequest()->getParam('q', null);
|
40 |
+
|
41 |
+
$content->version = Mage::getConfig()->getModuleConfig('Highstreet_SmartAppBanner')->version;
|
42 |
+
|
43 |
+
|
44 |
+
// Don't show on checkout
|
45 |
+
$module_blacklist = array( 'checkout', 'onestepcheckout', 'hsapi' );
|
46 |
+
$controller_blacklist = array( 'checkout_cart' );
|
47 |
+
|
48 |
+
if ( in_array($config->module, $module_blacklist)
|
49 |
+
|| in_array($config->controller, $controller_blacklist) ) {
|
50 |
+
|
51 |
+
return;
|
52 |
+
|
53 |
+
}
|
54 |
+
|
55 |
+
// Construct javascript url
|
56 |
+
$configHelper = Mage::helper('highstreet_hsapi/config_api');
|
57 |
+
$middleWareUrl = $configHelper->middlewareUrl();
|
58 |
+
$base_url = $middleWareUrl . "/smartbanner";
|
59 |
+
$key = md5('dY63*23xOi'. $configHelper->storeIdentifier());
|
60 |
+
$params = base64_url_encode(encrypt(json_encode($config), $key));
|
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 |
+
*/
|
77 |
+
function base64_url_encode($input) {
|
78 |
+
return strtr(base64_encode($input), '+/=', '-_~');
|
79 |
+
}
|
80 |
+
|
81 |
+
|
82 |
+
?>
|
83 |
+
|
84 |
+
<script type="text/javascript">
|
85 |
+
//<![CDATA[
|
86 |
+
var smartAppBannerContent = <?php echo json_encode($content); ?>;
|
87 |
+
//]]>
|
88 |
+
</script>
|
89 |
+
|
90 |
+
<script src="<?php echo $js_url; ?>" defer="true" ></script>
|
91 |
+
|
app/etc/modules/Highstreet_SmartAppBanner.xml
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<Highstreet_SmartAppBanner>
|
5 |
+
|
6 |
+
<!-- Whether our module is active: true or false -->
|
7 |
+
<active>true</active>
|
8 |
+
|
9 |
+
<!-- Which code pool to use: core, community or local -->
|
10 |
+
<codePool>local</codePool>
|
11 |
+
|
12 |
+
</Highstreet_SmartAppBanner>
|
13 |
+
</modules>
|
14 |
+
</config>
|
app/locale/de_DE/Highstreet_Hsapi.csv
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"Welcome","Willkommen"
|
2 |
+
"Billing address","Adresse"
|
3 |
+
"Shipment","Versand"
|
4 |
+
"Payment","Zahlung"
|
5 |
+
"Confirmation","Bestätigung"
|
6 |
+
"Log out","Ausloggen"
|
7 |
+
"Confirm and pay","Bestätigen & bezahlen"
|
8 |
+
"Your order is not final yet","Ihre Bestellung ist noch nicht definitiv"
|
9 |
+
"You will continue to our secure payment page","Sie werden in unsere gesicherte Zahlungsumgebung weitergeleitet"
|
10 |
+
"Hello!","Hallo!"
|
11 |
+
"Checkout as guest","Als Gast bezahlen"
|
12 |
+
"Log in","Einloggen"
|
13 |
+
"hsapi_Register","Registrieren"
|
14 |
+
"Sign In","Anmelden"
|
15 |
+
"E-mail address","E-Mail-Adresse"
|
16 |
+
"ipad_Password","Passwort"
|
17 |
+
"Forgot your password?","Passwort vergessen?"
|
18 |
+
"Send","Senden"
|
19 |
+
"We have sent you an e-mail with which you can change your password.","Eine E-Mail, mit der Sie Ihr Passwort ändern können, wurde an die von Ihnen angegebene Adresse gesendet."
|
20 |
+
"Create an account now","Account erstellen"
|
21 |
+
"and checkout faster next time","und beim nächsten Mal noch einfacher bestellen"
|
22 |
+
"Please enter a valid e-mailaddress","Eine gültige E-Mailadresse eingeben"
|
23 |
+
"Please enter a valid password","Ein gültiges Passwort eingeben"
|
24 |
+
"Repeat the password","Passwort wiederholen"
|
25 |
+
"First Name","Vorname"
|
26 |
+
"Last Name","Nachname"
|
27 |
+
"Please enter a valid phone number.","Eine gültige Telefonnummer angeben"
|
28 |
+
"Phone number","Telefonnummer"
|
29 |
+
"We ask for your phone number so that we can call you about your order if need be. We will never use your telephone number for other purposes.","Wir bitten Sie um die Angabe Ihrer Telefonnummer, sodass wir Sie wegen Ihrer Bestellung anrufen können, falls nötig. Wir werden Ihre Telefonnummer niemals für andere Zwecke verwenden."
|
30 |
+
"Street","Straße"
|
31 |
+
"House number","Hausnummer"
|
32 |
+
"Zip code","PLZ"
|
33 |
+
"City","Ort"
|
34 |
+
"Something went wrong","Etwas ist schief gegangen"
|
35 |
+
"Please try again","Noch einmal versuchen"
|
36 |
+
"How do you want to pay for your order?","Wie möchten Sie Ihre Bestellung <br /> bezahlen?"
|
37 |
+
"Please check your order.","Ist Ihre Bestellung richtig?"
|
38 |
+
"Please check the order overview. If this is correct, you can place your order.","Hier sehen Sie eine Übersicht Ihrer Bestellung. Wenn alles richtig ist, können Sie die Bestellung absenden."
|
39 |
+
"How do you want to receive your order?","Wie möchten Sie Ihre Bestellung <br /> erhalten?"
|
40 |
+
"Invoice address / delivery address","Rechnungsadresse / Lieferadresse"
|
41 |
+
"Edit","Ändern"
|
42 |
+
"Delivery method","Versandoption"
|
43 |
+
"Payment method","Zahlungsweise"
|
44 |
+
"You can continue to the next step when you have entered all fields","Sie können erst zum nächsten Schritt gehen, wenn Sie alle Felder ausgefüllt haben"
|
45 |
+
"There has been an unknown error. Please try again later again later.","Ein unbekannter Fehler ist aufgetreten. Versuchen Sie es später noch einmal."
|
46 |
+
"Thanks for shopping at ","Schön, dass Sie bei "
|
47 |
+
".<span class='hidden'>_ORDER_TEXT</span>"," bestellen."
|
48 |
+
"When you tap 'Confirm and pay', you agree with ","Wenn Sie auf ""Bestätigen und bezahlen"" klicken, akzeptieren Sie "
|
49 |
+
"the general terms","die allgemeinen Geschäftsbedingungen"
|
50 |
+
" of "," von "
|
51 |
+
"Ship to the same address","Bestellung an die gleiche Adresse senden"
|
52 |
+
"Invoice address","Rechnungsadresse"
|
53 |
+
"Delivery address","Lieferadresse"
|
54 |
+
"Please make sure your passwords match.","Die eingegebenen Passwörter stimmen nicht überein."
|
55 |
+
|
56 |
+
|
57 |
+
"hsapi.index.couponTip","Haben Sie einen Gutschein? <br /> Diesen können Sie später im Schritt <br /> ""Zahlung"" einlösen."
|
58 |
+
|
59 |
+
"hsapi.addCouponAction.error.fatal","Ein unbekannter Fehler ist aufgetreten. Versuchen Sie es später noch einmal."
|
60 |
+
"hsapi.addCouponAction.error.invalid","Der Gutschein, den Sie eingegeben haben, ist nicht gültig."
|
61 |
+
"hsapi.addCouponAction.error.length","Der Gutschein, den Sie eingegeben haben, ist zu lang, die maximale Länge beträgt "
|
62 |
+
"hsapi.addCouponAction.success","Gutschein '{coupon_code}' wurde erfolgreich eingelöst. Sie können Ihren Rabatt in der Bestellliste ansehen."
|
63 |
+
"hsapi.addCouponAction.success.removed","Gutschein '{coupon_code}' wurde erfolgreich gelöscht."
|
64 |
+
|
65 |
+
"hsapi.checkout.coupon.addTitle","<u> Gutschein </u> hinzufügen"
|
66 |
+
"hsapi.checkout.coupon.form.title","Geben Sie hier den Gutscheincode ein."
|
67 |
+
"hsapi.checkout.coupon.form.code","Gutschein"
|
68 |
+
"hsapi.checkout.coupon.form.add","Hinzufügen"
|
69 |
+
"hsapi.checkout.coupon.form.remove","Entfernen"
|
70 |
+
"hsapi.checkout.coupon.paymentTitle","Wählen Sie aus den folgenden Zahlungsmöglichkeiten"
|
71 |
+
|
72 |
+
"There is already a customer registered using this email address. Please login using this email address or enter a different email address to register your account.","Die angegebene E-Mailadresse ist schon an einen Account gekoppelt. Loggen Sie sich mit dieser Adresse ein oder verwenden Sie eine andere E-Mailadresse für die Registrierung."
|
package.xml
CHANGED
@@ -1,19 +1,19 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Highstreet</name>
|
4 |
-
<version>1.0
|
5 |
<stability>stable</stability>
|
6 |
<license>-</license>
|
7 |
<channel>community</channel>
|
8 |
<extends/>
|
9 |
-
<summary>Highstreet Magento Extension. This extension allows the Highstreet iPad
|
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
|
13 |
<authors><author><name>Christian Apers</name><user>Christian</user><email>Christian@Touchwonders.com</email></author><author><name>Tim Wachter</name><user>Tim</user><email>Tim@Touchwonders.com</email></author></authors>
|
14 |
-
<date>
|
15 |
-
<time>
|
16 |
-
<contents><target name="magecommunity"><dir name="Technooze"><dir name="Timage"><dir name="Block"><file name="Data.php" hash="02f8402df49abe64716e01746055330e"/></dir><dir name="Helper"><file name="Data.php" hash="4ade060d79bd29a91a524fce9e61e49b"/><file name="Data.php" hash="4ade060d79bd29a91a524fce9e61e49b"/></dir><dir name="etc"><file name="config.xml" hash="ff5675c31f16c03674ae87f19964a59d"/><file name="config.xml" hash="ff5675c31f16c03674ae87f19964a59d"/></dir></dir></dir></target><target name="magelocal"><dir name="Highstreet"><dir name="Hsapi"><dir name="Helper"><file name="
|
17 |
<compatible/>
|
18 |
<dependencies><required><php><min>5.0.0.0</min><max>6.0.0.0</max></php><extension><name>gd</name><min>2.0</min><max>3.0</max></extension></required></dependencies>
|
19 |
</package>
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Highstreet</name>
|
4 |
+
<version>1.1.0</version>
|
5 |
<stability>stable</stability>
|
6 |
<license>-</license>
|
7 |
<channel>community</channel>
|
8 |
<extends/>
|
9 |
+
<summary>Highstreet Magento Extension. This extension allows the Highstreet iPad and iPhone apps to connect to the store. </summary>
|
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>The new complete Highstreet extension</notes>
|
13 |
<authors><author><name>Christian Apers</name><user>Christian</user><email>Christian@Touchwonders.com</email></author><author><name>Tim Wachter</name><user>Tim</user><email>Tim@Touchwonders.com</email></author></authors>
|
14 |
+
<date>2015-09-14</date>
|
15 |
+
<time>15:47:30</time>
|
16 |
+
<contents><target name="magecommunity"><dir name="Technooze"><dir name="Timage"><dir name="Block"><file name="Data.php" hash="02f8402df49abe64716e01746055330e"/></dir><dir name="Helper"><file name="Data.php" hash="4ade060d79bd29a91a524fce9e61e49b"/><file name="Data.php" hash="4ade060d79bd29a91a524fce9e61e49b"/></dir><dir name="etc"><file name="config.xml" hash="ff5675c31f16c03674ae87f19964a59d"/><file name="config.xml" hash="ff5675c31f16c03674ae87f19964a59d"/></dir></dir></dir></target><target name="magelocal"><dir name="Highstreet"><dir name="Hsapi"><dir name="Helper"><dir name="Config"><file name="Api.php" hash="04ab6b698c0f21c467f9d80f4d649f74"/></dir><file name="Data.php" hash="cec9e38fe3e3cf06d544c013e52e9cc8"/><file name="Encryption.php" hash="a482d2a12ac584966d9f066bb1f5a892"/></dir><dir name="Model"><file name="Attributes.php" hash="6ad75fe439bfc6993ff741b2ae452150"/><file name="Categories.php" hash="e7f051c672b32a3913f2b5fe60e74378"/><file name="Checkout.php" hash="00a2912a581a9fa4ea0e9b98177860ee"/><file name="CheckoutV2.php" hash="4a462bd5ca20cea19d0eecf0cc61817c"/><file name="Images.php" hash="b26334f765cfd1f5b59c3509901ea8b1"/><file name="Observer.php" hash="e787c2c519232a1c93182df212e505c8"/><file name="Products.php" hash="6c2720b3f7bc327127955434e42ff9eb"/><file name="SearchSuggestions.php" hash="17e0a008e2f90c0f5f6c5f7c3f010c9c"/><dir name="System"><dir name="Config"><file name="Environment.php" hash="5ef07d78cf67bc47be1a64e54ff643ec"/></dir></dir></dir><dir name="controllers"><file name="CheckoutController.php" hash="c967c0075dae43e230d3f8dbc858d0db"/><file name="IndexController.php" hash="c4c697e4645f49d9b92fb7193a79eea8"/></dir><dir name="etc"><file name="config.xml" hash="64eb9de832bf0ef2de232d2af51d51bd"/><file name="system.xml" hash="3481c560e663170a96df5a09a766d03e"/></dir></dir><dir name="SmartAppBanner"><dir name="etc"><file name="config.xml" hash="aff217b03485fdf69874f5f0975c1cfe"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Highstreet_Api.xml" hash="97e586a7ef0a274d4f0fda883c646f31"/><file name="Technooze_Timage.xml" hash="bec7a12e3028d25b3a28c6eafe1878b4"/><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="915e6d1d2fbe97baea707c5be21d4cfe"/><file name="smart_app_banner.phtml" hash="0faa81b53d95a57583e1c1747ac9cd96"/></dir></dir></dir></dir></dir></target><target name="magelocale"><dir><dir name="de_DE"><file name="Highstreet_Hsapi.csv" hash="bd1c428e4da644cf5a39d3493ad142e4"/></dir><dir name="en_US"><file name="Highstreet_Hsapi.csv" hash="0246609251f607c5f4119ba56db14c6e"/></dir><dir name="nl_NL"><file name="Highstreet_Hsapi.csv" hash="a2f582408d85509c3de30d26f090fa9a"/></dir></dir></target></contents>
|
17 |
<compatible/>
|
18 |
<dependencies><required><php><min>5.0.0.0</min><max>6.0.0.0</max></php><extension><name>gd</name><min>2.0</min><max>3.0</max></extension></required></dependencies>
|
19 |
</package>
|