bee-8.x-1.1/src/EventSubscriber/OrderEventSubscriber.php

src/EventSubscriber/OrderEventSubscriber.php
<?php

namespace Drupal\bee\EventSubscriber;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\node\Entity\NodeType;
use Drupal\state_machine\Event\WorkflowTransitionEvent;
use RRule\RRule;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Interact with Orders.
 */
class OrderEventSubscriber implements EventSubscriberInterface {

  /**
   * The entity manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * Constructs a new OrderEventSubscriber object.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_manager
   *   The entity manager.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   */
  public function __construct(EntityTypeManagerInterface $entity_manager, ConfigFactoryInterface $config_factory) {
    $this->entityTypeManager = $entity_manager;
    $this->configFactory = $config_factory;
    $this->nodetypeStorage = $this->entityTypeManager->getStorage('node_type');
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents(): array {
    $events = ['commerce_order.place.pre_transition' => 'finalizeCart'];
    return $events;
  }

  /**
   * Finalizes the cart when the order is placed.
   *
   * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event
   *   The workflow transition event.
   */
  public function finalizeCart(WorkflowTransitionEvent $event) {

    $order = $event->getEntity();

    foreach ($order->getItems() as $order_item) {
      if ($order_item->bundle() == 'bee') {
        if ($booking = $order_item->get('field_booking')->entity) {

          $booking_event_reference = $booking->get("booking_event_reference")->target_id;

          if (!isset($booking_event_reference)) {

            $node = $order_item->get('field_node')->entity;

            $start_date = new \DateTime($booking->get('booking_start_date')->value);
            $end_date = new \DateTime($booking->get('booking_end_date')->value);

            $node_type = $this->nodetypeStorage->load($node->bundle());

            assert($node_type instanceof NodeType);
            $bee_settings = $node_type->getThirdPartySetting('bee', 'bee');

            if ($bee_settings['bookable_type'] == 'daily') {
              $booked_state = bat_event_load_state_by_machine_name('bee_daily_booked');
              $event_type = 'availability_daily';
            }
            else {
              $booked_state = bat_event_load_state_by_machine_name('bee_hourly_booked');
              $event_type = 'availability_hourly';
            }

            $events = [];

            $repeat_frequency = $booking->get('booking_repeat_frequency')->value;
            $repeat_until = $booking->get('booking_repeat_until')->value;

            if ($repeat_frequency && $repeat_until) {
              $repeat_until_object = new \DateTime($repeat_until);

              $label = $this->getEventSeriesLabel($node, $bee_settings['bookable_type'], $start_date, $end_date, $repeat_frequency, $repeat_until_object);

              $rrule = new RRule([
                'FREQ' => strtoupper($repeat_frequency),
                'UNTIL' => $repeat_until . 'T235959Z',
              ]);

              $event_series = bat_event_series_create([
                'type' => $event_type,
                'label' => $label,
                'rrule' => $rrule->rfcString(),
              ]);
              $event_dates = [
                'value' => $start_date->format('Y-m-d\TH:i:00'),
                'end_value' => $end_date->format('Y-m-d\TH:i:00'),
              ];
              $event_series->set('event_dates', $event_dates);
              $event_series->set('event_state_reference', $booked_state->id());

              $available_units = $this->getAvailableUnits($node, $start_date, $end_date);

              $event_series->set('event_bat_unit_reference', reset($available_units));

              $event_series->save();

              $booking->set('booking_event_series_reference', $event_series->id());

              $query = $this->entityTypeManager->getStorage('bat_event')->getQuery()
                ->condition('event_series.target_id', $event_series->id());
              $events_created = $query->execute();

              foreach ($events_created as $event_id) {
                $event = bat_event_load($event_id);
                $events[] = $event;
              }
            }
            else {
              $capacity = ($booking->get('booking_capacity')->value) ? ($booking->get('booking_capacity')->value) : 1;

              for ($i = 0; $i < $capacity; $i++) {

                $event = bat_event_create(['type' => $event_type]);
                $event_dates = [
                  'value' => $start_date->format('Y-m-d\TH:i:00'),
                  'end_value' => $end_date->format('Y-m-d\TH:i:00'),
                ];
                $event->set('event_dates', $event_dates);
                $event->set('event_state_reference', $booked_state->id());

                if ($event_series = $booking->get('booking_event_series_reference')->target_id) {
                  $event->set('event_series', $event_series);
                }

                $available_units = $this->getAvailableUnits($node, $start_date, $end_date);

                $event->set('event_bat_unit_reference', reset($available_units));
                $event->save();

                $events[] = $event;
              }
            }
            $booking->set('booking_event_reference', $events);
            $booking->save();
          }
        }
      }
    }
  }

  /**
   * Get available Units.
   *
   * @param object $node
   *   A Node object.
   * @param object $start_date
   *   A DateTime object.
   * @param object $end_date
   *   A DateTime object.
   *
   * @return array
   *   An array.
   */
  protected function getAvailableUnits($node, $start_date, $end_date) {

    $node_type = $this->nodetypeStorage->load($node->bundle());

    $bee_settings = $node_type->getThirdPartySetting('bee', 'bee');

    $units_ids = [];
    foreach ($node->get('field_availability_' . $bee_settings['bookable_type']) as $unit) {
      if ($unit->entity) {
        $units_ids[] = $unit->entity->id();
      }
    }

    $temp_end_date = clone($end_date);
    $temp_end_date->sub(new \DateInterval('PT1M'));

    if ($bee_settings['bookable_type'] == 'daily') {
      $available_units_ids = bat_event_get_matching_units($start_date, $temp_end_date, ['bee_daily_available'], [$bee_settings['type_id']], 'availability_daily');
    }
    else {
      $available_units_ids = bat_event_get_matching_units($start_date, $temp_end_date, ['bee_hourly_available'], [$bee_settings['type_id']], 'availability_hourly');
    }

    return array_intersect($units_ids, $available_units_ids);
  }

  /**
   * Get label for a event Serie.
   *
   * @param object $node
   *   A BEE node.
   * @param string $bookable_type
   *   A string.
   * @param object $start_date
   *   A DateTime object.
   * @param object $end_date
   *   A DateTime object.
   * @param string $repeat_frequency
   *   A string.
   * @param object $repeat_until
   *   A DateTime object.
   *
   * @return string
   *   A string.
   */
  protected function getEventSeriesLabel($node, $bookable_type, $start_date, $end_date, $repeat_frequency, $repeat_until) {
    $frequency = $this->t('Day');
    if ($repeat_frequency == 'weekly') {
      $frequency = $start_date->format('l');
    }
    elseif ($repeat_frequency == 'monthly') {
      $frequency = $this->t('@day of Month', ['@day' => $start_date->format('jS')]);
    }

    if ($bookable_type == 'daily') {
      $label = $this->t('Reservations for @node Every @frequency from @start_date -> @end_date', [
        '@node' => $node->label(),
        '@frequency' => $frequency,
        '@start_date' => $start_date->format('M j Y'),
        '@end_date' => $repeat_until->format('M j Y'),
      ]);
    }
    else {
      $label = $this->t('Reservations for @node Every @frequency from @start_time-@end_time from @start_date -> @end_date', [
        '@node' => $node->label(),
        '@frequency' => $frequency,
        '@start_time' => $start_date->format('gA'),
        '@end_time' => $end_date->format('gA'),
        '@start_date' => $start_date->format('M j Y'),
        '@end_date' => $repeat_until->format('M j Y'),
      ]);
    }

    return $label;
  }

}

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

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