You are here

function mobile_number_element_validate in Mobile Number 7

Mobile number element validate callback.

1 string reference to 'mobile_number_element_validate'
mobile_number_element_info in ./mobile_number.module
Implements hook_element_info().

File

./mobile_number.module, line 889
mobile_number.module

Code

function mobile_number_element_validate($element, &$form_state) {
  $errors = array();
  $field_path = implode('][', $element['#parents']);
  $tree_parents = $element['#parents'];
  $value = drupal_array_get_nested_value($form_state['values'], $tree_parents);
  $input = drupal_array_get_nested_value($form_state['input'], $tree_parents);
  $op = !empty($form_state['triggering_element']['#mobile_number_op']) ? $form_state['triggering_element']['#mobile_number_op'] : NULL;
  $button = !empty($form_state['triggering_element']['#name']) ? $form_state['triggering_element']['#name'] : NULL;
  $widget_settings = $element['#mobile_number'];
  $field_label = !empty($widget_settings['field_title']) ? $widget_settings['field_title'] : $element['#title'];
  if (!in_array($button, array(
    implode('__', $element['#parents']) . '__send_verification',
    implode('__', $element['#parents']) . '__verify',
  ))) {
    $op = NULL;
  }
  if (!$op && !empty($input['verification_token']) && !empty($input['verification_code'])) {
    $op = 'mobile_number_verify';
  }
  $unique = !empty($element['#field_name']) && !empty($form_state['field'][$element['#field_name']][$element['#language']]['field']['settings']['unique']) ? $form_state['field'][$element['#field_name']][$element['#language']]['field']['settings']['unique'] : NULL;
  $input = $input ? $input : array();
  $mobile_number = NULL;
  $token = NULL;
  $countries = MobileNumber::getCountryOptions(array(), TRUE);
  $verified = FALSE;
  if ($input) {
    $input += count($widget_settings['allowed_countries']) == 1 ? array(
      'country-code' => key($widget_settings['allowed_countries']),
    ) : array(
      'country-code' => NULL,
    );
    try {
      $mobile_number = new MobileNumber($input['mobile'], $input['country-code']);
      $verified = $mobile_number
        ->isVerified();
    } catch (Exception $e) {
      switch ($e
        ->getCode()) {
        case MobileNumber::ERROR_NO_NUMBER:
          if ($op) {
            $errors[$field_path . '][mobile'] = t('Phone number in %field is required.', array(
              '%field' => $field_label,
            ));
          }
          break;
        case MobileNumber::ERROR_INVALID_NUMBER:
        case MobileNumber::ERROR_WRONG_TYPE:
          $errors[$field_path . '][mobile'] = t('The phone number %value provided for %field is not a valid mobile number for country %country.', array(
            '%value' => $input['mobile'],
            '%field' => $field_label,
            '%country' => !empty($countries[$input['country-code']]) ? $countries[$input['country-code']] : '',
          ));
          break;
        case MobileNumber::ERROR_WRONG_COUNTRY:
          $errors[$field_path . '][mobile'] = t('The country %value provided for %field does not match the mobile number prefix.', array(
            '%value' => !empty($countries[$input['country-code']]) ? $countries[$input['country-code']] : '',
            '%field' => $field_label,
          ));
          break;
      }
    }
  }
  $verified = $verified || !empty($element['#default_value']['verified']) && !empty($value['value']) && $value['value'] == $element['#default_value']['value'];
  if ($mobile_number && !$errors) {
    if ($widget_settings['allowed_countries'] && empty($widget_settings['allowed_countries'][$mobile_number->country])) {
      $errors[$field_path . '][country-code'] = t('The country %value provided for %field is not an allowed country.', array(
        '%value' => $countries[$mobile_number->country],
        '%field' => $field_label,
      ));
    }
    elseif ($op == 'mobile_number_verify' && !$mobile_number
      ->checkFlood()) {
      $errors[$field_path . '][verification_code'] = t('Too many validation attempts for %field, please try again in a few hours.', array(
        '%field' => $field_label,
      ));
    }
    elseif ($op == 'mobile_number_send_verification' && !$mobile_number
      ->checkFlood('sms')) {
      $errors[$field_path . '][mobile'] = t('Too many verification code requests for %field, please try again shortly.', array(
        '%field' => $field_label,
      ));
    }
    elseif ($op == 'mobile_number_send_verification' && !$verified && !($token = $mobile_number
      ->sendVerification($widget_settings['message'], $mobile_number
      ->generateVerificationCode(), $widget_settings['token_data']))) {
      $errors[NULL] = t('An error occurred while sending sms.');
    }
    elseif ($op == 'mobile_number_verify' && !($verified = $mobile_number
      ->verifyCode($input['verification_code'], $input['verification_token']))) {
      $errors[$field_path . '][verification_code'] = t('Invalid verification code for %field.', array(
        '%field' => $field_label,
      ));
    }
    elseif (!$op && !$verified && $widget_settings['verify'] == MOBILE_NUMBER_VERIFY_REQUIRED && !user_access('bypass mobile number verification requirement')) {
      $errors[$field_path . '][mobile'] = t('%field verification is required.', array(
        '%field' => $field_label,
      ));
    }
    elseif (!$op && !empty($widget_settings['tfa']) && !empty($input['tfa']) && !$verified) {
      $errors[$field_path . '][tfa'] = t('%field verification is required for enabling two-factor authentication.', array(
        '%field' => $field_label,
      ));
    }
  }
  if ($op != 'mobile_number_send_verification' && !$errors && $mobile_number && !empty($unique) && $mobile_number->callableNumber !== $element['#default_value']['value']) {
    $field_query = new EntityFieldQuery();
    $field_query
      ->fieldCondition($element['#field_name'], 'value', $mobile_number->callableNumber);
    if ($unique == MOBILE_NUMBER_UNIQUE_YES_VERIFIED) {
      $field_query
        ->fieldCondition($element['#field_name'], 'verified', 1);
      if ($verified) {
        $result = $field_query
          ->execute();
      }
      else {
        $result = FALSE;
      }
    }
    else {
      $result = $field_query
        ->execute();
    }
    if ($result) {
      $errors[$field_path . '][mobile'] = t('The number for %field already exists. It must be unique.', array(
        '%field' => $field_label,
      ));
    }
  }
  $verification_prompt = FALSE;
  if ($mobile_number) {
    switch ($op) {
      case 'mobile_number_send_verification':
        $verification_prompt = !$verified && !$errors;
        break;
      case 'mobile_number_verify':
        $verification_prompt = !$verified;
        break;
    }
  }
  if ($verification_prompt && $op) {
    drupal_add_js(array(
      'mobileNumberVerificationPrompt' => $element['#id'],
    ), 'setting');
    $form_state['storage']['mobileNumberVerificationPrompt'][$field_path] = $element['#id'];
  }
  else {
    unset($form_state['storage']['mobileNumberVerificationPrompt'][$field_path]);
  }
  if ($verified && $op) {
    drupal_add_js(array(
      'mobileNumberVerified' => $element['#id'],
    ), 'setting');
    $form_state['storage']['mobileNumberVerified'][$field_path] = $element['#id'];
  }
  else {
    unset($form_state['storage']['mobileNumberVerified'][$field_path]);
  }
  foreach ($errors as $field => $error) {
    form_set_error($field, $error);
  }
  $form_state['storage']['mobile_number_fields'][$field_path]['errors'] = $errors;
  if ($token) {
    $form_state['storage']['mobile_number_fields'][$field_path]['token'] = $token;
  }
  return $element;
}