contacts_events-8.x-1.x-dev/src/Plugin/Field/FieldWidget/EventDropdown.php

src/Plugin/Field/FieldWidget/EventDropdown.php
<?php

namespace Drupal\contacts_events\Plugin\Field\FieldWidget;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Plugin implementation of 'contacts_events_dropdown'.
 *
 * @FieldWidget(
 *   id = "contacts_events_dropdown",
 *   label = @Translation("Event Dropdown"),
 *   field_types = {
 *     "entity_reference"
 *   }
 * )
 */
class EventDropdown extends WidgetBase implements ContainerFactoryPluginInterface {

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

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

  /**
   * Constructs widget plugin.
   *
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
   *   The definition of the field to which the widget is associated.
   * @param array $settings
   *   The widget settings.
   * @param array $third_party_settings
   *   Any third party settings.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   Entity type manager service.
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The time service.
   */
  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityTypeManagerInterface $entity_type_manager, TimeInterface $time) {
    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);

    $this->entityTypeManager = $entity_type_manager;
    $this->time = $time;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $plugin_id,
      $plugin_definition,
      $configuration['field_definition'],
      $configuration['settings'],
      $configuration['third_party_settings'],
      $container->get('entity_type.manager'),
      $container->get('datetime.time')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $multiple = $this->fieldDefinition->getFieldStorageDefinition()->isMultiple();
    $values = $items->getValue();
    if ($multiple) {
      $default_value = array_column($values, 'target_id');
    }
    else {
      $default_value = !empty($values) && !empty($values[0]['target_id']) ? $values[0]['target_id'] : NULL;
    }

    $user_id = $items->getEntity()->uid->target_id;

    $options = [];
    if ($upcoming = $this->upcomingEvents($user_id)) {
      $options[$this->t('Upcoming events')->render()] = $upcoming;
    }
    if ($last_6_month = $this->previousEvents($user_id, strtotime('-6 months'))) {
      $options[$this->t('Last 6 months')->render()] = $last_6_month;
    }
    if ($last_12_month = $this->previousEvents($user_id, strtotime('-12 months'), strtotime('-6 months'))) {
      $options[$this->t('Last 12 months')->render()] = $last_12_month;
    }

    $element += [
      '#type' => 'select',
      '#title' => $this->t('Event'),
      '#description' => $this->t('Assign this migration to an existing group.'),
      '#options' => $options,
      '#target_type' => $this->getFieldSetting('target_type'),
      '#multiple' => $multiple,
      '#default_value' => $default_value,
      '#required' => $this->fieldDefinition->isRequired(),
    ];

    return ['target_id' => $element];
  }

  /**
   * {@inheritdoc}
   */
  public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
    return $values[0]['target_id'];
  }

  /**
   * {@inheritdoc}
   */
  public static function isApplicable(FieldDefinitionInterface $field_definition) {
    $handler = $field_definition->getSetting('handler');
    return $handler == 'default:contacts_event';
  }

  /**
   * Get a list of upcoming events for #options.
   *
   * @param int|null $user_id
   *   The ID of the user to present previous events for.
   *   Restricts the events to ones the user doesn't have an order for. Use NULL
   *   to get all previous events.
   *
   * @return array
   *   An array of event labels keyed by event id.
   */
  protected function upcomingEvents($user_id = NULL) {
    $request_time = new DrupalDateTime();
    $request_time->setTimestamp($this->time->getRequestTime());

    $query = $this->entityTypeManager->getStorage('contacts_event')->getQuery();
    $query->accessCheck(TRUE);
    $query->condition('date.end_value', $request_time->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT), '>=');
    $query->sort('date.end_value', 'ASC');
    $result = $query->execute();
    $events = $this->entityTypeManager->getStorage('contacts_event')->loadMultiple($result);

    $existing_event_orders = $user_id ? $this->existingOrderEvents($user_id, array_keys($events)) : [];

    $options = [];
    foreach ($events as $event) {
      // If there is already an order for this event and user then do not add
      // it to the options.
      if (empty($existing_event_orders[$event->id()])) {
        $options[$event->id()] = $event->label();
      }
    }

    return $options;
  }

  /**
   * Get a list of previous events for #options.
   *
   * @param int|null $user_id
   *   The ID of the user to present previous events for.
   *   Restricts the events to ones the user doesn't have an order for. Use NULL
   *   to get all previous events.
   * @param int $start_timestamp
   *   Provide the start time that all events must be after.
   * @param int|null $end_timestamp
   *   Optionally provide an end time that all events must be before.
   *
   * @return array
   *   An array of event labels keyed by event id.
   */
  protected function previousEvents($user_id, $start_timestamp, $end_timestamp = NULL) {
    $start_time = new DrupalDateTime();
    $start_time->setTimestamp($start_timestamp);

    if (!$end_timestamp) {
      $end_timestamp = $this->time->getRequestTime();
    }
    $end_time = new DrupalDateTime();
    $end_time->setTimestamp($end_timestamp);

    $query = $this->entityTypeManager->getStorage('contacts_event')->getQuery();
    $query->accessCheck(TRUE);
    $query->condition('date.end_value', $start_time->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT), '>=');
    $query->condition('date.end_value', $end_time->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT), '<=');

    $query->sort('date.end_value', 'DESC');
    $result = $query->execute();
    $events = $this->entityTypeManager->getStorage('contacts_event')->loadMultiple($result);

    $existing_event_orders = $user_id ? $this->existingOrderEvents($user_id, array_keys($events)) : [];

    $options = [];
    foreach ($events as $event) {
      // If there is already an order for this event and user then do not add
      // it to the options.
      if (empty($existing_event_orders[$event->id()])) {
        $options[$event->id()] = $event->label();
      }
    }

    return $options;
  }

  /**
   * Get all the events that a user has existing orders for.
   *
   * @param int $user_id
   *   The ID of the user to get events for.
   * @param array|null $event_ids
   *   Specific event IDs to check if the user has orders for.
   *
   * @return array
   *   An array of order IDs keyed by event ID for the user.
   */
  protected function existingOrderEvents($user_id, $event_ids = NULL) {
    $order_query = $this->entityTypeManager->getStorage('commerce_order')->getQuery();
    $order_query->accessCheck(TRUE);
    $order_query->condition('uid', $user_id);
    $order_query->condition('type', 'contacts_booking');
    if ($event_ids) {
      $order_query->condition('event', $event_ids, 'IN');
    }
    $order_result = $order_query->execute();

    $order_events = [];
    $orders = $this->entityTypeManager->getStorage('commerce_order')->loadMultiple($order_result);
    foreach ($orders as $order) {
      $order_events[$order->get('event')->target_id] = $order->id();
    }

    return $order_events;
  }

}

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

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