Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Sending email

The shop sends emails about orders and registration by itself. A module can send its own — for example, tell the shop owner about a new review. The Mail::Send() method does that: it takes a mail template, substitutes variables into it and sends it through the shop's mail settings.

Where templates live

A module's mail templates are kept in the mails folder, one subfolder per language. Every email needs two files with the same name: an HTML version and a text one. Create them by hand:

modules/acmehello/
├── acmehello.php
├── mails/
│   └── en/
│       ├── review_added.html
│       └── review_added.txt
└── ...

The subfolder name is the language code: en, ru, fr. Always keep the en folder: if there is no template for the email's language, the engine takes the English one.

The template

<!-- modules/acmehello/mails/en/review_added.html -->
<h2>New review</h2>
<p>Product: {product}</p>
<p>Author: {author}</p>
<p>Rating: {rating} out of 5</p>
New review
 
Product: {product}
Author: {author}
Rating: {rating} out of 5

The second block is the content of the review_added.txt file. A mail template is not Smarty: it has no conditions or loops, only placeholders in curly braces that are replaced with values.

Sending

// modules/acmehello/acmehello.php
private function notifyAboutReview(string $productName, string $author, int $rating): bool
{
    return (bool) Mail::Send(
        (int) $this->context->language->id,
        'review_added',
        $this->trans('New product review', [], 'Modules.Acmehello.Admin'),
        [
            '{product}' => $productName,
            '{author}' => $author,
            '{rating}' => $rating,
        ],
        Configuration::get('PS_SHOP_EMAIL'),
        null,
        null,
        null,
        null,
        null,
        $this->getLocalPath() . 'mails/'
    );
}

The method sends an email to the shop address and returns true on success.

Arguments of Mail::Send

In orderWhat is passed
1The language id: it selects the template subfolder
2The template name without the extension
3The subject
4The array of variables: the key is the placeholder with its braces
5The recipient address
6The recipient name
7, 8The sender address and name; null means the shop settings
9An attachment
10Internal, left as null
11The templates folder. For a module — its mails folder

Without the eleventh argument the engine looks for the template in the shop's common mails folder and does not find it. getLocalPath() returns the path of the module folder on disk.

Calling it after a review is saved

// modules/acmehello/acmehello.php, the addReview method
if (!$review->add()) {
    return false;
}
 
$product = new Product($productId, false, $this->context->language->id);
$this->notifyAboutReview($product->name, $author, $rating);
 
return true;

The email goes out after the review is saved. The sending result does not affect saving: a review must not be lost because of broken mail.

How to see the result

Send a review through the form on the reviews page and open "Advanced Parameters → E-mail" in the back office. At the bottom of the page there is a log of sent emails: a line with the review_added template appears there. The same page is where the sending method is configured and a test email is sent.

On a local machine mail usually does not leave the computer. It is handy to point the SMTP settings at a local mail catcher such as Mailpit: the emails show up in its window.

Ready variables

The engine adds several placeholders to every email by itself.

PlaceholderWhat is substituted
{shop_name}The shop name
{shop_url}The shop address
{shop_logo}The logo

Common mistake

Only the .html file is created and the .txt one is forgotten. Mail::Send() returns false, the email is not sent, and there is no error on screen. Every email needs both files with the same name in the folder of every language.

Thanks for reading!

Donate to the site — we work hard for you.