You are here

private function WebformCivicrmPostProcess::validateBillingFields in Webform CiviCRM Integration 8.5

Normalize and validate billing input

Return value

bool

1 call to WebformCivicrmPostProcess::validateBillingFields()
WebformCivicrmPostProcess::validate in src/WebformCivicrmPostProcess.php
Called after a webform is submitted Or, for a multipage form, called after each page

File

src/WebformCivicrmPostProcess.php, line 1806
Front-end form validation and post-processing.

Class

WebformCivicrmPostProcess

Namespace

Drupal\webform_civicrm

Code

private function validateBillingFields() {
  $valid = TRUE;
  $params = $card_errors = [];
  $payment_processor_id = NestedArray::getValue($this->data, [
    'contribution',
    '1',
    'contribution',
    '1',
    'payment_processor_id',
  ]);
  $processor = \Civi\Payment\System::singleton()
    ->getById($payment_processor_id);
  $billingAddressFieldsMetadata = [];
  if (method_exists($processor, 'getBillingAddressFieldsMetadata')) {

    // getBillingAddressFieldsMetadata did not exist before 4.7
    $billingAddressFieldsMetadata = $processor
      ->getBillingAddressFieldsMetadata();
  }
  $fields = \CRM_Utils_Array::crmArrayMerge($processor
    ->getPaymentFormFieldsMetadata(), $billingAddressFieldsMetadata);
  $request = \Drupal::request();
  $form_values = array_merge($request->request
    ->all(), $this->form_state
    ->getValues());
  foreach ($form_values as $field => $value) {
    if (empty($value) && isset($fields[$field]) && $fields[$field]['is_required'] !== FALSE) {
      $this->form_state
        ->setErrorByName($field, t(':name field is required.', [
        ':name' => $fields[$field]['title'],
      ]));
      $valid = FALSE;
    }
    if (!empty($value) && (array_key_exists($field, $fields) || strpos($field, 'billing_address_') !== false)) {
      $name = str_replace('civicrm_1_contribution_1_contribution_billing_address_', '', $field);
      $params[$name] = $value;
      foreach ([
        "billing_{$name}",
        "billing_{$name}-5",
      ] as $billingName) {
        if (isset($fields[$billingName])) {
          $params[$billingName] = $value;
        }
      }
    }
  }

  // 4.6 compatibility - some processors (eg. authorizeNet / Paypal require that "year" and "month" are set in params.
  if (isset($params['credit_card_exp_date'])) {
    $params['year'] = \CRM_Core_Payment_Form::getCreditCardExpirationYear($params);
    $params['month'] = \CRM_Core_Payment_Form::getCreditCardExpirationMonth($params);
  }

  // Validate billing details
  if (!empty($this->data['billing']['number_number_of_billing'])) {
    \CRM_Core_Payment_Form::validatePaymentInstrument($payment_processor_id, $params, $card_errors, NULL);
  }
  foreach ($card_errors as $field => $msg) {
    $this->form_state
      ->setErrorByName($field, $msg);
    $valid = FALSE;
  }

  // Email
  for ($i = 1; $i <= $this->data['contact'][1]['number_of_email']; ++$i) {
    if (!empty($this->crmValues["civicrm_1_contact_{$i}_email_email"])) {
      $params['email'] = $this->crmValues["civicrm_1_contact_{$i}_email_email"];
      break;
    }
  }
  if (empty($params['email']) and !$processor
    ->supports('NoEmailProvided')) {
    $this->form_state
      ->setErrorByName('billing_email', ts('An email address is required to complete this transaction.'));
    $valid = FALSE;
  }
  if ($valid) {
    $this->billing_params = $params;
  }

  // Since billing fields are not "real" form fields they get cleared if the page reloads.
  // We add a bit of js to fix this annoyance.
  $this->form['#attached']['drupalSettings']['webform_civicrm']['billingSubmission'] = $params;
  return $valid;
}