Nosto_Tagging - Version 2.4.0

Version Notes

* Deprecate product re-crawl feature and implement product update API in it's place
* Add JavaScript "add-to-cart" feature to enable adding products to cart directly from recommendations
* Refactor order status handling in order confirmations and order exports

Download this release

Release Info

Developer Nosto
Extension Nosto_Tagging
Version 2.4.0
Comparing to
See all releases


Code changes from version 2.2.1 to 2.4.0

Files changed (37) hide show
  1. app/code/community/Nosto/Tagging/Block/Addtocart.php +52 -0
  2. app/code/community/Nosto/Tagging/Model/Meta/Order.php +19 -1
  3. app/code/community/Nosto/Tagging/Model/Meta/Order/Status.php +87 -0
  4. app/code/community/Nosto/Tagging/Model/Meta/Product.php +49 -25
  5. app/code/community/Nosto/Tagging/Model/Observer.php +76 -21
  6. app/code/community/Nosto/Tagging/controllers/Adminhtml/NostoController.php +31 -35
  7. app/code/community/Nosto/Tagging/controllers/ExportController.php +6 -3
  8. app/code/community/Nosto/Tagging/etc/config.xml +3 -3
  9. app/design/frontend/base/default/layout/nostotagging.xml +5 -0
  10. app/design/frontend/base/default/template/nostotagging/addtocart.phtml +61 -0
  11. lib/nosto/php-sdk/src/classes/Nosto.php +17 -0
  12. lib/nosto/php-sdk/src/classes/NostoAccount.php +4 -4
  13. lib/nosto/php-sdk/src/classes/NostoModelValidator.php +90 -0
  14. lib/nosto/php-sdk/src/classes/NostoOrderConfirmation.php +3 -1
  15. lib/nosto/php-sdk/src/classes/NostoProductReCrawl.php +3 -3
  16. lib/nosto/php-sdk/src/classes/api/NostoApiRequest.php +2 -0
  17. lib/nosto/php-sdk/src/classes/{export/NostoExportCollection.php → collection/NostoCollection.php} +3 -11
  18. lib/nosto/php-sdk/src/classes/collection/NostoOrderCollection.php +46 -0
  19. lib/nosto/php-sdk/src/classes/collection/NostoProductCollection.php +46 -0
  20. lib/nosto/php-sdk/src/classes/{NostoException.php → exception/NostoException.php} +0 -0
  21. lib/nosto/php-sdk/src/classes/exception/NostoHttpException.php +41 -0
  22. lib/nosto/php-sdk/src/classes/export/NostoExportOrderCollection.php +4 -6
  23. lib/nosto/php-sdk/src/classes/export/NostoExportProductCollection.php +1 -6
  24. lib/nosto/php-sdk/src/classes/export/NostoExporter.php +2 -2
  25. lib/nosto/php-sdk/src/classes/http/NostoHttpRequest.php +64 -0
  26. lib/nosto/php-sdk/src/classes/http/NostoHttpRequestAdapter.php +18 -0
  27. lib/nosto/php-sdk/src/classes/http/NostoHttpRequestAdapterCurl.php +45 -15
  28. lib/nosto/php-sdk/src/classes/http/NostoHttpRequestAdapterSocket.php +40 -6
  29. lib/nosto/php-sdk/src/classes/http/NostoHttpResponse.php +57 -49
  30. lib/nosto/php-sdk/src/classes/oauth/NostoOAuthClient.php +1 -1
  31. lib/nosto/php-sdk/src/classes/operation/NostoOperationProduct.php +214 -0
  32. lib/nosto/php-sdk/src/config.inc.php +13 -3
  33. lib/nosto/php-sdk/src/interfaces/NostoExportCollectionInterface.php +48 -0
  34. lib/nosto/php-sdk/src/interfaces/NostoValidatableModelInterface.php +51 -0
  35. lib/nosto/php-sdk/src/interfaces/order/NostoOrderInterface.php +7 -0
  36. lib/nosto/php-sdk/src/{classes/NostoXhrResponse.php → interfaces/order/NostoOrderStatusInterface.php} +9 -57
  37. package.xml +8 -6
app/code/community/Nosto/Tagging/Block/Addtocart.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Nosto
22
+ * @package Nosto_Tagging
23
+ * @author Nosto Solutions Ltd <magento@nosto.com>
24
+ * @copyright Copyright (c) 2013-2015 Nosto Solutions Ltd (http://www.nosto.com)
25
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
+ */
27
+
28
+ /**
29
+ * Adds the `add-to-cart` script.
30
+ *
31
+ * @category Nosto
32
+ * @package Nosto_Tagging
33
+ * @author Nosto Solutions Ltd <magento@nosto.com>
34
+ */
35
+ class Nosto_Tagging_Block_Addtocart extends Mage_Core_Block_Template
36
+ {
37
+ /**
38
+ * Render script if the module is enabled for the current store.
39
+ *
40
+ * @return string
41
+ */
42
+ protected function _toHtml()
43
+ {
44
+ if (!Mage::helper('nosto_tagging')->isModuleEnabled()
45
+ || !Mage::helper('nosto_tagging/account')->existsAndIsConnected()
46
+ ) {
47
+ return '';
48
+ }
49
+
50
+ return parent::_toHtml();
51
+ }
52
+ }
app/code/community/Nosto/Tagging/Model/Meta/Order.php CHANGED
@@ -60,7 +60,7 @@ class Nosto_Tagging_Model_Meta_Order extends Mage_Core_Model_Abstract implements
60
  protected $_paymentProvider;
61
 
62
  /**
63
- * @var Nosto_Tagging_Model_Meta_Order_Buyer The user info of the buyer.
64
  */
65
  protected $_buyer;
66
 
@@ -69,6 +69,11 @@ class Nosto_Tagging_Model_Meta_Order extends Mage_Core_Model_Abstract implements
69
  */
70
  protected $_items = array();
71
 
 
 
 
 
 
72
  /**
73
  * @inheritdoc
74
  */
@@ -128,6 +133,16 @@ class Nosto_Tagging_Model_Meta_Order extends Mage_Core_Model_Abstract implements
128
  return $this->_items;
129
  }
130
 
 
 
 
 
 
 
 
 
 
 
131
  /**
132
  * Loads the order info from a Magento order model.
133
  *
@@ -141,6 +156,9 @@ class Nosto_Tagging_Model_Meta_Order extends Mage_Core_Model_Abstract implements
141
  $method = $order->getPayment()->getMethodInstance();
142
  $this->_paymentProvider = $method->getCode();
143
 
 
 
 
144
  $this->_buyer = new Nosto_Tagging_Model_Meta_Order_Buyer();
145
  $this->_buyer->loadData($order);
146
 
60
  protected $_paymentProvider;
61
 
62
  /**
63
+ * @var Nosto_Tagging_Model_Meta_Order_Buyer the user info of the buyer.
64
  */
65
  protected $_buyer;
66
 
69
  */
70
  protected $_items = array();
71
 
72
+ /**
73
+ * @var Nosto_Tagging_Model_Meta_Order_Status the order status.
74
+ */
75
+ protected $_orderStatus;
76
+
77
  /**
78
  * @inheritdoc
79
  */
133
  return $this->_items;
134
  }
135
 
136
+ /**
137
+ * Returns the order status model.
138
+ *
139
+ * @return NostoOrderStatusInterface the model.
140
+ */
141
+ public function getOrderStatus()
142
+ {
143
+ return $this->_orderStatus;
144
+ }
145
+
146
  /**
147
  * Loads the order info from a Magento order model.
148
  *
156
  $method = $order->getPayment()->getMethodInstance();
157
  $this->_paymentProvider = $method->getCode();
158
 
159
+ $this->_orderStatus = new Nosto_Tagging_Model_Meta_Order_Status();
160
+ $this->_orderStatus->loadData($order);
161
+
162
  $this->_buyer = new Nosto_Tagging_Model_Meta_Order_Buyer();
163
  $this->_buyer->loadData($order);
164
 
app/code/community/Nosto/Tagging/Model/Meta/Order/Status.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Nosto
22
+ * @package Nosto_Tagging
23
+ * @author Nosto Solutions Ltd <magento@nosto.com>
24
+ * @copyright Copyright (c) 2013-2015 Nosto Solutions Ltd (http://www.nosto.com)
25
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
+ */
27
+
28
+ /**
29
+ * Meta data class which holds information about the order status.
30
+ * This is used during the order confirmation API request and the order history
31
+ * export.
32
+ *
33
+ * @category Nosto
34
+ * @package Nosto_Tagging
35
+ * @author Nosto Solutions Ltd <magento@nosto.com>
36
+ */
37
+ class Nosto_Tagging_Model_Meta_Order_Status extends Mage_Core_Model_Abstract implements NostoOrderStatusInterface
38
+ {
39
+ /**
40
+ * @var string the order status code.
41
+ */
42
+ protected $_code;
43
+
44
+ /**
45
+ * @var string the order status label.
46
+ */
47
+ protected $_label;
48
+
49
+ /**
50
+ * @inheritdoc
51
+ */
52
+ protected function _construct()
53
+ {
54
+ $this->_init('nosto_tagging/meta_order_status');
55
+ }
56
+
57
+ /**
58
+ * Loads the status info from a Magento order model.
59
+ *
60
+ * @param Mage_Sales_Model_Order $order the order model.
61
+ */
62
+ public function loadData(Mage_Sales_Model_Order $order)
63
+ {
64
+ $this->_code = $order->getStatus();
65
+ $this->_label = $order->getStatusLabel();
66
+ }
67
+
68
+ /**
69
+ * Returns the order status code.
70
+ *
71
+ * @return string the code.
72
+ */
73
+ public function getCode()
74
+ {
75
+ return $this->_code;
76
+ }
77
+
78
+ /**
79
+ * Returns the order status label.
80
+ *
81
+ * @return string the label.
82
+ */
83
+ public function getLabel()
84
+ {
85
+ return $this->_label;
86
+ }
87
+ }
app/code/community/Nosto/Tagging/Model/Meta/Product.php CHANGED
@@ -34,7 +34,7 @@
34
  * @package Nosto_Tagging
35
  * @author Nosto Solutions Ltd <magento@nosto.com>
36
  */
37
- class Nosto_Tagging_Model_Meta_Product extends Mage_Core_Model_Abstract implements NostoProductInterface
38
  {
39
  /**
40
  * Product "in stock" tagging string.
@@ -130,23 +130,35 @@ class Nosto_Tagging_Model_Meta_Product extends Mage_Core_Model_Abstract implemen
130
  }
131
 
132
  /**
133
- * Returns the absolute url to the product page in the shop frontend.
134
- *
135
- * @return string the url.
136
  */
137
- public function getUrl()
138
  {
139
- return $this->_url;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  }
141
 
142
  /**
143
- * Setter for the absolute url to the product page in the shop frontend.
144
  *
145
- * @param $url string the url.
146
  */
147
- public function setUrl($url)
148
  {
149
- $this->_url = $url;
150
  }
151
 
152
  /**
@@ -160,7 +172,7 @@ class Nosto_Tagging_Model_Meta_Product extends Mage_Core_Model_Abstract implemen
160
  }
161
 
162
  /**
163
- * Sets the product's unique identifier.
164
  *
165
  * @param int|string $productId the ID.
166
  */
@@ -293,24 +305,38 @@ class Nosto_Tagging_Model_Meta_Product extends Mage_Core_Model_Abstract implemen
293
  * Loads the product info from a Magento product model.
294
  *
295
  * @param Mage_Catalog_Model_Product $product the product model.
 
296
  */
297
- public function loadData(Mage_Catalog_Model_Product $product)
298
  {
299
- // Unset the cached url first, as it won't include the `___store` param.
300
- // We need to define the specific store view in the url for the crawler
301
- // to see the correct product data when crawling the site.
 
 
 
 
302
  $this->_url = $product
303
  ->unsetData('url')
304
- ->getUrlInStore(array('_ignore_category' => true));
 
 
 
 
 
 
305
 
306
  $this->_productId = $product->getId();
307
  $this->_name = $product->getName();
308
 
309
- if (!$product->getImage() || $product->getImage() == 'no_selection') {
310
- $this->_imageUrl = $product->getImageUrl();
311
- } else {
312
- $this->_imageUrl = $product->getMediaConfig()
313
- ->getMediaUrl($product->getImage());
 
 
 
314
  }
315
 
316
  $this->_price = Mage::helper('tax')->getPrice(
@@ -323,9 +349,7 @@ class Nosto_Tagging_Model_Meta_Product extends Mage_Core_Model_Abstract implemen
323
  Mage::helper('nosto_tagging/price')->getProductPrice($product),
324
  true
325
  );
326
- $this->_currencyCode = Mage::app()->getStore()
327
- ->getCurrentCurrencyCode();
328
-
329
  $this->_availability = $product->isAvailable()
330
  ? self::PRODUCT_IN_STOCK
331
  : self::PRODUCT_OUT_OF_STOCK;
@@ -337,7 +361,7 @@ class Nosto_Tagging_Model_Meta_Product extends Mage_Core_Model_Abstract implemen
337
  ->addStatusFilter(Mage_Tag_Model_Tag::STATUS_APPROVED)
338
  ->addProductFilter($product->getId())
339
  ->setFlag('relation', true)
340
- ->addStoreFilter(Mage::app()->getStore()->getId())
341
  ->setActiveFilter();
342
  foreach ($tagCollection as $tag) {
343
  $this->_tags[] = $tag->getName();
34
  * @package Nosto_Tagging
35
  * @author Nosto Solutions Ltd <magento@nosto.com>
36
  */
37
+ class Nosto_Tagging_Model_Meta_Product extends Mage_Core_Model_Abstract implements NostoProductInterface, NostoValidatableModelInterface
38
  {
39
  /**
40
  * Product "in stock" tagging string.
130
  }
131
 
132
  /**
133
+ * @inheritdoc
 
 
134
  */
135
+ public function getValidationRules()
136
  {
137
+ return array(
138
+ array(
139
+ array(
140
+ '_url',
141
+ '_productId',
142
+ '_name',
143
+ '_imageUrl',
144
+ '_price',
145
+ '_listPrice',
146
+ '_currencyCode',
147
+ '_availability'
148
+ ),
149
+ 'required'
150
+ )
151
+ );
152
  }
153
 
154
  /**
155
+ * Returns the absolute url to the product page in the shop frontend.
156
  *
157
+ * @return string the url.
158
  */
159
+ public function getUrl()
160
  {
161
+ return $this->_url;
162
  }
163
 
164
  /**
172
  }
173
 
174
  /**
175
+ * Setter for the product's unique identifier.
176
  *
177
  * @param int|string $productId the ID.
178
  */
305
  * Loads the product info from a Magento product model.
306
  *
307
  * @param Mage_Catalog_Model_Product $product the product model.
308
+ * @param Mage_Core_Model_Store|null $store the store to get the product data for.
309
  */
310
+ public function loadData(Mage_Catalog_Model_Product $product, Mage_Core_Model_Store $store = null)
311
  {
312
+ if (is_null($store)) {
313
+ $store = Mage::app()->getStore();
314
+ }
315
+
316
+ // Unset the cached url first, as it won't include the `___store` param
317
+ // if it's cached. We need to define the specific store view in the url
318
+ // in case the same domain is used for all sites.
319
  $this->_url = $product
320
  ->unsetData('url')
321
+ ->getUrlInStore(
322
+ array(
323
+ '_nosid' => true,
324
+ '_ignore_category' => true,
325
+ '_store' => $store->getCode(),
326
+ )
327
+ );
328
 
329
  $this->_productId = $product->getId();
330
  $this->_name = $product->getName();
331
 
332
+ $image = $product->getImage();
333
+ if (!empty($image) && $image !== 'no_selection') {
334
+ // We build the image url manually in order get the correct base url,
335
+ // even if this product is populated in the backend.
336
+ $baseUrl = rtrim($store->getBaseUrl('media'), '/');
337
+ $file = str_replace(DS, '/', $image);
338
+ $file = ltrim($file, '/');
339
+ $this->_imageUrl = $baseUrl.'/catalog/product/'.$file;
340
  }
341
 
342
  $this->_price = Mage::helper('tax')->getPrice(
349
  Mage::helper('nosto_tagging/price')->getProductPrice($product),
350
  true
351
  );
352
+ $this->_currencyCode = $store->getCurrentCurrencyCode();
 
 
353
  $this->_availability = $product->isAvailable()
354
  ? self::PRODUCT_IN_STOCK
355
  : self::PRODUCT_OUT_OF_STOCK;
361
  ->addStatusFilter(Mage_Tag_Model_Tag::STATUS_APPROVED)
362
  ->addProductFilter($product->getId())
363
  ->setFlag('relation', true)
364
+ ->addStoreFilter($store->getId())
365
  ->setActiveFilter();
366
  foreach ($tagCollection as $tag) {
367
  $this->_tags[] = $tag->getName();
app/code/community/Nosto/Tagging/Model/Observer.php CHANGED
@@ -64,36 +64,91 @@ class Nosto_Tagging_Model_Observer
64
 
65
  /**
66
  * Event handler for the "catalog_product_save_after" event.
67
- * Sends a product re-crawl API call to Nosto.
68
  *
69
  * @param Varien_Event_Observer $observer the event observer.
70
  *
71
  * @return Nosto_Tagging_Model_Observer
72
  */
73
- public function recrawlProduct(Varien_Event_Observer $observer)
74
  {
75
  if (Mage::helper('nosto_tagging')->isModuleEnabled()) {
76
- try {
77
- /** @var Mage_Catalog_Model_Product $product */
78
- $product = $observer->getEvent()->getProduct();
79
- /** @var Mage_Core_Model_Store $store */
80
- foreach (Mage::app()->getStores() as $store) {
81
- /** @var NostoAccount $account */
82
- $account = Mage::helper('nosto_tagging/account')
83
- ->find($store);
84
- if ($account === null || !$account->isConnectedToNosto()) {
85
- continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  }
87
- $model = new Nosto_Tagging_Model_Meta_Product();
88
- $model->setProductId($product->getId());
89
- $model->setUrl(
90
- $product->unsetData('url')
91
- ->getUrlInStore(array('_store' => $store->getCode()))
92
- );
93
- NostoProductReCrawl::send($model, $account);
94
  }
95
- } catch (NostoException $e) {
96
- Mage::log("\n" . $e->__toString(), Zend_Log::ERR, 'nostotagging.log');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  }
98
  }
99
 
64
 
65
  /**
66
  * Event handler for the "catalog_product_save_after" event.
67
+ * Sends a product update API call to Nosto.
68
  *
69
  * @param Varien_Event_Observer $observer the event observer.
70
  *
71
  * @return Nosto_Tagging_Model_Observer
72
  */
73
+ public function sendProductUpdate(Varien_Event_Observer $observer)
74
  {
75
  if (Mage::helper('nosto_tagging')->isModuleEnabled()) {
76
+ /** @var Mage_Catalog_Model_Product $product */
77
+ $product = $observer->getEvent()->getProduct();
78
+ $validator = new NostoModelValidator();
79
+ /** @var Mage_Core_Model_Store $store */
80
+ foreach (Mage::app()->getStores() as $store) {
81
+ /** @var NostoAccount $account */
82
+ $account = Mage::helper('nosto_tagging/account')
83
+ ->find($store);
84
+ if ($account === null || !$account->isConnectedToNosto()) {
85
+ continue;
86
+ }
87
+
88
+ // Load the product model for this particular store view.
89
+ $product = Mage::getModel('catalog/product')
90
+ ->setStoreId($store->getId())
91
+ ->load($product->getId());
92
+ if (is_null($product)) {
93
+ continue;
94
+ }
95
+ if (!$product->isVisibleInSiteVisibility()) {
96
+ continue;
97
+ }
98
+
99
+ $model = new Nosto_Tagging_Model_Meta_Product();
100
+ $model->loadData($product, $store);
101
+
102
+ // Only send product update if we have all required
103
+ // data for the product model.
104
+ if ($validator->validate($model)) {
105
+ try {
106
+ $op = new NostoOperationProduct($account);
107
+ $op->addProduct($model);
108
+ $op->update();
109
+ } catch (NostoException $e) {
110
+ Mage::log("\n" . $e, Zend_Log::ERR, 'nostotagging.log');
111
  }
 
 
 
 
 
 
 
112
  }
113
+ }
114
+ }
115
+
116
+ return $this;
117
+ }
118
+
119
+ /**
120
+ * Event handler for the "catalog_product_delete_after" event.
121
+ * Sends a product delete API call to Nosto.
122
+ *
123
+ * @param Varien_Event_Observer $observer the event observer.
124
+ *
125
+ * @return Nosto_Tagging_Model_Observer
126
+ */
127
+ public function sendProductDelete(Varien_Event_Observer $observer)
128
+ {
129
+ if (Mage::helper('nosto_tagging')->isModuleEnabled()) {
130
+ /** @var Mage_Catalog_Model_Product $product */
131
+ $product = $observer->getEvent()->getProduct();
132
+ /** @var Mage_Core_Model_Store $store */
133
+ foreach (Mage::app()->getStores() as $store) {
134
+ /** @var NostoAccount $account */
135
+ $account = Mage::helper('nosto_tagging/account')
136
+ ->find($store);
137
+
138
+ if ($account === null || !$account->isConnectedToNosto()) {
139
+ continue;
140
+ }
141
+
142
+ $model = new Nosto_Tagging_Model_Meta_Product();
143
+ $model->setProductId($product->getId());
144
+
145
+ try {
146
+ $op = new NostoOperationProduct($account);
147
+ $op->addProduct($model);
148
+ $op->delete();
149
+ } catch (NostoException $e) {
150
+ Mage::log("\n" . $e, Zend_Log::ERR, 'nostotagging.log');
151
+ }
152
  }
153
  }
154
 
app/code/community/Nosto/Tagging/controllers/Adminhtml/NostoController.php CHANGED
@@ -98,22 +98,25 @@ class Nosto_Tagging_Adminhtml_NostoController extends Mage_Adminhtml_Controller_
98
  */
99
  public function connectAccountAction()
100
  {
 
 
101
  $store = $this->getSelectedStore();
102
  if ($this->getRequest()->isPost() && $store !== null) {
103
  $client = new NostoOAuthClient(
104
  Mage::helper('nosto_tagging/oauth')->getMetaData($store)
105
  );
106
- $response = new NostoXhrResponse();
107
- $response->setSuccess(true)
108
- ->setRedirectUrl($client->getAuthorizationUrl());
 
109
  }
110
 
111
- if (!isset($response)) {
112
  /** @var Nosto_Tagging_Helper_Account $accountHelper */
113
  $accountHelper = Mage::helper('nosto_tagging/account');
114
- $response = new NostoXhrResponse();
115
- $response->setRedirectUrl(
116
- $accountHelper->getIframeUrl(
117
  $store,
118
  null, // connect attempt failed, so we have no account.
119
  array(
@@ -124,7 +127,7 @@ class Nosto_Tagging_Adminhtml_NostoController extends Mage_Adminhtml_Controller_
124
  );
125
  }
126
 
127
- $this->sendXhrResponse($response);
128
  }
129
 
130
  /**
@@ -132,6 +135,8 @@ class Nosto_Tagging_Adminhtml_NostoController extends Mage_Adminhtml_Controller_
132
  */
133
  public function createAccountAction()
134
  {
 
 
135
  /** @var Nosto_Tagging_Helper_Account $accountHelper */
136
  $accountHelper = Mage::helper('nosto_tagging/account');
137
 
@@ -145,9 +150,9 @@ class Nosto_Tagging_Adminhtml_NostoController extends Mage_Adminhtml_Controller_
145
  }
146
  $account = NostoAccount::create($meta);
147
  if ($accountHelper->save($account, $store)) {
148
- $response = new NostoXhrResponse();
149
- $response->setSuccess(true)->setRedirectUrl(
150
- $accountHelper->getIframeUrl(
151
  $store,
152
  $account,
153
  array(
@@ -164,10 +169,10 @@ class Nosto_Tagging_Adminhtml_NostoController extends Mage_Adminhtml_Controller_
164
  }
165
  }
166
 
167
- if (!isset($response)) {
168
- $response = new NostoXhrResponse();
169
- $response->setRedirectUrl(
170
- $accountHelper->getIframeUrl(
171
  $store,
172
  null, // account creation failed, so we have none.
173
  array(
@@ -178,7 +183,7 @@ class Nosto_Tagging_Adminhtml_NostoController extends Mage_Adminhtml_Controller_
178
  );
179
  }
180
 
181
- $this->sendXhrResponse($response);
182
  }
183
 
184
  /**
@@ -186,6 +191,8 @@ class Nosto_Tagging_Adminhtml_NostoController extends Mage_Adminhtml_Controller_
186
  */
187
  public function removeAccountAction()
188
  {
 
 
189
  /** @var Nosto_Tagging_Helper_Account $accountHelper */
190
  $accountHelper = Mage::helper('nosto_tagging/account');
191
 
@@ -193,9 +200,9 @@ class Nosto_Tagging_Adminhtml_NostoController extends Mage_Adminhtml_Controller_
193
  if ($this->getRequest()->isPost() && $store !== null) {
194
  $account = $accountHelper->find($store);
195
  if ($account !== null && $accountHelper->remove($account, $store)) {
196
- $response = new NostoXhrResponse();
197
- $response->setSuccess(true)->setRedirectUrl(
198
- $accountHelper->getIframeUrl(
199
  $store,
200
  null, // we don't have an account anymore
201
  array(
@@ -207,10 +214,10 @@ class Nosto_Tagging_Adminhtml_NostoController extends Mage_Adminhtml_Controller_
207
  }
208
  }
209
 
210
- if (!isset($response)) {
211
- $response = new NostoXhrResponse();
212
- $response->setRedirectUrl(
213
- $accountHelper->getIframeUrl(
214
  $store,
215
  $accountHelper->find($store),
216
  array(
@@ -221,7 +228,7 @@ class Nosto_Tagging_Adminhtml_NostoController extends Mage_Adminhtml_Controller_
221
  );
222
  }
223
 
224
- $this->sendXhrResponse($response);
225
  }
226
 
227
  /**
@@ -242,15 +249,4 @@ class Nosto_Tagging_Adminhtml_NostoController extends Mage_Adminhtml_Controller_
242
  return null;
243
  }
244
  }
245
-
246
- /**
247
- * Sends an XHR response to the browser.
248
- *
249
- * @param NostoXhrResponse $response the response object.
250
- */
251
- protected function sendXhrResponse(NostoXhrResponse $response)
252
- {
253
- $this->getResponse()->setHeader('Content-type', $response->contentType);
254
- $this->getResponse()->setBody($response->__toString());
255
- }
256
  }
98
  */
99
  public function connectAccountAction()
100
  {
101
+ $this->getResponse()->setHeader('Content-type', 'application/json');
102
+
103
  $store = $this->getSelectedStore();
104
  if ($this->getRequest()->isPost() && $store !== null) {
105
  $client = new NostoOAuthClient(
106
  Mage::helper('nosto_tagging/oauth')->getMetaData($store)
107
  );
108
+ $responseBody = array(
109
+ 'success' => true,
110
+ 'redirect_url' => $client->getAuthorizationUrl(),
111
+ );
112
  }
113
 
114
+ if (!isset($responseBody)) {
115
  /** @var Nosto_Tagging_Helper_Account $accountHelper */
116
  $accountHelper = Mage::helper('nosto_tagging/account');
117
+ $responseBody = array(
118
+ 'success' => false,
119
+ 'redirect_url' => $accountHelper->getIframeUrl(
120
  $store,
121
  null, // connect attempt failed, so we have no account.
122
  array(
127
  );
128
  }
129
 
130
+ $this->getResponse()->setBody(json_encode($responseBody));
131
  }
132
 
133
  /**
135
  */
136
  public function createAccountAction()
137
  {
138
+ $this->getResponse()->setHeader('Content-type', 'application/json');
139
+
140
  /** @var Nosto_Tagging_Helper_Account $accountHelper */
141
  $accountHelper = Mage::helper('nosto_tagging/account');
142
 
150
  }
151
  $account = NostoAccount::create($meta);
152
  if ($accountHelper->save($account, $store)) {
153
+ $responseBody = array(
154
+ 'success' => true,
155
+ 'redirect_url' => $accountHelper->getIframeUrl(
156
  $store,
157
  $account,
158
  array(
169
  }
170
  }
171
 
172
+ if (!isset($responseBody)) {
173
+ $responseBody = array(
174
+ 'success' => false,
175
+ 'redirect_url' => $accountHelper->getIframeUrl(
176
  $store,
177
  null, // account creation failed, so we have none.
178
  array(
183
  );
184
  }
185
 
186
+ $this->getResponse()->setBody(json_encode($responseBody));
187
  }
188
 
189
  /**
191
  */
192
  public function removeAccountAction()
193
  {
194
+ $this->getResponse()->setHeader('Content-type', 'application/json');
195
+
196
  /** @var Nosto_Tagging_Helper_Account $accountHelper */
197
  $accountHelper = Mage::helper('nosto_tagging/account');
198
 
200
  if ($this->getRequest()->isPost() && $store !== null) {
201
  $account = $accountHelper->find($store);
202
  if ($account !== null && $accountHelper->remove($account, $store)) {
203
+ $responseBody = array(
204
+ 'success' => true,
205
+ 'redirect_url' => $accountHelper->getIframeUrl(
206
  $store,
207
  null, // we don't have an account anymore
208
  array(
214
  }
215
  }
216
 
217
+ if (!isset($responseBody)) {
218
+ $responseBody = array(
219
+ 'success' => false,
220
+ 'redirect_url' => $accountHelper->getIframeUrl(
221
  $store,
222
  $accountHelper->find($store),
223
  array(
228
  );
229
  }
230
 
231
+ $this->getResponse()->setBody(json_encode($responseBody));
232
  }
233
 
234
  /**
249
  return null;
250
  }
251
  }
 
 
 
 
 
 
 
 
 
 
 
252
  }
app/code/community/Nosto/Tagging/controllers/ExportController.php CHANGED
@@ -97,6 +97,7 @@ class Nosto_tagging_ExportController extends Mage_Core_Controller_Front_Action
97
  if ($currentPage > $products->getLastPageNumber()) {
98
  $products = array();
99
  }
 
100
  $collection = new NostoExportProductCollection();
101
  foreach ($products as $product) {
102
  if ($product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
@@ -106,7 +107,9 @@ class Nosto_tagging_ExportController extends Mage_Core_Controller_Front_Action
106
  }
107
  $meta = new Nosto_Tagging_Model_Meta_Product();
108
  $meta->loadData($product);
109
- $collection[] = $meta;
 
 
110
  }
111
  $this->export($collection);
112
  }
@@ -115,9 +118,9 @@ class Nosto_tagging_ExportController extends Mage_Core_Controller_Front_Action
115
  /**
116
  * Encrypts the export collection and outputs it to the browser.
117
  *
118
- * @param NostoExportCollection $collection the data collection to export.
119
  */
120
- protected function export(NostoExportCollection $collection)
121
  {
122
  $account = Mage::helper('nosto_tagging/account')->find();
123
  if ($account !== null) {
97
  if ($currentPage > $products->getLastPageNumber()) {
98
  $products = array();
99
  }
100
+ $validator = new NostoModelValidator();
101
  $collection = new NostoExportProductCollection();
102
  foreach ($products as $product) {
103
  if ($product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
107
  }
108
  $meta = new Nosto_Tagging_Model_Meta_Product();
109
  $meta->loadData($product);
110
+ if ($validator->validate($meta)) {
111
+ $collection[] = $meta;
112
+ }
113
  }
114
  $this->export($collection);
115
  }
118
  /**
119
  * Encrypts the export collection and outputs it to the browser.
120
  *
121
+ * @param NostoExportCollectionInterface $collection the data collection to export.
122
  */
123
+ protected function export(NostoExportCollectionInterface $collection)
124
  {
125
  $account = Mage::helper('nosto_tagging/account')->find();
126
  if ($account !== null) {
app/code/community/Nosto/Tagging/etc/config.xml CHANGED
@@ -29,7 +29,7 @@
29
  <config>
30
  <modules>
31
  <Nosto_Tagging>
32
- <version>2.2.1</version>
33
  </Nosto_Tagging>
34
  </modules>
35
  <global>
@@ -71,7 +71,7 @@
71
  <nosto_tagging_catalog_product_save_after>
72
  <type>singleton</type>
73
  <class>Nosto_Tagging_Model_Observer</class>
74
- <method>recrawlProduct</method>
75
  </nosto_tagging_catalog_product_save_after>
76
  </observers>
77
  </catalog_product_save_after>
@@ -80,7 +80,7 @@
80
  <nosto_tagging_catalog_product_delete_after>
81
  <type>singleton</type>
82
  <class>Nosto_Tagging_Model_Observer</class>
83
- <method>recrawlProduct</method>
84
  </nosto_tagging_catalog_product_delete_after>
85
  </observers>
86
  </catalog_product_delete_after>
29
  <config>
30
  <modules>
31
  <Nosto_Tagging>
32
+ <version>2.4.0</version>
33
  </Nosto_Tagging>
34
  </modules>
35
  <global>
71
  <nosto_tagging_catalog_product_save_after>
72
  <type>singleton</type>
73
  <class>Nosto_Tagging_Model_Observer</class>
74
+ <method>sendProductUpdate</method>
75
  </nosto_tagging_catalog_product_save_after>
76
  </observers>
77
  </catalog_product_save_after>
80
  <nosto_tagging_catalog_product_delete_after>
81
  <type>singleton</type>
82
  <class>Nosto_Tagging_Model_Observer</class>
83
+ <method>sendProductDelete</method>
84
  </nosto_tagging_catalog_product_delete_after>
85
  </observers>
86
  </catalog_product_delete_after>
app/design/frontend/base/default/layout/nostotagging.xml CHANGED
@@ -43,6 +43,11 @@
43
  <block type="nosto_tagging/embed" name="nosto.embed" template="nostotagging/embed.phtml"/>
44
  </reference>
45
 
 
 
 
 
 
46
  <!-- Tag shopping cart -->
47
  <reference name="after_body_start">
48
  <block type="nosto_tagging/cart" name="nosto.cart" template="nostotagging/cart.phtml"/>
43
  <block type="nosto_tagging/embed" name="nosto.embed" template="nostotagging/embed.phtml"/>
44
  </reference>
45
 
46
+ <!-- Adds Nosto `add-to-cart` script to head -->
47
+ <reference name="head">
48
+ <block type="nosto_tagging/addtocart" name="nosto.addtocart" template="nostotagging/addtocart.phtml"/>
49
+ </reference>
50
+
51
  <!-- Tag shopping cart -->
52
  <reference name="after_body_start">
53
  <block type="nosto_tagging/cart" name="nosto.cart" template="nostotagging/cart.phtml"/>
app/design/frontend/base/default/template/nostotagging/addtocart.phtml ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category design
22
+ * @package frontend_base_default
23
+ * @author Nosto Solutions Ltd <magento@nosto.com>
24
+ * @copyright Copyright (c) 2013-2015 Nosto Solutions Ltd (http://www.nosto.com)
25
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
+ */
27
+ ?>
28
+
29
+ <?php
30
+ $formAction = Mage::getUrl('checkout/cart/add');
31
+ $formKey = Mage::getSingleton('core/session')->getFormKey();
32
+ ?>
33
+ <!-- Nosto `add-to-cart` Script -->
34
+ <script type="text/javascript">
35
+ if (typeof Nosto === "undefined") {
36
+ var Nosto = {};
37
+ }
38
+ Nosto.addProductToCart = function (productId) {
39
+ var form = document.createElement("form");
40
+ form.setAttribute("method", "post");
41
+ form.setAttribute("action", "<?php echo $formAction; ?>");
42
+
43
+ var hiddenFields = {
44
+ "product": productId,
45
+ "form_key": "<?php echo $formKey; ?>"
46
+ };
47
+
48
+ for(var key in hiddenFields) {
49
+ if(hiddenFields.hasOwnProperty(key)) {
50
+ var hiddenField = document.createElement("input");
51
+ hiddenField.setAttribute("type", "hidden");
52
+ hiddenField.setAttribute("name", key);
53
+ hiddenField.setAttribute("value", hiddenFields[key]);
54
+ form.appendChild(hiddenField);
55
+ }
56
+ }
57
+
58
+ document.body.appendChild(form);
59
+ form.submit();
60
+ };
61
+ </script>
lib/nosto/php-sdk/src/classes/Nosto.php CHANGED
@@ -105,6 +105,23 @@ class Nosto
105
  self::$registry[$key] = $value;
106
  }
107
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  /**
109
  * Converts a helper class name reference name to a real class name.
110
  *
105
  self::$registry[$key] = $value;
106
  }
107
 
108
+ /**
109
+ * Throws a new NostoHttpException exception with info about both the
110
+ * request and response.
111
+ *
112
+ * @param string $message the error message.
113
+ * @param NostoHttpRequest $request the request object to take additional info from.
114
+ * @param NostoHttpResponse $response the response object to take additional info from.
115
+ * @throws NostoHttpException the exception.
116
+ */
117
+ public static function throwHttpException($message, NostoHttpRequest $request, NostoHttpResponse $response)
118
+ {
119
+ $message .= sprintf(' Error: %s.', $response->getCode());
120
+ $message .= sprintf(' Request: %s.', $request);
121
+ $message .= sprintf(' Response: %s.', $response);
122
+ throw new NostoHttpException($message, $response->getCode());
123
+ }
124
+
125
  /**
126
  * Converts a helper class name reference name to a real class name.
127
  *
lib/nosto/php-sdk/src/classes/NostoAccount.php CHANGED
@@ -83,7 +83,7 @@ class NostoAccount implements NostoAccountInterface
83
  $response = $request->post(json_encode($params));
84
 
85
  if ($response->getCode() !== 200) {
86
- throw new NostoException('Nosto account could not be created', $response->getCode());
87
  }
88
 
89
  $account = new self;
@@ -116,7 +116,7 @@ class NostoAccount implements NostoAccountInterface
116
  $result = $response->getJsonResult(true);
117
 
118
  if ($response->getCode() !== 200) {
119
- throw new NostoException('Failed to sync account from Nosto', $response->getCode());
120
  }
121
  if (empty($result)) {
122
  throw new NostoException('Received invalid data from Nosto when trying to sync account');
@@ -147,7 +147,7 @@ class NostoAccount implements NostoAccountInterface
147
  $response = $request->post('');
148
 
149
  if ($response->getCode() !== 200) {
150
- throw new NostoException('Failed to notify Nosto about deleted account', $response->getCode());
151
  }
152
  }
153
 
@@ -227,7 +227,7 @@ class NostoAccount implements NostoAccountInterface
227
  $result = $response->getJsonResult();
228
 
229
  if ($response->getCode() !== 200) {
230
- throw new NostoException('Unable to login employee to Nosto with SSO token', $response->getCode());
231
  }
232
  if (empty($result->login_url)) {
233
  throw new NostoException('No "login_url" returned when logging in employee to Nosto');
83
  $response = $request->post(json_encode($params));
84
 
85
  if ($response->getCode() !== 200) {
86
+ Nosto::throwHttpException('Nosto account could not be created.', $request, $response);
87
  }
88
 
89
  $account = new self;
116
  $result = $response->getJsonResult(true);
117
 
118
  if ($response->getCode() !== 200) {
119
+ Nosto::throwHttpException('Failed to sync account from Nosto.', $request, $response);
120
  }
121
  if (empty($result)) {
122
  throw new NostoException('Received invalid data from Nosto when trying to sync account');
147
  $response = $request->post('');
148
 
149
  if ($response->getCode() !== 200) {
150
+ Nosto::throwHttpException('Failed to notify Nosto about deleted account.', $request, $response);
151
  }
152
  }
153
 
227
  $result = $response->getJsonResult();
228
 
229
  if ($response->getCode() !== 200) {
230
+ Nosto::throwHttpException('Unable to login employee to Nosto with SSO token.', $request, $response);
231
  }
232
  if (empty($result->login_url)) {
233
  throw new NostoException('No "login_url" returned when logging in employee to Nosto');
lib/nosto/php-sdk/src/classes/NostoModelValidator.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2015, Nosto Solutions Ltd
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without modification,
7
+ * are permitted provided that the following conditions are met:
8
+ *
9
+ * 1. Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ *
12
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ * this list of conditions and the following disclaimer in the documentation
14
+ * and/or other materials provided with the distribution.
15
+ *
16
+ * 3. Neither the name of the copyright holder nor the names of its contributors
17
+ * may be used to endorse or promote products derived from this software without
18
+ * specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
24
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ *
31
+ * @author Nosto Solutions Ltd <contact@nosto.com>
32
+ * @copyright 2015 Nosto Solutions Ltd
33
+ * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause
34
+ */
35
+
36
+ /**
37
+ * Model validator util that is used to validate `validatable` models.
38
+ */
39
+ class NostoModelValidator
40
+ {
41
+ /**
42
+ * Validates the `validatable` model based opn it's validation rules.
43
+ *
44
+ * @param NostoValidatableModelInterface $model the model to validate.
45
+ * @return bool true if the model is valid, false otherwise.
46
+ * @throws NostoException if the rule validator is not found.
47
+ */
48
+ public function validate(NostoValidatableModelInterface $model)
49
+ {
50
+ foreach ($model->getValidationRules() as $rule) {
51
+ if (isset($rule[0], $rule[1])) {
52
+ $properties = $rule[0];
53
+ $validator = 'validate'.$rule[1];
54
+ if (!method_exists($this, $validator)) {
55
+ throw new NostoException(sprintf('Nosto validator "%s" does not exist.', $validator));
56
+ }
57
+ $isValid = call_user_func(array($this, $validator), $model, $properties);
58
+ if (!$isValid) {
59
+ return false;
60
+ }
61
+ }
62
+ }
63
+ return true;
64
+ }
65
+
66
+ /**
67
+ * Validates that all the given properties are NOT empty in this instance.
68
+ *
69
+ * @param NostoValidatableModelInterface $model the model to validate the properties on.
70
+ * @param array $properties the list of property names to validate.
71
+ * @return bool true if all are valid, false otherwise.
72
+ */
73
+ protected function validateRequired(NostoValidatableModelInterface $model, array $properties)
74
+ {
75
+ foreach ($properties as $property) {
76
+ // Prefer property getter if available.
77
+ // Strip any "_" character at beginning of property name.
78
+ $getter = 'get'.trim($property, '_');
79
+ if (method_exists($model, $getter)) {
80
+ $value = $model->{$getter}();
81
+ if (empty($value)) {
82
+ return false;
83
+ }
84
+ } elseif (empty($model->{$property})) {
85
+ return false;
86
+ }
87
+ }
88
+ return true;
89
+ }
90
+ }
lib/nosto/php-sdk/src/classes/NostoOrderConfirmation.php CHANGED
@@ -69,6 +69,8 @@ class NostoOrderConfirmation
69
 
70
  $orderData = array(
71
  'order_number' => $order->getOrderNumber(),
 
 
72
  'buyer' => array(
73
  'first_name' => $order->getBuyerInfo()->getFirstName(),
74
  'last_name' => $order->getBuyerInfo()->getLastName(),
@@ -89,7 +91,7 @@ class NostoOrderConfirmation
89
  }
90
  $response = $request->post(json_encode($orderData));
91
  if ($response->getCode() !== 200) {
92
- throw new NostoException('Failed to send order confirmation to Nosto');
93
  }
94
  return true;
95
  }
69
 
70
  $orderData = array(
71
  'order_number' => $order->getOrderNumber(),
72
+ 'order_status_code' => $order->getOrderStatus()->getCode(),
73
+ 'order_status_label' => $order->getOrderStatus()->getLabel(),
74
  'buyer' => array(
75
  'first_name' => $order->getBuyerInfo()->getFirstName(),
76
  'last_name' => $order->getBuyerInfo()->getLastName(),
91
  }
92
  $response = $request->post(json_encode($orderData));
93
  if ($response->getCode() !== 200) {
94
+ Nosto::throwHttpException('Failed to send order confirmation to Nosto.', $request, $response);
95
  }
96
  return true;
97
  }
lib/nosto/php-sdk/src/classes/NostoProductReCrawl.php CHANGED
@@ -69,7 +69,7 @@ class NostoProductReCrawl
69
  public static function sendBatch(NostoExportProductCollection $collection, NostoAccountInterface $account)
70
  {
71
  if ($collection->count() === 0) {
72
- throw new NostoException('Failed to send product re-crawl to Nosto. No products in collection (Error 400).', 400);
73
  }
74
  $payload = array(
75
  'products' => array()
@@ -96,7 +96,7 @@ class NostoProductReCrawl
96
  {
97
  $token = $account->getApiToken('products');
98
  if ($token === null) {
99
- throw new NostoException('Failed to send product re-crawl to Nosto. No `products` API token found for account (Error 400).', 400);
100
  }
101
  $request = new NostoApiRequest();
102
  $request->setPath(NostoApiRequest::PATH_PRODUCT_RE_CRAWL);
@@ -104,7 +104,7 @@ class NostoProductReCrawl
104
  $request->setAuthBasic('', $token->value);
105
  $response = $request->post(json_encode($payload));
106
  if ($response->getCode() !== 200) {
107
- throw new NostoException('Failed to send product re-crawl to Nosto (Error '.$response->getCode().').', $response->getCode());
108
  }
109
  return true;
110
  }
69
  public static function sendBatch(NostoExportProductCollection $collection, NostoAccountInterface $account)
70
  {
71
  if ($collection->count() === 0) {
72
+ throw new NostoException('Failed to send product re-crawl to Nosto. No products in collection.');
73
  }
74
  $payload = array(
75
  'products' => array()
96
  {
97
  $token = $account->getApiToken('products');
98
  if ($token === null) {
99
+ throw new NostoException('Failed to send product re-crawl to Nosto. No `products` API token found for account.');
100
  }
101
  $request = new NostoApiRequest();
102
  $request->setPath(NostoApiRequest::PATH_PRODUCT_RE_CRAWL);
104
  $request->setAuthBasic('', $token->value);
105
  $response = $request->post(json_encode($payload));
106
  if ($response->getCode() !== 200) {
107
+ Nosto::throwHttpException('Failed to send product re-crawl to Nosto.', $request, $response);
108
  }
109
  return true;
110
  }
lib/nosto/php-sdk/src/classes/api/NostoApiRequest.php CHANGED
@@ -43,6 +43,8 @@ class NostoApiRequest extends NostoHttpRequest
43
  const PATH_SIGN_UP = '/accounts/create/{lang}';
44
  const PATH_SSO_AUTH = '/users/sso/{email}';
45
  const PATH_PRODUCT_RE_CRAWL = '/products/recrawl';
 
 
46
 
47
  /**
48
  * @var string base url for the nosto api.
43
  const PATH_SIGN_UP = '/accounts/create/{lang}';
44
  const PATH_SSO_AUTH = '/users/sso/{email}';
45
  const PATH_PRODUCT_RE_CRAWL = '/products/recrawl';
46
+ const PATH_PRODUCTS_UPSERT = '/v1/products/upsert';
47
+ const PATH_PRODUCTS_DISCONTINUE = '/v1/products/discontinue';
48
 
49
  /**
50
  * @var string base url for the nosto api.
lib/nosto/php-sdk/src/classes/{export/NostoExportCollection.php → collection/NostoCollection.php} RENAMED
@@ -34,25 +34,17 @@
34
  */
35
 
36
  /**
37
- * Base class for all export collection classes used for exporting historical data from the shop.
38
  * The base class provides the functionality to validate the items added to the collection.
39
  * The collection behaves like an array. making it easy to add items to it and iterate over it.
40
  */
41
- abstract class NostoExportCollection extends ArrayObject
42
  {
43
  /**
44
  * @var string the type of items this collection can contain.
45
  */
46
  protected $validItemType = '';
47
 
48
- /**
49
- * Returns the collection as a JSON string.
50
- * In the JSON camel case variables are converted into underscore format.
51
- *
52
- * @return string the JSON.
53
- */
54
- abstract public function getJson();
55
-
56
  /**
57
  * @inheritdoc
58
  */
@@ -74,7 +66,7 @@ abstract class NostoExportCollection extends ArrayObject
74
  /**
75
  * Validates that the given value is of correct type.
76
  *
77
- * @see NostoExportCollection::$validItemType
78
  * @param mixed $value the value.
79
  * @throws NostoException if the value is of invalid type.
80
  */
34
  */
35
 
36
  /**
37
+ * Base class for all Nosto object collection classes.
38
  * The base class provides the functionality to validate the items added to the collection.
39
  * The collection behaves like an array. making it easy to add items to it and iterate over it.
40
  */
41
+ abstract class NostoCollection extends ArrayObject
42
  {
43
  /**
44
  * @var string the type of items this collection can contain.
45
  */
46
  protected $validItemType = '';
47
 
 
 
 
 
 
 
 
 
48
  /**
49
  * @inheritdoc
50
  */
66
  /**
67
  * Validates that the given value is of correct type.
68
  *
69
+ * @see NostoCollection::$validItemType
70
  * @param mixed $value the value.
71
  * @throws NostoException if the value is of invalid type.
72
  */
lib/nosto/php-sdk/src/classes/collection/NostoOrderCollection.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2015, Nosto Solutions Ltd
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without modification,
7
+ * are permitted provided that the following conditions are met:
8
+ *
9
+ * 1. Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ *
12
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ * this list of conditions and the following disclaimer in the documentation
14
+ * and/or other materials provided with the distribution.
15
+ *
16
+ * 3. Neither the name of the copyright holder nor the names of its contributors
17
+ * may be used to endorse or promote products derived from this software without
18
+ * specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
24
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ *
31
+ * @author Nosto Solutions Ltd <contact@nosto.com>
32
+ * @copyright 2015 Nosto Solutions Ltd
33
+ * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause
34
+ */
35
+
36
+ /**
37
+ * Order object collection.
38
+ * Supports only items implementing "NostoOrderInterface".
39
+ */
40
+ class NostoOrderCollection extends NostoCollection
41
+ {
42
+ /**
43
+ * @inheritdoc
44
+ */
45
+ protected $validItemType = 'NostoOrderInterface';
46
+ }
lib/nosto/php-sdk/src/classes/collection/NostoProductCollection.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2015, Nosto Solutions Ltd
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without modification,
7
+ * are permitted provided that the following conditions are met:
8
+ *
9
+ * 1. Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ *
12
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ * this list of conditions and the following disclaimer in the documentation
14
+ * and/or other materials provided with the distribution.
15
+ *
16
+ * 3. Neither the name of the copyright holder nor the names of its contributors
17
+ * may be used to endorse or promote products derived from this software without
18
+ * specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
24
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ *
31
+ * @author Nosto Solutions Ltd <contact@nosto.com>
32
+ * @copyright 2015 Nosto Solutions Ltd
33
+ * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause
34
+ */
35
+
36
+ /**
37
+ * Product object collection.
38
+ * Supports only items implementing "NostoProductInterface".
39
+ */
40
+ class NostoProductCollection extends NostoCollection
41
+ {
42
+ /**
43
+ * @inheritdoc
44
+ */
45
+ protected $validItemType = 'NostoProductInterface';
46
+ }
lib/nosto/php-sdk/src/classes/{NostoException.php → exception/NostoException.php} RENAMED
File without changes
lib/nosto/php-sdk/src/classes/exception/NostoHttpException.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2015, Nosto Solutions Ltd
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without modification,
7
+ * are permitted provided that the following conditions are met:
8
+ *
9
+ * 1. Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ *
12
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ * this list of conditions and the following disclaimer in the documentation
14
+ * and/or other materials provided with the distribution.
15
+ *
16
+ * 3. Neither the name of the copyright holder nor the names of its contributors
17
+ * may be used to endorse or promote products derived from this software without
18
+ * specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
24
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ *
31
+ * @author Nosto Solutions Ltd <contact@nosto.com>
32
+ * @copyright 2015 Nosto Solutions Ltd
33
+ * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause
34
+ */
35
+
36
+ /**
37
+ * Nosto exception class for http errors within the sdk.
38
+ */
39
+ class NostoHttpException extends NostoException
40
+ {
41
+ }
lib/nosto/php-sdk/src/classes/export/NostoExportOrderCollection.php CHANGED
@@ -37,13 +37,8 @@
37
  * Order collection for historical data exports.
38
  * Supports only items implementing "NostoOrderInterface".
39
  */
40
- class NostoExportOrderCollection extends NostoExportCollection
41
  {
42
- /**
43
- * @inheritdoc
44
- */
45
- protected $validItemType = 'NostoOrderInterface';
46
-
47
  /**
48
  * @inheritdoc
49
  */
@@ -54,12 +49,15 @@ class NostoExportOrderCollection extends NostoExportCollection
54
  foreach ($this->getArrayCopy() as $item) {
55
  $data = array(
56
  'order_number' => $item->getOrderNumber(),
 
 
57
  'created_at' => Nosto::helper('date')->format($item->getCreatedDate()),
58
  'buyer' => array(
59
  'first_name' => $item->getBuyerInfo()->getFirstName(),
60
  'last_name' => $item->getBuyerInfo()->getLastName(),
61
  'email' => $item->getBuyerInfo()->getEmail(),
62
  ),
 
63
  'purchased_items' => array(),
64
  );
65
  foreach ($item->getPurchasedItems() as $orderItem) {
37
  * Order collection for historical data exports.
38
  * Supports only items implementing "NostoOrderInterface".
39
  */
40
+ class NostoExportOrderCollection extends NostoOrderCollection implements NostoExportCollectionInterface
41
  {
 
 
 
 
 
42
  /**
43
  * @inheritdoc
44
  */
49
  foreach ($this->getArrayCopy() as $item) {
50
  $data = array(
51
  'order_number' => $item->getOrderNumber(),
52
+ 'order_status_code' => $item->getOrderStatus()->getCode(),
53
+ 'order_status_label' => $item->getOrderStatus()->getLabel(),
54
  'created_at' => Nosto::helper('date')->format($item->getCreatedDate()),
55
  'buyer' => array(
56
  'first_name' => $item->getBuyerInfo()->getFirstName(),
57
  'last_name' => $item->getBuyerInfo()->getLastName(),
58
  'email' => $item->getBuyerInfo()->getEmail(),
59
  ),
60
+ 'payment_provider' => $item->getPaymentProvider(),
61
  'purchased_items' => array(),
62
  );
63
  foreach ($item->getPurchasedItems() as $orderItem) {
lib/nosto/php-sdk/src/classes/export/NostoExportProductCollection.php CHANGED
@@ -37,13 +37,8 @@
37
  * Product collection for historical data exports.
38
  * Supports only items implementing "NostoProductInterface".
39
  */
40
- class NostoExportProductCollection extends NostoExportCollection
41
  {
42
- /**
43
- * @inheritdoc
44
- */
45
- protected $validItemType = 'NostoProductInterface';
46
-
47
  /**
48
  * @inheritdoc
49
  */
37
  * Product collection for historical data exports.
38
  * Supports only items implementing "NostoProductInterface".
39
  */
40
+ class NostoExportProductCollection extends NostoProductCollection implements NostoExportCollectionInterface
41
  {
 
 
 
 
 
42
  /**
43
  * @inheritdoc
44
  */
lib/nosto/php-sdk/src/classes/export/NostoExporter.php CHANGED
@@ -44,10 +44,10 @@ class NostoExporter
44
  * Encrypts and returns the data.
45
  *
46
  * @param NostoAccountInterface $account the account to export the data for.
47
- * @param NostoExportCollection $collection the data collection to export.
48
  * @return string the encrypted data.
49
  */
50
- public static function export(NostoAccountInterface $account, NostoExportCollection $collection)
51
  {
52
  $data = '';
53
  // Use the first 16 chars of the SSO token as secret for encryption.
44
  * Encrypts and returns the data.
45
  *
46
  * @param NostoAccountInterface $account the account to export the data for.
47
+ * @param NostoExportCollectionInterface $collection the data collection to export.
48
  * @return string the encrypted data.
49
  */
50
+ public static function export(NostoAccountInterface $account, NostoExportCollectionInterface $collection)
51
  {
52
  $data = '';
53
  // Use the first 16 chars of the SSO token as secret for encryption.
lib/nosto/php-sdk/src/classes/http/NostoHttpRequest.php CHANGED
@@ -58,6 +58,11 @@ class NostoHttpRequest
58
  */
59
  protected $headers = array();
60
 
 
 
 
 
 
61
  /**
62
  * @var array list of optional query params that are added to the request url.
63
  */
@@ -331,6 +336,7 @@ class NostoHttpRequest
331
  */
332
  public function post($content)
333
  {
 
334
  $url = $this->url;
335
  if (!empty($this->replaceParams)) {
336
  $url = self::buildUri($url, $this->replaceParams);
@@ -344,6 +350,28 @@ class NostoHttpRequest
344
  );
345
  }
346
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
347
  /**
348
  * Sends a GET request.
349
  *
@@ -365,4 +393,40 @@ class NostoHttpRequest
365
  )
366
  );
367
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
368
  }
58
  */
59
  protected $headers = array();
60
 
61
+ /**
62
+ * @var string the request content (populated in post() and put() methods).
63
+ */
64
+ protected $content = '';
65
+
66
  /**
67
  * @var array list of optional query params that are added to the request url.
68
  */
336
  */
337
  public function post($content)
338
  {
339
+ $this->content = $content;
340
  $url = $this->url;
341
  if (!empty($this->replaceParams)) {
342
  $url = self::buildUri($url, $this->replaceParams);
350
  );
351
  }
352
 
353
+ /**
354
+ * Sends a PUT request.
355
+ *
356
+ * @param string $content
357
+ * @return NostoHttpResponse
358
+ */
359
+ public function put($content)
360
+ {
361
+ $this->content = $content;
362
+ $url = $this->url;
363
+ if (!empty($this->replaceParams)) {
364
+ $url = self::buildUri($url, $this->replaceParams);
365
+ }
366
+ return $this->adapter->put(
367
+ $url,
368
+ array(
369
+ 'headers' => $this->headers,
370
+ 'content' => $content,
371
+ )
372
+ );
373
+ }
374
+
375
  /**
376
  * Sends a GET request.
377
  *
393
  )
394
  );
395
  }
396
+
397
+ /**
398
+ * Sends a DELETE request.
399
+ *
400
+ * @return NostoHttpResponse
401
+ */
402
+ public function delete()
403
+ {
404
+ $url = $this->url;
405
+ if (!empty($this->replaceParams)) {
406
+ $url = self::buildUri($url, $this->replaceParams);
407
+ }
408
+ return $this->adapter->delete(
409
+ $url,
410
+ array(
411
+ 'headers' => $this->headers,
412
+ )
413
+ );
414
+ }
415
+
416
+ /**
417
+ * Converts the request to a string and returns it.
418
+ * Used when logging http request errors.
419
+ */
420
+ public function __toString()
421
+ {
422
+ $url = $this->url;
423
+ if (!empty($this->replaceParams)) {
424
+ $url = self::buildUri($url, $this->replaceParams);
425
+ }
426
+ return serialize(array(
427
+ 'url' => $url,
428
+ 'headers' => $this->headers,
429
+ 'body' => $this->content,
430
+ ));
431
+ }
432
  }
lib/nosto/php-sdk/src/classes/http/NostoHttpRequestAdapter.php CHANGED
@@ -79,4 +79,22 @@ abstract class NostoHttpRequestAdapter
79
  * @return NostoHttpResponse the response object.
80
  */
81
  abstract public function post($url, array $options = array());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  }
79
  * @return NostoHttpResponse the response object.
80
  */
81
  abstract public function post($url, array $options = array());
82
+
83
+ /**
84
+ * Does a PUT request and returns the http response object.
85
+ *
86
+ * @param string $url the URL to request.
87
+ * @param array $options the request options.
88
+ * @return NostoHttpResponse the response object.
89
+ */
90
+ abstract public function put($url, array $options = array());
91
+
92
+ /**
93
+ * Does a DELETE request and returns the http response object.
94
+ *
95
+ * @param string $url the URL to request.
96
+ * @param array $options the request options.
97
+ * @return NostoHttpResponse the response object.
98
+ */
99
+ abstract public function delete($url, array $options = array());
100
  }
lib/nosto/php-sdk/src/classes/http/NostoHttpRequestAdapterCurl.php CHANGED
@@ -77,6 +77,45 @@ class NostoHttpRequestAdapterCurl extends NostoHttpRequestAdapter
77
  );
78
  }
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  /**
81
  * Sends the request and creates a NostoHttpResponse instance containing the response headers and body.
82
  *
@@ -91,20 +130,11 @@ class NostoHttpRequestAdapterCurl extends NostoHttpRequestAdapter
91
  $ch = curl_init();
92
  curl_setopt_array($ch, $curlOptions);
93
  $result = curl_exec($ch);
94
- $response = new NostoHttpResponse();
95
- if ($result !== false) {
96
- $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
97
- $header = substr($result, 0, $headerSize);
98
- $header = explode("\r\n", $header);
99
- $body = substr($result, $headerSize);
100
- if (!empty($header)) {
101
- $response->setHeaders($header);
102
- }
103
- $response->setResult($body);
104
- } else {
105
- $response->setMessage(curl_error($ch));
106
- }
107
- curl_close($ch);
108
- return $response;
109
  }
110
  }
77
  );
78
  }
79
 
80
+ /**
81
+ * @inheritdoc
82
+ */
83
+ public function put($url, array $options = array())
84
+ {
85
+ $this->init($options);
86
+ return $this->send(
87
+ array(
88
+ CURLOPT_URL => $url,
89
+ CURLOPT_POSTFIELDS => $this->content,
90
+ CURLOPT_CUSTOMREQUEST => 'PUT',
91
+ CURLOPT_HEADER => 1,
92
+ CURLOPT_FRESH_CONNECT => 1,
93
+ CURLOPT_RETURNTRANSFER => 1,
94
+ CURLOPT_FORBID_REUSE => 1,
95
+ CURLOPT_TIMEOUT => 60,
96
+ )
97
+ );
98
+ }
99
+
100
+ /**
101
+ * @inheritdoc
102
+ */
103
+ public function delete($url, array $options = array())
104
+ {
105
+ $this->init($options);
106
+ return $this->send(
107
+ array(
108
+ CURLOPT_URL => $url,
109
+ CURLOPT_CUSTOMREQUEST => 'DELETE',
110
+ CURLOPT_HEADER => 1,
111
+ CURLOPT_FRESH_CONNECT => 1,
112
+ CURLOPT_RETURNTRANSFER => 1,
113
+ CURLOPT_FORBID_REUSE => 1,
114
+ CURLOPT_TIMEOUT => 60,
115
+ )
116
+ );
117
+ }
118
+
119
  /**
120
  * Sends the request and creates a NostoHttpResponse instance containing the response headers and body.
121
  *
130
  $ch = curl_init();
131
  curl_setopt_array($ch, $curlOptions);
132
  $result = curl_exec($ch);
133
+ $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
134
+ $headers = explode("\r\n", substr($result, 0, $headerSize));
135
+ $body = substr($result, $headerSize);
136
+ $message = curl_error($ch);
137
+ curl_close($ch);
138
+ return new NostoHttpResponse($headers, $body, $message);
 
 
 
 
 
 
 
 
 
139
  }
140
  }
lib/nosto/php-sdk/src/classes/http/NostoHttpRequestAdapterSocket.php CHANGED
@@ -81,6 +81,45 @@ class NostoHttpRequestAdapterSocket extends NostoHttpRequestAdapter
81
  );
82
  }
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  /**
85
  * Sends the request and creates a NostoHttpResponse instance containing the response headers and body.
86
  *
@@ -96,11 +135,6 @@ class NostoHttpRequestAdapterSocket extends NostoHttpRequestAdapter
96
  // is executed (http://php.net/manual/en/reserved.variables.httpresponseheader.php).
97
  $http_response_header = array();
98
  $result = @file_get_contents($url, false, $context);
99
- $response = new NostoHttpResponse();
100
- if (!empty($http_response_header)) {
101
- $response->setHeaders($http_response_header);
102
- }
103
- $response->setResult($result);
104
- return $response;
105
  }
106
  }
81
  );
82
  }
83
 
84
+ /**
85
+ * @inheritdoc
86
+ */
87
+ public function put($url, array $options = array())
88
+ {
89
+ $this->init($options);
90
+ return $this->send(
91
+ $url,
92
+ array(
93
+ 'http' => array(
94
+ 'method' => 'PUT',
95
+ 'header' => implode("\r\n", $this->headers),
96
+ 'content' => $this->content,
97
+ // Fetch the content even on failure status codes.
98
+ 'ignore_errors' => true,
99
+ ),
100
+ )
101
+ );
102
+ }
103
+
104
+ /**
105
+ * @inheritdoc
106
+ */
107
+ public function delete($url, array $options = array())
108
+ {
109
+ $this->init($options);
110
+ return $this->send(
111
+ $url,
112
+ array(
113
+ 'http' => array(
114
+ 'method' => 'DELETE',
115
+ 'header' => implode("\r\n", $this->headers),
116
+ // Fetch the content even on failure status codes.
117
+ 'ignore_errors' => true,
118
+ ),
119
+ )
120
+ );
121
+ }
122
+
123
  /**
124
  * Sends the request and creates a NostoHttpResponse instance containing the response headers and body.
125
  *
135
  // is executed (http://php.net/manual/en/reserved.variables.httpresponseheader.php).
136
  $http_response_header = array();
137
  $result = @file_get_contents($url, false, $context);
138
+ return new NostoHttpResponse($http_response_header, $result);
 
 
 
 
 
139
  }
140
  }
lib/nosto/php-sdk/src/classes/http/NostoHttpResponse.php CHANGED
@@ -53,15 +53,31 @@ class NostoHttpResponse
53
  */
54
  protected $message;
55
 
56
- /**
57
- * Setter for the request response data.
58
- *
59
- * @param mixed $result the response data of the request.
60
- */
61
- public function setResult($result)
62
- {
63
- $this->result = $result;
64
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
  /**
67
  * Getter for the request response data.
@@ -73,26 +89,6 @@ class NostoHttpResponse
73
  return $this->result;
74
  }
75
 
76
- /**
77
- * Setter for the error message of the request.
78
- *
79
- * @param string $message the message.
80
- */
81
- public function setMessage($message)
82
- {
83
- $this->message = $message;
84
- }
85
-
86
- /**
87
- * Getter for the error message of the request.
88
- *
89
- * @return string the message.
90
- */
91
- public function getMessage()
92
- {
93
- return $this->message;
94
- }
95
-
96
  /**
97
  * Getter for the request response as JSON.
98
  *
@@ -104,37 +100,49 @@ class NostoHttpResponse
104
  return json_decode($this->result, $assoc);
105
  }
106
 
107
- /**
108
- * Setter for the request response headers.
109
- *
110
- * @param array $headers the headers,
111
- */
112
- public function setHeaders($headers)
113
- {
114
- $this->headers = $headers;
115
- }
116
 
117
  /**
118
- * Returns the http request response code.
119
  *
120
  * @return int the http code or 0 if not set.
121
  */
122
  public function getCode()
123
  {
124
- $matches = array();
125
- if (isset($this->headers) && isset($this->headers[0])) {
126
- preg_match('|HTTP/\d\.\d\s+(\d+)\s+.*|', $this->headers[0], $matches);
127
- }
128
- return isset($matches[1]) ? (int)$matches[1] : 0;
 
 
 
 
 
 
 
 
 
129
  }
130
 
131
  /**
132
- * Returns the raw http request response status string.
133
- *
134
- * @return string the status string or empty if not set.
135
  */
136
- public function getRawStatus()
137
  {
138
- return (isset($this->headers) && isset($this->headers[0])) ? $this->headers[0] : '';
 
 
 
 
139
  }
140
  }
53
  */
54
  protected $message;
55
 
56
+ /**
57
+ * @var int runtime cache for the http response code.
58
+ */
59
+ private $_code;
60
+
61
+ /**
62
+ * Constructor.
63
+ * Creates and populates the response object.
64
+ *
65
+ * @param array $headers the response headers.
66
+ * @param string $body the response body.
67
+ * @param string $error optional error message.
68
+ */
69
+ public function __construct($headers, $body, $error = null)
70
+ {
71
+ if (!empty($headers) && is_array($headers)) {
72
+ $this->headers = $headers;
73
+ }
74
+ if (!empty($body) && is_string($body)) {
75
+ $this->result = $body;
76
+ }
77
+ if (!empty($error) && is_string($error)) {
78
+ $this->message = $error;
79
+ }
80
+ }
81
 
82
  /**
83
  * Getter for the request response data.
89
  return $this->result;
90
  }
91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  /**
93
  * Getter for the request response as JSON.
94
  *
100
  return json_decode($this->result, $assoc);
101
  }
102
 
103
+ /**
104
+ * Getter for the error message of the request.
105
+ *
106
+ * @return string the message.
107
+ */
108
+ public function getMessage()
109
+ {
110
+ return $this->message;
111
+ }
112
 
113
  /**
114
+ * Returns the `last` http response code.
115
  *
116
  * @return int the http code or 0 if not set.
117
  */
118
  public function getCode()
119
  {
120
+ if (is_null($this->_code)) {
121
+ $code = 0;
122
+ if (!empty($this->headers)) {
123
+ foreach ($this->headers as $header) {
124
+ $matches = array();
125
+ preg_match('|HTTP/\d\.\d\s+(\d+)\s+.*|', $header, $matches);
126
+ if (isset($matches[1])) {
127
+ $code = (int)$matches[1];
128
+ }
129
+ }
130
+ }
131
+ $this->_code = $code;
132
+ }
133
+ return $this->_code;
134
  }
135
 
136
  /**
137
+ * Converts the response to a string and returns it.
138
+ * Used when logging http request errors.
 
139
  */
140
+ public function __toString()
141
  {
142
+ return serialize(array(
143
+ 'headers' => $this->headers,
144
+ 'body' => $this->result,
145
+ 'error' => $this->message,
146
+ ));
147
  }
148
  }
lib/nosto/php-sdk/src/classes/oauth/NostoOAuthClient.php CHANGED
@@ -129,7 +129,7 @@ class NostoOAuthClient
129
  $result = $response->getJsonResult(true);
130
 
131
  if ($response->getCode() !== 200) {
132
- throw new NostoException('Failed to authenticate with code', $response->getCode());
133
  }
134
  if (empty($result['access_token'])) {
135
  throw new NostoException('No "access_token" returned after authenticating with code');
129
  $result = $response->getJsonResult(true);
130
 
131
  if ($response->getCode() !== 200) {
132
+ Nosto::throwHttpException('Failed to authenticate with code.', $request, $response);
133
  }
134
  if (empty($result['access_token'])) {
135
  throw new NostoException('No "access_token" returned after authenticating with code');
lib/nosto/php-sdk/src/classes/operation/NostoOperationProduct.php ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2015, Nosto Solutions Ltd
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without modification,
7
+ * are permitted provided that the following conditions are met:
8
+ *
9
+ * 1. Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ *
12
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ * this list of conditions and the following disclaimer in the documentation
14
+ * and/or other materials provided with the distribution.
15
+ *
16
+ * 3. Neither the name of the copyright holder nor the names of its contributors
17
+ * may be used to endorse or promote products derived from this software without
18
+ * specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
24
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ *
31
+ * @author Nosto Solutions Ltd <contact@nosto.com>
32
+ * @copyright 2015 Nosto Solutions Ltd
33
+ * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause
34
+ */
35
+
36
+ /**
37
+ * Handles create/update/delete of products through the Nosto API.
38
+ */
39
+ class NostoOperationProduct
40
+ {
41
+ /**
42
+ * @var NostoAccountInterface the account to perform the operation on.
43
+ */
44
+ protected $account;
45
+
46
+ /**
47
+ * @var NostoProductCollection collection object of products to perform the operation on.
48
+ */
49
+ protected $collection;
50
+
51
+ /**
52
+ * Constructor.
53
+ *
54
+ * Accepts the account for which the product operation is to be performed on.
55
+ *
56
+ * @param NostoAccountInterface $account the account object.
57
+ */
58
+ public function __construct(NostoAccountInterface $account)
59
+ {
60
+ $this->account = $account;
61
+ $this->collection = new NostoProductCollection();
62
+ }
63
+
64
+ /**
65
+ * Adds a product tho the collection on which the operation is the performed.
66
+ *
67
+ * @param NostoProductInterface $product
68
+ */
69
+ public function addProduct(NostoProductInterface $product)
70
+ {
71
+ $this->collection[] = $product;
72
+ }
73
+
74
+ /**
75
+ * Sends a POST request to create all the products currently in the collection.
76
+ *
77
+ * @return bool if the request was successful.
78
+ * @throws NostoException on failure.
79
+ */
80
+ public function create()
81
+ {
82
+ $request = $this->initApiRequest();
83
+ $request->setPath(NostoApiRequest::PATH_PRODUCTS_UPSERT);
84
+ $response = $request->post($this->getCollectionAsJson());
85
+ if ($response->getCode() !== 200) {
86
+ Nosto::throwHttpException('Failed to create Nosto product(s).', $request, $response);
87
+ }
88
+ return true;
89
+ }
90
+
91
+ /**
92
+ * Sends a POST request to update all the products currently in the collection.
93
+ *
94
+ * @return bool if the request was successful.
95
+ * @throws NostoException on failure.
96
+ */
97
+ public function update()
98
+ {
99
+ $request = $this->initApiRequest();
100
+ $request->setPath(NostoApiRequest::PATH_PRODUCTS_UPSERT);
101
+ $response = $request->post($this->getCollectionAsJson());
102
+ if ($response->getCode() !== 200) {
103
+ Nosto::throwHttpException('Failed to update Nosto product(s).', $request, $response);
104
+ }
105
+ return true;
106
+ }
107
+
108
+ /**
109
+ * Sends a POST request to delete all the products currently in the collection.
110
+ *
111
+ * @return bool if the request was successful.
112
+ * @throws NostoException on failure.
113
+ */
114
+ public function delete()
115
+ {
116
+ $request = $this->initApiRequest();
117
+ $request->setPath(NostoApiRequest::PATH_PRODUCTS_DISCONTINUE);
118
+ $response = $request->post($this->getCollectionIdsAsJson());
119
+ if ($response->getCode() !== 200) {
120
+ Nosto::throwHttpException('Failed to delete Nosto product(s).', $request, $response);
121
+ }
122
+ return true;
123
+ }
124
+
125
+ /**
126
+ * Create and returns a new API request object initialized with:
127
+ * - content type
128
+ * - auth token
129
+ *
130
+ * @return NostoApiRequest the newly created request object.
131
+ * @throws NostoException if the account does not have the `products` token set.
132
+ */
133
+ protected function initApiRequest()
134
+ {
135
+ $token = $this->account->getApiToken('products');
136
+ if (is_null($token)) {
137
+ throw new NostoException('No `products` API token found for account.');
138
+ }
139
+
140
+ $request = new NostoApiRequest();
141
+ $request->setContentType('application/json');
142
+ $request->setAuthBasic('', $token->value);
143
+ return $request;
144
+ }
145
+
146
+ /**
147
+ * Converts the product object into an array and returns it.
148
+ *
149
+ * @param NostoProductInterface $product the object.
150
+ * @return array the newly created array.
151
+ */
152
+ protected function getProductAsArray(NostoProductInterface $product)
153
+ {
154
+ return array(
155
+ 'url' => $product->getUrl(),
156
+ 'product_id' => (int)$product->getProductId(),
157
+ 'name' => $product->getName(),
158
+ 'image_url' => $product->getImageUrl(),
159
+ 'price' => Nosto::helper('price')->format($product->getPrice()),
160
+ 'list_price' => Nosto::helper('price')->format($product->getListPrice()),
161
+ 'price_currency_code' => strtoupper($product->getCurrencyCode()),
162
+ 'availability' => $product->getAvailability(),
163
+ 'tag1' => $product->getTags(),
164
+ 'categories' => $product->getCategories(),
165
+ 'description' => $product->getShortDescription().'<br/>'.$product->getDescription(),
166
+ 'brand' => $product->getBrand(),
167
+ 'date_published' => Nosto::helper('date')->format($product->getDatePublished()),
168
+ );
169
+ }
170
+
171
+ /**
172
+ * Returns the whole collection in JSON format.
173
+ *
174
+ * @return string the json.
175
+ * @throws NostoException if the collection is empty.
176
+ */
177
+ protected function getCollectionAsJson()
178
+ {
179
+ $data = array();
180
+ $validator = new NostoModelValidator();
181
+ foreach ($this->collection->getArrayCopy() as $item) {
182
+ /** @var NostoProductInterface|NostoValidatableModelInterface $item */
183
+ if ($validator->validate($item)) {
184
+ $data[] = $this->getProductAsArray($item);
185
+ }
186
+ }
187
+ if (empty($data)) {
188
+ throw new NostoException('No products found in collection.');
189
+ }
190
+ return json_encode($data);
191
+ }
192
+
193
+ /**
194
+ * Returns all the product IDs of the items in the collection in JSON format.
195
+ *
196
+ * @return string the json.
197
+ * @throws NostoException if the collection is empty.
198
+ */
199
+ protected function getCollectionIdsAsJson()
200
+ {
201
+ $data = array();
202
+ foreach ($this->collection->getArrayCopy() as $item) {
203
+ /** @var NostoProductInterface $item */
204
+ $productId = (int)$item->getProductId();
205
+ if ($productId > 0) {
206
+ $data[] = $productId;
207
+ }
208
+ }
209
+ if (empty($data)) {
210
+ throw new NostoException('No products found in collection.');
211
+ }
212
+ return json_encode($data);
213
+ }
214
+ }
lib/nosto/php-sdk/src/config.inc.php CHANGED
@@ -43,9 +43,12 @@ require_once(dirname(__FILE__).'/interfaces/account/NostoAccountMetaDataOwnerInt
43
  require_once(dirname(__FILE__).'/interfaces/order/NostoOrderBuyerInterface.php');
44
  require_once(dirname(__FILE__).'/interfaces/order/NostoOrderInterface.php');
45
  require_once(dirname(__FILE__).'/interfaces/order/NostoOrderPurchasedItemInterface.php');
 
46
 
47
  require_once(dirname(__FILE__).'/interfaces/NostoOAuthClientMetaDataInterface.php');
48
  require_once(dirname(__FILE__).'/interfaces/NostoProductInterface.php');
 
 
49
 
50
  // Classes
51
  require_once(dirname(__FILE__).'/classes/http/NostoHttpRequest.php'); // Must be loaded before `NostoApiRequest`
@@ -53,8 +56,14 @@ require_once(dirname(__FILE__).'/classes/http/NostoHttpRequest.php'); // Must be
53
  require_once(dirname(__FILE__).'/classes/api/NostoApiRequest.php');
54
  require_once(dirname(__FILE__).'/classes/api/NostoApiToken.php');
55
 
 
 
 
 
 
 
 
56
  require_once(dirname(__FILE__).'/classes/export/NostoExporter.php');
57
- require_once(dirname(__FILE__).'/classes/export/NostoExportCollection.php');
58
  require_once(dirname(__FILE__).'/classes/export/NostoExportProductCollection.php');
59
  require_once(dirname(__FILE__).'/classes/export/NostoExportOrderCollection.php');
60
 
@@ -71,15 +80,16 @@ require_once(dirname(__FILE__).'/classes/http/NostoHttpResponse.php');
71
  require_once(dirname(__FILE__).'/classes/oauth/NostoOAuthClient.php');
72
  require_once(dirname(__FILE__).'/classes/oauth/NostoOAuthToken.php');
73
 
 
 
74
  require_once(dirname(__FILE__).'/classes/Nosto.php');
75
  require_once(dirname(__FILE__).'/classes/NostoAccount.php');
76
  require_once(dirname(__FILE__).'/classes/NostoCipher.php');
77
  require_once(dirname(__FILE__).'/classes/NostoDotEnv.php');
78
- require_once(dirname(__FILE__).'/classes/NostoException.php');
79
  require_once(dirname(__FILE__).'/classes/NostoMessage.php');
80
  require_once(dirname(__FILE__).'/classes/NostoOrderConfirmation.php');
81
  require_once(dirname(__FILE__).'/classes/NostoProductReCrawl.php');
82
- require_once(dirname(__FILE__).'/classes/NostoXhrResponse.php');
83
 
84
  // Libs
85
  require_once(dirname(__FILE__).'/libs/phpseclib/crypt/NostoCryptBase.php');
43
  require_once(dirname(__FILE__).'/interfaces/order/NostoOrderBuyerInterface.php');
44
  require_once(dirname(__FILE__).'/interfaces/order/NostoOrderInterface.php');
45
  require_once(dirname(__FILE__).'/interfaces/order/NostoOrderPurchasedItemInterface.php');
46
+ require_once(dirname(__FILE__).'/interfaces/order/NostoOrderStatusInterface.php');
47
 
48
  require_once(dirname(__FILE__).'/interfaces/NostoOAuthClientMetaDataInterface.php');
49
  require_once(dirname(__FILE__).'/interfaces/NostoProductInterface.php');
50
+ require_once(dirname(__FILE__).'/interfaces/NostoExportCollectionInterface.php');
51
+ require_once(dirname(__FILE__).'/interfaces/NostoValidatableModelInterface.php');
52
 
53
  // Classes
54
  require_once(dirname(__FILE__).'/classes/http/NostoHttpRequest.php'); // Must be loaded before `NostoApiRequest`
56
  require_once(dirname(__FILE__).'/classes/api/NostoApiRequest.php');
57
  require_once(dirname(__FILE__).'/classes/api/NostoApiToken.php');
58
 
59
+ require_once(dirname(__FILE__).'/classes/collection/NostoCollection.php');
60
+ require_once(dirname(__FILE__).'/classes/collection/NostoProductCollection.php');
61
+ require_once(dirname(__FILE__).'/classes/collection/NostoOrderCollection.php');
62
+
63
+ require_once(dirname(__FILE__).'/classes/exception/NostoException.php');
64
+ require_once(dirname(__FILE__).'/classes/exception/NostoHttpException.php');
65
+
66
  require_once(dirname(__FILE__).'/classes/export/NostoExporter.php');
 
67
  require_once(dirname(__FILE__).'/classes/export/NostoExportProductCollection.php');
68
  require_once(dirname(__FILE__).'/classes/export/NostoExportOrderCollection.php');
69
 
80
  require_once(dirname(__FILE__).'/classes/oauth/NostoOAuthClient.php');
81
  require_once(dirname(__FILE__).'/classes/oauth/NostoOAuthToken.php');
82
 
83
+ require_once(dirname(__FILE__).'/classes/operation/NostoOperationProduct.php');
84
+
85
  require_once(dirname(__FILE__).'/classes/Nosto.php');
86
  require_once(dirname(__FILE__).'/classes/NostoAccount.php');
87
  require_once(dirname(__FILE__).'/classes/NostoCipher.php');
88
  require_once(dirname(__FILE__).'/classes/NostoDotEnv.php');
 
89
  require_once(dirname(__FILE__).'/classes/NostoMessage.php');
90
  require_once(dirname(__FILE__).'/classes/NostoOrderConfirmation.php');
91
  require_once(dirname(__FILE__).'/classes/NostoProductReCrawl.php');
92
+ require_once(dirname(__FILE__).'/classes/NostoModelValidator.php');
93
 
94
  // Libs
95
  require_once(dirname(__FILE__).'/libs/phpseclib/crypt/NostoCryptBase.php');
lib/nosto/php-sdk/src/interfaces/NostoExportCollectionInterface.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2015, Nosto Solutions Ltd
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without modification,
7
+ * are permitted provided that the following conditions are met:
8
+ *
9
+ * 1. Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ *
12
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ * this list of conditions and the following disclaimer in the documentation
14
+ * and/or other materials provided with the distribution.
15
+ *
16
+ * 3. Neither the name of the copyright holder nor the names of its contributors
17
+ * may be used to endorse or promote products derived from this software without
18
+ * specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
24
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ *
31
+ * @author Nosto Solutions Ltd <contact@nosto.com>
32
+ * @copyright 2015 Nosto Solutions Ltd
33
+ * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause
34
+ */
35
+
36
+ /**
37
+ * Interface for export collections.
38
+ */
39
+ interface NostoExportCollectionInterface
40
+ {
41
+ /**
42
+ * Returns the collection as a JSON string.
43
+ * In the JSON camel case variables are converted into underscore format.
44
+ *
45
+ * @return string the JSON.
46
+ */
47
+ public function getJson();
48
+ }
lib/nosto/php-sdk/src/interfaces/NostoValidatableModelInterface.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2015, Nosto Solutions Ltd
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without modification,
7
+ * are permitted provided that the following conditions are met:
8
+ *
9
+ * 1. Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ *
12
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ * this list of conditions and the following disclaimer in the documentation
14
+ * and/or other materials provided with the distribution.
15
+ *
16
+ * 3. Neither the name of the copyright holder nor the names of its contributors
17
+ * may be used to endorse or promote products derived from this software without
18
+ * specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
24
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ *
31
+ * @author Nosto Solutions Ltd <contact@nosto.com>
32
+ * @copyright 2015 Nosto Solutions Ltd
33
+ * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause
34
+ */
35
+
36
+ /**
37
+ * Interface for all models that support data validation.
38
+ */
39
+ interface NostoValidatableModelInterface
40
+ {
41
+ /**
42
+ * Returns an array of validator rules for the model properties.
43
+ *
44
+ * Example:
45
+ *
46
+ * return array(array('url', 'productId'), 'required');
47
+ *
48
+ * @return mixed
49
+ */
50
+ public function getValidationRules();
51
+ }
lib/nosto/php-sdk/src/interfaces/order/NostoOrderInterface.php CHANGED
@@ -73,4 +73,11 @@ interface NostoOrderInterface
73
  * @return NostoOrderPurchasedItemInterface[] the meta data models.
74
  */
75
  public function getPurchasedItems();
 
 
 
 
 
 
 
76
  }
73
  * @return NostoOrderPurchasedItemInterface[] the meta data models.
74
  */
75
  public function getPurchasedItems();
76
+
77
+ /**
78
+ * Returns the order status model.
79
+ *
80
+ * @return NostoOrderStatusInterface the model.
81
+ */
82
+ public function getOrderStatus();
83
  }
lib/nosto/php-sdk/src/{classes/NostoXhrResponse.php → interfaces/order/NostoOrderStatusInterface.php} RENAMED
@@ -34,70 +34,22 @@
34
  */
35
 
36
  /**
37
- * Util class for representing a XHR response object used when responding to
38
- * account administration iframe API calls.
39
  */
40
- class NostoXhrResponse
41
  {
42
  /**
43
- * @var string the `Content-Type` of the response.
44
- */
45
- public $contentType = 'application/json';
46
-
47
- /**
48
- * @var bool the response success flag.
49
- */
50
- protected $success = false;
51
-
52
- /**
53
- * @var string the response redirect url.
54
- */
55
- protected $redirectUrl;
56
-
57
- /**
58
- * Sets the response success state.
59
- *
60
- * @param boolean $success the state.
61
- * @return NostoXhrResponse the response instance.
62
- */
63
- public function setSuccess($success)
64
- {
65
- $this->success = $success;
66
- return $this;
67
- }
68
-
69
- /**
70
- * Sets the response redirect url.
71
  *
72
- * @param string $url the url.
73
- * @return NostoXhrResponse the response instance.
74
- */
75
- public function setRedirectUrl($url)
76
- {
77
- $this->redirectUrl = $url;
78
- return $this;
79
- }
80
-
81
- /**
82
- * Sends the response, i.e. sends it to the browser.
83
- * This method also sends the `Content-Type` header for the response data.
84
  */
85
- public function send()
86
- {
87
- header('Content-Type: '.$this->contentType);
88
- echo $this;
89
- }
90
 
91
  /**
92
- * Converts the response to a string and returns it.
93
  *
94
- * @return string the string representation of the response.
95
  */
96
- public function __toString()
97
- {
98
- return (string)json_encode(array(
99
- 'success' => (bool)$this->success,
100
- 'redirect_url' => (string)$this->redirectUrl,
101
- ));
102
- }
103
  }
34
  */
35
 
36
  /**
37
+ * Interface for order status meta data.
38
+ * This is used by the NostoOrderInterface meta data model when sending order confirmation API requests.
39
  */
40
+ interface NostoOrderStatusInterface
41
  {
42
  /**
43
+ * Returns the order status code.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  *
45
+ * @return string the code.
 
 
 
 
 
 
 
 
 
 
 
46
  */
47
+ public function getCode();
 
 
 
 
48
 
49
  /**
50
+ * Returns the order status label.
51
  *
52
+ * @return string the label.
53
  */
54
+ public function getLabel();
 
 
 
 
 
 
55
  }
package.xml CHANGED
@@ -1,18 +1,20 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Nosto_Tagging</name>
4
- <version>2.2.1</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL)</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Personalization for Magento</summary>
10
  <description>Increase your conversion rate and average order value by delivering your customers personalized product recommendations throughout their shopping journey.</description>
11
- <notes>* Add Enterprise Edition support</notes>
 
 
12
  <authors><author><name>Nosto</name><user>nosto</user><email>magento@nosto.com</email></author></authors>
13
- <date>2015-04-17</date>
14
- <time>06:45:14</time>
15
- <contents><target name="magecommunity"><dir name="Nosto"><dir name="Tagging"><dir name="Block"><dir name="Adminhtml"><file name="Iframe.php" hash="158340d20d1a01a0863f24278198c2e5"/><file name="Wizard.php" hash="f98931a1a6e327c0d05e43b73063f672"/></dir><file name="Cart.php" hash="feb9b5d1c84d2301c9f74613559dceb7"/><file name="Category.php" hash="177a5d8d9f1ba9e246d149c228c3aec8"/><file name="Customer.php" hash="d35777ca399244e4fb441456320f8ad7"/><file name="Element.php" hash="e5b12bb118b92eb7075ff7a6e16e0eba"/><file name="Embed.php" hash="e8b628b6bc49fb865697552300d08526"/><file name="Meta.php" hash="1f761e731214b7572ef139d9e0577ea1"/><file name="Order.php" hash="1666d552e61768cfd35860b9472feced"/><file name="Product.php" hash="261cd58ad94daa82d1cf2188179278c0"/></dir><dir name="Helper"><file name="Account.php" hash="afd5f7e1bc61a5ab450e0483db371370"/><file name="Customer.php" hash="92da4f0ae6c2aef635b837635cd74238"/><file name="Data.php" hash="b138748cea6b7c4ccda41e7f2ef1f1cb"/><file name="Date.php" hash="1a108a4ec8169b73411b6c11b86a1d80"/><file name="Oauth.php" hash="08f096ef785d64225ec71d7e2e99f534"/><file name="Price.php" hash="4c21321d10f40c6f985bd934b174a17c"/><file name="Url.php" hash="289294904d246c56e4de96798927a7f6"/></dir><dir name="Model"><dir name="Container"><file name="Cart.php" hash="20d2936693361999575f1e6ac56f2e40"/><file name="Customer.php" hash="b03bca89845b6c939521add8df1f7e9a"/></dir><file name="Customer.php" hash="6d992a43a75f29836ed1450e130df560"/><dir name="Meta"><dir name="Account"><file name="Billing.php" hash="d09b6b6ddc543201ec9485db9bb0a260"/><file name="Iframe.php" hash="f26a7ef337d86cb83c687ba2e0beb45b"/><file name="Owner.php" hash="801c33bbf04bcfbe133654770909d1df"/></dir><file name="Account.php" hash="c01a324111528339ddd71f0046b95ecc"/><file name="Oauth.php" hash="761b0dd6cede8122c715d077b010b927"/><dir name="Order"><file name="Buyer.php" hash="633c6de58a46128bb594d6580d3ffa46"/><file name="Item.php" hash="86baa577302a4791fa68981b06c2957c"/></dir><file name="Order.php" hash="7f041ef68a1f0652b4e2f92d0ef1c46b"/><file name="Product.php" hash="81bc01d556456090f1d094177fb81adb"/></dir><file name="Observer.php" hash="87bfc436fd2c2d05dd80f1caa2d92b22"/><dir name="Resource"><dir name="Customer"><file name="Collection.php" hash="0c99b46d5108a6fe31cad1190d8ef47c"/></dir><file name="Customer.php" hash="f92e4e5334b5e3493e8f04664b20f105"/><file name="Setup.php" hash="506b08bcb10cbe74e95812c5f646429f"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="NostoController.php" hash="4e7918941aa664562bb6129eef685f32"/></dir><file name="ExportController.php" hash="5c4d78762f631c759559af9e356b7f86"/><file name="OauthController.php" hash="e57a2578535e711ce1bdcb78e3fa1983"/></dir><dir name="etc"><file name="adminhtml.xml" hash="70f3a22856ec6cb31749a92ed4461b6b"/><file name="cache.xml" hash="e874fbbf2eb89b325deb1a62afbcfb4d"/><file name="config.xml" hash="81780334e2040cecc26d1efd75291790"/></dir><dir name="sql"><dir name="tagging_setup"><file name="mysql4-install-1.2.0.php" hash="3cbc52834c44870859562eec7969b9fd"/><file name="mysql4-upgrade-1.1.7-1.2.0.php" hash="0d8eb7990461a9d4b74b479120067aeb"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="nostotagging"><file name="iframe.phtml" hash="c81931adf855a4893e0cf2dc60c390cb"/><file name="wizard.phtml" hash="3f92e94e5ee3d3cd9906a6b0942a3a1b"/></dir></dir><dir name="layout"><file name="nostotagging.xml" hash="5f77c6921f67d08484c6d510b4706c29"/></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="nostotagging"><file name="cart.phtml" hash="c3d560050239066c73b1ec935048dbee"/><dir name="category"><file name="view.phtml" hash="fc09e2770ad6281ec96c8e92accc01f1"/></dir><file name="category.phtml" hash="81f36742cb4e3adbf9f692cc8f0ea8a8"/><file name="customer.phtml" hash="e9bc92bb7f7df989cc706c7eaee3614a"/><file name="element.phtml" hash="e1d38981789e632a3607ccf2e171f0cb"/><file name="embed.phtml" hash="9193ddd1ae373b68c53f8364f511b0a5"/><file name="meta.phtml" hash="c1b862a4993503fae420fb0eba194b00"/><file name="order.phtml" hash="7d65566ba4ee709dab7f2114340742af"/><file name="product.phtml" hash="412b7bd9ed43981f056132ea37719aab"/></dir></dir><dir name="layout"><file name="nostotagging.xml" hash="0ff843226af2cf96cac80764034ac15c"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Nosto_Tagging.xml" hash="1705cb7e6db28388662ef52882d61701"/></dir></target><target name="magelib"><dir name="nosto"><dir name="php-sdk"><dir name="src"><dir name="classes"><file name="Nosto.php" hash="80254fcb3fcda48a25cc3d4585b5f6ac"/><file name="NostoAccount.php" hash="17e77036cb2c068678cbe06d5f9b9086"/><file name="NostoCipher.php" hash="a3d7d148311aa0319387c0918e5e26dc"/><file name="NostoDotEnv.php" hash="90b23c1b02095c9368372f1d5346c3f9"/><file name="NostoException.php" hash="c4610fb70278d01bd85bc83b8e74df30"/><file name="NostoMessage.php" hash="5933eadd2ad08427010b0bf16657266b"/><file name="NostoOrderConfirmation.php" hash="5f6ea05fe40211433f5cd354244c3513"/><file name="NostoProductReCrawl.php" hash="adf49008cea0004c5a1f82b4bebdfbaa"/><file name="NostoXhrResponse.php" hash="a65d1d16b4a027c27ecc3c137fc07f63"/><dir name="api"><file name="NostoApiRequest.php" hash="a4960738a0ee3504a44168947057cd88"/><file name="NostoApiToken.php" hash="ca42b406a88735ac1565bf13efdf8a04"/></dir><dir name="export"><file name="NostoExportCollection.php" hash="fb539cc4ab9441b3b8529d1a8e5dae2e"/><file name="NostoExportOrderCollection.php" hash="c34cccb2d0593c31b54eeb541478aa0b"/><file name="NostoExportProductCollection.php" hash="4d461dddf9f89b7f51c82cb3e5a02530"/><file name="NostoExporter.php" hash="8d3f095c99662fc34c0a671799a1378e"/></dir><dir name="helper"><file name="NostoHelper.php" hash="f4ca6c78e047fec93c32b7eb822b0692"/><file name="NostoHelperDate.php" hash="081a2d8bfec710f2baa52192a99a2658"/><file name="NostoHelperIframe.php" hash="1364153a359dcfdf22f7376aba66da47"/><file name="NostoHelperPrice.php" hash="ee9f217dc1b8e0fc679fb56ca3fd3ca1"/></dir><dir name="http"><file name="NostoHttpRequest.php" hash="442e18206374924719d24c2e9c0b1fd3"/><file name="NostoHttpRequestAdapter.php" hash="1a76cc5ceba3caae37c73390a2096c98"/><file name="NostoHttpRequestAdapterCurl.php" hash="d3947393b19b50eb9871546dc2057b25"/><file name="NostoHttpRequestAdapterSocket.php" hash="3a3dfbb13b51d1abb14215df253d7d64"/><file name="NostoHttpResponse.php" hash="5c993520d4375103bca2b580a35987eb"/></dir><dir name="oauth"><file name="NostoOAuthClient.php" hash="d5b832ea8eca0fa8fdc05d27077b504b"/><file name="NostoOAuthToken.php" hash="f81c1c1e5c4fc2010162d8f69de2cb33"/></dir></dir><file name="config.inc.php" hash="f586713798d3e731b2dffd2da7e15861"/><dir name="interfaces"><file name="NostoOAuthClientMetaDataInterface.php" hash="75a82417bfc27cd82e41ea9810d31428"/><file name="NostoProductInterface.php" hash="110aabc704bed12ddacc304d6d1e1529"/><dir name="account"><file name="NostoAccountInterface.php" hash="5655c43db9e1e0a8e1fd23753ec5ef06"/><file name="NostoAccountMetaDataBillingDetailsInterface.php" hash="ef31f0c3b41591fd76f85a25021f0fe4"/><file name="NostoAccountMetaDataIframeInterface.php" hash="c739e6a3ef39a308df6852361f2fd1d7"/><file name="NostoAccountMetaDataInterface.php" hash="7395de56fb4e3a1831bc5f7cfeffed8d"/><file name="NostoAccountMetaDataOwnerInterface.php" hash="4c037b8cb1b529c16c91f25cce2b0ed7"/></dir><dir name="order"><file name="NostoOrderBuyerInterface.php" hash="890884e45bcca61f96f0f98cda40b6c1"/><file name="NostoOrderInterface.php" hash="d2d5d0770a383acd6004722ef376fcb5"/><file name="NostoOrderPurchasedItemInterface.php" hash="e33b94290465eea80d614db35144b75a"/></dir></dir><dir name="js"><file name="NostoIframe.min.js" hash="b4508aed29b641e6ad3d1062a54c209f"/><dir name="src"><file name="NostoIframe.js" hash="e9962928ba1cf0ff205e21a0d469f4d8"/></dir></dir><dir name="libs"><dir name="phpseclib"><dir name="crypt"><file name="NostoCryptAES.php" hash="7f16ec6fa7eefa011a27acf4506a3b57"/><file name="NostoCryptBase.php" hash="c78432d428ad8a70be832f91261d4c42"/><file name="NostoCryptRandom.php" hash="eb21a56b9cf6e6ef0b220620dd4d0ebe"/><file name="NostoCryptRijndael.php" hash="9c728d06c0249f8bc24a7c61606ccc89"/></dir></dir></dir><file name=".env.example" hash="ec9fd4d90a792e2c98b10ff8fe7ae984"/></dir></dir></dir></target><target name="mage"><dir name="js"><dir name="nosto"><file name="NostoIframe.min.js" hash="b4508aed29b641e6ad3d1062a54c209f"/><file name="iframeresizer.min.js" hash="163b065c9dd702dc364913a951b81fee"/><file name="nostotagging-config.js" hash="0119fb333233f1f0fa70f4167fb014ef"/></dir></dir></target></contents>
16
  <compatible/>
17
- <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php><package><name>Mage_Core_Modules</name><channel>community</channel><min>1.6.0.0</min><max>1.9.1.0</max></package></required></dependencies>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Nosto_Tagging</name>
4
+ <version>2.4.0</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL)</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Personalization for Magento</summary>
10
  <description>Increase your conversion rate and average order value by delivering your customers personalized product recommendations throughout their shopping journey.</description>
11
+ <notes>* Deprecate product re-crawl feature and implement product update API in it's place&#xD;
12
+ * Add JavaScript "add-to-cart" feature to enable adding products to cart directly from recommendations&#xD;
13
+ * Refactor order status handling in order confirmations and order exports</notes>
14
  <authors><author><name>Nosto</name><user>nosto</user><email>magento@nosto.com</email></author></authors>
15
+ <date>2015-05-13</date>
16
+ <time>10:52:00</time>
17
+ <contents><target name="magecommunity"><dir name="Nosto"><dir name="Tagging"><dir name="Block"><file name="Addtocart.php" hash="61d645e5cc9e54a5170ae03797f0426a"/><dir name="Adminhtml"><file name="Iframe.php" hash="158340d20d1a01a0863f24278198c2e5"/><file name="Wizard.php" hash="f98931a1a6e327c0d05e43b73063f672"/></dir><file name="Cart.php" hash="feb9b5d1c84d2301c9f74613559dceb7"/><file name="Category.php" hash="177a5d8d9f1ba9e246d149c228c3aec8"/><file name="Customer.php" hash="d35777ca399244e4fb441456320f8ad7"/><file name="Element.php" hash="e5b12bb118b92eb7075ff7a6e16e0eba"/><file name="Embed.php" hash="e8b628b6bc49fb865697552300d08526"/><file name="Meta.php" hash="1f761e731214b7572ef139d9e0577ea1"/><file name="Order.php" hash="1666d552e61768cfd35860b9472feced"/><file name="Product.php" hash="261cd58ad94daa82d1cf2188179278c0"/></dir><dir name="Helper"><file name="Account.php" hash="afd5f7e1bc61a5ab450e0483db371370"/><file name="Customer.php" hash="92da4f0ae6c2aef635b837635cd74238"/><file name="Data.php" hash="b138748cea6b7c4ccda41e7f2ef1f1cb"/><file name="Date.php" hash="1a108a4ec8169b73411b6c11b86a1d80"/><file name="Oauth.php" hash="08f096ef785d64225ec71d7e2e99f534"/><file name="Price.php" hash="4c21321d10f40c6f985bd934b174a17c"/><file name="Url.php" hash="289294904d246c56e4de96798927a7f6"/></dir><dir name="Model"><dir name="Container"><file name="Cart.php" hash="20d2936693361999575f1e6ac56f2e40"/><file name="Customer.php" hash="b03bca89845b6c939521add8df1f7e9a"/></dir><file name="Customer.php" hash="6d992a43a75f29836ed1450e130df560"/><dir name="Meta"><dir name="Account"><file name="Billing.php" hash="d09b6b6ddc543201ec9485db9bb0a260"/><file name="Iframe.php" hash="f26a7ef337d86cb83c687ba2e0beb45b"/><file name="Owner.php" hash="801c33bbf04bcfbe133654770909d1df"/></dir><file name="Account.php" hash="c01a324111528339ddd71f0046b95ecc"/><file name="Oauth.php" hash="761b0dd6cede8122c715d077b010b927"/><dir name="Order"><file name="Buyer.php" hash="633c6de58a46128bb594d6580d3ffa46"/><file name="Item.php" hash="86baa577302a4791fa68981b06c2957c"/><file name="Status.php" hash="37520c32630aa4bf14d8213f39e80a4b"/></dir><file name="Order.php" hash="5dc6ddaa5e6129ce4fa9928bdcd44c56"/><file name="Product.php" hash="ead9fece42fa1a155a2a5a12f54b1d15"/></dir><file name="Observer.php" hash="d084e9b8beb56e00dab2a1036a7b476d"/><dir name="Resource"><dir name="Customer"><file name="Collection.php" hash="0c99b46d5108a6fe31cad1190d8ef47c"/></dir><file name="Customer.php" hash="f92e4e5334b5e3493e8f04664b20f105"/><file name="Setup.php" hash="506b08bcb10cbe74e95812c5f646429f"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="NostoController.php" hash="6d0825f3190db7734637368c262d3c83"/></dir><file name="ExportController.php" hash="ab178910035ea0ba5524c88c66e73e18"/><file name="OauthController.php" hash="e57a2578535e711ce1bdcb78e3fa1983"/></dir><dir name="etc"><file name="adminhtml.xml" hash="70f3a22856ec6cb31749a92ed4461b6b"/><file name="cache.xml" hash="e874fbbf2eb89b325deb1a62afbcfb4d"/><file name="config.xml" hash="717904bbef1d6fdeeae3f67e4a4f094f"/></dir><dir name="sql"><dir name="tagging_setup"><file name="mysql4-install-1.2.0.php" hash="3cbc52834c44870859562eec7969b9fd"/><file name="mysql4-upgrade-1.1.7-1.2.0.php" hash="0d8eb7990461a9d4b74b479120067aeb"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="nostotagging"><file name="iframe.phtml" hash="c81931adf855a4893e0cf2dc60c390cb"/><file name="wizard.phtml" hash="3f92e94e5ee3d3cd9906a6b0942a3a1b"/></dir></dir><dir name="layout"><file name="nostotagging.xml" hash="5f77c6921f67d08484c6d510b4706c29"/></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="nostotagging"><file name="addtocart.phtml" hash="e8776f59ec4c7c7b6eea2fae9d56e2a4"/><file name="cart.phtml" hash="c3d560050239066c73b1ec935048dbee"/><dir name="category"><file name="view.phtml" hash="fc09e2770ad6281ec96c8e92accc01f1"/></dir><file name="category.phtml" hash="81f36742cb4e3adbf9f692cc8f0ea8a8"/><file name="customer.phtml" hash="e9bc92bb7f7df989cc706c7eaee3614a"/><file name="element.phtml" hash="e1d38981789e632a3607ccf2e171f0cb"/><file name="embed.phtml" hash="9193ddd1ae373b68c53f8364f511b0a5"/><file name="meta.phtml" hash="c1b862a4993503fae420fb0eba194b00"/><file name="order.phtml" hash="7d65566ba4ee709dab7f2114340742af"/><file name="product.phtml" hash="412b7bd9ed43981f056132ea37719aab"/></dir></dir><dir name="layout"><file name="nostotagging.xml" hash="8adc3eecf5f90feffabee29d6308912b"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Nosto_Tagging.xml" hash="1705cb7e6db28388662ef52882d61701"/></dir></target><target name="magelib"><dir name="nosto"><dir name="php-sdk"><dir name="src"><dir name="classes"><file name="Nosto.php" hash="c595c5f646f6e513b6604848f8d10118"/><file name="NostoAccount.php" hash="e245046832cd1655f456da6e999c1af7"/><file name="NostoCipher.php" hash="a3d7d148311aa0319387c0918e5e26dc"/><file name="NostoDotEnv.php" hash="90b23c1b02095c9368372f1d5346c3f9"/><file name="NostoMessage.php" hash="5933eadd2ad08427010b0bf16657266b"/><file name="NostoModelValidator.php" hash="5c978de7b8df8d06a3f5562b65db605c"/><file name="NostoOrderConfirmation.php" hash="2a3fd5efb196bc0dcb7ad57fb61a81d0"/><file name="NostoProductReCrawl.php" hash="c0c249070fe947e1f99ec67066d1e5cb"/><dir name="api"><file name="NostoApiRequest.php" hash="ce6e27815d268847cf629caf48323b6d"/><file name="NostoApiToken.php" hash="ca42b406a88735ac1565bf13efdf8a04"/></dir><dir name="collection"><file name="NostoCollection.php" hash="35cea0282628354413f629062b58663a"/><file name="NostoOrderCollection.php" hash="db6f517948c1258e1521ceb1ce49d477"/><file name="NostoProductCollection.php" hash="3ae29dbbcb7effa234fa83461d3e6901"/></dir><dir name="exception"><file name="NostoException.php" hash="c4610fb70278d01bd85bc83b8e74df30"/><file name="NostoHttpException.php" hash="dabf4298746db898c8fe709ea9e25818"/></dir><dir name="export"><file name="NostoExportOrderCollection.php" hash="d45096eef64e26e8dc3f5c042e52f938"/><file name="NostoExportProductCollection.php" hash="84349c0a7080a4f154c2d9e29d4e621f"/><file name="NostoExporter.php" hash="b72305e0a18c8afa6a3ee4f2e37049a0"/></dir><dir name="helper"><file name="NostoHelper.php" hash="f4ca6c78e047fec93c32b7eb822b0692"/><file name="NostoHelperDate.php" hash="081a2d8bfec710f2baa52192a99a2658"/><file name="NostoHelperIframe.php" hash="1364153a359dcfdf22f7376aba66da47"/><file name="NostoHelperPrice.php" hash="ee9f217dc1b8e0fc679fb56ca3fd3ca1"/></dir><dir name="http"><file name="NostoHttpRequest.php" hash="7872c46736ef462e5820229d1b16bd0d"/><file name="NostoHttpRequestAdapter.php" hash="d8bf8e5db44ad982b655372529f4d88c"/><file name="NostoHttpRequestAdapterCurl.php" hash="c903ab33e7c326528600c26501e8609a"/><file name="NostoHttpRequestAdapterSocket.php" hash="88f57e6d98de2ac652a235e2786f0be7"/><file name="NostoHttpResponse.php" hash="68a5c65b0bf9a212db0138e7b5d764e1"/></dir><dir name="oauth"><file name="NostoOAuthClient.php" hash="2672d9de80d23c91776d97b9803d01b4"/><file name="NostoOAuthToken.php" hash="f81c1c1e5c4fc2010162d8f69de2cb33"/></dir><dir name="operation"><file name="NostoOperationProduct.php" hash="14b9b8c02a890630df0164a244ae1715"/></dir></dir><file name="config.inc.php" hash="a7ca6d6fb79ae7b5a9fb29b4c7235ed7"/><dir name="interfaces"><file name="NostoExportCollectionInterface.php" hash="63c833c17fe43ce48b45e0f552313a8b"/><file name="NostoOAuthClientMetaDataInterface.php" hash="75a82417bfc27cd82e41ea9810d31428"/><file name="NostoProductInterface.php" hash="110aabc704bed12ddacc304d6d1e1529"/><file name="NostoValidatableModelInterface.php" hash="452d7c40b94573590c9b9f70189931fa"/><dir name="account"><file name="NostoAccountInterface.php" hash="5655c43db9e1e0a8e1fd23753ec5ef06"/><file name="NostoAccountMetaDataBillingDetailsInterface.php" hash="ef31f0c3b41591fd76f85a25021f0fe4"/><file name="NostoAccountMetaDataIframeInterface.php" hash="c739e6a3ef39a308df6852361f2fd1d7"/><file name="NostoAccountMetaDataInterface.php" hash="7395de56fb4e3a1831bc5f7cfeffed8d"/><file name="NostoAccountMetaDataOwnerInterface.php" hash="4c037b8cb1b529c16c91f25cce2b0ed7"/></dir><dir name="order"><file name="NostoOrderBuyerInterface.php" hash="890884e45bcca61f96f0f98cda40b6c1"/><file name="NostoOrderInterface.php" hash="d341b4faf020bfca01336c5d60ca5e48"/><file name="NostoOrderPurchasedItemInterface.php" hash="e33b94290465eea80d614db35144b75a"/><file name="NostoOrderStatusInterface.php" hash="8c89cf4296629b635f52b53a9b800b1f"/></dir></dir><dir name="js"><file name="NostoIframe.min.js" hash="b4508aed29b641e6ad3d1062a54c209f"/><dir name="src"><file name="NostoIframe.js" hash="e9962928ba1cf0ff205e21a0d469f4d8"/></dir></dir><dir name="libs"><dir name="phpseclib"><dir name="crypt"><file name="NostoCryptAES.php" hash="7f16ec6fa7eefa011a27acf4506a3b57"/><file name="NostoCryptBase.php" hash="c78432d428ad8a70be832f91261d4c42"/><file name="NostoCryptRandom.php" hash="eb21a56b9cf6e6ef0b220620dd4d0ebe"/><file name="NostoCryptRijndael.php" hash="9c728d06c0249f8bc24a7c61606ccc89"/></dir></dir></dir><file name=".env.example" hash="ec9fd4d90a792e2c98b10ff8fe7ae984"/></dir></dir></dir></target><target name="mage"><dir name="js"><dir name="nosto"><file name="NostoIframe.min.js" hash="b4508aed29b641e6ad3d1062a54c209f"/><file name="iframeresizer.min.js" hash="163b065c9dd702dc364913a951b81fee"/><file name="nostotagging-config.js" hash="0119fb333233f1f0fa70f4167fb014ef"/></dir></dir></target></contents>
18
  <compatible/>
19
+ <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php><package><name>Mage_Core_Modules</name><channel>community</channel><min>1.6.0.0</min><max>1.9.1.1</max></package></required></dependencies>
20
  </package>