You are here

function relation_add_endpoint_field in Relation 8.2

Same name and namespace in other branches
  1. 8 relation.module \relation_add_endpoint_field()

Adds an endpoint field to a relation type.

1 call to relation_add_endpoint_field()
RelationType::postSave in src/Entity/RelationType.php
Acts on a saved entity before the insert or update hook is invoked.

File

./relation.module, line 312
Describes relations between entities.

Code

function relation_add_endpoint_field(RelationTypeInterface $relation_type) {
  $field = FieldStorageConfig::loadByName('relation', RELATION_FIELD_NAME);
  $instance = FieldConfig::loadByName('relation', $relation_type
    ->id(), RELATION_FIELD_NAME);
  if (empty($field)) {
    $field = FieldStorageConfig::create([
      'field_name' => RELATION_FIELD_NAME,
      'entity_type' => 'relation',
      'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
      'type' => 'dynamic_entity_reference',
      'locked' => TRUE,
      'settings' => [
        // DER puts these two here, NOT on the instance. So instead we need to
        // allow all possible entity types on the field storage entity as
        // instances are added, and ensure the bundles validation on the
        // instances is sufficient.
        'exclude_entity_types' => TRUE,
        'entity_type_ids' => [],
      ],
    ]);
    $field
      ->save();
  }
  if ($field && empty($instance)) {
    $settings = [];

    // Handle directional relations differently, if they are going to be
    // supported with DER generally?
    foreach ($relation_type
      ->getBundles() as $selected_entity_type => $selected_bundles) {

      // Either patch DER to allow '*' in some way (e.g. allow no bundles to be
      // selected, to mean all bundle), or subscribe to bundle creation &
      // bundle rename events in order to add them then if this setting is *.
      // Also, default field settings, which will include all existing content
      // entity types, will be merged with our $settings array, so this will not
      // sufficiently restrict the allowed entity types. A rethink is therefore
      // needed.
      $settings[$selected_entity_type]['handler'] = "default:{$selected_entity_type}";
      foreach ($selected_bundles as $selected_bundle) {
        if ($selected_bundle === '*') {

          // If 'target_bundles' is NULL, all bundles are referenceable.
          $settings[$selected_entity_type]['handler_settings']['target_bundles'] = NULL;
        }
        else {
          $settings[$selected_entity_type]['handler_settings']['target_bundles'][$selected_bundle] = $selected_bundle;
        }
      }
    }

    // For all the entity types that are not selected in the relation type set
    // the target bundle to an empty array since then no bundle is
    // referenceable.
    foreach (\Drupal::service('entity_type.repository')
      ->getEntityTypeLabels() as $id => $label) {
      if (!isset($settings[$id])) {
        $settings[$id]['handler'] = "default:{$id}";
        $settings[$id]['handler_settings']['target_bundles'] = [];
      }
    }

    // Attach field instance.
    $instance = FieldConfig::create(array(
      'field_storage' => $field,
      'bundle' => $relation_type
        ->id(),
      'label' => t('Endpoints'),
      'settings' => $settings,
    ));
    $instance
      ->save();

    // Widget settings.
    $entity_form_display = \Drupal::entityTypeManager()
      ->getStorage('entity_form_display')
      ->load('relation.' . $relation_type
      ->id() . '.default');
    if (!$entity_form_display) {
      $entity_form_display = EntityFormDisplay::create(array(
        'targetEntityType' => 'relation',
        'bundle' => $relation_type
          ->id(),
        'mode' => 'default',
        'status' => TRUE,
      ));
    }
    $entity_form_display
      ->setComponent(RELATION_FIELD_NAME, array(
      'type' => 'dynamic_entity_reference_default',
    ))
      ->save();

    // Display settings.
    $display = \Drupal::entityTypeManager()
      ->getStorage('entity_view_display')
      ->load('relation.' . $relation_type
      ->id() . '.default');
    if (!$display) {
      $display = EntityViewDisplay::create(array(
        'targetEntityType' => 'relation',
        'bundle' => $relation_type
          ->id(),
        'mode' => 'default',
        'status' => TRUE,
      ));
    }
    $display
      ->setComponent(RELATION_FIELD_NAME, array(
      'label' => 'hidden',
      'type' => 'dynamic_entity_reference_label',
    ))
      ->save();
  }
}