diff --git a/core/includes/entity.inc b/core/includes/entity.inc index 5b7cb3f..eaea5b8 100644 --- a/core/includes/entity.inc +++ b/core/includes/entity.inc @@ -595,62 +595,6 @@ function entity_get_display($entity_type, $bundle, $view_mode) { } /** - * Returns the entity_display object used to render an entity. - * - * Depending on the configuration of the view mode for the bundle, this can be - * either the display object associated to the view mode, or the 'default' - * display. - * - * This function should only be used internally when rendering an entity. When - * assigning suggested display options for a component in a given view mode, - * entity_get_display() should be used instead, in order to avoid inadvertently - * modifying the output of other view modes that might happen to use the - * 'default' display too. Those options will then be effectively applied only - * if the view mode is configured to use them. - * - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity being rendered. - * @param string $view_mode - * The view mode being rendered. - * - * @return \Drupal\Core\Entity\Display\EntityViewDisplayInterface - * The display object that should be used to render the entity. - * - * @see entity_get_display(). - */ -function entity_get_render_display(EntityInterface $entity, $view_mode) { - $entity_type = $entity->entityType(); - $bundle = $entity->bundle(); - $render_view_mode = 'default'; - - // Fall back to the default display if the display for the view mode does - // not exist or is disabled. - if ($view_mode != 'default') { - $ids = array( - 'default' => $entity_type . '.' . $bundle . '.default', - $view_mode => $entity_type . '.' . $bundle . '.' . $view_mode, - ); - $entity_displays = entity_load_multiple('entity_display', $ids); - if (isset($entity_displays[$ids[$view_mode]]) && $entity_displays[$ids[$view_mode]]->status()) { - $render_view_mode = $view_mode; - } - } - - $display = entity_get_display($entity_type, $bundle, $render_view_mode); - $display->originalMode = $view_mode; - - // Let modules alter the display. - $display_context = array( - 'entity_type' => $entity_type, - 'bundle' => $bundle, - 'view_mode' => $view_mode, - ); - drupal_alter('entity_display', $display, $display_context); - - return $display; -} - -/** * Returns the entity_form_display object associated to a bundle and form mode. * * The function reads the entity_form_display object from the current diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php index fb19c4e..0f69413 100644 --- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php +++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php @@ -12,6 +12,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\entity\Entity\EntityDisplay; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -193,7 +194,6 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la // Build the view modes and display objects. $view_modes = array(); - $displays = array(); $context = array('langcode' => $langcode); foreach ($entities as $key => $entity) { $bundle = $entity->bundle(); @@ -208,14 +208,10 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la drupal_alter('entity_view_mode', $entity_view_mode, $entity, $context); // Store entities for rendering by view_mode. $view_modes[$entity_view_mode][$entity->id()] = $entity; - - // Get the corresponding display settings. - if (!isset($displays[$entity_view_mode][$bundle])) { - $displays[$entity_view_mode][$bundle] = entity_get_render_display($entity, $entity_view_mode); - } } foreach ($view_modes as $mode => $view_mode_entities) { + $displays[$mode] = EntityDisplay::collectRenderDisplays($view_mode_entities, $mode); $this->buildContent($view_mode_entities, $displays[$mode], $mode, $langcode); } diff --git a/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php b/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php index eac1097..c8b877a 100644 --- a/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php +++ b/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php @@ -11,6 +11,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\edit\Access\EditEntityFieldAccessCheckInterface; +use Drupal\entity\Entity\EntityDisplay; use Drupal\field\FieldInstanceInterface; /** @@ -78,7 +79,7 @@ public function generateFieldMetadata(FieldItemListInterface $items, $view_mode) } // Early-return if no editor is available. - $formatter_id = entity_get_render_display($entity, $view_mode)->getRenderer($field_name)->getPluginId(); + $formatter_id = EntityDisplay::collectRenderDisplay($entity, $view_mode)->getRenderer($field_name)->getPluginId(); $editor_id = $this->editorSelector->getEditor($formatter_id, $items); if (!isset($editor_id)) { return array('access' => FALSE); diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php index baf1cbd..122c0b1 100644 --- a/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php +++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php @@ -71,4 +71,107 @@ public function getRenderer($field_name) { return $formatter; } + /** + * Returns the entity_display object used to render an entity. + * + * Depending on the configuration of the view mode for the bundle, this can be + * either the display object associated to the view mode, or the 'default' + * display. + * + * This function should only be used internally when rendering an entity. When + * assigning suggested display options for a component in a given view mode, + * entity_get_display() should be used instead, in order to avoid inadvertently + * modifying the output of other view modes that might happen to use the + * 'default' display too. Those options will then be effectively applied only + * if the view mode is configured to use them. + * + * @param \Drupal\Core\Entity\EntityInterface[] $entities + * The entities being rendered. They should all be of the same entity type. + * @param string $view_mode + * The view mode being rendered. + * + * @return \Drupal\Core\Entity\Display\EntityViewDisplayInterface + * The display object that should be used to render the entity. + */ + public static function collectRenderDisplays($entities, $view_mode) { + if (empty($entities)) { + return array(); + } + + // Collect entity type and bundles. + $entity_type = current($entities)->entityType(); + $bundles = array(); + foreach ($entities as $entity) { + $bundles[$entity->bundle()] = TRUE; + } + $bundles = array_keys($bundles); + + // For each bundle, consider the 'default' display and the display for the + // view mode. + $candidate_ids = array(); + foreach ($bundles as $bundle) { + $candidate_ids["{$bundle}_default"] = $entity_type . '.' . $bundle . '.default'; + if ($view_mode != 'default') { + $candidate_ids["{$bundle}_{$view_mode}"] = $entity_type . '.' . $bundle . '.' . $view_mode; + } + } + $results = \Drupal::entityQuery('entity_display') + ->condition('id', $candidate_ids) + ->condition('status', TRUE) + ->execute(); + + // Determine the actual display to load for each bundle. + $load_ids = array(); + foreach ($bundles as $bundle) { + // Use the display for the view mode if it exists. + if ($view_mode != 'default') { + $candidate_id = $candidate_ids["{$bundle}_{$view_mode}"]; + if (isset($results[$candidate_id])) { + $load_ids[$bundle] = $candidate_id; + } + } + // Else, use the 'default' display if it exists. + if (empty($load_ids[$bundle])) { + $candidate_id = $candidate_ids["{$bundle}_default"]; + if (isset($results[$candidate_id])) { + $load_ids[$bundle] = $candidate_id; + } + } + } + + $displays = \Drupal::entityManager()->getStorageController('entity_display')->loadMultiple($load_ids); + + $displays_by_bundle = array(); + foreach ($bundles as $bundle) { + if (isset($load_ids[$bundle])) { + $display = $displays[$load_ids[$bundle]]; + } + else { + // Else, create a fresh runtime object. + $display = entity_get_display($entity_type, $bundle, 'default'); + } + $display->originalMode = $view_mode; + + // Let modules alter the display. + $display_context = array( + 'entity_type' => $entity_type, + 'bundle' => $bundle, + 'view_mode' => $view_mode, + ); + \Drupal::moduleHandler()->alter('entity_display', $display, $display_context); + + $displays_by_bundle[$bundle] = $display; + } + + return $displays_by_bundle; + } + + /** + * @todo + */ + public static function collectRenderDisplay($entity, $view_mode) { + $displays = static::collectRenderDisplays(array($entity), $view_mode); + return $displays[$entity->bundle()]; + } + } diff --git a/core/modules/field/field.module b/core/modules/field/field.module index fc29d92..ae70b8c 100644 --- a/core/modules/field/field.module +++ b/core/modules/field/field.module @@ -7,6 +7,7 @@ use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Template\Attribute; +use Drupal\entity\Entity\EntityDisplay; /* * Load all public Field API functions. Drupal currently has no @@ -428,7 +429,7 @@ function field_view_field(ContentEntityInterface $entity, $field_name, $display_ // Get the formatter object. if (is_string($display_options)) { $view_mode = $display_options; - $formatter = entity_get_render_display($entity, $view_mode)->getRenderer($field_name); + $formatter = EntityDisplay::collectRenderDisplay($entity, $view_mode)->getRenderer($field_name); } else { $view_mode = '_custom';