Problem/Motivation

When creating the content_moderation module we decided to create a ContentModerationState entity to store the information alongside the entity being moderated. We did this because this allowed the experimental module to uninstalled. This has the side effect of creating two entities for a single entity and twice the number of entity revisions. In an ideal world this would have been a field on the entity like other similar information.

Alternatively rebuild content moderation on top of workspaces and see what is required for that.

Proposed resolution

Discuss if we want to do this and how.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Comments

alexpott created an issue. See original summary.

alexpott’s picture

Issue summary: View changes
sam152’s picture

Hey @alexpott, thanks for filing this issue. The discussions around this are spread out all over the place, so it'll be good to get a single reference of it.

Here is a bit of a brain-dump of discussion points or issues which have been discussed over the years which I can recall:

  • Since moderation is added on a per-bundle basis, there is actually only one blocker for making the field a code-defined bundle field: #2280639: Add the FieldStorageDefinition class to define field storage definitions in hook_entity_field_storage_info()

    Right now, since the entity-attached-field is computed, it's pretty easy to just ignore values that are assigned to it if the entity itself is not being moderated, but that might be tricker with a field with table storage. Either way, it's a better DX when it comes to the field actually surfacing in places where a list of entity fields are present (the api, entity displays, REST etc). I think it would actually improve the current implementation a lot as well, hint hint ;)
  • When CM was going through a review to get stable and this was raised and discussions were had around the API surface of an entity type. I logged #2917276: Allow entity types to be @internal in such a way that removing them doesn't violate any BC to discuss this because of this very issue.

    For better or worse, the entity exposes a lot of API (from hooks to the views relationship). @xjm had an idea that you could continue to write to the entity while shifting the field over to having table storage, then deprecating all of the touch points, but I think there are quite a few places where deprecating one of the touch points is really tricky, see: #2894479: Deprecate the Views relationship from moderated content to the "content_moderation_state" entity .

    I'd fear that we'd be running both side-by-side, a lot of complexity would be introduced and then the efforts to actually remove the entity type would stall or fall flat. Since the deprecation issue exists, it sort of prevents this from happening in one "big bang". Also: #2917276: Allow entity types to be @internal in such a way that removing them doesn't violate any BC.
  • There are some aspects of the field which are really helped by the fact that it's computed with an entity backing it, instead of having table storage, a couple of these are:
    • The fact that switching on moderation, instantly exposes a moderation state for every revision without any kind of data inserts. I think the computed aspect of this would have to carry over into a table-storage implementation, since I think it's critical to a lot of the semantics of the module and probably also an API.
    • The schema is always stable, installing and uninstalling field storage definitions feels a lot more complex and prone to inconsistent schemas than a single installed-once schema. Remember that the field would need to be installed in a bunch of different circumstances, from the UI, when config is imported, when the workflows entity is changed, are alterations to the workflow entity using the simple config API also covered etc. I think this implementation would come with a lot of support and issues for folks who need to manually fix/install their schema so in a lot of ways the current implementation is far simpler in terms of schema management.
  • I discussed a workspaces implementation in some level of detail with @amateescu. One of the advantages that was pointed out was the fact that you could author other kinds of composite entity types as part of a content form and those would be published alongside the content, think: media items, terms, aliases, menu items etc.). However this is a super double edged sword, I think a tonne of these entity types people consider part of a common library (terms, media) and that expectations are pretty firmly set already that modifying these entities affects the whole site and should be published immediately. So an implementation based on workspaces would either need to capture only the main moderated entity or the other entities captured would need to be configured and BC.
  • For various reasons, workspaces also chose a "workspace association" entity instead of opting for entity-level table storage, even when we had base field purging. It might be worth reviewing that issue for the key take-aways, but I think it goes some way to validating the accidental design of CM. This also creates additional entities, which the IS describes as being a motivation to move away from this architecture.

These are just some initial thoughts, I think there are probably more considerations that would go into this. Overall, I think tackling this would be by far the most complex and disruptive change to CM since the stable release. I do honestly wonder if it needs more motivation than creating additional entities. One of the biggest driving factors in my eyes would be: the code to keep CM entities composite to moderated entities is complex, but again with the deprecation problem I think running it as BC would also be quite complex. Other than that, I think the architecture has served the use-case okay, but I may be bias.

I mentioned this somewhere else, but right now the queue is a bit slow even for fairly small well defined bug fixes or incremental improvements. For something of this scale to work, it would need significant commitment of resources, otherwise my fear would be the work would go to waste. I realise that's a bit meta, but it's been a barrier that has prevented me from looking at any of the above issues more deeply.

amateescu’s picture

For various reasons, workspaces also chose a "workspace association" entity instead of opting for entity-level table storage, even when we had base field purging. It might be worth reviewing that issue for the key take-aways, but I think it goes some way to validating the accidental design of CM. This also creates additional entities, which the IS describes as being a motivation to move away from this architecture.

The reason is that base field purging was not yet implemented in core when the initial workspaces-in-core patch was being written, see #2784921-73: Add Workspaces experimental module (from 27 Sep 2017), and #2282119-91: Make the Entity Field API handle field purging was committed a few weeks later. The only reason why workspaces still went with the "workspace_association" entity type in the final patch is.. lack of time I guess :)

sam152’s picture

Ah, thanks for clarifying. I seem to remember that there were technical discussions that still favoured the association entity, but without actually tracking them down, I could be mistaken.

sam152’s picture

One other nuance that came to me was: when disabling moderation, the history of the moderation states is retained via the CMS entity. If fields were uninstalled and purged, that would change. I can't think of too many scenarios that would depend on that behaviour, but it's worth being aware of.

sam152’s picture

This issue for me is more validation that managing schema attached to entity types a module doesn't "own" is complex: #3054765: Need to add an entity update event listener to add moderation state for newly revisionable fields.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

amateescu’s picture

Title: Move content moderation information to a base field of the entity being moderated » [PP-1] Move content moderation information to a base field of the entity being moderated
Priority: Normal » Major
Status: Active » Postponed

Postponing on #2835545: Provide a Workflow FieldType that references a workflow entity and tracks the current state of an entity. The detailed analysis from #3 is super helpful, and we'll need to carefully evaluate each point when the time comes.