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.'));
        }
      }
    }
  }

}

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

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