You are here

private function WebformCivicrmPostProcess::fillDataFromSubmission in Webform CiviCRM Integration 8.5

Fill data array with submitted form values

2 calls to WebformCivicrmPostProcess::fillDataFromSubmission()
WebformCivicrmPostProcess::loadMultiPageData in src/WebformCivicrmPostProcess.php
Load entire webform submission during validation, including contact ids and $this->data Used when validation for one page needs access to submitted values from other pages
WebformCivicrmPostProcess::preSave in src/WebformCivicrmPostProcess.php
Process webform submission when it is about to be saved. Called by the following hook:

File

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

Class

WebformCivicrmPostProcess

Namespace

Drupal\webform_civicrm

Code

private function fillDataFromSubmission() {
  $utils = \Drupal::service('webform_civicrm.utils');
  foreach ($this->enabled as $field_key => $fid) {
    $val = (array) $this
      ->submissionValue($fid);
    $customValue = NULL;

    // If value is null then it was hidden by a webform conditional rule - skip it
    if ($val !== NULL && $val !== [
      NULL,
    ]) {
      list(, $c, $ent, $n, $table, $name) = explode('_', $field_key, 6);

      // The following are not strictly CiviCRM fields, so ignore
      if (in_array($name, [
        'existing',
        'fieldset',
        'createmode',
      ])) {
        continue;
      }

      // Check to see if configured to ignore hidden field value(s)
      if ($this
        ->isFieldHiddenByExistingContactSettings($ent, $c, $table, $n, $name, TRUE)) {

        // Also remove the value from the webform submission
        $this
          ->submissionValue($fid, [
          NULL,
        ]);
        continue;
      }
      $field = $this->all_fields[$table . '_' . $name];
      $component = $this->node
        ->getElementDecoded($field_key);

      // Ignore values from hidden fields
      if ($field['type'] === 'hidden') {
        continue;
      }

      // Translate privacy options into separate values
      if ($name === 'privacy') {
        foreach (array_keys($this
          ->getExposedOptions($field_key)) as $key) {
          $this->data[$ent][$c][$table][$n][$key] = in_array($key, $val);
        }
        continue;
      }
      $dataType = wf_crm_aval($field, 'data_type');
      if (!empty($field['extra']['multiple'])) {
        if ($val === [
          '',
        ]) {
          $val = [];
        }

        // Merge with existing data
        if (!empty($this->data[$ent][$c][$table][$n][$name]) && is_array($this->data[$ent][$c][$table][$n][$name])) {
          $val = array_unique(array_merge($val, $this->data[$ent][$c][$table][$n][$name]));
        }
        if (substr($name, 0, 6) === 'custom' || $table == 'other' && in_array($name, [
          'group',
          'tag',
        ])) {
          $val = array_filter($val);
        }

        // We need to handle items being de-selected too and provide an array to pass to Entity.create API
        // Extract a list of available items
        $exposedOptions = $this
          ->getExposedOptions($field_key);
        $customValue = [];
        foreach ($exposedOptions as $itemName => $itemLabel) {
          if (in_array($itemName, $val)) {
            $customValue[] = $itemName;
          }
        }

        // Implode data that will be stored as a string
        if ($table !== 'other' && $name !== 'event_id' && $name !== 'relationship_type_id' && $table !== 'contact' && $dataType != 'ContactReference' && strpos($name, 'tag') !== 0) {
          $val = \CRM_Utils_Array::implodePadded($val);
        }
      }
      elseif ($name === 'image_URL') {
        if (empty($val[0]) || !($val = $this
          ->getDrupalFileUrl($val[0]))) {

          // This field can't be emptied due to the nature of file uploads
          continue;
        }
      }
      elseif ($dataType == 'File') {
        if (empty($val[0]) || !($val = $this
          ->saveDrupalFileToCivi($val[0]))) {

          // This field can't be emptied due to the nature of file uploads
          continue;
        }
      }
      elseif ($field['type'] === 'date') {
        $val = empty($val[0]) ? '' : str_replace('-', '', $val[0]);

        // Add time field value
        $time = wf_crm_aval($this->data, "{$ent}:{$c}:{$table}:{$n}:{$name}", '');

        // Remove default date if it has been added
        if (strlen($time) == 14) {
          $time = substr($time, -6);
        }
        $val .= $time;
      }
      elseif ($field['type'] === 'number') {
        $sum = 0;
        foreach ((array) $val as $k => $v) {

          // Perform multiplication across grid elements
          if (is_numeric($k) && $component['#type'] === 'grid') {
            $v *= $k;
          }
          if (is_numeric($v)) {
            $sum += $v;
          }
        }

        // Do not constrain to only allow positive amounts [note fields like contribution_amount come with a minimum 0 value - so admin must be specific/ok this]
        $val = $sum;
      }
      else {
        $val = is_array($val) ? reset($val) : $val;

        // Trim whitespace from user input
        if (is_string($val)) {
          $val = trim($val);
        }
      }
      if (is_string($val) && '' !== $val && $field['type'] === 'autocomplete') {
        $options = $utils
          ->wf_crm_field_options($component, '', $this->data);
        $val = array_search($val, $options);
      }

      // Only known contacts are allowed to empty a field
      if ($val !== '' && $val !== NULL && $val !== [] || !empty($this->existing_contacts[$c])) {
        $this->data[$ent][$c][$table][$n][$name] = $val;
        if (substr($name, 0, 6) === 'custom') {
          $multivaluesCreateMode = NULL;

          // Handle 'Create mode' for multivalues custom fields of Contact entity.
          if ($ent === 'contact' && is_numeric(substr($name, 7))) {
            $createModeKey = 'civicrm_' . $c . '_contact_' . $n . '_' . $table . '_createmode';
            $multivaluesCreateMode = $this->data['config']['create_mode'][$createModeKey] ?? NULL;
            $cgMaxInstance = $this->all_sets[$table]['max_instances'] ?? 1;

            // Is this a multi-value custom field?
            if ($cgMaxInstance > 1) {
              $name = $this
                ->getNameForMultiValueFields($multivaluesCreateMode, $name, $table, $c, $n);
              $n = 1;
            }
          }
          $this->data[$ent][$c][$ent][$n][$name] = $customValue ?? $val;
        }
      }
    }
  }
}