contacts_events-8.x-1.x-dev/src/EventSubscriber/BookingConfirmedSubscriber.php

src/EventSubscriber/BookingConfirmedSubscriber.php
<?php

namespace Drupal\contacts_events\EventSubscriber;

use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\contacts_events\OrderEventTransitionTrait;
use Drupal\contacts_events\OrderItemStateTrait;
use Drupal\contacts_events\OrderStateTrait;
use Drupal\state_machine\Event\WorkflowTransitionEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Event subscriber for booking confirmation.
 */
class BookingConfirmedSubscriber implements EventSubscriberInterface {

  use OrderStateTrait;
  use OrderItemStateTrait;
  use OrderEventTransitionTrait;

  /**
   * The time.
   *
   * @var \Drupal\Component\Datetime\TimeInterface
   */
  protected $time;

  /**
   * The event dispatcher.
   *
   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
   */
  protected $eventDispatcher;

  /**
   * Constructs a new TimestampEventSubscriber object.
   *
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The time service.
   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
   *   The event dispatcher service.
   */
  public function __construct(TimeInterface $time, EventDispatcherInterface $event_dispatcher) {
    $this->time = $time;
    $this->eventDispatcher = $event_dispatcher;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    // phpcs:disable Drupal.Arrays.Array.LongLineDeclaration
    // Confirming line items should be the very first step before transitioning.
    $events['commerce_order.place.pre_transition'][] = ['confirmLineItems', 500];

    // Set the confirmed time of line items.
    $events['contacts_events_order_items.confirm.pre_transition'][] = ['setConfirmedTime', 0];

    // Override the line items booking window to prevent recalculation changes.
    $events['contacts_events_order_items.paid_in_full.pre_transition'][] = ['setBookingWindowOverridden', 0];

    // Make sure confirmed_paid_in_full triggers additional events.
    $events['commerce_order.confirmed_paid_in_full.pre_transition'][] = ['fireOrderConfirmedPaidInFullAdditionalEvents', -999];
    $events['commerce_order.confirmed_paid_in_full.post_transition'][] = ['fireOrderConfirmedPaidInFullAdditionalEvents', 90];
    $events['contacts_events_order_items.confirmed_paid_in_full.pre_transition'][] = ['fireOrderItemConfirmedPaidInFullAdditionalEvents', -999];
    $events['contacts_events_order_items.confirmed_paid_in_full.post_transition'][] = ['fireOrderItemConfirmedPaidInFullAdditionalEvents', 90];

    // phpcs:enable
    return $events;
  }

  /**
   * Check whether this subscriber applies to the event.
   *
   * @param \Drupal\commerce_order\Entity\OrderInterface $order
   *   The order we are checking.
   *
   * @return bool
   *   Whether this subscriber applies to the given order.
   */
  protected function applies(OrderInterface $order) {
    return $order->bundle() == 'contacts_booking';
  }

  /**
   * Fire the additional pre transition events for paid in full and combined.
   *
   * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event
   *   The confirm transition event.
   * @param string $event_name
   *   The event name.
   */
  public function fireOrderConfirmedPaidInFullAdditionalEvents(WorkflowTransitionEvent $event, $event_name) {
    /** @var \Drupal\commerce_order\Entity\OrderInterface $entity */
    $entity = $event->getEntity();

    if (!$this->applies($entity)) {
      return;
    }

    // We have skipped the place and paid_in_full steps so trigger any events
    // that we may have missed.
    $event_parts = explode('.', $event_name);
    $phase = $event_parts[2];
    $this->dispatchTransitionEvent('place', $phase, $event, $entity);
    $this->dispatchTransitionEvent('paid_in_full', $phase, $event, $entity);
  }

  /**
   * Fire the additional post transition events for confirmed and paid in full.
   *
   * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event
   *   The confirmed_paid_in_full transition event.
   * @param string $event_name
   *   The event name.
   */
  public function fireOrderItemConfirmedPaidInFullAdditionalEvents(WorkflowTransitionEvent $event, $event_name) {
    /** @var \Drupal\commerce_order\Entity\OrderItemInterface $entity */
    $entity = $event->getEntity();
    /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
    $order = $entity->getOrder();

    if (!$this->applies($order)) {
      return;
    }

    // We have skipped the confirm and paid_in_full steps so trigger any events
    // that we may have missed.
    $event_parts = explode('.', $event_name);
    $phase = $event_parts[2];
    $this->dispatchTransitionEvent('confirm', $phase, $event, $entity);
    $this->dispatchTransitionEvent('paid_in_full', $phase, $event, $entity);
  }

  /**
   * Sets the order item's confirmed timestamp.
   *
   * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event
   *   The transition event.
   */
  public function setConfirmedTime(WorkflowTransitionEvent $event) {
    /** @var \Drupal\commerce_order\Entity\OrderItemInterface $item */
    $item = $event->getEntity();
    if ($this->applies($item->getOrder()) && $item->hasField('confirmed') && $item->get('confirmed')->isEmpty()) {
      $item->set('confirmed', $this->time->getRequestTime());
    }
  }

  /**
   * Sets the order item's booking window on payment.
   *
   * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event
   *   The transition event.
   */
  public function setBookingWindowOverridden(WorkflowTransitionEvent $event) {
    /** @var \Drupal\commerce_order\Entity\OrderItemInterface $item */
    $item = $event->getEntity();
    if ($this->applies($item->getOrder()) && $item->hasField('mapped_price')) {
      $item->get('mapped_price')->first()->set('booking_window_overridden', 1);
    }
  }

  /**
   * Confirm any line items when a booking is confirmed.
   *
   * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event
   *   The transition event.
   */
  public function confirmLineItems(WorkflowTransitionEvent $event) {
    /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
    $order = $event->getEntity();

    if (!$this->applies($order)) {
      return;
    }

    foreach ($order->getItems() as $item) {
      // Ignore any order items that are not stateful.
      if (!$item->hasField('state')) {
        continue;
      }

      /** @var \Drupal\state_machine\Plugin\Field\FieldType\StateItem $state */
      $state = $item->get('state')->first();

      // Start by confirming the item, without saving.
      $save = $this->applyTransitionIfAllowed($state, 'confirm');

      // Next check whether it can be moved to paid in full.
      $save = $this->checkOrderItemStatus($item) || $save;

      // Save if we have made any change.
      if ($save) {
        $item->save();
      }
    }
  }

}

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

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