Introduction

This article describes how developers can configure and send custom email notifications. Custom email notifications may be useful if you want to send messages after certain events. For instance, we want to be able to send notifications on behalf of the shop admin. This guide explains how to do it; it will also cover the topic of regiseting your custom notifications in the admin area.

Table of contents

Implementation

First of all, this task requires you to have a custom module. We’ll create a new module with the developer ID Tony and the module ID EmailDemo. Besides, we’ll create a custom page in the admin area to test our notifications. Please note that this page is purely optional and will serve as an example of an action that triggers the notification. This page will be available at cart.php?target=tony_custom_email address.

Creating the mailer method

X-Cart offers a convenient and expandable interface to send emails -XLite\Core\Mailer class. This class contains a lot of functions designed to build and send messages step by step. In order to use it, we decorate the class XLite\Core\Mailer and add a method to send our notification. We create a file <X-Cart>/classes/XLite/Module/Tony/EmailDemo/Core/Mailer.php with the following content: 

<?php
namespace XLite\Module\Tony\EmailDemo\Core;
/**
 * Mailer
 */
abstract class Mailer extends \XLite\Core\Mailer implements \XLite\Base\IDecorator
{
    /**
     * Send custom email
     *
     * @param string $to   Email address to send custom email to
     * @param string $body Custom email body text OPTIONAL
     * @param bool $advanced_mode Use yaml-loaded templates OPTIONAL
     *
     * @return string | null Possible error message
     */
    public static function sendEmailDemoMessage($to, $body = '')
    {
        static::register(
            array('custom_param' => $body, 'subject' => 'Demo notification')
        );
        $templatesDir = 'modules/Tony/EmailDemo/message';
        static::compose(
            'DemoMail',
            static::getSiteAdministratorMail(),
            $to,
            $templatesDir,
            array(),
            true,
            \XLite::ADMIN_INTERFACE
        );
        return static::getMailer()->getLastError();
    }
}

The method we will be using to send our notifications is sendEmailDemoMessage(). Be sure to define it as a static method and choose a unique name so it doesn’t override any existing mailer methods. Let’s get an overview of its features:

  • We are using the method register() with an array of key-value pairs to define some data that will be inserted into the mail template. For the sake of example, we are passing the argument $body to use it later as a ‘custom_param’ object.
  • $advanced_mode param defines which mail templates will be used. It is just an example of some custom logic, so you don’t have to use it in your method. 
  • Finally, to send the message we are calling the method XLite\Core\Mailer::compose() with a set of arguments:

    1. string $type - is used to preprocess the $to, $from, $dir and $customHeaders params. You can provide a set of methods, called like **prepare<param><$type>;** for example, prepareCustomHeadersDemoMail($customHeaders) or prepareToDemoMail($to). If these methods exist, they will be called automatically during message composing.
    2. string $from - email **From:** field.
    3. string $to - email To: field. For example, we can use the default site administrator email here.
    4. string $dir - directory where mail templates are located. The parent folder for this directory is <X-Cart>/skins/mail/<language (e.g. **en**)>/.
    5. (optional) array$customHeaders - an array of key-value pairs with additional headers (Cc:, Bcc:, Reply-To:, etc.).
    6. (optional) boolean $doSend - flag to cancel sending; can be used to debug the mailer;
    7. (optional) string $interface - template interface, either \XLite::ADMIN_INTERFACE or \XLite::CUSTOMER_INTERFACE.
    8. (optional) string $languageCode - language code of the message.
  • We’ll return the value static::getMailer()->getLastError() as a result of the operation. If the message is sent successfully, it will be **null**; otherwise, it will contain an error message.

Designing the message template

An email message is composed from several parts such as header, subjectbody and signature. _You can customize the general header and signature in your store’s admin area, on the _Store setup -> Email notifications -> Headers & signatures page. However, the subject and body need to be customized through the template files named subject.tpl and body.tpl, respectively. These files should exist in the mail templates directory. In our case, they are present in the directory <X-Cart>/skins/mail/en/modules/Tony/EmailDemo/message with the following content:

subject.tpl

{subject}

body.tpl

<p>
  The text is - {custom_param}
</p>

As you can see, we can mix some predefined content with the registered parameters. As a result, we will be able to send messages like this:

From now on, to send a message, you should call your newly created method like this:

/**
 * Action to send test email notification
 *
 * @return void
 */
protected function doActionSendEmail()
{
    $request = \XLite\Core\Request::getInstance();
	$error = \XLite\Core\Mailer::sendEmailDemoMessage(
        $request->custom_to_email_address,
        $request->custom_email_body
    );
    if ($error) {
        \XLite\Core\Session::getInstance()->custom_email_error = $error;
        \XLite\Core\TopMessage::getInstance()->addError('Error of test e-mail sending: ' . $error);
    } else {
        \XLite\Core\TopMessage::getInstance()->add('Test e-mail have been successfully sent');
    }
    $this->setReturnURL(
        $this->buildURL('tony_custom_email', '', array())
    );
}

Please note that the above way is simply an example of usage; you can send messages during certain events or logic processing, if needed. This example sends a message on form submit.

Registering the notification in the admin area

The admin area of an X-Cart store allows you to turn off certain notifications for admin or for customer. You can configure that on the Store setup -> Email notifications -> Settings page. This page contains a list of different notification types and provides switches allowing the user to enable/disable specific notification types for administrator and customer. For a custom notification to appear in the mentioned list, it should be registered in the module file install.yaml. For instance, we will add the following content:

XLite\Model\Notification:
  - templatesDirectory: modules/Tony/EmailDemo/message
    availableForAdmin: true
    availableForCustomer: false
    enabledForAdmin: true
    enabledForCustomer: false
    translations: 
      - code: en
        name: Advanced demo notification sent (Email Demo module)
        description: 'This notification is sent from testing page with preset subject and text'
        adminSubject: Someone has sent advanced demo notification
        adminText: "This is the body of your advanced demo notification"

Notification definition consists of several parameters:

  • templatesDirectory - is used as an identifier of the notification;
  • availableForAdmin - makes the notification available for administrator;
  • availableForCustomer - the same, but for customer;
  • enabledForAdmin - makes the notification enabled by default for administrator;
  • enabledForCustomer - the same, but for customer;
  • translations - language labels of a certain format:
    • code - language code
    • name - notification heading on the Settings page;
    • description - notification description on the Settings page;
    • (optional) adminSubject - default notification subject for ADMIN_INTERFACE;
    • (optional) adminText - default notification body for ADMIN_INTERFACE;
    • (optional) customerSubject and (optional) customerText - the same, but for CUSTOMER_INTERFACE;

After writing this code to the file, you should load it into system. It can be done using one of the two methods:

  1. by re-installing this module,
  2. by loading the YAML file manually.

You can also change the mail templates to make use of the default subject and body text, preset in the translation parameter, like this:

subject.tpl

{getNotificationSubject()}

body.tpl

<p>
  {getNotificationText():h}
</p>
<p>
	Custom parameter:<br>
	{custom_param}
</p>

This allows you to change the subject and body text in the admin area, without tampering with template files. The interface is shown on the picture below:

As a result of the above actions, you should be able to configure your custom method in the admin area:

Module example

You can download this module example from here: Tony-EmailDemo-v5.2.0.tar

Attachments: