You are here

public function FieldInheritanceForm::form in Field Inheritance 8

Same name and namespace in other branches
  1. 2.0.x src/Form/FieldInheritanceForm.php \Drupal\field_inheritance\Form\FieldInheritanceForm::form()

Gets the actual form array to be built.

Overrides EntityForm::form

See also

\Drupal\Core\Entity\EntityForm::processForm()

\Drupal\Core\Entity\EntityForm::afterBuild()

File

src/Form/FieldInheritanceForm.php, line 95

Class

FieldInheritanceForm
Provides a form for managing field inheritance entities.

Namespace

Drupal\field_inheritance\Form

Code

public function form(array $form, FormStateInterface $form_state) {
  $form = parent::form($form, $form_state);
  $field_inheritance = $this->entity;

  // This form needs AJAX support.
  $form['#attached']['library'][] = 'core/jquery.form';
  $form['#attached']['library'][] = 'core/drupal.ajax';
  $form['#prefix'] = '<div id="field-inheritance-add-form--wrapper">';
  $form['#suffix'] = '</div>';
  $form['label'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Label'),
    '#maxlength' => 255,
    '#default_value' => $field_inheritance
      ->label(),
    '#description' => $this
      ->t("Label for the Field inheritance."),
    '#required' => TRUE,
  ];
  $machine_name_prefix = '';
  if ($field_inheritance
    ->isNew()) {
    if (!empty($this->entity->destination_entity_type) && !empty($this->entity->destination_entity_bundle)) {
      $machine_name_prefix = $this->entity->destination_entity_type . '_' . $this->entity->destination_entity_bundle . '_';
    }
    else {
      $machine_name_prefix = '[entity-type]_[bundle]_';
    }
  }
  $form['id'] = [
    '#type' => 'machine_name',
    '#default_value' => $field_inheritance
      ->id(),
    '#field_prefix' => $machine_name_prefix,
    '#machine_name' => [
      'exists' => [
        $this,
        'exists',
      ],
    ],
    '#disabled' => !$field_inheritance
      ->isNew(),
  ];
  $help = [
    $this
      ->t('<b>Inherit</b> - Pull field data directly from the source.'),
    $this
      ->t('<b>Prepend</b> - Place destination data above source data.'),
    $this
      ->t('<b>Append</b> - Place destination data below source data.'),
    $this
      ->t('<b>Fallback</b> - Show destination data, if set, otherwise show source data.'),
  ];
  $form['type'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Inheritance Strategy'),
    '#description' => $this
      ->t('Select the method/strategy used to inherit data.'),
    '#options' => [
      'inherit' => $this
        ->t('Inherit'),
      'prepend' => $this
        ->t('Prepend'),
      'append' => $this
        ->t('Append'),
      'fallback' => $this
        ->t('Fallback'),
    ],
    '#required' => TRUE,
    '#default_value' => $field_inheritance
      ->type() ?? 'inherit',
  ];
  $form['information'] = [
    '#type' => 'markup',
    '#prefix' => '<p>',
    '#markup' => implode('</p><p>', $help),
    '#suffix' => '</p>',
  ];
  $entity_types = $this->entityTypeManager
    ->getDefinitions();
  $entity_types = array_keys(array_filter($entity_types, function ($type) {
    return $type
      ->entityClassImplements(FieldableEntityInterface::CLASS);
  }));
  $entity_types = array_combine($entity_types, $entity_types);
  $source_entity_bundles = $destination_entity_bundles = [];
  $source_entity_fields = $destination_entity_fields = [];
  $default_values = [
    '' => $this
      ->t('-- Select --'),
  ];
  $field_values = [];
  $form_values = $form_state
    ->getValues();
  if (!$field_inheritance
    ->isNew()) {
    $field_values['source_entity_type'] = $field_inheritance
      ->sourceEntityType();
    $field_values['source_entity_bundle'] = $field_inheritance
      ->sourceEntityBundle();
    $field_values['source_field'] = $field_inheritance
      ->sourceField();
    $field_values['destination_entity_type'] = $field_inheritance
      ->destinationEntityType();
    $field_values['destination_entity_bundle'] = $field_inheritance
      ->destinationEntityBundle();
  }
  elseif (!empty($form_values)) {
    $field_values['source_entity_type'] = $form_values['source_entity_type'];
    $field_values['source_entity_bundle'] = $form_values['source_entity_bundle'];
    $field_values['source_field'] = $form_values['source_field'];
    $field_values['destination_entity_type'] = $form_values['destination_entity_type'];
    $field_values['destination_entity_bundle'] = $form_values['destination_entity_bundle'];
  }
  if (!empty($field_inheritance
    ->destinationEntityType()) && empty($form_values)) {
    $field_values['destination_entity_type'] = $field_inheritance
      ->destinationEntityType();
  }
  if (!empty($field_inheritance
    ->destinationEntityBundle()) && empty($form_values)) {
    $field_values['destination_entity_bundle'] = $field_inheritance
      ->destinationEntityBundle();
  }
  if (!empty($form_values['source_field'])) {
    $field_values['source_field'] = $form_values['source_field'];
  }
  if (!empty($field_values['source_entity_type'])) {
    $source_entity_bundles = array_keys($this->entityTypeBundleInfo
      ->getBundleInfo($field_values['source_entity_type']));
    $source_entity_bundles = array_combine($source_entity_bundles, $source_entity_bundles);
    if (!empty($field_values['source_entity_bundle'])) {
      $source_entity_fields = array_keys($this->entityFieldManager
        ->getFieldDefinitions($field_values['source_entity_type'], $field_values['source_entity_bundle']));
      $source_entity_fields = $default_values + array_combine($source_entity_fields, $source_entity_fields);
    }
  }
  if (!empty($field_values['destination_entity_type'])) {
    $destination_entity_bundles = array_keys($this->entityTypeBundleInfo
      ->getBundleInfo($field_values['destination_entity_type']));
    $destination_entity_bundles = array_combine($destination_entity_bundles, $destination_entity_bundles);
    if (!empty($field_values['destination_entity_bundle'])) {
      $destination_entity_fields = array_keys($this->entityFieldManager
        ->getFieldDefinitions($field_values['destination_entity_type'], $field_values['destination_entity_bundle']));
      $destination_entity_fields = $default_values + array_combine($destination_entity_fields, $destination_entity_fields);

      // You should never be able to use the inherited field as part of an
      // inheritance as that creates an infinite loop.
      if (!empty($field_inheritance
        ->id() && !empty($destination_entity_fields[$field_inheritance
        ->idWithoutTypeAndBundle()]))) {
        unset($destination_entity_fields[$field_inheritance
          ->idWithoutTypeAndBundle()]);
      }
    }
  }
  $form['source'] = [
    '#type' => 'fieldset',
    '#title' => $this
      ->t('Source of Data'),
  ];
  $form['source']['source_entity_type'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Source Entity Type'),
    '#description' => $this
      ->t('Select the source entity type from which to inherit data.'),
    '#options' => $entity_types,
    '#required' => TRUE,
    '#default_value' => $field_inheritance
      ->sourceEntityType(),
    '#ajax' => [
      'callback' => '::updateFieldOptions',
      'wrapper' => 'field-inheritance-add-form--wrapper',
      'event' => 'change',
      'progress' => [
        'type' => 'throbber',
        'message' => $this
          ->t('Fetching source options...'),
      ],
    ],
  ];
  $form['source']['source_entity_bundle'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Source Entity Bundle'),
    '#description' => $this
      ->t('Select the source entity bundle from which to inherit data.'),
    '#options' => $source_entity_bundles,
    '#required' => TRUE,
    '#default_value' => $field_inheritance
      ->sourceEntityBundle(),
    '#ajax' => [
      'callback' => '::updateFieldOptions',
      'wrapper' => 'field-inheritance-add-form--wrapper',
      'event' => 'change',
      'progress' => [
        'type' => 'throbber',
        'message' => $this
          ->t('Fetching source options...'),
      ],
    ],
    '#states' => [
      'visible' => [
        'select[name="source_entity_type"]' => [
          '!value' => '',
        ],
      ],
    ],
  ];
  $form['source']['source_field'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Source Field'),
    '#description' => $this
      ->t('Select the field on the source entity from which to inherit data.'),
    '#options' => $source_entity_fields,
    '#required' => TRUE,
    '#default_value' => $field_inheritance
      ->sourceField(),
    '#ajax' => [
      'callback' => '::updateFieldOptions',
      'wrapper' => 'field-inheritance-add-form--wrapper',
      'event' => 'change',
      'progress' => [
        'type' => 'throbber',
        'message' => $this
          ->t('Updating plugin options...'),
      ],
    ],
    '#states' => [
      'visible' => [
        'select[name="source_entity_type"]' => [
          '!value' => '',
        ],
        'select[name="source_entity_bundle"]' => [
          '!value' => '',
        ],
      ],
    ],
  ];
  $form['destination'] = [
    '#type' => 'fieldset',
    '#title' => $this
      ->t('Destination of Data'),
  ];
  $form['destination']['destination_entity_type'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Destination Entity Type'),
    '#description' => $this
      ->t('Select the destination entity type to which to inherit data.'),
    '#options' => $entity_types,
    '#required' => TRUE,
    '#default_value' => $field_inheritance
      ->destinationEntityType(),
    '#ajax' => [
      'callback' => '::updateFieldOptions',
      'wrapper' => 'field-inheritance-add-form--wrapper',
      'event' => 'change',
      'progress' => [
        'type' => 'throbber',
        'message' => $this
          ->t('Fetching destination options...'),
      ],
    ],
  ];
  $form['destination']['destination_entity_bundle'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Destination Entity Bundle'),
    '#description' => $this
      ->t('Select the destination entity bundle to which to inherit data.'),
    '#options' => $destination_entity_bundles,
    '#required' => TRUE,
    '#default_value' => $field_inheritance
      ->destinationEntityBundle(),
    '#ajax' => [
      'callback' => '::updateFieldOptions',
      'wrapper' => 'field-inheritance-add-form--wrapper',
      'event' => 'change',
      'progress' => [
        'type' => 'throbber',
        'message' => $this
          ->t('Fetching destination options...'),
      ],
    ],
    '#states' => [
      'visible' => [
        'select[name="destination_entity_type"]' => [
          '!value' => '',
        ],
      ],
    ],
  ];
  $form['destination']['destination_field'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Destination Field'),
    '#description' => $this
      ->t('(Optionally) Select the field on the destination entity to use during inheritance.'),
    '#options' => $destination_entity_fields,
    '#default_value' => $field_inheritance
      ->destinationField(),
    '#states' => [
      'visible' => [
        'select[name="type"]' => [
          '!value' => 'inherit',
        ],
        'select[name="destination_entity_type"]' => [
          '!value' => '',
        ],
        'select[name="destination_entity_bundle"]' => [
          '!value' => '',
        ],
      ],
      'required' => [
        'select[name="type"]' => [
          '!value' => 'inherit',
        ],
        'select[name="destination_entity_type"]' => [
          '!value' => '',
        ],
        'select[name="destination_entity_bundle"]' => [
          '!value' => '',
        ],
      ],
    ],
  ];
  $plugins = [];
  foreach ($this->fieldInheritance
    ->getDefinitions() as $plugin_id => $plugin) {
    $plugins[$plugin_id] = $plugin['name']
      ->__toString();
  }
  $global_plugins = [];
  $prefered_plugin = '';

  // If a source field is set, then hide plugins not applicable to that field
  // type.
  if (!empty($field_values['source_field'])) {
    $source_definitions = $this->entityFieldManager
      ->getFieldDefinitions($field_values['source_entity_type'], $field_values['source_entity_bundle']);
    foreach ($plugins as $key => $plugin) {
      if ($key === '') {
        continue;
      }
      $plugin_definition = $this->fieldInheritance
        ->getDefinition($key);
      $field_types = $plugin_definition['types'];
      if (!in_array('any', $field_types)) {
        $prefered_plugin = $key;
        if (!in_array($source_definitions[$field_values['source_field']]
          ->getType(), $field_types)) {
          unset($plugins[$key]);
        }
      }

      // Global plugins should not take precedent over more specific plugins.
      if (in_array('any', $field_types)) {
        if (empty($prefered_plugin)) {
          $prefered_plugin = $key;
        }
        $global_plugins[$key] = $plugins[$key];
        unset($plugins[$key]);
      }
    }

    // If we have some global plugins, place them at the end of the list.
    if (!empty($global_plugins)) {
      $plugins = array_merge($plugins, $global_plugins);
    }
    $default_plugins = [
      '' => $this
        ->t('- Select -'),
    ];
    if (empty($plugins)) {
      $plugins = $default_plugins;
    }
    $form['advanced'] = [
      '#type' => 'details',
      '#title' => $this
        ->t('Advanced'),
      '#open' => TRUE,
    ];
    $form['advanced']['plugin'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Inheritance Plugin'),
      '#description' => $this
        ->t('Select the plugin used to perform the inheritance.'),
      '#options' => $plugins,
      '#required' => TRUE,
      '#default_value' => $field_inheritance
        ->isNew() ? $prefered_plugin : $field_inheritance
        ->plugin() ?? $prefered_plugin,
    ];
  }
  return $form;
}