You are here

public function AdminForm::postProcess in Webform CiviCRM Integration 8.5

Submission handler, saves CiviCRM options for a Webform node

Review this section and translate it to D8 @todo this is what sets the elements on the webform.

This needs to be reworked to support the checking of D8 elements and their removal.

File

src/AdminForm.php, line 1806
Webform CiviCRM module's admin form.

Class

AdminForm
@file Webform CiviCRM module's admin form.

Namespace

Drupal\webform_civicrm

Code

public function postProcess() {
  $utils = \Drupal::service('webform_civicrm.utils');
  $button = $this->form_state
    ->getTriggeringElement()['#id'];
  $this->settings = $this->form_state
    ->getValues();
  $handler_collection = $this->webform
    ->getHandlers('webform_civicrm');

  /** @var \Drupal\webform\Plugin\WebformHandlerInterface $handler */
  $handler = $handler_collection
    ->get('webform_civicrm');
  $handler_configuration = $handler
    ->getConfiguration();
  $enabled = $existing = $utils
    ->wf_crm_enabled_fields($this->webform, NULL, TRUE);
  $delete_me = $this
    ->getFieldsToDelete($enabled);

  // Display a confirmation before deleting fields
  if ($delete_me && $button == 'edit-submit') {
    $msg = '<p>' . t('These existing fields are no longer needed for CiviCRM processing based on your new form settings.') . '</p><ul>';
    foreach ($delete_me as $key => $id) {
      list(, $c, $ent, $n, $table, $name) = explode('_', $key, 6);
      $info = '';
      $element = $this->webform
        ->getElement($id);
      $label = $this
        ->getSettings()["{$c}_webform_label"] ?? '';
      $info = '<em>' . $label;
      if ($info && isset($this->sets[$table]['max_instances'])) {
        $info .= ' ' . $this->sets[$table]['label'] . ' ' . $n;
      }
      $info .= $info ? ':</em> ' : '';
      $msg .= '<li>' . $info . $element['#title'] . '</li>';
    }
    $msg .= '</ul><p>' . t('Would you like them to be automatically removed from the webform? This is recommended unless you need to keep webform-results information from these fields. (They can still be deleted manually later if you choose not to remove them now.)') . '</p><p><em>' . t('Note: Deleting webform components cannot be undone, and will result in the loss of webform-results info for those elements. Data in the CiviCRM database will not be affected.') . '</em></p>';
    $this->form_state
      ->set('msg', $msg);
    $this->form_state
      ->set('vals', $this->settings);
    $this->form_state
      ->setRebuild(TRUE);
    $this->confirmPage = TRUE;
    return;
  }
  \Drupal::ModuleHandler()
    ->loadInclude('webform', 'inc', 'includes/webform.components');

  // Delete/disable fields
  $deleted = 0;
  if ($button === 'edit-delete' || $button === 'edit-disable' && $this->settings['nid']) {
    foreach ($delete_me as $id) {
      $field = $this->webform
        ->getElementDecoded($id);
      unset($enabled[$field['#form_key']]);
      ++$deleted;
      if ($button === 'edit-delete') {
        $this->webform
          ->deleteElement($field['#form_key']);
      }
      else {
        $field['#form_key'] = 'disabled' . substr($field['#form_key'], 7);
        $this->webform
          ->setElementProperties($field['#form_key'], $field);
      }
    }
    if ($deleted == 1) {
      $p = [
        '%name' => $field['#title'],
      ];
      \Drupal::messenger()
        ->addStatus($button === 'edit-delete' ? t('Deleted field: %name', $p) : t('Disabled field: %name', $p));
    }
    else {
      $p = [
        ':num' => $deleted,
      ];
      \Drupal::messenger()
        ->addStatus($button === 'edit-delete' ? t('Deleted :num fields.', $p) : t('Disabled :num fields.', $p));
    }
    if ($button === 'edit-disable') {
      \Drupal::messenger()
        ->addStatus(t('Disabled fields will still be processed as normal Webform fields, but they will not be autofilled from or saved to the CiviCRM database.'));
    }
    else {

      // Remove empty fieldsets for deleted contacts
      foreach ($enabled as $key => $id) {
        if (substr($key, -8) == 'fieldset') {
          list(, $c, $ent, $i) = explode('_', $key);
          if ($ent == 'contact' && $i == 1 && (!$this->settings['nid'] || $c > $this->settings['number_of_contacts'])) {
            $children = $this->webform
              ->getElement($id)['#webform_children'] ?? [];
            if (empty($children)) {
              $this->webform
                ->deleteElement($id);
            }
          }
        }
      }
    }
  }

  // CiviCRM enabled
  $this
    ->rebuildData();
  if (!$this->settings['toggle_message']) {
    $this->settings['message'] = '';
  }

  // Index disabled components
  $disabled = [];

  // @todo there is no disabled?

  /*
      foreach (wf_crm_aval($this->node->webform, 'components', array()) as $field) {
        if (substr($field['form_key'], 0, 9) === 'disabled_') {
          $field['form_key'] = 'civicrm' . substr($field['form_key'], 8);
          $disabled[$field['form_key']] = $field;
        }
      }*/
  $i = 0;
  $created = [];
  foreach ($this->settings as $key => $val) {
    if (strpos($key, 'civicrm') === 0) {
      ++$i;
      $field = $utils
        ->wf_crm_get_field($key);
      if (!isset($enabled[$key])) {
        $val = (array) $val;
        if (in_array('create_civicrm_webform_element', $val, TRUE) || !empty($val[0]) && $field['type'] == 'hidden') {

          // Restore disabled component
          if (isset($disabled[$key])) {
            webform_component_update($disabled[$key]);
            $enabled[$key] = $disabled[$key]['cid'];
            \Drupal::messenger()
              ->addStatus(t('Re-enabled field: %name', [
              '%name' => $disabled[$key]['name'],
            ]));
          }
          else {
            $field += [
              // 'nid' => $nid,
              'form_key' => $key,
            ];

            // Cannot use isNewFieldset effectively.
            $previous_data = $handler_configuration['settings'];
            list(, $c, $ent) = $utils
              ->wf_crm_explode_key($key);
            $type = in_array($ent, self::$fieldset_entities) ? $ent : 'contact';
            $create = !isset($previous_data['data'][$type][$c]);

            /*
              list(, $c, $ent) =  wf_crm_explode_key($field_key);
              $type = in_array($ent, self::$fieldset_entities) ? $ent : 'contact';
              return !isset($this->node->webform_civicrm['data'][$type][$c]);
            */

            // @todo Properly handle fieldset creation.
            // self::insertComponent($field, $enabled, $this->settings, !isset($previous_data['data'][$type][$c]));
            self::insertComponent($field, $enabled, $this->settings, TRUE);
            $created[] = $field['name'];
            if (isset($field['civicrm_condition'])) {
              $this
                ->addConditionalRule($field, $enabled);
            }
          }
        }
      }
      elseif ($field['type'] === 'hidden' && !empty($field['expose_list'])) {
        $elements = $this->webform
          ->getElementsDecodedAndFlattened();
        $component = $elements[$enabled[$key]];
        $component = WebformArrayHelper::removePrefix($component);
        $component['value'] = $val;
        $enabled[$key] = $component;
      }
      elseif (substr($key, -11) === '_createmode') {

        // Update webform's settings with 'Create mode' value for custom group.
        $this->settings['data']['config']['create_mode'][$key] = $val;
      }
      else {

        // Try to "update" options for existing fields via ::insertComponent
        // Always insert fieldsets, as there are checks to see if the
        // fieldset already exists.
        if (!isset($field)) {
          $field = [];
        }
        $field += [
          'form_key' => $key,
        ];
        self::insertComponent($field, $enabled, $this->settings);
      }
    }
    elseif (strpos($key, 'settings_dynamic_custom') && $val == 1) {
      $emptySets = $utils
        ->wf_crm_get_empty_sets();
      list($ent, $n, , , , $cgId) = explode('_', $key, 6);
      $fieldsetKey = "civicrm_{$n}_{$ent}_1_{$cgId}_fieldset";
      if (array_key_exists($cgId, $emptySets) && !isset($existing[$fieldsetKey])) {
        $fieldset = [
          // 'nid' => $nid,
          'pid' => 0,
          'form_key' => $fieldsetKey,
          'name' => $emptySets[$cgId]['label'],
          'type' => 'fieldset',
          'weight' => $i,
        ];
        webform_component_insert($fieldset);
      }
    }
  }
  if (isset($enabled['contribution_pagebreak']) && empty($this->settings['disable_contact_paging'])) {
    $this
      ->setParentOnElements($enabled);
  }
  \Drupal::messenger()
    ->addStatus(\Drupal::translation()
    ->formatPlural(count($created), 'Added one field to the form', 'Added @count fields to the form'));

  // Create record
  $handler_configuration['settings'] = $this->settings;
  $handler
    ->setConfiguration($handler_configuration);
  $this
    ->addEnabledElements($enabled);
  $this
    ->sortPaging();

  // Update existing contact fields
  foreach ($existing as $fid => $id) {
    if (substr($fid, -8) === 'existing') {
      $stop = null;
    }
  }
}