You are here

protected function FieldCloner::copyDisplayComponents in Field tools 8

Copy the field's display settings to the destination bundle's displays.

This finds displays with the same name and copies the original field's settings to them. So for example, if the source bundle has a 'teaser' view mode and so does the destination bundle, the settings will be copied from one to the other.

Parameters

string $display_type: The entity type ID of the display entities to copy: one of 'entity_view_display' or entity_form_display'.

\Drupal\field\FieldConfigInterface $field_config: The field config entity to clone.

string $destination_entity_type_id: The destination entity type.

string $destination_bundle: The destination bundle.

1 call to FieldCloner::copyDisplayComponents()
FieldCloner::cloneField in src/FieldCloner.php
Clone a field to a new entity type and bundle.

File

src/FieldCloner.php, line 134

Class

FieldCloner
Contains methods for cloning fields.

Namespace

Drupal\field_tools

Code

protected function copyDisplayComponents($display_type, FieldConfigInterface $field_config, $destination_entity_type_id, $destination_bundle) {
  $field_name = $field_config
    ->getName();
  $field_config_target_entity_type_id = $field_config
    ->getTargetEntityTypeId();
  $field_config_target_bundle = $field_config
    ->getTargetBundle();

  // Get the view displays on the source entity bundle.
  $display_ids = $this->entityTypeManager
    ->getStorage($display_type)
    ->getQuery()
    ->condition('targetEntityType', $field_config_target_entity_type_id)
    ->condition('bundle', $field_config_target_bundle)
    ->execute();
  $original_field_bundle_displays = $this->entityTypeManager
    ->getStorage($display_type)
    ->loadMultiple($display_ids);

  // Get the views displays on the destination's target entity bundle.
  $display_ids = $this->entityTypeManager
    ->getStorage($display_type)
    ->getQuery()
    ->condition('targetEntityType', $destination_entity_type_id)
    ->condition('bundle', $destination_bundle)
    ->execute();
  $displays = $this->entityTypeManager
    ->getStorage($display_type)
    ->loadMultiple($display_ids);

  // Re-key this array by the mode name.
  $duplicate_field_bundle_displays = [];
  foreach ($displays as $display) {
    $duplicate_field_bundle_displays[$display
      ->getMode()] = $display;
  }

  // Work over the original field's view displays.
  foreach ($original_field_bundle_displays as $display) {

    // If the destination bundle doesn't have a display of the same name,
    // skip this.
    if (!isset($duplicate_field_bundle_displays[$display
      ->getMode()])) {
      continue;
    }
    $destination_display = $duplicate_field_bundle_displays[$display
      ->getMode()];

    // Get the settings for the field in this display.
    $field_component = $display
      ->getComponent($field_name);

    // Copy the settings to the duplicate field's view mode with the same
    // name.
    if (is_null($field_component)) {

      // Explicitly hide the field, so it's set in the display.
      $destination_display
        ->removeComponent($field_name);
    }
    else {
      $destination_display
        ->setComponent($field_name, $field_component);
    }

    // Copy field groups.
    if ($this->moduleHandler
      ->moduleExists('field_group')) {
      $source_display_field_group_settings = $display
        ->getThirdPartySettings('field_group');
      $destination_display_field_group_settings = $destination_display
        ->getThirdPartySettings('field_group');

      // Attempt to find the field in one of the groups.
      foreach ($source_display_field_group_settings as $group_id => $group_settings) {
        if (in_array($field_name, $group_settings['children'])) {

          // Insert the field into the field group of the same name on the
          // destination, creating the field group if necessary.
          // Clone the field group if it's not there already.
          if (!isset($destination_display_field_group_settings[$group_id])) {
            $field_group_copy = $group_settings;

            // Remove the children so the group starts off empty.
            $field_group_copy['children'] = [];
            $destination_display_field_group_settings[$group_id] = $field_group_copy;
          }

          // Splice the new field into the destination field group, attempting
          // to use the same position.
          $position = array_search($field_name, $group_settings['children']);
          array_splice($destination_display_field_group_settings[$group_id]['children'], $position, 0, [
            $field_name,
          ]);

          // Update the field group settings on the destination display.
          $destination_display
            ->setThirdPartySetting('field_group', $group_id, $destination_display_field_group_settings[$group_id]);

          // The field can be in only one group, so we're done: stop looking
          // at groups.
          break;
        }
      }
    }
    $destination_display
      ->save();
  }
}