A real-world use case for sending email notifications when a new entry draft is created using a Craft module and an event handler. It requires setting up a module and writing some PHP code, so pull up your sleeves and dust off your IDE.
The challenge is to create a module that listens for the EntryRevisions::EVENT_AFTER_SAVE_DRAFT
event. Whenever the event is fired, provided that the draft is new, the module should send a notification email to the system email address with the subject “First Draft” and the following message:
A new entry draft “{title}” has been created by “{username}”: {cpUrl}
Where {title}
is replaced by the title of the entry draft, {username}
is replaced by the username of the user that created the draft and {cpUrl}
is the URL to edit the entry in the control panel.
For bonus points, if the environment variable FIRST_DRAFT_EMAIL_TEMPLATE
is set then the module should use the rendered template (as defined by the the environment variable) as the email’s HTML body, providing the 3 variables above as template variables.
The module must be a single, self-contained file that sends an email notification as described above whenever a draft is created, if and only if the draft is new (not a revision of an existing draft). It should not rely on any plugins and the code will be evaluated based on the following criteria in order of priority:
Therefore the code should use native Craft components wherever possible. It should be readable and easy to understand, concise and non-repetative.
Every installation of Craft created using the Craft project as documented in the installation instructions comes with a modules/Module.php
file. You can use this file as a starting point or read the guide on how to build a module and create your own.
For an in-depth explanation of modules you can read the article Enhancing a Craft CMS 3 Website with a Custom Module.
Solution submitted by Spenser Hannon on 21 November 2018.
<?php
namespace modules;
use Craft;
use craft\events\DraftEvent;
use craft\mail\Message;
use craft\services\EntryRevisions;
use yii\base\Event;
class Module extends \yii\base\Module
{
public function init()
{
parent::init();
Event::on(EntryRevisions::class, EntryRevisions::EVENT_AFTER_SAVE_DRAFT, function (DraftEvent $e) {
if ($e->isNew) {
$replacements = array(
'{title}' => $e->draft->title,
'{username}' => $e->draft->author->username,
'{cpUrl}' => $e->draft->cpEditUrl
);
$subject = strtr('A new entry draft "{title}" has been created by "{username}"', $replacements);
$message = $subject . strtr(': <a href="{cpUrl}">{cpUrl}</a>', $replacements);
$this->sendEmail($message, $subject);
}
});
}
/**
* @param $html
* @param $subject
* @param null $mail
* @param array $attachments
* @return bool
*/
private function sendEmail($html, $subject): bool
{
$emailSettings = Craft::$app->systemSettings->getSettings('email');
$message = new Message();
$message->setFrom([$emailSettings['fromEmail'] => $emailSettings['fromName']]);
$message->setTo(getenv('FIRST_DRAFT_EMAIL_TEMPLATE') ?? $emailSettings['fromEmail']);
$message->setSubject($subject);
$message->setHtmlBody($html);
return Craft::$app->mailer->send($message);
}
}