Version Notes
- Fix encoding issue with french translations
- Add more translation
Download this release
Release Info
Developer | Digital Pianism |
Extension | DigitalPianism_Abandonedcarts |
Version | 0.3.2 |
Comparing to | |
See all releases |
Code changes from version 0.3.1 to 0.3.2
- app/code/community/DigitalPianism/Abandonedcarts/Model/Observer.php +54 -51
- app/code/community/DigitalPianism/Abandonedcarts/etc/config.xml +1 -1
- app/code/community/DigitalPianism/Abandonedcarts/etc/system.xml +1 -1
- app/locale/en_US/DigitalPianism_Abandonedcarts.csv +2 -1
- app/locale/fr_FR/DigitalPianism_Abandonedcarts.csv +14 -13
- package.xml +6 -5
app/code/community/DigitalPianism/Abandonedcarts/Model/Observer.php
CHANGED
@@ -17,7 +17,7 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
17 |
$store = Mage_Core_Model_App::ADMIN_STORE_ID;
|
18 |
$timezone = Mage::app()->getStore($store)->getConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_TIMEZONE);
|
19 |
date_default_timezone_set($timezone);
|
20 |
-
|
21 |
// Current date
|
22 |
$currentdate = date("Ymd");
|
23 |
|
@@ -26,7 +26,7 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
26 |
$year = (int)substr($currentdate,0,4);
|
27 |
|
28 |
$date = array('year' => $year,'month' => $month,'day' => $day,'hour' => 23,'minute' => 59,'second' => 59);
|
29 |
-
|
30 |
$today = new Zend_Date($date);
|
31 |
$today->setTimeZone("UTC");
|
32 |
|
@@ -73,14 +73,14 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
73 |
// Test if the customer is already in the array
|
74 |
if (!array_key_exists($args['row']['customer_email'], $this->_recipients))
|
75 |
{
|
76 |
-
// Create an array of variables to assign to template
|
77 |
-
$emailTemplateVariables = array();
|
78 |
-
|
79 |
// Array that contains the data which will be used inside the template
|
80 |
-
$emailTemplateVariables['fullname'] = $args['row']['customer_firstname'].' '.$args['row']['customer_lastname'];
|
81 |
$emailTemplateVariables['firstname'] = $args['row']['customer_firstname'];
|
82 |
$emailTemplateVariables['productname'] = $args['row']['product_name'];
|
83 |
-
|
84 |
// Assign the values to the array of recipients
|
85 |
$this->_recipients[$args['row']['customer_email']]['cartId'] = $args['row']['cart_id'];
|
86 |
|
@@ -95,7 +95,7 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
95 |
|
96 |
// Add product image
|
97 |
$emailTemplateVariables['productimage'] = (string)Mage::helper('catalog/image')->init($_productCollection->getFirstItem(), 'image');
|
98 |
-
|
99 |
$emailTemplateVariables['extraproductcount'] = 0;
|
100 |
}
|
101 |
else
|
@@ -127,36 +127,36 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
127 |
$fromDate = $this->_getToday();
|
128 |
}
|
129 |
else $fromDate = $args['row']['product_special_from_date'];
|
130 |
-
|
131 |
// Do the same for the special to date
|
132 |
if (!array_key_exists('product_special_to_date',$args['row']) || !$args['row']['product_special_to_date'])
|
133 |
{
|
134 |
$toDate = $this->_getToday();
|
135 |
}
|
136 |
else $toDate = $args['row']['product_special_to_date'];
|
137 |
-
|
138 |
// We need to ensure that the price in cart is higher than the new special price
|
139 |
// As well as the date comparison in case the sale is over or hasn't started
|
140 |
-
if ($args['row']['product_price_in_cart'] > 0.00
|
141 |
-
&& $args['row']['product_special_price'] > 0.00
|
142 |
&& ($args['row']['product_price_in_cart'] > $args['row']['product_special_price'])
|
143 |
&& ($fromDate <= $this->_getToday())
|
144 |
&& ($toDate >= $this->_getToday()))
|
145 |
{
|
146 |
-
|
147 |
// Test if the customer is already in the array
|
148 |
if (!array_key_exists($args['row']['customer_email'], $this->_saleRecipients))
|
149 |
{
|
150 |
-
// Create an array of variables to assign to template
|
151 |
-
$emailTemplateVariables = array();
|
152 |
-
|
153 |
// Array that contains the data which will be used inside the template
|
154 |
-
$emailTemplateVariables['fullname'] = $args['row']['customer_firstname'].' '.$args['row']['customer_lastname'];
|
155 |
$emailTemplateVariables['firstname'] = $args['row']['customer_firstname'];
|
156 |
-
$emailTemplateVariables['productname'] = $args['row']['product_name'];
|
157 |
-
$emailTemplateVariables['cartprice'] = number_format($args['row']['product_price_in_cart'],2);
|
158 |
$emailTemplateVariables['specialprice'] = number_format($args['row']['product_special_price'],2);
|
159 |
-
|
160 |
// Assign the values to the array of recipients
|
161 |
$this->_saleRecipients[$args['row']['customer_email']]['cartId'] = $args['row']['cart_id'];
|
162 |
|
@@ -192,7 +192,7 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
192 |
}
|
193 |
$emailTemplateVariables['extraproductcount'] += 1;
|
194 |
}
|
195 |
-
|
196 |
// Add currency codes to prices
|
197 |
$emailTemplateVariables['cartprice'] = Mage::helper('core')->currency($emailTemplateVariables['cartprice'], true, false);
|
198 |
$emailTemplateVariables['specialprice'] = Mage::helper('core')->currency($emailTemplateVariables['specialprice'], true, false);
|
@@ -200,7 +200,7 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
200 |
{
|
201 |
$emailTemplateVariables['discount'] = Mage::helper('core')->currency($emailTemplateVariables['discount'], true, false);
|
202 |
}
|
203 |
-
|
204 |
// Assign the array of template variables
|
205 |
$this->_saleRecipients[$args['row']['customer_email']]['emailTemplateVariables'] = $emailTemplateVariables;
|
206 |
}
|
@@ -213,14 +213,14 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
213 |
protected function _sendSaleEmails($dryrun,$testemail)
|
214 |
{
|
215 |
try
|
216 |
-
{
|
217 |
// Get the transactional email template
|
218 |
$templateId = Mage::getStoreConfig('abandonedcartsconfig/options/email_template_sale');
|
219 |
// Get the sender
|
220 |
$sender = array();
|
221 |
$sender['email'] = Mage::getStoreConfig('abandonedcartsconfig/options/email');
|
222 |
$sender['name'] = Mage::getStoreConfig('abandonedcartsconfig/options/name');
|
223 |
-
|
224 |
// Send the emails via a loop
|
225 |
foreach ($this->_getSaleRecipients() as $email => $recipient)
|
226 |
{
|
@@ -248,7 +248,7 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
248 |
else
|
249 |
{
|
250 |
Mage::helper('abandonedcarts')->log(__METHOD__ . "sendAbandonedCartsSaleEmail: " . $email);
|
251 |
-
|
252 |
// Send the email
|
253 |
Mage::getModel('core/email_template')
|
254 |
->sendTransactional(
|
@@ -259,13 +259,13 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
259 |
$recipient['emailTemplateVariables'],
|
260 |
null);
|
261 |
}
|
262 |
-
|
263 |
// Load the quote
|
264 |
$quote = Mage::getModel('sales/quote')->load($recipient['cartId']);
|
265 |
|
266 |
// We change the notification attribute
|
267 |
$quote->setAbandonedSaleNotified(1);
|
268 |
-
|
269 |
// Save only if dryrun is false or if the test email is set and found
|
270 |
if (!$dryrun || (isset($testemail) && $email == $testemail))
|
271 |
{
|
@@ -286,14 +286,14 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
286 |
protected function _sendEmails($dryrun,$testemail)
|
287 |
{
|
288 |
try
|
289 |
-
{
|
290 |
// Get the transactional email template
|
291 |
$templateId = Mage::getStoreConfig('abandonedcartsconfig/options/email_template');
|
292 |
// Get the sender
|
293 |
$sender = array();
|
294 |
$sender['email'] = Mage::getStoreConfig('abandonedcartsconfig/options/email');
|
295 |
$sender['name'] = Mage::getStoreConfig('abandonedcartsconfig/options/name');
|
296 |
-
|
297 |
// Send the emails via a loop
|
298 |
foreach ($this->_getRecipients() as $email => $recipient)
|
299 |
{
|
@@ -357,7 +357,7 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
357 |
* @param boolean $dryrun if dryrun is set to true, it won't send emails and won't alter quotes
|
358 |
* @param string $testemail email to test
|
359 |
*/
|
360 |
-
public function sendAbandonedCartsSaleEmail($dryrun = false, $testemail = null)
|
361 |
{
|
362 |
try
|
363 |
{
|
@@ -369,7 +369,7 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
369 |
if (Mage::helper('abandonedcarts')->isSaleEnabled())
|
370 |
{
|
371 |
$this->_setToday();
|
372 |
-
|
373 |
// Get the attribute id for the status attribute
|
374 |
$eavAttribute = Mage::getModel('eav/entity_attribute');
|
375 |
$statusId = $eavAttribute->getIdByCode('catalog_product', 'status');
|
@@ -378,7 +378,7 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
378 |
$spriceId = $eavAttribute->getIdByCode('catalog_product', 'special_price');
|
379 |
$spfromId = $eavAttribute->getIdByCode('catalog_product', 'special_from_date');
|
380 |
$sptoId = $eavAttribute->getIdByCode('catalog_product', 'special_to_date');
|
381 |
-
|
382 |
// Loop through the stores
|
383 |
foreach (Mage::app()->getWebsites() as $website) {
|
384 |
// Get the website id
|
@@ -386,22 +386,22 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
386 |
foreach ($website->getGroups() as $group) {
|
387 |
$stores = $group->getStores();
|
388 |
foreach ($stores as $store) {
|
389 |
-
|
390 |
// Get the store id
|
391 |
$storeId = $store->getStoreId();
|
392 |
-
|
393 |
// Init the store to be able to load the quote and the collections properly
|
394 |
Mage::app()->init($storeId,'store');
|
395 |
-
|
396 |
// Get the product collection
|
397 |
$collection = Mage::getResourceModel('catalog/product_collection')->setStore($storeId);
|
398 |
-
|
399 |
// Database TableNams
|
400 |
$eavEntityType = Mage::getSingleton("core/resource")->getTableName('eav_entity_type');
|
401 |
$eavAttribute = Mage::getSingleton("core/resource")->getTableName('eav_attribute');
|
402 |
-
|
403 |
// If flat catalog is enabled
|
404 |
-
if (Mage::helper('catalog/product_flat')->isEnabled())
|
405 |
{
|
406 |
// First collection: carts with products that became on sale
|
407 |
// Join the collection with the required tables
|
@@ -512,13 +512,13 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
512 |
null)
|
513 |
->order('quote_table.updated_at DESC');
|
514 |
}
|
515 |
-
|
516 |
//$collection->printlogquery(true,true);
|
517 |
$collection->load();
|
518 |
-
|
519 |
// Skip the rest of the code if the collection is empty
|
520 |
if ($collection->getSize() == 0) continue;
|
521 |
-
|
522 |
// Call iterator walk method with collection query string and callback method as parameters
|
523 |
// Has to be used to handle massive collection instead of foreach
|
524 |
Mage::getSingleton('core/resource_iterator')->walk($collection->getSelect(), array(array($this, 'generateSaleRecipients')));
|
@@ -553,11 +553,11 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
553 |
{
|
554 |
if (Mage::helper('abandonedcarts')->isEnabled())
|
555 |
{
|
556 |
-
// Date handling
|
557 |
$store = Mage_Core_Model_App::ADMIN_STORE_ID;
|
558 |
$timezone = Mage::app()->getStore($store)->getConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_TIMEZONE);
|
559 |
date_default_timezone_set($timezone);
|
560 |
-
|
561 |
// If the nodate parameter is set to false
|
562 |
if (!$nodate)
|
563 |
{
|
@@ -570,13 +570,13 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
570 |
// We create a date in the future to handle all abandoned carts
|
571 |
$delay = date('Y-m-d H:i:s', strtotime("+7 day"));
|
572 |
}
|
573 |
-
|
574 |
// Get the attribute id for several attributes
|
575 |
$eavAttribute = Mage::getModel('eav/entity_attribute');
|
576 |
$statusId = $eavAttribute->getIdByCode('catalog_product', 'status');
|
577 |
$nameId = $eavAttribute->getIdByCode('catalog_product', 'name');
|
578 |
$priceId = $eavAttribute->getIdByCode('catalog_product', 'price');
|
579 |
-
|
580 |
// Loop through the stores
|
581 |
foreach (Mage::app()->getWebsites() as $website) {
|
582 |
// Get the website id
|
@@ -584,17 +584,17 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
584 |
foreach ($website->getGroups() as $group) {
|
585 |
$stores = $group->getStores();
|
586 |
foreach ($stores as $store) {
|
587 |
-
|
588 |
// Get the store id
|
589 |
$storeId = $store->getStoreId();
|
590 |
// Init the store to be able to load the quote and the collections properly
|
591 |
Mage::app()->init($storeId,'store');
|
592 |
-
|
593 |
// Get the product collection
|
594 |
$collection = Mage::getResourceModel('catalog/product_collection')->setStore($storeId);
|
595 |
-
|
596 |
// If flat catalog is enabled
|
597 |
-
if (Mage::helper('catalog/product_flat')->isEnabled())
|
598 |
{
|
599 |
// First collection: carts with products that became on sale
|
600 |
// Join the collection with the required tables
|
@@ -682,10 +682,13 @@ class DigitalPianism_Abandonedcarts_Model_Observer extends Mage_Core_Model_Abstr
|
|
682 |
null)
|
683 |
->order('quote_table.updated_at DESC');
|
684 |
}
|
685 |
-
|
686 |
//$collection->printlogquery(true,true);
|
687 |
$collection->load();
|
688 |
-
|
|
|
|
|
|
|
689 |
// Call iterator walk method with collection query string and callback method as parameters
|
690 |
// Has to be used to handle massive collection instead of foreach
|
691 |
Mage::getSingleton('core/resource_iterator')->walk($collection->getSelect(), array(array($this, 'generateRecipients')));
|
17 |
$store = Mage_Core_Model_App::ADMIN_STORE_ID;
|
18 |
$timezone = Mage::app()->getStore($store)->getConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_TIMEZONE);
|
19 |
date_default_timezone_set($timezone);
|
20 |
+
|
21 |
// Current date
|
22 |
$currentdate = date("Ymd");
|
23 |
|
26 |
$year = (int)substr($currentdate,0,4);
|
27 |
|
28 |
$date = array('year' => $year,'month' => $month,'day' => $day,'hour' => 23,'minute' => 59,'second' => 59);
|
29 |
+
|
30 |
$today = new Zend_Date($date);
|
31 |
$today->setTimeZone("UTC");
|
32 |
|
73 |
// Test if the customer is already in the array
|
74 |
if (!array_key_exists($args['row']['customer_email'], $this->_recipients))
|
75 |
{
|
76 |
+
// Create an array of variables to assign to template
|
77 |
+
$emailTemplateVariables = array();
|
78 |
+
|
79 |
// Array that contains the data which will be used inside the template
|
80 |
+
$emailTemplateVariables['fullname'] = $args['row']['customer_firstname'].' '.$args['row']['customer_lastname'];
|
81 |
$emailTemplateVariables['firstname'] = $args['row']['customer_firstname'];
|
82 |
$emailTemplateVariables['productname'] = $args['row']['product_name'];
|
83 |
+
|
84 |
// Assign the values to the array of recipients
|
85 |
$this->_recipients[$args['row']['customer_email']]['cartId'] = $args['row']['cart_id'];
|
86 |
|
95 |
|
96 |
// Add product image
|
97 |
$emailTemplateVariables['productimage'] = (string)Mage::helper('catalog/image')->init($_productCollection->getFirstItem(), 'image');
|
98 |
+
|
99 |
$emailTemplateVariables['extraproductcount'] = 0;
|
100 |
}
|
101 |
else
|
127 |
$fromDate = $this->_getToday();
|
128 |
}
|
129 |
else $fromDate = $args['row']['product_special_from_date'];
|
130 |
+
|
131 |
// Do the same for the special to date
|
132 |
if (!array_key_exists('product_special_to_date',$args['row']) || !$args['row']['product_special_to_date'])
|
133 |
{
|
134 |
$toDate = $this->_getToday();
|
135 |
}
|
136 |
else $toDate = $args['row']['product_special_to_date'];
|
137 |
+
|
138 |
// We need to ensure that the price in cart is higher than the new special price
|
139 |
// As well as the date comparison in case the sale is over or hasn't started
|
140 |
+
if ($args['row']['product_price_in_cart'] > 0.00
|
141 |
+
&& $args['row']['product_special_price'] > 0.00
|
142 |
&& ($args['row']['product_price_in_cart'] > $args['row']['product_special_price'])
|
143 |
&& ($fromDate <= $this->_getToday())
|
144 |
&& ($toDate >= $this->_getToday()))
|
145 |
{
|
146 |
+
|
147 |
// Test if the customer is already in the array
|
148 |
if (!array_key_exists($args['row']['customer_email'], $this->_saleRecipients))
|
149 |
{
|
150 |
+
// Create an array of variables to assign to template
|
151 |
+
$emailTemplateVariables = array();
|
152 |
+
|
153 |
// Array that contains the data which will be used inside the template
|
154 |
+
$emailTemplateVariables['fullname'] = $args['row']['customer_firstname'].' '.$args['row']['customer_lastname'];
|
155 |
$emailTemplateVariables['firstname'] = $args['row']['customer_firstname'];
|
156 |
+
$emailTemplateVariables['productname'] = $args['row']['product_name'];
|
157 |
+
$emailTemplateVariables['cartprice'] = number_format($args['row']['product_price_in_cart'],2);
|
158 |
$emailTemplateVariables['specialprice'] = number_format($args['row']['product_special_price'],2);
|
159 |
+
|
160 |
// Assign the values to the array of recipients
|
161 |
$this->_saleRecipients[$args['row']['customer_email']]['cartId'] = $args['row']['cart_id'];
|
162 |
|
192 |
}
|
193 |
$emailTemplateVariables['extraproductcount'] += 1;
|
194 |
}
|
195 |
+
|
196 |
// Add currency codes to prices
|
197 |
$emailTemplateVariables['cartprice'] = Mage::helper('core')->currency($emailTemplateVariables['cartprice'], true, false);
|
198 |
$emailTemplateVariables['specialprice'] = Mage::helper('core')->currency($emailTemplateVariables['specialprice'], true, false);
|
200 |
{
|
201 |
$emailTemplateVariables['discount'] = Mage::helper('core')->currency($emailTemplateVariables['discount'], true, false);
|
202 |
}
|
203 |
+
|
204 |
// Assign the array of template variables
|
205 |
$this->_saleRecipients[$args['row']['customer_email']]['emailTemplateVariables'] = $emailTemplateVariables;
|
206 |
}
|
213 |
protected function _sendSaleEmails($dryrun,$testemail)
|
214 |
{
|
215 |
try
|
216 |
+
{
|
217 |
// Get the transactional email template
|
218 |
$templateId = Mage::getStoreConfig('abandonedcartsconfig/options/email_template_sale');
|
219 |
// Get the sender
|
220 |
$sender = array();
|
221 |
$sender['email'] = Mage::getStoreConfig('abandonedcartsconfig/options/email');
|
222 |
$sender['name'] = Mage::getStoreConfig('abandonedcartsconfig/options/name');
|
223 |
+
|
224 |
// Send the emails via a loop
|
225 |
foreach ($this->_getSaleRecipients() as $email => $recipient)
|
226 |
{
|
248 |
else
|
249 |
{
|
250 |
Mage::helper('abandonedcarts')->log(__METHOD__ . "sendAbandonedCartsSaleEmail: " . $email);
|
251 |
+
|
252 |
// Send the email
|
253 |
Mage::getModel('core/email_template')
|
254 |
->sendTransactional(
|
259 |
$recipient['emailTemplateVariables'],
|
260 |
null);
|
261 |
}
|
262 |
+
|
263 |
// Load the quote
|
264 |
$quote = Mage::getModel('sales/quote')->load($recipient['cartId']);
|
265 |
|
266 |
// We change the notification attribute
|
267 |
$quote->setAbandonedSaleNotified(1);
|
268 |
+
|
269 |
// Save only if dryrun is false or if the test email is set and found
|
270 |
if (!$dryrun || (isset($testemail) && $email == $testemail))
|
271 |
{
|
286 |
protected function _sendEmails($dryrun,$testemail)
|
287 |
{
|
288 |
try
|
289 |
+
{
|
290 |
// Get the transactional email template
|
291 |
$templateId = Mage::getStoreConfig('abandonedcartsconfig/options/email_template');
|
292 |
// Get the sender
|
293 |
$sender = array();
|
294 |
$sender['email'] = Mage::getStoreConfig('abandonedcartsconfig/options/email');
|
295 |
$sender['name'] = Mage::getStoreConfig('abandonedcartsconfig/options/name');
|
296 |
+
|
297 |
// Send the emails via a loop
|
298 |
foreach ($this->_getRecipients() as $email => $recipient)
|
299 |
{
|
357 |
* @param boolean $dryrun if dryrun is set to true, it won't send emails and won't alter quotes
|
358 |
* @param string $testemail email to test
|
359 |
*/
|
360 |
+
public function sendAbandonedCartsSaleEmail($dryrun = false, $testemail = null)
|
361 |
{
|
362 |
try
|
363 |
{
|
369 |
if (Mage::helper('abandonedcarts')->isSaleEnabled())
|
370 |
{
|
371 |
$this->_setToday();
|
372 |
+
|
373 |
// Get the attribute id for the status attribute
|
374 |
$eavAttribute = Mage::getModel('eav/entity_attribute');
|
375 |
$statusId = $eavAttribute->getIdByCode('catalog_product', 'status');
|
378 |
$spriceId = $eavAttribute->getIdByCode('catalog_product', 'special_price');
|
379 |
$spfromId = $eavAttribute->getIdByCode('catalog_product', 'special_from_date');
|
380 |
$sptoId = $eavAttribute->getIdByCode('catalog_product', 'special_to_date');
|
381 |
+
|
382 |
// Loop through the stores
|
383 |
foreach (Mage::app()->getWebsites() as $website) {
|
384 |
// Get the website id
|
386 |
foreach ($website->getGroups() as $group) {
|
387 |
$stores = $group->getStores();
|
388 |
foreach ($stores as $store) {
|
389 |
+
|
390 |
// Get the store id
|
391 |
$storeId = $store->getStoreId();
|
392 |
+
|
393 |
// Init the store to be able to load the quote and the collections properly
|
394 |
Mage::app()->init($storeId,'store');
|
395 |
+
|
396 |
// Get the product collection
|
397 |
$collection = Mage::getResourceModel('catalog/product_collection')->setStore($storeId);
|
398 |
+
|
399 |
// Database TableNams
|
400 |
$eavEntityType = Mage::getSingleton("core/resource")->getTableName('eav_entity_type');
|
401 |
$eavAttribute = Mage::getSingleton("core/resource")->getTableName('eav_attribute');
|
402 |
+
|
403 |
// If flat catalog is enabled
|
404 |
+
if (Mage::helper('catalog/product_flat')->isEnabled())
|
405 |
{
|
406 |
// First collection: carts with products that became on sale
|
407 |
// Join the collection with the required tables
|
512 |
null)
|
513 |
->order('quote_table.updated_at DESC');
|
514 |
}
|
515 |
+
|
516 |
//$collection->printlogquery(true,true);
|
517 |
$collection->load();
|
518 |
+
|
519 |
// Skip the rest of the code if the collection is empty
|
520 |
if ($collection->getSize() == 0) continue;
|
521 |
+
|
522 |
// Call iterator walk method with collection query string and callback method as parameters
|
523 |
// Has to be used to handle massive collection instead of foreach
|
524 |
Mage::getSingleton('core/resource_iterator')->walk($collection->getSelect(), array(array($this, 'generateSaleRecipients')));
|
553 |
{
|
554 |
if (Mage::helper('abandonedcarts')->isEnabled())
|
555 |
{
|
556 |
+
// Date handling
|
557 |
$store = Mage_Core_Model_App::ADMIN_STORE_ID;
|
558 |
$timezone = Mage::app()->getStore($store)->getConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_TIMEZONE);
|
559 |
date_default_timezone_set($timezone);
|
560 |
+
|
561 |
// If the nodate parameter is set to false
|
562 |
if (!$nodate)
|
563 |
{
|
570 |
// We create a date in the future to handle all abandoned carts
|
571 |
$delay = date('Y-m-d H:i:s', strtotime("+7 day"));
|
572 |
}
|
573 |
+
|
574 |
// Get the attribute id for several attributes
|
575 |
$eavAttribute = Mage::getModel('eav/entity_attribute');
|
576 |
$statusId = $eavAttribute->getIdByCode('catalog_product', 'status');
|
577 |
$nameId = $eavAttribute->getIdByCode('catalog_product', 'name');
|
578 |
$priceId = $eavAttribute->getIdByCode('catalog_product', 'price');
|
579 |
+
|
580 |
// Loop through the stores
|
581 |
foreach (Mage::app()->getWebsites() as $website) {
|
582 |
// Get the website id
|
584 |
foreach ($website->getGroups() as $group) {
|
585 |
$stores = $group->getStores();
|
586 |
foreach ($stores as $store) {
|
587 |
+
|
588 |
// Get the store id
|
589 |
$storeId = $store->getStoreId();
|
590 |
// Init the store to be able to load the quote and the collections properly
|
591 |
Mage::app()->init($storeId,'store');
|
592 |
+
|
593 |
// Get the product collection
|
594 |
$collection = Mage::getResourceModel('catalog/product_collection')->setStore($storeId);
|
595 |
+
|
596 |
// If flat catalog is enabled
|
597 |
+
if (Mage::helper('catalog/product_flat')->isEnabled())
|
598 |
{
|
599 |
// First collection: carts with products that became on sale
|
600 |
// Join the collection with the required tables
|
682 |
null)
|
683 |
->order('quote_table.updated_at DESC');
|
684 |
}
|
685 |
+
|
686 |
//$collection->printlogquery(true,true);
|
687 |
$collection->load();
|
688 |
+
|
689 |
+
// Skip the rest of the code if the collection is empty
|
690 |
+
if ($collection->getSize() == 0) continue;
|
691 |
+
|
692 |
// Call iterator walk method with collection query string and callback method as parameters
|
693 |
// Has to be used to handle massive collection instead of foreach
|
694 |
Mage::getSingleton('core/resource_iterator')->walk($collection->getSelect(), array(array($this, 'generateRecipients')));
|
app/code/community/DigitalPianism/Abandonedcarts/etc/config.xml
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
|
5 |
<modules>
|
6 |
<DigitalPianism_Abandonedcarts>
|
7 |
-
<version>0.3.
|
8 |
</DigitalPianism_Abandonedcarts>
|
9 |
</modules>
|
10 |
|
4 |
|
5 |
<modules>
|
6 |
<DigitalPianism_Abandonedcarts>
|
7 |
+
<version>0.3.2</version>
|
8 |
</DigitalPianism_Abandonedcarts>
|
9 |
</modules>
|
10 |
|
app/code/community/DigitalPianism/Abandonedcarts/etc/system.xml
CHANGED
@@ -89,7 +89,7 @@
|
|
89 |
<show_in_store>1</show_in_store>
|
90 |
</enable_sale>
|
91 |
<email_template_sale translate="label">
|
92 |
-
<label>Email Template for
|
93 |
<frontend_type>select</frontend_type>
|
94 |
<source_model>adminhtml/system_config_source_email_template</source_model>
|
95 |
<sort_order>70</sort_order>
|
89 |
<show_in_store>1</show_in_store>
|
90 |
</enable_sale>
|
91 |
<email_template_sale translate="label">
|
92 |
+
<label>Email Template for Sale Products</label>
|
93 |
<frontend_type>select</frontend_type>
|
94 |
<source_model>adminhtml/system_config_source_email_template</source_model>
|
95 |
<sort_order>70</sort_order>
|
app/locale/en_US/DigitalPianism_Abandonedcarts.csv
CHANGED
@@ -13,4 +13,5 @@ Sender Email,Sender Email
|
|
13 |
Email Template for Unaltered Abandoned Carts,Email Template for Unaltered Abandoned Carts
|
14 |
Send Abandoned Cart Email After,Send Abandoned Cart Email After
|
15 |
(days). NB: this only affects unaltered abandoned carts. If products go on sale, the email below is sent on the same day.,(days). NB: this only affects unaltered abandoned carts. If products go on sale, the email below is sent on the same day.
|
16 |
-
Email Template for Sale Products,Email Template for Sale Products
|
|
13 |
Email Template for Unaltered Abandoned Carts,Email Template for Unaltered Abandoned Carts
|
14 |
Send Abandoned Cart Email After,Send Abandoned Cart Email After
|
15 |
(days). NB: this only affects unaltered abandoned carts. If products go on sale, the email below is sent on the same day.,(days). NB: this only affects unaltered abandoned carts. If products go on sale, the email below is sent on the same day.
|
16 |
+
Email Template for Sale Products,Email Template for Sale Products
|
17 |
+
Customer Groups Restriction,Customer Groups Restriction
|
app/locale/fr_FR/DigitalPianism_Abandonedcarts.csv
CHANGED
@@ -1,16 +1,17 @@
|
|
1 |
-
Abandoned Carts Email,Email des paniers abandonn
|
2 |
-
Abandoned Carts Emails,Emails des paniers abandonn
|
3 |
-
Enable Abandoned Carts Notification,Activer les notifications de paniers abandonn
|
4 |
-
Enable Sale Abandoned Carts Notification,Activer les notifications de paniers abandonn
|
5 |
Dry Run,Test
|
6 |
-
Setting this parameter to Yes will log all the email addresses supposed to receive a notification into the var/log/digitalpianism_abandonedcarts.log file and will not send the real email notification,Mettre la valeur
|
7 |
Test Email,Email de test
|
8 |
-
With dry run set to yes, this email is used to filter the emails supposed to be sent and only send a notification email to the customer with this email address,Avec Test
|
9 |
Send Notifications Now,Envoyer les notification maintenant
|
10 |
-
Cron Schedule,R
|
11 |
-
Sender Name,Nom de l'exp
|
12 |
-
Sender Email,Email de l'exp
|
13 |
-
Email Template for Unaltered Abandoned Carts,Gabarit d'email pour les paniers abandonn
|
14 |
-
Send Abandoned Cart Email After,Envoyer l'email de notification apr
|
15 |
-
(days). NB: this only affects unaltered abandoned carts. If products go on sale, the email below is sent on the same day.,(jours). NB: cela affecte seulement les paniers abandonn
|
16 |
-
Email Template for Sale Products,Gabarit d'email pour les produits en promo
|
|
1 |
+
Abandoned Carts Email,Email des paniers abandonnés
|
2 |
+
Abandoned Carts Emails,Emails des paniers abandonnés
|
3 |
+
Enable Abandoned Carts Notification,Activer les notifications de paniers abandonnés
|
4 |
+
Enable Sale Abandoned Carts Notification,Activer les notifications de paniers abandonnés en promo
|
5 |
Dry Run,Test
|
6 |
+
Setting this parameter to Yes will log all the email addresses supposed to receive a notification into the var/log/digitalpianism_abandonedcarts.log file and will not send the real email notification,Mettre la valeur à Oui enregistrera toutes les adresses emails supposées recevoir une notification dans le fichier var/log/digitalpianism_abandonedcarts.log et n'enverra pas les emails
|
7 |
Test Email,Email de test
|
8 |
+
With dry run set to yes, this email is used to filter the emails supposed to be sent and only send a notification email to the customer with this email address,Avec Test à Oui, cette adresse email sera utilisée pour filter les emails supposés être envoyé et seulement envoyé l'email de notification au client avec cette adresse
|
9 |
Send Notifications Now,Envoyer les notification maintenant
|
10 |
+
Cron Schedule,Réglage du cron
|
11 |
+
Sender Name,Nom de l'expéditeur
|
12 |
+
Sender Email,Email de l'expéditeur
|
13 |
+
Email Template for Unaltered Abandoned Carts,Gabarit d'email pour les paniers abandonnés non modifiés
|
14 |
+
Send Abandoned Cart Email After,Envoyer l'email de notification après
|
15 |
+
(days). NB: this only affects unaltered abandoned carts. If products go on sale, the email below is sent on the same day.,(jours). NB: cela affecte seulement les paniers abandonnés non modifiés. Si un des produits passent en promotion, l'email ci dessous sera envoyé le m�me jour.
|
16 |
+
Email Template for Sale Products,Gabarit d'email pour les produits en promo
|
17 |
+
Customer Groups Restriction,Restriction de groupes clients
|
package.xml
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>DigitalPianism_Abandonedcarts</name>
|
4 |
-
<version>0.3.
|
5 |
<stability>stable</stability>
|
6 |
<license uri="http://opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
|
7 |
<channel>community</channel>
|
@@ -95,11 +95,12 @@ Save the configuration.
|
|
95 |

|
96 |
<p>To manually trigger the notification system, please access System &gt; Configuration &gt; Digital Pianism &gt; Abandoned carts email and click on the "Send" button</p>
|
97 |
<p>Please note that this functionality will send abandoned carts notification regardless the delay you provided, all possible abandoned carts emails will be sent.</p></description>
|
98 |
-
<notes>- Fix
|
|
|
99 |
<authors><author><name>Digital Pianism</name><user>digitalpianism</user><email>contact@digital-pianism.com</email></author></authors>
|
100 |
-
<date>2015-11-
|
101 |
-
<time>15:
|
102 |
-
<contents><target name="magecommunity"><dir name="DigitalPianism"><dir name="Abandonedcarts"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Form"><file name="Button.php" hash="1c8d9cad5c54bcc28c0760e72406b5e3"/></dir></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="5148fe5929e61f4c8385c6c5be0b89f3"/></dir><dir name="Model"><file name="Observer.php" hash="
|
103 |
<compatible/>
|
104 |
<dependencies><required><php><min>4.1.0</min><max>6.0.0</max></php></required></dependencies>
|
105 |
</package>
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>DigitalPianism_Abandonedcarts</name>
|
4 |
+
<version>0.3.2</version>
|
5 |
<stability>stable</stability>
|
6 |
<license uri="http://opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
|
7 |
<channel>community</channel>
|
95 |

|
96 |
<p>To manually trigger the notification system, please access System &gt; Configuration &gt; Digital Pianism &gt; Abandoned carts email and click on the "Send" button</p>
|
97 |
<p>Please note that this functionality will send abandoned carts notification regardless the delay you provided, all possible abandoned carts emails will be sent.</p></description>
|
98 |
+
<notes>- Fix encoding issue with french translations
|
99 |
+
- Add more translation</notes>
|
100 |
<authors><author><name>Digital Pianism</name><user>digitalpianism</user><email>contact@digital-pianism.com</email></author></authors>
|
101 |
+
<date>2015-11-24</date>
|
102 |
+
<time>15:15:20</time>
|
103 |
+
<contents><target name="magecommunity"><dir name="DigitalPianism"><dir name="Abandonedcarts"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Form"><file name="Button.php" hash="1c8d9cad5c54bcc28c0760e72406b5e3"/></dir></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="5148fe5929e61f4c8385c6c5be0b89f3"/></dir><dir name="Model"><file name="Observer.php" hash="86f9448aea6059484cb8aeb9e40af421"/><dir name="Sales"><dir name="Resource"><file name="Quote.php" hash="3b2f9f24a74a6ea3b6851d64bd6ae5ba"/></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="AbandonedcartsController.php" hash="c26ae0925cc1ca148f5e3277702842e2"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="8ddca513c0ed7e034c476f3e026ceda8"/><file name="config.xml" hash="81cd3beba01719cc31f571e29277e4e6"/><file name="system.xml" hash="07f261c1f35321317da8f09f75a37317"/></dir><dir name="sql"><dir name="abandonedcarts_setup"><file name="install-0.0.1.php" hash="851338e4a710b5d94fead688b065f4b5"/><file name="upgrade-0.0.1-0.0.2.php" hash="0227c009e49b97bcf3f34f84c49f0927"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="DigitalPianism_Abandonedcarts.xml" hash="8a7657855486c68d548db4ba48e083d2"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="digitalpianism"><dir name="abandonedcarts"><dir name="system"><dir name="config"><file name="button.phtml" hash="8f7e673ea52cd81b616cac01b1022990"/></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="magelocale"><dir name="en_US"><dir name="template"><dir name="email"><dir name="digitalpianism"><dir name="abandonedcarts"><file name="sales_abandonedcarts.html" hash="f8a5ec3af09730f06ade1fd18fa321e9"/><file name="sales_abandonedcarts_sale.html" hash="22bb7a1e95e336948a43f282e7e58806"/></dir></dir></dir></dir><file name="DigitalPianism_Abandonedcarts.csv" hash="b782bff95dba8b860cd773a674aac6c9"/></dir><dir name="fr_FR"><dir name="template"><dir name="email"><dir name="digitalpianism"><dir name="abandonedcarts"><file name="sales_abandonedcarts.html" hash="5340ea06fbf9d2213ea2f09e7425181b"/><file name="sales_abandonedcarts_sale.html" hash="22592c5467a554ab80195218bec5b6b0"/></dir></dir></dir></dir><file name="DigitalPianism_Abandonedcarts.csv" hash="0f5271e2ad1d6b07061314b18bd170c2"/></dir></target></contents>
|
104 |
<compatible/>
|
105 |
<dependencies><required><php><min>4.1.0</min><max>6.0.0</max></php></required></dependencies>
|
106 |
</package>
|