3 namespace Drupal\field_ui\Form;
5 use Drupal\Component\Plugin\Factory\DefaultFactory;
6 use Drupal\Component\Plugin\PluginManagerBase;
7 use Drupal\Core\Entity\EntityForm;
8 use Drupal\Core\Entity\EntityInterface;
9 use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
10 use Drupal\Core\Field\FieldDefinitionInterface;
11 use Drupal\Core\Field\FieldTypePluginManagerInterface;
12 use Drupal\Core\Field\PluginSettingsInterface;
13 use Drupal\Core\Form\FormStateInterface;
14 use Drupal\Core\Routing\RouteMatchInterface;
15 use Drupal\field_ui\Element\FieldUiTable;
16 use Drupal\field_ui\FieldUI;
19 * Base class for EntityDisplay edit forms.
21 abstract class EntityDisplayFormBase extends EntityForm {
24 * The display context. Either 'view' or 'form'.
28 protected $displayContext;
31 * The widget or formatter plugin manager.
33 * @var \Drupal\Component\Plugin\PluginManagerBase
35 protected $pluginManager;
38 * A list of field types.
42 protected $fieldTypes;
45 * The entity being used by this form.
47 * @var \Drupal\Core\Entity\Display\EntityDisplayInterface
52 * Constructs a new EntityDisplayFormBase.
54 * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager
55 * The field type manager.
56 * @param \Drupal\Component\Plugin\PluginManagerBase $plugin_manager
57 * The widget or formatter plugin manager.
59 public function __construct(FieldTypePluginManagerInterface $field_type_manager, PluginManagerBase $plugin_manager) {
60 $this->fieldTypes = $field_type_manager->getDefinitions();
61 $this->pluginManager = $plugin_manager;
67 public function getEntityFromRouteMatch(RouteMatchInterface $route_match, $entity_type_id) {
68 $route_parameters = $route_match->getParameters()->all();
70 return $this->getEntityDisplay($route_parameters['entity_type_id'], $route_parameters['bundle'], $route_parameters[$this->displayContext . '_mode_name']);
74 * Get the regions needed to create the overview form.
81 * // label for the region.
82 * 'title' => $this->t('Content'),
83 * // Indicates if the region is visible in the UI.
84 * 'invisible' => TRUE,
85 * // A message to indicate that there is nothing to be displayed in
87 * 'message' => $this->t('No field is displayed.'),
92 public function getRegions() {
95 'title' => $this->t('Content'),
97 'message' => $this->t('No field is displayed.'),
100 'title' => $this->t('Disabled', [], ['context' => 'Plural']),
101 'message' => $this->t('No field is hidden.'),
107 * Returns an associative array of all regions.
110 * An array containing the region options.
112 public function getRegionOptions() {
114 foreach ($this->getRegions() as $region => $data) {
115 $options[$region] = $data['title'];
121 * Collects the definitions of fields whose display is configurable.
123 * @return \Drupal\Core\Field\FieldDefinitionInterface[]
124 * The array of field definitions
126 protected function getFieldDefinitions() {
127 $context = $this->displayContext;
128 return array_filter($this->entityManager->getFieldDefinitions($this->entity->getTargetEntityTypeId(), $this->entity->getTargetBundle()), function (FieldDefinitionInterface $field_definition) use ($context) {
129 return $field_definition->isDisplayConfigurable($context);
136 public function form(array $form, FormStateInterface $form_state) {
137 $form = parent::form($form, $form_state);
139 $field_definitions = $this->getFieldDefinitions();
140 $extra_fields = $this->getExtraFields();
143 '#entity_type' => $this->entity->getTargetEntityTypeId(),
144 '#bundle' => $this->entity->getTargetBundle(),
145 '#fields' => array_keys($field_definitions),
146 '#extra' => array_keys($extra_fields),
149 if (empty($field_definitions) && empty($extra_fields) && $route_info = FieldUI::getOverviewRouteInfo($this->entity->getTargetEntityTypeId(), $this->entity->getTargetBundle())) {
150 $this->messenger()->addWarning($this->t('There are no fields yet added. You can add new fields on the <a href=":link">Manage fields</a> page.', [':link' => $route_info->toString()]));
155 '#type' => 'field_ui_table',
156 '#header' => $this->getTableHeader(),
157 '#regions' => $this->getRegions(),
159 'class' => ['field-ui-overview'],
160 'id' => 'field-display-overview',
165 'relationship' => 'sibling',
166 'group' => 'field-weight',
170 'relationship' => 'parent',
171 'group' => 'field-parent',
172 'subgroup' => 'field-parent',
173 'source' => 'field-name',
177 'relationship' => 'parent',
178 'group' => 'field-region',
179 'subgroup' => 'field-region',
180 'source' => 'field-name',
186 foreach ($field_definitions as $field_name => $field_definition) {
187 $table[$field_name] = $this->buildFieldRow($field_definition, $form, $form_state);
190 // Non-field elements.
191 foreach ($extra_fields as $field_id => $extra_field) {
192 $table[$field_id] = $this->buildExtraFieldRow($field_id, $extra_field);
195 $form['fields'] = $table;
197 // Custom display settings.
198 if ($this->entity->getMode() == 'default') {
199 // Only show the settings if there is at least one custom display mode.
200 $display_mode_options = $this->getDisplayModeOptions();
201 // Unset default option.
202 unset($display_mode_options['default']);
203 if ($display_mode_options) {
205 '#type' => 'details',
206 '#title' => $this->t('Custom display settings'),
208 // Prepare default values for the 'Custom display settings' checkboxes.
210 if ($enabled_displays = array_filter($this->getDisplayStatuses())) {
211 $default = array_keys(array_intersect_key($display_mode_options, $enabled_displays));
213 natcasesort($display_mode_options);
214 $form['modes']['display_modes_custom'] = [
215 '#type' => 'checkboxes',
216 '#title' => $this->t('Use custom display settings for the following @display_context modes', ['@display_context' => $this->displayContext]),
217 '#options' => $display_mode_options,
218 '#default_value' => $default,
220 // Provide link to manage display modes.
221 $form['modes']['display_modes_link'] = $this->getDisplayModesLink();
225 // In overviews involving nested rows from contributed modules (i.e
226 // field_group), the 'plugin type' selects can trigger a series of changes
227 // in child rows. The #ajax behavior is therefore not attached directly to
228 // the selects, but triggered by the client-side script through a hidden
229 // #ajax 'Refresh' button. A hidden 'refresh_rows' input tracks the name of
231 $form['refresh_rows'] = ['#type' => 'hidden'];
234 '#value' => $this->t('Refresh'),
235 '#op' => 'refresh_table',
236 '#submit' => ['::multistepSubmit'],
238 'callback' => '::multistepAjax',
239 'wrapper' => 'field-display-overview-wrapper',
241 // The button stays hidden, so we hide the Ajax spinner too. Ad-hoc
242 // spinners will be added manually by the client-side script.
243 'progress' => 'none',
245 '#attributes' => ['class' => ['visually-hidden']],
248 $form['actions'] = ['#type' => 'actions'];
249 $form['actions']['submit'] = [
251 '#button_type' => 'primary',
252 '#value' => $this->t('Save'),
255 $form['#attached']['library'][] = 'field_ui/drupal.field_ui';
261 * Builds the table row structure for a single field.
263 * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
264 * The field definition.
266 * An associative array containing the structure of the form.
267 * @param \Drupal\Core\Form\FormStateInterface $form_state
268 * The current state of the form.
273 protected function buildFieldRow(FieldDefinitionInterface $field_definition, array $form, FormStateInterface $form_state) {
274 $field_name = $field_definition->getName();
275 $display_options = $this->entity->getComponent($field_name);
276 $label = $field_definition->getLabel();
278 // Disable fields without any applicable plugins.
279 if (empty($this->getApplicablePluginOptions($field_definition))) {
280 $this->entity->removeComponent($field_name)->save();
281 $display_options = $this->entity->getComponent($field_name);
284 $regions = array_keys($this->getRegions());
286 '#attributes' => ['class' => ['draggable', 'tabledrag-leaf']],
287 '#row_type' => 'field',
288 '#region_callback' => [$this, 'getRowRegion'],
290 'rowHandler' => 'field',
291 'defaultPlugin' => $this->getDefaultPlugin($field_definition->getType()),
294 '#plain_text' => $label,
297 '#type' => 'textfield',
298 '#title' => $this->t('Weight for @title', ['@title' => $label]),
299 '#title_display' => 'invisible',
300 '#default_value' => $display_options ? $display_options['weight'] : '0',
302 '#attributes' => ['class' => ['field-weight']],
304 'parent_wrapper' => [
307 '#title' => $this->t('Label display for @title', ['@title' => $label]),
308 '#title_display' => 'invisible',
309 '#options' => array_combine($regions, $regions),
310 '#empty_value' => '',
311 '#attributes' => ['class' => ['js-field-parent', 'field-parent']],
312 '#parents' => ['fields', $field_name, 'parent'],
316 '#default_value' => $field_name,
317 '#attributes' => ['class' => ['field-name']],
322 '#title' => $this->t('Region for @title', ['@title' => $label]),
323 '#title_display' => 'invisible',
324 '#options' => $this->getRegionOptions(),
325 '#default_value' => $display_options ? $display_options['region'] : 'hidden',
326 '#attributes' => ['class' => ['field-region']],
330 $field_row['plugin'] = [
333 '#title' => $this->t('Plugin for @title', ['@title' => $label]),
334 '#title_display' => 'invisible',
335 '#options' => $this->getApplicablePluginOptions($field_definition),
336 '#default_value' => $display_options ? $display_options['type'] : 'hidden',
337 '#parents' => ['fields', $field_name, 'type'],
338 '#attributes' => ['class' => ['field-plugin-type']],
340 'settings_edit_form' => [],
343 // Get the corresponding plugin object.
344 $plugin = $this->entity->getRenderer($field_name);
346 // Base button element for the various plugin settings actions.
348 '#submit' => ['::multistepSubmit'],
350 'callback' => '::multistepAjax',
351 'wrapper' => 'field-display-overview-wrapper',
354 '#field_name' => $field_name,
357 if ($form_state->get('plugin_settings_edit') == $field_name) {
358 // We are currently editing this field's plugin settings. Display the
359 // settings form and submit buttons.
360 $field_row['plugin']['settings_edit_form'] = [];
363 // Generate the settings form and allow other modules to alter it.
364 $settings_form = $plugin->settingsForm($form, $form_state);
365 $third_party_settings_form = $this->thirdPartySettingsForm($plugin, $field_definition, $form, $form_state);
367 if ($settings_form || $third_party_settings_form) {
368 $field_row['plugin']['#cell_attributes'] = ['colspan' => 3];
369 $field_row['plugin']['settings_edit_form'] = [
370 '#type' => 'container',
371 '#attributes' => ['class' => ['field-plugin-settings-edit-form']],
372 '#parents' => ['fields', $field_name, 'settings_edit_form'],
374 '#markup' => $this->t('Plugin settings'),
376 'settings' => $settings_form,
377 'third_party_settings' => $third_party_settings_form,
379 '#type' => 'actions',
380 'save_settings' => $base_button + [
382 '#button_type' => 'primary',
383 '#name' => $field_name . '_plugin_settings_update',
384 '#value' => $this->t('Update'),
387 'cancel_settings' => $base_button + [
389 '#name' => $field_name . '_plugin_settings_cancel',
390 '#value' => $this->t('Cancel'),
392 // Do not check errors for the 'Cancel' button, but make sure we
393 // get the value of the 'plugin type' select.
394 '#limit_validation_errors' => [['fields', $field_name, 'type']],
398 $field_row['#attributes']['class'][] = 'field-plugin-settings-editing';
403 $field_row['settings_summary'] = [];
404 $field_row['settings_edit'] = [];
407 // Display a summary of the current plugin settings, and (if the
408 // summary is not empty) a button to edit them.
409 $summary = $plugin->settingsSummary();
411 // Allow other modules to alter the summary.
412 $this->alterSettingsSummary($summary, $plugin, $field_definition);
414 if (!empty($summary)) {
415 $field_row['settings_summary'] = [
416 '#type' => 'inline_template',
417 '#template' => '<div class="field-plugin-summary">{{ summary|safe_join("<br />") }}</div>',
418 '#context' => ['summary' => $summary],
419 '#cell_attributes' => ['class' => ['field-plugin-summary-cell']],
423 // Check selected plugin settings to display edit link or not.
424 $settings_form = $plugin->settingsForm($form, $form_state);
425 $third_party_settings_form = $this->thirdPartySettingsForm($plugin, $field_definition, $form, $form_state);
426 if (!empty($settings_form) || !empty($third_party_settings_form)) {
427 $field_row['settings_edit'] = $base_button + [
428 '#type' => 'image_button',
429 '#name' => $field_name . '_settings_edit',
430 '#src' => 'core/misc/icons/787878/cog.svg',
431 '#attributes' => ['class' => ['field-plugin-settings-edit'], 'alt' => $this->t('Edit')],
433 // Do not check errors for the 'Edit' button, but make sure we get
434 // the value of the 'plugin type' select.
435 '#limit_validation_errors' => [['fields', $field_name, 'type']],
436 '#prefix' => '<div class="field-plugin-settings-edit-wrapper">',
437 '#suffix' => '</div>',
447 * Builds the table row structure for a single extra field.
449 * @param string $field_id
451 * @param array $extra_field
452 * The pseudo-field element.
457 protected function buildExtraFieldRow($field_id, $extra_field) {
458 $display_options = $this->entity->getComponent($field_id);
460 $regions = array_keys($this->getRegions());
462 '#attributes' => ['class' => ['draggable', 'tabledrag-leaf']],
463 '#row_type' => 'extra_field',
464 '#region_callback' => [$this, 'getRowRegion'],
465 '#js_settings' => ['rowHandler' => 'field'],
467 '#markup' => $extra_field['label'],
470 '#type' => 'textfield',
471 '#title' => $this->t('Weight for @title', ['@title' => $extra_field['label']]),
472 '#title_display' => 'invisible',
473 '#default_value' => $display_options ? $display_options['weight'] : 0,
475 '#attributes' => ['class' => ['field-weight']],
477 'parent_wrapper' => [
480 '#title' => $this->t('Parents for @title', ['@title' => $extra_field['label']]),
481 '#title_display' => 'invisible',
482 '#options' => array_combine($regions, $regions),
483 '#empty_value' => '',
484 '#attributes' => ['class' => ['js-field-parent', 'field-parent']],
485 '#parents' => ['fields', $field_id, 'parent'],
489 '#default_value' => $field_id,
490 '#attributes' => ['class' => ['field-name']],
495 '#title' => $this->t('Region for @title', ['@title' => $extra_field['label']]),
496 '#title_display' => 'invisible',
497 '#options' => $this->getRegionOptions(),
498 '#default_value' => $display_options ? $display_options['region'] : 'hidden',
499 '#attributes' => ['class' => ['field-region']],
504 '#value' => $display_options ? 'visible' : 'hidden',
505 '#parents' => ['fields', $field_id, 'type'],
506 '#attributes' => ['class' => ['field-plugin-type']],
509 'settings_summary' => [],
510 'settings_edit' => [],
513 return $extra_field_row;
519 public function submitForm(array &$form, FormStateInterface $form_state) {
520 // If the main "Save" button was submitted while a field settings subform
521 // was being edited, update the new incoming settings when rebuilding the
522 // entity, just as if the subform's "Update" button had been submitted.
523 if ($edit_field = $form_state->get('plugin_settings_edit')) {
524 $form_state->set('plugin_settings_update', $edit_field);
527 parent::submitForm($form, $form_state);
528 $form_values = $form_state->getValues();
530 // Handle the 'display modes' checkboxes if present.
531 if ($this->entity->getMode() == 'default' && !empty($form_values['display_modes_custom'])) {
532 $display_modes = $this->getDisplayModes();
533 $current_statuses = $this->getDisplayStatuses();
536 foreach ($form_values['display_modes_custom'] as $mode => $value) {
537 if (!empty($value) && empty($current_statuses[$mode])) {
538 // If no display exists for the newly enabled view mode, initialize
539 // it with those from the 'default' view mode, which were used so
541 if (!$this->entityManager->getStorage($this->entity->getEntityTypeId())->load($this->entity->getTargetEntityTypeId() . '.' . $this->entity->getTargetBundle() . '.' . $mode)) {
542 $display = $this->getEntityDisplay($this->entity->getTargetEntityTypeId(), $this->entity->getTargetBundle(), 'default')->createCopy($mode);
546 $display_mode_label = $display_modes[$mode]['label'];
547 $url = $this->getOverviewUrl($mode);
548 $this->messenger()->addStatus($this->t('The %display_mode mode now uses custom display settings. You might want to <a href=":url">configure them</a>.', ['%display_mode' => $display_mode_label, ':url' => $url->toString()]));
550 $statuses[$mode] = !empty($value);
553 $this->saveDisplayStatuses($statuses);
556 $this->messenger()->addStatus($this->t('Your settings have been saved.'));
562 protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) {
563 $form_values = $form_state->getValues();
565 if ($this->entity instanceof EntityWithPluginCollectionInterface) {
566 // Do not manually update values represented by plugin collections.
567 $form_values = array_diff_key($form_values, $this->entity->getPluginCollections());
570 // Collect data for 'regular' fields.
571 foreach ($form['#fields'] as $field_name) {
572 $values = $form_values['fields'][$field_name];
574 if ($values['region'] == 'hidden') {
575 $entity->removeComponent($field_name);
578 $options = $entity->getComponent($field_name);
580 // Update field settings only if the submit handler told us to.
581 if ($form_state->get('plugin_settings_update') === $field_name) {
582 // Only store settings actually used by the selected plugin.
583 $default_settings = $this->pluginManager->getDefaultSettings($options['type']);
584 $options['settings'] = isset($values['settings_edit_form']['settings']) ? array_intersect_key($values['settings_edit_form']['settings'], $default_settings) : [];
585 $options['third_party_settings'] = isset($values['settings_edit_form']['third_party_settings']) ? $values['settings_edit_form']['third_party_settings'] : [];
586 $form_state->set('plugin_settings_update', NULL);
589 $options['type'] = $values['type'];
590 $options['weight'] = $values['weight'];
591 $options['region'] = $values['region'];
592 // Only formatters have configurable label visibility.
593 if (isset($values['label'])) {
594 $options['label'] = $values['label'];
596 $entity->setComponent($field_name, $options);
600 // Collect data for 'extra' fields.
601 foreach ($form['#extra'] as $name) {
602 if ($form_values['fields'][$name]['region'] == 'hidden') {
603 $entity->removeComponent($name);
606 $entity->setComponent($name, [
607 'weight' => $form_values['fields'][$name]['weight'],
608 'region' => $form_values['fields'][$name]['region'],
615 * Form submission handler for multistep buttons.
617 public function multistepSubmit($form, FormStateInterface $form_state) {
618 $trigger = $form_state->getTriggeringElement();
619 $op = $trigger['#op'];
623 // Store the field whose settings are currently being edited.
624 $field_name = $trigger['#field_name'];
625 $form_state->set('plugin_settings_edit', $field_name);
629 // Set the field back to 'non edit' mode, and update $this->entity with
630 // the new settings fro the next rebuild.
631 $field_name = $trigger['#field_name'];
632 $form_state->set('plugin_settings_edit', NULL);
633 $form_state->set('plugin_settings_update', $field_name);
634 $this->entity = $this->buildEntity($form, $form_state);
638 // Set the field back to 'non edit' mode.
639 $form_state->set('plugin_settings_edit', NULL);
642 case 'refresh_table':
643 // If the currently edited field is one of the rows to be refreshed, set
644 // it back to 'non edit' mode.
645 $updated_rows = explode(' ', $form_state->getValue('refresh_rows'));
646 $plugin_settings_edit = $form_state->get('plugin_settings_edit');
647 if ($plugin_settings_edit && in_array($plugin_settings_edit, $updated_rows)) {
648 $form_state->set('plugin_settings_edit', NULL);
653 $form_state->setRebuild();
657 * Ajax handler for multistep buttons.
659 public function multistepAjax($form, FormStateInterface $form_state) {
660 $trigger = $form_state->getTriggeringElement();
661 $op = $trigger['#op'];
663 // Pick the elements that need to receive the ajax-new-content effect.
666 $updated_rows = [$trigger['#field_name']];
667 $updated_columns = ['plugin'];
672 $updated_rows = [$trigger['#field_name']];
673 $updated_columns = ['plugin', 'settings_summary', 'settings_edit'];
676 case 'refresh_table':
677 $updated_rows = array_values(explode(' ', $form_state->getValue('refresh_rows')));
678 $updated_columns = ['settings_summary', 'settings_edit'];
682 foreach ($updated_rows as $name) {
683 foreach ($updated_columns as $key) {
684 $element = &$form['fields'][$name][$key];
685 $element['#prefix'] = '<div class="ajax-new-content">' . (isset($element['#prefix']) ? $element['#prefix'] : '');
686 $element['#suffix'] = (isset($element['#suffix']) ? $element['#suffix'] : '') . '</div>';
690 // Return the whole table.
691 return $form['fields'];
695 * Performs pre-render tasks on field_ui_table elements.
697 * @param array $elements
698 * A structured array containing two sub-levels of elements. Properties
700 * - #tabledrag: The value is a list of $options arrays that are passed to
701 * drupal_attach_tabledrag(). The HTML ID of the table is added to each
706 * @see \Drupal\Core\Render\RendererInterface::render()
707 * @see \Drupal\Core\Render\Element\Table::preRenderTable()
709 * @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
711 public function tablePreRender($elements) {
712 return FieldUiTable::tablePreRender($elements);
716 * Determines the rendering order of an array representing a tree.
718 * Callback for array_reduce() within
719 * \Drupal\field_ui\Form\EntityDisplayFormBase::tablePreRender().
721 * @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
723 public function reduceOrder($array, $a) {
724 return FieldUiTable::reduceOrder($array, $a);
728 * Returns the extra fields of the entity type and bundle used by this form.
731 * An array of extra field info.
733 * @see \Drupal\Core\Entity\EntityManagerInterface::getExtraFields()
735 protected function getExtraFields() {
736 $context = $this->displayContext == 'view' ? 'display' : $this->displayContext;
737 $extra_fields = $this->entityManager->getExtraFields($this->entity->getTargetEntityTypeId(), $this->entity->getTargetBundle());
738 return isset($extra_fields[$context]) ? $extra_fields[$context] : [];
742 * Returns an entity display object to be used by this form.
744 * @param string $entity_type_id
745 * The target entity type ID of the entity display.
746 * @param string $bundle
747 * The target bundle of the entity display.
748 * @param string $mode
749 * A view or form mode.
751 * @return \Drupal\Core\Entity\Display\EntityDisplayInterface
754 abstract protected function getEntityDisplay($entity_type_id, $bundle, $mode);
757 * Returns an array of applicable widget or formatter options for a field.
759 * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
760 * The field definition.
763 * An array of applicable widget or formatter options.
765 protected function getApplicablePluginOptions(FieldDefinitionInterface $field_definition) {
766 $options = $this->pluginManager->getOptions($field_definition->getType());
767 $applicable_options = [];
768 foreach ($options as $option => $label) {
769 $plugin_class = DefaultFactory::getPluginClass($option, $this->pluginManager->getDefinition($option));
770 if ($plugin_class::isApplicable($field_definition)) {
771 $applicable_options[$option] = $label;
774 return $applicable_options;
778 * Returns the ID of the default widget or formatter plugin for a field type.
780 * @param string $field_type
784 * The widget or formatter plugin ID.
786 abstract protected function getDefaultPlugin($field_type);
789 * Returns the form or view modes used by this form.
792 * An array of form or view mode info.
794 abstract protected function getDisplayModes();
797 * Returns an array of form or view mode options.
800 * An array of form or view mode options.
802 abstract protected function getDisplayModeOptions();
805 * Returns a link to the form or view mode admin page.
808 * An array of a form element to be rendered as a link.
810 abstract protected function getDisplayModesLink();
813 * Returns the region to which a row in the display overview belongs.
818 * @return string|null
819 * The region name this row belongs to.
821 public function getRowRegion(&$row) {
822 $regions = $this->getRegions();
823 if (!isset($regions[$row['region']['#value']])) {
824 $row['region']['#value'] = 'hidden';
826 return $row['region']['#value'];
830 * Returns entity (form) displays for the current entity display type.
832 * @return \Drupal\Core\Entity\Display\EntityDisplayInterface[]
833 * An array holding entity displays or entity form displays.
835 protected function getDisplays() {
837 $display_entity_type = $this->entity->getEntityTypeId();
838 $entity_type = $this->entityManager->getDefinition($display_entity_type);
839 $config_prefix = $entity_type->getConfigPrefix();
840 $ids = $this->configFactory()->listAll($config_prefix . '.' . $this->entity->getTargetEntityTypeId() . '.' . $this->entity->getTargetBundle() . '.');
841 foreach ($ids as $id) {
842 $config_id = str_replace($config_prefix . '.', '', $id);
843 list(,, $display_mode) = explode('.', $config_id);
844 if ($display_mode != 'default') {
845 $load_ids[] = $config_id;
848 return $this->entityManager->getStorage($display_entity_type)->loadMultiple($load_ids);
852 * Returns form or view modes statuses for the bundle used by this form.
855 * An array of form or view mode statuses.
857 protected function getDisplayStatuses() {
858 $display_statuses = [];
859 $displays = $this->getDisplays();
860 foreach ($displays as $display) {
861 $display_statuses[$display->get('mode')] = $display->status();
863 return $display_statuses;
867 * Saves the updated display mode statuses.
869 * @param array $display_statuses
870 * An array holding updated form or view mode statuses.
872 protected function saveDisplayStatuses($display_statuses) {
873 $displays = $this->getDisplays();
874 foreach ($displays as $display) {
875 // Only update the display if the status is changing.
876 $new_status = $display_statuses[$display->get('mode')];
877 if ($new_status !== $display->status()) {
878 $display->set('status', $new_status);
885 * Returns an array containing the table headers.
890 abstract protected function getTableHeader();
893 * Returns the Url object for a specific entity (form) display edit form.
895 * @param string $mode
896 * The form or view mode.
898 * @return \Drupal\Core\Url
899 * A Url object for the overview route.
901 abstract protected function getOverviewUrl($mode);
904 * Adds the widget or formatter third party settings forms.
906 * @param \Drupal\Core\Field\PluginSettingsInterface $plugin
907 * The widget or formatter.
908 * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
909 * The field definition.
911 * The (entire) configuration form array.
912 * @param \Drupal\Core\Form\FormStateInterface $form_state
916 * The widget or formatter third party settings form.
918 abstract protected function thirdPartySettingsForm(PluginSettingsInterface $plugin, FieldDefinitionInterface $field_definition, array $form, FormStateInterface $form_state);
921 * Alters the widget or formatter settings summary.
923 * @param array $summary
924 * The widget or formatter settings summary.
925 * @param \Drupal\Core\Field\PluginSettingsInterface $plugin
926 * The widget or formatter.
927 * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
928 * The field definition.
930 abstract protected function alterSettingsSummary(array &$summary, PluginSettingsInterface $plugin, FieldDefinitionInterface $field_definition);