Highstreet - Version 1.5.0

Version Notes

-

Download this release

Release Info

Developer Christian Apers
Extension Highstreet
Version 1.5.0
Comparing to
See all releases


Code changes from version 1.1.0 to 1.5.0

app/code/community/Technooze/Timage/Block/Data.php DELETED
@@ -1,10 +0,0 @@
1
- <?php
2
- /**
3
- * @category Technooze/Modules/magento-how-tos
4
- * @package Technooze_Timage
5
- * @author Damodar Bashyal
6
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
7
- */
8
- class Technooze_Timage_Block_Data extends Mage_Core_Block_Template
9
- {
10
- }
 
 
 
 
 
 
 
 
 
 
app/code/community/Technooze/Timage/Helper/Data.php DELETED
@@ -1,134 +0,0 @@
1
- <?php
2
- /**
3
- * @category Technooze/Modules/magento-how-tos
4
- * @package Technooze_Timage
5
- * @author Damodar Bashyal
6
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
7
- */
8
- class Technooze_Timage_Helper_Data extends Mage_Core_Helper_Abstract
9
- {
10
- var
11
- $width = null,
12
- $height = null,
13
- $rawImg = '',
14
- $img = false,
15
- $cacheDir = '',
16
- $cachedImage = '',
17
- $cachedImageUrl = '',
18
- $ext = '',
19
- $bgColor = array(255, 255, 255),
20
- $imageObj = '',
21
- $baseUrl = '',
22
- $placeHolder = false;
23
-
24
- public function init($img=false)
25
- {
26
- if($img)
27
- {
28
- $this->rawImg = $img;
29
- }
30
-
31
- if(empty($this->placeHolder))
32
- {
33
- $this->placeHolder = Mage::getDesign()->getSkinUrl('images/catalog/product/placeholder/image.jpg');
34
- }
35
- $this->imagePath($this->rawImg);
36
-
37
- $this->imageObj = new Varien_Image($this->img, Varien_Image_Adapter::ADAPTER_GD2);
38
-
39
- $path_parts = pathinfo($this->img);
40
-
41
- $this->ext = $path_parts['extension'];
42
-
43
- $this->cacheDir();
44
-
45
- return $this;
46
- }
47
-
48
- public function resize($width=false, $height=false)
49
- {
50
- if($width)
51
- {
52
- $this->width = $width;
53
- }
54
-
55
- if($height)
56
- {
57
- $this->height = $height;
58
- }
59
-
60
- $this->cacheIt();
61
-
62
- return $this->cachedImageUrl();
63
- }
64
-
65
- public function cachedImageUrl()
66
- {
67
- $img = str_replace(BP, '', $this->cachedImage);
68
- $img = trim(str_replace('\\', '/', $img), '/');
69
-
70
- return $this->baseUrl . $img;
71
- }
72
-
73
- public function cacheIt()
74
- {
75
- $this->cachedImage = $this->cacheDir . md5($this->img . $this->width . $this->height) . '.' .$this->ext;
76
-
77
- if(file_exists($this->cachedImage))
78
- {
79
- return $this->cachedImage;
80
- }
81
-
82
- $this->resizer();
83
- }
84
-
85
- public function resizer()
86
- {
87
- try{
88
- $this->imageObj->constrainOnly(true);
89
- $this->imageObj->keepAspectRatio(true);
90
- $this->imageObj->keepFrame(false);
91
- $this->imageObj->keepTransparency(true);
92
- $this->imageObj->backgroundColor($this->bgColor);
93
- $this->imageObj->resize($this->width, $this->height);
94
- $this->imageObj->save($this->cachedImage);
95
- } catch(Exception $e){
96
- return $e->getMessage();
97
- }
98
- }
99
-
100
- public function imagePath($img='')
101
- {
102
- $this->baseUrl = str_replace('index.php/', '', Mage::getBaseUrl());
103
- $img = str_replace($this->baseUrl, '', $img);
104
- $img = trim(str_replace('/', DS, $img), DS);
105
-
106
- $this->img = BP . DS . $img;
107
-
108
- if((!file_exists($this->img) || !is_file($this->img)) && !empty($this->placeHolder))
109
- {
110
- $this->imagePath($this->placeHolder);
111
- $this->placeHolder = false;
112
- }
113
- }
114
-
115
- public function cacheDir()
116
- {
117
- $cache = BP . DS . 'media' . DS . 'catalog' . DS . 'cache' . DS;
118
-
119
- if(!is_dir($cache))
120
- {
121
- mkdir($cache);
122
- }
123
- $this->cacheDir = $cache;
124
- }
125
-
126
- public function getOriginalSize() {
127
-
128
- $width = $this->imageObj->getOriginalWidth();
129
- $height = $this->imageObj->getOriginalHeight();
130
-
131
- return array('width' => $width, 'height' => $height);
132
-
133
- }
134
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Technooze/Timage/etc/config.xml DELETED
@@ -1,46 +0,0 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /**
4
- * @category Technooze/Modules/magento-how-tos
5
- * @package Technooze_Timage
6
- * @author Damodar Bashyal
7
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
8
- */
9
- -->
10
- <config>
11
- <modules>
12
- <Technooze_Timage>
13
- <version>0.1.0</version>
14
- </Technooze_Timage>
15
- </modules>
16
- <frontend>
17
- <routers>
18
- <timage>
19
- <use>standard</use>
20
- <args>
21
- <module>Technooze_Timage</module>
22
- <frontName>timage</frontName>
23
- </args>
24
- </timage>
25
- </routers>
26
- <layout>
27
- <updates>
28
- <timage>
29
- <file>timage.xml</file>
30
- </timage>
31
- </updates>
32
- </layout>
33
- </frontend>
34
- <global>
35
- <helpers>
36
- <timage>
37
- <class>Technooze_Timage_Helper</class>
38
- </timage>
39
- </helpers>
40
- <blocks>
41
- <timage>
42
- <class>Technooze_Timage_Block</class>
43
- </timage>
44
- </blocks>
45
- </global>
46
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Highstreet/Hsapi/Helper/Config/Api.php CHANGED
@@ -12,6 +12,7 @@ class Highstreet_Hsapi_Helper_Config_Api extends Mage_Core_Helper_Abstract {
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');
@@ -52,6 +53,16 @@ class Highstreet_Hsapi_Helper_Config_Api extends Mage_Core_Helper_Abstract {
52
  return ($app_name === NULL) ? "" : $app_name;
53
  }
54
 
 
 
 
 
 
 
 
 
 
 
55
  public function middlewareUrl() {
56
  if ($this->storeIdentifier() == "") {
57
  return NULL;
@@ -74,4 +85,18 @@ class Highstreet_Hsapi_Helper_Config_Api extends Mage_Core_Helper_Abstract {
74
  public function shouldShowNativeSmartbanner() {
75
  return ($this->nativeSmartbannerActive() && $this->nativeSmartbannerAppId() != "");
76
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  }
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
+ const CHECKOUT_URL_FALLBACK = "checkout/cart";
16
 
17
  public function alwaysAddSimpleProductsToCart() {
18
  $alwaysAddSimpleProductsToCart = Mage::getStoreConfig('highstreet_hsapi/api/always_add_simple_products');
53
  return ($app_name === NULL) ? "" : $app_name;
54
  }
55
 
56
+ public function standaloneCheckoutActive() {
57
+ $saco_active = Mage::getStoreConfig('highstreet_hsapi/api/checkout_saco_active');
58
+ return ($saco_active === NULL) ? true : (bool)$saco_active;
59
+ }
60
+
61
+ public function checkoutRedirectUrl() {
62
+ $checkout_redirect_url = Mage::getStoreConfig('highstreet_hsapi/api/checkout_redirect_url');
63
+ return ($checkout_redirect_url === NULL) ? self::CHECKOUT_URL_FALLBACK : $checkout_redirect_url;
64
+ }
65
+
66
  public function middlewareUrl() {
67
  if ($this->storeIdentifier() == "") {
68
  return NULL;
85
  public function shouldShowNativeSmartbanner() {
86
  return ($this->nativeSmartbannerActive() && $this->nativeSmartbannerAppId() != "");
87
  }
88
+
89
+ public function attributesSortOrderRaw() {
90
+ return Mage::getStoreConfig('highstreet_hsapi/api/attribute_sort_order');
91
+ }
92
+
93
+ public function attributesSortOrder() {
94
+ // Can return NULL or a string
95
+ $jsonString = $this->attributesSortOrderRaw();
96
+
97
+ // Will return NULL if given NULL or a malformed string
98
+ $data = json_decode($jsonString, true);
99
+
100
+ return ($data === NULL) ? array() : $data;
101
+ }
102
  }
app/code/local/Highstreet/Hsapi/Helper/Data.php CHANGED
@@ -4,7 +4,7 @@
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_Data extends Mage_Core_Helper_Abstract
@@ -95,16 +95,12 @@ class Highstreet_Hsapi_Helper_Data extends Mage_Core_Helper_Abstract
95
 
96
  // Check if there is an category ID set
97
  if (empty($categoryId) || !is_numeric($categoryId)) {
98
- $store = Mage::getModel('core/store')->load(Mage_Core_Model_App::DISTRO_STORE_ID);
99
  $categoryId = $store->getRootCategoryId();
100
  }
101
 
102
  $data = array("query_text" => $searchString, "popularity" => 1);
103
 
104
- if ($this->searchSuggestionTableHasHSAPIColumn()) {
105
- $data["hsapi_category_id"] = $categoryId;
106
- }
107
-
108
  $catalogSearchSaveModel->addData($data);
109
  $catalogSearchSaveModel->setIsProcessed(1);
110
  $catalogSearchSaveModel->save();
@@ -118,27 +114,4 @@ class Highstreet_Hsapi_Helper_Data extends Mage_Core_Helper_Abstract
118
  );
119
  }
120
  }
121
-
122
- /**
123
- * Returns a BOOL wether the "catalogsearch/query" table has the HSAPI category column
124
- *
125
- * @return bool
126
- */
127
- public function searchSuggestionTableHasHSAPIColumn() {
128
- try {
129
- $catalogSearchReadModel = Mage::getModel('catalogsearch/query')->getCollection();
130
- $catalogSearchReadModel->addFieldToSelect('hsapi_category_id');
131
- $catalogSearchReadModel->getSelect()->limit(1);
132
- $catalogSearchReadModel->getData();
133
- return TRUE;
134
- } catch (Exception $e) {
135
- return FALSE;
136
- }
137
-
138
- return FALSE;
139
- }
140
-
141
  }
142
-
143
-
144
-
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_Data extends Mage_Core_Helper_Abstract
95
 
96
  // Check if there is an category ID set
97
  if (empty($categoryId) || !is_numeric($categoryId)) {
98
+ $store = Mage::app()->getStore(Mage_Core_Model_App::DISTRO_STORE_ID);
99
  $categoryId = $store->getRootCategoryId();
100
  }
101
 
102
  $data = array("query_text" => $searchString, "popularity" => 1);
103
 
 
 
 
 
104
  $catalogSearchSaveModel->addData($data);
105
  $catalogSearchSaveModel->setIsProcessed(1);
106
  $catalogSearchSaveModel->save();
114
  );
115
  }
116
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  }
 
 
 
app/code/local/Highstreet/Hsapi/Helper/Encryption.php CHANGED
@@ -8,13 +8,8 @@
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();
8
  */
9
 
10
  class Highstreet_Hsapi_Helper_Encryption extends Mage_Core_Helper_Abstract {
 
11
  private $hmacEncryptionKey = "5JbqhKdBGtV8J4PH82cm5YDr5f8b4Rbk";
12
 
 
 
 
 
13
  public function APISignatureStringIsValid() {
14
  $givenAPISignature = $_SERVER['HTTP_X_API_SIGNATURE'];
15
  $signatureString = $this->_getSignatureString();
app/code/local/Highstreet/Hsapi/Model/Attributes.php CHANGED
@@ -4,7 +4,7 @@
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_Model_Attributes extends Mage_Core_Model_Abstract
@@ -18,6 +18,12 @@ class Highstreet_Hsapi_Model_Attributes extends Mage_Core_Model_Abstract
18
  */
19
  protected $_entityTypeId;
20
 
 
 
 
 
 
 
21
  /**
22
  * Class constructor
23
  * We are setting the entityTypeId on construct. In case we want
@@ -47,8 +53,19 @@ class Highstreet_Hsapi_Model_Attributes extends Mage_Core_Model_Abstract
47
  public function getAttribute($code=null)
48
  {
49
  if(null != $code){
50
- $response = $this->_extractResponse($this->_getAttribute($code));
51
- return $response['attributes'][0];
 
 
 
 
 
 
 
 
 
 
 
52
  }
53
  return false;
54
  }
@@ -75,7 +92,7 @@ class Highstreet_Hsapi_Model_Attributes extends Mage_Core_Model_Abstract
75
  * @param null $code
76
  * @return Mage_Eav_Model_Entity_Attribute
77
  */
78
- private function _getAttribute($code=null)
79
  {
80
  $attributes = Mage::getResourceModel('eav/entity_attribute_collection')
81
  ->setEntityTypeFilter($this->_entityTypeId)
@@ -133,7 +150,7 @@ class Highstreet_Hsapi_Model_Attributes extends Mage_Core_Model_Abstract
133
  {
134
  $optionValues = array();
135
  //We need to load the attribute to be able to use it get the options
136
- $attribute = Mage::getModel('eav/entity_attribute')->load($attributeId);
137
  $options = Mage::getModel('eav/entity_attribute_source_table')
138
  ->setAttribute($attribute)
139
  ->getAllOptions(false, false); //getAllOptions($withEmpty = true, $defaultValues = false)
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_Model_Attributes extends Mage_Core_Model_Abstract
18
  */
19
  protected $_entityTypeId;
20
 
21
+ /**
22
+ * Often times the same attribute type needs to be retrieved multiple times, cache the responses for speed
23
+ *
24
+ */
25
+ protected $_cachedAttributes = array();
26
+
27
  /**
28
  * Class constructor
29
  * We are setting the entityTypeId on construct. In case we want
53
  public function getAttribute($code=null)
54
  {
55
  if(null != $code){
56
+ if (array_key_exists($code, $this->_cachedAttributes)) {
57
+ return $this->_cachedAttributes[$code];
58
+ } else {
59
+ $attribute = $this->_extractResponse($this->_getAttribute($code));
60
+
61
+ $response = array();
62
+ if (array_key_exists('attributes', $attribute) && count($attribute['attributes']) > 0) {
63
+ $response = $attribute['attributes'][0];
64
+ }
65
+
66
+ $this->_cachedAttributes[$code] = $response;
67
+ return $response;
68
+ }
69
  }
70
  return false;
71
  }
92
  * @param null $code
93
  * @return Mage_Eav_Model_Entity_Attribute
94
  */
95
+ protected function _getAttribute($code=null)
96
  {
97
  $attributes = Mage::getResourceModel('eav/entity_attribute_collection')
98
  ->setEntityTypeFilter($this->_entityTypeId)
150
  {
151
  $optionValues = array();
152
  //We need to load the attribute to be able to use it get the options
153
+ $attribute = Mage::getSingleton('eav/config')->getAttribute('catalog_product', $attributeId);
154
  $options = Mage::getModel('eav/entity_attribute_source_table')
155
  ->setAttribute($attribute)
156
  ->getAllOptions(false, false); //getAllOptions($withEmpty = true, $defaultValues = false)
app/code/local/Highstreet/Hsapi/Model/Categories.php CHANGED
@@ -4,86 +4,31 @@
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_Model_Categories extends Mage_Core_Model_Abstract
11
  {
12
  const CATEGORY_MEDIA_PATH = "/media/catalog/category/";
13
 
14
- /**
15
- * Get category and children from id
16
- * @param $categoryId
17
- *
18
- * @return bool
19
- */
20
- public function getCategories($categoryId)
21
- {
22
- $categoryObject = Mage::getModel('catalog/category')->load($categoryId);
23
-
24
- $productCollection = $categoryObject->getProductCollection()
25
- ->addAttributeToFilter('visibility', array('in' => array(
26
- Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG,
27
- Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH))
28
- );
29
-
30
- $name = $categoryObject->getData('name');
31
- if (!empty($name)) {
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();
39
- } else {
40
- $imageUrl = '';
41
- }
42
- $category['image'] = $imageUrl;
43
-
44
- $category['product_count'] = $productCollection->count();
45
-
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
- }
66
-
67
- return $category;
68
- }
69
- else {
70
- return false;
71
- }
72
- }
73
-
74
  /**
75
  * Gets the entire category tree. Can be filtered for a specific category with param categoryId
76
  *
77
  * @param integer categoryId, a categoryId which will filter the tree
 
 
78
  * @return array Array of categories
79
  */
80
- public function getCategoryTree($categoryId = null) {
81
- if ($categoryId == null) {
82
  $categoryId = Mage::app()->getStore()->getRootCategoryId();
83
- }
84
 
85
- $categoryObject = Mage::getModel('catalog/category')->load($categoryId);
86
- $children = $this->getChildrenCollectionForCategoryId($categoryId);
 
 
 
87
 
88
  $productCollection = $categoryObject->getProductCollection()
89
  ->addAttributeToFilter('visibility', array('in' => array(
@@ -94,7 +39,7 @@ class Highstreet_Hsapi_Model_Categories extends Mage_Core_Model_Abstract
94
  $name = $categoryObject->getData('name');
95
  if (!empty($name)) {
96
  $category = array();
97
- $category['id'] = $categoryId;
98
  $category['title'] = $name;
99
  $category['position'] = $categoryObject->getData('position');
100
 
@@ -107,17 +52,21 @@ class Highstreet_Hsapi_Model_Categories extends Mage_Core_Model_Abstract
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
-
119
- if (is_array($childRepresentation)) {
120
- array_push($category['children'], $childRepresentation);
 
 
121
  }
122
  }
123
  }
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_Model_Categories extends Mage_Core_Model_Abstract
11
  {
12
  const CATEGORY_MEDIA_PATH = "/media/catalog/category/";
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  /**
15
  * Gets the entire category tree. Can be filtered for a specific category with param categoryId
16
  *
17
  * @param integer categoryId, a categoryId which will filter the tree
18
+ * @param integer maxDepth, Maxmimum depth of category tree to be gotten
19
+ * @param integer currentDepth, Current depth
20
  * @return array Array of categories
21
  */
22
+ public function getCategory($categoryId = null, $maxDepth = -1, $currentDepth = 0) {
23
+ if ($categoryId === null || $categoryId === "tree") {
24
  $categoryId = Mage::app()->getStore()->getRootCategoryId();
25
+ }
26
 
27
+ if (is_a($categoryId, "Mage_Catalog_Model_Category")) {
28
+ $categoryObject = $categoryId;
29
+ } else {
30
+ $categoryObject = Mage::getModel('catalog/category')->load($categoryId);
31
+ }
32
 
33
  $productCollection = $categoryObject->getProductCollection()
34
  ->addAttributeToFilter('visibility', array('in' => array(
39
  $name = $categoryObject->getData('name');
40
  if (!empty($name)) {
41
  $category = array();
42
+ $category['id'] = $categoryObject->getData('entity_id');
43
  $category['title'] = $name;
44
  $category['position'] = $categoryObject->getData('position');
45
 
52
 
53
  $category['include_in_menu'] = (bool)$categoryObject->getData('include_in_menu');
54
 
55
+ $category['product_count'] = $productCollection->getSize();
56
+
57
+ $category['default_sort_by'] = $categoryObject->getDefaultSortBy();
58
 
59
  // category children
60
  $category['children'] = array();
61
+ if ($maxDepth < 0 || ($maxDepth > 0 && $maxDepth > $currentDepth)) {
62
+ $children = $this->getChildrenCollectionForCategoryId($categoryObject->getData('entity_id'));
63
+ if ($children->count() > 0) {
64
+ foreach ($children as $child) {
65
+ $childRepresentation = $this->getCategory($child, $maxDepth, $currentDepth+1);
66
+
67
+ if (is_array($childRepresentation)) {
68
+ array_push($category['children'], $childRepresentation);
69
+ }
70
  }
71
  }
72
  }
app/code/local/Highstreet/Hsapi/Model/Checkout.php DELETED
@@ -1,461 +0,0 @@
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_Checkout extends Mage_Core_Model_Abstract
10
- {
11
- /**
12
- * 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.
13
- * The array should have the following format:
14
- * {"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}]}
15
- * With this format we will lateron be able to extend it for configurable products
16
- *
17
- * @param array An array of product SKU's to fill the cart
18
- */
19
- public function fillCartWithProductsAndQuantities($products = false) {
20
- if (!$products) {
21
- return;
22
- }
23
-
24
-
25
- $cart = Mage::getModel('checkout/cart');
26
- $cart->init();
27
- $cart->truncate(); // Reset cart everytime this function is called
28
-
29
- foreach ($products as $key => $value) {
30
- if (empty($value["id"])) {
31
- continue;
32
- }
33
-
34
- try {
35
- $product = $this->loadProduct($value["id"]);
36
- } catch (Exception $e) {
37
- continue;
38
- }
39
-
40
-
41
- if (empty($value["quantity"]) || !is_numeric($value["quantity"]) || $value["quantity"] === 0) {
42
- continue; //skip this product
43
- }
44
-
45
- $quantity = $value["quantity"];
46
-
47
- try {
48
-
49
- $parent = $this->_getParentProduct($product);
50
- if($parent) {
51
- $configurations = $this->_getConfiguration($product,$parent);
52
- $configurations = array('super_attribute' => $configurations);
53
- $options = array_merge(array("qty" => $quantity),$configurations);
54
- $cart->addProduct($parent,$options);
55
- } else {
56
- $cart->addProduct($product, array("qty" => $quantity));
57
- }
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
- } catch (Exception $e) {
66
- continue;
67
- }
68
- }
69
-
70
- $cart->save();
71
- Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
72
- }
73
-
74
-
75
- /**
76
- * Can retrieve an existing quote, or create a new (temporary) quote with the given objects
77
- * Purpose of this method is to return all products that exist in the cart, all shipping information and the totals
78
- *
79
- * @param array An array of product SKU's to fill the cart. Format identical to fillCartWithProductsAndQuantities
80
- * @param quote_id (optional) The quote_id for which you would like to return the information
81
- */
82
- public function getQuoteWithProductsAndQuantities($products = false, $quote_id = -1) {
83
- if ($products === false && $quote_id == -1) {
84
- return;
85
- }
86
-
87
- $response = array();
88
-
89
- Mage::getSingleton('checkout/session')->setQuoteId(null);
90
-
91
-
92
- $quote = null;
93
-
94
- if($quote_id == -1) {
95
- $cart = Mage::getModel('checkout/cart');
96
- $cart->init();
97
- $cart->truncate(); // Reset cart everytime this function is called
98
- $quote = $cart->getQuote();
99
- } else {
100
- $quote = Mage::getModel('sales/quote')->load($quote_id);
101
- if(!$quote->getId()) {
102
- return null;
103
- }
104
- }
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
-
129
-
130
-
131
- }
132
-
133
-
134
- //Helpers below
135
-
136
- private function getProductsInQuote($quote,$products = null) {
137
- $responseQuote = array();
138
-
139
-
140
- $quoteItemsAlreadyAdded = array();
141
- $quoteItems = $quote->getAllItems();
142
-
143
-
144
-
145
- //loop through the requested products
146
- foreach ($products as $key => $value) {
147
- if (empty($value["id"])) {
148
- continue;
149
- }
150
-
151
- try {
152
- $product = $this->loadProduct($value["id"]);
153
- } catch (Exception $e) {
154
- $productInQuote["errorMessage"] = $e->getMessage();
155
- $productInQuote["errorCode"] = 400; //something else went wrong
156
- $productInQuote["quantity"] = 0;
157
- }
158
-
159
- $parent = $this->_getParentProduct($product);
160
- if($parent)
161
- $configurations = $this->_getConfiguration($product,$parent);
162
-
163
-
164
-
165
- $requestedQuantity = $value["quantity"];
166
-
167
-
168
-
169
-
170
- //Set up default response
171
- $productInQuote = array();
172
- $productInQuote["product_id"] = $value["id"];
173
- $productInQuote["errorCode"] = 0;
174
- $productInQuote["errorMessage"] = null;
175
-
176
-
177
-
178
- try {
179
-
180
- if (!$product) {
181
- //product does not exist
182
-
183
- $productInQuote["errorCode"] = 400;
184
- $productInQuote["errorMessage"] = "The requested product does not exist";
185
- $productInQuote["quantity"] = 0;
186
-
187
-
188
- } else {
189
-
190
-
191
- $itemInventory = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product);
192
- $quoteItem = $quote->getItemByProduct($product);
193
-
194
-
195
- $actualQuantity = $requestedQuantity; //actual qty is what we are going to add
196
-
197
- //adjust actual quantity if we are requesting more than in stock
198
- $availableQuantity = $itemInventory->getQty();
199
- $isInStock = $itemInventory->getIsInStock();
200
- $isStockManaged = $itemInventory->getManageStock();
201
- $backordersAllowed = $itemInventory->getBackorders();
202
-
203
-
204
- if($isStockManaged) {
205
-
206
- if(!$isInStock) {
207
- $productInQuote["errorMessage"] = "Product is not in stock";
208
- $productInQuote["errorCode"] = 101; //product cannot be added
209
- $actualQuantity = 0;
210
- } else {
211
- //in stock, but should we cap it?
212
- if(!$backordersAllowed && $requestedQuantity > $availableQuantity) {
213
- $actualQuantity = $availableQuantity; //cap
214
- $productInQuote["errorMessage"] = "Requested quantity is not available, added ".(int)$actualQuantity." instead of ".$requestedQuantity ." products with id ".$value["id"]." to the cart";
215
- $productInQuote["errorCode"] = 102; //product can be added, but with a lower quantity
216
- //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
217
- //"Qty for Item's Status to Become Out of Stock" might be a negative integer
218
- }
219
-
220
- }
221
-
222
- }
223
-
224
- if($quoteItem) { //adjust existing entry
225
- $quoteItem->setQty($actualQuantity);
226
- } else { //or add new entry (but of course only when qty > 0)
227
- 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
228
- if($parent) {
229
- $configurations = array('super_attribute' => $configurations);
230
- $options = array_merge(array("qty" => $actualQuantity),$configurations);
231
-
232
-
233
- $quoteItem = $quote->addProduct($parent,new Varien_Object($options));
234
- } else {
235
- $quoteItem = $quote->addProduct($product,new Varien_Object(array("qty" => $actualQuantity)));
236
- }
237
-
238
- //response output
239
- $productInQuote = array_merge($this->getProductInQuoteResponse($quoteItem,$product),$productInQuote);
240
- } else {
241
- $productInQuote["quantity"] = 0;
242
- }
243
- }
244
-
245
-
246
- if($quoteItem) {
247
- $quoteItemsAlreadyAdded[] = $quoteItem->getProduct()->getId();
248
- }
249
-
250
-
251
-
252
- }
253
-
254
-
255
- } catch (Exception $e) {
256
- $productInQuote["errorMessage"] = $e->getMessage();
257
- $productInQuote["errorCode"] = 400; //something else went wrong
258
- $productInQuote["quantity"] = 0;
259
-
260
- }
261
-
262
-
263
-
264
- $responseQuote[] = $productInQuote;
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
-
288
- return $responseQuote;
289
- }
290
-
291
- private function getProductInQuoteResponse($quoteItem = null, $product = null) {
292
- if(!$quoteItem && !$product)
293
- return null;
294
- if(!$product)
295
- $product = $quoteItem->getProduct();
296
-
297
-
298
- $productInQuote = array();
299
- $productInQuote["product_id"] = $product->getId();
300
-
301
- if($quoteItem->getParentItem()) {
302
- $quoteItem = $quoteItem->getParentItem();
303
- $product = $quoteItem->getProduct();
304
- }
305
-
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;
317
- }
318
-
319
- private function getQuoteTotals($quote) {
320
-
321
-
322
- $quote->collectTotals()->save(); //required to fetch the totals
323
-
324
- //Totals
325
- $totals = $quote->getTotals(); //Total object
326
- $subtotal = $totals["subtotal"]->getValue(); //Subtotal value
327
- $grandtotal = $totals["grand_total"]->getValue(); //Grandtotal value
328
-
329
- $discount = 0;
330
- if(isset($totals['discount']) && $totals['discount']->getValue()) {
331
- $discount = $totals['discount']->getValue(); //Discount value if applied
332
- }
333
- $tax = 0;
334
- if(isset($totals['tax']) && $totals['tax']->getValue()) {
335
- $tax = $totals['tax']->getValue(); //Tax value if present
336
- }
337
-
338
- $totalItemsInCart = 0;
339
- foreach($quote->getAllItems() as $quoteItem) {
340
- if(count($quoteItem->getChildren()) > 0)
341
- continue;
342
- $totalItemsInCart++;
343
- }
344
-
345
-
346
- $responseTotals = array();
347
- $responseTotals["totalItemsInCart"] = $totalItemsInCart;
348
- $responseTotals["subtotal"] = $subtotal;
349
- $responseTotals["grandtotal"] = $grandtotal;
350
- $responseTotals["discount"] = $discount;
351
- $responseTotals["tax"] = $tax;
352
-
353
- return $responseTotals;
354
- }
355
-
356
- private function getSelectedShippingMethod($quote) {
357
- $quoteShippingAddress = $quote->getShippingAddress();
358
-
359
- $quoteShippingAddress->collectShippingRates()->save(); //collect the rates
360
-
361
- $chosenShippingMethod = $quoteShippingAddress->getShippingMethod();
362
-
363
- if ($chosenShippingMethod === "") {
364
- $chosenShippingMethod = null;
365
- }
366
-
367
- return $chosenShippingMethod;
368
- }
369
-
370
- private function getShippingMethods($quote, $selectedShippingMethod) {
371
- $responseCarriers = array();
372
-
373
- $quoteShippingAddress = $quote->getShippingAddress();
374
-
375
-
376
- $quoteShippingAddress->collectShippingRates()->save(); //collect the rates
377
- $groupedRates = $quoteShippingAddress->getGroupedAllShippingRates();
378
-
379
- foreach ($groupedRates as $carrierCode => $rates ) {
380
- foreach ($rates as $rate) {
381
- $price = $rate->getPrice();
382
- if ($rate->getCode() == $selectedShippingMethod) {
383
- $quoteShippingAddress->setShippingMethod($selectedShippingMethod);
384
- $quote->collectTotals()->save();
385
-
386
- $price = $quoteShippingAddress->getShippingInclTax();
387
- }
388
-
389
- $responseRate = array();
390
- $responseRate["carrier"] = $rate->getCarrier();
391
- $responseRate["carrierTitle"] = $rate->getCarrierTitle();
392
- $responseRate["carrierCode"] = $rate->getCode();
393
-
394
- $responseRate["method"] = $rate->getMethod();
395
- $responseRate["methodTitle"] = $rate->getMethodTitle();
396
- $responseRate["methodDescription"] = $rate->getMethodDescription();
397
- $responseRate["price"] = $price;
398
- $responseCarriers[] = $responseRate;
399
- }
400
- }
401
-
402
- return $responseCarriers;
403
- }
404
-
405
- private function loadProduct($productId = null) {
406
- if(!$productId)
407
- return null;
408
-
409
- $productModel = Mage::getModel('catalog/product');
410
- $product = $productModel->load($productId);
411
- if (!$product->getId())
412
- return null; //product does not exist
413
-
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) {
442
- $configurations = array();
443
- $conf = Mage::getModel('catalog/product_type_configurable')->setProduct($parent);
444
-
445
- //build the configuration_attributes array
446
- $configurableAttributes = $conf->getConfigurableAttributesAsArray($parent);
447
-
448
- foreach($configurableAttributes as $attribute) {
449
-
450
- $method = 'get' . uc_words($attribute['attribute_code'], '');
451
- $attribute_value = $product->$method();
452
- $attribute_id = $attribute['attribute_id'];
453
- $configurations[$attribute_id] = $attribute_value;
454
-
455
- }
456
-
457
- return $configurations;
458
- }
459
-
460
-
461
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Highstreet/Hsapi/Model/CheckoutV2.php CHANGED
@@ -4,13 +4,13 @@
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.
@@ -36,7 +36,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
36
 
37
 
38
  //add products
39
- $this->getProductsInQuote($quote,$products,false);
40
 
41
  $cart->save();
42
  $quote->save();
@@ -76,12 +76,12 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
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
 
@@ -94,12 +94,10 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
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
 
@@ -107,7 +105,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
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) {
@@ -173,7 +171,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
173
 
174
  $response['products'] = array();
175
  foreach ($quote->getAllVisibleItems() as $product) {
176
- array_push($response['products'], $this->getProductInQuoteResponse($product));
177
  }
178
 
179
  return $response;
@@ -239,7 +237,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
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"];
@@ -251,7 +249,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
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"];
@@ -277,7 +275,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
277
 
278
  //Helpers below
279
 
280
- private function getProductsInQuote($quote,$products = null,$capAmount = true) {
281
  $responseQuote = array();
282
 
283
 
@@ -296,7 +294,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
296
  $errorMessage = null;
297
 
298
  try {
299
- $product = $this->loadProduct($product_id);
300
  } catch (Exception $e) {
301
  $errorMessage = $e->getMessage();
302
  $product = null;
@@ -319,7 +317,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
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');
@@ -349,7 +347,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
349
  $isInStock = $itemInventory->getIsInStock();
350
  $isStockManaged = $itemInventory->getManageStock();
351
  $backordersAllowed = $itemInventory->getBackorders();
352
-
353
 
354
  if($isStockManaged) {
355
 
@@ -370,6 +368,10 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
370
 
371
  }
372
 
 
 
 
 
373
  } else {
374
  $actualQuantity = $requestedQuantity;
375
 
@@ -464,7 +466,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
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
 
@@ -473,7 +475,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
473
  }
474
  }
475
 
476
- private function _getErrorForProduct($product_hash) {
477
  $response = array();
478
  $response["errorCode"] = 0;
479
  $response["errorMessage"] = null;
@@ -489,9 +491,12 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
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);
@@ -521,12 +526,13 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
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;
@@ -595,14 +601,14 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
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';
@@ -655,7 +661,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
655
 
656
  }
657
 
658
- private function _getQuoteItemParentProductId($quoteItem) {
659
  $additionalInfo = $quoteItem->getAdditionalData();
660
  if($additionalInfo) {
661
  $json = json_decode($additionalInfo,true);
@@ -664,7 +670,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
664
  return null;
665
  }
666
 
667
- private function getQuoteTotals($quote) {
668
 
669
 
670
  $quote->save()->collectTotals(); //required to fetch the totals
@@ -695,13 +701,14 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
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
 
@@ -716,7 +723,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
716
  return $chosenShippingMethod;
717
  }
718
 
719
- private function getShippingMethods($quote, $selectedShippingMethod) {
720
  $responseCarriers = array();
721
 
722
  $quoteShippingAddress = $quote->getShippingAddress();
@@ -751,7 +758,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
751
  return $responseCarriers;
752
  }
753
 
754
- private function loadProduct($productId = null) {
755
  if(!$productId)
756
  return null;
757
 
@@ -764,7 +771,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
764
 
765
  }
766
 
767
- private function _getParentProduct($product) {
768
  $config = Mage::helper('highstreet_hsapi/config_api');
769
  if ($config->alwaysAddSimpleProductsToCart()) {
770
  return null;
@@ -785,7 +792,7 @@ class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
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
  }
4
  *
5
  * @package Highstreet_Api
6
  * @author Tim Wachter (tim@touchwonders.com)
7
+ * @copyright Copyright (c) 2015 Touchwonders (http://www.touchwonders.com/)
8
  */
9
  class Highstreet_Hsapi_Model_CheckoutV2 extends Mage_Core_Model_Abstract
10
  {
11
+ protected $_errorCodes = array();
12
+ protected $_errorMessages = array();
13
+ protected $_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.
36
 
37
 
38
  //add products
39
+ $this->_addProductsToQuote($quote,$products,false);
40
 
41
  $cart->save();
42
  $quote->save();
76
  }
77
 
78
  if($products) {
79
+ $this->_addProductsToQuote($quote,$products);
80
  }
81
+
82
 
83
  //Shipping carries
84
+ $response['selected_shipping_method'] = $this->_getSelectedShippingMethod($quote);
85
 
86
 
87
 
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
+ $response["totals"] = $this->_getQuoteTotals($quote);
 
 
101
 
102
  $quoteItems = $quote->getAllVisibleItems();
103
 
105
 
106
  foreach($quoteItems as $quoteItem) {
107
  $product_hash = $this->_getQuoteItemHash($quoteItem);
108
+ $responseQuote[] = array_merge($this->_getProductInQuoteResponse($quoteItem),$this->_getErrorForProduct($product_hash));
109
  }
110
 
111
  foreach($this->_productIdsNotAdded as $product_hash) {
171
 
172
  $response['products'] = array();
173
  foreach ($quote->getAllVisibleItems() as $product) {
174
+ array_push($response['products'], $this->_getProductInQuoteResponse($product));
175
  }
176
 
177
  return $response;
237
  $billingAddressResponse["email"] = $billingAddressData["email"];
238
  $billingAddressResponse["firstname"] = $billingAddressData["firstname"];
239
  $billingAddressResponse["lastname"] = $billingAddressData["lastname"];
240
+ $billingAddressResponse["telephone"] = (string) $billingAddressData["telephone"] . " ";
241
  $billingAddressResponse["street"] = $billingAddress->getStreet();
242
  $billingAddressResponse["postcode"] = $billingAddressData["postcode"];
243
  $billingAddressResponse["city"] = $billingAddressData["city"];
249
  if ($shippingAddressData["firstname"] !== null) {
250
  $shippingAddressResponse["firstname"] = $shippingAddressData["firstname"];
251
  $shippingAddressResponse["lastname"] = $shippingAddressData["lastname"];
252
+ $shippingAddressResponse["telephone"] = (string) $shippingAddressData["telephone"] . " ";
253
  $shippingAddressResponse["street"] = $shippingAddress->getStreet();
254
  $shippingAddressResponse["postcode"] = $shippingAddressData["postcode"];
255
  $shippingAddressResponse["city"] = $shippingAddressData["city"];
275
 
276
  //Helpers below
277
 
278
+ protected function _addProductsToQuote($quote,$products = null,$capAmount = true) {
279
  $responseQuote = array();
280
 
281
 
294
  $errorMessage = null;
295
 
296
  try {
297
+ $product = $this->_loadProduct($product_id);
298
  } catch (Exception $e) {
299
  $errorMessage = $e->getMessage();
300
  $product = null;
317
  if($product->getTypeId() == 'simple') {
318
  $simple_product = $product;
319
  } else if($product->getTypeId() == 'configurable') {
320
+ $simple_product = $this->_loadProduct($value['simple_product_id']);
321
 
322
  //if 'alwaysAddSimpleProductsToCart' is set, then we add the simple product of a configurable product to the cart
323
  $config = Mage::helper('highstreet_hsapi/config_api');
347
  $isInStock = $itemInventory->getIsInStock();
348
  $isStockManaged = $itemInventory->getManageStock();
349
  $backordersAllowed = $itemInventory->getBackorders();
350
+ $maxSaleQty = $itemInventory->getMaxSaleQty();
351
 
352
  if($isStockManaged) {
353
 
368
 
369
  }
370
 
371
+ if ($maxSaleQty < $requestedQuantity) {
372
+ $actualQuantity = $maxSaleQty;
373
+ }
374
+
375
  } else {
376
  $actualQuantity = $requestedQuantity;
377
 
466
 
467
  }
468
 
469
+ protected function _reportErrorForProduct($product_hash,$errorCode,$errorMessage,$notAdded = true) {
470
  $this->_errorCodes[$product_hash] = $errorCode;
471
  $this->_errorMessages[$product_hash] = $errorMessage;
472
 
475
  }
476
  }
477
 
478
+ protected function _getErrorForProduct($product_hash) {
479
  $response = array();
480
  $response["errorCode"] = 0;
481
  $response["errorMessage"] = null;
491
  return $response;
492
  }
493
 
494
+ protected function _getProductIdsNotAdded() {
495
+ return $this->_productIdsNotAdded;
496
+ }
497
 
498
 
499
+ protected function _getProductInQuoteResponse($quoteItem = null) {
500
 
501
  $product = $quoteItem->getProduct();
502
  $parent_product_id = $this->_getQuoteItemParentProductId($quoteItem);
526
 
527
 
528
  $productInQuote["hash"] = $this->_getQuoteItemHash($quoteItem);
529
+ $productInQuote["userInfo"] = array();
530
 
531
 
532
  return $productInQuote;
533
  }
534
 
535
+ protected function _getQuoteItemHash($quoteItem) {
536
  $product = $quoteItem->getProduct();
537
 
538
  $hash = null;
601
 
602
  }
603
 
604
+ protected function _compareBundleSelection($a, $b) {
605
  if ($a["option_id"] == $b["option_id"]) {
606
  return 0;
607
  }
608
  return ($a["option_id"] < $b["option_id"]) ? -1 : 1;
609
  }
610
 
611
+ protected function _getQuoteItemRequestHash($quoteItemRequest) {
612
 
613
  $hash = null;
614
  $type = 'simple';
661
 
662
  }
663
 
664
+ protected function _getQuoteItemParentProductId($quoteItem) {
665
  $additionalInfo = $quoteItem->getAdditionalData();
666
  if($additionalInfo) {
667
  $json = json_decode($additionalInfo,true);
670
  return null;
671
  }
672
 
673
+ protected function _getQuoteTotals($quote) {
674
 
675
 
676
  $quote->save()->collectTotals(); //required to fetch the totals
701
  $responseTotals["grandtotal"] = $grandtotal;
702
  $responseTotals["discount"] = $discount;
703
  $responseTotals["tax"] = $tax;
704
+ $responseTotals["userInfo"] = array();
705
 
706
  return $responseTotals;
707
  }
708
 
709
 
710
 
711
+ protected function _getSelectedShippingMethod($quote) {
712
  $quoteShippingAddress = $quote->getShippingAddress();
713
  $quoteShippingAddress->collectTotals(); //to make sure all available shipping methods are listed
714
 
723
  return $chosenShippingMethod;
724
  }
725
 
726
+ protected function _getShippingMethods($quote, $selectedShippingMethod) {
727
  $responseCarriers = array();
728
 
729
  $quoteShippingAddress = $quote->getShippingAddress();
758
  return $responseCarriers;
759
  }
760
 
761
+ protected function _loadProduct($productId = null) {
762
  if(!$productId)
763
  return null;
764
 
771
 
772
  }
773
 
774
+ protected function _getParentProduct($product) {
775
  $config = Mage::helper('highstreet_hsapi/config_api');
776
  if ($config->alwaysAddSimpleProductsToCart()) {
777
  return null;
792
  /**
793
  * Convenience method, compares 2 formatted address arrays
794
  */
795
+ protected function _billingAndShippingAddressesAreTheSame($billingAddressArray = array(), $shippingAddressArray = array()) {
796
  if (count($billingAddressArray) == 0 || count($shippingAddressArray) == 0) {
797
  return true;
798
  }
app/code/local/Highstreet/Hsapi/Model/Images.php DELETED
@@ -1,53 +0,0 @@
1
- <?php
2
- /**
3
- * Highstreet_HSAPI_module
4
- *
5
- * @package Highstreet_Hsapi
6
- * @author Tim Wachter (tim@touchwonders.com)
7
- * @copyright Copyright (c) 2014 Touchwonders (http://www.touchwonders.com/)
8
- */
9
- class Highstreet_Hsapi_Model_Images extends Mage_Core_Model_Abstract
10
- {
11
-
12
- public function getImage($src, $size) {
13
- if (!$src) {
14
- return null;
15
- } else {
16
- $image = Mage::helper('timage')->init($src);
17
-
18
- if ($src[0] !== "/") {
19
- $src = "/" . $src;
20
- }
21
-
22
- $imageUrl = Mage::getBaseDir() . $src;
23
- if(!file_exists($imageUrl) ) {
24
- return null;
25
- }
26
-
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);
38
- } else {
39
- if ($originalSize['width'] >= $originalSize['height']) {
40
- $image->resize($size, NULL);
41
- } else {
42
- $image->resize(NULL, $size);
43
- }
44
- }
45
-
46
- $imageUrl = $image->cachedImage;
47
- }
48
- }
49
-
50
- return $imageUrl;
51
- }
52
-
53
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Highstreet/Hsapi/Model/Observer.php CHANGED
@@ -1,65 +1,95 @@
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
  }
1
  <?php
2
 
3
  class Highstreet_Hsapi_Model_Observer {
 
 
 
 
4
 
5
+ private $_orderCommentTest = "Order made via the Highstreet app. Data identifier: ";
6
+
7
+ /**
8
+ * Listener for the sales_quote_merge_before event
9
+ * Makes sure nothing strange happens when one of out customers logs in
10
+ */
11
+ public function mergeQuote($observer) {
12
  $event = $observer->getEvent();
13
  $quote = $event->getQuote();
14
 
15
  foreach ($quote->getAllItems() as $item) {
16
  $quote->removeItem($item->getId());
17
  }
 
18
  }
19
 
20
+ /**
21
+ * Listens for the sales_order_invoice_pay event
22
+ * Communicates the invoice to the Highstreet Middleware if needed
23
+ */
24
  public function salesOrderInvoicePay(Varien_Event_Observer $observer) {
25
+ $order = $observer->getEvent()->getInvoice()->getOrder();
 
26
  $this->_communicateOrderEvent($order, '');
27
  }
28
 
29
+ /**
30
+ * Listens for the sales_order_invoice_cancel event
31
+ * Communicates the invoice to the Highstreet Middleware with status PAYMENT_CANCELED if needed
32
+ */
33
  public function salesOrderInvoiceCancel(Varien_Event_Observer $observer) {
34
+ $order = $observer->getEvent()->getInvoice()->getOrder();
35
+ $this->_communicateOrderEvent($order, 'PAYMENT_CANCELED');
 
36
  }
37
 
38
+ /**
39
+ * Listens for the sales_order_place_after event
40
+ * This event gets triggered before a user enters the off-site payment
41
+ * In this event we, if needed, add a comment to the order so we can later identify the order as ours
42
+ */
43
+ public function salesOrderPlaceAfter($data) {
44
+ if (Mage::getSingleton('checkout/session')->getHsTid() !== null) {
45
+ try {
46
+ $order = $data['order'];
47
+
48
+ $order->addStatusHistoryComment($this->_orderCommentTest . Mage::getSingleton('checkout/session')->getHsTid())
49
+ ->setIsVisibleOnFront(false)
50
+ ->setIsCustomerNotified(false);
51
+ $order->save();
52
+ } catch (Exception $e) {}
53
+ }
54
+ }
55
 
56
+ /**
57
+ * Private function used to communicate orders to the Highstreet middleware
58
+ */
59
  private function _communicateOrderEvent($order, $status = '') {
60
+ if ($order->getQuoteId() > 0) {
 
 
61
 
62
+ // Check if this order identifies as a HS order trough the earlier added comment
63
+ $relevantComment = null;
64
+ foreach ($order->getStatusHistoryCollection(true) as $comment) {
65
+ if (strstr($comment->getData('comment'), $this->_orderCommentTest) !== false) {
66
+ $relevantComment = $comment->getData('comment');
67
+ break;
68
+ }
69
+ }
70
 
71
+ $configHelper = Mage::helper('highstreet_hsapi/config_api');
72
+ $middleWareUrl = $configHelper->middlewareUrl();
73
 
74
+ if ($relevantComment !== null && $middleWareUrl !== null) {
75
+ $tid = str_replace($this->_orderCommentTest, "", $relevantComment); // Extract tracking ID
76
+
77
+ $checkoutModel = Mage::getModel('highstreet_hsapi/checkoutV2');
78
+ $data = $checkoutModel->getOrderInformationFromOrderObject($order, $order->getQuoteId(), $status); // Get relevant information from the order
79
 
80
+ // Communicate it with the middleware
81
+ $ch = curl_init($middleWareUrl . "/orders/" . $tid);
82
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
83
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
84
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); // Time CURL takes to wait for a connection to our server, 0 is indefinitely
85
+ curl_setopt($ch, CURLOPT_TIMEOUT, 15); // Maximum time CURL takes to execute
86
+ if (version_compare(PHP_VERSION, '5.3.3', '<')) {
87
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
88
+ } else {
89
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_NUMERIC_CHECK));
90
  }
91
+ $output = curl_exec($ch);
92
+ }
93
  }
94
+ }
95
  }
app/code/local/Highstreet/Hsapi/Model/Products.php CHANGED
@@ -4,15 +4,22 @@
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
  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;
14
  const SPECIAL_PRICE_FROM_DATE_FALLBACK = "1970-01-01 00:00:00";
15
 
 
 
 
 
 
 
16
  /**
17
  * Gets a single product for a given productId and attributes
18
  *
@@ -88,14 +95,6 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
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);
@@ -164,7 +163,7 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
164
 
165
  // apply search
166
  if ($categoryId && !$categoryNotSet) {
167
- $collection->addCategoryFilter($category);
168
  }
169
 
170
  if (!empty($range)) {
@@ -176,9 +175,21 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
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,28 +203,6 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
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)) {
201
- foreach ($order as $orderCondition) {
202
- $orderBy = explode(':', $orderCondition);
203
- $collection->setOrder($orderBy[0], $orderBy[1]);
204
- }
205
- } else {
206
- if($searching) {
207
- $collection->setOrder('relevance', 'desc');
208
- } else {
209
-
210
- $sortKey = $category->getDefaultSortBy();
211
- if (!$sortKey) {
212
- $sortKey = Mage::getStoreConfig('catalog/frontend/default_sort_by');
213
- }
214
- $collection->setOrder($sortKey, 'asc');
215
- }
216
- }
217
 
218
  // Add 'out of stock' filter, if preffered
219
  if (!Mage::getStoreConfig('cataloginventory/options/show_out_of_stock')) {
@@ -238,11 +227,16 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
238
  $collection->addAttributeToFilter('entity_id', array('nin' => $outOfStockConfis));
239
  }
240
  }
241
-
242
- if (!isset($productCount)) {
243
- // get total product count
244
- $productCount = $collection->getSize();
 
 
 
 
245
  }
 
246
  /**
247
  * Format result array
248
  */
@@ -255,7 +249,10 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
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
 
@@ -263,8 +260,8 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
263
  if (!$hideFilters) {
264
  $products['filters'] = $this->getFilters($categoryId);
265
  }
266
-
267
- $products['product_count'] = $productCount;
268
 
269
  $rangeLength = $range[1];
270
  if ($rangeLength > count($products["products"])) {
@@ -304,6 +301,7 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
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);
@@ -355,7 +353,7 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
355
  $products['products'] = $collection->getAllIds();
356
  }
357
 
358
- $products['product_count'] = $collection->getSize();
359
 
360
  $rangeLength = $range[1];
361
  if ($rangeLength > count($products["products"])) {
@@ -516,23 +514,14 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
516
  return $productModel->getUpSellProductIds();
517
  }
518
 
519
-
520
-
521
- /***********************************/
522
- /**
523
- * PRIVATE/protected FUNCTIONS
524
- */
525
- /***********************************/
526
  /**
527
  * Returns filters
528
  *
529
  * @param int $categoryId
530
  * @return array
531
- * @author Andrey Posudevsky
532
  *
533
  */
534
- protected function getFilters($categoryId = false) {
535
-
536
  if (!$categoryId) {
537
  $categoryId = Mage::app()->getStore()->getRootCategoryId();
538
  }
@@ -541,7 +530,7 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
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) {
@@ -561,10 +550,10 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
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
@@ -576,6 +565,90 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
576
  return $resultFilters;
577
  }
578
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
579
  /**
580
  *
581
  * Gets attributes of a given product object.
@@ -588,7 +661,7 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
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
  }
@@ -643,112 +716,7 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
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();
@@ -776,6 +744,11 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
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
@@ -794,12 +767,11 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
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;
@@ -822,6 +794,11 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
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) {
@@ -860,6 +837,150 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
860
  return $product;
861
  }
862
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
863
 
864
  /**
865
  * Converts product dates to timestamp
@@ -896,7 +1017,7 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
896
  * @return array Array of stock data
897
  */
898
 
899
- private function _getStockInformationForProduct($product) {
900
  $stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product);
901
  $stockinfo = array();
902
 
@@ -940,9 +1061,12 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
940
  return $product;
941
  }
942
 
943
- /**
944
  * Gets media gallery items for a given product id. Returns an array or media gallery items
945
  *
 
 
 
946
  * @param integer Product ID, ID of a product to get media gallery images for
947
  * @return array Array of media gallery items
948
  */
@@ -956,6 +1080,11 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
956
 
957
  foreach (Mage::getModel('catalog/product')->load($productId)->getMediaGalleryImages()->getItems() as $key => $value) {
958
  $imageData = $value->getData();
 
 
 
 
 
959
  if (array_key_exists('file', $imageData) && !strstr($imageData['file'], self::PRODUCTS_MEDIA_PATH)) {
960
  $imageData['file'] = self::PRODUCTS_MEDIA_PATH . $imageData['file'];
961
  }
@@ -968,6 +1097,26 @@ class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
968
  return $output;
969
  }
970
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
971
  /**
972
  * Returns an array of all core attributes
973
  *
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
  class Highstreet_Hsapi_Model_Products extends Mage_Core_Model_Abstract
10
  {
11
+ const MEDIA_PATH = '/media/';
12
  const PRODUCTS_MEDIA_PATH = '/media/catalog/product';
13
  const NO_IMAGE_PATH = 'no_selection';
14
  const RANGE_FALLBACK_RANGE = 100;
15
  const SPECIAL_PRICE_FROM_DATE_FALLBACK = "1970-01-01 00:00:00";
16
 
17
+ protected $_attributesModel = null;
18
+
19
+ public function __construct() {
20
+ $this->_attributesModel = Mage::getModel('highstreet_hsapi/attributes');
21
+ }
22
+
23
  /**
24
  * Gets a single product for a given productId and attributes
25
  *
95
  {
96
  $searching = !empty($search);
97
 
 
 
 
 
 
 
 
 
98
  // get order
99
  if (!empty($order)) {
100
  $order = explode(',', $order);
163
 
164
  // apply search
165
  if ($categoryId && !$categoryNotSet) {
166
+ $collection = $this->_addCategoryFilterToProductCollection($collection, $category);
167
  }
168
 
169
  if (!empty($range)) {
175
  }
176
 
177
  $collection->getSelect()->limit($range[1], $range[0]);
178
+
179
+ $attributesArray = array();
180
+ // get attributes
181
+ if (!empty($additional_attributes)) {
182
+ $attributesArray = $this->_translateAdditionalAttributes(explode(',', $additional_attributes));
183
+ }
184
+
185
+ $attributesArray = array_merge($attributesArray, $this->_getCoreAttributes());
186
+
187
+ // apply attributes
188
+ if (!$hideAttributes) {
189
+ $collection->addAttributeToSelect($attributesArray);
190
+ } else {
191
+ $collection->addAttributeToSelect('entity_id');
192
+ }
193
 
194
  //apply filters
195
  if(!empty($filters)) {
203
  }
204
  }
205
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
 
207
  // Add 'out of stock' filter, if preffered
208
  if (!Mage::getStoreConfig('cataloginventory/options/show_out_of_stock')) {
227
  $collection->addAttributeToFilter('entity_id', array('nin' => $outOfStockConfis));
228
  }
229
  }
230
+
231
+ // Apply type filter, we only want Simple and Configurable and Bundle products in our API
232
+ $collection->addAttributeToFilter('type_id', array('simple', 'configurable', 'bundle'));
233
+ // apply sort order
234
+ if($searching) {
235
+ $collection->setOrder('relevance', 'desc');
236
+ } else {
237
+ $collection = $this->_addSortingToProductCollection($collection, $order, $category);
238
  }
239
+
240
  /**
241
  * Format result array
242
  */
249
  array_push($products['products'], $this->_getProductAttributes($product, $additional_attributes, $include_configuration_details, $include_media_gallery));
250
  }
251
  } else {
252
+ // getAllIds resets product order
253
+ foreach($collection as $product) {
254
+ array_push($products['products'], $product->getEntityId());
255
+ }
256
  }
257
  }
258
 
260
  if (!$hideFilters) {
261
  $products['filters'] = $this->getFilters($categoryId);
262
  }
263
+
264
+ $products['product_count'] = $this->_getCountForProductCollection($collection, $categoryId, $categoryNotSet);
265
 
266
  $rangeLength = $range[1];
267
  if ($rangeLength > count($products["products"])) {
301
 
302
  $collection = Mage::getModel('catalog/product')->getCollection()->addAttributeToFilter('entity_id', array('in' => $productIds));
303
 
304
+ $attributesArray = array();
305
  // get attributes
306
  if (!empty($additional_attributes)) {
307
  $attributesArray = explode(',', $additional_attributes);
353
  $products['products'] = $collection->getAllIds();
354
  }
355
 
356
+ $products['product_count'] = $this->_getCountForProductCollection($collection);
357
 
358
  $rangeLength = $range[1];
359
  if ($rangeLength > count($products["products"])) {
514
  return $productModel->getUpSellProductIds();
515
  }
516
 
 
 
 
 
 
 
 
517
  /**
518
  * Returns filters
519
  *
520
  * @param int $categoryId
521
  * @return array
 
522
  *
523
  */
524
+ public function getFilters($categoryId = false) {
 
525
  if (!$categoryId) {
526
  $categoryId = Mage::app()->getStore()->getRootCategoryId();
527
  }
530
 
531
  $category = Mage::getModel('catalog/category')->load($categoryId);
532
  $layer->setCurrentCategory($category);
533
+ $controller = Mage::app()->getLayout();
534
  $attributes = $layer->getFilterableAttributes('price');
535
  $resultFilters = array();
536
  foreach ($attributes as $attribute) {
550
  array_push($options, array('value' => $option->getValue(), 'title' => $title, 'product_count' => $count));
551
  }
552
 
553
+ if (count($options) > 1) {
554
  array_push($resultFilters,
555
  array(
556
+ 'title' => $attribute->getData('store_label'),
557
  'type' => $attribute->getFrontendInput(),
558
  'code' => $attribute->getAttributeCode(),
559
  'options' => $options
565
  return $resultFilters;
566
  }
567
 
568
+ /***********************************/
569
+ /**
570
+ * PRIVATE/protected FUNCTIONS
571
+ */
572
+ /***********************************/
573
+
574
+ /**
575
+ * Gets count for given collection. Function made for easier subclassing
576
+ *
577
+ * @param mixed Collection
578
+ * @param int Category ID, can be needed
579
+ * @param bool Category not set, used to signify if the category was set or not
580
+ * @return int Product count
581
+ *
582
+ */
583
+
584
+ protected function _getCountForProductCollection ($collection = null, $categoryId = -1, $categoryNotSet = false) {
585
+ if ($collection === null) {
586
+ return -1;
587
+ }
588
+
589
+ return $collection->getSize();
590
+ }
591
+
592
+ /**
593
+ * Adds the category filter to a product collection. Function made for subclassing
594
+ *
595
+ * @param mixed Collection
596
+ * @param mixed Category object
597
+ * @return mixed Collection
598
+ */
599
+
600
+ protected function _addCategoryFilterToProductCollection ($collection = null, $categoryObject = null) {
601
+ if ($collection === null || $categoryObject === null) {
602
+ return $collection;
603
+ }
604
+
605
+ $collection->addCategoryFilter($categoryObject);
606
+
607
+ return $collection;
608
+ }
609
+
610
+ /**
611
+ * Adds the sort order to a product collection. Function made for subclassing
612
+ *
613
+ * @param mixed Collection
614
+ * @param mixed sortOrder
615
+ * @return mixed Collection
616
+ */
617
+
618
+ protected function _addSortingToProductCollection ($collection = null, $sortOrder = array(), $categoryObject = null) {
619
+ if ($collection === null) {
620
+ return $collection;
621
+ }
622
+
623
+ if (!empty($sortOrder)) {
624
+ foreach ($sortOrder as $orderCondition) {
625
+ $orderBy = explode(':', $orderCondition);
626
+ $collection->setOrder($orderBy[0], $orderBy[1]);
627
+ }
628
+ } else {
629
+ $sortKey = $categoryObject->getDefaultSortBy();
630
+ if (!$sortKey) {
631
+ $sortKey = Mage::getStoreConfig('catalog/frontend/default_sort_by');
632
+ }
633
+
634
+ $sortOrder = 'asc';
635
+ if ($sortKey == 'created_at' || $sortKey == 'updated_at') {
636
+ $sortOrder = 'desc';
637
+ }
638
+
639
+
640
+ $configApi = Mage::helper('highstreet_hsapi/config_api');
641
+ $sortOrderConfig = $configApi->attributesSortOrder();
642
+ if (array_key_exists($sortKey, $sortOrderConfig)) {
643
+ $sortOrder = $sortOrderConfig[$sortKey];
644
+ }
645
+
646
+ $collection->setOrder($sortKey, $sortOrder);
647
+ }
648
+
649
+ return $collection;
650
+ }
651
+
652
  /**
653
  *
654
  * Gets attributes of a given product object.
661
  *
662
  */
663
 
664
+ private function _getProductAttributes($resProduct = false, $additional_attributes = null, $include_configuration_details = false, $include_media_gallery = false) {
665
  if (!$resProduct) {
666
  return null;
667
  }
716
  $product['attribute_values'] = array(); // Make sure to always return an object for this key
717
  // if additional attributes specified
718
  if (!empty($additionalAttributesArray) && count($additionalAttributesArray) > 0) {
719
+ $product['attribute_values'] = $this->_getAdditionalAttributesForProduct($resProduct, $additionalAttributesArray);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
720
  }
721
 
722
  $product['id'] = $resProduct->getId();
744
  }
745
 
746
  if($resProduct->getTypeId() == 'configurable' && $include_configuration_details){
747
+ // Remove `hs_specifications` attribute from additionalAttributes for child products, this is currently not needed and can make the API call much slower
748
+ if (($index = array_search('hs_specifications', $additionalAttributesArray)) !== FALSE) {
749
+ unset($additionalAttributesArray[$index]);
750
+ }
751
+
752
  $conf = Mage::getModel('catalog/product_type_configurable')->setProduct($resProduct);
753
 
754
  //build the configuration_attributes array
767
  ->addAttributeToSelect('*')
768
  ->addFilterByRequiredOptions();
769
 
770
+ foreach($simple_collection as $resProduct){
771
  if(!Mage::getStoreConfig('cataloginventory/options/show_out_of_stock')
772
+ && !$resProduct->isSaleable())
773
  continue;
774
 
 
775
  if ($resProduct->getData('status') == Mage_Catalog_Model_Product_Status::STATUS_DISABLED || $resProduct->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_DISABLED ||
776
  $resProduct->getData('status') == "Uitgeschakeld" || $resProduct->getStatus() == "Uitgeschakeld") {
777
  continue;
794
  }
795
 
796
  if($resProduct->getTypeId() == 'bundle' && $include_configuration_details) {
797
+ // Remove `hs_specifications` attribute from additionalAttributes for child products, this is currently not needed and can make the API call much slower
798
+ if (($index = array_search('hs_specifications', $additionalAttributesArray)) !== FALSE) {
799
+ unset($additionalAttributesArray[$index]);
800
+ }
801
+
802
  $bundleProduct = Mage::getModel('bundle/product_type')->setProduct($resProduct);
803
  $bundles = $bundleProduct->getOptionsCollection()->getData();
804
  foreach($bundles as $bundle) {
837
  return $product;
838
  }
839
 
840
+ protected function _getAdditionalAttributesForProduct($resProduct = null, $additionalAttributesArray) {
841
+ if ($resProduct === null) {
842
+ return array();
843
+ }
844
+
845
+ $response = array();
846
+
847
+ foreach ($additionalAttributesArray as $attribute) {
848
+ if ($attribute == "media_gallery") {
849
+ continue;
850
+ }
851
+
852
+ if ($attribute === "share_url") {
853
+ $additionalAttributeData = array();
854
+ $additionalAttributeData['title'] = "Share url";
855
+ $additionalAttributeData['code'] = "share_url";
856
+ $additionalAttributeData['type'] = "url";
857
+ $additionalAttributeData['inline_value'] = $resProduct->getProductUrl();
858
+ $response[] = $additionalAttributeData;
859
+
860
+ continue;
861
+ }
862
+
863
+ if ($attribute === "hs_specifications") {
864
+ $additionalAttributeData = array();
865
+ $additionalAttributeData['title'] = "Highstreet Specifications";
866
+ $additionalAttributeData['code'] = "hs_specifications";
867
+ $additionalAttributeData['type'] = "html";
868
+ $html = "";
869
+
870
+ // Register product in the Mage registry, needed for the following block
871
+ Mage::register('product', $resProduct);
872
+
873
+ // SEE: Mage_Catalog_Block_Product_View_Attributes
874
+ $controller = Mage::app()->getLayout();
875
+ $block = $controller->createBlock('Mage_Catalog_Block_Product_View_Attributes');
876
+
877
+ // Same function as used by the layouting
878
+ foreach ($block->getAdditionalData() as $attribute) {
879
+ $html .= "<p><strong>".$attribute['label'].":</strong></br>".$attribute['value']."</p>";
880
+ }
881
+
882
+ $additionalAttributeData['inline_value'] = $html;
883
+ $response[] = $additionalAttributeData;
884
+
885
+ // Take responsibility to unregister the product
886
+ Mage::unregister('product');
887
+
888
+ continue;
889
+ }
890
+
891
+ $attributeObject = $resProduct->getResource()->getAttribute($attribute);
892
+
893
+ if ($attributeObject !== false) {
894
+ $readableAttributeValue = $attributeObject->getFrontend()->getValue($resProduct); // 'frontend' value, human readable value
895
+
896
+ $attributesData = $this->_attributesModel->getAttribute($attribute);
897
+
898
+ if (!array_key_exists('title', $attributesData) ||
899
+ !array_key_exists('code', $attributesData) ||
900
+ $attributesData['title'] == null ||
901
+ $attributesData['code'] == null ||
902
+ $attributeObject->getFrontendInput() == null) {
903
+ continue;
904
+ }
905
+
906
+ // Pre-make attribute object to be put into json
907
+ $additionalAttributeData = array();
908
+ $additionalAttributeData['title'] = $attributesData['title'];
909
+ $additionalAttributeData['code'] = $attributesData['code'];
910
+ $additionalAttributeData['type'] = $attributeObject->getFrontendInput();
911
+
912
+ // Switch statement from /app/code/core/Mage/Catalog/Model/Product/Attribute/Api.php:301
913
+ // Gets all attribute types and fill in the value field of the attribute object
914
+ switch ($attributesData['type']) {
915
+ case 'text':
916
+ case 'textarea':
917
+ case 'price':
918
+ $additionalAttributeData['inline_value'] = $readableAttributeValue;
919
+ break;
920
+ case 'date':
921
+ if ($readableAttributeValue == null) {
922
+ $additionalAttributeData['inline_value'] = null;
923
+ } else {
924
+ $additionalAttributeData['inline_value'] = strtotime($readableAttributeValue);
925
+ }
926
+
927
+ $additionalAttributeData['raw_value'] = $readableAttributeValue;
928
+ break;
929
+ case 'boolean':
930
+ $attributeMethod = "get" . uc_words($attribute);
931
+ $idAttributeValue = $resProduct->$attributeMethod();
932
+ $additionalAttributeData['raw_value'] = $readableAttributeValue;
933
+ $additionalAttributeData['inline_value'] = ($idAttributeValue == 1 ? true : false);
934
+ break;
935
+ case 'select':
936
+ case 'multiselect':
937
+ $hasFoundValue = false;
938
+ $additionalAttributeData['value'] = array();
939
+
940
+ $mutliSelectValues = $resProduct->getAttributeText($attribute); // Get values for multiselect type (array)
941
+
942
+ // Loop trough select options of attribute
943
+ foreach ($attributesData['options'] as $key => $value) {
944
+ if (($value->title === $readableAttributeValue && $attributesData['type'] === 'select') || // If attribute type is single select option, check title
945
+ ((is_array($mutliSelectValues) && in_array($value->title, $mutliSelectValues) || ($value->title === $mutliSelectValues)) &&
946
+ $attributesData['type'] === 'multiselect') // If attribute type is multi select option, check if value is in array of possible options or equal to the title
947
+ ) {
948
+ $attributeValueObject = array();
949
+ $attributeValueObject['id'] = $value->value;
950
+ $attributeValueObject['title'] = $value->title;
951
+ $attributeValueObject['sort_hint'] = $value->sort_hint;
952
+ $additionalAttributeData['value'][] = $attributeValueObject;
953
+ $hasFoundValue = true;
954
+
955
+ if ($attributesData['type'] === 'select') {
956
+ break; // single select option doesn't have to loop trough all possibilities
957
+ }
958
+ }
959
+ }
960
+
961
+ // If type is select and there is only one element, return the element as an object and not an array with 1 object
962
+ if ($attributesData['type'] == 'select' && count($additionalAttributeData['value']) == 1) {
963
+ $additionalAttributeData['value'] = $additionalAttributeData['value'][0];
964
+ }
965
+
966
+ // No value was found, make value field in attribute object null
967
+ if (!$hasFoundValue) {
968
+ $additionalAttributeData['value'] = null;
969
+ }
970
+ break;
971
+ default:
972
+ if ($readableAttributeValue != null) {
973
+ $additionalAttributeData['inline_value'] = $readableAttributeValue;
974
+ }
975
+ break;
976
+ }
977
+
978
+ $response[] = $additionalAttributeData;
979
+ }
980
+ }
981
+
982
+ return $response;
983
+ }
984
 
985
  /**
986
  * Converts product dates to timestamp
1017
  * @return array Array of stock data
1018
  */
1019
 
1020
+ protected function _getStockInformationForProduct($product) {
1021
  $stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product);
1022
  $stockinfo = array();
1023
 
1061
  return $product;
1062
  }
1063
 
1064
+ /**
1065
  * Gets media gallery items for a given product id. Returns an array or media gallery items
1066
  *
1067
+ * This function explicitly makes new product objects.
1068
+ * During development this was found to be faster then passing a product object and calling "->load('media_gallery')" on the object
1069
+ *
1070
  * @param integer Product ID, ID of a product to get media gallery images for
1071
  * @return array Array of media gallery items
1072
  */
1080
 
1081
  foreach (Mage::getModel('catalog/product')->load($productId)->getMediaGalleryImages()->getItems() as $key => $value) {
1082
  $imageData = $value->getData();
1083
+
1084
+ if ($this->_shouldExcludeImageFromMediaGallery($imageData["file"], $resProduct)) {
1085
+ continue;
1086
+ }
1087
+
1088
  if (array_key_exists('file', $imageData) && !strstr($imageData['file'], self::PRODUCTS_MEDIA_PATH)) {
1089
  $imageData['file'] = self::PRODUCTS_MEDIA_PATH . $imageData['file'];
1090
  }
1097
  return $output;
1098
  }
1099
 
1100
+ /**
1101
+ * Function that compares the given image to other images in the product object in order to determine of this image should be included in the media gallery
1102
+ * Made for subclassing
1103
+ */
1104
+ protected function _shouldExcludeImageFromMediaGallery($image, $product) {
1105
+ return false;
1106
+ }
1107
+
1108
+ /**
1109
+ * For some vendors we have implemented custom attribute names, if such an attribute needs a specific other attribute to load, we can override this function and do this.
1110
+ * Implementation here is empty because we currently don't need it in the base class
1111
+ *
1112
+ * @param array $additionalAttributes, the array of additional attributes
1113
+ * @return array Array of additional attributes
1114
+ *
1115
+ */
1116
+ protected function _translateAdditionalAttributes($additionalAttributes) {
1117
+ return $additionalAttributes;
1118
+ }
1119
+
1120
  /**
1121
  * Returns an array of all core attributes
1122
  *
app/code/local/Highstreet/Hsapi/Model/SearchSuggestions.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * @package Highstreet_Hsapi
6
  * @author Tim Wachter (tim@touchwonders.com)
7
- * @copyright Copyright (c) 2014 Touchwonders (http://www.touchwonders.com/)
8
  */
9
  class Highstreet_Hsapi_Model_SearchSuggestions extends Mage_Core_Model_Abstract
10
  {
@@ -25,12 +25,18 @@ class Highstreet_Hsapi_Model_SearchSuggestions extends Mage_Core_Model_Abstract
25
 
26
  // Set limit
27
  $limit = 10;
 
28
  if (!empty($paramLimit)) {
29
  $limit = $paramLimit;
30
  }
31
 
 
 
 
 
32
  // Limit data to search term
33
  if (!empty($paramSearch)) {
 
34
  $searchCollection->addFieldToFilter('query_text', array("like" => $paramSearch . "%"));
35
  }
36
 
4
  *
5
  * @package Highstreet_Hsapi
6
  * @author Tim Wachter (tim@touchwonders.com)
7
+ * @copyright Copyright (c) 2015 Touchwonders (http://www.touchwonders.com/)
8
  */
9
  class Highstreet_Hsapi_Model_SearchSuggestions extends Mage_Core_Model_Abstract
10
  {
25
 
26
  // Set limit
27
  $limit = 10;
28
+ $maxLimit = 50;
29
  if (!empty($paramLimit)) {
30
  $limit = $paramLimit;
31
  }
32
 
33
+ if ($limit > $maxLimit) { // Limit the limit otherwise attackers could abuse this API
34
+ $limit = $maxLimit;
35
+ }
36
+
37
  // Limit data to search term
38
  if (!empty($paramSearch)) {
39
+ $paramSearch = str_replace('%', '', $paramSearch);
40
  $searchCollection->addFieldToFilter('query_text', array("like" => $paramSearch . "%"));
41
  }
42
 
app/code/local/Highstreet/Hsapi/controllers/CheckoutController.php CHANGED
@@ -4,7 +4,7 @@
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
@@ -83,34 +83,34 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
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
 
@@ -140,6 +140,11 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
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'])) {
@@ -168,6 +173,11 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
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'])) {
@@ -223,7 +233,7 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
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
 
@@ -235,7 +245,7 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
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
 
@@ -243,7 +253,7 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
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
 
@@ -253,28 +263,28 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
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
 
@@ -319,19 +329,6 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
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
  }
@@ -345,22 +342,6 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
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;
@@ -445,6 +426,9 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
445
  }
446
 
447
  $quote = Mage::getSingleton('checkout/cart')->getQuote();
 
 
 
448
  foreach ($quote->getShippingAddress()->getGroupedAllShippingRates() as $_rates) {
449
  foreach ($_rates as $_rate){
450
  $checked = false;
@@ -501,38 +485,48 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
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() {
@@ -550,8 +544,13 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
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
 
@@ -561,8 +560,13 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
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
 
@@ -587,7 +591,7 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
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
  }
@@ -617,13 +621,13 @@ class Highstreet_Hsapi_CheckoutController extends Mage_Core_Controller_Front_Act
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
  }
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_CheckoutController extends Mage_Core_Controller_Front_Action
83
 
84
  if ($session->isLoggedIn()) {
85
  $success = false;
86
+ $message = "hsapi.loginAction.success.already";
87
  } else {
88
  try {
89
  if ($session->login($email, $password)) {
90
  $success = true;
91
+ $message = "hsapi.loginAction.success";
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 = "hsapi.loginAction.error.activate";
98
  break;
99
  }
100
  case Mage_Customer_Model_Customer::EXCEPTION_INVALID_EMAIL_OR_PASSWORD: { // E-mail or password wrong
101
  $success = false;
102
+ $message = "hsapi.loginAction.error";
103
  break;
104
  }
105
  default: {
106
  $success = false;
107
+ $message = "hsapi.loginAction.error.fatal";
108
  break;
109
  }
110
  }
111
  } catch (Exception $e) {
112
  $success = false;
113
+ $message = "hsapi.loginAction.error.fatal";
114
  }
115
  }
116
 
140
  if (isset($data['email'])) {
141
  $data['email'] = trim($data['email']);
142
  }
143
+
144
+ if (isset($data['telephone'])) { // We return the telephone number from Magento with a trailing space, put it trough trim before saving
145
+ $data['telephone'] = trim($data['telephone']);
146
+ }
147
+
148
  $result = $this->getOnepage()->saveBilling($data, $customerAddressId);
149
 
150
  if (!isset($result['error'])) {
173
  {
174
  $data = $this->getRequest()->getPost('shipping', array());
175
  $customerAddressId = $this->getRequest()->getPost('shipping_address_id', false);
176
+
177
+ if (isset($data['telephone'])) { // We return the telephone number from Magento with a trailing space, put it trough trim before saving
178
+ $data['telephone'] = trim($data['telephone']);
179
+ }
180
+
181
  $result = $this->getOnepage()->saveShipping($data, $customerAddressId);
182
 
183
  if (!isset($result['error'])) {
233
  // Shopping cart is empty
234
  // The checkout should fire a restart
235
  if (!$quote->getItemsCount()) {
236
+ $this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_FATAL, "message" => 'hsapi.addCouponAction.error.fatal'));
237
  return;
238
  }
239
 
245
 
246
  // No coupon code given
247
  if (!strlen($couponCode) && !strlen($oldCouponCode)) {
248
+ $this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_ERROR, "message" => 'hsapi.addCouponAction.error.invalid'));
249
  return;
250
  }
251
 
253
  $codeLength = strlen($couponCode);
254
 
255
  if ($codeLength >= self::COUPON_CODE_MAX_LENGTH) {
256
+ $this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_ERROR, "message" => 'hsapi.addCouponAction.error.length'));
257
  return;
258
  }
259
 
263
 
264
  if ($codeLength) {
265
  if ($couponCode == $quote->getCouponCode()) { // Code was successfully added
266
+ $message = str_replace(self::COUPON_SUCCESS_REPLACE, $this->getRequest()->getParam('coupon_code'), 'hsapi.addCouponAction.success');
267
  $this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_SUCCESS, "message" => $message));
268
  return;
269
  } else { // Code was not valid
270
+ $this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_ERROR, "message" => 'hsapi.addCouponAction.error.invalid'));
271
  return;
272
  }
273
  } else {
274
+ $message = str_replace(self::COUPON_SUCCESS_REPLACE, $this->getRequest()->getParam('coupon_code'), 'hsapi.addCouponAction.success.removed');
275
  $this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_SUCCESS, "message" => $message));
276
  return;
277
  }
278
 
279
  } catch (Mage_Core_Exception $e) {
280
+ $this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_FATAL, "message" => 'hsapi.addCouponAction.error.fatal'));
281
  return;
282
  } catch (Exception $e) {
283
+ $this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_FATAL, "message" => 'hsapi.addCouponAction.error.fatal'));
284
  return;
285
  }
286
 
287
+ $this->_JSONencodeAndRespond(array("error" => self::COUPON_CODE_FATAL, "message" => 'hsapi.addCouponAction.error.fatal'));
288
  return;
289
  }
290
 
329
  public function saveOrderAction() {
330
  $result = array();
331
  try {
 
 
 
 
 
 
 
 
 
 
 
 
 
332
  if ($data = $this->getRequest()->getPost('payment', false)) {
333
  $this->getOnepage()->getQuote()->getPayment()->importData($data);
334
  }
342
  // We can read this value to get the order ID and insert a comment in the order.
343
  // This comment in the order is absolutely crucial for the order tracking of Highstreet.
344
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
  $redirectUrl = $this->getOnepage()->getCheckout()->getRedirectUrl();
346
  $result['success'] = true;
347
  $result['error'] = false;
426
  }
427
 
428
  $quote = Mage::getSingleton('checkout/cart')->getQuote();
429
+
430
+ $quote->getShippingAddress()->collectShippingRates();
431
+
432
  foreach ($quote->getShippingAddress()->getGroupedAllShippingRates() as $_rates) {
433
  foreach ($_rates as $_rate){
434
  $checked = false;
485
  if (!empty($selectedPaymentMethod) && $selectedPaymentMethod == $code) {
486
  $checked = true;
487
  }
488
+
489
+ $object["title"] = str_replace("<br>", " ", $methodTitle);
490
  $object["code"] = $code;
491
  $object["checked"] = $checked;
492
 
493
+ $object["sub_options"] = $this->_getSuboptionsForPaymentMethod($method);
494
+
495
+ $paymentMethods[] = $object;
496
+ }
497
+
498
+ return $paymentMethods;
499
+ }
 
 
 
 
 
 
 
500
 
501
+ protected function _getSuboptionsForPaymentMethod($method) {
502
+ if ($method->getCode() === "buckaroo3extended_ideal") {
503
+ $options = array();
504
+
505
+ $session = Mage::getSingleton('checkout/session');
506
+ $sessionValue = $session->getData('buckaroo3extended_ideal_BPE_Issuer');
507
+ $buckarooIdealModel = new TIG_Buckaroo3Extended_Block_PaymentMethods_Ideal_Checkout_Form();
508
+ $issuerList = $buckarooIdealModel->getIssuerList();
509
+
510
+ foreach ($issuerList as $issuer => $issuerDetails) {
511
+ $option = array();
512
+ $optionChecked = false;
513
+ if (!empty($sessionValue) && array_key_exists($sessionValue, $issuerList)) {
514
+ if ($issuer == $sessionValue) {
515
+ $optionChecked = true;
516
+ }
517
  }
518
+
519
+ $option["checked"] = $optionChecked;
520
+ $option["title"] = $issuerDetails['name'];
521
+ $option["code"] = $issuer;
522
+ $option["image"] = $issuerDetails['logo'];
523
+ $options[] = $option;
524
  }
525
 
526
+ return $options;
527
  }
528
 
529
+ return null;
530
  }
531
 
532
  private function _getReviewData() {
544
  $billing_address["email"] = $quote->getCustomerEmail();
545
  $billing_address["firstname"] = $billingAddressData["firstname"];
546
  $billing_address["lastname"] = $billingAddressData["lastname"];
547
+ $billing_address["telephone"] = (string) $billingAddressData["telephone"] . " ";
548
+ $billingStreet = $billingAddress->getStreet();
549
+ if (is_array($billingStreet)) {
550
+ $billing_address["street"] = implode(' ', $billingStreet);
551
+ } else {
552
+ $billing_address["street"] = $billingStreet;
553
+ }
554
  $billing_address["postcode"] = $billingAddressData["postcode"];
555
  $billing_address["city"] = $billingAddressData["city"];
556
 
560
  $shipping_address = array();
561
  $shipping_address["firstname"] = $shippingAddressData["firstname"];
562
  $shipping_address["lastname"] = $shippingAddressData["lastname"];
563
+ $shipping_address["telephone"] = (string) $shippingAddressData["telephone"] . " ";
564
+ $shippingStreet = $shippingAddress->getStreet();
565
+ if (is_array($shippingStreet)) {
566
+ $shipping_address["street"] = implode(' ', $shippingStreet);
567
+ } else {
568
+ $shipping_address["street"] = $shippingStreet;
569
+ }
570
  $shipping_address["postcode"] = $shippingAddressData["postcode"];
571
  $shipping_address["city"] = $shippingAddressData["city"];
572
 
591
  /**
592
  * Conveinience method, compares 2 formatted address arrays
593
  */
594
+ protected function _billingAndShippingAddressesAreTheSame($billingAddressArray = array(), $shippingAddressArray = array()) {
595
  if (count($billingAddressArray) == 0 || count($shippingAddressArray) == 0) {
596
  return true;
597
  }
621
  /**
622
  * Sets headers and body with proper JSON encoding
623
  */
624
+ protected function _JSONencodeAndRespond($data, $numericCheck = true) {
625
  //set response body
626
  $this->_setHeader();
627
+ if ($numeric_check === FALSE || version_compare(PHP_VERSION, '5.3.3', '<')) {
 
 
628
  $this->getResponse()->setBody(json_encode($data));
629
+ } else {
630
+ $this->getResponse()->setBody(json_encode($data, JSON_NUMERIC_CHECK));
631
  }
632
 
633
  }
app/code/local/Highstreet/Hsapi/controllers/IndexController.php CHANGED
@@ -4,7 +4,7 @@
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_IndexController extends Mage_Core_Controller_Front_Action
@@ -54,15 +54,15 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
54
  }
55
  $this->_JSONencodeAndRespond(array("title" => $page->getData('title'), "content" => $page->getData('content')));
56
  } else if ($pageIds !== null || $contentKeys !== null) {
57
- $page = Mage::getModel('cms/page');
58
- $page->setStoreId(Mage::app()->getStore()->getId());
59
-
60
  $response = array();
61
  if ($pageIds !== null) {
62
  foreach ($pageIds as $key => $value) {
63
  try {
 
 
64
  $page->load($value, 'identifier');
65
  $response[$key] = array("title" => $page->getData('title'), "content" => $page->getData('content'));
 
66
  } catch (Exception $e) {
67
  $response[$key] = array("title" => "Page not found", "content" => "");
68
  }
@@ -70,8 +70,11 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
70
  } else if ($contentKeys !== null) {
71
  foreach ($contentKeys as $key => $value) {
72
  try {
 
 
73
  $page->load($value, 'identifier');
74
  $response[$key] = array("title" => $page->getData('title'), "contentKey" => $value, "content" => $page->getData('content'));
 
75
  } catch (Exception $e) {
76
  $response[$key] = array("title" => "Page not found", "content" => "");
77
  }
@@ -100,7 +103,8 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
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
  /**
@@ -117,16 +121,17 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
117
  public function categoriesAction()
118
  {
119
  //Get categoryId and check
120
- $categoryId = Mage::app()->getRequest()->getParam('id');
 
 
 
 
 
121
 
122
  $categories = null;
123
  $categoryModel = Mage::getModel('highstreet_hsapi/categories');
124
 
125
- if ($categoryId === 'tree') {
126
- $categories = $categoryModel->getCategoryTree();
127
- } else if(!$categoryId || $categoryId !== '') {
128
- $categories = $categoryModel->getCategories($categoryId);
129
- }
130
 
131
  if($categories == null) {
132
  $this->_respondWith404();
@@ -144,39 +149,31 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
144
  return $this->productsAction();
145
  }
146
 
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
 
@@ -200,19 +197,6 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
200
 
201
  }
202
 
203
-
204
-
205
- public function postCart() {
206
- $requestObject = Mage::app()->getRequest();
207
- $data = json_decode($requestObject->getParam('products'), true);
208
-
209
- $checkoutModel = Mage::getModel('highstreet_hsapi/checkout');
210
- $cart = $checkoutModel->getQuoteWithProductsAndQuantities($data["checkout"]);
211
-
212
- $this->_JSONencodeAndRespond($cart);
213
-
214
- }
215
-
216
  public function postCart_v2() {
217
  $requestObject = Mage::app()->getRequest();
218
  $data = json_decode($requestObject->getParam('items'), true);
@@ -223,23 +207,7 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
223
  $this->_JSONencodeAndRespond($cart);
224
 
225
  }
226
-
227
- public function getCart() {
228
- $requestObject = Mage::app()->getRequest();
229
- $quote_id = $requestObject->getParam('quote_id');
230
- if(!$quote_id) {
231
- $this->_respondWith404();
232
- return false;
233
- }
234
-
235
- $checkoutModel = Mage::getModel('highstreet_hsapi/checkout');
236
- $cart = $checkoutModel->getQuoteWithProductsAndQuantities(null,$quote_id);
237
-
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');
@@ -350,12 +318,16 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
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) {
@@ -405,24 +377,6 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
405
  $this->_JSONencodeAndRespond($response);
406
  }
407
 
408
- /**
409
- * Media
410
- */
411
- public function imagesAction() {
412
- $requestObject = $this->getRequest();
413
-
414
- $imageUrl = Mage::getModel('highstreet_hsapi/images')->getImage(urldecode($requestObject->getParam('src')), $requestObject->getParam('size'));
415
-
416
- if ($imageUrl === null || !file_exists($imageUrl)) {
417
- $this->_respondWith404();
418
- return false;
419
- }
420
-
421
- $this->getResponse()->setHeader('Content-Type', $this->_getHelper()->imageHeaderStringForImage($imageUrl), true);
422
- $this->getResponse()->setBody(file_get_contents($imageUrl));
423
- }
424
-
425
-
426
  /**
427
  * attributes
428
  */
@@ -507,21 +461,21 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
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');
520
  $this->getResponse()->sendHeaders();
521
  return;
522
  }
523
 
524
- private function _respondWith401()
525
  {
526
  $this->getResponse()->setHeader('HTTP/1.1','401 Unauthorized');
527
  $this->getResponse()->sendHeaders();
@@ -531,7 +485,7 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
531
  /**
532
  * Sets the proper headers
533
  */
534
- private function _setHeader()
535
  {
536
  Mage::getSingleton('core/session')->setLastStoreCode(Mage::app()->getStore()->getCode());
537
  header_remove('Pragma'); // removes 'no-cache' header
@@ -541,10 +495,10 @@ class Highstreet_Hsapi_IndexController extends Mage_Core_Controller_Front_Action
541
  /**
542
  * Sets headers and body with proper JSON encoding
543
  */
544
- private function _JSONencodeAndRespond($data, $numeric_check = TRUE) {
545
  //set response body
546
  $this->_setHeader();
547
- if ($numeric_check === FALSE) {
548
  $this->getResponse()->setBody(json_encode($data));
549
  } else {
550
  $this->getResponse()->setBody(json_encode($data, JSON_NUMERIC_CHECK));
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_IndexController extends Mage_Core_Controller_Front_Action
54
  }
55
  $this->_JSONencodeAndRespond(array("title" => $page->getData('title'), "content" => $page->getData('content')));
56
  } else if ($pageIds !== null || $contentKeys !== null) {
 
 
 
57
  $response = array();
58
  if ($pageIds !== null) {
59
  foreach ($pageIds as $key => $value) {
60
  try {
61
+ $page = Mage::getModel('cms/page');
62
+ $page->setStoreId(Mage::app()->getStore()->getId());
63
  $page->load($value, 'identifier');
64
  $response[$key] = array("title" => $page->getData('title'), "content" => $page->getData('content'));
65
+ unset($page);
66
  } catch (Exception $e) {
67
  $response[$key] = array("title" => "Page not found", "content" => "");
68
  }
70
  } else if ($contentKeys !== null) {
71
  foreach ($contentKeys as $key => $value) {
72
  try {
73
+ $page = Mage::getModel('cms/page');
74
+ $page->setStoreId(Mage::app()->getStore()->getId());
75
  $page->load($value, 'identifier');
76
  $response[$key] = array("title" => $page->getData('title'), "contentKey" => $value, "content" => $page->getData('content'));
77
+ unset($page);
78
  } catch (Exception $e) {
79
  $response[$key] = array("title" => "Page not found", "content" => "");
80
  }
103
  "version" => (string)Mage::getConfig()->getNode()->modules->Highstreet_Hsapi->version,
104
  "magento_version" => (string)Mage::getVersion(),
105
  "environment" => $configApi->environment(),
106
+ "storefront" => Mage::app()->getStore()->getCode(),
107
+ "attributes_sort_order_setting_raw" => $configApi->attributesSortOrderRaw()));
108
  }
109
 
110
  /**
121
  public function categoriesAction()
122
  {
123
  //Get categoryId and check
124
+ $request = Mage::app()->getRequest();
125
+ $categoryId = $request->getParam('id');
126
+ $maxDepth = $request->getParam('max_depth');
127
+ if ($maxDepth === null) {
128
+ $maxDepth = -1;
129
+ }
130
 
131
  $categories = null;
132
  $categoryModel = Mage::getModel('highstreet_hsapi/categories');
133
 
134
+ $categories = $categoryModel->getCategory($categoryId, $maxDepth);
 
 
 
 
135
 
136
  if($categories == null) {
137
  $this->_respondWith404();
149
  return $this->productsAction();
150
  }
151
 
 
 
 
 
 
 
 
152
  public function checkout_v2Action() {
153
  $requestObject = Mage::app()->getRequest();
154
  $data = json_decode($requestObject->getParam('items'), true);
155
 
156
+ $trackingId = $requestObject->getParam('tid');
157
+ Mage::getSingleton('checkout/session')->setHsTid($trackingId);
158
+
159
  $country = $requestObject->getParam('country');
160
+ return $this->_postCheckout($data,$country);
161
 
162
  }
163
 
164
+ private function _postCheckout($items,$country = null) {
165
+ $checkoutModel = Mage::getModel('highstreet_hsapi/checkoutV2');
166
+
 
 
 
 
167
  $checkoutModel->fillCartWithProductsAndQuantities($items);
168
 
169
+ $configApi = Mage::helper('highstreet_hsapi/config_api');
170
+ if ($configApi->standaloneCheckoutActive()) {
171
+ $this->_JSONencodeAndRespond($checkoutModel->getStartData());
172
+ } else {
173
+ $url = $configApi->checkoutRedirectUrl();
174
+
175
+ Mage::app()->getFrontController()->getResponse()->setRedirect($url);
176
  }
 
 
 
 
177
  }
178
 
179
 
197
 
198
  }
199
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  public function postCart_v2() {
201
  $requestObject = Mage::app()->getRequest();
202
  $data = json_decode($requestObject->getParam('items'), true);
207
  $this->_JSONencodeAndRespond($cart);
208
 
209
  }
210
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  public function getCart_v2() {
212
  $requestObject = Mage::app()->getRequest();
213
  $quote_id = $requestObject->getParam('quote_id');
318
  $requestObject = Mage::app()->getRequest();
319
  $model = Mage::getModel('highstreet_hsapi/products');
320
 
 
321
  $productObjects = array();
322
+ if ($requestObject->getParam('ids') != "") {
323
+ $idsArray = explode(',', $requestObject->getParam('ids'));
324
 
325
+ foreach ($idsArray as $value) {
326
+ $productObject = Mage::getModel('catalog/product')->load($value);
327
+ if (is_object($productObject) && $productObject->getId() > 0) {
328
+ $productObjects[] = $productObject;
329
+ }
330
+ }
331
  }
332
 
333
  if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) && $_SERVER["HTTP_IF_MODIFIED_SINCE"] !== NULL) {
377
  $this->_JSONencodeAndRespond($response);
378
  }
379
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
380
  /**
381
  * attributes
382
  */
461
  /**
462
  * Header and http functions
463
  */
464
+ protected function _respondWith304()
465
  {
466
  $this->getResponse()->setHeader('HTTP/1.1','304 Not Modified');
467
  $this->getResponse()->sendHeaders();
468
  return;
469
  }
470
 
471
+ protected function _respondWith404()
472
  {
473
  $this->getResponse()->setHeader('HTTP/1.1','404 Not Found');
474
  $this->getResponse()->sendHeaders();
475
  return;
476
  }
477
 
478
+ protected function _respondWith401()
479
  {
480
  $this->getResponse()->setHeader('HTTP/1.1','401 Unauthorized');
481
  $this->getResponse()->sendHeaders();
485
  /**
486
  * Sets the proper headers
487
  */
488
+ protected function _setHeader()
489
  {
490
  Mage::getSingleton('core/session')->setLastStoreCode(Mage::app()->getStore()->getCode());
491
  header_remove('Pragma'); // removes 'no-cache' header
495
  /**
496
  * Sets headers and body with proper JSON encoding
497
  */
498
+ protected function _JSONencodeAndRespond($data, $numeric_check = TRUE) {
499
  //set response body
500
  $this->_setHeader();
501
+ if ($numeric_check === FALSE || version_compare(PHP_VERSION, '5.3.3', '<')) {
502
  $this->getResponse()->setBody(json_encode($data));
503
  } else {
504
  $this->getResponse()->setBody(json_encode($data, JSON_NUMERIC_CHECK));
app/code/local/Highstreet/Hsapi/etc/config.xml CHANGED
@@ -5,13 +5,13 @@
5
  *
6
  * @package Highstreet_Hsapi
7
  * @author Tim Wachter (tim@touchwonders.com) ~ Touchwonders
8
- * @copyright Copyright (c) 2013 Touchwonders b.v. (http://www.touchwonders.com/)
9
  */
10
  -->
11
  <config>
12
  <modules>
13
  <Highstreet_Hsapi>
14
- <version>1.4.3</version>
15
  </Highstreet_Hsapi>
16
  </modules>
17
  <frontend>
@@ -24,16 +24,6 @@
24
  </args>
25
  </hsapi>
26
  </routers>
27
- <translate>
28
- <modules>
29
- <Highstreet_Hsapi>
30
- <files>
31
- <default>Highstreet_Hsapi.csv</default>
32
- </files>
33
- </Highstreet_Hsapi>
34
- </modules>
35
- </translate>
36
-
37
  </frontend>
38
  <global>
39
  <models>
@@ -68,7 +58,15 @@
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>
5
  *
6
  * @package Highstreet_Hsapi
7
  * @author Tim Wachter (tim@touchwonders.com) ~ Touchwonders
8
+ * @copyright Copyright (c) 2015 Touchwonders b.v. (http://www.touchwonders.com/)
9
  */
10
  -->
11
  <config>
12
  <modules>
13
  <Highstreet_Hsapi>
14
+ <version>1.5.0</version>
15
  </Highstreet_Hsapi>
16
  </modules>
17
  <frontend>
24
  </args>
25
  </hsapi>
26
  </routers>
 
 
 
 
 
 
 
 
 
 
27
  </frontend>
28
  <global>
29
  <models>
58
  </highstreet_hsapi_merge_quote>
59
  </observers>
60
  </sales_quote_merge_before>
61
+ <sales_order_place_after>
62
+ <observers>
63
+ <highstreet_hsapi_sales_order_place_after>
64
+ <class>Highstreet_Hsapi_Model_Observer</class>
65
+ <method>salesOrderPlaceAfter</method>
66
+ </highstreet_hsapi_sales_order_place_after>
67
+ </observers>
68
+ </sales_order_place_after>
69
+ <sales_order_invoice_pay>
70
  <observers>
71
  <highstreet_hsapi_sales_order_invoice_pay>
72
  <class>Highstreet_Hsapi_Model_Observer</class>
app/code/local/Highstreet/Hsapi/etc/system.xml CHANGED
@@ -95,6 +95,34 @@
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>
95
  <show_in_website>1</show_in_website>
96
  <show_in_store>1</show_in_store>
97
  </smartbanner_native_app_name>
98
+ <checkout_saco_active translate="label">
99
+ <label>Enable the standalone checkout</label>
100
+ <comment></comment>
101
+ <frontend_type>select</frontend_type>
102
+ <source_model>adminhtml/system_config_source_yesno</source_model>
103
+ <sort_order>90</sort_order>
104
+ <show_in_default>1</show_in_default>
105
+ <show_in_website>1</show_in_website>
106
+ <show_in_store>1</show_in_store>
107
+ </checkout_saco_active>
108
+ <checkout_redirect_url translate="label">
109
+ <label>Set the full checkout redirect url</label>
110
+ <comment>i.e. https://www.vendor.nl/checkout/cart?source=app</comment>
111
+ <frontend_type>text</frontend_type>
112
+ <sort_order>91</sort_order>
113
+ <show_in_default>1</show_in_default>
114
+ <show_in_website>1</show_in_website>
115
+ <show_in_store>1</show_in_store>
116
+ </checkout_redirect_url>
117
+ <attribute_sort_order translate="label">
118
+ <label>Adjust the product sort order</label>
119
+ <comment>JSON encoded string, formatted as {"attribute_name":"sortorder",...}</comment>
120
+ <frontend_type>textarea</frontend_type>
121
+ <sort_order>100</sort_order>
122
+ <show_in_default>1</show_in_default>
123
+ <show_in_website>1</show_in_website>
124
+ <show_in_store>1</show_in_store>
125
+ </attribute_sort_order>
126
  </fields>
127
  </api>
128
  </groups>
app/code/local/Highstreet/SmartAppBanner/etc/config.xml CHANGED
@@ -5,7 +5,7 @@
5
  <modules>
6
 
7
  <Highstreet_SmartAppBanner>
8
- <version>1.3.1</version>
9
  </Highstreet_SmartAppBanner>
10
 
11
  </modules>
5
  <modules>
6
 
7
  <Highstreet_SmartAppBanner>
8
+ <version>1.5.0</version>
9
  </Highstreet_SmartAppBanner>
10
 
11
  </modules>
app/design/frontend/base/default/template/highstreet/native_smart_app_banner.phtml CHANGED
@@ -14,6 +14,12 @@ if ($configHelper->nativeSmartbannerAppUrl() != "") {
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;
@@ -22,7 +28,13 @@ if ($configHelper->nativeSmartbannerAppUrl() != "") {
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
  }
14
  $searchQuery = Mage::app()->getRequest()->getParam('q');
15
  $deeplink .= $searchQuery ? "search/" . $searchQuery . "/" : "";
16
 
17
+ if ($deeplink === $configHelper->nativeSmartbannerAppUrl() . "://") {
18
+ $deeplink .= 'home/';
19
+ }
20
+
21
+ $deeplink = rtrim($deeplink, '/'); // Remove trailing slash. Note: This funciton removes *all* trailing slashes,not just one
22
+
23
  if ($configHelper->shouldShowNativeSmartbanner()) {
24
  $metaTag = '<meta name="apple-itunes-app" content="app-id=' . $configHelper->nativeSmartbannerAppId();
25
  $metaTag .= ', app-argument=' . $deeplink;
28
  echo $metaTag;
29
  }
30
 
31
+ echo '<meta property="al:ios:url" content="' . $deeplink . '"/>';
32
+
33
+ if ($configHelper->nativeSmartbannerAppName() != "") {
34
+ echo '<meta property="al:ios:app_name" content="' . $configHelper->nativeSmartbannerAppName() . '"/>';
35
+ }
36
+
37
+ if ($configHelper->nativeSmartbannerAppId() != "") {
38
+ echo '<meta property="al:ios:app_store_id" content="' . $configHelper->nativeSmartbannerAppId() . '"/>';
39
+ }
40
  }
app/etc/modules/Technooze_Timage.xml DELETED
@@ -1,17 +0,0 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /**
4
- * @category Technooze/Modules/magento-how-tos
5
- * @package Technooze_Timage
6
- * @author Damodar Bashyal
7
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
8
- */
9
- -->
10
- <config>
11
- <modules>
12
- <Technooze_Timage>
13
- <active>true</active>
14
- <codePool>community</codePool>
15
- </Technooze_Timage>
16
- </modules>
17
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/locale/de_DE/Highstreet_Hsapi.csv DELETED
@@ -1,72 +0,0 @@
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."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/locale/en_US/Highstreet_Hsapi.csv DELETED
@@ -1,97 +0,0 @@
1
- "Welcome", "Welcome"
2
- "Billing address", "Billing address"
3
- "Shipment", "Shipment"
4
- "Payment", "Payment"
5
- "Confirmation", "Confirmation"
6
- "Log out", "Log out"
7
- "Confirm and pay", "Confirm and pay"
8
- "Your order is not final yet", "Your order is not final yet"
9
- "You will continue to our secure payment page", "You will continue to our secure payment page"
10
- "Hello!", "Hello!"
11
- "Checkout as guest", "Checkout as guest"
12
- "Log in", "Log in"
13
- "hsapi_Register", "Register"
14
- "Sign In", "Sign In"
15
- "E-mail address", "E-mail address"
16
- "ipad_Password", "Password"
17
- "Forgot your password?", "Forgot your password?"
18
- "Send", "Send"
19
- "We have sent you an e-mail with which you can change your password.", "We have sent you an e-mail with which you can change your password."
20
- "Create an account now", "Create an account now"
21
- "and checkout faster next time", "and checkout faster next time"
22
- "Please enter a valid e-mailaddress", "Please enter a valid e-mailaddress"
23
- "Please enter a valid password", "Please enter a valid password"
24
- "Repeat the password", "Repeat the password"
25
- "First Name", "First Name"
26
- "Last Name", "Last Name"
27
- "Please enter a valid phone number.", "Please enter a valid phone number."
28
- "Phone number", "Phone number"
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.", "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."
30
- "Street", "Street"
31
- "House number", "House number"
32
- "Zip code", "Zip code"
33
- "City", "City"
34
- "Something went wrong", "Something went wrong"
35
- "Please try again", "Please try again"
36
- "How do you want to pay for your order?", "How do you want to pay for your order?"
37
- "Please check your order.", "Please check your order."
38
- "Please check the order overview. If this is correct, you can place your order.", "Please check the order overview. If this is correct, you can place your order."
39
- "How do you want to receive your order?", "How do you want to receive your order?"
40
- "Invoice address / delivery address", "Invoice address / delivery address"
41
- "Edit", "Edit"
42
- "Delivery method", "Delivery method"
43
- "Payment method", "Payment method"
44
- "You can continue to the next step when you have entered all fields", "You can continue to the next step when you have entered all fields"
45
- "There has been an unknown error. Please try again later again later.", "There has been an unknown error. Please try again later again later."
46
- "Thanks for shopping at ", "Thanks for shopping at "
47
- ".<span class='hidden'>_ORDER_TEXT</span>", ".<span class='hidden'>_ORDER_TEXT</span>"
48
- "When you tap 'Confirm and pay', you agree with ", "When you tap `Confirm and pay`, you agree with "
49
- "the general terms", "the general terms"
50
- " of ", " of "
51
- "Ship to the same address", "Ship to the same address"
52
- "Invoice address", "Invoice address"
53
- "Delivery address", "Delivery address"
54
- "Please make sure your passwords match.", "Please make sure your passwords match."
55
- "Something went wrong while trying to get your address trough your zip code and house number. Please fill in your street and city manually.", "Er is iets fout gegaan met het ophalen van het adres via postcode en huisnummer. Vul het adres handmatig in."
56
- "Street name is being retrieved", "Street name is being retrieved"
57
- "City name is being retrieved", "City name is being retrieved"
58
- "No addition is known for this housenumber.", "No addition is known for this housenumber."
59
- "Housenumber addition unknown.", "Housenumber addition unknown."
60
- "Known addition:", "Known addition:"
61
- "Known additions:", "Known additions:"
62
-
63
- "hsapi.index.couponTip", "Do you have a coupon code?<br />You can add your code on the<br />'payment' step."
64
-
65
- "hsapi.addCouponAction.error.fatal", "An unexpected error has occurred, please try again later."
66
- "hsapi.addCouponAction.error.invalid", "The coupon code you entered is invalid or has expired."
67
- "hsapi.addCouponAction.error.length", "The coupon code you entered is too long, the maximum length is "
68
- "hsapi.addCouponAction.success", "Kortingsbon '{coupon_code}' is succesvol toegepast. In je bestellijst kun je je korting bekijken."
69
- "hsapi.addCouponAction.success.removed", "Kortingsbon '{coupon_code}' is succesvol verwijdert."
70
-
71
- "hsapi.checkout.coupon.addTitle", "Add a <u>coupon code</u>"
72
- "hsapi.checkout.coupon.form.title", "Here you can fill in your coupon code."
73
- "hsapi.checkout.coupon.form.code", "Coupon code"
74
- "hsapi.checkout.coupon.form.add", "Add"
75
- "hsapi.checkout.coupon.form.remove", "Remove"
76
- "hsapi.checkout.coupon.paymentTitle", "Choose one of the payment options"
77
-
78
- "hsapi.checkout.payment.acceptAfterpayTermsText", "You have to accept the terms and conditions of AfterPay to use this payment method"
79
-
80
- "hsapi.checkout.billing.error.email", "Please enter a valid e-mailaddress"
81
-
82
-
83
- "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.", "The entered email address is already linked to an account. Please login instead or use a different email address for registration."
84
-
85
- '"%s" is not a valid email address.', "hsapi.checkout.email.error"
86
- '"%s" is not a valid hostname.', "hsapi.checkout.email.error"
87
- '"%s" exceeds the allowed length.', "hsapi.checkout.email.error"
88
- "'%value%' appears to be an IP address, but IP addresses are not allowed", "hsapi.checkout.email.error"
89
- "'%value%' appears to be a DNS hostname but cannot match TLD against known list", "hsapi.checkout.email.error"
90
- "'%value%' appears to be a DNS hostname but contains a dash in an invalid position", "hsapi.checkout.email.error"
91
- "'%value%' appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'", "hsapi.checkout.email.error"
92
- "'%value%' appears to be a DNS hostname but cannot extract TLD part", "hsapi.checkout.email.error"
93
- "'%value%' does not appear to be a valid local network name", "hsapi.checkout.email.error"
94
- "'%value%' appears to be a local network name but local network names are not allowed", "hsapi.checkout.email.error"
95
- "'%value%' appears to be a DNS hostname but the given punycode notation cannot be decoded", "hsapi.checkout.email.error"
96
-
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/locale/nl_NL/Highstreet_Hsapi.csv DELETED
@@ -1,98 +0,0 @@
1
- "Welcome", "Welkom"
2
- "Billing address", "Factuuradres"
3
- "Shipment", "Verzending"
4
- "Payment", "Betaalwijze"
5
- "Confirmation", "Bevestiging"
6
- "Log out", "Log uit"
7
- "Confirm and pay", "Bevestig en betaal"
8
- "Your order is not final yet", "Je bestelling is nog niet definitief"
9
- "You will continue to our secure payment page", "Je gaat door naar onze beveiligde betaalomgeving"
10
- "Hello!", "Hallo!"
11
- "Checkout as guest", "Reken af als gast"
12
- "Log in", "Log in"
13
- "hsapi_Register", "Registreer"
14
- "Sign In", "Sign In"
15
- "E-mail address", "E-mailadres"
16
- "ipad_Password", "Wachtwoord"
17
- "Forgot your password?", "Wachtwoord vergeten?"
18
- "Send", "Verzenden"
19
- "We have sent you an e-mail with which you can change your password.", "Er is een e-mail naar het door u opgegeven adres gestuurd waarmee u uw wachtwoord kunt veranderen."
20
- "Create an account now", "Maak een account aan"
21
- "and checkout faster next time", "en bestel de volgende keer makkelijker"
22
- "Please enter a valid e-mailaddress", "Vul een geldig e-mail adres in"
23
- "Please enter a valid password", "Vul een geldig wachtwoord in"
24
- "Repeat the password", "Herhaal wachtwoord"
25
- "First Name", "Voornaam"
26
- "Last Name", "Achternaam"
27
- "Please enter a valid phone number.", "Vul een geldig telefoonnummer in"
28
- "Phone number", "Telefoonnummer"
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.", "We vragen om een telefoonnummer zodat we je indien nodig kunnen bellen over de bestelling. We zullen je telefoonnummer nooit gebruiken voor andere doeleinden."
30
- "Street", "Straat"
31
- "House number", "Huisnummer"
32
- "Zip code", "Postcode"
33
- "City", "Plaats"
34
- "Something went wrong", "Er is iets mis gegaan"
35
- "Please try again", "Probeer het opnieuw"
36
- "How do you want to pay for your order?", "Hoe wil je je bestelling<br />betalen?"
37
- "Please check your order.", "Klopt jouw bestelling?"
38
- "Please check the order overview. If this is correct, you can place your order.", "Hier zie je een overzicht van de bestelling. Als dit helemaal klopt kun je de bestelling plaatsen."
39
- "How do you want to receive your order?", "Hoe wil je je bestelling<br />ontvangen?"
40
- "Invoice address / delivery address", "Factuuradres/Bezorgadres"
41
- "Edit", "Wijzig"
42
- "Delivery method", "Verzendoptie"
43
- "Payment method", "Betaalwijze"
44
- "You can continue to the next step when you have entered all fields", "Je kunt pas naar de volgende stap als je alle velden volledig hebt ingevuld"
45
- "There has been an unknown error. Please try again later again later.", "Er heeft zich een onbekende fout voorgedaan. Probeer het later nog eens."
46
- "Thanks for shopping at ", "Leuk dat je bij "
47
- ".<span class='hidden'>_ORDER_TEXT</span>", " bestelt."
48
- "When you tap 'Confirm and pay', you agree with ", "Als je op `Bevestig en betaal` tapt, ga je akkoord met "
49
- "the general terms", "de algemene voorwaarden"
50
- " of ", " van "
51
- "Ship to the same address", "Bestelling verzenden naar hetzelfde adres"
52
- "Invoice address", "Factuuradres"
53
- "Delivery address", "Bezorgadres"
54
- "Please make sure your passwords match.", "De ingevoerde wachtwoorden komen niet met elkaar overeen."
55
- "Something went wrong while trying to get your address trough your zip code and house number. Please fill in your street and city manually.", "Er is iets fout gegaan met het ophalen van het adres via postcode en huisnummer. Vul het adres handmatig in."
56
- "Street name is being retrieved", "Straatnaam wordt opgehaald"
57
- "City name is being retrieved", "Plaatsnaam wordt opgehaald"
58
- "No addition is known for this housenumber.", "Geen toevoeging bekend voor dit huisnummer."
59
- "Housenumber addition unknown.", "Huisnummer toevoeging onbekend."
60
- "Known addition:", "Bekende toevoeging:"
61
- "Known additions:", "Bekende toevoegingen:"
62
-
63
- "hsapi.index.couponTip", "Heb je een tegoedbon?<br />Die kun je straks in de stap<br />'betaalwijze' invoeren."
64
-
65
- "hsapi.addCouponAction.error.fatal", "Er heeft zich een onbekende fout voorgedaan, probleer het later nog eens."
66
- "hsapi.addCouponAction.error.invalid", "De tegoedbon die je ingevoerd hebt is niet geldig."
67
- "hsapi.addCouponAction.error.length", "De tegoedbon die je hebt ingevoerd is te lang, de maximale lengte is "
68
- "hsapi.addCouponAction.success", "Tegoedbon '{coupon_code}' is succesvol toegepast. In je bestellijst kun je je korting bekijken."
69
- "hsapi.addCouponAction.success.removed", "Tegoedbon '{coupon_code}' is succesvol verwijderd."
70
-
71
- "hsapi.checkout.coupon.addTitle", "Voeg <u>tegoedbon</u> toe"
72
- "hsapi.checkout.coupon.form.title", "Vul hier de code van je tegoedbon in."
73
- "hsapi.checkout.coupon.form.code", "Tegoedbon"
74
- "hsapi.checkout.coupon.form.add", "Voeg toe"
75
- "hsapi.checkout.coupon.form.remove", "Verwijder"
76
- "hsapi.checkout.coupon.paymentTitle", "Maak hier een keuze uit de volgende betaalopties"
77
-
78
- "hsapi.checkout.payment.acceptAfterpayTermsText", "Je moet akkoord gaan met de betalingsvoorwaarden van AfterPay om gebruik te maken van deze betaalmethode"
79
-
80
- "hsapi.checkout.billing.error.email", "Vul een geldig e-mailadres in"
81
-
82
-
83
- "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.", "Het gebruikte e-mailadres is al gekoppeld aan een account. Log in met dit adres of gebruik een ander e-mailadres voor registratie."
84
-
85
- '"%s" is not a valid email address.', "hsapi.checkout.email.error"
86
- '"%s" is not a valid hostname.', "hsapi.checkout.email.error"
87
- '"%s" exceeds the allowed length.', "hsapi.checkout.email.error"
88
- "'%value%' appears to be an IP address, but IP addresses are not allowed", "hsapi.checkout.email.error"
89
- "'%value%' appears to be a DNS hostname but cannot match TLD against known list", "hsapi.checkout.email.error"
90
- "'%value%' appears to be a DNS hostname but contains a dash in an invalid position", "hsapi.checkout.email.error"
91
- "'%value%' appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'", "hsapi.checkout.email.error"
92
- "'%value%' appears to be a DNS hostname but cannot extract TLD part", "hsapi.checkout.email.error"
93
- "'%value%' does not appear to be a valid local network name", "hsapi.checkout.email.error"
94
- "'%value%' appears to be a local network name but local network names are not allowed", "hsapi.checkout.email.error"
95
- "'%value%' appears to be a DNS hostname but the given punycode notation cannot be decoded", "hsapi.checkout.email.error"
96
-
97
-
98
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
package.xml CHANGED
@@ -1,7 +1,7 @@
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>
@@ -9,11 +9,11 @@
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. &#xD;
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>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Highstreet</name>
4
+ <version>1.5.0</version>
5
  <stability>stable</stability>
6
  <license>-</license>
7
  <channel>community</channel>
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. &#xD;
11
  This extension does not modify or affect the Magento installation, nor does it change any catalog data.</description>
12
+ <notes>-</notes>
13
  <authors><author><name>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-11-11</date>
15
+ <time>16:02:28</time>
16
+ <contents><target name="magelocal"><dir name="Highstreet"><dir name="Hsapi"><dir name="Helper"><dir name="Config"><file name="Api.php" hash="2d36d4018cb9f106794a7a895dcc3e0b"/></dir><file name="Data.php" hash="c0a9f7313e8487f10c40be73dbe34e2a"/><file name="Encryption.php" hash="c381845a0bb22e460abac657ac96cd8b"/></dir><dir name="Model"><file name="Attributes.php" hash="419fad545dc34dafd246fdfb4a139e3d"/><file name="Categories.php" hash="46b5f643165efdcaaab8a77f51b126f8"/><file name="CheckoutV2.php" hash="b9a85c8729d3cac5f34f67dd3dabda89"/><file name="Observer.php" hash="66c91124a567aba176a12c42de870af0"/><file name="Products.php" hash="3bb719c0731ba4570cad5184b4efc4f2"/><file name="SearchSuggestions.php" hash="7bed3efaf5af19276a4fbb7d6aade83f"/><dir name="System"><dir name="Config"><file name="Environment.php" hash="5ef07d78cf67bc47be1a64e54ff643ec"/></dir></dir></dir><dir name="controllers"><file name="CheckoutController.php" hash="e6bf261b14ba1db83e21b2bfb9ae4dee"/><file name="IndexController.php" hash="56d2269c92984d46c9fa9575647088a2"/></dir><dir name="etc"><file name="config.xml" hash="c31bd4f4f8a0c3e11ca556b74e797099"/><file name="system.xml" hash="531fc9ffcf8cb09ee7d6457ef7cbaa4b"/></dir></dir><dir name="SmartAppBanner"><dir name="etc"><file name="config.xml" hash="6abce99709952c93f3af13afdca03a79"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Highstreet_Api.xml" hash="97e586a7ef0a274d4f0fda883c646f31"/><file name="Highstreet_SmartAppBanner.xml" hash="c739b442a3907d7d7414d0abfd0efaf2"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="highstreet"><file name="smart_app_banner.xml" hash="ed1ad1737439e221c8ca1e0daa0ccd1b"/></dir></dir><dir name="template"><dir name="highstreet"><file name="native_smart_app_banner.phtml" hash="e7c16669aa29fcfbc18ea5275b80341a"/><file name="smart_app_banner.phtml" hash="0faa81b53d95a57583e1c1747ac9cd96"/></dir></dir></dir></dir></dir></target></contents>
17
  <compatible/>
18
+ <dependencies><required><php><min>5.0.0.0</min><max>6.0.0.0</max></php></required></dependencies>
19
  </package>