recurring_events-2.0.x-dev/modules/recurring_events_ical/src/Form/EventICalMappingForm.php

modules/recurring_events_ical/src/Form/EventICalMappingForm.php
<?php

declare(strict_types=1);

namespace Drupal\recurring_events_ical\Form;

use Drupal\Core\DependencyInjection\AutowireTrait;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\token\TokenEntityMapperInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

/**
 * Form handler for the event iCal property mapping add/edit form.
 */
class EventICalMappingForm extends EntityForm {

  use AutowireTrait;

  /**
   * The entity being used by this form.
   *
   * @var \Drupal\recurring_events_ical\EventICalMappingInterface
   */
  protected $entity;

  public function __construct(
    EntityTypeManagerInterface $entityTypeManager,
    protected EntityTypeBundleInfoInterface $entityTypeBundleInfo,
    #[Autowire(service: 'token.entity_mapper')]
    protected TokenEntityMapperInterface $tokenEntityMapper,
  ) {
    $this->entityTypeManager = $entityTypeManager;
  }

  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state) {
    $form = parent::form($form, $form_state);
    $eventType = $this->entity->isNew() ? $form_state->get('event_type') : $this->entity->id();

    // If this is a new mapping, show a selector for unmapped event types.
    if ($this->entity->isNew()) {
      $form['#ajax_wrapper_id'] = 'event-ical-mapping-form-ajax-wrapper';
      $ajax = [
        'wrapper' => $form['#ajax_wrapper_id'],
        'callback' => '::rebuildForm',
      ];
      $form['#prefix'] = '<div id="' . $form['#ajax_wrapper_id'] . '">';
      $form['#suffix'] = '</div>';

      $form['id'] = [
        '#type' => 'select',
        '#title' => $this->t('Event instance type'),
        '#description' => $this->t('Select the type of event for which to map iCalendar properties.'),
        '#options' => $this->getUnmappedTypes(),
        '#default_value' => $eventType,
        '#required' => TRUE,
        '#ajax' => $ajax + [
          'trigger_as' => [
            'name' => 'select_id_submit',
          ],
        ],
      ];
      $form['select_id_submit'] = [
        '#type' => 'submit',
        '#value' => $this->t('Submit'),
        '#name' => 'select_id_submit',
        '#ajax' => $ajax,
        '#attributes' => [
          'class' => ['js-hide'],
        ],
      ];
    }

    // Hide the rest of the form until a type is selected.
    if (!isset($eventType)) {
      return $form;
    }

    // Show the token browser.
    $tokenTypes = [
      'eventinstance' => $this->tokenEntityMapper->getTokenTypeForEntityType('eventinstance'),
    ];
    $form['token_browser'] = [
      '#theme' => 'token_tree_link',
      '#token_types' => $tokenTypes,
      '#global_types' => TRUE,
      '#show_nested' => TRUE,
    ];

    // iCalendar properties.
    $form['properties'] = ['#tree' => TRUE];
    $propertyDefaults = [
      '#type' => 'textfield',
      '#size' => 65,
      '#maxlength' => 1280,
      '#element_validate' => ['token_element_validate'],
      '#after_build' => ['token_element_validate'],
      '#token_types' => $tokenTypes,
    ];
    $form['properties']['summary'] = [
      '#title' => $this->t('Summary'),
      '#default_value' => $this->entity->getProperty('summary') ?? '[eventinstance:title]',
      '#description' => $this->t('Short summary or subject for the event.'),
      '#required' => TRUE,
    ] + $propertyDefaults;
    $form['properties']['contact'] = [
      '#title' => $this->t('Contact'),
      '#default_value' => $this->entity->getProperty('contact'),
      '#description' => $this->t('Contact information for the event.'),
    ] + $propertyDefaults;
    $form['properties']['description'] = [
      '#title' => $this->t('Description'),
      '#default_value' => $this->entity->getProperty('description') ?? '[eventinstance:description]',
      '#description' => $this->t('A more complete description of the event than that provided by the summary.'),
    ] + $propertyDefaults;
    $form['properties']['geo'] = [
      '#title' => $this->t('Geographic Position'),
      '#default_value' => $this->entity->getProperty('geo'),
      '#description' => $this->t('The global position for the event. The value must be two semicolon-separated float values.'),
    ] + $propertyDefaults;
    $form['properties']['location'] = [
      '#title' => $this->t('Location'),
      '#default_value' => $this->entity->getProperty('location'),
      '#description' => $this->t('The intended venue for the event.'),
    ] + $propertyDefaults;
    $form['properties']['priority'] = [
      '#title' => $this->t('Priority'),
      '#default_value' => $this->entity->getProperty('priority'),
      '#description' => $this->t('The relative priority of the event. The value must be an integer in the range 0 to 9. A value of 0 specifies an undefined priority. A value of 1 is the highest priority. A value of 9 is the lowest priority.'),
    ] + $propertyDefaults;
    $form['properties']['url'] = [
      '#title' => $this->t('URL'),
      '#default_value' => $this->entity->getProperty('url') ?? '[eventinstance:url]',
      '#description' => $this->t('A URL associated with the event.'),
    ] + $propertyDefaults;

    return $form;
  }

  /**
   * Ajax form submit handler that returns the rebuilt form.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @return array
   *   The form structure.
   */
  public function rebuildForm(array $form, FormStateInterface $form_state): array {
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildForm($form, $form_state);
    if ($this->entity->isNew() && empty($form['id']['#options'])) {
      $form['id'] = [
        '#markup' => $this->t('All event instance types are already mapped.'),
      ];
      unset($form['actions']['submit']);
      $form['actions']['cancel'] = [
        '#type' => 'link',
        '#title' => $this->t('Cancel'),
        '#url' => new Url('entity.event_ical_mapping.collection'),
        '#attributes' => [
          'class' => [
            'button',
          ],
        ],
      ];
    }
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function buildEntity(array $form, FormStateInterface $form_state) {
    $entity = parent::buildEntity($form, $form_state);
    if ($entity->isNew()) {
      $type = $form_state->getValue('id');
      $types = $this->entityTypeBundleInfo->getBundleInfo('eventinstance');
      $entity->set('label', $types[$type]['label']);
    }
    return $entity;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    if ($form_state->getTriggeringElement()['#name'] === 'select_id_submit') {
      $form_state->set('event_type', $form_state->getValue('id'));
      $form_state->setRebuild();
    }
    else {
      parent::submitForm($form, $form_state);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    $status = parent::save($form, $form_state);
    $this->messenger()->addMessage($this->t('%label iCalendar property mapping saved.', [
      '%label' => $this->entity->label(),
    ]));
    $form_state->setRedirectUrl($this->entity->toUrl('collection'));
    return $status;
  }

  /**
   * Returns an array of unmapped event instance types.
   *
   * @return array
   *   A list of unmapped event instance types as $id => $label.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  protected function getUnmappedTypes(): array {
    $unmappedTypes = [];
    $types = $this->entityTypeBundleInfo->getBundleInfo('eventinstance');
    if ($types) {
      $mappedTypes = $this->entityTypeManager->getStorage('event_ical_mapping')->loadMultiple(array_keys($types));
      foreach ($types as $type => $info) {
        if (!isset($mappedTypes[$type])) {
          $unmappedTypes[$type] = $info['label'];
        }
      }
    }
    return $unmappedTypes;
  }

}

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

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