You are here

public static function AdminForm::handleDynamicCustomField in Webform CiviCRM Integration 8.5

When a custom field is saved/deleted in CiviCRM, sync webforms with dynamic fieldsets.

Parameters

string $op:

int $fid:

int $gid:

Overrides AdminFormInterface::handleDynamicCustomField

File

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

Class

AdminForm
@file Webform CiviCRM module's admin form.

Namespace

Drupal\webform_civicrm

Code

public static function handleDynamicCustomField($op, $fid, $gid) {
  $utils = \Drupal::service('webform_civicrm.utils');
  $sets = $utils
    ->wf_crm_get_fields('sets');
  $field_name = $element = "cg{$gid}_custom_{$fid}";
  if ($op === 'create' || $op === 'enable') {
    $element = "cg{$gid}_custom_";
  }

  // Retrieve all webforms with this custom group.
  $webforms = \Drupal::entityQuery('webform')
    ->condition('handlers.webform_civicrm.status', 1)
    ->condition('elements', $element, 'CONTAINS')
    ->execute();

  /** @var \Drupal\webform\WebformInterface[] $webforms */
  foreach ($webforms as $webformID) {
    $webform = Webform::load($webformID);
    $settings = $webform
      ->getHandler('webform_civicrm')
      ->getConfiguration()['settings'] ?? [];

    // Check if the webform has a dynamic custom group.
    $hasDynamicCG = FALSE;
    foreach ($settings as $key => $value) {
      if (strpos($key, "settings_dynamic_custom_cg{$gid}") !== FALSE && !empty($value)) {
        $hasDynamicCG = TRUE;
        break;
      }
    }
    if (!$hasDynamicCG) {
      continue;
    }
    $data = $settings['data'];
    $field_info = $utils
      ->wf_crm_get_field($field_name);

    // $field_info contains old data, so re-fetch
    $fieldConfigs = $utils
      ->wf_civicrm_api('CustomField', 'getsingle', [
      'id' => $fid,
    ]);
    $enabled = $utils
      ->wf_crm_enabled_fields($webform, NULL, TRUE);
    $updated = [];

    // Handle update & delete of existing components
    $elements = $webform
      ->getElementsDecodedAndFlattened();
    foreach ($elements as $component_key => $component) {
      if (substr($component['#form_key'], 0 - strlen($field_name)) === $field_name) {
        if ($pieces = $utils
          ->wf_crm_explode_key($component['#form_key'])) {
          list(, $c, $ent, $n, $table, $name) = $pieces;
          if (!empty($data[$ent][$c]["dynamic_custom_cg{$gid}"])) {
            if ($op === 'delete' || $op === 'disable') {
              unset($elements[$component_key]);
              $webform
                ->deleteElement($component_key);
            }
            elseif (isset($field_info)) {
              $component['#title'] = $fieldConfigs['label'];
              $component['#required'] = $fieldConfigs['is_required'];
              $component['#default_value'] = $fieldConfigs['default_value'] ?: '';
              $component['#extra']['description'] = $fieldConfigs['help_pre'] ?: '';
              $component['#extra']['description_above'] = $field_info['extra']['description_above'];
              $webform
                ->setElementProperties($component_key, $component);
            }
            $updated[$ent][$c] = 1;
          }
        }
      }
    }

    // Handle create new components
    if ($op === 'create' || $op === 'enable') {
      $webform_element_manager = \Drupal::getContainer()
        ->get('plugin.manager.webform.element');
      $ent = $sets["cg{$gid}"]['entity_type'];
      foreach ($data[$ent] as $c => $item) {
        if (!empty($item["dynamic_custom_cg{$gid}"]) && empty($updated[$ent][$c])) {
          $new = $field_info;
          $new['nid'] = $webform
            ->id();
          $new['form_key'] = "civicrm_{$c}_{$ent}_1_{$field_name}";
          if ($op === 'enable') {
            $new['title'] = $fieldConfigs['label'];
            $new['required'] = $fieldConfigs['is_required'];
            $new['value'] = implode(',', $utils
              ->wf_crm_explode_multivalue_str($fieldConfigs['default_value']));
            $new['data_type'] = $fieldConfigs['data_type'];
            $custom_types = $utils
              ->wf_crm_custom_types_map_array();
            $new['type'] = $custom_types[$fieldConfigs['html_type']]['type'];
          }
          self::insertComponent($new, $enabled, $settings);
          $element_plugin = $webform_element_manager
            ->getElementInstance([
            '#type' => $new['type'],
          ]);
          $stub_form = [];
          $stub_form_state = new FormState();
          $stub_form_state
            ->set('default_properties', $element_plugin
            ->getDefaultProperties());
          if (!isset($new['title']) && isset($new['name'])) {
            $new['title'] = $new['name'];
          }
          unset($new['name']);
          $stub_form_state
            ->setValues($new);
          $properties = $element_plugin
            ->getConfigurationFormProperties($stub_form, $stub_form_state);

          // @todo support parent key, for fieldsets and such.
          $webform
            ->setElementProperties($new['form_key'], $properties);
        }
      }
    }
    $webform
      ->save();
  }
}