Updated: Comment #0
Problem/Motivation
All entity types that implement EntityChangedInterface have implemented the method getChangedTime() in the exact same way. This duplication could be avoided by using a trait.
Proposed resolution
Provide an EntityChangedTrait that provides EntityChangedTrait::getChangedTime().
Because this method relies on the changed field of an entity, it makes sense for the trait to provide that field as well. Since there can only be one baseFieldDefinitions(), however, we cannot provide that directly in the trait. For this reason a private function changedFieldDefinitions() is introduced as part of the trait that entity types can call in their baseFieldDefinitions().
Remaining tasks
User interface changes
-
API changes
-
Comments
Comment #1
tstoecklerHere we go.
Comment #2
tstoecklerComment #3
berdirHm, the field definitions thing does affect the order in which the field is defined, we also lose the context-specific description...
Comment #4
tstoecklerThat's true. Reverted the order to how it was previously. I updated the description to include the entity type. It's now pretty much identical to how it was before except for 'edited' vs. 'changed', which I changed (no pun intended) because the latter is actually more correct.
I slightly expanded the scope of this issue to rename $entity_type to $entity_type_id in baseFieldDefinitions(). It seemed wrong to introduce this incorrectly as $entity_type in changedFieldDefinitions(), and I also didn't want to introduce a further inconsistency. I can revert that, if people are worried about kitten safety.
Comment #6
berdirPeople are not because your issue is now going to conflict on every instance that you changed anyway because HEAD is now using EntityTypeInterface $entity_type as argument for that method ;)
The same will happen once the changed field type is commited, might be easier to wait on that with further re-rolls? :)
Comment #7
tstoecklerRight I definitely want to wait on the changed issue, but I wanted to post this to get some feedback if people agree with this in principle first.
Will re-roll.
Comment #8
tstoecklerHere's a re-roll.
Comment #10
dawehnerThere might be a couple of entities which uses timestamp instead. Could we just pull 'changed' from a property?
Comment #11
berdirSee #2182239: Improve ContentEntityBase::id() for better DX. We could just add a changed entity key. But not sure about adding too many of those.
Comment #12
tstoecklerHmm... not sure. I'm not so keen on entity keys in general, but it sort of does seem it would be consistent here.
Anyway, here's a re-roll, which should pass. And this implements #10 for now. Thoughts?
Comment #14
tstoecklerWell, that was not particularly smart... :-)
Comment #16
tstoecklerOh lord, this is so embarassing...
Comment #17
tstoecklerThis needed a re-roll after the changed field type.
Here we go.
Comment #18
tstoecklerOh, forgot to mention this: I changed the implementation to not return an array of field definitions but return the single field definition directly. This made for a more fluent API when setting additional stuff on the field definition (i.e. isRevisionable() or isTranslatable()) like CustomBlock or Node do. This can be seen in the patch context.
Comment #23
tstoecklerSo #2506213: Update content entity changed timestamp on UI save already "fixed" this, however in a problematic way, because it hardcoded the name of the changed field to
'changed'. However, maybe after #2635224: ContentEntityBase should provide field definitions for key fields we can use this to auto-generate the changed field and fix the hardcoding.Comment #24
tstoecklerLet's see.
Comment #26
tstoecklerHmm.. should apply to 8.3.x, though, so re-uploading.
Comment #27
tstoecklerComment #29
berdirAdding a key enforces an index on that, and by adding it automatically, we add it to all entity types.
I think we shouldn't have that logic (all keys automatically have an index) but no idea how to avoid that in a non BC way. Removing it will also result in schema changes, just in the opposite direction.
Maybe start to introduce a blacklist of entity keys that shoudn't get a key with a @todo to change it to a whitelist for 9.x?
Or maybe we actually want that index by default? Node adds one by hand at the moment..
Comment #31
timmillwoodIs there any harm in making it revisionable and translatable even if the entity type isn't?
Comment #32
amateescu commented@timmillwood, yes, there is a problem with that. See #2497737: Entity type revisionability is not taken into account when switching field revisionability
Comment #33
hchonovRe #29:
Just talked with @berdir and @amateescu in IRC about this and what @berdir was pointing out is that the entity keys are flagged as NOT NULL, which according to @amateescu will change in #2841291: Fix NOT NULL handling in the entity storage and 'primary key' changes when updating the storage definition of an identifier field "and only required fields will be marked as NOT NULL".
Comment #40
andypostIn related #2086125: Last read comment field/filter/argument uses still the node.changed instead of node_field_data.changed column views needs to make sure that changed field exists for entity type
I used to add todo here because there's no way now to make sure that commented entity has the field (except checking for interface)
Patch is re-roll and fix remaining entities
Comment #43
tstoecklerThe interdiff in #40 is incorrect, but the patch itself looks good, it fixes the media and workspace entity types to no longer declare the changed entity type.
Will pick this up and attempt to fix #29, i.e. remove the "automatic" adding of the entity key. I'm fine with having to add this explicitly, but I think we should then do that for all core entity types and provide respective update paths to add them.
I think we can also still provide the field in
ContentEntityBaseand I think we should then updateEntityChangedTraitto fall back on'changed'as the field name, but with a deprecation notice, so that in Drupal 10 a'changed'entity key will be required for usingEntityChangedTrait. Of course, feedback on all parts of this plan is much appreciated.Comment #44
tstoecklerOK, here's an updated patch that should be fair bit along the path laid out in #43. In detail the following patch:
EntityChangedTraitto fall back to hardcodingchangedas the field name (with deprecation). There is not yet deprecation testing for this.SqlContentEntityStorageSchemato not mark the changed entity key asNOT NULLin the schema. This is also mentioned in #29 already.UpdatePathTestBaseFilledTestpasses with this applied, so this seems to work. Not sure if we need dedicated update path tests for this because any outstanding schema changes would already fail all existing update tests. I think not, but not sure.ContentTranslationHandlerandContentTranslationMetadataWrapper. I found this by just checking where'changed'is referenced in core. The fallback to hardcodingchangedis still there with deprecation. The deprecation testing for this is also still missing.Comment #45
tstoecklerSorry, not yet in the habit of running the pre-commit script locally. This one should be better.
Comment #50
rassoni commentedReroll patched
Comment #52
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.