Problem/Motivation
As part of #2721129: Workflow Initiative, we want to improve revision metadata and publishing state capabilities for content entity types, in order to allow them to be used in the following contexts:
- Content Moderation: more content entity types will be able to go through moderation workflows.
- Trash: more content entity types will have archiving support.
- Workspaces: see #2732071: WI: Workspace module roadmap.
Proposed resolution
Introduce a new base class for content entities which supports extended revision and publishing state capabilities by default, through RevisionLogInterface
/ RevisionLogEntityTrait
and \Drupal\Core\Entity\EntityPublishedInterface
/ EntityPublishedTrait
.
The list of core entity types which will implement the new base class is being discussed in #2745619: [policy, no patch] Which core entities get revisions?.
Remaining tasks
- Finish #2248983: Define the revision metadata base fields in the entity annotation in order for the storage to create them only in the revision table and #2789315: Create EntityPublishedInterface and use for Node and Comment as this issue depends on them.
- Finish #2721313: Upgrade path between revisionable / non-revisionable entities which will allow us to enable revisioning for entity types with existing data.
- Figure out if more common functionality is needed in the new base class.
User interface changes
Nope.
API changes
API addition: a new content entity base class is available.
Data model changes
Nope.
Comment | File | Size | Author |
---|---|---|---|
#38 | interdiff.txt | 1.04 KB | amateescu |
#38 | 2825973-38.patch | 10.51 KB | amateescu |
#31 | interdiff.txt | 1.98 KB | amateescu |
#31 | 2825973-31.patch | 9.47 KB | amateescu |
#28 | 2825973-28.patch | 9.26 KB | timmillwood |
Comments
Comment #2
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedHere's how it could look like. Also posting a patch combined with #2248983: Define the revision metadata base fields in the entity annotation in order for the storage to create them only in the revision table and #2789315: Create EntityPublishedInterface and use for Node and Comment to check if we're missing anything in those issues.
Comment #4
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedOk, BlockContent needs the status field first so it will require it's own issue, so let's try to convert only nodes here.
Comment #5
timmillwoodThe status field is added to BlockContent in #2820848: Make BlockContent entities publishable
Comment #6
BerdirI have no idea what this is supposed to be. And why this field on node wouldn't be "queryable" while it would be on the trait/default definition. Either both shouldnt' be queryable or neither?
Should we also use this for some test entity types? One that does nothing but extend from this, to make sure that this works out of the box on its own?
Comment #7
dawehnerMaking them not queryable seems to be just a pure historical effect. If you are honest, there is a big value in a complex moderation workflow, in which people want to know which particular revisions they have touched for example. Enabling queryability, is IMHO not some sort of BC break.
Comment #8
timmillwoodIf I understand right setting it as not queryable is just to not break BC, maybe we can look in a follow up about resolving this.
Comment #9
dawehner@timmillwood
Sure, but we could enable it for new entity types and then just override it in node ... even I still don't see how it should be a BC break :)
Comment #11
timmillwoodNow all the dependencies have landed I'm re-uploading the "do not test" patch from #4 to see what testbot thinks. I've tested locally and it applies to 8.4.x and seems to work fine.
I guess the only remaining item would be #6, or if we break that out into a follow up?
Comment #13
Berdirthe REST fails are because that test code still hardcodes the order in which fields are defined/returned, and this patch is changing that.
IMHO, that is a bad test, and we should rewrite it so it verifies that all the fields deny access but that it doesn't matter in which order.
Comment #14
Wim Leers+1
If field error order does matter for a particular entity type (it could if field A depends on field B for example), then they should have explicit test coverage for that.
Comment #15
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedOk then, let's fix the bad test.
Comment #17
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedAll those tests are not initializing the entity tables properly, so let's just use a dummy field value for the purpose of that test.
As for the 'queryable' discussion above, I did quite a bit of digging and found out that it was introduced in #1696640-57: Implement API to unify entity properties and fields but never used, so I opened #2855886: Deprecate \Drupal\Core\Field\FieldStorageDefinitionInterface::isQueryable() because it's not used anywhere for it.
Comment #18
timmillwoodI think this looks good, ready to go!
Comment #19
Wim LeersExplicitly RTBC'ing this portion of the patch as
rest.module
maintainer. This still tests what we need to be tested, just in a way that is less brittle. Thanks!Comment #21
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedRerolled for #2855886: Deprecate \Drupal\Core\Field\FieldStorageDefinitionInterface::isQueryable() because it's not used anywhere.
Comment #22
himanshu-dixit CreditAttribution: himanshu-dixit as a volunteer commentedLooks like it needed a reroll.
UPDATE: Sorry didn't refreshed the page. This was already rerolled :(
But let this set to NR to see the reroll passes all the test
Comment #23
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedThe testbot will kick it back to NW in case of a test fail ;)
Comment #26
timmillwoodFixing the broken rest tests.
Comment #28
timmillwoodHelps if I upload the right patch.
Comment #30
timmillwoodoops, I guess that did more harm than good.
Comment #31
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedRerolled for the short array syntax conversion and fixed the failing tests.
Interdiff is to #21.
Comment #32
dawehnerIMHO it would be great to reference this base class somewhere in some central documentation, otherwise people might not find it.
Comment #33
timmillwoodI guess
Drupal/Core/Entity/entity.api.php
would be a good place to document this?I also wonder if it's worth adding a
EditorialContentEntityInterface
, just so we can doif ($entity_type interfaceof EditorialContentEntityInterface)
rather thanif (is_subclass_of($entity_type, 'EditorialContentEntityBase'))
.Comment #34
dawehnerYeah sounds like it.
I think we should never explicitly test for that ... Aren't there all the other interfaces already we should use instead?
Comment #35
timmillwoodWe could do
if ($entity_type instanceof EntityPublishedInterface && $entity_type instanceof RevisionLogInterface)
to test if an entity type is revisionable and publishable, I guess we can also test for "published" and "revision" entity keys too.Comment #36
dawehnerWell, I would have thought that code either wants to deal with the published or the revision log part of an entity, so it can check what it needs to at a given point in time.
Comment #37
jibranLet's fix #32 and then it is good to go imo.
Comment #38
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedHow about this?
Comment #39
dawehnerThat works for me.
Comment #41
boaloysius CreditAttribution: boaloysius as a volunteer commentedWhy did patch #38 fail? I checked if it needs to reroll. But it is not the problem.
Why does just adding documentation make it fail tests?
I put #38 for a retest.
Comment #42
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedIt was just a random testbot fail :)
Comment #44
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedComment #45
alexpottIt seems a shame we are changing the order of base field definitions here - especially since as far as I can see revision_uid now comes before uid - does that even make sense? It's like EntityOwnerInterface needs a trait or something. Not sure.
This change deserves a change record.
Comment #46
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedStruggled a bit to write this one without repeating myself too much: https://www.drupal.org/node/2870643
Hope it's useful though :)
Comment #47
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedAs for the base field ordering, it is indeed a shame that we don't have any good way to order them, but that should be easy enough to implement with something like
setStorageWeight()
. What do you think, should we open an issue for that?Comment #48
alexpott@amateescu thanks for the CR - it is really useful for people implementing the new base class. I think you should have a section on updating existing entities - and point them to the CRs that coverage the additional metadata needed for the traits to work if you have non standard field names.
I've tried to compare all the node tables before and after this patch - whilst the base field definitions have changed order in the API this has not resulted in any change to the underlying data structures. I guess we should include something in the CR about the order of this changing but that this is not API. I'm unsure of
setStorageWeight()
it'd be great if an entity API maintainer could chime in.Comment #49
amateescu CreditAttribution: amateescu for Pfizer, Inc. commented@alexpott, ok, I added a paragraph for updating an existing entity type and pointed to https://www.drupal.org/node/2831499 and https://www.drupal.org/node/2830201 which I also had to publish because they were still in draft.
And I don't think we should go into much detail about the field ordering change in this CR, better keep it simple and to the point :)
Comment #50
alexpottComment #51
alexpottCommitted 7667c3e and pushed to 8.4.x. Thanks!
Comment #53
Wim LeersThis caused a nasty-to-fix failure in a previously RTBC patch: #2768651. The root cause is explained at #2768651-113: Let TimestampItem (de)normalize to/from RFC3339 timestamps, not UNIX timestamps, for better DX, and is not the fault of this patch, it's the flaws in the Entity/Field API's validation system, i.e. either in the Symfony constraints system, or the way Drupal uses it.
See #2820364: Entity + Field + Property validation constraints are processed in the incorrect order.
Comment #54
himanshu-dixit CreditAttribution: himanshu-dixit as a volunteer and at Google Summer of Code commented