contacts_events-8.x-1.x-dev/modules/contacts_events_segments/src/EventSubscriber/PriceCalculationSubscriber.php
modules/contacts_events_segments/src/EventSubscriber/PriceCalculationSubscriber.php
<?php
namespace Drupal\contacts_events_segments\EventSubscriber;
use Drupal\contacts_events\Entity\TicketInterface;
use Drupal\contacts_events\Event\PriceCalculationEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Price subscriber for partial tickets.
*/
class PriceCalculationSubscriber implements EventSubscriberInterface {
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return [
PriceCalculationEvent::NAME => [
['adjustDayTickets'],
],
];
}
/**
* Changes ticket price for day tickets.
*
* @param \Drupal\contacts_events\Event\PriceCalculationEvent $event
* Event.
*/
public function adjustDayTickets(PriceCalculationEvent $event): void {
$ticket = $this->getValidTicket($event);
if (!$ticket) {
return;
}
// Nothing to do if it's not a day ticket.
if (!$this->hasSegments($ticket)) {
return;
}
$booking_window = $event->getMapping()['booking_window'];
$class = $event->getMapping()['class'];
$total_price = $event->getCalculatedPrice()->multiply('0');
/** @var \Drupal\contacts_events_segments\Entity\SegmentInterface $segment */
foreach ($ticket->get('segments')->referencedEntities() as $segment) {
/** @var \Drupal\contacts_events\Plugin\Field\FieldType\PriceMapItem[][] $price_map */
$price_map = $segment->get('price')->getPriceMap();
if (isset($price_map[$booking_window][$class])) {
$total_price = $total_price->add($price_map[$booking_window][$class]->toPrice());
}
}
$event->setPrice($total_price);
}
/**
* Get and validate the ticket for the event, if there is one.
*
* A valid ticket is one that has successfully got a price mapping.
*
* @param \Drupal\contacts_events\Event\PriceCalculationEvent $event
* The calculation event.
*
* @return \Drupal\contacts_events\Entity\TicketInterface|null
* The ticket if there is one and it is valid, NULL otherwise.
*/
protected function getValidTicket(PriceCalculationEvent $event): ?TicketInterface {
// We only want to deal with tickets that have a mapping.
if ($event->getOrderItem()->bundle() != 'contacts_ticket' || !$event->getMapping() || !$event->getPrice()) {
return NULL;
}
return $event->getPurchasedEntity();
}
/**
* Check whether the ticket has segments.
*
* @param \Drupal\contacts_events\Entity\TicketInterface $ticket
* The ticket.
*
* @return bool
* Whether the ticket has segments.
*/
protected function hasSegments(TicketInterface $ticket): bool {
// Ensure the segment field exists.
if (!$ticket->hasField('segments')) {
return FALSE;
}
return !$ticket->get('segments')->isEmpty();
}
}
