You are here

public static function WebformElementBase::validateUnique in Webform 8.5

Same name and namespace in other branches
  1. 6.x src/Plugin/WebformElementBase.php \Drupal\webform\Plugin\WebformElementBase::validateUnique()

Form API callback. Validate element #unique value.

File

src/Plugin/WebformElementBase.php, line 2026

Class

WebformElementBase
Provides a base class for a webform element.

Namespace

Drupal\webform\Plugin

Code

public static function validateUnique(array &$element, FormStateInterface $form_state) {
  if (!isset($element['#unique'])) {
    return;
  }

  /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
  $element_manager = \Drupal::service('plugin.manager.webform.element');
  $name = $element['#webform_key'];
  $value = NestedArray::getValue($form_state
    ->getValues(), $element['#parents']);

  // Skip composite elements.
  $element_plugin = $element_manager
    ->getElementInstance($element);
  if ($element_plugin
    ->isComposite()) {
    return;
  }

  // Skip empty values but allow for '0'.
  if ($value === '' || $value === NULL || is_array($value) && empty($value)) {
    return;
  }

  /** @var \Drupal\webform\WebformSubmissionForm $form_object */
  $form_object = $form_state
    ->getFormObject();

  /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
  $webform_submission = $form_object
    ->getEntity();
  $webform = $webform_submission
    ->getWebform();

  // Build unique query which return a single duplicate value.
  $query = \Drupal::database()
    ->select('webform_submission', 'ws');
  $query
    ->leftJoin('webform_submission_data', 'wsd', 'ws.sid = wsd.sid');
  $query
    ->fields('wsd', [
    'value',
  ]);
  $query
    ->condition('wsd.webform_id', $webform
    ->id());
  $query
    ->condition('wsd.name', $name);
  $query
    ->condition('wsd.value', (array) $value, 'IN');

  // Unique user condition.
  if (!empty($element['#unique_user'])) {
    $query
      ->condition('ws.uid', $webform_submission
      ->getOwnerId());
  }

  // Unique (source) entity condition.
  if (!empty($element['#unique_entity'])) {
    if ($source_entity = $webform_submission
      ->getSourceEntity()) {
      $query
        ->condition('ws.entity_type', $source_entity
        ->getEntityTypeId());
      $query
        ->condition('ws.entity_id', $source_entity
        ->id());
    }
    else {
      $query
        ->isNull('ws.entity_type');
      $query
        ->isNull('ws.entity_id');
    }
  }

  // Exclude the current webform submission.
  if ($sid = $webform_submission
    ->id()) {
    $query
      ->condition('ws.sid', $sid, '<>');
  }

  // Get single duplicate value.
  $query
    ->range(0, 1);
  $duplicate_value = $query
    ->execute()
    ->fetchField();

  // Skip NULL or empty string value.
  if ($duplicate_value === FALSE || $duplicate_value === '') {
    return;
  }
  if (isset($element['#unique_error'])) {
    $form_state
      ->setError($element, WebformHtmlHelper::toHtmlMarkup($element['#unique_error']));
  }
  elseif (isset($element['#title'])) {

    // Get #options display value.
    if (isset($element['#options'])) {
      $duplicate_value = WebformOptionsHelper::getOptionText($duplicate_value, $element['#options'], TRUE);
    }
    $t_args = [
      '%name' => empty($element['#title']) ? $element['#parents'][0] : $element['#title'],
      '%value' => $duplicate_value,
    ];
    $form_state
      ->setError($element, t('The value %value has already been submitted once for the %name element. You may have already submitted this webform, or you need to use a different value.', $t_args));
  }
  else {
    $form_state
      ->setError($element);
  }
}