You are here

public function YamlFormEntityReferenceTrait::form in YAML Form 8

File

src/Plugin/YamlFormElement/YamlFormEntityReferenceTrait.php, line 383

Class

YamlFormEntityReferenceTrait
Provides an 'entity_reference' trait.

Namespace

Drupal\yamlform\Plugin\YamlFormElement

Code

public function form(array $form, FormStateInterface $form_state) {
  $form = parent::form($form, $form_state);
  $element_properties = $form_state
    ->get('element_properties');
  if ($properties = $form_state
    ->getValue('properties')) {
    $target_type = $properties['target_type'];
    $selection_handler = $properties['selection_handler'];
    $selection_settings = $properties['selection_settings'];
  }
  else {

    // Set default #target_type and #selection_handler.
    if (empty($element_properties['target_type'])) {
      $element_properties['target_type'] = 'node';
    }
    if (empty($element_properties['selection_handler'])) {
      $element_properties['selection_handler'] = 'default:' . $element_properties['target_type'];
    }
    $target_type = $element_properties['target_type'];
    $selection_handler = $element_properties['selection_handler'];
    $selection_settings = $element_properties['selection_settings'];
  }
  $form_state
    ->set('element_properties', $element_properties);

  /** @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface $entity_reference_selection_manager */
  $entity_reference_selection_manager = \Drupal::service('plugin.manager.entity_reference_selection');

  // @see \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem
  $selection_plugins = $entity_reference_selection_manager
    ->getSelectionGroups($target_type);
  $handlers_options = [];
  foreach (array_keys($selection_plugins) as $selection_group_id) {
    if (array_key_exists($selection_group_id, $selection_plugins[$selection_group_id])) {
      $handlers_options[$selection_group_id] = Html::escape($selection_plugins[$selection_group_id][$selection_group_id]['label']);
    }
    elseif (array_key_exists($selection_group_id . ':' . $target_type, $selection_plugins[$selection_group_id])) {
      $selection_group_plugin = $selection_group_id . ':' . $target_type;
      $handlers_options[$selection_group_plugin] = Html::escape($selection_plugins[$selection_group_id][$selection_group_plugin]['base_plugin_label']);
    }
  }

  // ISSUE:
  // The AJAX handling for @EntityReferenceSelection plugins is just broken.
  //
  // WORKAROUND:
  // Implement custom #ajax that refresh the entire details element and
  // remove #ajax from selection settings to just get an MVP UI
  // for entity reference elements.
  //
  // @see https://www.drupal.org/project/issues/drupal?text=EntityReferenceSelection&version=8.x
  // @todo Figure out how to properly implement @EntityReferenceSelection plugins.
  $ajax_settings = [
    'callback' => [
      get_class($this),
      'ajaxEntityReference',
    ],
    'wrapper' => 'yamlform-entity-reference-selection-wrapper',
  ];
  $form['entity_reference'] = [
    '#type' => 'fieldset',
    '#title' => t('Entity reference settings'),
    '#prefix' => '<div id="yamlform-entity-reference-selection-wrapper">',
    '#suffix' => '</div>',
    '#weight' => -40,
  ];

  // Tags (only applies to 'entity_autocomplete' element).
  if ($this
    ->hasProperty('tags')) {
    $form['entity_reference']['tags'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Tags'),
      '#description' => $this
        ->t('Check this option if the user should be allowed to enter multiple entity references.'),
      '#return_value' => TRUE,
    ];
  }

  // Target type.
  $form['entity_reference']['target_type'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Type of item to reference'),
    '#options' => \Drupal::service('entity_type.repository')
      ->getEntityTypeLabels(TRUE),
    '#required' => TRUE,
    '#empty_option' => t('- Select a target type -'),
    '#ajax' => $ajax_settings,
    '#default_value' => $target_type,
  ];

  // Selection handler.
  $form['entity_reference']['selection_handler'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Reference method'),
    '#options' => $handlers_options,
    '#required' => TRUE,
    '#ajax' => $ajax_settings,
    '#default_value' => $selection_handler,
  ];

  // Selection settings.
  // Note: The below options are used to populate the #default_value for
  // selection settings.
  $entity_reference_selection_handler = $entity_reference_selection_manager
    ->getInstance([
    'target_type' => $target_type,
    'handler' => $selection_handler,
    'handler_settings' => $selection_settings,
  ]);
  $form['entity_reference']['selection_settings'] = $entity_reference_selection_handler
    ->buildConfigurationForm([], $form_state);
  $form['entity_reference']['selection_settings']['#tree'] = TRUE;
  $this
    ->updateAjaxCallbackRecursive($form['entity_reference']['selection_settings'], $ajax_settings);

  // Remove the no-ajax submit button.
  unset($form['entity_reference']['selection_settings']['target_bundles_update']);

  // Remove auto create, except for entity_autocomplete.
  if ($this
    ->getPluginId() != 'entity_autocomplete' || $target_type != 'taxonomy_term') {
    unset($form['entity_reference']['selection_settings']['auto_create'], $form['entity_reference']['selection_settings']['auto_create_bundle']);
  }

  // Disable AJAX callback that we don't need.
  unset($form['entity_reference']['selection_settings']['target_bundles']['#ajax']);
  unset($form['entity_reference']['selection_settings']['sort']['field']['#ajax']);

  // Remove user role filter, which is not working correctly.
  // @see \Drupal\user\Plugin\EntityReferenceSelection\UserSelection
  unset($form['entity_reference']['selection_settings']['filter']);
  return $form;
}