recapture - Version 1.3.0

Version Notes

Updated version to 1.3.0

Added bot IP exclusion

Download this release

Release Info

Developer David Webber
Extension recapture
Version 1.3.0
Comparing to
See all releases


Code changes from version 1.2.0 to 1.3.0

app/code/local/Recapture/Connector/Helper/Data.php CHANGED
@@ -1,254 +1,273 @@
1
- <?php
2
-
3
- class Recapture_Connector_Helper_Data extends Mage_Core_Helper_Abstract {
4
-
5
- private $_registry = array();
6
-
7
- public function isEnabled(){
8
-
9
- return Mage::getStoreConfig('recapture/configuration/enabled');
10
-
11
- }
12
-
13
- public function shouldCaptureSubscriber(){
14
-
15
- return Mage::getStoreConfig('recapture/abandoned_carts/capture_subscriber');
16
-
17
- }
18
-
19
- public function getHomeUrl($path){
20
-
21
- $baseUrl = Mage::getStoreConfig('recapture/configuration/dev_base_url');
22
- if (!$baseUrl) $baseUrl = 'http://www.recapture.io/';
23
-
24
- return $baseUrl . $path;
25
-
26
- }
27
-
28
- public function canTrackEmail(){
29
-
30
- return Mage::getStoreConfig('recapture/abandoned_carts/track_email');
31
-
32
- }
33
-
34
- public function getReturnLanding(){
35
-
36
- return Mage::getStoreConfig('recapture/abandoned_carts/return_landing');
37
-
38
- }
39
-
40
- public function getApiKey(){
41
-
42
- return Mage::getStoreConfig('recapture/configuration/api_key');
43
-
44
- }
45
-
46
- public function getScopeStoreId(){
47
-
48
- $website = Mage::app()->getRequest()->getParam('website');
49
- $website = !empty($website) ? $website : Mage::getSingleton('adminhtml/config_data')->getWebsite();
50
-
51
- $store = Mage::app()->getRequest()->getParam('store');
52
- $store = !empty($store) ? $store : Mage::getSingleton('adminhtml/config_data')->getStore();
53
-
54
- if (!$website && !$store) return '0';
55
-
56
- if ($store) return Mage::getModel('core/store')->load($store)->getId();
57
- if ($website) return Mage::getModel('core/website')->load($website)->getDefaultGroup()->getDefaultStoreId();
58
-
59
-
60
-
61
- }
62
-
63
- public function getCurrentScope(){
64
-
65
- $website = Mage::app()->getRequest()->getParam('website');
66
- $website = !empty($website) ? $website : Mage::getSingleton('adminhtml/config_data')->getWebsite();
67
-
68
- $store = Mage::app()->getRequest()->getParam('store');
69
- $store = !empty($store) ? $store : Mage::getSingleton('adminhtml/config_data')->getStore();
70
-
71
- if (!$website && !$store) return 'default';
72
-
73
- if ($store) return 'stores';
74
- if ($website) return 'websites';
75
-
76
- }
77
-
78
- public function getScopeForUrl(){
79
-
80
- $website = Mage::app()->getRequest()->getParam('website');
81
- $website = !empty($website) ? $website : Mage::getSingleton('adminhtml/config_data')->getWebsite();
82
-
83
- $store = Mage::app()->getRequest()->getParam('store');
84
- $store = !empty($store) ? $store : Mage::getSingleton('adminhtml/config_data')->getStore();
85
-
86
- if (!$website && !$store) return array();
87
-
88
- if ($store) return array('website' => $website, 'store' => $store);
89
- if ($website) return array('website' => $website);
90
-
91
- }
92
-
93
- public function getCurrentScopeId(){
94
-
95
- $website = Mage::app()->getRequest()->getParam('website');
96
- $website = !empty($website) ? $website : Mage::getSingleton('adminhtml/config_data')->getWebsite();
97
-
98
- $store = Mage::app()->getRequest()->getParam('store');
99
- $store = !empty($store) ? $store : Mage::getSingleton('adminhtml/config_data')->getStore();
100
-
101
- if (!$website && !$store) return 0;
102
-
103
- if ($store) return Mage::getModel('core/store')->load($store)->getId();
104
- if ($website) return Mage::getModel('core/website')->load($website)->getId();
105
-
106
- }
107
-
108
- public function translateCartHash($hash = ''){
109
-
110
- if (empty($hash)) return false;
111
-
112
- $result = Mage::helper('recapture/transport')->dispatch('cart/retrieve', array(
113
- 'hash' => $hash
114
- ));
115
-
116
- $body = @json_decode($result->getBody());
117
-
118
- if ($body->status == 'success'){
119
-
120
- return $body->data->cart_id;
121
-
122
- } else return false;
123
-
124
- }
125
-
126
- public function associateCartToMe($cartId = null){
127
-
128
- if (empty($cartId)) return false;
129
-
130
- $session = Mage::getSingleton('checkout/session');
131
-
132
- $session->clear();
133
- $session->setQuoteId($cartId);
134
-
135
- $quote = $session->getQuote();
136
-
137
- //if this cart somehow was already converted, we're not going to be able to load it. as such, we can't associate it.
138
- if ($quote->getId() != $cartId) return false;
139
-
140
- return true;
141
-
142
- }
143
-
144
- public function getCustomerFirstname(Mage_Sales_Model_Quote $quote){
145
-
146
- //we first check the quote model itself
147
- $customerFirstname = $quote->getCustomerFirstname();
148
- if (!empty($customerFirstname)) return $customerFirstname;
149
-
150
- //if not on the quote model, we check the billing address
151
- $billingAddress = $quote->getBillingAddress();
152
- if ($billingAddress){
153
-
154
- $customerFirstname = $billingAddress->getFirstname();
155
- if (!empty($customerFirstname)) return $customerFirstname;
156
-
157
- }
158
-
159
- //if not in the billing address, last resort we check the shipping address
160
- $shippingAddress = $quote->getShippingAddress();
161
- if ($shippingAddress){
162
-
163
- $customerFirstname = $shippingAddress->getFirstname();
164
- if (!empty($customerFirstname)) return $customerFirstname;
165
-
166
- }
167
-
168
- return null;
169
-
170
- }
171
-
172
- public function getCustomerLastname(Mage_Sales_Model_Quote $quote){
173
-
174
- //we first check the quote model itself
175
- $customerLastname = $quote->getCustomerLastname();
176
- if (!empty($customerLastname)) return $customerLastname;
177
-
178
- //if not on the quote model, we check the billing address
179
- $billingAddress = $quote->getBillingAddress();
180
- if ($billingAddress){
181
-
182
- $customerLastname = $billingAddress->getLastname();
183
- if (!empty($customerLastname)) return $customerLastname;
184
-
185
- }
186
-
187
- //if not in the billing address, last resort we check the shipping address
188
- $shippingAddress = $quote->getShippingAddress();
189
- if ($shippingAddress){
190
-
191
- $customerLastname = $shippingAddress->getLastname();
192
- if (!empty($customerLastname)) return $customerLastname;
193
-
194
- }
195
-
196
- return null;
197
-
198
- }
199
-
200
- public function getCustomerEmail(Mage_Sales_Model_Quote $quote){
201
-
202
- //we first check the quote model itself
203
- $customerEmail = $quote->getCustomerEmail();
204
- if (!empty($customerEmail)) return $customerEmail;
205
-
206
- //if not on the quote model, we check the billing address
207
- $billingAddress = $quote->getBillingAddress();
208
- if ($billingAddress){
209
-
210
- $customerEmail = $billingAddress->getEmail();
211
- if (!empty($customerEmail)) return $customerEmail;
212
-
213
- }
214
-
215
- //if not in the billing address, last resort we check the shipping address
216
- $shippingAddress = $quote->getShippingAddress();
217
- if ($shippingAddress){
218
-
219
- $customerEmail = $shippingAddress->getEmail();
220
- if (!empty($customerEmail)) return $customerEmail;
221
-
222
- }
223
-
224
- return null;
225
-
226
- }
227
-
228
-
229
- public function getCustomerHash(){
230
-
231
- return isset($_COOKIE['ra_customer_id']) ? $_COOKIE['ra_customer_id'] : null;
232
-
233
- }
234
-
235
-
236
- public function translateEmailHashes($hashes = array()){
237
-
238
- if (empty($hashes)) return false;
239
-
240
- $result = Mage::helper('recapture/transport')->dispatch('email/retrieve', array(
241
- 'hashes' => $hashes
242
- ));
243
-
244
- $body = @json_decode($result->getBody());
245
-
246
- if ($body->status == 'success'){
247
-
248
- return $body->data->emails;
249
-
250
- } else return false;
251
-
252
- }
253
-
254
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Recapture_Connector_Helper_Data extends Mage_Core_Helper_Abstract {
4
+
5
+ private $_registry = array();
6
+
7
+ public function isEnabled(){
8
+
9
+ return Mage::getStoreConfig('recapture/configuration/enabled');
10
+
11
+ }
12
+
13
+ public function isIpIgnored(){
14
+
15
+ $ips = Mage::getStoreConfig('recapture/abandoned_carts/ignore_ips');
16
+ $exploded = explode(',', $ips);
17
+
18
+ foreach ($exploded as $ip){
19
+
20
+ $ip = trim($ip);
21
+
22
+ if ($ip == Mage::helper('core/http')->getRemoteAddr()){
23
+ return true;
24
+ }
25
+
26
+ }
27
+
28
+ return false;
29
+
30
+ }
31
+
32
+ public function shouldCaptureSubscriber(){
33
+
34
+ return Mage::getStoreConfig('recapture/abandoned_carts/capture_subscriber');
35
+
36
+ }
37
+
38
+ public function getHomeUrl($path){
39
+
40
+ $baseUrl = Mage::getStoreConfig('recapture/configuration/dev_base_url');
41
+ if (!$baseUrl) $baseUrl = 'http://www.recapture.io/';
42
+
43
+ return $baseUrl . $path;
44
+
45
+ }
46
+
47
+ public function canTrackEmail(){
48
+
49
+ return Mage::getStoreConfig('recapture/abandoned_carts/track_email');
50
+
51
+ }
52
+
53
+ public function getReturnLanding(){
54
+
55
+ return Mage::getStoreConfig('recapture/abandoned_carts/return_landing');
56
+
57
+ }
58
+
59
+ public function getApiKey(){
60
+
61
+ return Mage::getStoreConfig('recapture/configuration/api_key');
62
+
63
+ }
64
+
65
+ public function getScopeStoreId(){
66
+
67
+ $website = Mage::app()->getRequest()->getParam('website');
68
+ $website = !empty($website) ? $website : Mage::getSingleton('adminhtml/config_data')->getWebsite();
69
+
70
+ $store = Mage::app()->getRequest()->getParam('store');
71
+ $store = !empty($store) ? $store : Mage::getSingleton('adminhtml/config_data')->getStore();
72
+
73
+ if (!$website && !$store) return '0';
74
+
75
+ if ($store) return Mage::getModel('core/store')->load($store)->getId();
76
+ if ($website) return Mage::getModel('core/website')->load($website)->getDefaultGroup()->getDefaultStoreId();
77
+
78
+
79
+
80
+ }
81
+
82
+ public function getCurrentScope(){
83
+
84
+ $website = Mage::app()->getRequest()->getParam('website');
85
+ $website = !empty($website) ? $website : Mage::getSingleton('adminhtml/config_data')->getWebsite();
86
+
87
+ $store = Mage::app()->getRequest()->getParam('store');
88
+ $store = !empty($store) ? $store : Mage::getSingleton('adminhtml/config_data')->getStore();
89
+
90
+ if (!$website && !$store) return 'default';
91
+
92
+ if ($store) return 'stores';
93
+ if ($website) return 'websites';
94
+
95
+ }
96
+
97
+ public function getScopeForUrl(){
98
+
99
+ $website = Mage::app()->getRequest()->getParam('website');
100
+ $website = !empty($website) ? $website : Mage::getSingleton('adminhtml/config_data')->getWebsite();
101
+
102
+ $store = Mage::app()->getRequest()->getParam('store');
103
+ $store = !empty($store) ? $store : Mage::getSingleton('adminhtml/config_data')->getStore();
104
+
105
+ if (!$website && !$store) return array();
106
+
107
+ if ($store) return array('website' => $website, 'store' => $store);
108
+ if ($website) return array('website' => $website);
109
+
110
+ }
111
+
112
+ public function getCurrentScopeId(){
113
+
114
+ $website = Mage::app()->getRequest()->getParam('website');
115
+ $website = !empty($website) ? $website : Mage::getSingleton('adminhtml/config_data')->getWebsite();
116
+
117
+ $store = Mage::app()->getRequest()->getParam('store');
118
+ $store = !empty($store) ? $store : Mage::getSingleton('adminhtml/config_data')->getStore();
119
+
120
+ if (!$website && !$store) return 0;
121
+
122
+ if ($store) return Mage::getModel('core/store')->load($store)->getId();
123
+ if ($website) return Mage::getModel('core/website')->load($website)->getId();
124
+
125
+ }
126
+
127
+ public function translateCartHash($hash = ''){
128
+
129
+ if (empty($hash)) return false;
130
+
131
+ $result = Mage::helper('recapture/transport')->dispatch('cart/retrieve', array(
132
+ 'hash' => $hash
133
+ ));
134
+
135
+ $body = @json_decode($result->getBody());
136
+
137
+ if ($body->status == 'success'){
138
+
139
+ return $body->data->cart_id;
140
+
141
+ } else return false;
142
+
143
+ }
144
+
145
+ public function associateCartToMe($cartId = null){
146
+
147
+ if (empty($cartId)) return false;
148
+
149
+ $session = Mage::getSingleton('checkout/session');
150
+
151
+ $session->clear();
152
+ $session->setQuoteId($cartId);
153
+
154
+ $quote = $session->getQuote();
155
+
156
+ //if this cart somehow was already converted, we're not going to be able to load it. as such, we can't associate it.
157
+ if ($quote->getId() != $cartId) return false;
158
+
159
+ return true;
160
+
161
+ }
162
+
163
+ public function getCustomerFirstname(Mage_Sales_Model_Quote $quote){
164
+
165
+ //we first check the quote model itself
166
+ $customerFirstname = $quote->getCustomerFirstname();
167
+ if (!empty($customerFirstname)) return $customerFirstname;
168
+
169
+ //if not on the quote model, we check the billing address
170
+ $billingAddress = $quote->getBillingAddress();
171
+ if ($billingAddress){
172
+
173
+ $customerFirstname = $billingAddress->getFirstname();
174
+ if (!empty($customerFirstname)) return $customerFirstname;
175
+
176
+ }
177
+
178
+ //if not in the billing address, last resort we check the shipping address
179
+ $shippingAddress = $quote->getShippingAddress();
180
+ if ($shippingAddress){
181
+
182
+ $customerFirstname = $shippingAddress->getFirstname();
183
+ if (!empty($customerFirstname)) return $customerFirstname;
184
+
185
+ }
186
+
187
+ return null;
188
+
189
+ }
190
+
191
+ public function getCustomerLastname(Mage_Sales_Model_Quote $quote){
192
+
193
+ //we first check the quote model itself
194
+ $customerLastname = $quote->getCustomerLastname();
195
+ if (!empty($customerLastname)) return $customerLastname;
196
+
197
+ //if not on the quote model, we check the billing address
198
+ $billingAddress = $quote->getBillingAddress();
199
+ if ($billingAddress){
200
+
201
+ $customerLastname = $billingAddress->getLastname();
202
+ if (!empty($customerLastname)) return $customerLastname;
203
+
204
+ }
205
+
206
+ //if not in the billing address, last resort we check the shipping address
207
+ $shippingAddress = $quote->getShippingAddress();
208
+ if ($shippingAddress){
209
+
210
+ $customerLastname = $shippingAddress->getLastname();
211
+ if (!empty($customerLastname)) return $customerLastname;
212
+
213
+ }
214
+
215
+ return null;
216
+
217
+ }
218
+
219
+ public function getCustomerEmail(Mage_Sales_Model_Quote $quote){
220
+
221
+ //we first check the quote model itself
222
+ $customerEmail = $quote->getCustomerEmail();
223
+ if (!empty($customerEmail)) return $customerEmail;
224
+
225
+ //if not on the quote model, we check the billing address
226
+ $billingAddress = $quote->getBillingAddress();
227
+ if ($billingAddress){
228
+
229
+ $customerEmail = $billingAddress->getEmail();
230
+ if (!empty($customerEmail)) return $customerEmail;
231
+
232
+ }
233
+
234
+ //if not in the billing address, last resort we check the shipping address
235
+ $shippingAddress = $quote->getShippingAddress();
236
+ if ($shippingAddress){
237
+
238
+ $customerEmail = $shippingAddress->getEmail();
239
+ if (!empty($customerEmail)) return $customerEmail;
240
+
241
+ }
242
+
243
+ return null;
244
+
245
+ }
246
+
247
+
248
+ public function getCustomerHash(){
249
+
250
+ return isset($_COOKIE['ra_customer_id']) ? $_COOKIE['ra_customer_id'] : null;
251
+
252
+ }
253
+
254
+
255
+ public function translateEmailHashes($hashes = array()){
256
+
257
+ if (empty($hashes)) return false;
258
+
259
+ $result = Mage::helper('recapture/transport')->dispatch('email/retrieve', array(
260
+ 'hashes' => $hashes
261
+ ));
262
+
263
+ $body = @json_decode($result->getBody());
264
+
265
+ if ($body->status == 'success'){
266
+
267
+ return $body->data->emails;
268
+
269
+ } else return false;
270
+
271
+ }
272
+
273
+ }
app/code/local/Recapture/Connector/Model/Observer.php CHANGED
@@ -1,226 +1,228 @@
1
- <?php
2
-
3
- class Recapture_Connector_Model_Observer {
4
-
5
- public function quoteUpdate($observer){
6
-
7
- if (!Mage::helper('recapture')->isEnabled()) return $this;
8
-
9
- try {
10
-
11
- return $this->_updateQuote($observer->getEvent()->getQuote());
12
-
13
- } catch (Exception $e){
14
-
15
- Mage::log($e->getMessage());
16
-
17
- }
18
-
19
- return $this;
20
-
21
- }
22
-
23
- protected function _updateQuote(Mage_Sales_Model_Quote $quote){
24
-
25
- if (!Mage::helper('recapture')->isEnabled()) return $this;
26
-
27
- if (!$quote->getId()) return;
28
-
29
- //sales_quote_save_before gets called like 5 times on some page loads, we don't want to do 5 updates per page load
30
- if (Mage::registry('recapture_has_posted')) return;
31
-
32
- Mage::register('recapture_has_posted', true);
33
-
34
- $mediaConfig = Mage::getModel('catalog/product_media_config');
35
- $storeId = Mage::app()->getStore();
36
-
37
- $totalWithTax = Mage::getStoreConfig('recapture/abandoned_carts/include_tax_with_products');
38
-
39
- $transportData = array(
40
- 'first_name' => Mage::helper('recapture')->getCustomerFirstname($quote),
41
- 'last_name' => Mage::helper('recapture')->getCustomerLastname($quote),
42
- 'email' => Mage::helper('recapture')->getCustomerEmail($quote),
43
- 'external_id' => $quote->getId(),
44
- 'grand_total' => $quote->getBaseGrandTotal(),
45
- 'grand_total_display' => Mage::helper('core')->currency($quote->getGrandTotal(), true, false),
46
- 'products' => array(),
47
- 'totals' => array()
48
- );
49
-
50
- $cartItems = $quote->getAllVisibleItems();
51
-
52
- foreach ($cartItems as $item){
53
-
54
- $productModel = $item->getProduct();
55
-
56
- $productImage = false;
57
-
58
- $image = Mage::getResourceModel('catalog/product')->getAttributeRawValue($productModel->getId(), 'thumbnail', $storeId);
59
- if ($image && $image != 'no_selection') $productImage = $mediaConfig->getMediaUrl($image);
60
-
61
- //check configurable first
62
- if ($item->getProductType() == 'configurable'){
63
-
64
- if (Mage::getStoreConfig('checkout/cart/configurable_product_image') == 'itself'){
65
-
66
- $child = $productModel->getIdBySku($item->getSku());
67
-
68
- $image = Mage::getResourceModel('catalog/product')->getAttributeRawValue($child, 'thumbnail', $storeId);
69
- if ($image && $image != 'no_selection') $productImage = $mediaConfig->getMediaUrl($image);
70
-
71
- }
72
- }
73
-
74
- //then check grouped
75
- if (Mage::getStoreConfig('checkout/cart/grouped_product_image') == 'parent'){
76
-
77
- $options = $productModel->getTypeInstance(true)->getOrderOptions($productModel);
78
-
79
- if (isset($options['super_product_config']) && $options['super_product_config']['product_type'] == 'grouped'){
80
-
81
- $parent = $options['super_product_config']['product_id'];
82
- $image = Mage::getResourceModel('catalog/product')->getAttributeRawValue($parent, 'thumbnail', $storeId);
83
-
84
- if ($image && $image != 'no_selection') $productImage = $mediaConfig->getMediaUrl($image);
85
-
86
- }
87
- }
88
-
89
- //if after all that, we still don't have a product image, we get the placeholder image
90
- if (!$productImage) {
91
-
92
- $productImage = $mediaConfig->getMediaUrl('placeholder/' . Mage::getStoreConfig("catalog/placeholder/image_placeholder"));
93
-
94
- }
95
-
96
- $optionsHelper = Mage::helper('catalog/product_configuration');
97
-
98
- if ($item->getProductType() == 'configurable'){
99
-
100
- $visibleOptions = $optionsHelper->getConfigurableOptions($item);
101
-
102
- } else {
103
-
104
- $visibleOptions = $optionsHelper->getCustomOptions($item);
105
-
106
- }
107
-
108
- $product = array(
109
- 'name' => $item->getName(),
110
- 'sku' => $item->getSku(),
111
- 'price' => $totalWithTax ? $item->getBasePriceInclTax() : $item->getBasePrice(),
112
- 'price_display' => Mage::helper('core')->currency($totalWithTax ? $item->getPriceInclTax() : $item->getPrice(), true, false),
113
- 'qty' => $item->getQty(),
114
- 'image' => $productImage,
115
- 'options' => $visibleOptions
116
- );
117
-
118
- $transportData['products'][] = $product;
119
-
120
- }
121
-
122
- $totals = $quote->getTotals();
123
-
124
- foreach ($totals as $total){
125
-
126
- //we pass grand total on the top level
127
- if ($total->getCode() == 'grand_total') continue;
128
-
129
- $total = array(
130
- 'name' => $total->getTitle(),
131
- 'amount' => $total->getValue()
132
- );
133
-
134
- $transportData['totals'][] = $total;
135
-
136
- }
137
-
138
- Mage::helper('recapture/transport')->dispatch('cart', $transportData);
139
-
140
- return $this;
141
-
142
- }
143
-
144
- public function quoteDelete($observer){
145
-
146
- if (!Mage::helper('recapture')->isEnabled()) return $this;
147
-
148
- try {
149
-
150
- $quote = $observer->getEvent()->getQuote();
151
-
152
- $transportData = array(
153
- 'external_id' => $quote->getId()
154
- );
155
-
156
- Mage::helper('recapture/transport')->dispatch('cart/remove', $transportData);
157
-
158
- } catch (Exception $e){
159
-
160
- Mage::log($e->getMessage());
161
-
162
- }
163
-
164
- return $this;
165
-
166
- }
167
-
168
- public function cartConversion($observer){
169
-
170
- if (!Mage::helper('recapture')->isEnabled()) return $this;
171
-
172
- try {
173
-
174
- $order = $observer->getEvent()->getOrder();
175
-
176
- $transportData = array(
177
- 'external_id' => $order->getQuoteId()
178
- );
179
-
180
- Mage::helper('recapture/transport')->dispatch('conversion', $transportData);
181
-
182
- } catch (Exception $e){
183
-
184
- Mage::log($e->getMessage());
185
-
186
- }
187
-
188
- return $this;
189
-
190
- }
191
-
192
- public function newsletterSubscriber($observer){
193
-
194
- if (!Mage::helper('recapture')->isEnabled()) return $this;
195
- if (!Mage::helper('recapture')->shouldCaptureSubscriber()) return $this;
196
-
197
- //if we can't identify this customer, we return out
198
- if (!Mage::helper('recapture')->getCustomerHash()) return $this;
199
-
200
- try {
201
-
202
- $subscriber = $observer->getEvent()->getSubscriber();
203
-
204
- $email = $subscriber->getSubscriberEmail();
205
-
206
- if (Zend_Validate::is($email, 'EmailAddress')){
207
-
208
- $transportData = array(
209
- 'email' => $email
210
- );
211
-
212
- Mage::helper('recapture/transport')->dispatch('email/subscribe', $transportData);
213
-
214
- }
215
-
216
- } catch (Exception $e){
217
-
218
- Mage::log($e->getMessage());
219
-
220
- }
221
-
222
- return $this;
223
-
224
- }
225
-
 
 
226
  }
1
+ <?php
2
+
3
+ class Recapture_Connector_Model_Observer {
4
+
5
+ public function quoteUpdate($observer){
6
+
7
+ if (!Mage::helper('recapture')->isEnabled()) return $this;
8
+
9
+ try {
10
+
11
+ return $this->_updateQuote($observer->getEvent()->getQuote());
12
+
13
+ } catch (Exception $e){
14
+
15
+ Mage::log($e->getMessage());
16
+
17
+ }
18
+
19
+ return $this;
20
+
21
+ }
22
+
23
+ protected function _updateQuote(Mage_Sales_Model_Quote $quote){
24
+
25
+ if (!Mage::helper('recapture')->isEnabled()) return $this;
26
+
27
+ if (!$quote->getId()) return;
28
+
29
+ //sales_quote_save_before gets called like 5 times on some page loads, we don't want to do 5 updates per page load
30
+ if (Mage::registry('recapture_has_posted')) return;
31
+
32
+ Mage::register('recapture_has_posted', true);
33
+
34
+ if (Mage::helper('recapture')->isIpIgnored()) return $this;
35
+
36
+ $mediaConfig = Mage::getModel('catalog/product_media_config');
37
+ $storeId = Mage::app()->getStore();
38
+
39
+ $totalWithTax = Mage::getStoreConfig('recapture/abandoned_carts/include_tax_with_products');
40
+
41
+ $transportData = array(
42
+ 'first_name' => Mage::helper('recapture')->getCustomerFirstname($quote),
43
+ 'last_name' => Mage::helper('recapture')->getCustomerLastname($quote),
44
+ 'email' => Mage::helper('recapture')->getCustomerEmail($quote),
45
+ 'external_id' => $quote->getId(),
46
+ 'grand_total' => $quote->getBaseGrandTotal(),
47
+ 'grand_total_display' => Mage::helper('core')->currency($quote->getGrandTotal(), true, false),
48
+ 'products' => array(),
49
+ 'totals' => array()
50
+ );
51
+
52
+ $cartItems = $quote->getAllVisibleItems();
53
+
54
+ foreach ($cartItems as $item){
55
+
56
+ $productModel = $item->getProduct();
57
+
58
+ $productImage = false;
59
+
60
+ $image = Mage::getResourceModel('catalog/product')->getAttributeRawValue($productModel->getId(), 'thumbnail', $storeId);
61
+ if ($image && $image != 'no_selection') $productImage = $mediaConfig->getMediaUrl($image);
62
+
63
+ //check configurable first
64
+ if ($item->getProductType() == 'configurable'){
65
+
66
+ if (Mage::getStoreConfig('checkout/cart/configurable_product_image') == 'itself'){
67
+
68
+ $child = $productModel->getIdBySku($item->getSku());
69
+
70
+ $image = Mage::getResourceModel('catalog/product')->getAttributeRawValue($child, 'thumbnail', $storeId);
71
+ if ($image && $image != 'no_selection') $productImage = $mediaConfig->getMediaUrl($image);
72
+
73
+ }
74
+ }
75
+
76
+ //then check grouped
77
+ if (Mage::getStoreConfig('checkout/cart/grouped_product_image') == 'parent'){
78
+
79
+ $options = $productModel->getTypeInstance(true)->getOrderOptions($productModel);
80
+
81
+ if (isset($options['super_product_config']) && $options['super_product_config']['product_type'] == 'grouped'){
82
+
83
+ $parent = $options['super_product_config']['product_id'];
84
+ $image = Mage::getResourceModel('catalog/product')->getAttributeRawValue($parent, 'thumbnail', $storeId);
85
+
86
+ if ($image && $image != 'no_selection') $productImage = $mediaConfig->getMediaUrl($image);
87
+
88
+ }
89
+ }
90
+
91
+ //if after all that, we still don't have a product image, we get the placeholder image
92
+ if (!$productImage) {
93
+
94
+ $productImage = $mediaConfig->getMediaUrl('placeholder/' . Mage::getStoreConfig("catalog/placeholder/image_placeholder"));
95
+
96
+ }
97
+
98
+ $optionsHelper = Mage::helper('catalog/product_configuration');
99
+
100
+ if ($item->getProductType() == 'configurable'){
101
+
102
+ $visibleOptions = $optionsHelper->getConfigurableOptions($item);
103
+
104
+ } else {
105
+
106
+ $visibleOptions = $optionsHelper->getCustomOptions($item);
107
+
108
+ }
109
+
110
+ $product = array(
111
+ 'name' => $item->getName(),
112
+ 'sku' => $item->getSku(),
113
+ 'price' => $totalWithTax ? $item->getBasePriceInclTax() : $item->getBasePrice(),
114
+ 'price_display' => Mage::helper('core')->currency($totalWithTax ? $item->getPriceInclTax() : $item->getPrice(), true, false),
115
+ 'qty' => $item->getQty(),
116
+ 'image' => $productImage,
117
+ 'options' => $visibleOptions
118
+ );
119
+
120
+ $transportData['products'][] = $product;
121
+
122
+ }
123
+
124
+ $totals = $quote->getTotals();
125
+
126
+ foreach ($totals as $total){
127
+
128
+ //we pass grand total on the top level
129
+ if ($total->getCode() == 'grand_total') continue;
130
+
131
+ $total = array(
132
+ 'name' => $total->getTitle(),
133
+ 'amount' => $total->getValue()
134
+ );
135
+
136
+ $transportData['totals'][] = $total;
137
+
138
+ }
139
+
140
+ Mage::helper('recapture/transport')->dispatch('cart', $transportData);
141
+
142
+ return $this;
143
+
144
+ }
145
+
146
+ public function quoteDelete($observer){
147
+
148
+ if (!Mage::helper('recapture')->isEnabled()) return $this;
149
+
150
+ try {
151
+
152
+ $quote = $observer->getEvent()->getQuote();
153
+
154
+ $transportData = array(
155
+ 'external_id' => $quote->getId()
156
+ );
157
+
158
+ Mage::helper('recapture/transport')->dispatch('cart/remove', $transportData);
159
+
160
+ } catch (Exception $e){
161
+
162
+ Mage::log($e->getMessage());
163
+
164
+ }
165
+
166
+ return $this;
167
+
168
+ }
169
+
170
+ public function cartConversion($observer){
171
+
172
+ if (!Mage::helper('recapture')->isEnabled()) return $this;
173
+
174
+ try {
175
+
176
+ $order = $observer->getEvent()->getOrder();
177
+
178
+ $transportData = array(
179
+ 'external_id' => $order->getQuoteId()
180
+ );
181
+
182
+ Mage::helper('recapture/transport')->dispatch('conversion', $transportData);
183
+
184
+ } catch (Exception $e){
185
+
186
+ Mage::log($e->getMessage());
187
+
188
+ }
189
+
190
+ return $this;
191
+
192
+ }
193
+
194
+ public function newsletterSubscriber($observer){
195
+
196
+ if (!Mage::helper('recapture')->isEnabled()) return $this;
197
+ if (!Mage::helper('recapture')->shouldCaptureSubscriber()) return $this;
198
+
199
+ //if we can't identify this customer, we return out
200
+ if (!Mage::helper('recapture')->getCustomerHash()) return $this;
201
+
202
+ try {
203
+
204
+ $subscriber = $observer->getEvent()->getSubscriber();
205
+
206
+ $email = $subscriber->getSubscriberEmail();
207
+
208
+ if (Zend_Validate::is($email, 'EmailAddress')){
209
+
210
+ $transportData = array(
211
+ 'email' => $email
212
+ );
213
+
214
+ Mage::helper('recapture/transport')->dispatch('email/subscribe', $transportData);
215
+
216
+ }
217
+
218
+ } catch (Exception $e){
219
+
220
+ Mage::log($e->getMessage());
221
+
222
+ }
223
+
224
+ return $this;
225
+
226
+ }
227
+
228
  }
app/code/local/Recapture/Connector/etc/config.xml CHANGED
@@ -1,140 +1,140 @@
1
- <?xml version="1.0"?>
2
- <config>
3
- <modules>
4
- <Recapture_Connector>
5
- <version>1.2.0</version>
6
- </Recapture_Connector>
7
- </modules>
8
-
9
- <global>
10
-
11
- <blocks>
12
- <recapture>
13
- <class>Recapture_Connector_Block</class>
14
- </recapture>
15
- </blocks>
16
-
17
- <helpers>
18
- <recapture>
19
- <class>Recapture_Connector_Helper</class>
20
- </recapture>
21
- </helpers>
22
-
23
- <models>
24
- <recapture>
25
- <class>Recapture_Connector_Model</class>
26
- </recapture>
27
- </models>
28
-
29
- <events>
30
-
31
- <sales_quote_save_after>
32
- <observers>
33
- <recapture_cart_update>
34
- <type>singleton</type>
35
- <class>Recapture_Connector_Model_Observer</class>
36
- <method>quoteUpdate</method>
37
- </recapture_cart_update>
38
- </observers>
39
- </sales_quote_save_after>
40
-
41
- <sales_quote_delete_after>
42
- <observers>
43
- <recapture_cart_update>
44
- <type>singleton</type>
45
- <class>Recapture_Connector_Model_Observer</class>
46
- <method>quoteDelete</method>
47
- </recapture_cart_update>
48
- </observers>
49
- </sales_quote_delete_after>
50
-
51
- <sales_order_place_after>
52
- <observers>
53
- <recapture_cart_conversion>
54
- <type>singleton</type>
55
- <class>Recapture_Connector_Model_Observer</class>
56
- <method>cartConversion</method>
57
- </recapture_cart_conversion>
58
- </observers>
59
- </sales_order_place_after>
60
-
61
- <newsletter_subscriber_save_before>
62
- <observers>
63
- <recapture_cart_subscriber>
64
- <type>singleton</type>
65
- <class>Recapture_Connector_Model_Observer</class>
66
- <method>newsletterSubscriber</method>
67
- </recapture_cart_subscriber>
68
- </observers>
69
- </newsletter_subscriber_save_before>
70
-
71
- </events>
72
-
73
- </global>
74
-
75
- <frontend>
76
- <routers>
77
- <recapture>
78
- <use>standard</use>
79
- <args>
80
- <module>Recapture_Connector</module>
81
- <frontName>recapture</frontName>
82
- </args>
83
- </recapture>
84
- </routers>
85
- <layout>
86
- <updates>
87
- <recapture>
88
- <file>recapture.xml</file>
89
- </recapture>
90
- </updates>
91
- </layout>
92
- </frontend>
93
-
94
- <admin>
95
- <routers>
96
- <adminhtml>
97
- <args>
98
- <modules>
99
- <recaptureadmin after="Mage_Adminhtml">Recapture_Connector</recaptureadmin>
100
- </modules>
101
- </args>
102
- </adminhtml>
103
- </routers>
104
- </admin>
105
-
106
- <adminhtml>
107
- <acl>
108
- <resources>
109
- <all>
110
- <title>Allow Everything</title>
111
- </all>
112
- <admin>
113
- <children>
114
- <system>
115
- <children>
116
- <config>
117
- <children>
118
- <recapture>
119
- <title>Recapture Connector - All</title>
120
- </recapture>
121
- </children>
122
- </config>
123
- </children>
124
- </system>
125
- </children>
126
- </admin>
127
- </resources>
128
- </acl>
129
- </adminhtml>
130
-
131
- <default>
132
- <recapture>
133
- <abandoned_carts>
134
- <return_landing>cart</return_landing>
135
- <include_tax_with_products>0</include_tax_with_products>
136
- </abandoned_carts>
137
- </recapture>
138
- </default>
139
-
140
- </config>
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Recapture_Connector>
5
+ <version>1.3.0</version>
6
+ </Recapture_Connector>
7
+ </modules>
8
+
9
+ <global>
10
+
11
+ <blocks>
12
+ <recapture>
13
+ <class>Recapture_Connector_Block</class>
14
+ </recapture>
15
+ </blocks>
16
+
17
+ <helpers>
18
+ <recapture>
19
+ <class>Recapture_Connector_Helper</class>
20
+ </recapture>
21
+ </helpers>
22
+
23
+ <models>
24
+ <recapture>
25
+ <class>Recapture_Connector_Model</class>
26
+ </recapture>
27
+ </models>
28
+
29
+ <events>
30
+
31
+ <sales_quote_save_after>
32
+ <observers>
33
+ <recapture_cart_update>
34
+ <type>singleton</type>
35
+ <class>Recapture_Connector_Model_Observer</class>
36
+ <method>quoteUpdate</method>
37
+ </recapture_cart_update>
38
+ </observers>
39
+ </sales_quote_save_after>
40
+
41
+ <sales_quote_delete_after>
42
+ <observers>
43
+ <recapture_cart_update>
44
+ <type>singleton</type>
45
+ <class>Recapture_Connector_Model_Observer</class>
46
+ <method>quoteDelete</method>
47
+ </recapture_cart_update>
48
+ </observers>
49
+ </sales_quote_delete_after>
50
+
51
+ <sales_order_place_after>
52
+ <observers>
53
+ <recapture_cart_conversion>
54
+ <type>singleton</type>
55
+ <class>Recapture_Connector_Model_Observer</class>
56
+ <method>cartConversion</method>
57
+ </recapture_cart_conversion>
58
+ </observers>
59
+ </sales_order_place_after>
60
+
61
+ <newsletter_subscriber_save_before>
62
+ <observers>
63
+ <recapture_cart_subscriber>
64
+ <type>singleton</type>
65
+ <class>Recapture_Connector_Model_Observer</class>
66
+ <method>newsletterSubscriber</method>
67
+ </recapture_cart_subscriber>
68
+ </observers>
69
+ </newsletter_subscriber_save_before>
70
+
71
+ </events>
72
+
73
+ </global>
74
+
75
+ <frontend>
76
+ <routers>
77
+ <recapture>
78
+ <use>standard</use>
79
+ <args>
80
+ <module>Recapture_Connector</module>
81
+ <frontName>recapture</frontName>
82
+ </args>
83
+ </recapture>
84
+ </routers>
85
+ <layout>
86
+ <updates>
87
+ <recapture>
88
+ <file>recapture.xml</file>
89
+ </recapture>
90
+ </updates>
91
+ </layout>
92
+ </frontend>
93
+
94
+ <admin>
95
+ <routers>
96
+ <adminhtml>
97
+ <args>
98
+ <modules>
99
+ <recaptureadmin after="Mage_Adminhtml">Recapture_Connector</recaptureadmin>
100
+ </modules>
101
+ </args>
102
+ </adminhtml>
103
+ </routers>
104
+ </admin>
105
+
106
+ <adminhtml>
107
+ <acl>
108
+ <resources>
109
+ <all>
110
+ <title>Allow Everything</title>
111
+ </all>
112
+ <admin>
113
+ <children>
114
+ <system>
115
+ <children>
116
+ <config>
117
+ <children>
118
+ <recapture>
119
+ <title>Recapture Connector - All</title>
120
+ </recapture>
121
+ </children>
122
+ </config>
123
+ </children>
124
+ </system>
125
+ </children>
126
+ </admin>
127
+ </resources>
128
+ </acl>
129
+ </adminhtml>
130
+
131
+ <default>
132
+ <recapture>
133
+ <abandoned_carts>
134
+ <return_landing>cart</return_landing>
135
+ <include_tax_with_products>0</include_tax_with_products>
136
+ </abandoned_carts>
137
+ </recapture>
138
+ </default>
139
+
140
+ </config>
app/code/local/Recapture/Connector/etc/system.xml CHANGED
@@ -1,120 +1,131 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <config>
3
- <tabs>
4
- <recapture translate="label" module="recapture">
5
- <label>Recapture Connector</label>
6
- <sort_order>100</sort_order>
7
- </recapture>
8
- </tabs>
9
- <sections>
10
- <recapture translate="label" module="recapture">
11
- <label>Extension Options</label>
12
- <tab>recapture</tab>
13
- <sort_order>1000</sort_order>
14
- <show_in_default>1</show_in_default>
15
- <show_in_website>1</show_in_website>
16
- <show_in_store>1</show_in_store>
17
-
18
- <groups>
19
- <configuration translate="label" module="recapture">
20
- <label>Authentication</label>
21
- <frontend_type>text</frontend_type>
22
- <sort_order>10</sort_order>
23
- <show_in_default>1</show_in_default>
24
- <show_in_website>1</show_in_website>
25
- <show_in_store>1</show_in_store>
26
-
27
- <fields>
28
- <status translate="label">
29
- <label>Authentication Status</label>
30
- <sort_order>0</sort_order>
31
- <type>text</type>
32
- <show_in_default>1</show_in_default>
33
- <show_in_website>1</show_in_website>
34
- <show_in_store>1</show_in_store>
35
- <frontend_model>recapture/adminhtml_system_config_status</frontend_model>
36
- </status>
37
- <authenticate translate="label">
38
- <label>Authenticate Account</label>
39
- <sort_order>1</sort_order>
40
- <type>button</type>
41
- <show_in_default>1</show_in_default>
42
- <show_in_website>1</show_in_website>
43
- <show_in_store>0</show_in_store>
44
- <frontend_model>recapture/adminhtml_system_config_authenticate</frontend_model>
45
- </authenticate>
46
- <enabled translate="label">
47
- <label>Enabled</label>
48
- <frontend_type>select</frontend_type>
49
- <sort_order>2</sort_order>
50
- <show_in_default>1</show_in_default>
51
- <show_in_website>1</show_in_website>
52
- <show_in_store>0</show_in_store>
53
- <source_model>adminhtml/system_config_source_yesno</source_model>
54
- </enabled>
55
- <api_key translate="label">
56
- <label>API Key</label>
57
- <frontend_type>text</frontend_type>
58
- <frontend_model>recapture/adminhtml_system_config_key</frontend_model>
59
- <sort_order>20</sort_order>
60
- <show_in_default>1</show_in_default>
61
- <show_in_website>1</show_in_website>
62
- <show_in_store>0</show_in_store>
63
- </api_key>
64
- </fields>
65
- </configuration>
66
- <abandoned_carts translate="label" module="recapture">
67
- <label>Abandoned Carts Configuration</label>
68
- <frontend_type>text</frontend_type>
69
- <sort_order>20</sort_order>
70
- <show_in_default>1</show_in_default>
71
- <show_in_website>1</show_in_website>
72
- <show_in_store>1</show_in_store>
73
-
74
- <fields>
75
- <track_email translate="label">
76
- <label>Enable Pre-submit Email Capturing</label>
77
- <frontend_type>select</frontend_type>
78
- <sort_order>10</sort_order>
79
- <show_in_default>1</show_in_default>
80
- <show_in_website>1</show_in_website>
81
- <show_in_store>0</show_in_store>
82
- <source_model>adminhtml/system_config_source_yesno</source_model>
83
- <comment>When enabled, this will immediately capture typed email addresses anywhere on your site, without requiring the customer to submit any type of form. Useful on checkouts like One Step Checkout.</comment>
84
- </track_email>
85
- <capture_subscriber translate="label">
86
- <label>Enable Newsletter Subscription Capturing</label>
87
- <frontend_type>select</frontend_type>
88
- <sort_order>10</sort_order>
89
- <show_in_default>1</show_in_default>
90
- <show_in_website>1</show_in_website>
91
- <show_in_store>0</show_in_store>
92
- <source_model>adminhtml/system_config_source_yesno</source_model>
93
- <comment>When enabled, this will capture any emails that are subscribed to your newsletter.</comment>
94
- </capture_subscriber>
95
- <return_landing translate="label">
96
- <label>Click Through Landing</label>
97
- <frontend_type>select</frontend_type>
98
- <sort_order>20</sort_order>
99
- <show_in_default>1</show_in_default>
100
- <show_in_website>1</show_in_website>
101
- <show_in_store>0</show_in_store>
102
- <source_model>recapture/landing</source_model>
103
- <comment>What page do you want the customer to land on when they click a link in any abandoned cart emails we send?</comment>
104
- </return_landing>
105
- <include_tax_with_products translate="label">
106
- <label>Include Tax with Product Totals</label>
107
- <frontend_type>select</frontend_type>
108
- <sort_order>30</sort_order>
109
- <show_in_default>1</show_in_default>
110
- <show_in_website>1</show_in_website>
111
- <show_in_store>0</show_in_store>
112
- <source_model>adminhtml/system_config_source_yesno</source_model>
113
- <comment>Whether or not to include tax in the product total.</comment>
114
- </include_tax_with_products>
115
- </fields>
116
- </abandoned_carts>
117
- </groups>
118
- </recapture>
119
- </sections>
 
 
 
 
 
 
 
 
 
 
 
120
  </config>
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <tabs>
4
+ <recapture translate="label" module="recapture">
5
+ <label>Recapture Connector</label>
6
+ <sort_order>100</sort_order>
7
+ </recapture>
8
+ </tabs>
9
+ <sections>
10
+ <recapture translate="label" module="recapture">
11
+ <label>Extension Options</label>
12
+ <tab>recapture</tab>
13
+ <sort_order>1000</sort_order>
14
+ <show_in_default>1</show_in_default>
15
+ <show_in_website>1</show_in_website>
16
+ <show_in_store>1</show_in_store>
17
+
18
+ <groups>
19
+ <configuration translate="label" module="recapture">
20
+ <label>Authentication</label>
21
+ <frontend_type>text</frontend_type>
22
+ <sort_order>10</sort_order>
23
+ <show_in_default>1</show_in_default>
24
+ <show_in_website>1</show_in_website>
25
+ <show_in_store>1</show_in_store>
26
+
27
+ <fields>
28
+ <status translate="label">
29
+ <label>Authentication Status</label>
30
+ <sort_order>0</sort_order>
31
+ <type>text</type>
32
+ <show_in_default>1</show_in_default>
33
+ <show_in_website>1</show_in_website>
34
+ <show_in_store>1</show_in_store>
35
+ <frontend_model>recapture/adminhtml_system_config_status</frontend_model>
36
+ </status>
37
+ <authenticate translate="label">
38
+ <label>Authenticate Account</label>
39
+ <sort_order>1</sort_order>
40
+ <type>button</type>
41
+ <show_in_default>1</show_in_default>
42
+ <show_in_website>1</show_in_website>
43
+ <show_in_store>0</show_in_store>
44
+ <frontend_model>recapture/adminhtml_system_config_authenticate</frontend_model>
45
+ </authenticate>
46
+ <enabled translate="label">
47
+ <label>Enabled</label>
48
+ <frontend_type>select</frontend_type>
49
+ <sort_order>2</sort_order>
50
+ <show_in_default>1</show_in_default>
51
+ <show_in_website>1</show_in_website>
52
+ <show_in_store>0</show_in_store>
53
+ <source_model>adminhtml/system_config_source_yesno</source_model>
54
+ </enabled>
55
+ <api_key translate="label">
56
+ <label>API Key</label>
57
+ <frontend_type>text</frontend_type>
58
+ <frontend_model>recapture/adminhtml_system_config_key</frontend_model>
59
+ <sort_order>20</sort_order>
60
+ <show_in_default>1</show_in_default>
61
+ <show_in_website>1</show_in_website>
62
+ <show_in_store>0</show_in_store>
63
+ </api_key>
64
+ </fields>
65
+ </configuration>
66
+ <abandoned_carts translate="label" module="recapture">
67
+ <label>Abandoned Carts Configuration</label>
68
+ <frontend_type>text</frontend_type>
69
+ <sort_order>20</sort_order>
70
+ <show_in_default>1</show_in_default>
71
+ <show_in_website>1</show_in_website>
72
+ <show_in_store>1</show_in_store>
73
+
74
+ <fields>
75
+ <track_email translate="label">
76
+ <label>Enable Pre-submit Email Capturing</label>
77
+ <frontend_type>select</frontend_type>
78
+ <sort_order>10</sort_order>
79
+ <show_in_default>1</show_in_default>
80
+ <show_in_website>1</show_in_website>
81
+ <show_in_store>0</show_in_store>
82
+ <source_model>adminhtml/system_config_source_yesno</source_model>
83
+ <comment>When enabled, this will immediately capture typed email addresses anywhere on your site, without requiring the customer to submit any type of form. Useful on checkouts like One Step Checkout.</comment>
84
+ </track_email>
85
+ <capture_subscriber translate="label">
86
+ <label>Enable Newsletter Subscription Capturing</label>
87
+ <frontend_type>select</frontend_type>
88
+ <sort_order>10</sort_order>
89
+ <show_in_default>1</show_in_default>
90
+ <show_in_website>1</show_in_website>
91
+ <show_in_store>0</show_in_store>
92
+ <source_model>adminhtml/system_config_source_yesno</source_model>
93
+ <comment>When enabled, this will capture any emails that are subscribed to your newsletter.</comment>
94
+ </capture_subscriber>
95
+ <return_landing translate="label">
96
+ <label>Click Through Landing</label>
97
+ <frontend_type>select</frontend_type>
98
+ <sort_order>20</sort_order>
99
+ <show_in_default>1</show_in_default>
100
+ <show_in_website>1</show_in_website>
101
+ <show_in_store>0</show_in_store>
102
+ <source_model>recapture/landing</source_model>
103
+ <comment>What page do you want the customer to land on when they click a link in any abandoned cart emails we send?</comment>
104
+ </return_landing>
105
+ <include_tax_with_products translate="label">
106
+ <label>Include Tax with Product Totals</label>
107
+ <frontend_type>select</frontend_type>
108
+ <sort_order>30</sort_order>
109
+ <show_in_default>1</show_in_default>
110
+ <show_in_website>1</show_in_website>
111
+ <show_in_store>0</show_in_store>
112
+ <source_model>adminhtml/system_config_source_yesno</source_model>
113
+ <comment>Whether or not to include tax in the product total.</comment>
114
+ </include_tax_with_products>
115
+
116
+ <ignore_ips translate="label">
117
+ <label>Bot IP Addresses</label>
118
+ <frontend_type>text</frontend_type>
119
+ <frontend_model>recapture/adminhtml_system_config_key</frontend_model>
120
+ <sort_order>40</sort_order>
121
+ <show_in_default>1</show_in_default>
122
+ <show_in_website>1</show_in_website>
123
+ <show_in_store>0</show_in_store>
124
+ <comment>Activity will not be recorded for these IP addresses. Useful if you have a bot that tests your checkout on a scheduled basis. Multiple IP addresses must be comma separated.</comment>
125
+ </ignore_ips>
126
+ </fields>
127
+ </abandoned_carts>
128
+ </groups>
129
+ </recapture>
130
+ </sections>
131
  </config>
package.xml CHANGED
@@ -1,18 +1,20 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>recapture</name>
4
- <version>1.2.0</version>
5
  <stability>stable</stability>
6
  <license>OSL</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Free analytics dashboard for abandoned carts. Set up automated cart recovery email campaigns in minutes.</summary>
10
  <description>Free analytics dashboard for abandoned carts. Set up automated cart recovery email campaigns in minutes.</description>
11
- <notes>Updated version to 1.2.0</notes>
 
 
12
  <authors><author><name>David Webber</name><user>Recapture</user><email>hello@recapture.io</email></author></authors>
13
- <date>2015-12-28</date>
14
- <time>13:10:21</time>
15
- <contents><target name="magelocal"><dir name="Recapture"><dir name="Connector"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><file name="Authenticate.php" hash="2447363f87e72e922841760980b11942"/><file name="Key.php" hash="edc94e9fa84251d875e4a176f067f3fb"/><file name="Status.php" hash="eb53daf1bacc3d994b79506e6eff0d82"/></dir></dir></dir><dir name="Client"><file name="Page.php" hash="16cc42ba69dae1dc572230fe1fea1f9e"/><file name="Product.php" hash="ea2312b5ef50c49324b1b50cd17cb209"/></dir><file name="Client.php" hash="8780534cb8b8b4b6a88d5aeb4725c2c8"/></dir><dir name="Helper"><file name="Data.php" hash="4100aaba15822e103d63f19e548f9027"/><file name="Transport.php" hash="1219b8da93905496e383b3d358e0c1e2"/></dir><dir name="Model"><file name="Landing.php" hash="b50b47fb13f6bfef79fba6a6efd926c8"/><file name="Observer.php" hash="c1846c885264346b9d994b2a3f6fc0cd"/></dir><dir name="controllers"><file name="CartController.php" hash="fc341ddef155031b8aba22504d85b197"/><file name="EmailController.php" hash="4248cbc84fca095697e1c1185d516ffb"/><file name="IndexController.php" hash="cb6747d719c1080cd8ca485255cbdbf0"/><dir name="Recaptureadmin"><file name="AuthenticateController.php" hash="e1ae384a0b93f155934000205ee393d7"/></dir></dir><dir name="etc"><file name="config.xml" hash="784654592548f0c49dcca43a2108842e"/><file name="system.xml" hash="5cd5494936e54186e7180ddc37b9c56a"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Recapture_Connector.xml" hash="9d4118bc5293b3d732a353a8e402316a"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="recapture.xml" hash="db6abfffb58287c0a9c13ef8ceccbcc8"/></dir><dir name="template"><dir name="recapture"><dir name="client"><file name="page.phtml" hash="b09e356b874e5e3cf5ead473f0215036"/><file name="product.phtml" hash="ea01d5c7bde14881157e65c6571f68a3"/></dir></dir></dir></dir></dir></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>recapture</name>
4
+ <version>1.3.0</version>
5
  <stability>stable</stability>
6
  <license>OSL</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Free analytics dashboard for abandoned carts. Set up automated cart recovery email campaigns in minutes.</summary>
10
  <description>Free analytics dashboard for abandoned carts. Set up automated cart recovery email campaigns in minutes.</description>
11
+ <notes>Updated version to 1.3.0&#xD;
12
+ &#xD;
13
+ Added bot IP exclusion</notes>
14
  <authors><author><name>David Webber</name><user>Recapture</user><email>hello@recapture.io</email></author></authors>
15
+ <date>2016-10-11</date>
16
+ <time>15:00:54</time>
17
+ <contents><target name="magelocal"><dir name="Recapture"><dir name="Connector"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><file name="Authenticate.php" hash="2447363f87e72e922841760980b11942"/><file name="Key.php" hash="edc94e9fa84251d875e4a176f067f3fb"/><file name="Status.php" hash="eb53daf1bacc3d994b79506e6eff0d82"/></dir></dir></dir><dir name="Client"><file name="Page.php" hash="16cc42ba69dae1dc572230fe1fea1f9e"/><file name="Product.php" hash="ea2312b5ef50c49324b1b50cd17cb209"/></dir><file name="Client.php" hash="8780534cb8b8b4b6a88d5aeb4725c2c8"/></dir><dir name="Helper"><file name="Data.php" hash="52df137e4f352014ad85823a0828254c"/><file name="Transport.php" hash="1219b8da93905496e383b3d358e0c1e2"/></dir><dir name="Model"><file name="Landing.php" hash="b50b47fb13f6bfef79fba6a6efd926c8"/><file name="Observer.php" hash="9440fca7368528c485e372145bddcb27"/></dir><dir name="controllers"><file name="CartController.php" hash="fc341ddef155031b8aba22504d85b197"/><file name="EmailController.php" hash="4248cbc84fca095697e1c1185d516ffb"/><file name="IndexController.php" hash="cb6747d719c1080cd8ca485255cbdbf0"/><dir name="Recaptureadmin"><file name="AuthenticateController.php" hash="e1ae384a0b93f155934000205ee393d7"/></dir></dir><dir name="etc"><file name="config.xml" hash="536b6426437864b23aa83250e8da0a6e"/><file name="system.xml" hash="81c8d6cf5e2cb9f1d65aeed73dc6a202"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Recapture_Connector.xml" hash="9d4118bc5293b3d732a353a8e402316a"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="recapture.xml" hash="db6abfffb58287c0a9c13ef8ceccbcc8"/></dir><dir name="template"><dir name="recapture"><dir name="client"><file name="page.phtml" hash="b09e356b874e5e3cf5ead473f0215036"/><file name="product.phtml" hash="ea01d5c7bde14881157e65c6571f68a3"/></dir></dir></dir></dir></dir></dir></target></contents>
18
  <compatible/>
19
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
20
  </package>