You are here

public function PaymentInformation::buildPaneForm in Commerce Core 8.2

Builds the pane form.

Parameters

array $pane_form: The pane form, containing the following basic properties:

  • #parents: Identifies the position of the pane form in the overall parent form, and identifies the location where the field values are placed within $form_state->getValues().

\Drupal\Core\Form\FormStateInterface $form_state: The form state of the parent form.

array $complete_form: The complete form structure.

Overrides CheckoutPaneInterface::buildPaneForm

File

modules/payment/src/Plugin/Commerce/CheckoutPane/PaymentInformation.php, line 149

Class

PaymentInformation
Provides the payment information pane.

Namespace

Drupal\commerce_payment\Plugin\Commerce\CheckoutPane

Code

public function buildPaneForm(array $pane_form, FormStateInterface $form_state, array &$complete_form) {
  if (!$this->order
    ->getTotalPrice() || $this->order
    ->isPaid() || $this->order
    ->getTotalPrice()
    ->isZero()) {

    // 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 = $this
      ->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) {
    if ($js_library = $payment_gateway
      ->getPlugin()
      ->getJsLibrary()) {
      $pane_form['#attached']['library'][] = $js_library;
    }
  }
  $options = $this->paymentOptionsBuilder
    ->buildOptions($this->order, $payment_gateways);
  $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);
  }
  $pane_form['#after_build'][] = [
    get_class($this),
    'clearValues',
  ];
  $pane_form['payment_method'] = [
    '#type' => 'radios',
    '#title' => $this
      ->t('Payment method'),
    '#options' => $option_labels,
    '#default_value' => $default_option
      ->getId(),
    '#ajax' => [
      'callback' => [
        get_class($this),
        'ajaxRefresh',
      ],
      'wrapper' => $pane_form['#id'],
    ],
    '#access' => count($options) > 1,
  ];

  // Add a class to each individual radio, to help themers.
  foreach ($options as $option) {
    $class_name = $option
      ->getPaymentMethodId() ? 'stored' : 'new';
    $pane_form['payment_method'][$option
      ->getId()]['#attributes']['class'][] = "payment-method--{$class_name}";
  }

  // 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);
  }
  elseif ($payment_gateway_plugin
    ->collectsBillingInformation()) {
    $pane_form = $this
      ->buildBillingProfileForm($pane_form, $form_state);
  }
  return $pane_form;
}