Document what it does technically and what's the implications

Created on 29 August 2024, 4 months ago

Problem/Motivation

Hi and thank you so much for this great module! I was looking for such a functionality since Drupal 6 ;)

Reading the module page and evaluating the module I was wondering, what this module does technically to trash entities and what implications this may have (for the data structure, performance, ...)

Could you eventually add a some sentences how this module works technically?
For example where is the data put when trashed? Is it flagged or stored somewhere else, ... that would be great to know without going into the code details.

Thank you!

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

✨ Feature request
Status

Active

Version

3.0

Component

Documentation

Created by

πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

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

Comments & Activities

  • Issue created by @Anybody
  • πŸ‡ΈπŸ‡ͺSweden twod Sweden

    I'm not an official maintainer or anything, but fairly familiar with the module as I've contributed a few pathes, so I'll give it a shot.

    How is an entity put in the trashcan?

    Trash module works by adding an internal field/property to your "trashable" entities called "deleted". This field is a Unix timestamp indicating when an individual entity was "deleted" (or rather, put in the trash). That's really the only difference you would see if just looking at your entities after installing the module, though the "deleted" field isn't actually exposed in any visible way on the entity itself.
    When pressing "Delete" on an entity form, that field gets set with the current time, that's it.

    If the field is empty, the entity is not trashed. If it has a timestamp, it is trashed. If it has a timestamp, it may be actually deleted (aka "purged") for real after some configurable delay.

    How does a "trashed" entity disappear from everywhere (except the "Trashcan") if it isn't actually deleted yet?

    Trash module mainly uses the entity access hook and the Entity Queries alter hook to achieve this.
    The access hook implementation allows the module to actively stop/forbid someone from directly accessing a trashed entity without the appropriate permissions.
    The Entity Query implementation achieves the same for any listings, such as in Views or the default list builders.
    As these are the same for all content entities, the module should work the same with all of them.

    How does Trash achieve this?

    First, entities must not actually be deleted when pressing "Delete" - or even via $entity->delete(). Annonyingly, there is no great hook or event to implement which can ensure that operation can always be intercepted. However, it is fairly easy to substiture an entity's storage implementation. Basically, Trash implements hook_entity_type_alter(), dynamically generates/renders a new storage class for your enabled entity, and sets that on your entity instead. Say what? Yes, you read that correctly. It uses Twig to render out a new class, which inherits from the original class it found from the entity definition, saves it as a PHP file and uses that instead, much like how templates are replaced with classes. This is also why it's [at least for now] limited to SQL based entity storage classes.
    That trait which gets included has all the logic to override the delete() call, and instead just set the $entity->deleted timestamp. (It does do a bit more if what was deleted was a translation instead of the whole entity, but that's not important right now.)

    This way, there is no way to accidentally bypass the trashcan even by other modules deleting stuff and having no idea Trash exists.

    What about "inside" the trashcan itself, or if I really want to delete (purge) something right now?

    Trash module has the concept of a "trash context" (yeah, there are many things named context already, this is none of those). It's more or less just a static string variable value in the module's TrashManager service.

    The context is global and can have one of three values (hello enums!), and the current value affects the outcome of certain things:

    A note on query alteration: If you have made a custom Entity Query and add a condition on the deleted field yourself then Trash will try to detect that, and if found it'll back off and trust you know what you're doing.

    Trash also uses a route option to automatically swith the context to one of these values for certain routes to allow trashed entities to be viewed or permanently deleted.

    How will this affect my custom code?

    In the broad view, it should not affect it much at all. Obviously, if you have a custom entity storage class, you should check that it's compatible with the code Trash generates.
    Trash also overrides the access handler class for nodes, so you may want to ensure any custom class you use either does the same things or extend Trash module's class.

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    @twod I just wanted to give a big THANK YOU for your wonderful and clear explanation!

    Thank you for taking the time to explain to the community, how it works!
    Maybe you could ask a maintainer to place most important parts of this onto the module page and maybe the whole explanation into the README.md so that this helpful information doesn't get lost?

    Thank you very much, much appreciated!

    • amateescu β†’ committed f06bfc5c on 3.x
      Issue #3471006 by twod: Document what it does technically and what's the...
  • πŸ‡·πŸ‡΄Romania amateescu

    Another big thank you from me as well! I couldn't have written all this in such a friendly yet concise manner :)

    Committed the patch attached to 3.x!

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    @amateescu would it maybe make sense to also add this on the module page or at least write a sentence about the README.md that contains details?

  • πŸ‡·πŸ‡΄Romania amateescu

    Definitely a good idea :) Added a link to the new README on the project page.

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    Thank you once more!!

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

Production build 0.71.5 2024