contacts_events-8.x-1.x-dev/src/Form/EventForm.php
src/Form/EventForm.php
<?php namespace Drupal\contacts_events\Form; use Drupal\commerce_price\Price; use Drupal\Component\Render\FormattableMarkup; use Drupal\Component\Utility\NestedArray; use Drupal\contacts_events\Entity\EventInterface; use Drupal\contacts_events\Event\CloneEvent; use Drupal\Core\Entity\ContentEntityForm; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\StringTranslation\TranslatableMarkup; /** * Form controller for Event edit forms. * * @ingroup contacts_events */ class EventForm extends ContentEntityForm { /** * The event entity. * * @var \Drupal\contacts_events\Entity\EventInterface */ protected $entity; /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { // Get the cloning status early so it's available. $form['#cloning'] = $this->entity->getSetting('clone.status'); $form = parent::buildForm($form, $form_state); $form['booking_status']['widget'][EventInterface::STATUS_OPEN]['#description'] = new TranslatableMarkup('Allow users with permission to create new bookings and modify existing bookings for this event.'); $form['booking_status']['widget'][EventInterface::STATUS_CLOSED]['#description'] = new TranslatableMarkup('Restrict new bookings and confirming new tickets to users who can manage bookings from the administrative pages. Booking managers can still make payments of outstanding balances.'); $form['booking_status']['widget'][EventInterface::STATUS_DISABLED]['#description'] = new TranslatableMarkup('Disable all new bookings and modifications, including payments, for this event.'); foreach ($form['booking_status']['widget']['#options'] as $value => $label) { $form['booking_status']['widget'][$value]['#title'] = new FormattableMarkup('<strong>@title</strong>', [ '@title' => $label, ]); } $form['booking_status']['widget']['#attached']['library'][] = 'contacts_events/event-forms'; $form['settings_deposit'] = [ '#type' => 'fieldset', '#title' => $this->t('Deposits'), ]; // phpcs:ignore Drupal.Arrays.Array.LongLineDeclaration $form['settings_deposit']['#element_validate'][] = [$this, 'validateSettingsDeposit']; $form['settings_deposit']['enabled'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow deposits'), '#description' => $this->t('Bookings can be confirmed by paying only the lower of the deposit amount and the item price on each item.'), '#default_value' => (bool) $this->entity->getSetting('payment.deposit', FALSE), '#parents' => array_merge($form['#parents'] ?? [], ['settings_payment_deposit']), ]; $form['settings_deposit']['amount'] = [ '#type' => 'commerce_price', '#title' => $this->t('Deposit amount'), '#default_value' => $this->entity->getSetting('payment.deposit'), '#parents' => array_merge($form['#parents'] ?? [], ['settings', 'payment', 'deposit']), '#states' => [ 'visible' => [ ':input[name="settings_payment_deposit"]' => ['checked' => TRUE], ], ], ]; $form['settings_instalments'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow instalments'), '#description' => $this->t('Bookings can be paid in instalments. Individual items must have at least their deposit paid.'), '#default_value' => $this->entity->getSetting('payment.instalments'), '#parents' => array_merge($form['#parents'] ?? [], ['settings', 'payment', 'instalments']), '#access' => $this->moduleHandler->moduleExists('commerce_partial_payments'), ]; // If we are cloning, we want to prevent the booking status being changed. if ($form['#cloning'] && $form['#cloning'] !== CloneEvent::STATUS_COMPLETED) { // If the event is already saved, show a progress message and disable the // form to prevent conflicts with the clone process. if (!$this->entity->isNew()) { $source = $this->entityTypeManager ->getStorage('contacts_event') ->load($this->entity->getSetting('clone.source')); $this->messenger() ->addWarning($this->t('This event is currently being cloned from %source. Please wait until cloning has completed before editing or opening for bookings to prevent conflicts. Approximate progress: @percent%.', [ '%source' => $source->label(), '@percent' => $this->entity->getSetting('clone.progress'), ])); $form['#disabled'] = TRUE; $form['actions']['#access'] = FALSE; } // Otherwise, just disable the booking status so it can't be enabled yet. else { $form['booking_status']['widget']['#disabled'] = TRUE; } } return $form; } /** * {@inheritdoc} */ protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { // Get all event settings from entity. $existing = $entity->get('settings')->value; /** @var \Drupal\contacts_events\Entity\EventInterface $entity */ parent::copyFormValuesToEntity($entity, $form, $form_state); // Merge form submitted settings with existing settings. $submitted = $form_state->getValue('settings'); $merged = NestedArray::mergeDeepArray([$existing, $submitted]); $entity->set('settings', $merged); if (!$form_state->getValue('settings_payment_deposit')) { $entity->unsetSetting('payment.deposit'); } } /** * {@inheritdoc} */ public function save(array $form, FormStateInterface $form_state) { $entity = $this->entity; $status = parent::save($form, $form_state); switch ($status) { case SAVED_NEW: $this->messenger()->addMessage($this->t('Created the %label Event.', [ '%label' => $entity->label(), ])); break; default: $this->messenger()->addMessage($this->t('Saved the %label Event.', [ '%label' => $entity->label(), ])); } $form_state->setRedirect('entity.contacts_event.canonical', ['contacts_event' => $entity->id()]); } /** * Validates the deposit settings. * * @param array $element * Element. * @param \Drupal\Core\Form\FormStateInterface $form_state * Form state. */ public function validateSettingsDeposit(array $element, FormStateInterface $form_state) { if ($form_state->getValue($element['enabled']['#parents'])) { $value = $form_state->getValue($element['amount']['#parents']); if (!$value) { $form_state->setError($element['amount'], $this->t('Please provide a deposit amount.')); } else { $price = Price::fromArray($value); if (!$price->isPositive()) { $form_state->setError($element['amount'], $this->t('Deposit amount must be more than zero.')); } } } } }