class DisplayCloner in Field tools 8
Contains methods for cloning displays.
Hierarchy
- class \Drupal\field_tools\DisplayCloner
Expanded class hierarchy of DisplayCloner
1 file declares its use of DisplayCloner
1 string reference to 'DisplayCloner'
1 service uses DisplayCloner
File
- src/
DisplayCloner.php, line 13
Namespace
Drupal\field_toolsView source
class DisplayCloner {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The entity field manager service.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* Constructs a new FieldCloner.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* The entity field manager service.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, ModuleHandlerInterface $module_handler) {
$this->entityTypeManager = $entity_type_manager;
$this->entityFieldManager = $entity_field_manager;
$this->moduleHandler = $module_handler;
}
/**
* Clone or merge a form or view display to a new bundle.
*
* Display settings are copied to the new bundle.
* - Fields which are present on the source but not the target are ignored.
* If the target already has this display:
* - Fields which are on the both source and target have their settings
* overwritten.
* - Fields which are on the target only but not the source have their
* settings left untouched.
*
* @param \Drupal\Core\Entity\EntityDisplayBase $source_entity_display
* The entity display (form or view) to clone.
* @param string $destination_bundle
* The destination bundle.
*/
public function cloneDisplay(EntityDisplayBase $source_entity_display, $destination_bundle) {
$display_entity_type = $source_entity_display
->getEntityTypeId();
// Have to deduce the context from the entity type, as there's no accessor
// for $displayContext: see https://www.drupal.org/node/2823807.
if ($display_entity_type == 'entity_form_display') {
$context = 'form';
}
else {
$context = 'view';
}
$target_entity_type_id = $source_entity_display
->getTargetEntityTypeId();
$source_bundle = $source_entity_display
->getTargetBundle();
$mode_name = $source_entity_display
->getMode();
// Try to load the destination display.
$destination_display = $this->entityTypeManager
->getStorage($display_entity_type)
->load($target_entity_type_id . '.' . $destination_bundle . '.' . $mode_name);
if (empty($destination_display)) {
// Create a new display, duplicating the source. We keep the mode the same
// but then change the target bundle.
$destination_display = $source_entity_display
->createCopy($source_entity_display
->getMode());
$destination_display
->setTargetBundle($destination_bundle);
}
// Get all fields on destination bundle.
$destination_bundle_fields = array_filter($this->entityFieldManager
->getFieldDefinitions($target_entity_type_id, $destination_bundle), function ($field_definition) {
return !$field_definition
->isComputed();
});
// Get the display components from the source display, and copy them to the
// destination.
// This only returns visible fields.
$components = $source_entity_display
->getComponents();
foreach ($components as $field_name => $source_display_field_component) {
// Skip fields that do not exist on the destination bundle.
if (!isset($destination_bundle_fields[$field_name])) {
continue;
}
$destination_display
->setComponent($field_name, $source_display_field_component);
}
// Copy field groups.
if ($this->moduleHandler
->moduleExists('field_group')) {
$field_group_settings = $source_entity_display
->getThirdPartySettings('field_group');
foreach ($field_group_settings as $group_id => $group_settings) {
// Remove any fields in groups which do not exist on the destination
// bundle.
foreach ($group_settings['children'] as $index => $child_field) {
if (!isset($destination_bundle_field_names[$child_field])) {
unset($group_settings['children'][$index]);
}
}
// Skip groups which don't have any fields left in them.
if (empty($group_settings['children'])) {
continue;
}
// TODO: rekey the numeric 'children' array?
// Set the group in the destination display.
// (There's no setThirdPartySetting*s*() method...)
$destination_display
->setThirdPartySetting('field_group', $group_id, $group_settings);
}
}
// Save the display.
$destination_display
->save();
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DisplayCloner:: |
protected | property | The entity field manager service. | |
DisplayCloner:: |
protected | property | The entity type manager. | |
DisplayCloner:: |
protected | property | The module handler. | |
DisplayCloner:: |
public | function | Clone or merge a form or view display to a new bundle. | |
DisplayCloner:: |
public | function | Constructs a new FieldCloner. |