You are here

private function WebformCivicrmPreProcess::fillForm in Webform CiviCRM Integration 8.5

Recursively walk through form array and set properties of CiviCRM fields

Parameters

array $elements (reference): FAPI form array

array $submitted: Existing submission (optional)

1 call to WebformCivicrmPreProcess::fillForm()
WebformCivicrmPreProcess::alterForm in src/WebformCivicrmPreProcess.php
Alter front-end of webforms: Called by hook_form_alter() when rendering a civicrm-enabled webform Add custom prefix. Display messages. Block users who should not have access. Set webform default values.

File

src/WebformCivicrmPreProcess.php, line 453
Front-end form pre-processor.

Class

WebformCivicrmPreProcess

Namespace

Drupal\webform_civicrm

Code

private function fillForm(&$elements, $submitted = []) {
  foreach ($elements as $eid => &$element) {
    if ($eid[0] == '#' || !is_array($element)) {
      continue;
    }

    // Recurse through nested elements
    $this
      ->fillForm($element, $submitted);
    if (empty($element['#type']) || $element['#type'] == 'fieldset') {
      continue;
    }
    $utils = \Drupal::service('webform_civicrm.utils');
    if (!empty($element['#webform']) && ($pieces = $utils
      ->wf_crm_explode_key($eid))) {
      list(, $c, $ent, $n, $table, $name) = $pieces;
      if ($field = wf_crm_aval($this->all_fields, $table . '_' . $name)) {
        $element['#attributes']['class'][] = 'civicrm-enabled';
        if ($element['#type'] == 'webform_radios_other') {
          $element['other']['#attributes']['class'][] = 'civicrm-enabled';
        }
        $dt = NULL;
        if (!empty($field['data_type'])) {
          $dt = $element['#civicrm_data_type'] = $field['data_type'];
        }
        $element['#attributes']['data-civicrm-field-key'] = $eid;

        // For contribution line-items
        if ($table == 'contribution' && in_array($name, [
          'line_total',
          'total_amount',
        ])) {
          $element['#attributes']['class'][] = 'contribution-line-item';
        }

        // Provide live options from the Civi DB
        if (!empty($element['#civicrm_live_options']) && isset($element['#options'])) {
          $params = [
            'extra' => wf_crm_aval($field, 'extra', []) + wf_crm_aval($element, '#extra', []),
            'form_key' => $element['#webform_key'],
          ];
          $new = $utils
            ->wf_crm_field_options($params, 'live_options', $this->data);
          $old = $element['#options'];
          $resave = FALSE;

          // If an item doesn't exist, we add it. If it's changed, we update it.
          // But we don't subtract items that have been removed in civi - this prevents
          // breaking the display of old submissions.
          foreach ($new as $k => $v) {
            if (!isset($old[$k]) || $old[$k] != $v) {
              $old[$k] = $v;
              $resave = TRUE;
            }
          }
          if ($resave) {
            $element['#extra']['extra']['items'] = $utils
              ->wf_crm_array2str($old);

            //webform_component_update($component);
          }
          $element['#options'] = $new;
        }

        // If the user has already entered a value for this field, don't change it
        if (isset($this->info[$ent][$c][$table][$n][$name]) && !(isset($element['#form_key']) && isset($submitted[$element['#form_key']]))) {
          $val = $this->info[$ent][$c][$table][$n][$name];
          if ($ent === 'contact') {
            $createModeKey = 'civicrm_' . $c . '_contact_' . $n . '_' . $table . '_createmode';
            $multivaluesCreateMode = isset($this->data['config']['create_mode'][$createModeKey]) ? (int) $this->data['config']['create_mode'][$createModeKey] : NULL;

            // Set empty value for field with 'Create only' mode.
            if ($multivaluesCreateMode === self::MULTIVALUE_FIELDSET_MODE_CREATE_ONLY) {
              $val = wf_crm_aval($element, '#default_value', '');
            }
          }
          if (($element['#type'] == 'checkboxes' || !empty($element['#multiple'])) && !is_array($val)) {
            $val = $utils
              ->wf_crm_explode_multivalue_str($val);
          }
          if ($element['#type'] != 'checkboxes' && $element['#type'] != 'date' && empty($element['#multiple']) && is_array($val)) {

            // If there's more than one value for a non-multi field, pick the most appropriate
            if (!empty($element['#options']) && !empty(array_filter($val))) {
              foreach ($element['#options'] as $k => $v) {
                if (in_array($k, $val)) {
                  $val = $k;
                  break;
                }
              }
            }
            else {
              $val = array_pop($val);
            }
          }
          if ($element['#type'] == 'autocomplete' && is_string($val) && strlen($val)) {
            $options = $utils
              ->wf_crm_field_options($element, '', $this->data);
            $val = wf_crm_aval($options, $val);
          }

          // Contact image & custom file fields
          if ($dt == 'File') {
            $fileInfo = $this
              ->getFileInfo($name, $val, $ent, $n);
            if ($fileInfo && in_array($element['#type'], [
              'file',
              'managed_file',
            ])) {
              $elements['#attached']['drupalSettings']['webform_civicrm']['fileFields'][] = [
                'eid' => $eid,
                'fileInfo' => $fileInfo,
              ];
            }
          }
          elseif ($element['#type'] == 'value') {
            $element['#value'] = $val;
          }
          elseif ($element['#type'] == 'datetime') {
            if (!empty($val)) {
              $element['#default_value'] = DrupalDateTime::createFromTimestamp(strtotime($val));
            }
          }
          elseif ($element['#type'] == 'date') {

            // Must pass date only
            $element['#default_value'] = substr($val, 0, 10);
          }
          else {
            $element['#default_value'] = $val;
          }
        }
        if ($name == 'existing') {
          CivicrmContact::wf_crm_fill_contact_value($this->node, $element, $this->ent);
        }
      }
    }
  }
}