Prevent trashed entities from being returned by entity_load

Created on 27 June 2023, over 1 year ago
Updated 15 November 2023, about 1 year ago

Problem/Motivation

If there is reference to "deleted" entity, the referencing entity can't be saved/changed anymore.
There is a validation error: This entity (node: 11729) cannot be referenced.
And on the reference field, instead of label the "- Restricted access - (11729)" is displayed.
Even if user has "View deleted entities" permission.

An additional problem is custom code that outputs entity-derived data (e.g. counts of referenced entities) without going through access checks.

Proposed resolution

1. Prevent trashed entities from being returned by entity_load

🐛 Bug report
Status

Fixed

Version

3.0

Component

Code

Created by

🇷🇺Russia kala4ek 🇷🇺 Novosibirsk

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @kala4ek
  • Issue was unassigned.
  • Status changed to Needs review over 1 year ago
  • Open in Jenkins → Open on Drupal.org →
    Core: 10.0.7 + Environment: PHP 8.1 & MySQL 8
    last update over 1 year ago
    Patch Failed to Apply
  • 🇷🇺Russia kala4ek 🇷🇺 Novosibirsk
  • Open in Jenkins → Open on Drupal.org →
    Core: 10.0.7 + Environment: PHP 8.1 & MySQL 8
    last update over 1 year ago
    5 pass
  • 🇷🇺Russia kala4ek 🇷🇺 Novosibirsk
  • Open in Jenkins → Open on Drupal.org →
    Core: 10.0.7 + Environment: PHP 8.1 & MySQL 8
    last update over 1 year ago
    5 pass
  • 🇷🇺Russia kala4ek 🇷🇺 Novosibirsk

    Also need to override default ValidReference constraint.

  • Open in Jenkins → Open on Drupal.org →
    Core: 10.1.4 + Environment: PHP 8.1 & MySQL 8
    last update about 1 year ago
    5 pass
  • 🇷🇴Romania amateescu

    I've been thinking about this problem for a while, and finally decided to go in a (somewhat radical) different direction: Trash needs to prevent entity_load from returning trashed entities completely.

    This was based on observations from custom code on various sites, and the problem that stood out the most was that there are cases where entity-derived data is displayed without going through access checks, for example directly outputting the result of count($entity->get('some_reference_field')->referencedEntities()), which internally does an entity_load_multiple, but doesn't run any access checks. This specific example could've been solved by overriding core's field item list class for ER fields, but then contrib/custom code that also override it wouldn't benefit from our changes.

    This decision is also in line with the recent fix from 🐛 Trash breaks revision-based views and relation queries Fixed , which made all views (using either the data or the revision data as the base table) stop returning trashed entities by default.

  • Status changed to Fixed about 1 year ago
  • 🇷🇴Romania amateescu

    Committed the patch from #5 to 3.x.

    • amateescu committed dc4093ac on 3.x
      Issue #3370639 followup: Prevent trashed entities from being returned by...
  • 🇷🇴Romania amateescu

    Now that we don't return anything on entity_load, we need different approaches for trash routes (restore, purge) and for viewing trashed entities.

    Committed the followup patch attached to 3.x.

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

  • Status changed to Fixed about 1 year ago
  • 🇷🇺Russia kala4ek 🇷🇺 Novosibirsk

    Hm, but how it will works with entity edit forms? Looks like now trashed entites wouldn't displayed in referency fields anymore and after submitting the form, reference would gone. That means if the admin will restore the trashed node, it wouldn't appears at the place where it was before...

  • 🇷🇴Romania amateescu

    @kala4ek, that's right, the new behavior is closer to the entity being actually deleted, which matches the scenario you described. Fixing the problem within \Drupal\Core\Field\EntityReferenceFieldItemList::referencedEntities() would have had the same outcome.

Production build 0.71.5 2024