Commit 7163d259 authored by Vitaliy Marchuk's avatar Vitaliy Marchuk Committed by Ryan Szrama
Browse files

Issue #3145846 by marchuk.vitaliy, rszrama: Support adding additional token...

Issue #3145846 by marchuk.vitaliy, rszrama: Support adding additional token types to email token replacement
parent 9a34f812
Loading
Loading
Loading
Loading
+19 −11
Original line number Diff line number Diff line
@@ -39,19 +39,26 @@ class EmailSender implements EmailSenderInterface {
  /**
   * {@inheritDoc}
   */
  public function send(EmailInterface $email, ContentEntityInterface $entity) {
  public function send(EmailInterface $email, ContentEntityInterface $entity, array $related_entities = []) {
    $entity_type_id = $entity->getEntityTypeId();
    $event_entity_type_id = $email->getEvent()->getEntityTypeId();
    if ($entity_type_id != $event_entity_type_id) {
      throw new \InvalidArgumentException(sprintf('The email requires a "%s" entity, but a "%s" entity was given.', $event_entity_type_id, $entity_type_id));
    }

    // An array of keyed entities used to replace tokens.
    $replacements = [$entity_type_id => $entity];
    if (!empty($related_entities)) {
      $related_entity_type_ids = $email->getEvent()->getRelatedEntityTypeIds();
      $replacements = array_merge($replacements, array_combine($related_entity_type_ids, $related_entities));
    }

    $short_entity_type_id = str_replace('commerce_', '', $entity_type_id);
    $to = $this->replaceTokens($email->getTo(), $entity);
    $subject = $this->replaceTokens($email->getSubject(), $entity);
    $to = $this->replaceTokens($email->getTo(), $replacements);
    $subject = $this->replaceTokens($email->getSubject(), $replacements);
    $body = [
      '#type' => 'inline_template',
      '#template' => $this->replaceTokens($email->getBody(), $entity),
      '#template' => $this->replaceTokens($email->getBody(), $replacements),
      '#context' => [
        $short_entity_type_id => $entity,
      ],
@@ -59,9 +66,9 @@ class EmailSender implements EmailSenderInterface {
    // @todo Figure out how to get the langcode generically.
    $params = [
      'id' => 'commerce_email_' . $email->id(),
      'from' => $this->replaceTokens($email->getFrom(), $entity),
      'cc' => $this->replaceTokens($email->getCc(), $entity),
      'bcc' => $this->replaceTokens($email->getBcc(), $entity),
      'from' => $this->replaceTokens($email->getFrom(), $replacements),
      'cc' => $this->replaceTokens($email->getCc(), $replacements),
      'bcc' => $this->replaceTokens($email->getBcc(), $replacements),
    ];

    return $this->mailHandler->sendMail($to, $subject, $body, $params);
@@ -72,16 +79,17 @@ class EmailSender implements EmailSenderInterface {
   *
   * @param string $value
   *   The value.
   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
   *   The entity to use for token replacements.
   * @param array $replacements
   *   An array of keyed entities.
   *
   * @return string
   *   The value with tokens replaced.
   */
  protected function replaceTokens($value, ContentEntityInterface $entity) {
  protected function replaceTokens(string $value, array $replacements) {
    if (!empty($value)) {
      $value = $this->token->replace($value, [$entity->getEntityTypeId() => $entity]);
      $value = $this->token->replace($value, $replacements);
    }

    return $value;
  }

+3 −1
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@ interface EmailSenderInterface {
   *   The email.
   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
   *   The entity.
   * @param \Drupal\Core\Entity\ContentEntityInterface[] $related_entities
   *   The related entities.
   *
   * @return bool
   *   TRUE if the email was sent successfully, FALSE otherwise.
@@ -21,6 +23,6 @@ interface EmailSenderInterface {
   * @throws \InvalidArgumentException
   *   Thrown when given an entity that doesn't match the email event.
   */
  public function send(EmailInterface $email, ContentEntityInterface $entity);
  public function send(EmailInterface $email, ContentEntityInterface $entity, array $related_entities = []);

}
+13 −3
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

namespace Drupal\commerce_email\EventSubscriber;

use Drupal\commerce\EntityHelper;
use Drupal\commerce_email\EmailEventManager;
use Drupal\commerce_email\EmailSenderInterface;
use Drupal\commerce_email\Entity\EmailInterface;
@@ -134,7 +135,8 @@ class EmailSubscriber implements EventSubscriberInterface {
      if ($email_event->getEventName() == $event_name) {
        $entity = $email_event->extractEntityFromEvent($event);
        if ($email->applies($entity)) {
          $this->sendEmail($email, $entity);
          $related_entities = $email_event->extractRelatedEntitiesFromEvent($event);
          $this->sendEmail($email, $entity, $related_entities);
        }
      }
    }
@@ -147,13 +149,21 @@ class EmailSubscriber implements EventSubscriberInterface {
   *   The email.
   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
   *   The entity.
   * @param \Drupal\Core\Entity\ContentEntityInterface[] $related_entities
   *   The related entities.
   */
  protected function sendEmail(EmailInterface $email, ContentEntityInterface $entity) {
  protected function sendEmail(EmailInterface $email, ContentEntityInterface $entity, array $related_entities = []) {
    if ($email->shouldQueue()) {
      if (!empty($related_entities)) {
        $related_entity_type_ids = $email->getEvent()->getRelatedEntityTypeIds();
        $related_entity_ids = EntityHelper::extractIds($related_entities);
        $related_entities = array_combine($related_entity_type_ids, $related_entity_ids);
      }
      $queue_item = [
        'email_id' => $email->id(),
        'entity_id' => $entity->id(),
        'entity_type_id' => $entity->getEntityTypeId(),
        'related_entities' => $related_entities,
      ];
      if ($this->moduleHandler->moduleExists('advancedqueue')) {
        $queue_storage = $this->entityTypeManager->getStorage('advancedqueue_queue');
@@ -167,7 +177,7 @@ class EmailSubscriber implements EventSubscriberInterface {
      }
    }
    else {
      $this->emailSender->send($email, $entity);
      $this->emailSender->send($email, $entity, $related_entities);
    }
  }

+8 −7
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ class EmailForm extends EntityForm {
    /** @var \Drupal\commerce_email\Plugin\Commerce\EmailEvent\EmailEventInterface $event */
    $event = $this->emailEventManager->createInstance($selected_event_id);
    $target_entity_type_id = $event->getEntityTypeId();
    $token_types = array_merge([$target_entity_type_id], $event->getRelatedEntityTypeIds());

    // These addresses can't use the "email" element type because they
    // might contain tokens (which wouldn't pass validation).
@@ -107,7 +108,7 @@ class EmailForm extends EntityForm {
      '#default_value' => $email->getFrom(),
      '#required' => TRUE,
      '#element_validate' => ['token_element_validate'],
      '#token_types' => [$target_entity_type_id],
      '#token_types' => $token_types,
    ];
    $form['to'] = [
      '#type' => 'textfield',
@@ -116,7 +117,7 @@ class EmailForm extends EntityForm {
      '#default_value' => $email->getTo(),
      '#required' => TRUE,
      '#element_validate' => ['token_element_validate'],
      '#token_types' => [$target_entity_type_id],
      '#token_types' => $token_types,
    ];
    $form['cc'] = [
      '#type' => 'textfield',
@@ -124,7 +125,7 @@ class EmailForm extends EntityForm {
      '#maxlength' => 255,
      '#default_value' => $email->getCc(),
      '#element_validate' => ['token_element_validate'],
      '#token_types' => [$target_entity_type_id],
      '#token_types' => $token_types,
    ];
    $form['bcc'] = [
      '#type' => 'textfield',
@@ -132,7 +133,7 @@ class EmailForm extends EntityForm {
      '#maxlength' => 255,
      '#default_value' => $email->getBcc(),
      '#element_validate' => ['token_element_validate'],
      '#token_types' => [$target_entity_type_id],
      '#token_types' => $token_types,
    ];
    $form['subject'] = [
      '#type' => 'textfield',
@@ -141,7 +142,7 @@ class EmailForm extends EntityForm {
      '#default_value' => $email->getSubject(),
      '#required' => TRUE,
      '#element_validate' => ['token_element_validate'],
      '#token_types' => [$target_entity_type_id],
      '#token_types' => $token_types,
    ];
    $form['body'] = [
      '#type' => 'textarea',
@@ -150,7 +151,7 @@ class EmailForm extends EntityForm {
      '#rows' => 10,
      '#required' => TRUE,
      '#element_validate' => ['token_element_validate'],
      '#token_types' => [$target_entity_type_id],
      '#token_types' => $token_types,
    ];
    $form['queue'] = [
      '#type' => 'checkbox',
@@ -160,7 +161,7 @@ class EmailForm extends EntityForm {
    ];
    $form['token_help'] = [
      '#theme' => 'token_tree_link',
      '#token_types' => [$target_entity_type_id],
      '#token_types' => $token_types,
    ];

    $form['conditions'] = [
+22 −8
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ class TestEmailForm extends FormBase {
    // Get the target entity type ID and definition.
    $target_entity_type_id = $commerce_email->getTargetEntityTypeId();
    $target_entity_type = $this->entityTypeManager->getDefinition($target_entity_type_id);
    $token_types = array_merge([$target_entity_type_id], $commerce_email->getEvent()->getRelatedEntityTypeIds());

    // Prompt the user to supply the variables derived from the event context.
    $form['context'] = [
@@ -80,9 +81,16 @@ class TestEmailForm extends FormBase {
      '#type' => 'entity_autocomplete',
      '#target_type' => $target_entity_type_id,
      '#title' => $target_entity_type->getLabel(),
      '#description' => $this->t('Reference the entity to use for token replacement in this email.'),
      '#description' => $this->t('Reference the primary entity to use for token replacement in this email.'),
    ];

    // Test emails do not currently support related entity tokens. Only show a
    // notice if the email event actually uses them.
    // @see https://www.drupal.org/project/commerce_email/issues/3300087
    if (!empty($commerce_email->getEvent()->getRelatedEntityTypeIds())) {
      $form['context']['target_entity']['#description'] .= '<br />' . $this->t('Note: related entity tokens are <a href="https://www.drupal.org/project/commerce_email/issues/3300087">not currently replaced</a> in test emails.');
    }

    // Allow the user to override the default settings of this email.
    $form['from'] = [
      '#type' => 'textfield',
@@ -91,7 +99,7 @@ class TestEmailForm extends FormBase {
      '#default_value' => $commerce_email->getFrom(),
      '#required' => TRUE,
      '#element_validate' => ['token_element_validate'],
      '#token_types' => [$target_entity_type_id],
      '#token_types' => $token_types,
    ];
    $form['to'] = [
      '#type' => 'textfield',
@@ -100,7 +108,7 @@ class TestEmailForm extends FormBase {
      '#default_value' => $commerce_email->getTo(),
      '#required' => TRUE,
      '#element_validate' => ['token_element_validate'],
      '#token_types' => [$target_entity_type_id],
      '#token_types' => $token_types,
    ];
    $form['cc'] = [
      '#type' => 'textfield',
@@ -108,7 +116,7 @@ class TestEmailForm extends FormBase {
      '#maxlength' => 255,
      '#default_value' => $commerce_email->getCc(),
      '#element_validate' => ['token_element_validate'],
      '#token_types' => [$target_entity_type_id],
      '#token_types' => $token_types,
    ];
    $form['bcc'] = [
      '#type' => 'textfield',
@@ -116,7 +124,7 @@ class TestEmailForm extends FormBase {
      '#maxlength' => 255,
      '#default_value' => $commerce_email->getBcc(),
      '#element_validate' => ['token_element_validate'],
      '#token_types' => [$target_entity_type_id],
      '#token_types' => $token_types,
    ];
    $form['subject'] = [
      '#type' => 'textfield',
@@ -125,7 +133,7 @@ class TestEmailForm extends FormBase {
      '#default_value' => '[TEST] ' . $commerce_email->getSubject(),
      '#required' => TRUE,
      '#element_validate' => ['token_element_validate'],
      '#token_types' => [$target_entity_type_id],
      '#token_types' => $token_types,
    ];
    $form['body'] = [
      '#type' => 'textarea',
@@ -134,9 +142,14 @@ class TestEmailForm extends FormBase {
      '#rows' => 10,
      '#required' => TRUE,
      '#element_validate' => ['token_element_validate'],
      '#token_types' => [$target_entity_type_id],
      '#token_types' => $token_types,
    ];
    $form['token_help'] = [
      '#theme' => 'token_tree_link',
      '#token_types' => $token_types,
    ];

    $form['actions'] = ['#type' => 'actions'];
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => 'Test email',
@@ -164,8 +177,9 @@ class TestEmailForm extends FormBase {
    $commerce_email->setBody($values['body']);

    // Send the email using the referenced entity.
    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
    $entity = $this->entityTypeManager->getStorage($commerce_email->getTargetEntityTypeId())->load($form_state->getValue('target_entity'));
    $this->emailSender->send($commerce_email, $entity);
    $this->emailSender->send($commerce_email, $entity, []);

    $this->messenger()->addMessage($this->t('Test email sent.'));
  }
Loading