Entity Reference Revision not loaded in EntityReferenceFormatterBase

Created on 20 April 2024, 8 months ago
Updated 20 June 2024, 6 months ago

Problem/Motivation

After going through the following issues

and then debugging, led to the discovery that EntityReferenceFormatterBase class does not load the proper revision based on the revision of the entity where it the reference field lies.
It loads the default revision of the entity which is referenced, rather than loading the revision based on the revision of the entity it is attached to.

Steps to reproduce

Follow the steps mentioned in the description of https://www.drupal.org/project/paragraphs_table/issues/3441247 🐛 Node revisions not working when using paragraph table as display format. Active .

Proposed resolution

In EntityReferenceFormatterBase::prepareView() load the proper revision of the entity which is referenced.

Remaining tasks

N/A

User interface changes

N/A

API changes

N/A

Data model changes

N/A

Release notes snippet

🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component
Entity reference 

Last updated 27 days ago

No maintainer
Created by

🇮🇳India Vivek Panicker Kolkata

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @Vivek Panicker
  • Pipeline finished with Failed
    8 months ago
    Total: 664s
    #152067
  • Issue was unassigned.
  • Status changed to Needs review 8 months ago
  • Status changed to Needs work 8 months ago
  • 🇺🇸United States smustgrave

    Thank you for reporting. Appears to have test failures and will need test coverage

  • 🇮🇳India Vivek Panicker Kolkata

    @smustgrave can you please explain a bit more on what all is necessary now?
    I can then give it a try.

  • 🇨🇦Canada dale42 Vancouver, Canada

    This issue causes the display of invalid information on the Content Moderation "Latest version" tab. Specifically, it does not actually display the data from the latest version, it displays information from the default/published version. Adding the "content moderation" issue tag.

    After reading the description of priorities I believe it qualifies a Major, as it is displaying incorrect data.

  • 🇨🇦Canada dale42 Vancouver, Canada

    target_revision_id does not appear on every item. I expect this is why the tests are failing.

    I have an alternative solution, also attached as a file, that is solving the issue on my system. I don't believe this is the best solution, but I think it will advance discussion on the issue.

    $item sometimes has a target_revision_id and sometimes not. This code uses the target_revision_id if available, and falls back to target_id when it isn't. According to the comments "multiple entity load" should be used, so this was used to load the revised version.

    Perhaps all items should have a target_revision_id so that all the entities could be loaded by revision id? This would work even if revisions were used, since every entity has a revision id. This would require an upstream change to what ever is producing $item.

    There is also EntityReferenceRevisionsFormatterBase. I'm not sure where it fits in the picture.

    --- core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceFormatterBase.php	2024-06-20 09:17:49
    +++ core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceFormatterBaseFix.php	2024-06-20 09:21:59
    @@ -122,6 +122,7 @@
         // "entity reference item lists" being displayed. We thus cannot use
         // \Drupal\Core\Field\EntityReferenceFieldItemList::referencedEntities().
         $ids = [];
    +    $vids = [];
         foreach ($entities_items as $items) {
           foreach ($items as $item) {
             // To avoid trying to reload non-existent entities in
    @@ -130,13 +131,25 @@
             // at FALSE.
             $item->_loaded = FALSE;
             if ($this->needsEntityLoad($item)) {
    -          $ids[] = $item->target_id;
    +          if (!is_null($item->target_revision_id)) {
    +            $vids[] = $item->target_revision_id;
    +          }
    +          else {
    +            $ids[] = $item->target_id;
    +          }
             }
           }
         }
    -    if ($ids) {
    +    if ($ids || $vids) {
           $target_type = $this->getFieldSetting('target_type');
    -      $target_entities = \Drupal::entityTypeManager()->getStorage($target_type)->loadMultiple($ids);
    +      $storage = \Drupal::entityTypeManager()->getStorage($target_type);
    +      $target_entities = ($ids) ? $storage->loadMultiple($ids) : [];
    +      if ($vids) {
    +        $target_entities_vids = $storage->loadMultipleRevisions($vids);
    +        foreach ($target_entities_vids as $target_entity) {
    +          $target_entities[$target_entity->id()] = $target_entity;
    +        }
    +      }
         }
     
         // For each item, pre-populate the loaded entity in $item->entity, and set
    
    
  • 🇨🇦Canada dale42 Vancouver, Canada

    Sorry, did not mean to remove the "Needs tests" tag. Re-adding.

Production build 0.71.5 2024