contacts_events-8.x-1.x-dev/src/Plugin/Commerce/CheckoutPane/BookingReview.php
src/Plugin/Commerce/CheckoutPane/BookingReview.php
<?php
namespace Drupal\contacts_events\Plugin\Commerce\CheckoutPane;
use Drupal\commerce_checkout\Plugin\Commerce\CheckoutFlow\CheckoutFlowInterface;
use Drupal\commerce_checkout\Plugin\Commerce\CheckoutPane\CheckoutPaneBase;
use Drupal\commerce_checkout\Plugin\Commerce\CheckoutPane\CheckoutPaneInterface;
use Drupal\contacts_events\Plugin\Commerce\CheckoutFlow\BookingFlowInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides the review pane.
*
* @CommerceCheckoutPane(
* id = "booking_review",
* label = @Translation("Booking Review"),
* default_step = "review",
* )
*/
class BookingReview extends CheckoutPaneBase implements CheckoutPaneInterface {
/**
* The currency formatter.
*
* @var \CommerceGuys\Intl\Formatter\CurrencyFormatterInterface
*/
protected $currencyFormatter;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, CheckoutFlowInterface $checkout_flow = NULL) {
$self = parent::create($container, $configuration, $plugin_id, $plugin_definition, $checkout_flow);
$self->currencyFormatter = $container->get('commerce_price.currency_formatter');
return $self;
}
/**
* {@inheritdoc}
*/
public function buildPaneForm(array $pane_form, FormStateInterface $form_state, array &$complete_form) {
// Get the effective step weight, excluding the summary.
$steps = $this->checkoutFlow->getSteps();
unset($steps['summary']);
$steps = array_keys($steps);
$step_weights = array_flip($steps);
/** @var \Drupal\commerce_checkout\Plugin\Commerce\CheckoutPane\CheckoutPaneInterface[] $enabled_panes */
$enabled_panes = array_filter($this->checkoutFlow->getPanes(), function ($pane) {
return !in_array($pane->getStepId(), ['_sidebar', '_disabled']);
});
$route_name = $this->checkoutFlow instanceof BookingFlowInterface ? $this->checkoutFlow::ROUTE_NAME : 'commerce_checkout.form';
$pane_form['_intro']['#weight'] = -9;
$pane_form['_intro']['title'] = [
'#type' => 'html_tag',
'#tag' => 'h2',
'#value' => $this->t('Welcome to your Booking Dashboard'),
];
$pane_form['_intro']['subtitle'] = [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t('You can come back and manage your booking progress from here at every step of the process.'),
];
$continue_step = $this->order->get('checkout_step')->value ?: reset($steps);
$pane_form['_intro']['continue'] = [
'#type' => 'link',
'#title' => $this->t('Continue my booking'),
'#url' => Url::fromRoute($route_name, [
'commerce_order' => $this->order->id(),
'step' => $continue_step,
]),
'#attributes' => [
'class' => ['button', 'button--primary'],
],
'#access' => $continue_step != 'review',
];
// If the booking has been assigned a village, and displaying villages
// is public then display it at the top.
if ($this->order->hasField('village') && $this->order->get('village')->entity) {
/** @var \Drupal\contacts_events\Entity\Event $event */
$event = $this->order->get('event')->entity;
if ($event->get('make_village_allocation_public')->value) {
$pane_form['allocation_label'] = [
'#type' => 'html_tag',
'#tag' => 'dt',
'#value' => $this->t('Camping Village'),
];
$pane_form['allocation'] = [
'#type' => 'html_tag',
'#tag' => 'dd',
'#value' => $this->order->get('village')->entity->label(),
];
}
}
foreach ($enabled_panes as $pane_id => $pane) {
if ($pane->isVisible() && $summary = $pane->buildPaneSummary()) {
// BC layer for panes which still return rendered strings.
if ($summary && !is_array($summary)) {
$summary = [
'#markup' => $summary,
];
}
$label = $summary['#title'] ?? $pane->getDisplayLabel();
$pane_form[$pane_id] = [
'#type' => 'fieldset',
'#title' => $label,
'#weight' => ($step_weights[$pane->getStepId()] * 1000) + $pane->getConfiguration()['weight'],
];
$pane_form[$pane_id]['summary'] = $summary;
$definition = $pane->getPluginDefinition();
// Force a button for the payment step if we don't already have a
// continue.
if (!$pane_form['_intro']['continue']['#access'] && $pane->getPluginId() == 'booking_payment_information') {
if (!($this->checkoutFlow instanceof BookingFlowInterface) || $this->checkoutFlow->needsPayment()) {
$definition['review_link'] = $this->t('Review and pay now');
}
elseif ($this->checkoutFlow->needsConfirmation()) {
$definition['review_link'] = $this->t('Review and confirm now');
}
}
if ($pane->isVisible() && !empty($definition['review_link'])) {
$pane_form[$pane_id]['link'] = [
'#type' => 'link',
'#title' => $definition['review_link'],
'#url' => Url::fromRoute($route_name, [
'commerce_order' => $this->order->id(),
'step' => $pane->getStepId(),
]),
'#attributes' => [
'class' => ['button'],
],
];
// Make payment a primary action if we don't already have a continue.
if ($pane->getPluginId() == 'booking_payment_information') {
$pane_form[$pane_id]['link']['#attributes']['class'][] = 'button--primary';
}
}
}
}
// Bump the payment info to the top.
if (isset($pane_form['booking_payment_information'])) {
$pane_form['booking_payment_information']['#weight'] = -1;
}
// Add in a new section for additional charges.
$pane_form['_additional_charges'] = $this->buildAdditionalChargesSection();
// Put additional charges underneath tickets, if tickets is available.
$pane_form['_additional_charges']['#weight'] = $pane_form['tickets']['#weight'] ?? 99;
return $pane_form;
}
/**
* Builds the Additional Charges section.
*
* This section is hidden if there are no additional charges.
*
* @return array
* Render array containing the additional charges field set.
*/
private function buildAdditionalChargesSection() {
$section = [
'#type' => 'fieldset',
'#title' => $this->t('Additional Charges'),
];
$section['table'] = [
'#type' => 'table',
'#header' => [
'item' => $this->t('Charge'),
'price' => $this->t('Price'),
],
];
$has_additional_charges = FALSE;
$format_options = [
'currency_display' => 'symbol',
'minimum_fraction_digits' => 2,
];
foreach ($this->order->getItems() as $order_item) {
if ($order_item->bundle() == 'additional_charge') {
$has_additional_charges = TRUE;
$section['table']['#rows'][$order_item->id()] = [
'item' => $order_item->label(),
'price' => $this->currencyFormatter->format($order_item->getTotalPrice()->getNumber(), $order_item->getTotalPrice()->getCurrencyCode(), $format_options),
];
}
}
$section['#access'] = $has_additional_charges;
return $section;
}
}
