Updated: Comment #N

Problem/Motivation

There is a lot of code that calls entity_get_view_modes() that duplicates effort by having to add a 'default' option when presenting view modes in an #options element. This code should also be moved to EntityManager class to remove old procedural code.

Proposed resolution

Move these procedural functions to methods in EntityManager class and add a couple of new methods to provide the display mode available options.

Remaining tasks

User interface changes

None

API changes

  • Adds 4 new methods to EntityManagerInterface:
    • getFormModes()
    • getAllFormModes()
    • getViewModes()
    • getAllViewModes()
    • getFormModeOptions()
    • getViewModeOptions()
  • Deprecates entity_get_view_mode_options() and entity_get_form_mode_options()

Original report by @Dave Reid

There is a lot of code that calls entity_get_view_modes() that duplicates effort by having to add a 'default' option when presenting view modes in an #options element.

CommentFileSizeAuthor
#74 interdiff.txt1.75 KBjlbellido
#74 entity-display-mode-2154711-74.patch1.64 KBjlbellido
#68 entity-display-mode-2154711-68.patch1.1 KBjlbellido
#63 entity-display-mode-2154711-63.patch33.84 KBtim.plunkett
#59 entity-display-mode-2154711-59.patch33.81 KBtim.plunkett
#55 entity_display_mode-2154711-55.patch33.81 KBplopesc
#50 entity_display_mode-2154711-50.patch33.83 KBtim.plunkett
#48 entity_display_mode-2154711-48.patch33.81 KBBerdir
#45 interdiff.txt894 bytesplopesc
#45 entity_display_mode-2154711-45.patch33.76 KBplopesc
#43 interdiff.txt18.74 KBplopesc
#43 entity_display_mode-2154711-43.patch33.62 KBplopesc
#41 entity_display_mode-2154711-41.patch28.8 KBplopesc
#40 entity_display_mode-2154711-40.patch28.78 KBplopesc
#37 entity_display_mode-2154711-37.patch28.74 KBplopesc
#36 entity_display_mode-2154711-36.patch29.28 KBplopesc
#31 entity_display_mode-2154711-31.patch29.63 KBplopesc
#18 entity_display_mode-2154711-18.patch27.09 KBplopesc
#17 entity_display_mode-2154711-16.patch21.7 KBplopesc
#14 entity_display_mode-2154711-14.patch20.22 KBplopesc
#12 entity_display_mode-2154711-12.patch20.3 KBplopesc
#4 entity_display_mode-2154711-4.patch16.04 KBtim.plunkett
#27 interdiff.txt991 bytesplopesc
#27 entity_display_mode-2154711-27.patch29.6 KBplopesc
#25 interdiff.txt28.61 KBplopesc
#25 entity_display_mode-2154711-25.patch29.6 KBplopesc
#12 interdiff.txt2.65 KBplopesc
#10 interdiff.txt2.35 KBolli
#10 entity_display_mode-2154711-10.patch14.6 KBolli
#8 interdiff.txt832 bytesolli
#8 entity_display_mode-2154711-8.patch14.59 KBolli
#6 interdiff.txt553 bytestim.plunkett
#6 entity_display_mode-2154711-6.patch15.95 KBtim.plunkett
#2 2154711-entity-get-view-mode-options.patch10.06 KBDave Reid
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner’s picture

+1, this would be nice for views!

Dave Reid’s picture

Status: Active » Needs review
FileSize
10.06 KB

Initial version.

Status: Needs review » Needs work

The last submitted patch, 2: 2154711-entity-get-view-mode-options.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
16.04 KB

This is what I was describing on IRC today, putting methods on the storage controller.

I'm using the inline @var docblock form where things need to be injected. This will allow IDEs like PHPStorm to work until it is injected properly.

Status: Needs review » Needs work

The last submitted patch, 4: entity_display_mode-2154711-4.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
15.95 KB
553 bytes

I was just looking at that static earlier today. Let's see when it actually needs to be called (probably not during install!)

The last submitted patch, 6: entity_display_mode-2154711-6.patch, failed testing.

olli’s picture

Fixed one fatal.

The last submitted patch, 8: entity_display_mode-2154711-8.patch, failed testing.

olli’s picture

The last submitted patch, 10: entity_display_mode-2154711-10.patch, failed testing.

plopesc’s picture

Re-rolling after #2164827: Rename the entityInfo() and entityType() methods on EntityInterface and EntityStorageControllerInterface.
Also removing the checking of the displayMode status property to pass tests because the old implementations didn't do it. Should we change the tests and expected results and keep the checking to show only the modes which provides custom options?

Regards.

Status: Needs review » Needs work

The last submitted patch, 12: entity_display_mode-2154711-12.patch, failed testing.

plopesc’s picture

Status: Needs work » Needs review
FileSize
20.22 KB

Forgot to remove an old parameter...

Status: Needs review » Needs work

The last submitted patch, 14: entity_display_mode-2154711-14.patch, failed testing.

Dave Reid’s picture

Also removing the checking of the displayMode status property to pass tests because the old implementations didn't do it. Should we change the tests and expected results and keep the checking to show only the modes which provides custom options?

My opinon is yes, we should fix the tests because users likely shouldn't be able to select view modes that aren't even customized. I still think it should be an additional parameter on the getDisplayModeOptions() if disabled display modes should be included in the result or not. Let the caller decide what it wants, but default to not including disabled display modes. Without this logic in that method, I have to duplicate a lot of work in order to filter out disabled ones when it could easily just be done in that method.

plopesc’s picture

Status: Needs work » Needs review
FileSize
21.7 KB

Silly me... :(
Forgot to add the new file to the patch.
Sorry for the noise.

plopesc’s picture

Sorry for the previous crossposting...
New patch fixing tests and adding the second parameter in EntityDisplayModeStorageController::getDisplayModeOptions().
Regards.

The last submitted patch, 17: entity_display_mode-2154711-16.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 18: entity_display_mode-2154711-18.patch, failed testing.

plopesc’s picture

Status: Needs work » Needs review

Oh, I must go to sleep... so many work today

I hope this works at least.

Berdir’s picture

Status: Needs review » Needs work

The last submitted patch, 21: entity_display_mode-2154711-21.patch, failed testing.

Berdir’s picture

Note: There's a drupal_static_reset() call for entity_get_view_modes() in entity_info_clear_cache(), once that is removed we can kill that function.

Hiding those fairly often used functions on a storage controller seems unfortunate.

Given that view and form modes and their underlying entity types are core concept of the entity system, Drupal\Core\Entity depending on it and they really should be in there anyway (#2031717: Make entity module not required), can't we add those methods to the entity manager? I'm worried about what @webchick will say about the changed calls here ;)

plopesc’s picture

Status: Needs work » Needs review
FileSize
29.6 KB
28.61 KB

Re-rolling, moving getDisplayModesByEntityType() from the storage controller to EntityManager::getViewModes($entity_type_id) and EntityManager::getFormModes($entity_type_id). Same with getDisplayModesOptions().

Regards.

Status: Needs review » Needs work

The last submitted patch, 25: entity_display_mode-2154711-25.patch, failed testing.

plopesc’s picture

Status: Needs work » Needs review
FileSize
29.6 KB
991 bytes

Silly me...

The last submitted patch, 27: entity_display_mode-2154711-27.patch, failed testing.

Berdir’s picture

Thanks, I think that looks much much nicer (the interdiff in #25). let's see what others have to say ;)

plopesc’s picture

Status: Needs review » Needs work

The last submitted patch, 31: entity_display_mode-2154711-31.patch, failed testing.

plopesc’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 31: entity_display_mode-2154711-31.patch, failed testing.

plopesc’s picture

Status: Needs work » Needs review
plopesc’s picture

FileSize
29.28 KB

Straight re-roll

plopesc’s picture

Status: Needs review » Needs work

The last submitted patch, 37: entity_display_mode-2154711-37.patch, failed testing.

plopesc’s picture

Title: Add an entity_get_view_mode_options() function that always adds the default view mode » Move entity_get_(form/view)_mode_options() functions to EntityManager and add get(Form/View)ModeOptions() methods
Issue summary: View changes
plopesc’s picture

Status: Needs work » Needs review
FileSize
28.78 KB
plopesc’s picture

Berdir’s picture

Status: Needs review » Needs work
  1. +++ b/core/lib/Drupal/Core/Entity/EntityManager.php
    @@ -117,6 +117,13 @@ class EntityManager extends PluginManagerBase implements EntityManagerInterface
    +   *
    +   * @var array
    +   */
    +  protected $displayModeInfo;
    
    @@ -157,6 +164,7 @@ public function clearCachedDefinitions() {
         $this->bundleInfo = NULL;
    +    $this->displayModeInfo = NULL;
    

    Should we initialize this to an empty array and set it back to = array() ?

  2. +++ b/core/lib/Drupal/Core/Entity/EntityManager.php
    @@ -458,4 +466,95 @@ public function getTranslationFromContext(EntityInterface $entity, $langcode = N
    +      $langcode = \Drupal::languageManager()->getCurrentLanguage(Language::TYPE_INTERFACE)->id;
    

    EntityManager has the language manager injected, so use $this->languageManager.

  3. +++ b/core/lib/Drupal/Core/Entity/EntityManager.php
    @@ -458,4 +466,95 @@ public function getTranslationFromContext(EntityInterface $entity, $langcode = N
    +      if ($cache = \Drupal::cache('cache')->get("$key:$langcode")) {
    

    Same, $this->cache->get()

  4. +++ b/core/lib/Drupal/Core/Entity/EntityManager.php
    @@ -458,4 +466,95 @@ public function getTranslationFromContext(EntityInterface $entity, $langcode = N
    +        \Drupal::moduleHandler()->alter($key, $this->displayModeInfo[$display_type]);
    

    Same for the module handler :)

  5. +++ b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php
    @@ -220,4 +220,54 @@ public function getDefinition($entity_type_id, $exception_on_invalid = FALSE);
    +  public function getViewModes($entity_type_id = NULL);
    ...
    +  public function getFormModes($entity_type_id = NULL);
    

    Methods that return different structures based on the argument are somewhat discouraged. Should we maybe have getAllViewModes() and getViewModes($entity_type_id) ?

  6. +++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
    @@ -291,7 +291,7 @@ protected function isViewModeCacheable($view_mode) {
    -    $view_modes_info = entity_get_view_modes($this->entityTypeId);
    +    $view_modes_info = \Drupal::entityManager()->getViewModes($this->entityTypeId);
    

    $this->entityManager :)

  7. +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Block/CustomBlockBlock.php
    @@ -102,14 +102,9 @@ public function defaultConfiguration() {
    -    $options = array('default' => t('Default'));
    -    $view_modes = entity_get_view_modes('custom_block');
    -    foreach ($view_modes as $view_mode => $detail) {
    -      $options[$view_mode] = $detail['label'];
    -    }
         $form['custom_block']['view_mode'] = array(
           '#type' => 'select',
    -      '#options' => $options,
    +      '#options' => \Drupal::entityManager()->getViewModeOptions('custom_block'),
    

    This one doesn't have the entity manager injected yet but we should probably do that.

  8. +++ b/core/modules/edit/lib/Drupal/edit/EditController.php
    @@ -276,7 +276,7 @@ public function fieldForm(EntityInterface $entity, $field_name, $langcode, $view
       public function renderField(EntityInterface $entity, $field_name, $langcode, $view_mode_id) {
    -    $entity_view_mode_ids = array_keys(entity_get_view_modes($entity->getEntityTypeId()));
    +    $entity_view_mode_ids = array_keys(\Drupal::entityManager()->getViewModes($entity->getEntityTypeId()));
         if (in_array($view_mode_id, $entity_view_mode_ids)) {
    

    This can use $this->entityManager() (method, not property)

  9. +++ /dev/null
    @@ -1,32 +0,0 @@
    -  /**
    -   * {@inheritdoc}
    -   */
    -  protected function preSave(EntityInterface $view_mode) {
    -    entity_info_cache_clear();
    -  }
    -
    -  /**
    -   * {@inheritdoc}
    -   */
    -  protected function preDelete($view_modes) {
    -    entity_info_cache_clear();
    -  }
    

    The manual cache clear in the test at the end shouldn't be necessary. We can we move this to methods on the entity classes instead?

  10. +++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
    @@ -172,7 +172,7 @@ protected function getDefaultPlugin($field_type) {
        */
       protected function getDisplayModes() {
    -    return entity_get_view_modes($this->entity_type);
    +    return \Drupal::entityManager()->getViewModes($this->entity_type);
       }
    

    This also seems to have $this->entityManager.

  11. +++ b/core/modules/field_ui/lib/Drupal/field_ui/FormDisplayOverview.php
    @@ -139,7 +139,7 @@ protected function getDefaultPlugin($field_type) {
       protected function getDisplayModes() {
    -    return entity_get_form_modes($this->entity_type);
    +    return \Drupal::entityManager()->getFormModes($this->entity_type);
       }
    

    Same :)

  12. +++ b/core/modules/field_ui/lib/Drupal/field_ui/Plugin/Derivative/FieldUiLocalTask.php
    @@ -132,7 +132,7 @@ public function getDerivativeDefinitions(array $base_plugin_definition) {
     
             // One local task for each form mode.
             $weight = 0;
    -        foreach (entity_get_form_modes($entity_type_id) as $form_mode => $form_mode_info) {
    +        foreach (\Drupal::entityManager()->getFormModes($entity_type_id) as $form_mode => $form_mode_info) {
               $this->derivatives['field_form_display_' . $form_mode . '_' . $entity_type_id] = array(
                 'title' => $form_mode_info['label'],
    

    Same, also others in this class.

plopesc’s picture

Status: Needs work » Needs review
FileSize
33.62 KB
18.74 KB

Thanks for your review @Berdir

New patch addressing following points:

  • Removing calls to \Drupal::entityManager() when possible.
  • Injecting entityManager in CustomBlockBlock
  • Adding new methods EntityManagerInterface::getAllViewModes() and EntityManagerInterface::getAllFormModes()
  • Clear entity info cache on EntityDisplayModeBase::preSave() and EntityDisplayModeBase::preDelete()

Regards

Berdir’s picture

+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayModeBase.php
@@ -82,4 +83,16 @@ public function getTargetType() {
 
+  /**
+   * {@inheritdoc}
+   */
+  public function preSave(EntityStorageControllerInterface $storage_controller) {
+    parent::preSave($storage_controller);
+    entity_info_cache_clear();
+  }
+
+  public static function preDelete(EntityStorageControllerInterface $storage_controller, array $entities) {
+    entity_info_cache_clear();
+  }

They should probably call clearCachedDefinitions() on the entity manager now. Not sure if we want to add specific methods for that, to avoid having to re-parse the entity types for it.

The second needs the parent:: call and @inheritdoc

plopesc’s picture

FileSize
33.76 KB
894 bytes

Oh sorry,
I forgot your reference to kill entity_info_cache_clear() in #24.
I didn't add the call to parent::preDelete() because currently is empty. but you're right, that might change in the future.

Regards

tim.plunkett’s picture

Status: Needs review » Reviewed & tested by the community

Looks good, thanks @plopesc for bringing this home

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll

entity_display_mode-2154711-45.patch no longer applies.

error: patch failed: core/modules/edit/lib/Drupal/edit/EditController.php:276
error: core/modules/edit/lib/Drupal/edit/EditController.php: patch does not apply
error: patch failed: core/modules/views/lib/Drupal/views/Tests/Handler/AreaEntityTest.php:101
error: core/modules/views/lib/Drupal/views/Tests/Handler/AreaEntityTest.php: patch does not apply

Berdir’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
33.81 KB

Trivial re-roll, so back to RTBC assuming that bot agrees.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 48: entity_display_mode-2154711-48.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
33.83 KB

#2134857: PHPUnit test the entity base classes added some use statements, no changes.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 50: entity_display_mode-2154711-50.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
Berdir’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC. random fails--.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 50: entity_display_mode-2154711-50.patch, failed testing.

plopesc’s picture

FileSize
33.81 KB

Straight re-roll, #2216701: Random test failure in ToolbarAdminMenuTest removed some use statements.

plopesc’s picture

Status: Needs work » Reviewed & tested by the community
Issue tags: -Needs reroll

Let's go testbot!

plopesc’s picture

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 55: entity_display_mode-2154711-55.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
33.81 KB

Just a case of another issue adding a method to the bottom of core/modules/entity/lib/Drupal/entity/EntityDisplayModeBase.php.

Berdir’s picture

Status: Needs review » Reviewed & tested by the community

Yep, adding methods at the end of a class is dangerous business :)

Berdir’s picture

Issue tags: +Entity Field API
alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll

entity-display-mode-2154711-59.patch no longer applies.

error: patch failed: core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php:31
error: core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php: patch does not apply
error: patch failed: core/modules/entity/lib/Drupal/entity/EntityDisplayModeBase.php:8
error: core/modules/entity/lib/Drupal/entity/EntityDisplayModeBase.php: patch does not apply

tim.plunkett’s picture

Status: Needs work » Reviewed & tested by the community
Issue tags: -Needs reroll
FileSize
33.84 KB

Simple conflicts (use statements, changes at end of file), no real changes.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed
+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayModeBase.php
index cca791e..0000000
--- a/core/modules/entity/lib/Drupal/entity/EntityDisplayModeStorageController.php

--- a/core/modules/entity/lib/Drupal/entity/EntityDisplayModeStorageController.php
+++ /dev/null

Nice!

Committed 02f761b and pushed to 8.x. Thanks!

diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php
index d510917..b9e8fcb 100644
--- a/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php
+++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php
@@ -24,7 +24,8 @@
  * display settings, or just replicate the settings of the 'default' form mode,
  * thus reducing the amount of form display configurations to keep track of.
  *
- * @see entity_get_form_modes()
+ * @see \Drupal\Core\Entity\EntityManagerInterface::getAllFormModes()
+ * @see \Drupal\Core\Entity\EntityManagerInterface::getFormModes()
  * @see hook_entity_form_mode_info_alter()
  *
  * @ConfigEntityType(
diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php
index df31790..221de9c 100644
--- a/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php
+++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php
@@ -25,7 +25,8 @@
  * replicate the settings of the 'default' view mode, thus reducing the amount
  * of display configurations to keep track of.
  *
- * @see entity_get_view_modes()
+ * @see \Drupal\Core\Entity\EntityManagerInterface::getAllViewModes()
+ * @see \Drupal\Core\Entity\EntityManagerInterface::getViewModes()
  * @see hook_entity_view_mode_info_alter()
  *
  * @ConfigEntityType(
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index ba5151f..a226e59 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -429,7 +429,7 @@ function node_add_body_field(NodeTypeInterface $type, $label = 'Body') {
 
     // The teaser view mode is created by the Standard profile and therefore
     // might not exist.
-    $view_modes = entity_get_view_modes('node');
+    $view_modes = \Drupal::entityManager()->getViewModes('node');
     if (isset($view_modes['teaser'])) {
       entity_get_display('node', $type->type, 'teaser')
         ->setComponent('body', array(
diff --git a/core/modules/system/entity.api.php b/core/modules/system/entity.api.php
index ab25a74..c6cb1d9 100644
--- a/core/modules/system/entity.api.php
+++ b/core/modules/system/entity.api.php
@@ -144,7 +144,8 @@ function hook_entity_type_alter(array &$entity_types) {
  * @param array $view_modes
  *   An array of view modes, keyed first by entity type, then by view mode name.
  *
- * @see entity_get_view_modes()
+ * @see \Drupal\Core\Entity\EntityManagerInterface::getAllViewModes()
+ * @see \Drupal\Core\Entity\EntityManagerInterface::getViewModes()
  * @see hook_entity_view_mode_info()
  */
 function hook_entity_view_mode_info_alter(&$view_modes) {

Fixed this during commit.

  • Commit 02f761b on 8.x by alexpott:
    Issue #2154711 by plopesc, tim.plunkett, olli, Berdir, Dave Reid: Move...
ianthomas_uk’s picture

Status: Fixed » Needs work

Deprecates entity_get_view_mode_options() and entity_get_form_mode_options()

When do we plan to remove these, before Drupal 8 or before Drupal 9? This should be stated in the docblocks.

@deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
@deprecated in Drupal 8.0, will be removed in Drupal 9.0.

tim.plunkett’s picture

Before 8.0. I would have removed them here, but that would be too easy.

jlbellido’s picture

Status: Needs work » Needs review
FileSize
1.1 KB

@deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.

Added to entity_get_form_modes and entity_get_view_modes functions.

Thanks @plopesc for support.

Status: Needs review » Needs work

The last submitted patch, 68: entity-display-mode-2154711-68.patch, failed testing.

jlbellido’s picture

Status: Needs work » Needs review

Not related fail, restesting.

jlbellido’s picture

Status: Needs review » Needs work

The last submitted patch, 68: entity-display-mode-2154711-68.patch, failed testing.

ianthomas_uk’s picture

If these are no longer used we can just remove them. We try not to remove functions as part of big patches incase something goes wrong, but a small followup immediately afterwards is fine.

jlbellido’s picture

Status: Needs work » Needs review
FileSize
1.64 KB
1.75 KB

Removed "entity_get_form_modes" and "entity_get_view_modes" from core/includes/entity.inc

ianthomas_uk’s picture

Assigned: Dave Reid » Unassigned
Status: Needs review » Reviewed & tested by the community
alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 1df1d3b and pushed to 8.x. Thanks!

  • Commit 1df1d3b on 8.x by alexpott:
    Issue #2154711 followup by by jlbellido: Move entity_get_(form/view)...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.