You are here

protected function PaymentAddForm::buildPaymentGatewayForm in Commerce Core 8.2

Builds the form for selecting a payment gateway.

Parameters

array $form: The parent form.

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

Return value

array The built form.

1 call to PaymentAddForm::buildPaymentGatewayForm()
PaymentAddForm::buildForm in modules/payment/src/Form/PaymentAddForm.php
Form constructor.

File

modules/payment/src/Form/PaymentAddForm.php, line 132

Class

PaymentAddForm
Provides the payment add form.

Namespace

Drupal\commerce_payment\Form

Code

protected function buildPaymentGatewayForm(array $form, FormStateInterface $form_state) {

  /** @var \Drupal\commerce_payment\PaymentGatewayStorageInterface $payment_gateway_storage */
  $payment_gateway_storage = $this->entityTypeManager
    ->getStorage('commerce_payment_gateway');
  $payment_gateways = $payment_gateway_storage
    ->loadMultipleForOrder($this->order);

  // Allow on-site and manual payment gateways.
  $payment_gateways = array_filter($payment_gateways, function ($payment_gateway) {

    /** @var \Drupal\commerce_payment\Entity\PaymentGateway $payment_gateway */
    return !$payment_gateway
      ->getPlugin() instanceof OffsitePaymentGatewayInterface;
  });

  // @todo Move this check to the access handler.
  if (count($payment_gateways) < 1) {
    throw new AccessDeniedHttpException();
  }

  // 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()) {
      $form['#attached']['library'][] = $js_library;
    }
  }
  $payment_options = $this->paymentOptionsBuilder
    ->buildOptions($this->order, $payment_gateways);

  // Do not allow admins to add payments to non-reusable payment methods
  // through this form.
  $this->paymentOptions = array_filter($payment_options, function (PaymentOption $payment_option) {
    $order_payment_method = $this->order
      ->get('payment_method')->entity;
    if (!$order_payment_method) {
      return TRUE;
    }

    /** @var \Drupal\commerce_payment\Entity\PaymentMethodInterface $order_payment_method */
    if ($order_payment_method
      ->id() === $payment_option
      ->getPaymentMethodId()) {
      return $order_payment_method
        ->isReusable();
    }
    return TRUE;
  });
  $option_labels = array_map(function (PaymentOption $option) {
    return $option
      ->getLabel();
  }, $this->paymentOptions);
  $default_option_id = NestedArray::getValue($form_state
    ->getUserInput(), [
    'payment_option',
  ]);
  if ($default_option_id && isset($this->paymentOptions[$default_option_id])) {
    $default_option = $this->paymentOptions[$default_option_id];
  }
  else {
    $default_option = $this->paymentOptionsBuilder
      ->selectDefaultOption($this->order, $this->paymentOptions);
  }
  $form['payment_option'] = [
    '#type' => 'radios',
    '#title' => $this
      ->t('Payment option'),
    '#options' => $option_labels,
    '#default_value' => $default_option
      ->getId(),
    '#ajax' => [
      'callback' => [
        get_class($this),
        'ajaxRefresh',
      ],
      'wrapper' => $form['#wrapper_id'],
    ],
  ];

  // Add a class to each individual radio, to help themers.
  foreach ($this->paymentOptions as $option) {
    $class_name = $option
      ->getPaymentMethodId() ? 'stored' : 'new';
    $form['payment_option'][$option
      ->getId()]['#attributes']['class'][] = "payment-method--{$class_name}";
  }
  $default_payment_gateway_id = $default_option
    ->getPaymentGatewayId();
  $payment_gateway = $payment_gateways[$default_payment_gateway_id];
  if ($payment_gateway
    ->getPlugin() instanceof SupportsStoredPaymentMethodsInterface) {
    $form = $this
      ->buildPaymentMethodForm($form, $form_state, $default_option);
  }
  $form['actions']['#type'] = 'actions';
  $form['actions']['submit'] = [
    '#type' => 'submit',
    '#value' => $this
      ->t('Continue'),
    '#button_type' => 'primary',
  ];
  return $form;
}