contacts_events-8.x-1.x-dev/modules/teams/src/Guard/TeamWorkflowGuard.php
modules/teams/src/Guard/TeamWorkflowGuard.php
<?php
namespace Drupal\contacts_events_teams\Guard;
use Drupal\commerce_order\Entity\OrderItem;
use Drupal\contacts_events_teams\TeamQueries;
use Drupal\Core\Entity\EntityInterface;
use Drupal\state_machine\Guard\GuardInterface;
use Drupal\state_machine\Plugin\Workflow\WorkflowInterface;
use Drupal\state_machine\Plugin\Workflow\WorkflowTransition;
/**
* Workflow guard for the booking transitions for team tickets.
*/
class TeamWorkflowGuard implements GuardInterface {
/**
* The team query service.
*
* @var \Drupal\contacts_events_teams\TeamQueries
*/
protected $queries;
/**
* Construct the team workflow guard.
*
* @param \Drupal\contacts_events_teams\TeamQueries $queries
* The team query service.
*/
public function __construct(TeamQueries $queries) {
$this->queries = $queries;
}
/**
* {@inheritdoc}
*/
public function allowed(WorkflowTransition $transition, WorkflowInterface $workflow, EntityInterface $entity) {
if ($workflow->getId() == 'contacts_events_order_item_process' && $entity->bundle() == 'contacts_ticket') {
$transition_id = $transition->getId();
// If we are returning back to pending, we dont need any additional
// checks. Also the team ticket might already have been reset at this
// point so additional checks may fail.
// @see \Drupal\contacts_events_teams\Form\TicketFormAlter::submitSetupTeamApplication
if ($transition_id == 'team_app_back_to_pending') {
return NULL;
}
/** @var \Drupal\commerce_order\Entity\OrderItem $entity */
$is_team_ticket = $this->isTeamTicket($entity);
// If this is not a team ticket ignore unless it is a team transition.
if (!$is_team_ticket) {
return substr($transition_id, 0, 5) == 'team_' ? FALSE : NULL;
}
// Team tickets should never be confirmed.
if ($transition->getToState()->getId() == 'confirmed') {
return FALSE;
}
// Make sure we use the team_payment_undone transition rather than the
// payment_undone transition.
/* @see \Drupal\contacts_events\Entity\PaymentHooks::postSave() */
if ($transition_id == 'payment_undone') {
return FALSE;
}
// Allow all other transitions to happen normally, except for transitions
// to paid_in_full.
if ($transition->getToState()->getId() != 'paid_in_full') {
return NULL;
}
/** @var \Drupal\contacts_events\Entity\TicketInterface $ticket */
$ticket = $entity->getPurchasedEntity();
$app = $this->queries->getTeamApplicationForTicket($ticket);
// Only allow progressing to paid in full if the application has been
// approved.
return $app && $app->state->value == 'approved';
}
// Otherwise we don't want to influence the outcome.
return NULL;
}
/**
* Checks if a ticket is a team ticket.
*
* @param \Drupal\commerce_order\Entity\OrderItem $entity
* The Order Item.
*
* @return bool
* Whether the order item is for a team ticket.
*/
protected function isTeamTicket(OrderItem $entity) {
if ($entity->bundle() === 'contacts_ticket') {
/** @var \Drupal\contacts_events\Entity\Ticket $ticket */
return $entity->getPurchasedEntity()->is_team_ticket->value;
}
return FALSE;
}
}
