Drupal: swiftmailer is abandoned, use symfony mailer (part 2)

Photo by Maksim Goncharenok: https://www.pexels.com/photo/gold-letter-y-on-black-background-5605061/
 

 

Plugin and Symfony Mailer

In previous article we explored the installation and quick configuration of Symfony Mailer.

For the first integration, we start with the EK messaging module that is part of EK Back-office tools. The module creates messages and send notifications to user email.To learn more about what this module do, check documentation.

Since we already have a Swiftmailer integration, we will follow the process described in Symfony Mailer tutorial to create a plugin.

Our first step is to create a plugin file MessagingEmailBuilder.php inside our module under \ek_messaging\src\Plugin\EmailBuilder

Within the file we define the plugin:


<?php

namespace Drupal\ek_messaging\Plugin\EmailBuilder;

use Drupal\Core\Url;
use Drupal\symfony_mailer\EmailFactoryInterface;
use Drupal\symfony_mailer\EmailInterface;
use Drupal\symfony_mailer\Entity\MailerPolicy;
use Drupal\symfony_mailer\MailerHelperTrait;
use Drupal\symfony_mailer\Processor\EmailBuilderBase;

/**
 * Defines the Email Builder plug-in for ek_messaging module.
 *
 * @EmailBuilder(
 *   id = "ek_messaging",
 *   sub_types = { "ek_message" = @Translation("Internal message") },
 *   common_adjusters = {"email_subject", "email_body", "email_to"},
 *   import = @Translation("Update messaging"),
 * )
 */

 

The plugin will be automatically detected with Symfony Mailer configuration and can be edited with module interface. however, we will build the email message within the plugin class.


class MessagingEmailBuilder extends EmailBuilderBase {

  use MailerHelperTrait;

public function createParams(EmailInterface $email,$body = NULL, $sender = NULL, $recipient = NULL, $subject = NULL, $options = NULL) {}

public function fromArray(EmailFactoryInterface $factory, array $message) {}

public function build(EmailInterface $email) {}

}

We use 3 functions whose main job is to merge parameters of the mail service into the email object then build and send the message with Symfony Mail.

 

Function:  fromArray

Ek module triggers email with \Drupal::service('plugin.manager.mail')->mail() that pass different data and parameters. Mainly $params, for instance:


$params = [
   'subject' => $this->t('You have a new message'),
   'body' => $open,
   'from' => $currentuserMail,
   'priority' => $form_state->getValue('priority'),
   'link' => 1,
   'url' => $url,
];

then


\Drupal::service('plugin.manager.mail')->mail(
        'ek_messaging', 
        'ek_message',
        $account->getEmail(),
        $account->getPreferredLangcode(),
        $params,
        $currentuserMail,
        true
 );

The fromArray() plugin function will take those data to include them in the email object.


public function fromArray(EmailFactoryInterface $factory, array $message) {
    $sender = $message['params']['from'];  
    $body = $message['params']['body'];
    $recipient = $message['to'];
    $subject = $message['params']['subject'];
    $options = ['priority' => $message['params']['priority'], 'link' => $message['params']['link'], 'url' => $message['params']['url']];
    return $factory->newModuleEmail($message['module'], $message['key'],$body,$sender,$recipient,$subject,$options);
  }

 

Function : createParams

The function createParams() receives the data and saves it in the newly created email before building. the message.


public function createParams(EmailInterface $email,$body = NULL, $sender = NULL, $recipient = NULL, $subject = NULL, $options = NULL) {
    assert($recipient != NULL);
    $email->setParam('body', $body)
            ->setParam('from', $sender)
            ->setParam('to', $recipient)
            ->setParam('subject', $subject)
            ->setParam('options',$options);
  }

 

Function: build

Now that we have all information needed we will build the message by setting variables into email which will then be available for the email template. Basically this was handled by hook in the Swiftmailer configuration, i.e.


/**
 * Implementation hook_mail().
 */
function ek_messaging_mail($key, &$message, $params) {}

Which is now processed within the plugin:


public function build(EmailInterface $email) {
              
    $email->setVariable('site_name', $site_name)
      ->setVariable('site_logo', $site_logo)
      ->setVariable('stamp', $stamp)      
      ->setVariable('origin', \Drupal::currentUser()->getAccountName())
      ->setVariable('update_settings', Url::fromRoute('update.settings')->toString())
      ->setVariable('body', $body)  
      ->setVariable('messages', $messages);
    $email->setTo($email->getParam('to'));
    $email->setSubject($email->getParam('subject'));
  }

We don't replicate the full code for the build function above, but what is important are variables that are build into $email. Those variables will be available in Symfony Mailer hooks at various process steps and can be altered as well as twig template.

The 3 hooks function will be:


/**
 * Implements hook_mailer_
 * function invokeHooks(EmailInterface $email) in symfony_mailer/EmailFactory
*/

function ek_messaging_mailer_ek_messaging_init(\Drupal\symfony_mailer\EmailInterface $email) {}
function ek_messaging_mailer_ek_messaging_build(\Drupal\symfony_mailer\EmailInterface $email) {}
function ek_messaging_mailer_ek_messaging_post_send(\Drupal\symfony_mailer\EmailInterface $email) {}

 

We are not altering any data via hooks in our implementation.

We have now a fully functional plugin with variable we need for the email template.

 

Twig

The twig template follow the naming suggestion [module]--[type]--[key].html.twig. Our file name is then email--ek-messaging--ek-message.html.twig and placed into our theme template folder. Note that the theme used is defined in the Symfony Mailer configuration by  type and key.

We will not reproduce here the complete twig file as it is out of scope, but highlight what are the variables available to be used after processing from plugin.

;
{#
/**
* @file
* The default symfony mailer template for ek_messages.
* variables:
*       site_name
*       site_logo
*       messages.color
*       messages.priority
*       origin
*       messages.link
*       messages.body
*       messages.url
*       stamp
*/
#}
HTML Email
This is a sample HTML formatted email sent

 

If you have any comment or suggestion, please feel free to add yours.

 

Comments

Add new comment

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.