Metrilo_Analytics - Version 1.1.0

Version Notes

Submit async orders to Metrilo to handle drops on external payment pages.

Download this release

Release Info

Developer Murry Ivanoff
Extension Metrilo_Analytics
Version 1.1.0
Comparing to
See all releases


Code changes from version 1.0.8 to 1.1.0

app/code/community/Metrilo/Analytics/Block/Adminhtml/System/Config/Form/Button.php CHANGED
@@ -37,6 +37,7 @@ class Metrilo_Analytics_Block_Adminhtml_System_Config_Form_Button extends Mage_A
37
  {
38
  $html = parent::_toHtml();
39
  $helper = Mage::helper('metrilo_analytics');
 
40
  if($helper->isEnabled() && $helper->getApiToken() && $helper->getApiSecret())
41
  return $html;
42
  }
@@ -78,4 +79,4 @@ class Metrilo_Analytics_Block_Adminhtml_System_Config_Form_Button extends Mage_A
78
 
79
  return $button->toHtml();
80
  }
81
- }
37
  {
38
  $html = parent::_toHtml();
39
  $helper = Mage::helper('metrilo_analytics');
40
+
41
  if($helper->isEnabled() && $helper->getApiToken() && $helper->getApiSecret())
42
  return $html;
43
  }
79
 
80
  return $button->toHtml();
81
  }
82
+ }
app/code/community/Metrilo/Analytics/Helper/AsyncHttpClient.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Helper class for metrilo properties
4
+ *
5
+ * @author Zhivko Draganov <zhivko@metrilo.com>
6
+ */
7
+ class Metrilo_Analytics_Helper_AsyncHttpClient extends Mage_Core_Helper_Abstract
8
+ {
9
+ /**
10
+ * Create HTTP GET async request to URL
11
+ *
12
+ * @param String $url
13
+ * @return void
14
+ */
15
+ public function get($url)
16
+ {
17
+ $parsedUrl = parse_url($url);
18
+ $raw = $this->_buildRawGet($parsedUrl['host'], $parsedUrl['path']);
19
+
20
+ $fp = fsockopen(
21
+ $parsedUrl['host'],
22
+ isset($parsedUrl['port']) ? $parsedUrl['port'] : 80,
23
+ $errno, $errstr, 30);
24
+
25
+ if ($fp) {
26
+ fwrite($fp, $raw);
27
+ fclose($fp);
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Create HTTP POSTasync request to URL
33
+ *
34
+ * @param String $url
35
+ * @param Array $bodyArray
36
+ * @return void
37
+ */
38
+ public function post($url, $bodyArray = false)
39
+ {
40
+ $parsedUrl = parse_url($url);
41
+ $encodedBody = $bodyArray ? json_encode($bodyArray) : '';
42
+
43
+ $raw = $this->_buildRawPost($parsedUrl['host'], $parsedUrl['path'], $encodedBody);
44
+
45
+ $fp = fsockopen(
46
+ $parsedUrl['host'],
47
+ isset($parsedUrl['port']) ? $parsedUrl['port'] : 80,
48
+ $errno, $errstr, 30);
49
+
50
+ if ($fp) {
51
+ fwrite($fp, $raw);
52
+ fclose($fp);
53
+ }
54
+ }
55
+
56
+ private function _buildRawGet($host, $path)
57
+ {
58
+ $out = "GET ".$path." HTTP/1.1\r\n";
59
+ $out .= "Host: ".$host."\r\n";
60
+ // $out .= "Accept: application/json\r\n";
61
+ $out .= "Connection: Close\r\n\r\n";
62
+
63
+ return $out;
64
+ }
65
+
66
+ private function _buildRawPost($host, $path, $encodedCall)
67
+ {
68
+ $out = "POST ".$path." HTTP/1.1\r\n";
69
+ $out .= "Host: ".$host."\r\n";
70
+ $out .= "Content-Type: application/json\r\n";
71
+ $out .= "Content-Length: ".strlen($encodedCall)."\r\n";
72
+ $out .= "Accept: */*\r\n";
73
+ $out .= "User-Agent: AsyncHttpClient/1.0.0\r\n";
74
+ $out .= "Connection: Close\r\n\r\n";
75
+
76
+ $out .= $encodedCall;
77
+
78
+ return $out;
79
+ }
80
+ }
app/code/community/Metrilo/Analytics/Helper/Data.php CHANGED
@@ -50,7 +50,7 @@ class Metrilo_Analytics_Helper_Data extends Mage_Core_Helper_Abstract
50
  /**
51
  * Add event to queue
52
  *
53
- * @param string $method Can be identiy|track
54
  * @param string $type
55
  * @param string|array $data
56
  */
@@ -100,6 +100,8 @@ class Metrilo_Analytics_Helper_Data extends Mage_Core_Helper_Abstract
100
  'payment_method' => $order->getPayment()->getMethodInstance()->getTitle(),
101
  );
102
 
 
 
103
  if ($order->getCouponCode()) {
104
  $data['coupons'] = array($order->getCouponCode());
105
  }
@@ -132,81 +134,99 @@ class Metrilo_Analytics_Helper_Data extends Mage_Core_Helper_Abstract
132
  }
133
  $data['items'][] = $dataItem;
134
  }
 
135
  return $data;
136
  }
137
 
138
  /**
139
- * Create HTTP request to metrilo server
140
  *
141
- * @param string $ident
142
- * @param string $event
143
- * @param array $params
144
- * @param boolean|array $identityData
145
- * @param boolean|int $time
146
- * @param boolean|array $callParameters
147
  * @return void
148
  */
149
- public function callApi($ident, $event, $params, $identityData = false, $time = false, $callParameters = false)
150
  {
151
  try {
152
- $call = $this->buildEventArray($ident, $event, $params, $identityData, $time, $callParameters);
153
- // We should handle the setting of token parameter, as it's part of the request
154
- $call['token'] = $this->getApiToken();
155
-
156
- // Additional ksort here because of adding token param
157
- ksort($call);
158
- $basedCall = base64_encode(Mage::helper('core')->jsonEncode($call));
159
- $signature = md5($basedCall.$this->getApiSecret());
160
- // Use Varien_Http_Client
161
- // to generate API call end point and call it
162
- $url = 'http://p.metrilo.com/t?s='.$signature.'&hs='.$basedCall;
163
- $client = new Varien_Http_Client($url);
164
- $response = $client->request();
165
- $result = Mage::helper('core')->jsonDecode($response->getBody());
166
- if (!$result['status']) {
167
- Mage::log($result['error'], null, 'Metrilo_Analytics.log');
168
- }
169
  } catch (Exception $e){
170
  Mage::log($e->getMessage(), null, 'Metrilo_Analytics.log');
171
  }
172
  }
173
 
174
- public function callBatchApi($ordersForSubmition)
 
 
 
 
 
 
175
  {
176
  try {
177
- // Consider token is in the first level in the hashed json
178
- $version = (string)Mage::getConfig()->getModuleConfig("Metrilo_Analytics")->version;
179
- $call = array(
180
- 'token' => $this->getApiToken(),
181
- 'events' => $ordersForSubmition,
182
- // for debugging/support purposes
183
- 'platform' => 'Magento ' . Mage::getEdition() . ' ' . Mage::getVersion(),
184
- 'version' => $version
185
- );
 
 
186
 
187
- // Additional ksort here because of adding token param
188
- ksort($call);
189
 
190
- $basedCall = base64_encode(Mage::helper('core')->jsonEncode($call));
191
- $signature = md5($basedCall.$this->getApiSecret());
 
 
192
 
193
- $url = 'http://p.metrilo.com/bt';
194
- $client = new Varien_Http_Client($url);
 
 
195
 
196
- $requestBody = array(
197
- 's' => $signature,
198
- 'hs' => $basedCall
199
- );
200
- // This method supports passing named array as well as key, value
201
- $client->setParameterPost($requestBody);
202
- $response = $client->request('POST');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
- if ($response->isError()) {
205
- Mage::log($response->getBody(), null, 'Metrilo_Analytics.log');
 
 
 
 
 
 
 
 
 
206
  }
207
- } catch (Exception $e) {
208
- Mage::log($e->getMessage(), null, 'Metrilo_Analytics.log');
209
  }
 
 
210
  }
211
 
212
  /**
@@ -220,31 +240,86 @@ class Metrilo_Analytics_Helper_Data extends Mage_Core_Helper_Abstract
220
  * @param boolean|array $callParameters
221
  * @return void
222
  */
223
- public function buildEventArray($ident, $event, $params, $identityData = false, $time = false, $callParameters = false)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  {
225
- $call = array(
226
- 'event_type' => $event,
227
- 'params' => $params,
228
- 'uid' => $ident
229
- );
230
- if($time) {
231
- $call['time'] = $time;
232
- }
233
-
234
- // check for special parameters to include in the API call
235
- if($callParameters) {
236
- if($callParameters['use_ip']) {
237
- $call['use_ip'] = $callParameters['use_ip'];
238
- }
239
- }
240
- // put identity data in call if available
241
- if($identityData) {
242
- $call['identity'] = $identityData;
243
- }
244
-
245
- // Prepare keys is alphabetical order
246
- ksort($call);
247
-
248
- return $call;
249
  }
250
  }
50
  /**
51
  * Add event to queue
52
  *
53
+ * @param string $method Can be identify|track
54
  * @param string $type
55
  * @param string|array $data
56
  */
100
  'payment_method' => $order->getPayment()->getMethodInstance()->getTitle(),
101
  );
102
 
103
+ $this->_assignBillingInfo($data, $order);
104
+
105
  if ($order->getCouponCode()) {
106
  $data['coupons'] = array($order->getCouponCode());
107
  }
134
  }
135
  $data['items'][] = $dataItem;
136
  }
137
+
138
  return $data;
139
  }
140
 
141
  /**
142
+ * Create HTTP request to Metrilo API to sync single order
143
  *
144
+ * @param Mage_Sales_Model_Order $order
 
 
 
 
 
145
  * @return void
146
  */
147
+ public function callApi($order, $async = false)
148
  {
149
  try {
150
+ $this->callBatchApi(array($order), $async);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  } catch (Exception $e){
152
  Mage::log($e->getMessage(), null, 'Metrilo_Analytics.log');
153
  }
154
  }
155
 
156
+ /**
157
+ * Create HTTP request to Metrilo API to sync multiple orders
158
+ *
159
+ * @param Array(Mage_Sales_Model_Order) $orders
160
+ * @return void
161
+ */
162
+ public function callBatchApi($orders, $async = false)
163
  {
164
  try {
165
+ $ordersForSubmition = $this->_buildOrdersForSubmition($orders);
166
+ $call = $this->_buildCall($ordersForSubmition);
167
+ if ($async) {
168
+ $this->_callMetriloApiAsync($call);
169
+ } else {
170
+ $this->_callMetriloApi($call);
171
+ }
172
+ } catch (Exception $e) {
173
+ Mage::log($e->getMessage(), null, 'Metrilo_Analytics.log');
174
+ }
175
+ }
176
 
177
+ // Private functions start here
 
178
 
179
+ private function _callMetriloApiAsync($call) {
180
+ ksort($call);
181
+ $basedCall = base64_encode(Mage::helper('core')->jsonEncode($call));
182
+ $signature = md5($basedCall.$this->getApiSecret());
183
 
184
+ $requestBody = array(
185
+ 's' => $signature,
186
+ 'hs' => $basedCall
187
+ );
188
 
189
+ $asyncHttpHelper = Mage::helper('metrilo_analytics/asynchttpclient');
190
+ $asyncHttpHelper->post('http://p.metrilo.com/bt', $requestBody);
191
+ }
192
+
193
+ private function _callMetriloApi($call) {
194
+ // Prepare call for submition
195
+ ksort($call);
196
+ $basedCall = base64_encode(Mage::helper('core')->jsonEncode($call));
197
+ $signature = md5($basedCall.$this->getApiSecret());
198
+
199
+ $requestBody = array(
200
+ 's' => $signature,
201
+ 'hs' => $basedCall
202
+ );
203
+
204
+ $client = new Varien_Http_Client('http://p.metrilo.com/bt');
205
+
206
+ // This method supports passing named array as well as key, value
207
+ $client->setParameterPost($requestBody);
208
+ $response = $client->request('POST');
209
+
210
+ if ($response->isError()) {
211
+ Mage::log($response->getBody(), null, 'Metrilo_Analytics.log');
212
+ }
213
+ }
214
 
215
+ /**
216
+ * Create submition ready arrays from Array of Mage_Sales_Model_Order
217
+ * @param Array(Mage_Sales_Model_Order) $orders
218
+ * @return Array of Arrays
219
+ */
220
+ private function _buildOrdersForSubmition($orders) {
221
+ $ordersForSubmition = array();
222
+
223
+ foreach ($orders as $order) {
224
+ if ($order->getId()) {
225
+ array_push($ordersForSubmition, $this->_buildOrderForSubmition($order));
226
  }
 
 
227
  }
228
+
229
+ return $ordersForSubmition;
230
  }
231
 
232
  /**
240
  * @param boolean|array $callParameters
241
  * @return void
242
  */
243
+ private function _buildEventArray($ident, $event, $params, $identityData = false, $time = false, $callParameters = false)
244
+ {
245
+ $call = array(
246
+ 'event_type' => $event,
247
+ 'params' => $params,
248
+ 'uid' => $ident
249
+ );
250
+ if($time) {
251
+ $call['time'] = $time;
252
+ }
253
+
254
+ // check for special parameters to include in the API call
255
+ if($callParameters) {
256
+ if($callParameters['use_ip']) {
257
+ $call['use_ip'] = $callParameters['use_ip'];
258
+ }
259
+ }
260
+ // put identity data in call if available
261
+ if($identityData) {
262
+ $call['identity'] = $identityData;
263
+ }
264
+
265
+ // Prepare keys is alphabetical order
266
+ ksort($call);
267
+
268
+ return $call;
269
+ }
270
+
271
+ private function _buildOrderForSubmition($order) {
272
+ $orderDetails = $this->prepareOrderDetails($order);
273
+ // initialize additional params
274
+ $callParameters = false;
275
+ // check if order has customer IP in it
276
+ $ip = $order->getRemoteIp();
277
+ if ($ip) {
278
+ $callParameters = array('use_ip' => $ip);
279
+ }
280
+ // initialize time
281
+ $time = false;
282
+ if ($order->getCreatedAtStoreDate()) {
283
+ $time = $order->getCreatedAtStoreDate()->getTimestamp() * 1000;
284
+ }
285
+
286
+ $identityData = $this->_orderIdentityData($order);
287
+
288
+ return $this->_buildEventArray(
289
+ $identityData['email'], 'order', $orderDetails, $identityData, $time, $callParameters
290
+ );
291
+ }
292
+
293
+
294
+ private function _orderIdentityData($order) {
295
+ return array(
296
+ 'email' => $order->getCustomerEmail(),
297
+ 'first_name' => $order->getBillingAddress()->getFirstname(),
298
+ 'last_name' => $order->getBillingAddress()->getLastname(),
299
+ 'name' => $order->getBillingAddress()->getName(),
300
+ );
301
+ }
302
+
303
+ private function _buildCall($ordersForSubmition) {
304
+ return array(
305
+ 'token' => $this->getApiToken(),
306
+ 'events' => $ordersForSubmition,
307
+ // for debugging/support purposes
308
+ 'platform' => 'Magento ' . Mage::getEdition() . ' ' . Mage::getVersion(),
309
+ 'version' => (string)Mage::getConfig()->getModuleConfig("Metrilo_Analytics")->version
310
+ );
311
+ }
312
+
313
+ private function _assignBillingInfo(&$data, $order)
314
  {
315
+ $billingAddress = $order->getBillingAddress();
316
+ # Assign billing data to order data array
317
+ $data['billing_phone'] = $billingAddress->getTelephone();
318
+ $data['billing_country'] = $billingAddress->getCountryId();
319
+ $data['billing_region'] = $billingAddress->getRegion();
320
+ $data['billing_city'] = $billingAddress->getCity();
321
+ $data['billing_postcode'] = $billingAddress->getPostcode();
322
+ $data['billing_address'] = $billingAddress->getStreetFull();
323
+ $data['billing_company'] = $billingAddress->getCompany();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
  }
325
  }
app/code/community/Metrilo/Analytics/Model/Observer.php CHANGED
@@ -1,8 +1,9 @@
1
  <?php
2
  /**
3
- * Catch events and track them to metrilo api
4
  *
5
  * @author Miroslav Petrov <miro91tn@gmail.com>
 
6
  */
7
  class Metrilo_Analytics_Model_Observer
8
  {
@@ -74,7 +75,7 @@ class Metrilo_Analytics_Model_Observer
74
  return;
75
  }
76
  // category view pages
77
- if($action == 'catalog_category_view') {
78
  $category = Mage::registry('current_category');
79
  $data = array(
80
  'id' => $category->getId(),
@@ -93,10 +94,10 @@ class Metrilo_Analytics_Model_Observer
93
  'url' => $product->getProductUrl()
94
  );
95
  // Additional information ( image and categories )
96
- if($product->getImage())
97
  $data['image_url'] = (string)Mage::helper('catalog/image')->init($product, 'image');
98
 
99
- if(count($product->getCategoryIds())) {
100
  $categories = array();
101
  $collection = $product->getCategoryCollection()->addAttributeToSelect('*');
102
  foreach ($collection as $category) {
@@ -111,7 +112,7 @@ class Metrilo_Analytics_Model_Observer
111
  return;
112
  }
113
  // cart view
114
- if($action == 'checkout_cart_index') {
115
  $helper->addEvent('track', 'view_cart', array());
116
  return;
117
  }
@@ -122,19 +123,6 @@ class Metrilo_Analytics_Model_Observer
122
  }
123
  }
124
 
125
- /**
126
- * Events that we don't want to track
127
- *
128
- * @param string event
129
- */
130
- private function _isRejected($event)
131
- {
132
- return in_array(
133
- $event,
134
- array('catalogsearch_advanced_result', 'catalogsearch_advanced_index')
135
- );
136
- }
137
-
138
  /**
139
  * Event for adding product to cart
140
  * "checkout_cart_product_add_after"
@@ -165,39 +153,6 @@ class Metrilo_Analytics_Model_Observer
165
 
166
  }
167
 
168
- /**
169
- * Add to cart event
170
- *
171
- * @param integer $productId
172
- * @param Mage_Catalog_Model_Product $item
173
- * @param integer $qty
174
- */
175
- private function _addToCart($productId, $item, $qty) {
176
- $helper = Mage::helper('metrilo_analytics');
177
- $product = Mage::getModel('catalog/product')->load($productId);
178
-
179
- $data = array(
180
- 'id' => (int)$product->getId(),
181
- 'price' => (float)$product->getFinalPrice(),
182
- 'name' => $product->getName(),
183
- 'url' => $product->getProductUrl(),
184
- 'quantity' => $qty
185
- );
186
-
187
- // Add options for grouped or configurable products
188
- if ($item->isGrouped() || $item->isConfigurable()) {
189
- $data['id'] = $item->getId();
190
- $data['name'] = $item->getName();
191
- $data['url'] = $item->getProductUrl();
192
- // Options
193
- $data['option_id'] = $product->getSku();
194
- $data['option_name'] = trim(str_replace("-", " ", $product->getName()));
195
- $data['option_price'] = (float)$product->getFinalPrice();
196
- }
197
-
198
- $helper->addEvent('track', 'add_to_cart', $data);
199
- }
200
-
201
  /**
202
  * Event for removing item from shopping bag
203
  *
@@ -270,30 +225,53 @@ class Metrilo_Analytics_Model_Observer
270
  public function updateOrder(Varien_Event_Observer $observer)
271
  {
272
  $helper = Mage::helper('metrilo_analytics');
273
- $order = $observer->getOrder();
274
- $orderDetails = $helper->prepareOrderDetails($order);
275
-
276
- $callParameters = false;
277
 
278
- // check if order has customer IP in it
279
- $ip = $order->getRemoteIp();
280
- if ($ip){
281
- $callParameters = array('use_ip' => $ip);
282
- }
 
 
 
 
 
 
 
283
 
284
- $time = false;
285
- if ($order->getCreatedAtStoreDate()) {
286
- $time = $order->getCreatedAtStoreDate()->getTimestamp() * 1000;
287
- }
 
 
 
 
 
 
 
288
 
289
- $identityData = array(
290
- 'email' => $order->getCustomerEmail(),
291
- 'first_name' => $order->getBillingAddress()->getFirstname(),
292
- 'last_name' => $order->getBillingAddress()->getLastname(),
293
- 'name' => $order->getBillingAddress()->getName(),
 
294
  );
295
 
296
- $helper->callApi($identityData['email'], 'order', $orderDetails, $identityData, $time, $callParameters);
297
- }
 
 
 
 
 
 
 
 
298
 
 
 
299
  }
1
  <?php
2
  /**
3
+ * Catch events and track them to Metrilo API
4
  *
5
  * @author Miroslav Petrov <miro91tn@gmail.com>
6
+ * @author Zhivko Draganov <zhivko@metrilo.com>
7
  */
8
  class Metrilo_Analytics_Model_Observer
9
  {
75
  return;
76
  }
77
  // category view pages
78
+ if ($action == 'catalog_category_view') {
79
  $category = Mage::registry('current_category');
80
  $data = array(
81
  'id' => $category->getId(),
94
  'url' => $product->getProductUrl()
95
  );
96
  // Additional information ( image and categories )
97
+ if ($product->getImage())
98
  $data['image_url'] = (string)Mage::helper('catalog/image')->init($product, 'image');
99
 
100
+ if (count($product->getCategoryIds())) {
101
  $categories = array();
102
  $collection = $product->getCategoryCollection()->addAttributeToSelect('*');
103
  foreach ($collection as $category) {
112
  return;
113
  }
114
  // cart view
115
+ if ($action == 'checkout_cart_index') {
116
  $helper->addEvent('track', 'view_cart', array());
117
  return;
118
  }
123
  }
124
  }
125
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  /**
127
  * Event for adding product to cart
128
  * "checkout_cart_product_add_after"
153
 
154
  }
155
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  /**
157
  * Event for removing item from shopping bag
158
  *
225
  public function updateOrder(Varien_Event_Observer $observer)
226
  {
227
  $helper = Mage::helper('metrilo_analytics');
228
+ $helper->callApi($observer->getOrder(), true);
229
+ }
 
 
230
 
231
+ /**
232
+ * Events that we don't want to track
233
+ *
234
+ * @param string event
235
+ */
236
+ private function _isRejected($event)
237
+ {
238
+ return in_array(
239
+ $event,
240
+ array('catalogsearch_advanced_result', 'catalogsearch_advanced_index')
241
+ );
242
+ }
243
 
244
+ /**
245
+ * Add to cart event
246
+ *
247
+ * @param integer $productId
248
+ * @param Mage_Catalog_Model_Product $item
249
+ * @param integer $qty
250
+ */
251
+ private function _addToCart($productId, $item, $qty)
252
+ {
253
+ $helper = Mage::helper('metrilo_analytics');
254
+ $product = Mage::getModel('catalog/product')->load($productId);
255
 
256
+ $data = array(
257
+ 'id' => (int)$product->getId(),
258
+ 'price' => (float)$product->getFinalPrice(),
259
+ 'name' => $product->getName(),
260
+ 'url' => $product->getProductUrl(),
261
+ 'quantity' => $qty
262
  );
263
 
264
+ // Add options for grouped or configurable products
265
+ if ($item->isGrouped() || $item->isConfigurable()) {
266
+ $data['id'] = $item->getId();
267
+ $data['name'] = $item->getName();
268
+ $data['url'] = $item->getProductUrl();
269
+ // Options
270
+ $data['option_id'] = $product->getSku();
271
+ $data['option_name'] = trim(str_replace("-", " ", $product->getName()));
272
+ $data['option_price'] = (float)$product->getFinalPrice();
273
+ }
274
 
275
+ $helper->addEvent('track', 'add_to_cart', $data);
276
+ }
277
  }
app/code/community/Metrilo/Analytics/controllers/Adminhtml/AjaxController.php CHANGED
@@ -19,42 +19,10 @@ class Metrilo_Analytics_Adminhtml_AjaxController extends Mage_Adminhtml_Controll
19
  try {
20
  $import = Mage::getSingleton('metrilo_analytics/import');
21
  $chunkId = (int)$this->getRequest()->getParam('chunk_id');
 
22
  $orders = $import->getOrders($chunkId);
23
- $ordersForSubmition = array();
24
-
25
- foreach ($orders as $order) {
26
- if ($order->getId()) {
27
- $orderDetails = $helper->prepareOrderDetails($order);
28
-
29
- $callParameters = false;
30
-
31
- // check if order has customer IP in it
32
- $ip = $order->getRemoteIp();
33
- if($ip){
34
- $callParameters = array('use_ip' => $ip);
35
- }
36
-
37
- $time = false;
38
- if ($order->getCreatedAtStoreDate()) {
39
- $time = $order->getCreatedAtStoreDate()->getTimestamp() * 1000;
40
- }
41
-
42
- $identityData = array(
43
- 'email' => $order->getCustomerEmail(),
44
- 'first_name' => $order->getBillingAddress()->getFirstname(),
45
- 'last_name' => $order->getBillingAddress()->getLastname(),
46
- 'name' => $order->getBillingAddress()->getName(),
47
- );
48
-
49
- $builtEventArray = $helper->buildEventArray(
50
- $identityData['email'], 'order', $orderDetails, $identityData, $time, $callParameters
51
- );
52
-
53
- array_push($ordersForSubmition, $builtEventArray);
54
- }
55
- }
56
-
57
- $helper->callBatchApi($ordersForSubmition);
58
  $result['success'] = true;
59
  } catch (Exception $e) {
60
  Mage::logException($e);
19
  try {
20
  $import = Mage::getSingleton('metrilo_analytics/import');
21
  $chunkId = (int)$this->getRequest()->getParam('chunk_id');
22
+ // Get orders from the Database
23
  $orders = $import->getOrders($chunkId);
24
+ // Send orders via API helper method
25
+ $helper->callBatchApi($orders);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  $result['success'] = true;
27
  } catch (Exception $e) {
28
  Mage::logException($e);
app/code/community/Metrilo/Analytics/etc/config.xml CHANGED
@@ -8,7 +8,7 @@
8
  <config>
9
  <modules>
10
  <Metrilo_Analytics>
11
- <version>1.0.5</version>
12
  </Metrilo_Analytics>
13
  </modules>
14
  <frontend>
8
  <config>
9
  <modules>
10
  <Metrilo_Analytics>
11
+ <version>1.1.0</version>
12
  </Metrilo_Analytics>
13
  </modules>
14
  <frontend>
app/design/adminhtml/default/default/template/metrilo/system/config/button.phtml CHANGED
@@ -21,7 +21,7 @@
21
  jQuery.post('<?php echo $this->getAjaxUrl(); ?>', data, function(response) {
22
  new_chunk_id = chunk_id + 1;
23
  if(new_chunk_id < total_chunks){
24
- setTimeout(function(){
25
  sync_chunk(new_chunk_id);
26
  }, 100);
27
  }else{
21
  jQuery.post('<?php echo $this->getAjaxUrl(); ?>', data, function(response) {
22
  new_chunk_id = chunk_id + 1;
23
  if(new_chunk_id < total_chunks){
24
+ setTimeout(function() {
25
  sync_chunk(new_chunk_id);
26
  }, 100);
27
  }else{
app/design/frontend/base/default/template/metrilo/head.phtml CHANGED
@@ -5,7 +5,7 @@ window.metrilo||(window.metrilo=[]),window.metrilo.queue=[],window.metrilo.metho
5
  window.metrilo.skelet=function(e){return function(){a=Array.prototype.slice.call(arguments);a.unshift(e);window.metrilo.queue.push(a)}};
6
  for(var i=0;window.metrilo.methods.length>i;i++){var mthd=window.metrilo.methods[i];window.metrilo[mthd]=window.metrilo.skelet(mthd)}
7
  window.metrilo.load=function(e){var t=document,n=t.getElementsByTagName("script")[0],r=t.createElement("script");
8
- r.type="text/javascript";r.async=true;r.src="//p.metrilo.com/j/"+e+".js";n.parentNode.insertBefore(r,n)};
9
  metrilo.load("<?php echo $helper->getApiToken(); ?>");
10
 
11
  <?php foreach ($events as $event) : ?>
5
  window.metrilo.skelet=function(e){return function(){a=Array.prototype.slice.call(arguments);a.unshift(e);window.metrilo.queue.push(a)}};
6
  for(var i=0;window.metrilo.methods.length>i;i++){var mthd=window.metrilo.methods[i];window.metrilo[mthd]=window.metrilo.skelet(mthd)}
7
  window.metrilo.load=function(e){var t=document,n=t.getElementsByTagName("script")[0],r=t.createElement("script");
8
+ r.type="text/javascript";r.async=true;r.src="//t.metrilo.com/j/"+e+".js";n.parentNode.insertBefore(r,n)};
9
  metrilo.load("<?php echo $helper->getApiToken(); ?>");
10
 
11
  <?php foreach ($events as $event) : ?>
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Metrilo_Analytics</name>
4
- <version>1.0.8</version>
5
  <stability>stable</stability>
6
  <license>Apache Software License (ASL)</license>
7
  <channel>community</channel>
@@ -18,11 +18,11 @@
18
  * Powerful intelligence for your sales team&amp;#xD;&#xD;
19
  * With Metrilo, you have an amazing real-time overview of who's doing what on your eCommerce store.&amp;#xD;&#xD;
20
  * Metrilo automatically collects and analyzes your eCommerce data to use for your email campaigns.</description>
21
- <notes>Identify before each order. Ensure order passed with the new identification data.</notes>
22
  <authors><author><name>Murry Ivanoff</name><user>Metrilo</user><email>murry@metrilo.com</email></author><author><name>Zhivko Draganov</name><user>zhivko</user><email>zhivko@metirlo.com</email></author><author><name>Miroslav Petrov</name><user>miro</user><email>miro91tn@gmail.com</email></author></authors>
23
- <date>2016-02-18</date>
24
- <time>15:18:14</time>
25
- <contents><target name="magecommunity"><dir name="Metrilo"><dir name="Analytics"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Form"><file name="Button.php" hash="70aadb3d62d998a3076bd4f9209db560"/></dir></dir></dir></dir><file name="Head.php" hash="7fc6870506f8882520b4e2b9596600d7"/></dir><dir name="Helper"><file name="Data.php" hash="119612e3b9ede8a13a037b0ae265cf55"/></dir><dir name="Model"><file name="Import.php" hash="1eb20cd00c210ee378039edb8d0515dc"/><file name="Observer.php" hash="6157b27b79941b781074a26b36358b71"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="AjaxController.php" hash="0a16196c1c62b3359508b0b688a36e04"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="00c90fdba5e48bb35367c16c83abd6a7"/><file name="config.xml" hash="8fd63a66c503b8d5589a107eaff71949"/><file name="system.xml" hash="7564c68e51df23d7975bc1c9ead7be8f"/></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="metrilo_analytics.xml" hash="0e6911e2e883992f2182969286d929b1"/></dir><dir name="template"><dir name="metrilo"><dir name="system"><dir name="config"><file name="button.phtml" hash="528d7eb52bf996b7b2a31e8c6a4d7d86"/></dir></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="metrilo_analytics.xml" hash="c7dcf4057bc31d906865e82159ac5eca"/></dir><dir name="template"><dir name="metrilo"><file name="head.phtml" hash="5330ccdcfe648e146402f7c552bf6043"/></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="metrilo"><file name="favicon-metrilo.png" hash="743558f1e49a730be9d515197a36567b"/><file name="loader.gif" hash="e05e6bb35d035cac4f3e0c8af213e9ab"/><file name="logo.png" hash="e9e54afd81384e12f77aca4eaebf5be8"/><file name="styles.css" hash="da0c07513d917e4ad08ff50814b536e1"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Metrilo_Analytics.xml" hash="3a4dbecc4e093537f11dd4c8fa2756e7"/></dir></target></contents>
26
  <compatible/>
27
  <dependencies><required><php><min>5.2.1</min><max>5.6.22</max></php></required></dependencies>
28
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Metrilo_Analytics</name>
4
+ <version>1.1.0</version>
5
  <stability>stable</stability>
6
  <license>Apache Software License (ASL)</license>
7
  <channel>community</channel>
18
  * Powerful intelligence for your sales team&amp;#xD;&#xD;
19
  * With Metrilo, you have an amazing real-time overview of who's doing what on your eCommerce store.&amp;#xD;&#xD;
20
  * Metrilo automatically collects and analyzes your eCommerce data to use for your email campaigns.</description>
21
+ <notes>Submit async orders to Metrilo to handle drops on external payment pages.</notes>
22
  <authors><author><name>Murry Ivanoff</name><user>Metrilo</user><email>murry@metrilo.com</email></author><author><name>Zhivko Draganov</name><user>zhivko</user><email>zhivko@metirlo.com</email></author><author><name>Miroslav Petrov</name><user>miro</user><email>miro91tn@gmail.com</email></author></authors>
23
+ <date>2016-03-28</date>
24
+ <time>08:01:26</time>
25
+ <contents><target name="magecommunity"><dir name="Metrilo"><dir name="Analytics"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Form"><file name="Button.php" hash="056b366e98b9a61a5594679ae4b15cdd"/></dir></dir></dir></dir><file name="Head.php" hash="7fc6870506f8882520b4e2b9596600d7"/></dir><dir name="Helper"><file name="AsyncHttpClient.php" hash="1a4a85f68808e3eee8651a82f86093c5"/><file name="Data.php" hash="9430df17c85bc59687f46cdcaa7cbb28"/></dir><dir name="Model"><file name="Import.php" hash="1eb20cd00c210ee378039edb8d0515dc"/><file name="Observer.php" hash="3a1a7ad40a6d385c7acfe39844660b7c"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="AjaxController.php" hash="e99c1af2e7c9cb18dc2b5ee61022f87b"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="00c90fdba5e48bb35367c16c83abd6a7"/><file name="config.xml" hash="c85a9993d7046eb8e6a52f7684268ff3"/><file name="system.xml" hash="7564c68e51df23d7975bc1c9ead7be8f"/></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="metrilo_analytics.xml" hash="0e6911e2e883992f2182969286d929b1"/></dir><dir name="template"><dir name="metrilo"><dir name="system"><dir name="config"><file name="button.phtml" hash="c69dd7d8286cdff217c8c18c8ef5e2e9"/></dir></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="metrilo_analytics.xml" hash="c7dcf4057bc31d906865e82159ac5eca"/></dir><dir name="template"><dir name="metrilo"><file name="head.phtml" hash="c32d5255058eefcc623c51a1dc51c23e"/></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="metrilo"><file name="favicon-metrilo.png" hash="743558f1e49a730be9d515197a36567b"/><file name="loader.gif" hash="e05e6bb35d035cac4f3e0c8af213e9ab"/><file name="logo.png" hash="e9e54afd81384e12f77aca4eaebf5be8"/><file name="styles.css" hash="da0c07513d917e4ad08ff50814b536e1"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Metrilo_Analytics.xml" hash="3a4dbecc4e093537f11dd4c8fa2756e7"/></dir></target></contents>
26
  <compatible/>
27
  <dependencies><required><php><min>5.2.1</min><max>5.6.22</max></php></required></dependencies>
28
  </package>