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