diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php index ce88527..7f4d393 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php @@ -4,6 +4,7 @@ use Drupal\Core\Entity\Entity\EntityViewMode; use Drupal\Core\Entity\EntityDisplayRepositoryInterface; +use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; @@ -57,6 +58,13 @@ class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase implem protected $entityDisplayRepository; /** + * The entity type bundle info. + * + * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface + */ + protected $entityTypeBundleInfo; + + /** * An array of counters for the recursive rendering protection. * * Each counter takes into account all the relevant information about the @@ -91,12 +99,15 @@ class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase implem * The entity type manager. * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository * The entity display repository. + * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info + * The entity type bundle info. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, LoggerChannelFactoryInterface $logger_factory, EntityTypeManagerInterface $entity_type_manager, EntityDisplayRepositoryInterface $entity_display_repository) { + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, LoggerChannelFactoryInterface $logger_factory, EntityTypeManagerInterface $entity_type_manager, EntityDisplayRepositoryInterface $entity_display_repository, EntityTypeBundleInfoInterface $entity_type_bundle_info) { parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); $this->loggerFactory = $logger_factory; $this->entityTypeManager = $entity_type_manager; $this->entityDisplayRepository = $entity_display_repository; + $this->entityTypeBundleInfo = $entity_type_bundle_info; } /** @@ -113,7 +124,8 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['third_party_settings'], $container->get('logger.factory'), $container->get('entity_type.manager'), - $container->get('entity_display.repository') + $container->get('entity_display.repository'), + $container->get('entity_type.bundle.info') ); } @@ -127,10 +139,6 @@ public static function defaultSettings() { ] + parent::defaultSettings(); } - protected function getSelectedViewModeName(FormStateInterface $form_state) { - return $this->getSetting('view_mode', $form_state); - } - /** * Wrapper around ::getSetting() to reflect current values from Form State. * @@ -180,10 +188,18 @@ public static function rebuildOnSubmit(array &$form, FormStateInterface $form_st */ public function settingsForm(array $form, FormStateInterface $form_state) { $entity_type_id = $this->getFieldSetting('target_type'); + $entity_type_label = $this->entityTypeManager->getDefinition($entity_type_id)->getLabel(); $bundle_entity_type_id = $this->entityTypeManager->getDefinition($entity_type_id)->getBundleEntityType(); - $bundles = array_keys($this->getFieldSetting('handler_settings')['target_bundles']); + $target_bundles_setting = $this->getFieldSetting('handler_settings')['target_bundles']; + if ($target_bundles_setting === NULL) { + // If no bundle is configured in the field settings, all are selectable. + $bundles = array_keys($this->entityTypeBundleInfo->getBundleInfo($entity_type_id)); + } + else { + $bundles = array_keys($target_bundles_setting); + } - $currently_selected_view_mode_name = $this->getSelectedViewModeName($form_state); + $currently_selected_view_mode_name = $this->getSetting('view_mode', $form_state); $currently_selected_view_mode = EntityViewMode::load("$entity_type_id.$currently_selected_view_mode_name"); // @todo Simplify this in https://www.drupal.org/node/2844203. $currently_selected_view_mode_label = $currently_selected_view_mode ? $currently_selected_view_mode->label() : $this->t('Default'); @@ -195,7 +211,12 @@ public function settingsForm(array $form, FormStateInterface $form_state) { '#context' => ['list_style' => 'comma-list'], '#items' => [], ]; - if (count($bundles) === 1) { + // If targeting entities of the same type this field is attached to, skip + // the viewmode for the bundle we are currently editing, once it wouldn't + // make sense to open in the modal the same form we have on the main page. + if (count($bundles) === 1 && !($entity_type_id === $this->fieldDefinition->getTargetEntityTypeId() + && $bundles[0] === $form_state->getFormObject()->getEntity()->getTargetBundle() + && $currently_selected_view_mode_name === $this->viewMode)) { $description['#items'][] = [ '#type' => 'link', '#title' => $this->t('Configure %view-mode-label view mode', ['%view-mode-label' => $currently_selected_view_mode_label]), @@ -214,12 +235,15 @@ public function settingsForm(array $form, FormStateInterface $form_state) { else { $bundle_info = entity_get_bundles($entity_type_id); for ($i = 0; $i < count($bundles); $i++) { + $skip_bundle = $entity_type_id === $this->fieldDefinition->getTargetEntityTypeId() + && $bundles[$i] === $form_state->getFormObject()->getEntity()->getTargetBundle() + && $currently_selected_view_mode_name === $this->viewMode; + if ($skip_bundle) { + continue; + } $description['#items'][] = [ '#type' => 'link', - '#prefix' => $i == 0 - ? $this->t('Configure %view-mode-label view mode for', ['%view-mode-label' => $currently_selected_view_mode_label]) . ' ' - : '', - '#title' => $this->t('%bundle-label %entity-type-label', ['%bundle-label' => $bundle_info[$bundles[$i]]['label'], '%entity-type-label' => 'Media items']), + '#title' => $this->t('%bundle-label %entity-type-label', ['%bundle-label' => $bundle_info[$bundles[$i]]['label'], '%entity-type-label' => $entity_type_label]), '#url' => $currently_selected_view_mode_name === 'default' ? Url::fromRoute(sprintf('entity.entity_view_display.%s.default', $entity_type_id), [$bundle_entity_type_id => $bundles[$i]]) : Url::fromRoute(sprintf('entity.entity_view_display.%s.view_mode', $entity_type_id), [$bundle_entity_type_id => $bundles[$i], 'view_mode_name' => $currently_selected_view_mode_name]), @@ -232,11 +256,17 @@ public function settingsForm(array $form, FormStateInterface $form_state) { ], ]; } + if (!empty($description['#items'][0])) { + $description['#items'][0]['#prefix'] = $this->t('Configure %view-mode-label view mode for', [ + '%view-mode-label' => $currently_selected_view_mode_label, + ]) . ' '; + } } + $description['#items'][] = [ '#type' => 'link', - '#title' => $this->t('add new view mode'), - '#prefix' => Markup::create(t('or') . ' '), + '#title' => !empty($description['#items']) ? $this->t('add new view mode') : $this->t('Add new view mode'), + '#prefix' => !empty($description['#items']) ? Markup::create(t('or') . ' ') : '', '#url' => Url::fromRoute('entity.entity_view_mode.add_form', ['entity_type_id' => $entity_type_id]), '#attributes' => [ 'class' => ['use-ajax'], @@ -260,7 +290,7 @@ public function settingsForm(array $form, FormStateInterface $form_state) { '#executes_submit_callback' => TRUE, '#required' => TRUE, '#description' => $description + [ - '#access' => \Drupal::currentUser()->hasPermission('administer ' . $entity_type_id . ' display') + '#access' => \Drupal::currentUser()->hasPermission('administer ' . $entity_type_id . ' display'), ], ]; diff --git a/core/modules/field_ui/src/Form/EntityDisplayModeFormBase.php b/core/modules/field_ui/src/Form/EntityDisplayModeFormBase.php index 72a8a19..ae5f381 100644 --- a/core/modules/field_ui/src/Form/EntityDisplayModeFormBase.php +++ b/core/modules/field_ui/src/Form/EntityDisplayModeFormBase.php @@ -2,6 +2,9 @@ namespace Drupal\field_ui\Form; +use Drupal\Core\Ajax\AjaxResponse; +use Drupal\Core\Ajax\CloseModalDialogCommand; +use Drupal\Core\Ajax\HtmlCommand; use Drupal\Core\Entity\EntityForm; use Drupal\Core\Form\FormStateInterface; @@ -84,4 +87,41 @@ public function save(array $form, FormStateInterface $form_state) { $form_state->setRedirectUrl($this->entity->urlInfo('collection')); } + /** + * {@inheritdoc} + */ + public function actions(array $form, FormStateInterface $form_state) { + $actions = parent::actions($form, $form_state); + $actions['submit']['#ajax'] = [ + 'callback' => '::ajaxCallback', + 'event' => 'click', + ]; + return $actions; + } + + /** + * Ajax callback to close the modal and update the selected text. + * + * @return \Drupal\Core\Ajax\AjaxResponse + * An ajax response object. + */ + public function ajaxCallback(array $form, FormStateInterface $form_state) { + $response = new AjaxResponse(); + if ($form_state->getErrors()) { + unset($form['#prefix'], $form['#suffix']); + $form['status_messages'] = [ + '#type' => 'status_messages', + '#weight' => -10, + ]; + $response->addCommand(new HtmlCommand('#drupal-modal', $form)); + } + else { + // @TODO Show message for successful saving of settings once + // https://www.drupal.org/node/77245 lands. This message is set by + // \Drupal\field_ui\Form\EntityDisplayFormBase::submitForm(). + $response->addCommand(new CloseModalDialogCommand()); + } + return $response; + } + }