contacts_events-8.x-1.x-dev/modules/contacts_events_segments/contacts_events_segments.module

modules/contacts_events_segments/contacts_events_segments.module
<?php

/**
 * @file
 * Contains contacts_events_segments.module.
 */

use Drupal\Component\Render\FormattableMarkup;
use Drupal\contacts_events\Entity\EventInterface;
use Drupal\contacts_events\Entity\EventType;
use Drupal\contacts_events\Entity\Ticket;
use Drupal\contacts_events\Entity\TicketInterface;
use Drupal\contacts_events_segments\Entity\Segment;
use Drupal\contacts_events_segments\Entity\SegmentInterface;
use Drupal\contacts_events_segments\PreRenderCallbacks;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;

/**
 * Implements hook_entity_extra_field_info().
 */
function contacts_events_segments_entity_extra_field_info() {
  $extra = [];

  foreach (EventType::loadMultiple() as $bundle) {
    $extra['contacts_event'][$bundle->id()]['form']['segments'] = [
      'label' => new TranslatableMarkup('Day tickets'),
      'visible' => FALSE,
    ];
  }

  return $extra;
}

/**
 * Implements hook_form_BASE_FORM_ID_alter() for contacts_events_form.
 */
function contacts_events_segments_form_contacts_event_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  /** @var \Drupal\Core\Entity\ContentEntityFormInterface $form_object */
  $form_object = $form_state->getFormObject();
  $form_display = $form_object->getFormDisplay($form_state);
  if ($form_display->getComponent('segments')) {
    $event = $form_object->getEntity();
    $form['segments'] = [
      '#type' => 'container',
    ];
    $form['segments']['segments'] = [
      '#type' => 'radios',
      '#title' => new TranslatableMarkup('Does this event have day tickets?'),
      // phpcs:ignore Drupal.Arrays.Array.LongLineDeclaration
      '#parents' => array_merge($form['#parents'] ?? [], ['settings', 'segments']),
      '#options' => [
        EventInterface::STATUS_OPEN => new TranslatableMarkup('Open for bookings'),
        EventInterface::STATUS_CLOSED => new TranslatableMarkup('Closed for new tickets'),
        EventInterface::STATUS_DISABLED => new TranslatableMarkup('Day tickets disabled'),
      ],
      '#default_value' => $event->getSetting('segments', EventInterface::STATUS_DISABLED),
      EventInterface::STATUS_OPEN => [
        '#description' => new TranslatableMarkup('The public can add and confirm enabled day tickets.'),
      ],
      EventInterface::STATUS_CLOSED => [
        '#description' => new TranslatableMarkup('Only staff can add or confirm new day tickets.'),
      ],
      EventInterface::STATUS_DISABLED => [
        '#description' => new TranslatableMarkup('Day tickets and configuration are disabled for this event.'),
      ],
    ];
    foreach ($form['segments']['segments']['#options'] as $value => $title) {
      $form['segments']['segments'][$value]['#title'] = new FormattableMarkup('<strong>@title</strong>', [
        '@title' => $title,
      ]);
    }
  }
}

/**
 * Allowed values callback for the segment day field.
 *
 * @see \callback_allowed_values_function()
 */
function contacts_events_segments_segment_day_options(FieldStorageDefinitionInterface $definition, FieldableEntityInterface $entity = NULL, &$cacheable = TRUE) {
  if (!$entity) {
    return [];
  }

  $cacheable = FALSE;

  // We can't handle values for non-events.
  if (!$entity instanceof SegmentInterface) {
    return [];
  }

  $event = $entity->getEvent();
  $options = [];
  /** @var \Drupal\Core\Datetime\DrupalDateTime|null $date */
  $date = clone $event->get('date')->start_date;
  if (!$date) {
    return [];
  }
  $date->setTime(0, 0, 0);

  /** @var \Drupal\Core\Datetime\DrupalDateTime|null $end */
  $end = $event->get('date')->end_date;
  do {
    $options[] = $date->format('D j F');
    $date->add(new DateInterval('P1D'));
  } while ($end && $end->getTimestamp() > $date->getTimestamp());
  return $options;
}

/**
 * Implements hook_field_widget_WIDGET_TYPE_form_alter().
 */
function contacts_events_segments_field_widget_options_buttons_form_alter(&$element, FormStateInterface $form_state, $context) {
  /** @var \Drupal\Core\Field\FieldItemListInterface $items */
  $items = $context['items'];
  /** @var \Drupal\Core\Field\FieldDefinitionInterface $field_definition */
  $field_definition = $items->getFieldDefinition();
  if ($field_definition->getTargetEntityTypeId() !== 'contacts_ticket' || $field_definition->getName() !== 'segments') {
    return;
  }

  $ticket = $items->getEntity();
  if (!$ticket instanceof TicketInterface || !$ticket->get('event')->target_id) {
    return;
  }

  /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $field_manager */
  $field_manager = \Drupal::service('entity_field.manager');
  $fields = $field_manager->getFieldDefinitions('contacts_event_segment', 'contacts_event_segment');
  if (isset($fields['day']) && isset($fields['part'])) {
    /** @var \Drupal\contacts_events_segments\Entity\SegmentInterface $entity */
    $entity = Segment::create(['event' => $ticket->get('event')->target_id]);
    $element['#segment_parts'] = $fields['part']->getFieldStorageDefinition()->getOptionsProvider('value', $entity)->getPossibleOptions();
    $element['#segment_days'] = $fields['day']->getFieldStorageDefinition()->getOptionsProvider('value', $entity)->getPossibleOptions();
    $element['#pre_render'][] = [
      PreRenderCallbacks::class,
      'preRenderSegmentsTicketEventSegmentsCheckboxTable',
    ];
  }
}

/**
 * Implements hook_contacts_events_ticket_form_alter().
 */
function contacts_events_segments_contacts_events_ticket_form_alter(array &$form, FormStateInterface $form_state, Ticket $ticket, string $display_mode) {
  if (!isset($form['segments'])) {
    return;
  }

  /** @var \Drupal\contacts_events_segments\Access\SegmentsAccessChecker $access */
  $access = Drupal::service('access_check._contacts_events_segments._contacts_events_segments');

  // Do not render the day tickets UI if day tickets are disabled
  // of if they're closed and the user is not staff.
  if (!$access->bookingAccess($ticket->getEvent())) {
    $form['segments']['#access'] = FALSE;
    return;
  }

  // Add a header.
  $form['segments_heading'] = [
    '#type' => 'html_tag',
    '#tag' => 'h3',
    '#weight' => $form['segments']['#weight'] - 0.2,
    '#value' => $form['segments']['widget']['#title'],
  ];
  $form['segments']['widget']['#title_display'] = 'none';

  // Add a checkbox.
  $form['segments_enabled'] = [
    '#type' => 'checkbox',
    '#title' => new TranslatableMarkup('This person only wants day tickets'),
    '#description' => new TranslatableMarkup('Day tickets do not grant overnight access to the site or accommodation.'),
    '#default_value' => !empty($form['segments']['widget']['#default_value']),
    '#weight' => $form['segments']['#weight'] - 0.1,
  ];

  // Make the main widget dependent on the checkbox.
  $parents = $form['#parents'] ?? [];
  $parents[] = 'segments_enabled';
  $name = array_shift($parents);
  if ($parents) {
    $name = $name . '[' . implode('][', $parents) . ']';
  }
  $form['segments']['#states']['visible'] = [
    ':input[name="' . $name . '"]' => ['checked' => TRUE],
  ];

  // Register the segments fields to trigger a price update.
  /** @var \Drupal\contacts_events\Element\AjaxUpdate $price_updater */
  $price_updater = $form['price_update']['#element'];
  $price_updater->registerElementToRespondTo($form['segments']['widget']);
}

/**
 * Implements hook_views_data_alter().
 */
function contacts_events_segments_views_data_alter(array &$data) {
  $data['contacts_ticket__segments']['segments_target_id']['filter']['id'] = 'contacts_event_segment';
}

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

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