Unverified Commit 2ab0b879 authored by spokje's avatar spokje Committed by Jonathan Hedstrom
Browse files

Issue #2953489 by dww, diamondsea, Spokje, mmcintosh: Add Twig support in...

Issue #2953489 by dww, diamondsea, Spokje, mmcintosh: Add Twig support in Subject, Email, and Message fields
parent 17df7fb0
Loading
Loading
Loading
Loading
+47 −2
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ CONTENTS OF THIS FILE
 * Requirements
 * Installation
 * Configuration
 * Using Twig Templates
 * Maintainers


@@ -46,8 +47,52 @@ CONFIGURATION
       Moderation Notifications to add notifications.
    3. Select a workflow.
    4. Select which transitions triggers this notification.
    5. Choose which roles to send notifications.
    6. Configure the email settings. Create Notification.
    5. Choose which roles and/or ad-hoc email addresses should receive notifications.
    6. Configure the message settings.
    7. Create Notification.

USING TWIG TEMPLATES
--------------------

You may use any valid Twig syntax within the Subject, Adhoc Email addresses, and
Message fields.

This will allow you to include additional fields, entity references, conditional
logic and TWIG functions in these fields.

NOTE: The Twig Tweak module will provide many additional Twig functions to your
template, such as drupal_token() which can be used to display any available
tokens.

Examples:

Subject: (no Twig used)
  New Content Needs Review

Subject: (using Twig variables)
  {{ entity.bundle|title }} from {{ entity.Owner.name.0.value }} Needs Review

Subject: (using Twig variables, comments, and conditionals and Twig Tweak's drupal_token() function)
  {% set author = entity.Owner.name.0.value %}
  {{ entity.bundle|title }} from {{ author }} Needs Review
  {# Get their attention if it's from someone important #}
  {% if author == "admin" %}
    !!! DO IT NOW !!!
  {% endif %}
  ({{ drupal_token('site:name') }})

Adhoc Email addresses: (add an email in an single-value entity reference field and a standard email box)
  {{ entity.field_department.entity.field_manager_email.0.value }}, dropbox@example.com

Adhoc Email addresses: (add a standard email box and all emails in an multi-value entity reference field)
  dropbox@example.com
  {% for referenced_entity in entity.field_content_owners %}
    {{ referenced_entity.entity.field_email.0.value }}
  {% endfor %}

Message:  (Can support all the same Twig options, but will run template output through the selected
           Text Format's (Basic HTML, Full HTML, etc) Input Filters  before it will be mailed)
  Please update this content from {{ entity.Owner.name.0.value }}.


MAINTAINERS
+1 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ content_moderation_notifications.content_moderation_notification.*:
       type: string
       label: 'Emails'
    subject:
       type: label
       type: string
       label: 'Subject'
    body:
      type: text_format
+6 −3
Original line number Diff line number Diff line
@@ -179,18 +179,20 @@ class ContentModerationNotificationsFormBase extends EntityForm {

    $form['emails'] = [
      '#type' => 'textarea',
      '#rows' => 3,
      '#title' => $this->t('Adhoc email addresses'),
      '#default_value' => $content_moderation_notification->getEmails(),
      '#description' => $this->t('Send notifications to these email addresses, emails should be entered as a comma separated list and optionally on separate lines.'),
      '#description' => $this->t('Send notifications to these email addresses. Separate emails with commas or newlines. You may use Twig templating code in this field.'),
    ];

    // Email subject line.
    $form['subject'] = [
      '#type' => 'textfield',
      '#type' => 'textarea',
      '#rows' => 1,
      '#title' => $this->t('Email Subject'),
      '#default_value' => $content_moderation_notification->getSubject(),
      '#required' => TRUE,
      '#maxlength' => 1024,
      '#description' => $this->t('You may use Twig templating code in this field.'),
    ];

    // Email body content.
@@ -199,6 +201,7 @@ class ContentModerationNotificationsFormBase extends EntityForm {
      '#format' => $content_moderation_notification->getMessageFormat() ?: filter_default_format(),
      '#title' => $this->t('Email Body'),
      '#default_value' => $content_moderation_notification->getMessage(),
      '#description' => $this->t('You may use Twig templating code in this field.'),
    ];

    // Add token tree link if module exists.
+35 −7
Original line number Diff line number Diff line
@@ -103,10 +103,7 @@ class Notification implements NotificationInterface {
      $data['langcode'] = $this->currentUser->getPreferredLangcode();
      $data['notification'] = $notification;
      // Setup the email subject and body content.
      $data['params']['subject'] = $notification->getSubject();
      $data['params']['message'] = check_markup($notification->getMessage(), $notification->getMessageFormat());

      // Add the entity as context to aid in token replacement.
      // Add the entity as context to aid in token and Twig replacement.
      if ($this->tokenEntityMapper) {
        $data['params']['context'] = [
          'entity' => $entity,
@@ -122,15 +119,37 @@ class Notification implements NotificationInterface {
        ];
      }

      // Get Subject and process any Twig templating.
      $subject = $notification->getSubject();
      $template = [
        '#type' => 'inline_template',
        '#template' => $subject,
        '#context' => $data['params']['context'],
      ];
      $subject = \Drupal::service('renderer')->renderPlain($template);
      // Remove any newlines from Subject.
      $subject = trim(str_replace("\n", ' ', $subject));
      $data['params']['subject'] = $subject;

      // Get Message, process any Twig templating, and apply input filter.
      $message = $notification->getMessage();
      $template = [
        '#type' => 'inline_template',
        '#template' => $message,
        '#context' => $data['params']['context'],
      ];
      $message = \Drupal::service('renderer')->renderPlain($template);
      $data['params']['message'] = check_markup($message, $notification->getMessageFormat());

      // Figure out who the email should be going to.
      $data['to'] = [];

      // Authors.
      // Get Author.
      if ($notification->author and ($entity instanceof EntityOwnerInterface)) {
        $data['to'][] = $entity->getOwner()->getEmail();
      }

      // Roles.
      // Get Roles.
      foreach ($notification->getRoleIds() as $role) {
        /** @var \Drupal\Core\Entity\EntityStorageInterface $user_storage */
        $user_storage = $this->entityTypeManager->getStorage('user');
@@ -152,7 +171,16 @@ class Notification implements NotificationInterface {
      }

      // Adhoc emails.
      $adhoc_emails = array_map('trim', explode(',', preg_replace("/((\r?\n)|(\r\n?))/", ',', $notification->getEmails())));
      $adhoc_emails = $notification->getEmails();
      $template = [
        '#type' => 'inline_template',
        '#template' => $adhoc_emails,
        '#context' => $data['params']['context'],
      ];
      $adhoc_emails = \Drupal::service('renderer')->renderPlain($template);

      // Split Adhoc emails on commas and newlines.
      $adhoc_emails = array_map('trim', explode(',', preg_replace("/((\r?\n)|(\r\n?))/", ',', $adhoc_emails)));
      foreach ($adhoc_emails as $email) {
        $data['to'][] = $email;
      }
+61 −0
Original line number Diff line number Diff line
@@ -3,6 +3,8 @@
namespace Drupal\Tests\content_moderation_notifications\Kernel;

use Drupal\Component\Render\PlainTextOutput;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
use Drupal\Tests\node\Traits\NodeCreationTrait;
use Drupal\workflows\Entity\Workflow;
@@ -85,4 +87,63 @@ class TokenNotificationsTest extends NotificationsTest {
    $this->assertEquals('Test token replacement ' . $entity->label() . ". Draft | Editorial | Published!\n", $mail['body']);
  }

  /**
   * Test Twig functionality.
   */
  public function testTwig() {
    // Add a text field to the 'article' content type for adhoc email address.
    $field_storage = FieldStorageConfig::create([
      'field_name' => 'adhoc_email',
      'entity_type' => 'node',
      'type' => 'text',
    ]);
    $field_storage->save();
    $field = FieldConfig::create([
      'field_name' => 'adhoc_email',
      'entity_type' => 'node',
      'bundle' => 'article',
      'label' => 'Adhoc email',
    ]);
    $field->save();

    // Add a notification.
    $notification = $this->createNotification([
      'emails' => 'foo@example.com, bar@example.com, {{ entity.adhoc_email.value }}',
      'transitions' => [
        'create_new_draft' => 'create_new_draft',
        'publish' => 'publish',
        'archived_published' => 'archived_published',
      ],
      'body' => [
        'value' => 'Test Twig replacement {{ entity.title.value }}. [content_moderation_notifications:from-state] | [content_moderation_notifications:workflow] | [content_moderation_notifications:to-state]!',
        'format' => 'filtered_html',
      ],
      'subject' => '{{ entity.bundle|title }} with ID {{ entity.id }} Needs review',
    ]);

    $entity = $this->createNode(
      [
        'type' => 'article',
        'adhoc_email' => 'adhoc1@example.com',
      ]
    );

    $this->assertMail('to', 'admin@example.com');
    $this->assertBccRecipients('foo@example.com,bar@example.com,adhoc1@example.com');
    $this->assertMail('id', 'content_moderation_notifications_content_moderation_notification');
    $this->assertMail('subject', 'Article with ID ' . $entity->id() . ' Needs review');
    $this->assertCount(1, $this->getMails());

    // Verify token and Twig replacement in the message body.
    $mail = $this->getMails()[0];
    $this->assertEquals('Test Twig replacement ' . $entity->label() . ". Draft | Editorial | Draft!\n", $mail['body']);

    // Publish.
    $this->container->get('state')->set('system.test_mail_collector', []);
    $entity->moderation_state = 'published';
    $entity->save();
    $mail = $this->getMails()[0];
    $this->assertEquals('Test Twig replacement ' . $entity->label() . ". Draft | Editorial | Published!\n", $mail['body']);
  }

}