commerce_funds-8.x-1.7/src/Plugin/Commerce/CheckoutPane/DepositPaymentInformation.php
src/Plugin/Commerce/CheckoutPane/DepositPaymentInformation.php
<?php
namespace Drupal\commerce_funds\Plugin\Commerce\CheckoutPane;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Form\FormStateInterface;
use Drupal\commerce_checkout\Plugin\Commerce\CheckoutFlow\CheckoutFlowInterface;
use Drupal\commerce_payment\PaymentOption;
use Drupal\commerce_payment\Plugin\Commerce\CheckoutPane\PaymentInformation;
use Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\SupportsCreatingPaymentMethodsInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides the payment information pane.
*
* This class is not a plugin as we need to use PaymentInformation
* to get the checkout flow working. A hook is implemented to override
* PaymentInformation.
*
* @see Drupal\commerce_payment\Plugin\Commerce\CheckoutPane\PaymentInformation
* @see commerce_funds_commerce_checkout_pane_info_alter()
*/
class DepositPaymentInformation extends PaymentInformation {
/**
* The fees manager.
*
* @var \Drupal\commerce_funds\FeesManagerInterface
*/
protected $feesManager;
/**
* The messenger.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, ?CheckoutFlowInterface $checkout_flow = NULL) {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition, $checkout_flow);
$instance->feesManager = $container->get('commerce_funds.fees_manager');
$instance->messenger = $container->get('messenger');
return $instance;
}
/**
* {@inheritdoc}
*/
public function buildPaneForm(array $pane_form, FormStateInterface $form_state, array &$complete_form) {
// Return parent pane if not a deposit.
if ($this->order->get('type')->getValue()[0]['target_id'] !== 'deposit') {
return parent::buildPaneForm($pane_form, $form_state, $complete_form);
}
if ($this->collectBillingProfileOnly()) {
// No payment is needed if the order is free or has already been paid.
// In that case, collect just the billing information.
$pane_form['#title'] = $this->t('Billing information');
$pane_form = parent::buildBillingProfileForm($pane_form, $form_state);
return $pane_form;
}
/** @var \Drupal\commerce_payment\PaymentGatewayStorageInterface $payment_gateway_storage */
$payment_gateway_storage = $this->entityTypeManager->getStorage('commerce_payment_gateway');
// Load the payment gateways. This fires an event for filtering the
// available gateways, and then evaluates conditions on all remaining ones.
$payment_gateways = $payment_gateway_storage->loadMultipleForOrder($this->order);
// Can't proceed without any payment gateways.
if (empty($payment_gateways)) {
$this->messenger->addError($this->noPaymentGatewayErrorMessage());
return $pane_form;
}
// Core bug #1988968 doesn't allow the payment method add form JS to depend
// on an external library, so the libraries need to be preloaded here.
foreach ($payment_gateways as $payment_gateway) {
foreach ($payment_gateway->getPlugin()->getLibraries() as $library) {
$pane_form['#attached']['library'][] = $library;
}
}
$options = $this->paymentOptionsBuilder->buildOptions($this->order, $payment_gateways);
// Can't proceed without any payment gateways.
if (empty($options)) {
$this->messenger()->addError($this->noPaymentGatewayErrorMessage());
return $pane_form;
}
$option_labels = array_map(function (PaymentOption $option) {
return $option->getLabel();
}, $options);
$parents = array_merge($pane_form['#parents'], ['payment_method']);
$default_option_id = NestedArray::getValue($form_state->getUserInput(), $parents);
if ($default_option_id && isset($options[$default_option_id])) {
$default_option = $options[$default_option_id];
}
else {
$default_option = $this->paymentOptionsBuilder->selectDefaultOption($this->order, $options);
}
// Prepare the form for ajax.
$pane_form['#wrapper_id'] = Html::getUniqueId('payment-information-wrapper');
$pane_form['#prefix'] = '<div id="' . $pane_form['#wrapper_id'] . '">';
$pane_form['#suffix'] = '</div>';
$pane_form['#after_build'][] = [parent::class, 'clearValues'];
$pane_form['payment_method'] = [
'#type' => 'radios',
'#title' => $this->t('Payment method'),
'#options' => $option_labels,
'#default_value' => $default_option->getId(),
'#ajax' => [
'callback' => [parent::class, 'ajaxRefresh'],
'wrapper' => $pane_form['#wrapper_id'],
],
'#access' => count($options) > 1,
];
// Add a class to each individual radio, to help themers.
$currency_code = $this->order->getTotalPrice()->getCurrencyCode();
foreach ($options as $option) {
$class_name = $option->getPaymentMethodId() ? 'stored' : 'new';
$pane_form['payment_method'][$option->getId()]['#attributes']['class'][] = "payment-method--$class_name";
$pane_form['payment_method'][$option->getId()]['#description'] = $this->feesManager->printPaymentGatewayFees($option->getPaymentGatewayId(), $currency_code, 'deposit');
}
// Store the options for submitPaneForm().
$pane_form['#payment_options'] = $options;
// If this is an existing payment method, return the pane form.
// Editing payment methods at checkout is not supported.
if ($default_option->getPaymentMethodId()) {
return $pane_form;
}
$default_payment_gateway_id = $default_option->getPaymentGatewayId();
$payment_gateway = $payment_gateways[$default_payment_gateway_id];
$payment_gateway_plugin = $payment_gateway->getPlugin();
// If this payment gateway plugin supports creating tokenized payment
// methods before processing payment, we build the "add-payment-method"
// plugin form.
if ($payment_gateway_plugin instanceof SupportsCreatingPaymentMethodsInterface) {
$pane_form = $this->buildPaymentMethodForm($pane_form, $form_state, $default_option);
}
// Check if the billing profile form should be rendered for the payment
// gateway to collect billing information.
elseif ($payment_gateway_plugin->collectsBillingInformation()) {
$pane_form = $this->buildBillingProfileForm($pane_form, $form_state);
}
return $pane_form;
}
/**
* {@inheritdoc}
*/
public function submitPaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form) {
// Return parent submit function if not a deposit.
if ($this->order->get('type')->getValue()[0]['target_id'] !== 'deposit') {
return parent::submitPaneForm($pane_form, $form_state, $complete_form);
}
parent::submitPaneForm($pane_form, $form_state, $complete_form);
// Apply the fee to the order on build if any.
$this->feesManager->applyFeeToOrder($this->order);
}
}
