Nosto_Tagging - Version 2.6.8

Version Notes

- Tagging for 404 pages and order confirmation page
- Loosen up the data validation
- Fix tagging currency for product
- Enhance product and order exports

Download this release

Release Info

Developer Nosto
Extension Nosto_Tagging
Version 2.6.8
Comparing to
See all releases


Code changes from version 2.6.7.1 to 2.6.8

app/code/community/Nosto/Tagging/Helper/Account.php CHANGED
@@ -140,6 +140,9 @@ class Nosto_Tagging_Helper_Account extends Mage_Core_Helper_Abstract
140
  );
141
  if (is_array($tokens) && !empty($tokens)) {
142
  foreach ($tokens as $name => $value) {
 
 
 
143
  $token = new NostoApiToken($name, $value);
144
  $account->addApiToken($token);
145
  }
140
  );
141
  if (is_array($tokens) && !empty($tokens)) {
142
  foreach ($tokens as $name => $value) {
143
+ if (!in_array($name, NostoApiToken::$tokenNames)) {
144
+ continue;
145
+ }
146
  $token = new NostoApiToken($name, $value);
147
  $account->addApiToken($token);
148
  }
app/code/community/Nosto/Tagging/Helper/Customer.php CHANGED
@@ -34,11 +34,6 @@
34
  */
35
  class Nosto_Tagging_Helper_Customer extends Mage_Core_Helper_Abstract
36
  {
37
- /**
38
- * @var string the name of the cookie where the Nosto ID can be found.
39
- */
40
- const COOKIE_NAME = '2c_cId';
41
-
42
  /**
43
  * Gets the Nosto ID for an order model.
44
  * The Nosto ID represents the customer who placed to the order on Nosto's
@@ -70,7 +65,7 @@ class Nosto_Tagging_Helper_Customer extends Mage_Core_Helper_Abstract
70
  $quoteId = ($cart->getQuote() !== null)
71
  ? $cart->getQuote()->getId()
72
  : false;
73
- $nostoId = $cookie->get(self::COOKIE_NAME);
74
  if (!empty($quoteId) && !empty($nostoId)) {
75
  /** @var Nosto_Tagging_Model_Customer $customer */
76
  $customer = Mage::getModel('nosto_tagging/customer')
34
  */
35
  class Nosto_Tagging_Helper_Customer extends Mage_Core_Helper_Abstract
36
  {
 
 
 
 
 
37
  /**
38
  * Gets the Nosto ID for an order model.
39
  * The Nosto ID represents the customer who placed to the order on Nosto's
65
  $quoteId = ($cart->getQuote() !== null)
66
  ? $cart->getQuote()->getId()
67
  : false;
68
+ $nostoId = $cookie->get(Nosto_Tagging_Helper_Data::COOKIE_NAME);
69
  if (!empty($quoteId) && !empty($nostoId)) {
70
  /** @var Nosto_Tagging_Model_Customer $customer */
71
  $customer = Mage::getModel('nosto_tagging/customer')
app/code/community/Nosto/Tagging/Helper/Data.php CHANGED
@@ -44,6 +44,16 @@ class Nosto_Tagging_Helper_Data extends Mage_Core_Helper_Abstract
44
  */
45
  const XML_PATH_IMAGE_VERSION = 'nosto_tagging/image_options/image_version';
46
 
 
 
 
 
 
 
 
 
 
 
47
  /**
48
  * @inheritdoc
49
  */
44
  */
45
  const XML_PATH_IMAGE_VERSION = 'nosto_tagging/image_options/image_version';
46
 
47
+ /**
48
+ * @var string the name of the cookie where the Nosto ID can be found.
49
+ */
50
+ const COOKIE_NAME = '2c_cId';
51
+
52
+ /**
53
+ * @var string the name of the cookie where the Nosto ID can be found.
54
+ */
55
+ const VISITOR_HASH_ALGO = 'sha256';
56
+
57
  /**
58
  * @inheritdoc
59
  */
app/code/community/Nosto/Tagging/Helper/Price.php CHANGED
@@ -127,4 +127,44 @@ class Nosto_Tagging_Helper_Price extends Mage_Core_Helper_Abstract
127
 
128
  return $price;
129
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  }
127
 
128
  return $price;
129
  }
130
+
131
+ /**
132
+ * @param float $price
133
+ * @param Mage_Core_Model_Store $store
134
+ * @return float
135
+ */
136
+ public function convertToDefaultCurrency($price, Mage_Core_Model_Store $store)
137
+ {
138
+ if (!is_numeric($price)) {
139
+ Mage::log(
140
+ sprintf(
141
+ 'price must be a numeric value in %s, got %s.',
142
+ __CLASS__,
143
+ $price
144
+ ),
145
+ Zend_Log::WARN,
146
+ Nosto_Tagging_Model_Base::LOG_FILE_NAME
147
+ );
148
+ $price = 0;
149
+ }
150
+ return Mage::helper('directory')->currencyConvert(
151
+ $price,
152
+ $store->getBaseCurrency()->getCode(),
153
+ $store->getDefaultCurrency()->getCode()
154
+ );
155
+ }
156
+
157
+ /**
158
+ * Get the final price in base currency for an ordered item including
159
+ * taxes as discounts.
160
+ *
161
+ * @param Mage_Sales_Model_Order_Item $item the item model.
162
+ *
163
+ * @return float
164
+ */
165
+ public function getItemFinalPriceInclTax(Mage_Sales_Model_Order_Item $item)
166
+ {
167
+ $price = $item->getBaseRowTotal() + $item->getBaseTaxAmount() + $item->getBaseHiddenTaxAmount() - $item->getBaseDiscountAmount();
168
+ return $price;
169
+ }
170
  }
app/code/community/Nosto/Tagging/Model/Base.php CHANGED
@@ -34,6 +34,12 @@
34
  */
35
  class Nosto_Tagging_Model_Base extends Mage_Core_Model_Abstract
36
  {
 
 
 
 
 
 
37
  /**
38
  * Returns a protected/private property value by invoking it's public getter.
39
  *
34
  */
35
  class Nosto_Tagging_Model_Base extends Mage_Core_Model_Abstract
36
  {
37
+
38
+ /**
39
+ * Log file for plugin related messages.
40
+ */
41
+ const LOG_FILE_NAME = 'nostotagging.log';
42
+
43
  /**
44
  * Returns a protected/private property value by invoking it's public getter.
45
  *
app/code/community/Nosto/Tagging/Model/Meta/Order.php CHANGED
@@ -102,7 +102,14 @@ class Nosto_Tagging_Model_Meta_Order extends Mage_Core_Model_Abstract implements
102
  $this->_orderNumber = $order->getId();
103
  $this->_externalOrderRef = $order->getRealOrderId();
104
  $this->_createdDate = $order->getCreatedAt();
105
- $this->_paymentProvider = $order->getPayment()->getMethod();
 
 
 
 
 
 
 
106
 
107
  if ($order->getStatus()) {
108
  $this->_orderStatus = Mage::getModel(
@@ -143,14 +150,14 @@ class Nosto_Tagging_Model_Meta_Order extends Mage_Core_Model_Abstract implements
143
  }
144
 
145
  if ($this->includeSpecialItems) {
146
- if (($discount = $order->getDiscountAmount()) > 0) {
147
  /** @var Nosto_Tagging_Model_Meta_Order_Item $orderItem */
148
  $this->_items[] = Mage::getModel(
149
  'nosto_tagging/meta_order_item',
150
  array(
151
  'productId' => -1,
152
  'quantity' => 1,
153
- 'name' => 'Discount',
154
  'unitPrice' => $discount,
155
  'currencyCode' => $order->getOrderCurrencyCode()
156
  )
@@ -173,6 +180,40 @@ class Nosto_Tagging_Model_Meta_Order extends Mage_Core_Model_Abstract implements
173
  }
174
  }
175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  /**
177
  * Builds a order items object form the Magento sales item.
178
  *
@@ -183,13 +224,15 @@ class Nosto_Tagging_Model_Meta_Order extends Mage_Core_Model_Abstract implements
183
  */
184
  protected function buildItem(Mage_Sales_Model_Order_Item $item, Mage_Sales_Model_Order $order)
185
  {
 
 
186
  return Mage::getModel(
187
  'nosto_tagging/meta_order_item',
188
  array(
189
  'productId' => (int)$this->buildItemProductId($item),
190
  'quantity' => (int)$item->getQtyOrdered(),
191
  'name' => $this->buildItemName($item),
192
- 'unitPrice' => $item->getPriceInclTax(),
193
  'currencyCode' => $order->getOrderCurrencyCode()
194
  )
195
  );
102
  $this->_orderNumber = $order->getId();
103
  $this->_externalOrderRef = $order->getRealOrderId();
104
  $this->_createdDate = $order->getCreatedAt();
105
+ if (
106
+ $order->getPayment()
107
+ && method_exists($order->getPayment(), 'getMethod')
108
+ ) {
109
+ $this->_paymentProvider = $order->getPayment()->getMethod();
110
+ } else {
111
+ $this->_paymentProvider = '';
112
+ }
113
 
114
  if ($order->getStatus()) {
115
  $this->_orderStatus = Mage::getModel(
150
  }
151
 
152
  if ($this->includeSpecialItems) {
153
+ if (($discount = $order->getDiscountAmount()) < 0) {
154
  /** @var Nosto_Tagging_Model_Meta_Order_Item $orderItem */
155
  $this->_items[] = Mage::getModel(
156
  'nosto_tagging/meta_order_item',
157
  array(
158
  'productId' => -1,
159
  'quantity' => 1,
160
+ 'name' => $this->buildDiscountRuleDescription($order),
161
  'unitPrice' => $discount,
162
  'currencyCode' => $order->getOrderCurrencyCode()
163
  )
180
  }
181
  }
182
 
183
+ /**
184
+ * Generates a textual description of the applied discount rules
185
+ *
186
+ * @param Mage_Sales_Model_Order $order
187
+ * @return string discount description
188
+ */
189
+ protected function buildDiscountRuleDescription(Mage_Sales_Model_Order $order)
190
+ {
191
+ try {
192
+ $appliedRules = array();
193
+ foreach ($order->getAllVisibleItems() as $item) {
194
+ $itemAppliedRules = $item->getAppliedRuleIds();
195
+ if (empty($itemAppliedRules)) {
196
+ continue;
197
+ }
198
+ $ruleIds = explode(',', $item->getAppliedRuleIds());
199
+ foreach ($ruleIds as $ruleId) {
200
+ $rule = Mage::getModel('salesrule/rule')->load($ruleId);
201
+ $appliedRules[$ruleId] = $rule->getName();
202
+ }
203
+ }
204
+ if (count($appliedRules) == 0) {
205
+ $appliedRules[] = 'unknown rule';
206
+ }
207
+ $discountTxt = sprintf(
208
+ 'Discount (%s)', implode(', ', $appliedRules)
209
+ );
210
+ } catch(\Exception $e) {
211
+ $discountTxt = 'Discount (error)';
212
+ }
213
+
214
+ return $discountTxt;
215
+ }
216
+
217
  /**
218
  * Builds a order items object form the Magento sales item.
219
  *
224
  */
225
  protected function buildItem(Mage_Sales_Model_Order_Item $item, Mage_Sales_Model_Order $order)
226
  {
227
+ /* @var Nosto_Tagging_Helper_Price */
228
+ $nostoPriceHelper = Mage::helper('nosto_tagging/price');
229
  return Mage::getModel(
230
  'nosto_tagging/meta_order_item',
231
  array(
232
  'productId' => (int)$this->buildItemProductId($item),
233
  'quantity' => (int)$item->getQtyOrdered(),
234
  'name' => $this->buildItemName($item),
235
+ 'unitPrice' => $nostoPriceHelper->getItemFinalPriceInclTax($item),
236
  'currencyCode' => $order->getOrderCurrencyCode()
237
  )
238
  );
app/code/community/Nosto/Tagging/Model/Meta/Order/Buyer.php CHANGED
@@ -57,30 +57,46 @@ class Nosto_Tagging_Model_Meta_Order_Buyer extends Mage_Core_Model_Abstract impl
57
  * Sets up this Value Object.
58
  *
59
  * @param array $args the object data.
60
- *
61
- * @throws InvalidArgumentException
62
  */
63
  public function __construct(array $args)
64
  {
65
- if (isset($args['firstName'])) {
66
- if (!is_string($args['firstName'])) {
67
- throw new InvalidArgumentException(sprintf('%s.firstName must be a string value.', __CLASS__));
68
- }
 
 
 
 
 
 
69
  }
70
- if (isset($args['lastName'])) {
71
- if (!is_string($args['lastName'])) {
72
- throw new InvalidArgumentException(sprintf('%s.lastName must be a string value.', __CLASS__));
73
- }
 
 
 
 
 
 
74
  }
75
- if (isset($args['email'])) {
76
- if (!is_string($args['email'])) {
77
- throw new InvalidArgumentException(sprintf('%s.email must be a string value.', __CLASS__));
78
- }
 
 
 
 
 
 
79
  }
80
 
81
- $this->_firstName = !empty($args['firstName']) ? $args['firstName'] : null;
82
- $this->_lastName = !empty($args['lastName']) ? $args['lastName'] : null;
83
- $this->_email = !empty($args['email']) ? $args['email'] : null;
84
  }
85
 
86
  /**
57
  * Sets up this Value Object.
58
  *
59
  * @param array $args the object data.
 
 
60
  */
61
  public function __construct(array $args)
62
  {
63
+ if (!isset($args['firstName']) || !is_string($args['firstName'])) {
64
+ Mage::log(
65
+ sprintf(
66
+ '%s.firstName must be a string value',
67
+ __CLASS__
68
+ ),
69
+ Zend_Log::WARN,
70
+ Nosto_Tagging_Model_Base::LOG_FILE_NAME
71
+ );
72
+ $args['firstName'] = '';
73
  }
74
+ if (!isset($args['lastName']) || !is_string($args['lastName'])) {
75
+ Mage::log(
76
+ sprintf(
77
+ '%s.lastName must be a string value',
78
+ __CLASS__
79
+ ),
80
+ Zend_Log::WARN,
81
+ Nosto_Tagging_Model_Base::LOG_FILE_NAME
82
+ );
83
+ $args['lastName'] = '';
84
  }
85
+ if (!isset($args['email']) || !is_string($args['email'])) {
86
+ Mage::log(
87
+ sprintf(
88
+ '%s.email must be a string value',
89
+ __CLASS__
90
+ ),
91
+ Zend_Log::WARN,
92
+ Nosto_Tagging_Model_Base::LOG_FILE_NAME
93
+ );
94
+ $args['email'] = '';
95
  }
96
 
97
+ $this->_firstName = $args['firstName'];
98
+ $this->_lastName = $args['lastName'];
99
+ $this->_email = $args['email'];
100
  }
101
 
102
  /**
app/code/community/Nosto/Tagging/Model/Meta/Order/Item.php CHANGED
@@ -68,25 +68,63 @@ class Nosto_Tagging_Model_Meta_Order_Item extends Mage_Core_Model_Abstract imple
68
  * Sets up this Value Object.
69
  *
70
  * @param array $args the object data.
71
- *
72
- * @throws InvalidArgumentException
73
  */
74
  public function __construct(array $args)
75
  {
76
  if (!isset($args['productId']) || !is_int($args['productId'])) {
77
- throw new InvalidArgumentException(sprintf('%s.productId must be a integer value.', __CLASS__));
 
 
 
 
 
 
 
 
78
  }
79
  if (!isset($args['quantity']) || !is_int($args['quantity']) || !($args['quantity'] > 0)) {
80
- throw new InvalidArgumentException(sprintf('%s.quantity must be a integer value above zero.', __CLASS__));
 
 
 
 
 
 
 
 
81
  }
82
  if (!isset($args['name']) || !is_string($args['name']) || empty($args['name'])) {
83
- throw new InvalidArgumentException(sprintf('%s.name must be a non-empty string value.', __CLASS__));
 
 
 
 
 
 
 
 
84
  }
85
  if (!isset($args['unitPrice']) || !is_numeric($args['unitPrice'])) {
86
- throw new InvalidArgumentException(sprintf('%s.unitPrice must be a numeric value.', __CLASS__));
 
 
 
 
 
 
 
 
87
  }
88
  if (!isset($args['currencyCode']) || !is_string($args['currencyCode']) || empty($args['currencyCode'])) {
89
- throw new InvalidArgumentException(sprintf('%s.currencyCode must be a non-empty string value.', __CLASS__));
 
 
 
 
 
 
 
 
90
  }
91
 
92
  $this->_productId = $args['productId'];
68
  * Sets up this Value Object.
69
  *
70
  * @param array $args the object data.
 
 
71
  */
72
  public function __construct(array $args)
73
  {
74
  if (!isset($args['productId']) || !is_int($args['productId'])) {
75
+ Mage::log(
76
+ sprintf(
77
+ '%s.productId must be an integer value',
78
+ __CLASS__
79
+ ),
80
+ Zend_Log::WARN,
81
+ Nosto_Tagging_Model_Base::LOG_FILE_NAME
82
+ );
83
+ $args['productId'] = '';
84
  }
85
  if (!isset($args['quantity']) || !is_int($args['quantity']) || !($args['quantity'] > 0)) {
86
+ Mage::log(
87
+ sprintf(
88
+ '%s.quantity must be an integer value',
89
+ __CLASS__
90
+ ),
91
+ Zend_Log::WARN,
92
+ Nosto_Tagging_Model_Base::LOG_FILE_NAME
93
+ );
94
+ $args['quantity'] = '';
95
  }
96
  if (!isset($args['name']) || !is_string($args['name']) || empty($args['name'])) {
97
+ Mage::log(
98
+ sprintf(
99
+ '%s.name must be a non-empty string value',
100
+ __CLASS__
101
+ ),
102
+ Zend_Log::WARN,
103
+ Nosto_Tagging_Model_Base::LOG_FILE_NAME
104
+ );
105
+ $args['name'] = '';
106
  }
107
  if (!isset($args['unitPrice']) || !is_numeric($args['unitPrice'])) {
108
+ Mage::log(
109
+ sprintf(
110
+ '%s.unitPrice must be a numeric value',
111
+ __CLASS__
112
+ ),
113
+ Zend_Log::WARN,
114
+ Nosto_Tagging_Model_Base::LOG_FILE_NAME
115
+ );
116
+ $args['unitPrice'] = '';
117
  }
118
  if (!isset($args['currencyCode']) || !is_string($args['currencyCode']) || empty($args['currencyCode'])) {
119
+ Mage::log(
120
+ sprintf(
121
+ '%s.currencyCode must be a numeric value',
122
+ __CLASS__
123
+ ),
124
+ Zend_Log::WARN,
125
+ Nosto_Tagging_Model_Base::LOG_FILE_NAME
126
+ );
127
+ $args['currencyCode'] = '';
128
  }
129
 
130
  $this->_productId = $args['productId'];
app/code/community/Nosto/Tagging/Model/Meta/Order/Status.php CHANGED
@@ -58,27 +58,52 @@ class Nosto_Tagging_Model_Meta_Order_Status extends Mage_Core_Model_Abstract imp
58
  *
59
  * @param array $args the object data.
60
  *
61
- * @throws InvalidArgumentException
62
  */
63
  public function __construct(array $args)
64
  {
65
- if (!isset($args['code']) || !is_string($args['code']) || empty($args['code'])) {
66
- throw new InvalidArgumentException(sprintf('%s.code must be a non-empty string value.', __CLASS__));
 
 
 
 
 
 
 
 
67
  }
68
- if (isset($args['label'])) {
69
- if (!is_string($args['label'])) {
70
- throw new InvalidArgumentException(sprintf('%s.label must be a string value.', __CLASS__));
71
- }
 
 
 
 
 
 
 
72
  }
 
73
  if (isset($args['createdAt'])) {
74
- if (!is_string($args['createdAt']) || strtotime($args['createdAt']) === false) {
75
- throw new InvalidArgumentException(sprintf('%s.createdAt must be a valid date.', __CLASS__));
 
 
 
 
 
 
 
 
76
  }
 
 
77
  }
78
 
79
  $this->_code = $args['code'];
80
- $this->_label = !empty($args['label']) ? $args['label'] : $args['code'];
81
- $this->_createdAt = isset($args['createdAt']) ? $args['createdAt'] : null;
82
  }
83
 
84
  /**
58
  *
59
  * @param array $args the object data.
60
  *
 
61
  */
62
  public function __construct(array $args)
63
  {
64
+ if (!isset($args['code']) || !is_string($args['code'])) {
65
+ Mage::log(
66
+ sprintf(
67
+ '%s.code must be a non-empty string value',
68
+ __CLASS__
69
+ ),
70
+ Zend_Log::WARN,
71
+ Nosto_Tagging_Model_Base::LOG_FILE_NAME
72
+ );
73
+ $args['code'] = '';
74
  }
75
+
76
+ if (!isset($args['label'])) {
77
+ Mage::log(
78
+ sprintf(
79
+ '%s.label is not set',
80
+ __CLASS__
81
+ ),
82
+ Zend_Log::WARN,
83
+ Nosto_Tagging_Model_Base::LOG_FILE_NAME
84
+ );
85
+ $args['label'] = $args['code'];
86
  }
87
+
88
  if (isset($args['createdAt'])) {
89
+ if (empty($args['createdAt'])) {
90
+ Mage::log(
91
+ sprintf(
92
+ '%s.createdAt is not set',
93
+ __CLASS__
94
+ ),
95
+ Zend_Log::WARN,
96
+ Nosto_Tagging_Model_Base::LOG_FILE_NAME
97
+ );
98
+ $args['createdAt'] = '';
99
  }
100
+ } else {
101
+ $args['createdAt'] = '';
102
  }
103
 
104
  $this->_code = $args['code'];
105
+ $this->_label = $args['label'];
106
+ $this->_createdAt = $args['createdAt'];
107
  }
108
 
109
  /**
app/code/community/Nosto/Tagging/Model/Meta/Product.php CHANGED
@@ -174,9 +174,9 @@ class Nosto_Tagging_Model_Meta_Product extends Nosto_Tagging_Model_Base implemen
174
  $this->_productId = $product->getId();
175
  $this->_name = $product->getName();
176
  $this->_imageUrl = $this->buildImageUrl($product, $store);
177
- $this->_price = $priceHelper->getProductFinalPriceInclTax($product);
178
- $this->_listPrice = $priceHelper->getProductPriceInclTax($product);
179
- $this->_currencyCode = $store->getCurrentCurrencyCode();
180
  $this->_availability = $product->isAvailable()
181
  ? self::PRODUCT_IN_STOCK
182
  : self::PRODUCT_OUT_OF_STOCK;
174
  $this->_productId = $product->getId();
175
  $this->_name = $product->getName();
176
  $this->_imageUrl = $this->buildImageUrl($product, $store);
177
+ $this->_price = $priceHelper->convertToDefaultCurrency($priceHelper->getProductFinalPriceInclTax($product), $store);
178
+ $this->_listPrice = $priceHelper->convertToDefaultCurrency($priceHelper->getProductPriceInclTax($product), $store);
179
+ $this->_currencyCode = $store->getDefaultCurrency()->getCode();
180
  $this->_availability = $product->isAvailable()
181
  ? self::PRODUCT_IN_STOCK
182
  : self::PRODUCT_OUT_OF_STOCK;
app/code/community/Nosto/Tagging/Model/Resource/Product/Collection.php CHANGED
@@ -43,4 +43,12 @@ class Nosto_Tagging_Model_Resource_Product_Collection extends Mage_Catalog_Model
43
  // Never use the flat collection.
44
  return false;
45
  }
 
 
 
 
 
 
 
 
46
  }
43
  // Never use the flat collection.
44
  return false;
45
  }
46
+
47
+ /**
48
+ * Returns the name of model(s) in collection
49
+ * @return string
50
+ */
51
+ public function getModelName() {
52
+ return "nosto_tagging/product";
53
+ }
54
  }
app/code/community/Nosto/Tagging/controllers/Adminhtml/NostoController.php CHANGED
@@ -166,7 +166,7 @@ class Nosto_Tagging_Adminhtml_NostoController extends Mage_Adminhtml_Controller_
166
  }
167
  } catch (NostoException $e) {
168
  Mage::log(
169
- "\n" . $e->__toString(), Zend_Log::ERR, 'nostotagging.log'
170
  );
171
  }
172
  }
@@ -251,4 +251,14 @@ class Nosto_Tagging_Adminhtml_NostoController extends Mage_Adminhtml_Controller_
251
  return null;
252
  }
253
  }
 
 
 
 
 
 
 
 
 
 
254
  }
166
  }
167
  } catch (NostoException $e) {
168
  Mage::log(
169
+ "\n" . $e->__toString(), Zend_Log::ERR, Nosto_Tagging_Model_Base::LOG_FILE_NAME
170
  );
171
  }
172
  }
251
  return null;
252
  }
253
  }
254
+
255
+ /**
256
+ * Checks if logged in user has privilege to access Nosto settings
257
+ *
258
+ * @return boolean
259
+ */
260
+ protected function _isAllowed()
261
+ {
262
+ return Mage::getSingleton('admin/session')->isAllowed('nosto');
263
+ }
264
  }
app/code/community/Nosto/Tagging/controllers/ExportController.php CHANGED
@@ -39,6 +39,43 @@ require_once Mage::getBaseDir('lib') . '/nosto/php-sdk/src/config.inc.php';
39
  */
40
  class Nosto_Tagging_ExportController extends Mage_Core_Controller_Front_Action
41
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  /**
43
  * Exports completed orders from the current store.
44
  * Result can be limited by the `limit` and `offset` GET parameters.
@@ -46,15 +83,16 @@ class Nosto_Tagging_ExportController extends Mage_Core_Controller_Front_Action
46
  public function orderAction()
47
  {
48
  if (Mage::helper('nosto_tagging')->isModuleEnabled()) {
49
- $pageSize = (int)$this->getRequest()->getParam('limit', 100);
50
- $currentOffset = (int)$this->getRequest()->getParam('offset', 0);
51
  $currentPage = ($currentOffset / $pageSize) + 1;
52
  /** @var Mage_Sales_Model_Resource_Order_Collection $orders */
53
- $orders = Mage::getModel('sales/order')
54
- ->getCollection()
55
- ->addFieldToFilter('store_id', Mage::app()->getStore()->getId())
56
  ->setPageSize($pageSize)
57
- ->setCurPage($currentPage);
 
58
  if ($currentPage > $orders->getLastPageNumber()) {
59
  $orders = array();
60
  }
@@ -64,7 +102,7 @@ class Nosto_Tagging_ExportController extends Mage_Core_Controller_Front_Action
64
  /** @var Nosto_Tagging_Model_Meta_Order $meta */
65
  $meta = Mage::getModel('nosto_tagging/meta_order');
66
  // We don't need special items like shipping cost and discounts.
67
- $meta->includeSpecialItems = false;
68
  $meta->loadData($order);
69
  $collection[] = $meta;
70
  }
@@ -79,15 +117,15 @@ class Nosto_Tagging_ExportController extends Mage_Core_Controller_Front_Action
79
  public function productAction()
80
  {
81
  if (Mage::helper('nosto_tagging')->isModuleEnabled()) {
82
- $pageSize = (int)$this->getRequest()->getParam('limit', 100);
83
- $currentOffset = (int)$this->getRequest()->getParam('offset', 0);
84
  $currentPage = ($currentOffset / $pageSize) + 1;
85
  // We use our own collection object to avoid issues with the product
86
  // flat collection. It's missing required data by default.
87
  /** @var Nosto_Tagging_Model_Resource_Product_Collection $products */
88
- $products = Mage::getModel('nosto_tagging/product')
89
- ->getCollection()
90
- ->addStoreFilter(Mage::app()->getStore()->getId())
91
  ->addAttributeToSelect('*')
92
  ->addAttributeToFilter(
93
  'status', array(
@@ -99,7 +137,8 @@ class Nosto_Tagging_ExportController extends Mage_Core_Controller_Front_Action
99
  Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH
100
  )
101
  ->setPageSize($pageSize)
102
- ->setCurPage($currentPage);
 
103
  if ($currentPage > $products->getLastPageNumber()) {
104
  $products = array();
105
  }
39
  */
40
  class Nosto_Tagging_ExportController extends Mage_Core_Controller_Front_Action
41
  {
42
+ const ID = 'id';
43
+ const LIMIT = 'limit';
44
+ const OFFSET = 'offset';
45
+ const CREATED_AT = 'created_at';
46
+
47
+ private static $searchableFields = array(
48
+ 'sales/order' => array(
49
+ self::ID => 'entity_id'
50
+ ),
51
+ 'nosto_tagging/product' => array(
52
+ self::ID => 'entity_id'
53
+ )
54
+ );
55
+
56
+ protected function applyIdFilters(&$collection) {
57
+ if ($id = $this->getRequest()->getParam(self::ID)) {
58
+ $collectionModel = $collection->getModelName();
59
+ if (
60
+ !empty(self::$searchableFields[$collectionModel])
61
+ && !empty(self::$searchableFields[$collectionModel][self::ID])
62
+ ) {
63
+ $filterByField = self::$searchableFields[$collectionModel][self::ID];
64
+ if (!is_array($id)) {
65
+ $ids = explode(',', $id);
66
+ if (count($ids) > 0) {
67
+ $id = $ids;
68
+ }
69
+ }
70
+ if (is_array($id) && count($id) > 0) {
71
+ $collection->addFieldToFilter($filterByField, array('in' => $id));
72
+ } else {
73
+ $collection->addFieldToFilter($filterByField, $id);
74
+ }
75
+ }
76
+ }
77
+ }
78
+
79
  /**
80
  * Exports completed orders from the current store.
81
  * Result can be limited by the `limit` and `offset` GET parameters.
83
  public function orderAction()
84
  {
85
  if (Mage::helper('nosto_tagging')->isModuleEnabled()) {
86
+ $pageSize = (int)$this->getRequest()->getParam(self::LIMIT, 100);
87
+ $currentOffset = (int)$this->getRequest()->getParam(self::OFFSET, 0);
88
  $currentPage = ($currentOffset / $pageSize) + 1;
89
  /** @var Mage_Sales_Model_Resource_Order_Collection $orders */
90
+ $orders = Mage::getModel('sales/order')->getCollection();
91
+ $this->applyIdFilters($orders);
92
+ $orders->addFieldToFilter('store_id', Mage::app()->getStore()->getId())
93
  ->setPageSize($pageSize)
94
+ ->setCurPage($currentPage)
95
+ ->setOrder(self::CREATED_AT, Varien_Data_Collection::SORT_ORDER_DESC);
96
  if ($currentPage > $orders->getLastPageNumber()) {
97
  $orders = array();
98
  }
102
  /** @var Nosto_Tagging_Model_Meta_Order $meta */
103
  $meta = Mage::getModel('nosto_tagging/meta_order');
104
  // We don't need special items like shipping cost and discounts.
105
+ $meta->includeSpecialItems = true;
106
  $meta->loadData($order);
107
  $collection[] = $meta;
108
  }
117
  public function productAction()
118
  {
119
  if (Mage::helper('nosto_tagging')->isModuleEnabled()) {
120
+ $pageSize = (int)$this->getRequest()->getParam(self::LIMIT, 100);
121
+ $currentOffset = (int)$this->getRequest()->getParam(self::OFFSET, 0);
122
  $currentPage = ($currentOffset / $pageSize) + 1;
123
  // We use our own collection object to avoid issues with the product
124
  // flat collection. It's missing required data by default.
125
  /** @var Nosto_Tagging_Model_Resource_Product_Collection $products */
126
+ $products = Mage::getModel('nosto_tagging/product')->getCollection();
127
+ $this->applyIdFilters($products);
128
+ $products->addStoreFilter(Mage::app()->getStore()->getId())
129
  ->addAttributeToSelect('*')
130
  ->addAttributeToFilter(
131
  'status', array(
137
  Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH
138
  )
139
  ->setPageSize($pageSize)
140
+ ->setCurPage($currentPage)
141
+ ->setOrder(self::CREATED_AT, Varien_Data_Collection::SORT_ORDER_DESC);
142
  if ($currentPage > $products->getLastPageNumber()) {
143
  $products = array();
144
  }
app/code/community/Nosto/Tagging/controllers/OauthController.php CHANGED
@@ -83,7 +83,7 @@ class Nosto_tagging_OauthController extends Mage_Core_Controller_Front_Action
83
  }
84
  } catch (NostoException $e) {
85
  Mage::log(
86
- "\n" . $e->__toString(), Zend_Log::ERR, 'nostotagging.log'
87
  );
88
  $params = array(
89
  'message_type' => NostoMessage::TYPE_ERROR,
@@ -101,7 +101,7 @@ class Nosto_tagging_OauthController extends Mage_Core_Controller_Front_Action
101
  if (($desc = $request->getParam('error_description')) !== null) {
102
  $logMsg .= ' - ' . $desc;
103
  }
104
- Mage::log("\n" . $logMsg, Zend_Log::ERR, 'nostotagging.log');
105
  $this->_redirect(
106
  'adminhtml/nosto/redirectProxy', array(
107
  'message_type' => NostoMessage::TYPE_ERROR,
83
  }
84
  } catch (NostoException $e) {
85
  Mage::log(
86
+ "\n" . $e->__toString(), Zend_Log::ERR, Nosto_Tagging_Model_Base::LOG_FILE_NAME
87
  );
88
  $params = array(
89
  'message_type' => NostoMessage::TYPE_ERROR,
101
  if (($desc = $request->getParam('error_description')) !== null) {
102
  $logMsg .= ' - ' . $desc;
103
  }
104
+ Mage::log("\n" . $logMsg, Zend_Log::ERR, Nosto_Tagging_Model_Base::LOG_FILE_NAME);
105
  $this->_redirect(
106
  'adminhtml/nosto/redirectProxy', array(
107
  'message_type' => NostoMessage::TYPE_ERROR,
app/code/community/Nosto/Tagging/etc/config.xml CHANGED
@@ -29,7 +29,7 @@
29
  <config>
30
  <modules>
31
  <Nosto_Tagging>
32
- <version>2.6.7.1</version>
33
  </Nosto_Tagging>
34
  </modules>
35
  <global>
@@ -66,24 +66,24 @@
66
  </nosto_tagging_resource>
67
  </models>
68
  <events>
69
- <catalog_product_save_after>
70
  <observers>
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>
78
- <catalog_product_delete_after>
79
  <observers>
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>
87
  <sales_order_save_commit_after>
88
  <observers>
89
  <nosto_tagging_sales_order_save_commit_after>
29
  <config>
30
  <modules>
31
  <Nosto_Tagging>
32
+ <version>2.6.8</version>
33
  </Nosto_Tagging>
34
  </modules>
35
  <global>
66
  </nosto_tagging_resource>
67
  </models>
68
  <events>
69
+ <catalog_product_save_commit_after>
70
  <observers>
71
+ <nosto_tagging_catalog_product_save_commit_after>
72
  <type>singleton</type>
73
  <class>Nosto_Tagging_Model_Observer</class>
74
  <method>sendProductUpdate</method>
75
+ </nosto_tagging_catalog_product_save_commit_after>
76
  </observers>
77
+ </catalog_product_save_commit_after>
78
+ <catalog_product_delete_commit_after>
79
  <observers>
80
+ <nosto_tagging_catalog_product_delete_commit_after>
81
  <type>singleton</type>
82
  <class>Nosto_Tagging_Model_Observer</class>
83
  <method>sendProductDelete</method>
84
+ </nosto_tagging_catalog_product_delete_commit_after>
85
  </observers>
86
+ </catalog_product_delete_commit_after>
87
  <sales_order_save_commit_after>
88
  <observers>
89
  <nosto_tagging_sales_order_save_commit_after>
app/design/frontend/base/default/layout/nostotagging.xml CHANGED
@@ -57,6 +57,7 @@
57
  <reference name="after_body_start">
58
  <block type="nosto_tagging/customer" name="nosto.customer" template="nostotagging/customer.phtml"/>
59
  </reference>
 
60
  </default>
61
 
62
  <!-- Tag category -->
@@ -275,4 +276,51 @@
275
  </block>
276
  </reference>
277
  </catalogsearch_result_index>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  </layout>
57
  <reference name="after_body_start">
58
  <block type="nosto_tagging/customer" name="nosto.customer" template="nostotagging/customer.phtml"/>
59
  </reference>
60
+
61
  </default>
62
 
63
  <!-- Tag category -->
276
  </block>
277
  </reference>
278
  </catalogsearch_result_index>
279
+
280
+ <!-- 404 Not found page -->
281
+ <cms_index_noroute>
282
+ <reference name="content">
283
+ <block type="nosto_tagging/element" name="nosto.page.notfound1" after="-"
284
+ template="nostotagging/element.phtml">
285
+ <action method="setData">
286
+ <name>div_id</name>
287
+ <value>notfound-nosto-1</value>
288
+ </action>
289
+ </block>
290
+ <block type="nosto_tagging/element" name="nosto.page.notfound2" after="nosto.page.notfound1"
291
+ template="nostotagging/element.phtml">
292
+ <action method="setData">
293
+ <name>div_id</name>
294
+ <value>notfound-nosto-2</value>
295
+ </action>
296
+ </block>
297
+ <block type="nosto_tagging/element" name="nosto.page.notfound3" after="nosto.page.notfound2"
298
+ template="nostotagging/element.phtml">
299
+ <action method="setData">
300
+ <name>div_id</name>
301
+ <value>notfound-nosto-3</value>
302
+ </action>
303
+ </block>
304
+ </reference>
305
+ </cms_index_noroute>
306
+
307
+ <!-- Order confirmation page -->
308
+ <checkout_onepage_success>
309
+ <reference name="content">
310
+ <block type="nosto_tagging/element" name="nosto.page.orderconfirmation1" after="-"
311
+ template="nostotagging/element.phtml">
312
+ <action method="setData">
313
+ <name>div_id</name>
314
+ <value>thankyou-nosto-1</value>
315
+ </action>
316
+ </block>
317
+ <block type="nosto_tagging/element" name="nosto.page.orderconfirmation2" after="nosto.page.orderconfirmation1"
318
+ template="nostotagging/element.phtml">
319
+ <action method="setData">
320
+ <name>div_id</name>
321
+ <value>thankyou-nosto-2</value>
322
+ </action>
323
+ </block>
324
+ </reference>
325
+ </checkout_onepage_success>
326
  </layout>
lib/nosto/php-sdk/LICENSE.txt DELETED
@@ -1,27 +0,0 @@
1
- Copyright (c) 2015, Nosto Solutions Ltd
2
- All rights reserved.
3
-
4
- Redistribution and use in source and binary forms, with or without modification,
5
- are permitted provided that the following conditions are met:
6
-
7
- 1. Redistributions of source code must retain the above copyright notice,
8
- this list of conditions and the following disclaimer.
9
-
10
- 2. Redistributions in binary form must reproduce the above copyright notice,
11
- this list of conditions and the following disclaimer in the documentation
12
- and/or other materials provided with the distribution.
13
-
14
- 3. Neither the name of the copyright holder nor the names of its contributors
15
- may be used to endorse or promote products derived from this software without
16
- specific prior written permission.
17
-
18
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/nosto/php-sdk/README.md DELETED
@@ -1,416 +0,0 @@
1
- php-sdk
2
- =======
3
-
4
- Provides tools for building modules that integrate Nosto into your e-commerce platform.
5
-
6
- ## Requirements
7
-
8
- * PHP 5.2+
9
-
10
- ## What's included?
11
-
12
- ### Classes
13
-
14
- * **NostoApiRequest** class for making API requests to the Nosto APIs
15
- * **NostoApiToken** class that represents an API token which can be used whn making authenticated requests to the Nosto APIs
16
- * **NostoCollection** collection base class
17
- * **NostoProductCollection** collection class for nosto product objects
18
- * **NostoOrderCollection** collection class for nosto order objects
19
- * **NostoException** main exception class for all exceptions thrown by the SDK
20
- * **NostoHttpException** HTTP request exceptions upon request failure
21
- * **NostoExporter** class for exporting encrypted historical data from the shop
22
- * **NostoExportOrderCollection** class for exporting historical order data
23
- * **NostoExportProductCollection** class for exporting historical product data
24
- * **NostoHelper** base class for all nosto helpers
25
- * **NostoHelperDate** helper class for date related operations
26
- * **NostoHelperIframe** helper class for iframe related operations
27
- * **NostoHelperPrice** helper class for price related operations
28
- * **NostoHttpRequest** class for making HTTP request, supports both curl and socket connections
29
- * **NostoHttpRequestAdapter** base class for creating http request adapters
30
- * **NostoHttpRequestAdapterCurl** http request adapter for making http requests using curl
31
- * **NostoHttpRequestAdapterSocket** http request adapter for making http requests using sockets
32
- * **NostoHttpResponse** class that represents a response for an http request made through the NostoHttpRequest class
33
- * **NostoOAuthClient** class for authorizing the module to act on the Nosto account owners behalf using OAuth2 Authorization Code method
34
- * **NostoOAuthToken** class that represents a token granted using the OAuth client
35
- * **NostoOperationProduct** class for performing create/update/delete operations on product object
36
- * **Nosto** main sdk class for common functionality
37
- * **NostoAccount** class that represents a Nosto account which can be used to create new accounts and connect to existing accounts using OAuth2
38
- * **NostoCipher** class for AES encrypting product/order information that can be exported for Nosto to improve recommendations from the get-go
39
- * **NostoDotEnv** class for handling environment variables used while developing and testing
40
- * **NostoMessage** util class for holding info about messages that can be forwarded to the account administration iframe to show to the user
41
- * **NostoObject** base class for Nosto objects that need to share functionality
42
- * **NostoOrderConfirmation** class for sending order confirmations through the API
43
- * **NostoProductReCrawl** class for sending product re-crawl requests to Nosto over the API
44
- * **NostoValidator** class for performing data validations on objects implementing NostoValidatableInterface
45
-
46
- ### Interfaces
47
-
48
- * **NostoAccountInterface** interface defining methods needed to manage Nosto accounts
49
- * **NostoAccountMetaDataBillingDetailsInterface** interface defining getters for billing information needed during Nosto account creation over the API
50
- * **NostoAccountMetaDataIframeInterface** interface defining getters for information needed by the Nosto account configuration iframe
51
- * **NostoAccountMetaDataInterface** interface defining getters for information needed during Nosto account creation over the API
52
- * **NostoAccountMetaDataOwnerInterface** interface defining getters for account owner information needed during Nosto account creation over the API
53
- * **NostoOrderBuyerInterface** interface defining getters for buyer information needed during order confirmation requests
54
- * **NostoOrderInterface** interface defining getters for information needed during order confirmation requests
55
- * **NostoOrderPurchasedItemInterface** interface defining getters for purchased item information needed during order confirmation requests
56
- * **NostoOrderStatusInterface** interface defining getters for order status information needed during order confirmation requests
57
- * **NostoExportCollectionInterface** interface defining getters for exportable data collections for the historical data
58
- * **NostoOauthMetaDataInterface** interface defining getters for information needed during OAuth2 requests
59
- * **NostoProductInterface** interface defining getters for product information needed during product re-crawl requests to Nosto over the API
60
- * **NostoValidatableInterface** interface defining getters for validatable objects that can be used in conjunction with the NostoValidator class
61
-
62
- ### Libs
63
-
64
- * **NostoCryptAES** class for aes encryption that uses mcrypt if available and an internal implementation otherwise
65
- * **NostoCryptBase** base class for creating encryption classes
66
- * **NostoCryptRijndael** class for rijndael encryption that uses mcrypt if available and an internal implementation otherwise
67
- * **NostoCryptRandom** class for generating random strings
68
-
69
- ## Getting started
70
-
71
- ### Creating a new Nosto account
72
-
73
- A Nosto account is needed for every shop and every language within each shop.
74
-
75
- ```php
76
- .....
77
- try {
78
- /** @var NostoAccountMetaDataInterface $meta */
79
- /** @var NostoAccount $account */
80
- $account = NostoAccount::create($meta);
81
- // save newly created account according to the platforms requirements
82
- .....
83
- } catch (NostoException $e) {
84
- // handle failure
85
- .....
86
- }
87
- .....
88
- ```
89
-
90
- ### Connecting with an existing Nosto account
91
-
92
- This should be done in the shops back end when the admin user wants to connect an existing Nosto account to the shop.
93
-
94
- First redirect to the Nosto OAuth2 server.
95
-
96
- ```php
97
- .....
98
- /** @var NostoOAuthClientMetaDataInterface $meta */
99
- $client = new NostoOAuthClient($meta);
100
- header('Location: ' . $client->getAuthorizationUrl());
101
- ```
102
-
103
- Then have a public endpoint ready to handle the return request.
104
-
105
- ```php
106
- if (isset($_GET['code'])) {
107
- try {
108
- /** @var NostoOAuthClientMetaDataInterface $meta */
109
- $account = NostoAccount::syncFromNosto($meta, $_GET['code']);
110
- // save the synced account according to the platforms requirements
111
- } catch (NostoException $e) {
112
- // handle failures
113
- }
114
- // redirect to the admin page where the user can see the account configuration iframe
115
- .....
116
- }
117
- } elseif (isset($_GET['error'])) {
118
- // handle errors; 3 parameter will be sent, 'error', 'error_reason' and 'error_description'
119
- // redirect to the admin page where the user can see an error message
120
- .....
121
- } else {
122
- // 404
123
- .....
124
- }
125
- ```
126
-
127
- ### Deleting a Nosto account
128
-
129
- This should be used when you delete a Nosto account for a shop. It will notify Nosto that this account is no longer used.
130
-
131
- ```php
132
- try {
133
- /** @var NostoAccount $account */
134
- $account->delete();
135
- } catch (NostoException $e) {
136
- // handle failure
137
- }
138
- ```
139
-
140
- ### Get authenticated iframe URL for Nosto account configuration
141
-
142
- The Nosto account can be created and managed through an iframe that should be accessible to the admin user in the shops
143
- backend.
144
- This iframe will load only content from nosto.com.
145
-
146
- ```php
147
- .....
148
- /**
149
- * @var NostoAccount|null $account account with at least the 'SSO' token loaded or null if no account exists yet
150
- * @var NostoAccountMetaDataIframeInterface $meta
151
- * @var array $params (optional) extra params to add to the iframe url
152
- */
153
- try
154
- {
155
- $url = Nosto::helper('iframe')->getUrl($meta, $account, $params);
156
- }
157
- catch (NostoException $e)
158
- {
159
- // handle failure
160
- }
161
- // show the iframe to the user with given url
162
- .....
163
- ```
164
-
165
- The iframe can communicate with your module through window.postMessage
166
- (https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage). In order to set this up you can include the JS
167
- file `src/js/NostoIframe.min.js` on the page where you show the iframe and just init the API.
168
-
169
- ```js
170
- ...
171
- Nosto.iframe({
172
- iframeId: "nosto_iframe",
173
- urls: {
174
- createAccount: "url_to_the_create_account_endpoint_for_current_shop",
175
- connectAccount: "url_to_the_connect_account_endpoint_for_current_shop",
176
- deleteAccount: "url_to_the_delete_account_endpoint_for_current_shop"
177
- },
178
- xhrParams: {} // additional xhr params to include in the requests
179
- });
180
- ```
181
-
182
- The iframe API makes POST requests to the specified endpoints with content-type `application/x-www-form-urlencoded`.
183
- The response for these requests should always be JSON and include a `redirect_url` key. This url will be used to
184
- redirect the iframe after the action has been performed. In case of the connect account, the url will be used to
185
- redirect your browser to the Nosto OAuth server.
186
- The redirect url also needs to include error/success message keys, if you want to show messages to the user after the
187
- actions, e.g. when a new account has been created a success message can be shown with instructions. These messages are
188
- hard-coded in Nosto.
189
- You do NOT need to use this JS API, but instead set up your own postMessage handler in your application.
190
-
191
- ### Sending order confirmations using the Nosto API
192
-
193
- Sending order confirmations to Nosto is a vital part of the functionality. Order confirmations should be sent when an
194
- order has been completed in the shop. It is NOT recommended to do this when the "thank you" page is shown to the user,
195
- as payment gateways work differently and you cannot rely on the user always being redirected back to the shop after a
196
- payment has been made. Therefore, it is recommended to send the order conformation when the order is marked as payed
197
- in the shop.
198
-
199
- Order confirmations can be sent two different ways:
200
-
201
- * matched orders; where we know the Nosto customer ID of the user who placed the order
202
- * un-matched orders: where we do not know the Nosto customer ID of the user who placed the order
203
-
204
- The Nosto customer ID is set in a cookie "2c.cId" by Nosto and it is up to the platform to keep a link between users
205
- and the Nosto customer ID. It is recommended to tie the Nosto customer ID to the order or shopping cart instead of an
206
- user ID, as the platform may support guest checkouts.
207
-
208
- ```php
209
- .....
210
- try {
211
- /**
212
- * @var NostoOrderInterface $order
213
- * @var NostoAccountInterface $account
214
- * @var string $customerId
215
- */
216
- NostoOrderConfirmation::send($order, $account, $customerId);
217
- } catch (NostoException $e) {
218
- // handle error
219
- }
220
- .....
221
- ```
222
-
223
- ### Sending product re-crawl requests using the Nosto API
224
-
225
- Note: this feature has been deprecated in favor of the create/update/delete method below.
226
-
227
- When a product changes in the store, stock is reduced, price is updated etc. it is recommended to send an API request
228
- to Nosto that initiates a product "re-crawl" event. This is done to update the recommendations including that product
229
- so that the newest information can be shown to the users on the site.
230
-
231
- Note: the $product model needs to include only `productId` and `url` properties, all others can be omitted.
232
-
233
- ```php
234
- .....
235
- try {
236
- /**
237
- * @var NostoProductInterface $product
238
- * @var NostoAccountInterface $account
239
- */
240
- NostoProductReCrawl::send($product, $account);
241
- } catch (NostoException $e) {
242
- // handle error
243
- }
244
- .....
245
- ```
246
-
247
- Batch re-crawling is also possible by creating a collection of product models:
248
-
249
- ```php
250
- .....
251
- try {
252
- /**
253
- * @var NostoExportProductCollection $collection
254
- * @var NostoProductInterface $product
255
- * @var NostoAccountInterface $account
256
- */
257
- $collection[] = $product;
258
- NostoProductReCrawl::sendBatch($collection, $account);
259
- } catch (NostoException $e) {
260
- // handle error
261
- }
262
- .....
263
- ```
264
-
265
- ### Sending product create/update/delete requests using the Nosto API
266
-
267
- When a product changes in the store, stock is reduced, price is updated etc. it is recommended to send an API request
268
- to Nosto to handle the updated product info. This is also true when adding new products as well as deleting existing ones.
269
- This is done to update the recommendations including that product so that the newest information can be shown to the users
270
- on the site.
271
-
272
- Creating new products:
273
-
274
- ```php
275
- .....
276
- try {
277
- /**
278
- * @var NostoProductInterface $product
279
- * @var NostoAccountInterface $account
280
- */
281
- $op = new NostoOperationProduct($account);
282
- $op->addProduct($product);
283
- $op->create();
284
- } catch (NostoException $e) {
285
- // handle error
286
- }
287
- .....
288
- ```
289
-
290
- Note: you can call `addProduct` multiple times to add more products to the request. This way you can batch create products.
291
-
292
- Updating existing products:
293
-
294
- ```php
295
- .....
296
- try {
297
- /**
298
- * @var NostoProductInterface $product
299
- * @var NostoAccountInterface $account
300
- */
301
- $op = new NostoOperationProduct($account);
302
- $op->addProduct($product);
303
- $op->update();
304
- } catch (NostoException $e) {
305
- // handle error
306
- }
307
- .....
308
- ```
309
-
310
- Note: you can call `addProduct` multiple times to add more products to the request. This way you can batch update products.
311
-
312
- Deleting existing products:
313
-
314
- ```php
315
- .....
316
- try {
317
- /**
318
- * @var NostoProductInterface $product
319
- * @var NostoAccountInterface $account
320
- */
321
- $op = new NostoOperationProduct($account);
322
- $op->addProduct($product);
323
- $op->delete();
324
- } catch (NostoException $e) {
325
- // handle error
326
- }
327
- .....
328
- ```
329
-
330
- Note: you can call `addProduct` multiple times to add more products to the request. This way you can batch delete products.
331
-
332
- ### Exporting encrypted product/order information that Nosto can request
333
-
334
- When new Nosto accounts are created for a shop, Nosto will try to fetch historical data about products and orders.
335
- This information is used to bootstrap recommendations and decreases the time needed to get accurate recommendations
336
- showing in the shop.
337
-
338
- For this to work, Nosto requires 2 public endpoints that can be called once a new account has been created through
339
- the API. These endpoints should serve the history data encrypted with AES. The SDK comes bundled with the ability to
340
- encrypt the data with a pure PHP solution (http://phpseclib.sourceforge.net/), It is recommended, but not required, to
341
- have mcrypt installed on the server.
342
-
343
- Additionally, the endpoints need to support the ability to limit the amount of products/orders to export and an offset
344
- for fetching batches of data. These must be implemented as GET parameters "limit" and "offset" which will be sent as
345
- integer values and expected to be applied to the data set being exported.
346
-
347
- ```php
348
- .....
349
- /**
350
- * @var NostoProductInterface[] $products
351
- * @var NostoAccountInterface $account
352
- */
353
- $collection = new NostoExportProductCollection();
354
- foreach ($products as $product) {
355
- $collection[] = $product;
356
- }
357
- // The exported will encrypt the collection and output the result.
358
- $cipher_text = NostoExporter::export($account, $collection);
359
- echo $cipher_text;
360
- // It is important to stop the script execution after the export, in order to avoid any additional data being outputted.
361
- die();
362
- ```
363
-
364
- ```php
365
- .....
366
- /**
367
- * @var NostoOrderInterface[] $orders
368
- * @var NostoAccountInterface $account
369
- */
370
- $collection = new NostoExportOrderCollection();
371
- foreach ($orders as $order) {
372
- $collection[] = $order;
373
- }
374
- // The exported will encrypt the collection and output the result.
375
- $cipher_text = NostoExporter::export($account, $collection);
376
- echo $cipher_text;
377
- // It is important to stop the script execution after the export, in order to avoid any additional data being outputted.
378
- die();
379
- ```
380
-
381
- ## Testing
382
-
383
- The SDK is unit tested with Codeception (http://codeception.com/).
384
- API and OAuth2 requests are tested using api-mock server (https://www.npmjs.com/package/api-mock) running on Node.
385
-
386
- ### Install Codeception & api-mock
387
-
388
- First cd into the root directory.
389
-
390
- Then install Codeception via composer:
391
-
392
- ```bash
393
- php composer.phar install
394
- ```
395
-
396
- And then install Node (http://nodejs.org/) and the npm package manager (https://www.npmjs.com/). After that you can install the api-mock server via npm:
397
-
398
- ```bash
399
- npm install -g api-mock
400
- ```
401
-
402
- ### Running tests
403
-
404
- First cd into the root directory.
405
-
406
- Then start the api-mock server with the API blueprint:
407
-
408
- ```bash
409
- api-mock tests/api-blueprint.md
410
- ```
411
-
412
- Then in another window run the tests:
413
-
414
- ```bash
415
- vendor/bin/codecept run
416
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/nosto/php-sdk/src/.env.example DELETED
@@ -1,5 +0,0 @@
1
- NOSTO_SERVER_URL=connect.nosto.com
2
- NOSTO_API_BASE_URL=https://api.nosto.com
3
- NOSTO_OAUTH_BASE_URL=https://my.nosto.com/oauth
4
- NOSTO_WEB_HOOK_BASE_URL=https://my.nosto.com
5
- NOSTO_IFRAME_ORIGIN_REGEXP=(https:\/\/platform-([a-z0-9]+)\.hub\.nosto\.com)|(https:\/\/my\.nosto\.com)
 
 
 
 
 
package.xml CHANGED
@@ -1,18 +1,21 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Nosto_Tagging</name>
4
- <version>2.6.7.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>* Version bump to support for Magento version 1.9.2.3</notes>
 
 
 
12
  <authors><author><name>Nosto</name><user>nosto</user><email>magento@nosto.com</email></author></authors>
13
- <date>2016-01-21</date>
14
- <time>13:26:16</time>
15
- <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="f9e8bc4dcdff141b2f070777d025960d"/><file name="Wizard.php" hash="f98931a1a6e327c0d05e43b73063f672"/></dir><file name="Cart.php" hash="c1c707dad76c98d807d5160b90c06ac6"/><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="32115070d380e654f093da11dd6e4d85"/><file name="Product.php" hash="ac7b85e6d03d94d03c59416b622b0039"/></dir><dir name="Helper"><file name="Account.php" hash="40eb62dd1718741b2064d4a440f46b2f"/><file name="Customer.php" hash="92da4f0ae6c2aef635b837635cd74238"/><file name="Data.php" hash="c50b9b5a694fdd0401748741de97f6ab"/><file name="Date.php" hash="1a108a4ec8169b73411b6c11b86a1d80"/><file name="Oauth.php" hash="9ecbea9e8411501cabe780e0511a1d05"/><file name="Price.php" hash="b7fe656fad1182f5c2166e95a4b29204"/><file name="Url.php" hash="289294904d246c56e4de96798927a7f6"/></dir><dir name="Model"><file name="Base.php" hash="c0b3c4a6f68a0b707bf85ceff50e3c4b"/><dir name="Container"><file name="Cart.php" hash="20d2936693361999575f1e6ac56f2e40"/><file name="Customer.php" hash="b03bca89845b6c939521add8df1f7e9a"/></dir><file name="Customer.php" hash="6d992a43a75f29836ed1450e130df560"/><dir name="Export"><dir name="Collection"><file name="Order.php" hash="29c370bdfcaedab833df0abcc83f9f32"/></dir></dir><dir name="Meta"><dir name="Account"><file name="Billing.php" hash="353e807f832a37591bf7359857044ca1"/><file name="Iframe.php" hash="731e2bf424e1b9d4e00d403f55a87b54"/><file name="Owner.php" hash="6fd3228a2758d06f78729c0250f7fd30"/></dir><file name="Account.php" hash="8df7024533e1cf657b407c49fb19a3c5"/><file name="Oauth.php" hash="0863271d8a3db0de93525f0e64308f1c"/><dir name="Order"><file name="Buyer.php" hash="f2fc1abc28902e0ee6798c81a1503a38"/><file name="Item.php" hash="598aa5a2c713a59e9125976b48764488"/><file name="Status.php" hash="9f981363c48ae3adb59498a9d942a86f"/></dir><file name="Order.php" hash="64972a34441121c02c758047d95738f5"/><file name="Product.php" hash="40cf899477bac2f9916b030af8885e5e"/></dir><file name="Observer.php" hash="102b3e6d330e151a4595c54dc88a18a9"/><file name="Product.php" hash="3630a2a688f013b296d1865e6f32e1d2"/><dir name="Resource"><dir name="Customer"><file name="Collection.php" hash="0c99b46d5108a6fe31cad1190d8ef47c"/></dir><file name="Customer.php" hash="f92e4e5334b5e3493e8f04664b20f105"/><dir name="Product"><file name="Collection.php" hash="7566a7f4483a00c923bac2fbea173abd"/></dir><file name="Setup.php" hash="506b08bcb10cbe74e95812c5f646429f"/></dir><dir name="Service"><file name="Order.php" hash="f6ebc1fef63f7f984d7d3b81a53c0f16"/></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="Image.php" hash="d1fcc96aab01342627b96edf6fad1dd1"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="NostoController.php" hash="fd43fd322ea1f8d6b7db6d716250f71e"/></dir><file name="ExportController.php" hash="f22510a39256c0baca4fbcb9301c8ef5"/><file name="OauthController.php" hash="19927d6e9648d0f381b1c2f1b9684339"/></dir><dir name="etc"><file name="adminhtml.xml" hash="7ea210738a77630f299a14b442f3b8d0"/><file name="cache.xml" hash="e874fbbf2eb89b325deb1a62afbcfb4d"/><file name="config.xml" hash="9ea497afb9d7fce65202d56b23dde42d"/><file name="system.xml" hash="7deba6544a09d7af8c07e6b5edc0975a"/></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="8b6a8faca7d5ab5240b9411993021ca8"/><file name="wizard.phtml" hash="3f92e94e5ee3d3cd9906a6b0942a3a1b"/></dir></dir><dir name="layout"><file name="nostotagging.xml" hash="81c0aa3f71e1c509475410e8ec017214"/></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="3c4e80cdcebf63c56dc14a6594e167b8"/><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="3ec29ce57313c9c837a8d17b4455a9a0"/><file name="product.phtml" hash="9df3ff9f6e363e478d7fd68bd09827b1"/></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"><file name="LICENSE.txt" hash="309b355442cb85601216abd7a41909d2"/><file name="README.md" hash="0c4860a3dfe7bca30f3eb56c146b4166"/><dir name="src"><dir name="classes"><file name="Nosto.php" hash="c595c5f646f6e513b6604848f8d10118"/><file name="NostoAccount.php" hash="c422a7f104c5ebc6eac9d83986280579"/><file name="NostoCipher.php" hash="a3d7d148311aa0319387c0918e5e26dc"/><file name="NostoDotEnv.php" hash="90b23c1b02095c9368372f1d5346c3f9"/><file name="NostoMessage.php" hash="5933eadd2ad08427010b0bf16657266b"/><file name="NostoObject.php" hash="187808f0c55d02294d41e9395f4c5d58"/><file name="NostoOrderConfirmation.php" hash="2a3fd5efb196bc0dcb7ad57fb61a81d0"/><file name="NostoProductReCrawl.php" hash="f370c539409dd74fc98b7aa1ea0f6387"/><file name="NostoValidator.php" hash="2096ddc9979ec77f8f0b1ec58b459329"/><dir name="api"><file name="NostoApiRequest.php" hash="37db50c0d35ff9a848afe6a4bb871b6f"/><file name="NostoApiToken.php" hash="2febdbec0fd3609162845aa678b36b38"/></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="91bdd99a2be75be062fe5c7cde1803e4"/><file name="NostoExportProductCollection.php" hash="33986c8767922da98aa90f03759dbc0f"/><file name="NostoExporter.php" hash="72ad0af4bce8e57ada5a29e3634df94f"/></dir><dir name="helper"><file name="NostoHelper.php" hash="f4ca6c78e047fec93c32b7eb822b0692"/><file name="NostoHelperDate.php" hash="081a2d8bfec710f2baa52192a99a2658"/><file name="NostoHelperIframe.php" hash="303668f25103c245396b43811a15c28d"/><file name="NostoHelperPrice.php" hash="ee9f217dc1b8e0fc679fb56ca3fd3ca1"/></dir><dir name="http"><file name="NostoHttpRequest.php" hash="2c5b96a56d33b33e334d4d3772c2b14d"/><file name="NostoHttpRequestAdapter.php" hash="d8bf8e5db44ad982b655372529f4d88c"/><file name="NostoHttpRequestAdapterCurl.php" hash="945a4357578f91291d09f1e2850da580"/><file name="NostoHttpRequestAdapterSocket.php" hash="88f57e6d98de2ac652a235e2786f0be7"/><file name="NostoHttpResponse.php" hash="9982d3ed15bfcc8f0147b2b4cc400223"/></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="37e24121df779ead75e028b15a3fe226"/></dir></dir><file name="config.inc.php" hash="b46a56f8d61ff2cf69cedb4281719e00"/><dir name="interfaces"><file name="NostoExportCollectionInterface.php" hash="63c833c17fe43ce48b45e0f552313a8b"/><file name="NostoOAuthClientMetaDataInterface.php" hash="75a82417bfc27cd82e41ea9810d31428"/><file name="NostoProductInterface.php" hash="64a9e110a97ebd8be690664ce5b8e371"/><file name="NostoValidatableInterface.php" hash="57ad8b28225344127843b97049f5868d"/><dir name="account"><file name="NostoAccountInterface.php" hash="063da0d25a5420f4e727938467c078f3"/><file name="NostoAccountMetaDataBillingDetailsInterface.php" hash="ef31f0c3b41591fd76f85a25021f0fe4"/><file name="NostoAccountMetaDataIframeInterface.php" hash="c739e6a3ef39a308df6852361f2fd1d7"/><file name="NostoAccountMetaDataInterface.php" hash="5adf0a5ed876348a05028a3ff111bf79"/><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="5fd9f5b418dd796c469aaa0c58b34aaa"/><dir name="src"><file name="NostoIframe.js" hash="ca03585215f846258d2dbb58724e48fa"/></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="42aa9514d8b3f65e9df96b0df601f63c"/></dir></dir></dir></target><target name="mage"><dir name="js"><dir name="nosto"><file name="iframeHandler.min.js" hash="c13b574b829791cd061ed63c81060680"/><file name="iframeResizer.min.js" hash="163b065c9dd702dc364913a951b81fee"/></dir></dir></target></contents>
16
  <compatible/>
17
- <dependencies><required><php><min>5.2.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.2.3</max></package></required></dependencies>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Nosto_Tagging</name>
4
+ <version>2.6.8</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>- Tagging for 404 pages and order confirmation page&#xD;
12
+ - Loosen up the data validation&#xD;
13
+ - Fix tagging currency for product&#xD;
14
+ - Enhance product and order exports</notes>
15
  <authors><author><name>Nosto</name><user>nosto</user><email>magento@nosto.com</email></author></authors>
16
+ <date>2016-03-02</date>
17
+ <time>08:12:55</time>
18
+ <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="f9e8bc4dcdff141b2f070777d025960d"/><file name="Wizard.php" hash="f98931a1a6e327c0d05e43b73063f672"/></dir><file name="Cart.php" hash="c1c707dad76c98d807d5160b90c06ac6"/><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="32115070d380e654f093da11dd6e4d85"/><file name="Product.php" hash="ac7b85e6d03d94d03c59416b622b0039"/></dir><dir name="Helper"><file name="Account.php" hash="d6870520bdbd4bc9d70eff77704f790a"/><file name="Customer.php" hash="8faa27321f26ece8ff5ebf12058f546f"/><file name="Data.php" hash="f7f737ba34cc9144a01db32fc91d3bcb"/><file name="Date.php" hash="1a108a4ec8169b73411b6c11b86a1d80"/><file name="Oauth.php" hash="9ecbea9e8411501cabe780e0511a1d05"/><file name="Price.php" hash="6667651768abaced20f31cd62abe9417"/><file name="Url.php" hash="289294904d246c56e4de96798927a7f6"/></dir><dir name="Model"><file name="Base.php" hash="c4246068fa6667578188a8c1fc289334"/><dir name="Container"><file name="Cart.php" hash="20d2936693361999575f1e6ac56f2e40"/><file name="Customer.php" hash="b03bca89845b6c939521add8df1f7e9a"/></dir><file name="Customer.php" hash="6d992a43a75f29836ed1450e130df560"/><dir name="Export"><dir name="Collection"><file name="Order.php" hash="29c370bdfcaedab833df0abcc83f9f32"/></dir></dir><dir name="Meta"><dir name="Account"><file name="Billing.php" hash="353e807f832a37591bf7359857044ca1"/><file name="Iframe.php" hash="731e2bf424e1b9d4e00d403f55a87b54"/><file name="Owner.php" hash="6fd3228a2758d06f78729c0250f7fd30"/></dir><file name="Account.php" hash="8df7024533e1cf657b407c49fb19a3c5"/><file name="Oauth.php" hash="0863271d8a3db0de93525f0e64308f1c"/><dir name="Order"><file name="Buyer.php" hash="45ee761ba052ef3372846c22e28921d8"/><file name="Item.php" hash="bdd21faf7e05d6c5d703935568054be4"/><file name="Status.php" hash="795b2e53be043aeb0b27bbd500e2c412"/></dir><file name="Order.php" hash="660ddd441a65db393491a0d90452327e"/><file name="Product.php" hash="a3aecb016c1880cd5922eb24f4c2b574"/></dir><file name="Observer.php" hash="102b3e6d330e151a4595c54dc88a18a9"/><file name="Product.php" hash="3630a2a688f013b296d1865e6f32e1d2"/><dir name="Resource"><dir name="Customer"><file name="Collection.php" hash="0c99b46d5108a6fe31cad1190d8ef47c"/></dir><file name="Customer.php" hash="f92e4e5334b5e3493e8f04664b20f105"/><dir name="Product"><file name="Collection.php" hash="fe8114fbccd62fe3a0bca18732e5d852"/></dir><file name="Setup.php" hash="506b08bcb10cbe74e95812c5f646429f"/></dir><dir name="Service"><file name="Order.php" hash="f6ebc1fef63f7f984d7d3b81a53c0f16"/></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="Image.php" hash="d1fcc96aab01342627b96edf6fad1dd1"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="NostoController.php" hash="753096ec550fe95c62b71cbb9b6a8158"/></dir><file name="ExportController.php" hash="10b8cd717ea124b52af3e7a00b9f5160"/><file name="OauthController.php" hash="c04d91992c6b3ed0cda4fdf8923ea6b2"/></dir><dir name="etc"><file name="adminhtml.xml" hash="7ea210738a77630f299a14b442f3b8d0"/><file name="cache.xml" hash="e874fbbf2eb89b325deb1a62afbcfb4d"/><file name="config.xml" hash="c16d1ba17b6c4eaf906b44ec7baf8c44"/><file name="system.xml" hash="7deba6544a09d7af8c07e6b5edc0975a"/></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="8b6a8faca7d5ab5240b9411993021ca8"/><file name="wizard.phtml" hash="3f92e94e5ee3d3cd9906a6b0942a3a1b"/></dir></dir><dir name="layout"><file name="nostotagging.xml" hash="81c0aa3f71e1c509475410e8ec017214"/></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="3c4e80cdcebf63c56dc14a6594e167b8"/><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="3ec29ce57313c9c837a8d17b4455a9a0"/><file name="product.phtml" hash="9df3ff9f6e363e478d7fd68bd09827b1"/></dir></dir><dir name="layout"><file name="nostotagging.xml" hash="52db089fa338cca29625f0a9103a1451"/></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="c422a7f104c5ebc6eac9d83986280579"/><file name="NostoCipher.php" hash="a3d7d148311aa0319387c0918e5e26dc"/><file name="NostoDotEnv.php" hash="90b23c1b02095c9368372f1d5346c3f9"/><file name="NostoMessage.php" hash="5933eadd2ad08427010b0bf16657266b"/><file name="NostoObject.php" hash="187808f0c55d02294d41e9395f4c5d58"/><file name="NostoOrderConfirmation.php" hash="2a3fd5efb196bc0dcb7ad57fb61a81d0"/><file name="NostoProductReCrawl.php" hash="f370c539409dd74fc98b7aa1ea0f6387"/><file name="NostoValidator.php" hash="2096ddc9979ec77f8f0b1ec58b459329"/><dir name="api"><file name="NostoApiRequest.php" hash="37db50c0d35ff9a848afe6a4bb871b6f"/><file name="NostoApiToken.php" hash="2febdbec0fd3609162845aa678b36b38"/></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="91bdd99a2be75be062fe5c7cde1803e4"/><file name="NostoExportProductCollection.php" hash="33986c8767922da98aa90f03759dbc0f"/><file name="NostoExporter.php" hash="72ad0af4bce8e57ada5a29e3634df94f"/></dir><dir name="helper"><file name="NostoHelper.php" hash="f4ca6c78e047fec93c32b7eb822b0692"/><file name="NostoHelperDate.php" hash="081a2d8bfec710f2baa52192a99a2658"/><file name="NostoHelperIframe.php" hash="303668f25103c245396b43811a15c28d"/><file name="NostoHelperPrice.php" hash="ee9f217dc1b8e0fc679fb56ca3fd3ca1"/></dir><dir name="http"><file name="NostoHttpRequest.php" hash="2c5b96a56d33b33e334d4d3772c2b14d"/><file name="NostoHttpRequestAdapter.php" hash="d8bf8e5db44ad982b655372529f4d88c"/><file name="NostoHttpRequestAdapterCurl.php" hash="945a4357578f91291d09f1e2850da580"/><file name="NostoHttpRequestAdapterSocket.php" hash="88f57e6d98de2ac652a235e2786f0be7"/><file name="NostoHttpResponse.php" hash="9982d3ed15bfcc8f0147b2b4cc400223"/></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="37e24121df779ead75e028b15a3fe226"/></dir></dir><file name="config.inc.php" hash="b46a56f8d61ff2cf69cedb4281719e00"/><dir name="interfaces"><file name="NostoExportCollectionInterface.php" hash="63c833c17fe43ce48b45e0f552313a8b"/><file name="NostoOAuthClientMetaDataInterface.php" hash="75a82417bfc27cd82e41ea9810d31428"/><file name="NostoProductInterface.php" hash="64a9e110a97ebd8be690664ce5b8e371"/><file name="NostoValidatableInterface.php" hash="57ad8b28225344127843b97049f5868d"/><dir name="account"><file name="NostoAccountInterface.php" hash="063da0d25a5420f4e727938467c078f3"/><file name="NostoAccountMetaDataBillingDetailsInterface.php" hash="ef31f0c3b41591fd76f85a25021f0fe4"/><file name="NostoAccountMetaDataIframeInterface.php" hash="c739e6a3ef39a308df6852361f2fd1d7"/><file name="NostoAccountMetaDataInterface.php" hash="5adf0a5ed876348a05028a3ff111bf79"/><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="5fd9f5b418dd796c469aaa0c58b34aaa"/><dir name="src"><file name="NostoIframe.js" hash="ca03585215f846258d2dbb58724e48fa"/></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></dir></dir></dir></target><target name="mage"><dir name="js"><dir name="nosto"><file name="iframeHandler.min.js" hash="c13b574b829791cd061ed63c81060680"/><file name="iframeResizer.min.js" hash="163b065c9dd702dc364913a951b81fee"/></dir></dir></target></contents>
19
  <compatible/>
20
+ <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.2.4</max></package></required></dependencies>
21
  </package>