contacts_events-8.x-1.x-dev/src/Cron/BookingWindowCronBase.php

src/Cron/BookingWindowCronBase.php
<?php

namespace Drupal\contacts_events\Cron;

use Drupal\Component\Datetime\Time;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\State\StateInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;

/**
 * A base class for performing actions based on booking window transistions.
 */
abstract class BookingWindowCronBase extends CronBase {

  /**
   * Event entity storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $eventStorage;

  /**
   * The entity field manager.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected $entityFieldManager;

  /**
   * An offset to apply when checking booking windows.
   *
   * A positive offset will mean the action is performed that interval before
   * the deadline change.
   *
   * @var \DateInterval|null
   */
  protected $dateOffset;

  /**
   * Construct the booking window transition cron base class.
   *
   * @param \Drupal\Core\State\StateInterface $state
   *   The state service.
   * @param \Drupal\Component\Datetime\Time $time
   *   The time service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
   *   The entity field manager.
   *
   * @throws \Exception
   *   Thrown if the STATE_LAST_RUN constant is not set.
   */
  public function __construct(StateInterface $state, Time $time, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager) {
    parent::__construct($state, $time);
    $this->eventStorage = $entity_type_manager->getStorage('contacts_event');
    $this->entityFieldManager = $entity_field_manager;
  }

  /**
   * {@inheritdoc}
   *
   * @todo Refactor this so multiple order item types get handle as one action.
   */
  protected function doInvoke() {
    // Get the booking window fields and the order item types they affect.
    $window_fields = [];
    $field_map = $this->entityFieldManager->getFieldMapByFieldType('price_map');
    if (isset($field_map['contacts_event'])) {
      foreach ($field_map['contacts_event'] as $field_name => $field_info) {
        foreach ($field_info['bundles'] as $bundle) {
          $definition = $this->entityFieldManager
            ->getFieldDefinitions('contacts_event', $bundle)[$field_name];
          if ($window_field = $definition->getSetting('booking_window_field')) {
            $window_definition = $this->entityFieldManager
              ->getFieldDefinitions('contacts_event', $bundle)[$window_field];
            $order_item_type = $definition->getSetting('order_item_type');
            $window_fields[$window_field][$order_item_type] = $window_definition->getSetting('datetime_type');
          }
        }
      }
    }

    // If we have no fields, there's nothing to do.
    if (empty($window_fields)) {
      return;
    }

    // Look for any events which have passed a booking window.
    $now = $this->getCurrentTime();
    $last_run = $this->getLastRunTime();

    // Apply an offset if there is one.
    if ($this->dateOffset) {
      $now->add($this->dateOffset);

      if ($last_run) {
        $last_run->add($this->dateOffset);
      }
    }

    foreach ($window_fields as $field_name => $order_item_types) {
      foreach ($order_item_types as $order_item_type => $date_type) {
        $query = $this->eventStorage->getQuery();
        $query->accessCheck(FALSE);

        // Get the database date format.
        if ($date_type == DateTimeItem::DATETIME_TYPE_DATE) {
          $format = DateTimeItemInterface::DATE_STORAGE_FORMAT;
        }
        else {
          $format = DateTimeItemInterface::DATETIME_STORAGE_FORMAT;
        }

        // Put the two cut off checks in an OR condition group.
        $or = $query->orConditionGroup();
        $query->condition($or);
        $cut_off_condition = $query->andConditionGroup();
        $or->condition($cut_off_condition);
        $cut_off_confirmed_condition = $query->andConditionGroup();
        $or->condition($cut_off_confirmed_condition);

        // Check the cut off is before now.
        $cut_off_condition->condition("{$field_name}.cut_off", $now->format($format), '<');
        $cut_off_confirmed_condition->condition("{$field_name}.cut_off_confirmed", $now->format($format), '<');

        // If we have a last run, only look more recent than that.
        if ($last_run) {
          $cut_off_condition->condition("{$field_name}.cut_off", $last_run->format($format), '>=');
          $cut_off_confirmed_condition->condition("{$field_name}.cut_off_confirmed", $last_run->format($format), '>=');
        }

        // Queue up any orders for recalculation.
        $event_ids = $query->execute();
        if (!empty($event_ids)) {
          $this->runActionsForEvents($event_ids, [$order_item_type]);
        }
      }
    }
  }

  /**
   * Run the actions for given events/order item types.
   *
   * @param int[] $event_ids
   *   An array of event IDs to perform an action for.
   * @param string[] $order_item_types
   *   The order item types the action is relevant for.
   */
  abstract protected function runActionsForEvents(array $event_ids, array $order_item_types): void;

}

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

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