contacts_events-8.x-1.x-dev/modules/teams/src/EventSubscriber/ReferenceSubscriber.php

modules/teams/src/EventSubscriber/ReferenceSubscriber.php
<?php

namespace Drupal\contacts_events_teams\EventSubscriber;

use Drupal\contacts_events\OrderStateTrait;
use Drupal\contacts_events_teams\Entity\TeamApplication;
use Drupal\contacts_references\ReferenceFieldHelper;
use Drupal\contacts_references\ReferenceSender;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\state_machine\Event\WorkflowTransitionEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Event subscriber relating to team ticket and reference states.
 *
 * @package Drupal\contacts_events_teams\EventSubscriber
 */
class ReferenceSubscriber implements EventSubscriberInterface {

  use OrderStateTrait;

  /**
   * Reference field helper.
   *
   * @var \Drupal\contacts_references\ReferenceFieldHelper
   */
  protected $referenceFieldHelper;

  /**
   * Reference email sender.
   *
   * @var \Drupal\contacts_references\ReferenceSender
   */
  protected $sender;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $applicationStorage;

  /**
   * ReferenceSubscriber constructor.
   *
   * @param \Drupal\contacts_references\ReferenceFieldHelper $reference_field_helper
   *   Helper for finding reference fields.
   * @param \Drupal\contacts_references\ReferenceSender $sender
   *   Reference email sender.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct(ReferenceFieldHelper $reference_field_helper, ReferenceSender $sender, EntityTypeManagerInterface $entity_type_manager) {
    $this->referenceFieldHelper = $reference_field_helper;
    $this->sender = $sender;
    $this->applicationStorage = $entity_type_manager->getStorage('c_events_team_app');
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    // When a team applicatiion is submitted, trigger a reference.
    $events['contacts_events_teams_applications.submit.post_transition'][] = ['triggerReferenceRequest'];

    // Check whether the references are already in a submitted/reviewed state.
    $events['contacts_events_teams_applications.submit.post_transition'][] = ['checkReferenceStatesOnSubmission'];

    // When all references are submitted, update the application.
    $events['contacts_reference.submit.post_transition'][] = ['checkApplicationAfterReferencesSubmitted'];

    // When all references have been reviewed (accepted/rejected), update
    // the application.
    $events['contacts_reference.approve.post_transition'][] = ['checkApplicationAfterReferencesReviewed'];
    $events['contacts_reference.reject.post_transition'][] = ['checkApplicationAfterReferencesReviewed'];

    return $events;
  }

  /**
   * Triggers a reference request.
   *
   * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event
   *   Transition event on the team app.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function triggerReferenceRequest(WorkflowTransitionEvent $event) {
    /** @var \Drupal\contacts_events_teams\Entity\TeamApplication $app */
    $app = $event->getEntity();
    /** @var \Drupal\contacts_references\Entity\Reference[] $references */
    $references = $this->referenceFieldHelper->findReferences($app);

    foreach ($references as $reference) {
      // Check to make sure reference is configured.
      // This might be a team transfer and the references may have already been
      // submitted.
      if ($reference && $this->sender->canSendReference($reference)) {
        $this->sender->send($reference);
      }
    }
  }

  /**
   * Checks if references are already received/reviewed on app submission.
   *
   * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event
   *   Transition event on the team app.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function checkReferenceStatesOnSubmission(WorkflowTransitionEvent $event) {
    /** @var \Drupal\contacts_events_teams\Entity\TeamApplication $app */
    $app = $event->getEntity();

    $this->updateApplicationAfterReferencesSubmitted($app);
    $this->updateApplicationAfterReferencesReviewed($app);

    // The above checks will transition and save the team application. If this
    // check is called as part of a team application post transition, it is
    // however already inside a save process and saving it again will clear the
    // $entity->original property.
    // @todo A better way of fixing this would be to add additional transitions
    // and guard them at a form level based on the state of the references.
    $app->original = $this->applicationStorage->loadUnchanged($app->id());
  }

  /**
   * Updates a team appication after all references are submitted.
   *
   * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event
   *   Transition event.
   */
  public function checkApplicationAfterReferencesSubmitted(WorkflowTransitionEvent $event) {
    /** @var \Drupal\contacts_references\Entity\ReferenceInterface $reference */
    $reference = $event->getEntity();
    $app = $reference->getTeamApplication();

    $this->updateApplicationAfterReferencesSubmitted($app);
  }

  /**
   * Updates a team appication after all references are submitted.
   *
   * Once all references on the application have been submitted
   * then transition the submission into references_received state.
   *
   * @param \Drupal\contacts_events_teams\Entity\TeamApplication $app
   *   The team application to update.
   */
  public function updateApplicationAfterReferencesSubmitted(TeamApplication $app) {
    $references = $this->referenceFieldHelper->findReferences($app);
    $has_outstanding = FALSE;

    foreach ($references as $reference) {
      // If a reference has been deleted, we can throw a fatal error here, so
      // we'll check before we do.
      if ($reference) {
        if (!$reference->getSubmittedTime()) {
          $has_outstanding = TRUE;
        }
      }
    }

    // No outstanding references left to submit - transition the application to
    // the received state.
    if (!$has_outstanding) {
      /** @var \Drupal\state_machine\Plugin\Field\FieldType\StateItem $state */
      $state = $app->get('state')->first();
      $this->applyTransitionIfAllowed($state, 'references_received', TRUE);
    }
  }

  /**
   * Updates a team application after all references are reviewed.
   *
   * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event
   *   Transition event.
   */
  public function checkApplicationAfterReferencesReviewed(WorkflowTransitionEvent $event) {
    /** @var \Drupal\contacts_references\Entity\ReferenceInterface $reference */
    $reference = $event->getEntity();
    $app = $reference->getTeamApplication();

    $this->updateApplicationAfterReferencesReviewed($app);
  }

  /**
   * Updates a team application after all references are reviewed.
   *
   * Once all references on the application have been accepted or rejected
   * then transition the submission into references_reviewed state.
   *
   * @param \Drupal\contacts_events_teams\Entity\TeamApplication $app
   *   The team application to update.
   */
  public function updateApplicationAfterReferencesReviewed(TeamApplication $app) {
    $references = $this->referenceFieldHelper->findReferences($app);
    $has_outstanding = FALSE;

    foreach ($references as $reference) {
      $has_been_reviewed = $reference->getApprovedTime() || $reference->getRejectedTime();
      if (!$has_been_reviewed) {
        $has_outstanding = TRUE;
      }
    }

    // No outstanding references left to review. Transition application to the
    // reviewed state.
    if (!$has_outstanding) {
      /** @var \Drupal\state_machine\Plugin\Field\FieldType\StateItem $state */
      $state = $app->get('state')->first();
      $this->applyTransitionIfAllowed($state, 'references_reviewed', TRUE);
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc