commerce-8.x-2.8/modules/payment/src/PluginForm/PaymentMethodEditForm.php
modules/payment/src/PluginForm/PaymentMethodEditForm.php
<?php namespace Drupal\commerce_payment\PluginForm; use Drupal\commerce_payment\CreditCard; use Drupal\commerce_payment\Entity\PaymentMethodInterface; use Drupal\commerce_payment\Exception\DeclineException; use Drupal\commerce_payment\Exception\PaymentGatewayException; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Logger\LoggerChannelFactoryInterface; use Symfony\Component\DependencyInjection\ContainerInterface; class PaymentMethodEditForm extends PaymentGatewayFormBase implements ContainerInjectionInterface { /** * The store storage. * * @var \Drupal\commerce_store\StoreStorageInterface */ protected $storeStorage; /** * The logger. * * @var \Drupal\Core\Logger\LoggerChannelInterface */ protected $logger; /** * Constructs a new PaymentMethodEditForm object. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager. * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory * The logger factory. * * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException */ public function __construct(EntityTypeManagerInterface $entity_type_manager, LoggerChannelFactoryInterface $logger_factory) { $this->storeStorage = $entity_type_manager->getStorage('commerce_store'); $this->logger = $logger_factory->get('commerce_payment'); } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('entity_type.manager'), $container->get('logger.factory') ); } /** * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { /** @var \Drupal\commerce_payment\Entity\PaymentMethodInterface $payment_method */ $payment_method = $this->entity; $billing_profile = $payment_method->getBillingProfile(); $store = $this->storeStorage->loadDefault(); $form['#tree'] = TRUE; $form['#attached']['library'][] = 'commerce_payment/payment_method_form'; $form['billing_information'] = [ '#parents' => array_merge($form['#parents'], ['billing_information']), '#type' => 'commerce_profile_select', '#default_value' => $billing_profile, '#default_country' => $store ? $store->getAddress()->getCountryCode() : NULL, '#available_countries' => $store ? $store->getBillingCountries() : [], '#weight' => 50, ]; if ($payment_method->bundle() == 'credit_card') { $form['payment_details'] = $this->buildCreditCardForm($payment_method, $form_state); } elseif ($payment_method->bundle() == 'paypal') { // @todo Decide how to handle saved PayPal payment methods. } return $form; } /** * {@inheritdoc} */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { /** @var \Drupal\commerce_payment\Entity\PaymentMethodInterface $payment_method */ $payment_method = $this->entity; $payment_method->setBillingProfile($form['billing_information']['#profile']); if ($payment_method->bundle() == 'credit_card') { $expiration_date = $form_state->getValue(['payment_method', 'payment_details', 'expiration']); $payment_method->get('card_exp_month')->setValue($expiration_date['month']); $payment_method->get('card_exp_year')->setValue($expiration_date['year']); $expires = CreditCard::calculateExpirationTimestamp($expiration_date['month'], $expiration_date['year']); $payment_method->setExpiresTime($expires); } elseif ($payment_method->bundle() == 'paypal') { // @todo Decide how to handle saved PayPal payment methods. } /** @var \Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\SupportsUpdatingStoredPaymentMethodsInterface $payment_gateway_plugin */ $payment_gateway_plugin = $this->plugin; // The payment method form is customer facing. For security reasons // the returned errors need to be more generic. try { $payment_gateway_plugin->updatePaymentMethod($payment_method); $payment_method->save(); } catch (DeclineException $e) { $this->logger->warning($e->getMessage()); throw new DeclineException(t('We encountered an error processing your payment method. Please verify your details and try again.')); } catch (PaymentGatewayException $e) { $this->logger->error($e->getMessage()); throw new PaymentGatewayException(t('We encountered an unexpected error processing your payment method. Please try again later.')); } } /** * Builds the credit card form. * * @param \Drupal\commerce_payment\Entity\PaymentMethodInterface $payment_method * The payment method. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the complete form. * * @return array * The built credit card form. */ protected function buildCreditCardForm(PaymentMethodInterface $payment_method, FormStateInterface $form_state) { // Build a month select list that shows months with a leading zero. $months = []; for ($i = 1; $i < 13; $i++) { $month = str_pad($i, 2, '0', STR_PAD_LEFT); $months[$month] = $month; } // Build a year select list that uses a 4 digit key with a 2 digit value. $current_year_4 = date('Y'); $current_year_2 = date('y'); $years = []; for ($i = 0; $i < 10; $i++) { $years[$current_year_4 + $i] = $current_year_2 + $i; } $element['#attached']['library'][] = 'commerce_payment/payment_method_icons'; $element['#attributes']['class'][] = 'credit-card-form'; $element['type'] = [ '#type' => 'hidden', '#value' => $payment_method->get('card_type')->value, ]; $element['number'] = [ '#type' => 'inline_template', '#template' => '<span class="payment-method-icon payment-method-icon--{{ type }}"></span>{{ label }}', '#context' => [ 'type' => $payment_method->get('card_type')->value, 'label' => $payment_method->label(), ], ]; $element['expiration'] = [ '#type' => 'container', '#attributes' => [ 'class' => ['credit-card-form__expiration'], ], ]; $element['expiration']['month'] = [ '#type' => 'select', '#title' => t('Month'), '#options' => $months, '#default_value' => str_pad($payment_method->get('card_exp_month')->value, 2, '0', STR_PAD_LEFT), '#required' => TRUE, ]; $element['expiration']['divider'] = [ '#type' => 'item', '#title' => '', '#markup' => '<span class="credit-card-form__divider">/</span>', ]; $element['expiration']['year'] = [ '#type' => 'select', '#title' => t('Year'), '#options' => $years, '#default_value' => $payment_method->get('card_exp_year')->value, '#required' => TRUE, ]; return $element; } }