event_platform-1.0.x-dev/event_platform_scheduler/src/Form/TimeSlotsForm.php

event_platform_scheduler/src/Form/TimeSlotsForm.php
<?php

namespace Drupal\event_platform_scheduler\Form;

use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\taxonomy\Entity\Term;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides a form to generate time slots in bulk.
 *
 * @ingroup event_platform_scheduler
 */
class TimeSlotsForm extends FormBase {

  /**
   * Information about the entity type.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Constructs a new SchedulerSettingsForm.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   The Drupal service container.
   *
   * @return static
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
    );
  }

  /**
   * Returns a unique string identifying the form.
   *
   * @return string
   *   The unique string identifying the form.
   */
  public function getFormId() {
    return 'event_platform_time_slots';
  }

  /**
   * Form submission handler.
   *
   * @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.
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    if ($form_state->getValue('replace')) {
      $this->deleteAllTimeSlots();
    }
    $timezone = date_default_timezone_get();
    $weight = 0;
    // Convert the provided dates and determine the difference.
    $start_date = new DrupalDateTime($form_state->getValue('start_date'));
    $end_date = new DrupalDateTime($form_state->getValue('end_date'));
    $diff = $start_date->diff($end_date);
    // Convert the difference to an integer.
    $diff = (int) $diff->format('%a');

    // Parse the times input.
    $times = $this->parseTimes($form_state->getValue('times'));

    // Populate variables we will use within our loops.
    $current_date = $start_date;
    $day_interval = \DateInterval::createFromDateString('1 day');
    $duration_string = $form_state->getValue('duration');
    $duration_interval = \DateInterval::createFromDateString($duration_string . ' minutes');

    for ($i = 0; $i <= $diff; $i++) {
      if ($i) {
        $current_date->add($day_interval);
      }
      $date_string = $current_date->format('Y-m-d');
      foreach ($times as $time) {
        $assembled_time = $date_string . ' ' . $time . ' ' . $timezone;
        $start_time = new \DateTimeImmutable($assembled_time);
        // @todo Check if time was properly converted.
        $end_time = $start_time;
        $end_time = $end_time->add($duration_interval);

        $new_term = Term::create([
          'vid' => 'time_slot',
          'field_when' => [
            'value' => $start_time->getTimestamp(),
            'end_value' => $end_time->getTimestamp(),
            'duration' => $duration_string,
          ],
          'weight' => $weight++,
        ]);

        $new_term->enforceIsNew();
        $new_term->save();
      }
    }
    $this->messenger()->addMessage($this->t('Time slots have been generated.'));
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $start_date = new DrupalDateTime($form_state->getValue('start_date'));
    $end_date = new DrupalDateTime($form_state->getValue('end_date'));
    if ($start_date > $end_date) {
      $form_state
        ->setErrorByName('time_slots', $this
          ->t('Please choose an end date on or after the start date.'));
    }

    // Check that the provided times can be converted to dates.
    $times = $this->parseTimes($form_state->getValue('times'));
    $date_string = $start_date->format('Y-m-d');
    $timezone = date_default_timezone_get();
    foreach ($times as $index => $time) {
      $assembled_time = $date_string . ' ' . $time . ' ' . $timezone;
      try {
        $start_time = new \DateTimeImmutable($assembled_time);
      }
      catch (\Exception $e) {
        $form_state
          ->setErrorByName('time_slots', $this
            ->t('Unable to parse the time string @time. Please check that it uses one of the supported formats.', ['@time' => $index]));
      }
    }
  }

  /**
   * Defines the settings form for Search elevate entities.
   *
   * @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
   *   Form definition array.
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config_pages = $this->entityTypeManager->getStorage('config_pages');
    $event_details = $config_pages->load('event_details');
    $current_event_val = $event_details->get('field_current')?->getValue();
    // Extract the value from within a nested array.
    while (is_array($current_event_val)) {
      $current_event_val = array_pop($current_event_val);
    }
    $current_event = Term::load($current_event_val);
    $dates = $current_event->get('field_dates')?->first();
    $form['start_date'] = [
      '#type' => 'date',
      '#title' => $this->t('Start Date'),
      '#default_value' => $dates?->get('start_date')->getValue()->format('Y-m-d'),
      '#description' => $this->t('The first day for which time slots will be generated.'),
      '#required' => TRUE,
    ];
    $form['end_date'] = [
      '#type' => 'date',
      '#title' => $this->t('End Date'),
      '#default_value' => $dates?->get('end_date')->getValue()->format('Y-m-d'),
      '#description' => $this->t('The last day for which time slots will be generated.'),
      '#required' => TRUE,
    ];
    $form['times'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Start Times'),
      '#default_value' => "10am\n11am\n12pm\n1pm\n2pm\n3pm",
      '#description' => $this->t('Provide the start times for the time slots to be generated, with each time on its own line. The following formats can all be understood: 1:00pm, 13:00, 13h00'),
      '#required' => TRUE,
    ];
    $form['duration'] = [
      '#type' => 'number',
      '#title' => $this->t('Duration'),
      '#default_value' => '45',
      '#field_suffix' => ' ' . $this->t('minutes'),
      '#description' => $this->t('The length, in minutes, of the time slots that will be generated.'),
      '#required' => TRUE,
    ];
    $form['replace'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Replace existing'),
      '#description' => $this->t('Select this to replace all existing time slots with the generated values.'),
    ];
    $form['save'] = [
      '#type' => 'submit',
      '#value' => $this->t('Generate'),
    ];

    return $form;
  }

  /**
   * Parse the user input into a normalized array of times.
   *
   * @param string $input
   *   The user input to be parsed.
   *
   * @return array
   *   An array of normalized times.
   */
  protected function parseTimes(string $input) {
    $rows = explode("\n", $input);
    $times = [];
    foreach ($rows as $row) {
      $adjust_twelve = FALSE;
      if (stripos($row, 'am')) {
        $adjust_twelve = TRUE;
      }
      // Normalize time formatting.
      $row = str_ireplace(['h', 'am'], [':', ''], trim($row));
      if (empty($row)) {
        continue;
      }
      $time_parts = explode(':', $row);
      $last_index = count($time_parts) - 1;
      $hour = (int) $time_parts[0];
      // Convert afternoon times to 24h format.
      if (stripos($time_parts[$last_index], 'pm')) {
        $time_parts[$last_index] = str_ireplace('pm', '', $time_parts[$last_index]);
        if ($hour != 12) {
          $time_parts[0] = $hour + 12;
        }
      }
      // Convert midnight times.
      elseif ($adjust_twelve && $hour == 12) {
        $hour = '00';
      }
      // Check for an empty string in the minutes.
      if (isset($time_parts[1]) && empty($time_parts[1])) {
        unset($time_parts[1]);
      }
      // Normalize our time_parts array.
      $all_parts = ['12', '00', '00'];
      // $time_parts = array_merge($all_parts, $time_parts);
      $time_parts = $time_parts + $all_parts;
      $times[$row] = implode(':', $time_parts);
    }
    return $times;
  }

  /**
   * Helper function to clear out any existing time slots.
   */
  protected function deleteAllTimeSlots() {
    $storage = $this->entityTypeManager->getStorage('taxonomy_term');

    $time_slots = $storage->loadByProperties([
      'vid' => 'time_slot',
    ]);
    foreach ($time_slots as $time_slot) {
      $time_slot->delete();
    }
  }

}

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

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