bee-8.x-1.1/src/Form/UpdateAvailabilityForm.php
src/Form/UpdateAvailabilityForm.php
qq<?php
namespace Drupal\bee\Form;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\node\Entity\NodeType;
use Drupal\node\NodeInterface;
use Drupal\node\Entity\Node;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Update reservation form for a BEE node.
*/
class UpdateAvailabilityForm extends FormBase {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* Node type storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected EntityStorageInterface $nodetypeStorage;
/**
* Node storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected EntityStorageInterface $nodeStorage;
/**
* Constructs a new UpdateAvailabilityForm object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory) {
$this->entityTypeManager = $entity_type_manager;
$this->configFactory = $config_factory;
$this->nodetypeStorage = $this->entityTypeManager->getStorage('node_type');
$this->nodeStorage = $this->entityTypeManager->getStorage('node');
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager'),
$container->get('config.factory')
);
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'bee_update_availability_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, ?NodeInterface $node = NULL) {
$node_type = $this->nodetypeStorage->load($node->bundle());
assert($node_type instanceof NodeType);
$bee_settings = $node_type->getThirdPartySetting('bee', 'bee');
$today = new \DateTime();
$tomorrow = clone($today);
$tomorrow->modify('+1 day');
$one_hour_later = clone($today);
$one_hour_later->modify('+1 hour');
$form['node'] = [
'#type' => 'hidden',
'#value' => $node->id(),
];
$form['availability'] = [
'#type' => 'details',
'#title' => $this->t('Update availability'),
];
// ************************************************************
// @todo Can we update the very unit?
foreach ($node->get('field_availability_' . $bee_settings['bookable_type']) as $unit) {
if ($unit->entity) {
$bat_unit = bat_unit_load($unit->entity->id());
$options[$bat_unit->Id()] = $bat_unit->get('name')->value;
}
}
$form['availability']['unit'] = [
'#type' => 'select',
'#title' => $this->t('Unit (@experimental)'),
'#options' => $options,
'#prefix' => '<div class="form-row unit">',
];
// ***********************************************************
$form['availability']['state'] = [
'#type' => 'select',
'#title' => $this->t('State'),
'#options' => [
'available' => $this->t('Available'),
'unavailable' => $this->t('Unavailable'),
],
'#prefix' => '<div class="form-row">',
];
$form['availability']['start_date'] = [
'#type' => ($bee_settings['bookable_type'] == 'daily') ? 'date' : 'datetime',
'#title' => $this->t('Start'),
'#date_increment' => 60,
'#default_value' => ($bee_settings['bookable_type'] == 'daily') ? $today->format('Y-m-d') : new DrupalDateTime($today->format('Y-m-d H:00')),
'#required' => TRUE,
];
$form['availability']['end_date'] = [
'#type' => ($bee_settings['bookable_type'] == 'daily') ? 'date' : 'datetime',
'#title' => $this->t('End'),
'#default_value' => ($bee_settings['bookable_type'] == 'daily') ? $tomorrow->format('Y-m-d') : new DrupalDateTime($one_hour_later->format('Y-m-d H:00')),
'#date_increment' => 60,
'#required' => TRUE,
'#suffix' => '</div>',
];
$form['availability']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Update Availability'),
];
$form['#attached']['library'][] = 'bee/bee_form';
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
$d = [];
$d['values'] = $form_state->getValues();
$d['start_date'] = $d['values']['start_date'];
$end_date = $d['values']['end_date'];
$d['node'] = $this->nodeStorage->load($d['values']['node']);
$node_type = $this->nodetypeStorage->load($d['node']->bundle());
assert($node_type instanceof NodeType);
$bee_settings = $node_type->getThirdPartySetting('bee', 'bee');
if ($bee_settings['bookable_type'] == 'daily') {
$d['start_date'] = new \DateTime($d['start_date']);
$end_date = new \DateTime($end_date);
}
else {
$d['start_date'] = new \DateTime($d['start_date']->format('Y-m-d H:i'));
$end_date = new \DateTime($end_date->format('Y-m-d H:i'));
}
// The end date must be greater or equal than start date.
if ($end_date < $d['start_date']) {
$form_state->setErrorByName('end_date', $this->t('End date must be on or after the start date.'));
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$d = [];
$d['values'] = $form_state->getValues();
$d['start_date'] = $d['values']['start_date'];
$end_date = $d['values']['end_date'];
$d['node'] = $this->nodeStorage->load($d['values']['node']);
$node_type = $this->nodetypeStorage->load($d['node']->bundle());
assert($node_type instanceof NodeType);
$bee_settings = $node_type->getThirdPartySetting('bee', 'bee');
if ($bee_settings['bookable_type'] == 'daily') {
$d['start_date'] = new \DateTime($d['start_date']);
$end_date = new \DateTime($end_date);
$this->createDailyEvent($d['node'], $d['start_date'], $end_date, $bee_settings['type_id'], $d['values']['state']);
}
else {
$d['start_date'] = new \DateTime($d['start_date']->format('Y-m-d H:i'));
$end_date = new \DateTime($end_date->format('Y-m-d H:i'));
$this->createHourlyEvent($d['node'], $d['start_date'], $end_date, $bee_settings['type_id'], $d['values']['state']);
}
}
/**
* Create daily event.
*
* @param \Drupal\node\Entity\Node $node
* A node object.
* @param \DateTime $start_date
* A DateTime object.
* @param \DateTime $end_date
* A DateTime object.
* @param int $type_id
* An integer.
* @param string $new_state
* A string.
*/
private function createDailyEvent(Node $node, \DateTime $start_date, \DateTime $end_date, $type_id, $new_state) {
$d = [];
$d['type_id'] = $type_id;
$d['start_date'] = $start_date;
$d['node'] = $node;
$d['new_state'] = $new_state;
$d['temp_end_date'] = clone($end_date);
$d['temp_end_date']->sub(new \DateInterval('PT1M'));
$d['booked_units'] = bat_event_get_matching_units(
$d['start_date'],
$d['temp_end_date'],
['bee_daily_booked'],
[$d['type_id']],
'availability_daily'
);
$d['available_units'] = bat_event_get_matching_units(
$d['start_date'],
$d['temp_end_date'],
['bee_daily_available', 'bee_daily_not_available'],
[$d['type_id']],
'availability_daily'
);
$d['units_ids'] = [];
foreach ($d['node']->get('field_availability_daily') as $unit) {
if ($unit->entity) {
$d['units_ids'][] = $unit->entity->id();
}
}
if (isset($d['available_units'])) {
if ($d['new_state'] == 'available') {
$d['state'] = bat_event_load_state_by_machine_name('bee_daily_available');
}
else {
$d['state'] = bat_event_load_state_by_machine_name('bee_daily_not_available');
}
foreach ($d['available_units'] as $unit) {
$event = bat_event_create(['type' => 'availability_daily']);
$event_dates = [
'value' => $d['start_date']->format('Y-m-d\TH:i:00'),
'end_value' => $end_date->format('Y-m-d\TH:i:00'),
];
$event->set('event_dates', $event_dates);
$event->set('event_state_reference', $d['state']->id());
$event->set('event_bat_unit_reference', $unit);
$event->save();
}
}
if (isset($d['booked_units'])) {
foreach ($d['booked_units'] as $unit) {
$bat_unit = bat_unit_load($unit);
$this->messenger()->addWarning($this->t('Could not create event from @start to @end for unit @label with ID: @unit', [
'@unit' => $unit,
'@label' => $bat_unit->label(),
'@start' => $d['start_date']->format('Y-m-d'),
'@end' => $end_date->format('Y-m-d'),
]));
}
}
}
/**
* Create hourly event.
*
* @param \Drupal\node\Entity\Node $node
* A node object.
* @param \DateTime $start_date
* A DateTime object.
* @param \DateTime $end_date
* A DateTime object.
* @param int $type_id
* An integer.
* @param string $new_state
* A string.
*/
private function createHourlyEvent(Node $node, \DateTime $start_date, \DateTime $end_date, $type_id, $new_state) {
$d = [];
$d['node'] = $node;
$d['type_id'] = $type_id;
$d['start_date'] = $start_date;
$d['temp_end_date'] = clone($end_date);
$d['temp_end_date']->sub(new \DateInterval('PT1M'));
$d['booked_units'] = bat_event_get_matching_units($d['start_date'], $d['temp_end_date'], ['bee_hourly_booked'], [$d['type_id']], 'availability_hourly');
$d['available_units'] = bat_event_get_matching_units(
$d['start_date'],
$d['temp_end_date'],
['bee_hourly_available', 'bee_hourly_not_available'],
[$d['type_id']],
'availability_hourly'
);
$d['units_ids'] = [];
foreach ($d['node']->get('field_availability_hourly') as $unit) {
if ($unit->entity) {
$d['units_ids'][] = $unit->entity->id();
}
}
$units = array_intersect($d['units_ids'], $d['available_units']);
if ($units) {
if ($d['new_state'] == 'available') {
$d['state'] = bat_event_load_state_by_machine_name('bee_hourly_available');
}
else {
$d['state'] = bat_event_load_state_by_machine_name('bee_hourly_not_available');
}
foreach ($units as $unit) {
$event = bat_event_create(['type' => 'availability_hourly']);
$event_dates = [
'value' => $d['start_date']->format('Y-m-d\TH:i:00'),
'end_value' => $end_date->format('Y-m-d\TH:i:00'),
];
$event->set('event_dates', $event_dates);
$event->set('event_state_reference', $d['state']->id());
$event->set('event_bat_unit_reference', $unit);
$event->save();
}
}
foreach ($d['booked_units'] as $unit) {
$bat_unit = bat_unit_load($unit);
$this->messenger()->addWarning($this->t('Could not create event from @start to @end for unit @label with ID: @unit', [
'@unit' => $unit,
'@label' => $bat_unit->label(),
'@start' => $d['start_date']->format('Y-m-d'),
'@end' => $end_date->format('Y-m-d'),
]));
}
}
}
