View source  
  <?php
namespace Drupal\workbench_email\EventSubscriber;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Queue\QueueFactory;
use Drupal\Core\Session\AccountInterface;
use Drupal\workbench_email\QueuedEmail;
use Drupal\workbench_email\TemplateInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class WorkbenchTransitionEventSubscriber implements EventSubscriberInterface {
  
  protected $entityTypeManager;
  
  protected $currentUser;
  
  protected $queueFactory;
  
  public function __construct(EntityTypeManagerInterface $entity_type_manager, AccountInterface $current_user, QueueFactory $queue_factory) {
    $this->entityTypeManager = $entity_type_manager;
    $this->currentUser = $current_user;
    $this->queueFactory = $queue_factory;
  }
  
  public function onWorkbenchModerationTransition($event) {
    $entity = $event
      ->getEntity();
    
    $bundle_entity = $this->entityTypeManager
      ->getStorage($entity
      ->getEntityType()
      ->getBundleEntityType())
      ->load($entity
      ->bundle());
    if (!$event
      ->getStateBefore()) {
      
      $from = $bundle_entity
        ->getThirdPartySetting('workbench_moderation', 'default_moderation_state', FALSE);
    }
    else {
      $from = $event
        ->getStateBefore();
    }
    $to = $event
      ->getStateAfter();
    
    if ($transitions = $this->entityTypeManager
      ->getStorage('moderation_state_transition')
      ->loadByProperties([
      'stateFrom' => $from,
      'stateTo' => $to,
    ])) {
      
      $transitions = array_filter($transitions, function ($transition) {
        
        return $this->currentUser
          ->hasPermission(sprintf('use %s transition', $transition
          ->id())) && $transition
          ->getThirdPartySetting('workbench_email', 'workbench_email_templates', []);
      });
      if (!$transitions) {
        
        return;
      }
      
      $transition = reset($transitions);
      
      $queue = $this->queueFactory
        ->get('workbench_email_send' . PluginBase::DERIVATIVE_SEPARATOR . $entity
        ->getEntityTypeId());
      
      foreach ($this->entityTypeManager
        ->getStorage('workbench_email_template')
        ->loadMultiple($transition
        ->getThirdPartySetting('workbench_email', 'workbench_email_templates', [])) as $template) {
        if ($template
          ->getBundles() && !in_array($entity
          ->getEntityTypeId() . ':' . $entity
          ->bundle(), $template
          ->getBundles(), TRUE)) {
          
          continue;
        }
        foreach ($this
          ->prepareRecipients($entity, $template) as $to) {
          $queue
            ->createItem(new QueuedEmail($template, $entity
            ->uuid(), $to));
        }
      }
    }
  }
  
  public function onContentModerationTransition($event) {
    $entity = $event
      ->getModeratedEntity();
    
    $workflow = $this->entityTypeManager
      ->getStorage('workflow')
      ->load($event
      ->getWorkflow());
    
    $type_plugin = $workflow
      ->getTypePlugin();
    if (!$event
      ->getOriginalState()) {
      $from = $type_plugin
        ->getInitialState($entity)
        ->id();
    }
    else {
      $from = $event
        ->getOriginalState();
    }
    $to = $event
      ->getNewState();
    $templates = $workflow
      ->getThirdPartySetting('workbench_email', 'workbench_email_templates', []);
    try {
      $transition = $type_plugin
        ->getTransitionFromStateToState($from, $to);
    } catch (\InvalidArgumentException $e) {
      
      return;
    }
    
    if (!isset($templates[$transition
      ->id()])) {
      return;
    }
    
    $queue = $this->queueFactory
      ->get('workbench_email_send' . PluginBase::DERIVATIVE_SEPARATOR . $entity
      ->getEntityTypeId());
    
    foreach ($this->entityTypeManager
      ->getStorage('workbench_email_template')
      ->loadMultiple($templates[$transition
      ->id()]) as $template) {
      if ($template
        ->getBundles() && !in_array($entity
        ->getEntityTypeId() . ':' . $entity
        ->bundle(), $template
        ->getBundles(), TRUE)) {
        
        continue;
      }
      foreach ($this
        ->prepareRecipients($entity, $template) as $to) {
        $queue
          ->createItem(new QueuedEmail($template, $entity
          ->uuid(), $to));
      }
    }
  }
  
  public static function getSubscribedEvents() {
    return [
      'workbench_moderation.state_transition' => 'onWorkbenchModerationTransition',
      'content_moderation.state_changed' => 'onContentModerationTransition',
    ];
  }
  
  protected function prepareRecipients(ContentEntityInterface $entity, TemplateInterface $template) {
    return $template
      ->getRecipients($entity);
  }
}