Problem/Motivation
Currently when invoking field methods we iterate over the entity translations and call the desired method on each field for each entity translation. However there is no specific order in which we'll iterate over the translations, which might be a problem for contrib and custom if you have a complex field, which updates it's value in the presave method and depends on the entity translation which has been currently edited.
For example if you save a referenced entity in the field presave method with a new revision but before doing so check if the referenced entity is already saved in a new revision. The referenced entity will be changed only for the currently edited entity translation, which means we have to ensure that the field presave method is called first for the current entity translation.
Proposed resolution
Change the order of the entity translation languages over which we iterate in ContentEntityStorageBase::invokeFieldMethod, so that the current entity translation will be processed as the very first one.
Remaining tasks
Review
User interface changes
none
API changes
none
Data model changes
none
| Comment | File | Size | Author |
|---|---|---|---|
| #14 | 2755525-14.patch | 7.01 KB | hchonov |
| #9 | field_invocation_order_failing_test.patch | 5.95 KB | hchonov |
Comments
Comment #2
hchonovComment #3
hchonovComment #4
hchonovOups forget to rename the file name of the entity class.
Comment #9
hchonovComment #12
hchonovComment #13
webflo commentedWe can do it in one line.
$langcodes = array_diff($langcodes, [$current_entity_langcode]);Comment #14
hchonov@webflo done.
Comment #15
gábor hojtsyI think this patch makes sense. I don't think it is a backwards compatibility problem to better define an order that was not defined before. Nonetheless I asked Berdir and plach to look at this, if either of them are available :)
Comment #16
gábor hojtsyAnyway, no need to block this on them I think :)
Comment #18
gábor hojtsyRandom fail.
Comment #20
gábor hojtsyGit checkout error on testbot.
Comment #22
hchonovIt has been a random test failure, so putting back to RTBC.
Comment #24
gábor hojtsyYet another random fail.
Comment #25
hchonovI think this one should be target against 8.2.x and probably per cherry pick taken into 8.1.x as well.
Comment #26
effulgentsia commentedComment #27
alexpottThis looks pretty solid. Looking at ContentEntityStorageBase the other similar invocation by language is ::invokeTranslationHooks() - should we make it behave similarly? I.e starting with the current entity's language? Maybe that doesn't make much sense because this is about firing the translation_insert and translation_delete hooks.
In discussion with @effulgentsia, @catch, @xjm and @cottser we decided that this patch should probably only go in 8.2.x as changing the order hooks are fired in is a behaviour change and this is a task not a bug.
Committed e0af755 and pushed to 8.2.x. Thanks!
Comment #29
hchonov@alexpott like you've mentioned the ::invokeTranslationHooks function is calling the hooks for the new or the deleted translation and this happens with the appropriate entity translation object, therefore everything there looks good. I cannot think at least at the moment of a case where the order of the entity translations for the translation insert and delete hooks does matter.
Thanks for accepting and commiting this change!
Comment #33
gábor hojtsyRemoving from sprint, thanks all again!