commerce-8.x-2.8/modules/payment/src/Form/PaymentAddForm.php

modules/payment/src/Form/PaymentAddForm.php
<?php

namespace Drupal\commerce_payment\Form;

use Drupal\commerce\EntityHelper;
use Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\OffsitePaymentGatewayInterface;
use Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\SupportsStoredPaymentMethodsInterface;
use Drupal\Component\Utility\Html;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

/**
 * Provides the payment add form.
 */
class PaymentAddForm extends FormBase implements ContainerInjectionInterface {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The current order.
   *
   * @var \Drupal\commerce_order\Entity\OrderInterface
   */
  protected $order;

  /**
   * Constructs a new PaymentAddForm instance.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The route match.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, RouteMatchInterface $route_match) {
    $this->entityTypeManager = $entity_type_manager;
    $this->order = $route_match->getParameter('commerce_order');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
      $container->get('current_route_match')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'commerce_payment_add_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    // Prepare the form for ajax.
    $form['#wrapper_id'] = Html::getUniqueId('payment-add-form-wrapper');
    $form['#prefix'] = '<div id="' . $form['#wrapper_id'] . '">';
    $form['#suffix'] = '</div>';
    $form['#tree'] = TRUE;

    $step = $form_state->get('step');
    $step = $step ?: 'payment_gateway';
    $form_state->set('step', $step);
    if ($step == 'payment_gateway') {
      $form = $this->buildPaymentGatewayForm($form, $form_state);
    }
    elseif ($step == 'payment') {
      $form = $this->buildPaymentForm($form, $form_state);
    }

    return $form;
  }

  /**
   * Builds the form for selecting a payment gateway.
   *
   * @param array $form
   *   The parent form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the complete form.
   *
   * @return array
   *   The built form.
   */
  protected function buildPaymentGatewayForm(array $form, FormStateInterface $form_state) {
    // @todo
    // Support adding payments to anonymous orders, by adding support for
    // creating payment methods directly on this form.
    if (!$this->order->getCustomerId()) {
      throw new AccessDeniedHttpException();
    }

    /** @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();
    }

    $user_input = $form_state->getUserInput();
    $first_payment_gateway = reset($payment_gateways);
    $selected_payment_gateway_id = $first_payment_gateway->id();
    if (isset($user_input['payment_gateway'])) {
      $selected_payment_gateway_id = $user_input['payment_gateway'];
    }
    $selected_payment_gateway = $payment_gateways[$selected_payment_gateway_id];
    $form['payment_gateway'] = [
      '#type' => 'radios',
      '#title' => $this->t('Payment gateway'),
      '#options' => EntityHelper::extractLabels($payment_gateways),
      '#default_value' => $selected_payment_gateway_id,
      '#required' => TRUE,
      '#ajax' => [
        'callback' => [get_class($this), 'ajaxRefresh'],
        'wrapper' => $form['#wrapper_id'],
      ],
    ];

    if ($selected_payment_gateway->getPlugin() instanceof SupportsStoredPaymentMethodsInterface) {
      /** @var \Drupal\commerce_payment\PaymentMethodStorageInterface $payment_method_storage */
      $payment_method_storage = $this->entityTypeManager->getStorage('commerce_payment_method');
      $billing_countries = $this->order->getStore()->getBillingCountries();
      $payment_methods = $payment_method_storage->loadReusable($this->order->getCustomer(), $selected_payment_gateway, $billing_countries);
      if (!empty($payment_methods)) {
        $selected_payment_method = reset($payment_methods);
        $payment_method_options = [];
        foreach ($payment_methods as $id => $payment_method) {
          $payment_method_options[$id] = $payment_method->label();
          if ($payment_method->isDefault()) {
            $selected_payment_method = $payment_method;
          }
        }

        $form['payment_method'] = [
          '#type' => 'radios',
          '#title' => $this->t('Payment method'),
          '#options' => $payment_method_options,
          '#default_value' => $selected_payment_method->id(),
          '#required' => TRUE,
          '#after_build' => [
            [get_class($this), 'clearValue'],
          ],
        ];
      }
      else {
        $form['payment_method'] = [
          '#type' => 'markup',
          '#markup' => $this->t('There are no reusable payment methods available for the selected gateway.'),
        ];
        // Don't allow the form to be submitted.
        return $form;
      }
    }

    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Continue'),
      '#button_type' => 'primary',
    ];

    return $form;
  }

  /**
   * Clears the payment method value when the payment gateway changes.
   *
   * Changing the payment gateway results in a new set of payment methods,
   * causing the submitted value to trigger an "Illegal choice" error, cause
   * it's no longer allowed. Clearing the value causes the element to fallback
   * to the default value, avoiding the error.
   */
  public static function clearValue(array $element, FormStateInterface $form_state) {
    $value = $element['#value'];
    if (!isset($element['#options'][$value])) {
      $element['#value'] = NULL;
      $user_input = &$form_state->getUserInput();
      unset($user_input['payment_method']);
    }
    return $element;
  }

  /**
   * Builds the form for adding a payment.
   *
   * @param array $form
   *   The parent form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the complete form.
   *
   * @return array
   *   The built form.
   */
  protected function buildPaymentForm(array $form, FormStateInterface $form_state) {
    $values = [
      'payment_gateway' => $form_state->getValue('payment_gateway'),
      'order_id' => $this->order->id(),
    ];
    if ($payment_method = $form_state->getValue('payment_method')) {
      $values['payment_method'] = $payment_method;
    }
    $payment_storage = $this->entityTypeManager->getStorage('commerce_payment');
    $payment = $payment_storage->create($values);

    $form['payment'] = [
      '#type' => 'commerce_payment_gateway_form',
      '#operation' => 'add-payment',
      '#default_value' => $payment,
    ];
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Add payment'),
      '#button_type' => 'primary',
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $step = $form_state->get('step');
    if ($step == 'payment_gateway') {
      $form_state->set('step', 'payment');
      $form_state->setRebuild(TRUE);
    }
    elseif ($step == 'payment') {
      /** @var \Drupal\commerce_payment\Entity\PaymentInterface $payment */
      $payment = $form_state->getValue('payment');
      $this->messenger()->addMessage($this->t('Payment saved.'));
      $form_state->setRedirect('entity.commerce_payment.collection', ['commerce_order' => $payment->getOrderId()]);
    }
  }

  /**
   * Ajax callback.
   */
  public static function ajaxRefresh(array $form, FormStateInterface $form_state) {
    return $form;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc