Enable Email Notifications for Product Comments in PrestaShop

If you have a solid and active customer base, it is frustrating to go and check the Product Comments module every day just to know if a new review has been posted. Let’s see how to add email notifications for comments!


Download Project Files

  • Compatibility: Prestashop 1.5, Prestashop 1.6
  • Version used: Prestashop 1.6

Introduction

Although I will be using Prestashop 1.6’s code for this tutorial, you can apply the same process to the Prestashop 1.5 version of the product comments module. Just be aware that you will have to use a 1.5 email template instead of copying the 1.6 one I will use here, to have all your emails uniform, if needed.

There is a small thing to notice: no language variable is passed when a new comment is added via ajax. This means we will create a new email template for the default shop language only, as, for the time being, I have found no reliable way to create a multilanguage-enabled function for this.

We will be amending one file only throughout the tutorial: default.php, along with creating two new email templates in the main mails/*language* folder. Let’s get started!

The default Comments controller

Prestashop comments’ submission is handled through an ajax call, so that no page refresh is needed when adding a new one. The main php file beneath all the comment submission process is default.php, and can be found in modules/productcomments/controllers/front/. Open it up in your favorite code editor, then locate the ajaxProcessAddComment() method.

This function is called upon comment submission, and it’s the place where we need to add our email send-out.

<br /><%%KEEPWHITESPACE%%>	protected function ajaxProcessAddComment()<br /><%%KEEPWHITESPACE%%>	{<br /><%%KEEPWHITESPACE%%>		$module_instance = new ProductComments();<br /><br /><%%KEEPWHITESPACE%%>		$result = true;<br /><%%KEEPWHITESPACE%%>		$id_guest = 0;<br /><%%KEEPWHITESPACE%%>		$id_customer = $this->context->customer->id;<br /><%%KEEPWHITESPACE%%>		if (!$id_customer)<br /><%%KEEPWHITESPACE%%>			$id_guest = $this->context->cookie->id_guest;<br /><br /><%%KEEPWHITESPACE%%>		$errors = array();<br /><%%KEEPWHITESPACE%%>		// Validation<br /><%%KEEPWHITESPACE%%>		if (!Validate::isInt(Tools::getValue('id_product')))<br /><%%KEEPWHITESPACE%%>			$errors[] = $module_instance->l('ID product is incorrect', 'default');<br /><%%KEEPWHITESPACE%%>		if (!Tools::getValue('title') || !Validate::isGenericName(Tools::getValue('title')))<br /><%%KEEPWHITESPACE%%>			$errors[] = $module_instance->l('Title is incorrect', 'default');<br /><%%KEEPWHITESPACE%%>		if (!Tools::getValue('content') || !Validate::isMessage(Tools::getValue('content')))<br /><%%KEEPWHITESPACE%%>			$errors[] = $module_instance->l('Comment is incorrect', 'default');<br /><%%KEEPWHITESPACE%%>		if (!$id_customer && (!Tools::isSubmit('customer_name') || !Tools::getValue('customer_name') || !Validate::isGenericName(Tools::getValue('customer_name'))))<br /><%%KEEPWHITESPACE%%>			$errors[] = $module_instance->l('Customer name is incorrect', 'default');<br /><%%KEEPWHITESPACE%%>		if (!$this->context->customer->id && !Configuration::get('PRODUCT_COMMENTS_ALLOW_GUESTS'))<br /><%%KEEPWHITESPACE%%>			$errors[] = $module_instance->l('You must be logged in order to send a comment', 'default');<br /><%%KEEPWHITESPACE%%>		if (!count(Tools::getValue('criterion')))<br /><%%KEEPWHITESPACE%%>			$errors[] = $module_instance->l('You must give a rating', 'default');<br /><br /><%%KEEPWHITESPACE%%>		$product = new Product(Tools::getValue('id_product'));<br /><%%KEEPWHITESPACE%%>		if (!$product->id)<br /><%%KEEPWHITESPACE%%>			$errors[] = $module_instance->l('Product not found', 'default');<br /><br /><%%KEEPWHITESPACE%%>		if (!count($errors))<br /><%%KEEPWHITESPACE%%>		{<br /><%%KEEPWHITESPACE%%>			$customer_comment = ProductComment::getByCustomer(Tools::getValue('id_product'), $id_customer, true, $id_guest);<br /><%%KEEPWHITESPACE%%>			if (!$customer_comment || ($customer_comment && (strtotime($customer_comment['date_add']) + (int)Configuration::get('PRODUCT_COMMENTS_MINIMAL_TIME')) < time()))<br /><%%KEEPWHITESPACE%%>			{<br /><br /><%%KEEPWHITESPACE%%>				$comment = new ProductComment();<br /><%%KEEPWHITESPACE%%>				$comment->content = strip_tags(Tools::getValue('content'));<br /><%%KEEPWHITESPACE%%>				$comment->id_product = (int)Tools::getValue('id_product');<br /><%%KEEPWHITESPACE%%>				$comment->id_customer = (int)$id_customer;<br /><%%KEEPWHITESPACE%%>				$comment->id_guest = $id_guest;<br /><%%KEEPWHITESPACE%%>				$comment->customer_name = Tools::getValue('customer_name');<br /><%%KEEPWHITESPACE%%>				if (!$comment->customer_name)<br /><%%KEEPWHITESPACE%%>					$comment->customer_name = pSQL($this->context->customer->firstname.' '.$this->context->customer->lastname);<br /><%%KEEPWHITESPACE%%>				$comment->title = Tools::getValue('title');<br /><%%KEEPWHITESPACE%%>				$comment->grade = 0;<br /><%%KEEPWHITESPACE%%>				$comment->validate = 0;<br /><%%KEEPWHITESPACE%%>				$comment->save();<br /><br /><%%KEEPWHITESPACE%%>				$grade_sum = 0;<br /><%%KEEPWHITESPACE%%>				foreach(Tools::getValue('criterion') as $id_product_comment_criterion => $grade)<br /><%%KEEPWHITESPACE%%>				{<br /><%%KEEPWHITESPACE%%>					$grade_sum += $grade;<br /><%%KEEPWHITESPACE%%>					$product_comment_criterion = new ProductCommentCriterion($id_product_comment_criterion);<br /><%%KEEPWHITESPACE%%>					if ($product_comment_criterion->id)<br /><%%KEEPWHITESPACE%%>						$product_comment_criterion->addGrade($comment->id, $grade);<br /><%%KEEPWHITESPACE%%>				}<br /><br /><%%KEEPWHITESPACE%%>				if (count(Tools::getValue('criterion')) >= 1)<br /><%%KEEPWHITESPACE%%>				{<br /><%%KEEPWHITESPACE%%>					$comment->grade = $grade_sum / count(Tools::getValue('criterion'));<br /><%%KEEPWHITESPACE%%>					// Update Grade average of comment<br /><%%KEEPWHITESPACE%%>					$comment->save();<br /><%%KEEPWHITESPACE%%>				}<br /><%%KEEPWHITESPACE%%>				$result = true;<br /><br /><%%KEEPWHITESPACE%%>				Tools::clearCache(Context::getContext()->smarty, $this->getTemplatePath('productcomments-reviews.tpl'));<br /><%%KEEPWHITESPACE%%>			}<br /><%%KEEPWHITESPACE%%>			else<br /><%%KEEPWHITESPACE%%>			{<br /><%%KEEPWHITESPACE%%>				$result = false;<br /><%%KEEPWHITESPACE%%>				$errors[] = $module_instance->l('You should wait').' '.Configuration::get('PRODUCT_COMMENTS_MINIMAL_TIME').' '.$module_instance->l('seconds before posting a new comment');<br /><%%KEEPWHITESPACE%%>			}<br /><%%KEEPWHITESPACE%%>		}<br /><%%KEEPWHITESPACE%%>		else<br /><%%KEEPWHITESPACE%%>			$result = false;<br /><br /><%%KEEPWHITESPACE%%>		die(Tools::jsonEncode(array(<br /><%%KEEPWHITESPACE%%>			'result' => $result,<br /><%%KEEPWHITESPACE%%>			'errors' => $errors<br /><%%KEEPWHITESPACE%%>		)));<br /><%%KEEPWHITESPACE%%>	}<br />

It would be useless to send an email notification if the comment submission process failed; thus, we will insert our code right after that $result = true; declaration.

So, right before Tools::clearCache(Context::getContext()->smarty, $this->getTemplatePath(‘productcomments-reviews.tpl’)); add:

<br /><%%KEEPWHITESPACE%%>				// send out an email! by Nemo<br /><br /><%%KEEPWHITESPACE%%>				$product_name = Product::getProductName($comment->id_product);<br /><%%KEEPWHITESPACE%%>				$shop_email = Configuration::get('PS_SHOP_EMAIL');<br /><%%KEEPWHITESPACE%%>				$shop_name = Configuration::get('PS_SHOP_NAME');<br /><br /><%%KEEPWHITESPACE%%>				Mail::Send(Configuration::get('PS_LANG_DEFAULT'), 'new_comment', Mail::l('New comment added'),<br /><%%KEEPWHITESPACE%%>				array(<br /><%%KEEPWHITESPACE%%>					'{comment_content}' => $comment->content,<br /><%%KEEPWHITESPACE%%>					'{product_name}' => $product_name<br /><%%KEEPWHITESPACE%%>				), $shop_email,<br /><%%KEEPWHITESPACE%%>					$shop_name, $shop_email);<br /><br />

Explanation: first off, we need some variables. We get the product name, to print out more information in the email, then the shop name and email to be used as arguments of the Mail::Send function. This very same method is really simple:

We pass the default language to it, then the name of the template we need (which doesn’t exist yet at this stage, but we will be creating it shortly), then the email Title. As template variables, we want ourselves to be aware of the content of the comment, as well as the product concerned. Lastly, we set the shop email as sender, receiver, and the shop name as receiver’s name.

We are done with this file already. Let’s create the actual email templates!

Creating the new email templates

This is the easiest part. Two files are needed in order for email notifications to work in Prestashop: an .html version, and a .txt one. Reach the main mails/ folder, and inside it access the subfolder with your default store language’s ISO code. Then, create a new file called new_comment.html and paste the following inside:

<br /><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd"><br /><html><br /><%%KEEPWHITESPACE%%>	<head><br /><%%KEEPWHITESPACE%%>		<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><br /><%%KEEPWHITESPACE%%>		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" /><br /><%%KEEPWHITESPACE%%>		<title>Message from {shop_name}</title><br /><br /><%%KEEPWHITESPACE%%>		<style>	@media only screen and (max-width: 300px){<br /><%%KEEPWHITESPACE%%>				body {<br /><%%KEEPWHITESPACE%%>					width:218px !important;<br /><%%KEEPWHITESPACE%%>					margin:auto !important;<br /><%%KEEPWHITESPACE%%>				}<br /><%%KEEPWHITESPACE%%>				.table {width:195px !important;margin:auto !important;}<br /><%%KEEPWHITESPACE%%>				.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto !important;display: block !important;}<br /><%%KEEPWHITESPACE%%>				span.title{font-size:20px !important;line-height: 23px !important}<br /><%%KEEPWHITESPACE%%>				span.subtitle{font-size: 14px !important;line-height: 18px !important;padding-top:10px !important;display:block !important;}<br /><%%KEEPWHITESPACE%%>				td.box p{font-size: 12px !important;font-weight: bold !important;}<br /><%%KEEPWHITESPACE%%>				.table-recap table, .table-recap thead, .table-recap tbody, .table-recap th, .table-recap td, .table-recap tr {<br /><%%KEEPWHITESPACE%%>					display: block !important;<br /><%%KEEPWHITESPACE%%>				}<br /><%%KEEPWHITESPACE%%>				.table-recap{width: 200px!important;}<br /><%%KEEPWHITESPACE%%>				.table-recap tr td, .conf_body td{text-align:center !important;}<br /><%%KEEPWHITESPACE%%>				.address{display: block !important;margin-bottom: 10px !important;}<br /><%%KEEPWHITESPACE%%>				.space_address{display: none !important;}<br /><%%KEEPWHITESPACE%%>			}<br /><%%KEEPWHITESPACE%%>	@media only screen and (min-width: 301px) and (max-width: 500px) {<br /><%%KEEPWHITESPACE%%>				body {width:308px!important;margin:auto!important;}<br /><%%KEEPWHITESPACE%%>				.table {width:285px!important;margin:auto!important;}<br /><%%KEEPWHITESPACE%%>				.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}<br /><%%KEEPWHITESPACE%%>				.table-recap table, .table-recap thead, .table-recap tbody, .table-recap th, .table-recap td, .table-recap tr {<br /><%%KEEPWHITESPACE%%>					display: block !important;<br /><%%KEEPWHITESPACE%%>				}<br /><%%KEEPWHITESPACE%%>				.table-recap{width: 293px !important;}<br /><%%KEEPWHITESPACE%%>				.table-recap tr td, .conf_body td{text-align:center !important;}<br /><br /><%%KEEPWHITESPACE%%>			}<br /><%%KEEPWHITESPACE%%>	@media only screen and (min-width: 501px) and (max-width: 768px) {<br /><%%KEEPWHITESPACE%%>				body {width:478px!important;margin:auto!important;}<br /><%%KEEPWHITESPACE%%>				.table {width:450px!important;margin:auto!important;}<br /><%%KEEPWHITESPACE%%>				.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}<br /><%%KEEPWHITESPACE%%>			}<br /><%%KEEPWHITESPACE%%>	@media only screen and (max-device-width: 480px) {<br /><%%KEEPWHITESPACE%%>				body {width:308px!important;margin:auto!important;}<br /><%%KEEPWHITESPACE%%>				.table {width:285px;margin:auto!important;}<br /><%%KEEPWHITESPACE%%>				.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}<br /><br /><%%KEEPWHITESPACE%%>				.table-recap{width: 285px!important;}<br /><%%KEEPWHITESPACE%%>				.table-recap tr td, .conf_body td{text-align:center!important;}<br /><%%KEEPWHITESPACE%%>				.address{display: block !important;margin-bottom: 10px !important;}<br /><%%KEEPWHITESPACE%%>				.space_address{display: none !important;}<br /><%%KEEPWHITESPACE%%>			}<br /></style><br /><br /><%%KEEPWHITESPACE%%>	</head><br /><%%KEEPWHITESPACE%%>	<body style="-webkit-text-size-adjust:none;background-color:#fff;width:650px;font-family:Open-sans, sans-serif;color:#555454;font-size:13px;line-height:18px;margin:auto"><br /><%%KEEPWHITESPACE%%>		<table class="table table-mail" style="width:100%;margin-top:10px;-moz-box-shadow:0 0 5px #afafaf;-webkit-box-shadow:0 0 5px #afafaf;-o-box-shadow:0 0 5px #afafaf;box-shadow:0 0 5px #afafaf;filter:progid:DXImageTransform.Microsoft.Shadow(color=#afafaf,Direction=134,Strength=5)"><br /><%%KEEPWHITESPACE%%>			<tr><br /><%%KEEPWHITESPACE%%>				<td class="space" style="width:20px;padding:7px 0"> </td><br /><%%KEEPWHITESPACE%%>				<td align="center" style="padding:7px 0"><br /><%%KEEPWHITESPACE%%>					<table class="table" bgcolor="#ffffff" style="width:100%"><br /><%%KEEPWHITESPACE%%>						<tr><br /><%%KEEPWHITESPACE%%>							<td align="center" class="logo" style="border-bottom:4px solid #333333;padding:7px 0"><br /><%%KEEPWHITESPACE%%>								<a title="{shop_name}" href="{shop_url}" style="color:#337ff1"><br /><%%KEEPWHITESPACE%%>									<img src="{shop_logo}" alt="{shop_name}" /><br /><%%KEEPWHITESPACE%%>								</a><br /><%%KEEPWHITESPACE%%>							</td><br /><%%KEEPWHITESPACE%%>						</tr><br /><br /><tr><br /><%%KEEPWHITESPACE%%>	<td align="center" class="titleblock" style="padding:7px 0"><br /><%%KEEPWHITESPACE%%>		<font size="2" face="Open-sans, sans-serif" color="#555454"><br /><%%KEEPWHITESPACE%%>			<span class="title" style="font-weight:500;font-size:28px;text-transform:uppercase;line-height:33px">Hi!</span><br /><%%KEEPWHITESPACE%%>		</font><br /><%%KEEPWHITESPACE%%>	</td><br /></tr><br /><tr><br /><%%KEEPWHITESPACE%%>	<td class="space_footer" style="padding:0!important"> </td><br /></tr><br /><tr><br /><%%KEEPWHITESPACE%%>	<td class="box" style="border:1px solid #D6D4D4;background-color:#f8f8f8;padding:7px 0"><br /><%%KEEPWHITESPACE%%>		<table class="table" style="width:100%"><br /><%%KEEPWHITESPACE%%>			<tr><br /><%%KEEPWHITESPACE%%>				<td width="10" style="padding:7px 0"> </td><br /><%%KEEPWHITESPACE%%>				<td style="padding:7px 0"><br /><%%KEEPWHITESPACE%%>					<font size="2" face="Open-sans, sans-serif" color="#555454"><br /><%%KEEPWHITESPACE%%>						<p data-html-only="1" style="border-bottom:1px solid #D6D4D4;margin:3px 0 7px;text-transform:uppercase;font-weight:500;font-size:18px;padding-bottom:10px"><br /><%%KEEPWHITESPACE%%>							You have received a new comment for the product "{product_name}"						</p><br /><%%KEEPWHITESPACE%%>						<span style="color:#777"><br /><%%KEEPWHITESPACE%%>							{comment_content}<br /><%%KEEPWHITESPACE%%>						</span><br /><%%KEEPWHITESPACE%%>					</font><br /><%%KEEPWHITESPACE%%>				</td><br /><%%KEEPWHITESPACE%%>				<td width="10" style="padding:7px 0"> </td><br /><%%KEEPWHITESPACE%%>			</tr><br /><%%KEEPWHITESPACE%%>		</table><br /><%%KEEPWHITESPACE%%>	</td><br /></tr><br /><br /><%%KEEPWHITESPACE%%>						<tr><br /><%%KEEPWHITESPACE%%>							<td class="space_footer" style="padding:0!important"> </td><br /><%%KEEPWHITESPACE%%>						</tr><br /><%%KEEPWHITESPACE%%>						<tr><br /><%%KEEPWHITESPACE%%>							<td class="footer" style="border-top:4px solid #333333;padding:7px 0"><br /><%%KEEPWHITESPACE%%>								<span><a href="{shop_url}" style="color:#337ff1">{shop_name}</a> powered by <a href="http://www.prestashop.com/" style="color:#337ff1">PrestaShop™</a></span><br /><%%KEEPWHITESPACE%%>							</td><br /><%%KEEPWHITESPACE%%>						</tr><br /><%%KEEPWHITESPACE%%>					</table><br /><%%KEEPWHITESPACE%%>				</td><br /><%%KEEPWHITESPACE%%>				<td class="space" style="width:20px;padding:7px 0"> </td><br /><%%KEEPWHITESPACE%%>			</tr><br /><%%KEEPWHITESPACE%%>		</table><br /><%%KEEPWHITESPACE%%>	</body><br /></html><br />

Then create another one named new_comment.txt, and paste this inside:

<br /><br />[{shop_url}] <br /><br />Hi!,<br /><br />You have received a new comment for the product "{product_name}"<br /><br />{comment_content}<br />{shop_name} [{shop_url}] powered by<br />PrestaShop(tm) [http://www.prestashop.com/] <br /><br />

NOTE: If you are using Prestashop 1.6 you can simply copy and paste the above inside a .html and .txt file, otherwise, if you are trying to apply it to 1.5, my suggestion is to pick a default email template, such as the log_alert one, and modify it accordingly by adding the new variables.

We are done! Save, and then test the new email notifications out by adding a comment!

Final Notes

If your emails are not being sent out, make sure you test them by going to Advanced Parameters, E-Mail in the back office. Double check our email settings and try sending out a test email as well.

If everything works at this state, inspect the ajax call by accessing the network tab in a browser console (F12 on Chrome, for example). The comment ajax call looks like default?action=add_comment&secure_key=6efb5690f08b14a4d0c050119418fc68&rand=1397469373235.

That’s all!

Looking for quality web hosting? Look no further than Arvixe Web Hosting!

Tags: , , , , , , , , , , , | Posted under PrestaShop | RSS 2.0

Author Spotlight

Fabio Porta

Fabio Porta

Fabio has been involved in web development and design since 2005, when launched his first website at the age of 16. He’s now highly skilled in both client and server side development, along with design, and since August 2012 runs a successful website about PrestaShop tutorials and Prestashop Modules called Nemo’s Post Scriptum, at http://nemops.com

Leave a Reply

Your email address will not be published. Required fields are marked *


6 − = 4

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>