contacts_events-8.x-1.x-dev/src/EventSubscriber/BookingCompletionValidationSubscriber.php
src/EventSubscriber/BookingCompletionValidationSubscriber.php
<?php
namespace Drupal\contacts_events\EventSubscriber;
use Drupal\contacts_events\Event\BookingCompletionValidationEvent;
use Drupal\contacts_events\SupervisionHelper;
use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Subscriber for booking completion validation.
*/
class BookingCompletionValidationSubscriber implements EventSubscriberInterface {
/**
* The supervision helper service.
*
* @var \Drupal\contacts_events\SupervisionHelper
*/
protected $supervisionHelper;
/**
* Construct the subscriber.
*
* @param \Drupal\contacts_events\SupervisionHelper $supervision_helper
* The supervision helper service.
*/
public function __construct(SupervisionHelper $supervision_helper) {
$this->supervisionHelper = $supervision_helper;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return [
BookingCompletionValidationEvent::NAME => [
['validateBookingsStatus', -99],
['validateSupervision'],
],
];
}
/**
* Validate that completion is allowed for this event.
*
* @param \Drupal\contacts_events\Event\BookingCompletionValidationEvent $validation_event
* The validation event.
*/
public function validateBookingsStatus(BookingCompletionValidationEvent $validation_event) {
// Check the booking status of the event.
$order = $validation_event->getOrder();
/** @var \Drupal\contacts_events\Entity\EventInterface $event */
$event = $order->get('event')->entity;
// If booking is open, there's nothing to do.
if ($event->isBookingOpen()) {
return;
}
// Not enabled shouldn't even allow other validation to take place.
if (!$event->isBookingEnabled()) {
$validation_event->addError(new TranslatableMarkup('This event does not allow bookings.'));
$validation_event->stopPropagation();
return;
}
// Disallow confirming if there are no items.
$items = $order->getItems();
if (count($items) === 0) {
$validation_event->addError(new TranslatableMarkup('This booking is empty.'));
$validation_event->stopPropagation();
return;
}
// Check whether there are unconfirmed items on the booking and get the
// total for any confirmed items.
$has_unconfirmed = FALSE;
/** @var \Drupal\commerce_price\Price|null $confirmed_total */
$confirmed_total = NULL;
foreach ($items as $item) {
if ($item->hasField('state') && $item->get('state')->value == 'pending') {
$has_unconfirmed = TRUE;
}
elseif ($item_total = $item->getAdjustedTotalPrice()) {
$confirmed_total = $confirmed_total ? $confirmed_total->add($item_total) : $item_total;
}
}
// If there are unconfirmed items we show a soft error to allow users with
// the manage permission to continue.
if ($has_unconfirmed) {
// If there is an outstanding balance on the confirmed items, we will show
// a slightly different message.
$paid = $order->getTotalPaid();
if ($confirmed_total && $confirmed_total->isPositive() && (!$paid || $paid->lessThan($confirmed_total))) {
$validation_event->addSoftError(new TranslatableMarkup('You are now unable to make any changes to this booking. To pay your outstanding balance, please remove any attempted changes to this booking.'));
}
// Otherwise we can simplify the message.
else {
$validation_event->addSoftError(new TranslatableMarkup('You are now unable to make any changes to this booking.'));
}
}
}
/**
* Validate supervision ratio.
*
* @param \Drupal\contacts_events\Event\BookingCompletionValidationEvent $event
* The validation event.
*/
public function validateSupervision(BookingCompletionValidationEvent $event) {
// Check that event is configured for child supervision validation.
$ratio = $this->supervisionHelper->getRatio($event->getOrder());
if (!$ratio) {
return;
}
// Get the booking helper to calculate current ratios.
$booking_helper = $this->supervisionHelper->getBookingHelper($event->getOrder()->get('order_items'));
$adults_total = $booking_helper->getAdultDelegates();
$non_adult_total = $booking_helper->getNonAdultDelegates();
$result = $this->supervisionHelper->validateSupervision($adults_total, $non_adult_total, $ratio);
switch ($result) {
case SupervisionHelper::VALIDATE_OK:
case SupervisionHelper::VALIDATE_UNNECESSARY:
// No error, so nothing to do.
break;
case SupervisionHelper::VALIDATE_TOO_FEW:
$error = new TranslatableMarkup('It looks like you have not booked enough adults to supervise the @count you are booking for.', [
'@count' => new PluralTranslatableMarkup($non_adult_total, 'under 18', '@count under 18s'),
]);
break;
case SupervisionHelper::VALIDATE_NONE:
$error = new TranslatableMarkup('It looks like you have not booked any adults for this booking. At least one delegate must be over 18 at the time of the event.');
break;
default:
$error = new TranslatableMarkup('Sorry, we encountered an unknown error.');
break;
}
if (isset($error)) {
$event->addSoftError($error);
}
}
}
