This example is used to send out a reminder email to customers 21 days after a purchase, if they have not reviewed their products.
This also is using email templates, which makes it a bit more complicated, otherwise you can just use the good ole php mail function instead.
I am using a site called Bloom so all my notes will reflect that file structure.
We need to create a module in /app/etc/modules/.
Create a file called Bloom_ReminderEmail.xml and in that file put in the following:
<?xml version="1.0"?>
<config>
<modules>
<Bloom_ReminderEmail>
<active>true</active>
<codePool>local</codePool>
<version>0.1</version>
</Bloom_ReminderEmail>
</modules>
</config>
Create the email template in /app/locale/en_US/template/email/ called reminder_email.html and that file include:
<!--@subject Review your products at bloom.com @-->
<!--@vars
{"store url=\"\"":"Store Url",
"skin url=\"images/logo.png\" _area='frontend'":"Email Logo Image"}
Sample Image Url:
<img src="{{skin url="images/logo.png" _area='frontend'}}" border="0"/> -->
<!--@styles
body,td { color:#2f2f2f; font:14px/1.35em Verdana, Arial, Helvetica, sans-serif; }
a, a:visited{color:#801F94;text-decoration:;}
a:hover{color:#801F94;}
@-->
<body style="background:#F6F6F6; font-family:Verdana, Arial, Helvetica, sans-serif; font-size:12px; margin:0; padding:0;">
<div style="font-family: Verdana,Arial,Helvetica,sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 11px; line-height: 1.35em; font-size-adjust: none;">
<table cellspacing="0" cellpadding="0" border="0" width="98%" style="margin-top:10px; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; margin-bottom:10px;">
<tr>
<td align="center" valign="top">
<!-- [ header starts here] -->
<table cellspacing="0" cellpadding="0" border="0" width="650">
<tr>
<td valign="top">
<img src="http://bloom.com/skin/frontend/enterprise/bloom/images/logo.png" border="0" alt="Bloom.com" />
</td>
</tr>
</table>
<!-- [ middle starts here] -->
<table cellspacing="0" cellpadding="0" border="0" width="650">
<tr>
<td valign="top">
<p>
<strong>Dear {{var customerName}}</strong>!<br/>
<p style="color: #000000;font-family:arial;font-size:14px">Thank you for your recent Bloom.com order. You\'ve tried the products, now share the
love! Please don\'t keep the results a secret! Thousands of women are anxious to see what
you think before making the same purchases. Women helping women...that\'s what social
beauty is all about. It only takes a few seconds! Just click the products in your Beauty
Cabinet below and share your opinion-voilà</p>
{{var productList}}
</p>
<p style="color: #000000;font-family:arial;font-size:14px">
Have a question? Our Beauty Conceirge is standing by at
<a href="mailto:{{var supportEmail}}" style="color:#1E7EC8;">{{var supportEmail}}</a>
or {{var supportPhone}}.
</p>
<span style="color: #48107D;font-family:arial;font-size:16px">Have a beautiful day,<br/>
<strong>bloom.com</strong></span>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</body>
Now create a folder in /app/code/local/Bloom/ called ReminderEmail and in that folder create 3 new folders:
etc, Model and sql
In /app/code/local/Bloom/ReminderEmail/etc create a file called config.xml and that file should contain:
<?xml version="1.0"?>
<config>
<modules>
<Bloom_ReminderEmail>
<version>0.0.1</version>
</Bloom_ReminderEmail>
</modules>
<global>
<models>
<bloom_reminderemail>
<class>Bloom_ReminderEmail_Model</class>
</bloom_reminderemail>
</models>
<resources>
<reminderemail_setup>
<setup>
<module>Bloom_ReminderEmail</module>
</setup>
</reminderemail_setup>
</resources>
<template>
<email>
<reminder_email_template translate="label" module="reminderemail">
<label>Send Reminder Email</label>
<file>reminder_email.html</file>
<type>html</type>
</reminder_email_template>
</email>
</template>
</global>
<crontab>
<jobs>
<send_bloom_reminder_emails>
<schedule><cron_expr>0 0 * * *</cron_expr></schedule>
<run><model>bloom_reminderemail/observer::sendbloomreminderemails</model></run>
</send_bloom_reminder_emails>
</jobs>
</crontab>
</config>
In /app/code/local/Bloom/ReminderEmail/Model create a file called Observer.php and that file should contain:
<?php
class Bloom_ReminderEmail_Model_Observer
{
/*
* function remove_duplicates( $product_list, $already_reviewed )
*
* Requires two arrays, the first is the entire product list from the order
* The second is the already reviewed list of product ID's
*
* Returns an array with only the products ID's that have not been reviewed by the customer
*
*/
private function remove_duplicates( $product_list, $already_reviewed )
{
foreach( $product_list as $list_key => $list1 )
{
foreach( $already_reviewed as $list2 )
{
if ( $list1 == $list2 )
{
unset( $product_list[ $list_key ] );
}
}
}
return $product_list;
}
public function sendBloomReminderEmails()
{
// get the template for sending the reminder email
$templateId = Mage::getStoreConfig('reminder_email/template');
// subject
$mailSubject = 'Update your beauty cabinet';
// Sender email
$sender = array(
'name' => 'Bloom',
'email' => 'myaccount@bloom.com'
);
$support_email = Mage::getStoreConfig('trans_email/ident_general/email');
$support_phone = Mage::getStoreConfig('general/store_information/phone');
$baseUrl = Mage::getBaseUrl();
/*
*
* Set the time for our query, 00:00:00 to 11:59:59 and the amount of days to go back
* 21 days is our default setting
*
*/
$days_back = 21;
$am = date( "Y-m-d H:i:s", mktime( 0,0,0, date( "m" ), date( "d" ) - $days_back, date( "Y" ) ) );
$pm = date( "Y-m-d H:i:s", mktime( 23,59,59, date( "m" ), date( "d" ) - $days_back, date( "Y" ) ) );
/*
* This first query sets up all the orders that happened on the day in question
* Returns an array of customers ID, email and Order ID
* The Order ID is actually an internal counter that ties our other tables together, not the Magento ID
*
*/
$query1 = "SELECT
sfo.customer_id,
sfo.store_id,
sfo.customer_email,
sfo.entity_id as order_id
FROM
sales_flat_order as sfo,
sales_flat_shipment_track as sfst
WHERE
sfo.entity_id = sfst.order_id
AND
sfst.updated_at
BETWEEN
'$am'
AND
'$pm'";
$result1 = Mage::getSingleton('core/resource') ->getConnection('core_read')->fetchAll($query1);
for( $i = 0; $i <= count( $result1 ) - 1; $i++)
{
$customer_id = array();
$customer_email = array();
$order_id = array();
$purchased_list = array();
$reviewed_list = array();
$order_id = array();
$order_increment_id = array();
$shipping_name = array();
$magento_order_id = array();
/*
*
* This query gathers all the products and the order_increment_id
* The Order Increment ID is the actual Magento Order ID# that we are used to seeing and using in the
* Administration section in Magento
*
*/
$query2 = "SELECT
product_id,
order_increment_id,
shipping_name
FROM
sales_flat_shipment_item,
sales_flat_shipment_grid
WHERE
order_id = '{$result1[$i]['order_id']}'
AND
parent_id = sales_flat_shipment_grid.entity_id";
$result2 = Mage::getSingleton('core/resource') ->getConnection('core_read')->fetchAll($query2);
$shipping_name = $result2[0]['shipping_name'];
//$magento_order_id = $result2[0]['order_increment_id'];
for( $j = 0; $j <= count($result2) - 1; $j++)
{
$purchased_list[] = $result2[$j]['product_id'];
}
/*
*
* This last query is getting the entity_pk_value, which is the same as the product ID
* for all the products that the current customer has reviewed.
* We are gathering this so we can remove them from our final array of product ID's that still need a review
*
*/
$query3 = "SELECT
entity_pk_value
FROM
review,
review_detail
WHERE
review_detail.customer_id = '{$result1[$i]['customer_id']}'
AND
review.review_id = review_detail.review_id";
$result3 = Mage::getSingleton('core/resource') ->getConnection('core_read')->fetchAll($query3);
for( $k = 0; $k <= count($result3) - 1; $k++)
{
$reviewed_list[] = $result3[$k]['entity_pk_value'];
}
/*
*
* Array of products that still need to be reviewed
*
* $product_reviews_needed = $this->remove_duplicates( $purchased_list, $reviewed_list );
*
* What this does is take the purchased list from the current order, and then looks
* at the already reviewed items and removes any that are in both. Whats left
* is an array of products that still need a review.
*
*/
// Store ID
$storeId = $result1[$i]['store_id'];
// Load the skin url based on the store ID
$bloom_logo = 'http://bloom.com/skin/frontend/enterprise/bloom/images/logo.png';
$product_reviews_needed = $this->remove_duplicates( $purchased_list, $reviewed_list );
$product_list_formatted = '<table>';
foreach( $product_reviews_needed as $product_reviews_key => $id )
{
$_imagehelper = Mage::helper('catalog/image');
//$productDetails = Mage::getModel('catalog/product')->load($id)->getShortDescription();
$product = Mage::getModel('catalog/product')->load($id);
if($product->isConfigurable())
{
$product_list_formatted .= '<tr>
<td><img src="'. $_imagehelper->init($product, 'image')->resize(100) .'" alt="Bloom product image" /></td>
<td>'. $product->getName(). '</td>
<td><a href="' . $baseUrl . 'customer/account/cabinet/" target="_blank">Review Now</a></td>
</tr>';
}
else
{
// Take away one from the array, we are counting to see if an email needs to be sent
unset($product_reviews_needed[$product_reviews_key]);
}
}
$product_list_formatted .= '</table>';
$customer_email = $result1[$i]['customer_email'];
// If this customer has at least one review needed send the email
if( count( $product_reviews_needed ) > 0 )
{
// Set variables that can be used in email template
$vars = array(
'customerName' => $shipping_name,
'customerEmail' => $customer_email,
'supportPhone' => $support_phone,
'supportEmail' => $support_email,
'productList' => $product_list_formatted,
'bloomLogo' => $bloom_logo
);
$translate = Mage::getSingleton('core/translate');
Mage::getModel('core/email_template')
->setTemplateSubject($mailSubject)
->sendTransactional($templateId, $sender, $customer_email, $shipping_name, $vars, $storeId);
$translate->setTranslateInline(true);
}
}
}
}
?>
Finally in In /app/code/local/Bloom/ReminderEmail/sql create a sub folder called:
reminderemail_setup
In that folder /app/code/local/Bloom/sql/reminderemail_setup create a file called mysql4-install-0.0.1.php and that file should have this in it:
<?php
$installer = $this;
$installer->startSetup();
/* @var $installer Mage_Core_Model_Resource_Setup */
$configValuesMap = array(
'reminder_email/template' =>
'reminder_email_template',
);
foreach ($configValuesMap as $configPath=>$configValue) {
$installer->setConfigData($configPath, $configValue);
}
$installer->endSetup();
Now, that should be it, when cron is run, it will establish a cron rule that will run every day at midnight and remind your customers to review their products they purchased 21 days ago.