Problem/Motivation
Every code which deals with a single content entity in a controller has to load the proper language manually, because we always load the content entity in its original form in upcasting.
Proposed resolution
We should just load the right translation in the routing level, same as we do for configuration entities, which we only load in the original language in the upcast when in an admin context.
Remaining tasks
- Review.
- Commit.
User interface changes
None.
API changes
None. But the expectation about the loaded entity will change, it will load the entity in the proper language for the page.
Comment | File | Size | Author |
---|---|---|---|
#45 | entity_upcasting-216095-45_TESTS_ONLY_SHOULD_FAIL.patch | 3.32 KB | robertdbailey |
#45 | entity_upcasting-216095-45.patch | 6.05 KB | robertdbailey |
#42 | demo.tar_.gz | 1.42 KB | broon |
#38 | entity_upcasting-216095-38.patch | 2.73 KB | robertdbailey |
#33 | reroll-entity_upcasting-216095-33.patch | 3.14 KB | fran seva |
Comments
Comment #1
BerdirThis is part of a larger problem on how we now want to deal with entity translations, see the comments #125 and #145 in #2019055: Switch from field-level language fallback to entity-level language fallback, among others. We need a meta issue to discuss and implement the whole thing.
We can use this or create another issue, and the meta will need to be added to #2095603: [meta] Complete Entity Field API :)
Comment #2
plachComment #3
Gábor HojtsyIf this is an API change significant enough, we may need to elevate this to Critical and beta blocker? Since nobody was working on this for 5 months, I'm removing from the sprint board as a start at least.
Comment #4
plachI am not sure this will be an API change itself, but it might imply a change in how code is written. I am sorry I was not able to work on this, but I really feel I should be the one at least starting the work. I will try to get back here as soon as we are done with the entity storage stuff.
Comment #5
dawehnerThis one is probably blocked based upon #1906810: Require type hints for automatic entity upcasting, given that it would change similar code, potentially.
Comment #6
plachWe should really try to get this in before beta.
Comment #7
tim.plunkettThat went in.
Comment #8
dawehnerThis is a really naive approach. Maybe we want to have this logic in another request listener.
Comment #10
BerdirThere's a method for this that we can use.
Comment #11
Gábor HojtsyWe already do this for config entities by default. It would be useful to match behaviour with content entities then. Updated issue summary and title.
Comment #13
BerdirKept the interface check to avoid that NULL is passed into that method.
Comment #14
dawehner@berdir
Good idea to use getTranslationFromContext ... Is there a specific reason why you added the check for the TranslationInterface? I would argue that the method on the entity manager should not fail in case you pass in some other entity, and afaik it should not.
In case you just wanted to fix the NULL case I would recommend to check for EntityInterface given that this seems a little bit more semantically correct.
Comment #16
BerdirWow, did expect more fails, although I have no clue what the delete thing there exactly means ;)
Yeah, possibly checking for EntityInterface or just != NULL might make more sense, getTranslationFromContext() does have the same interface check internally, checking for this interface would avoid the additional step into that function, though.
Comment #17
plachThis looks promising, thanks!
I am wondering whether it would make sense to pass an
entity_upcast
context operation, to allow modules to perform a more targeted altering.Comment #18
herom CreditAttribution: herom commentedThe delete issue is caused by the following lines. Now, the entity is loaded in the same language that it's removing, so the save will fail.
I don't know the best solution here, but I tried falling back to the default language in removeTranslation; let's see if the tests are happy.
There is still a fail in EntityTranslationFormTest.php, which I couldn't figure out. It's showing "Access Denied" when visiting [langcode]/node/[entity_id]/edit in the test.
Comment #20
plachWe should not be changing the active language of a translation object, instead we should just instantiate the original object in the CT remove translation controller.
Comment #21
yched CreditAttribution: yched commented(tangential : the internal language handling in ContentEntityBase could be vastly simplified - #2142885: Simplify ContentEntityBase internal field storage by removing special treatment for LANGCODE_DEFAULT)
Comment #22
herom CreditAttribution: herom commentedupdate.
Comment #23
plachThanks, this looks almost good to me!
This should be
TranslatableInterface
.@Berdir:
What do you think about #17?
Comment #24
herom CreditAttribution: herom commentedcorrecting based on #23.
Comment #25
plachRTBC here. Sasha, Daniel?
Comment #26
BerdirWe went back and forth on that instanceof earlier already. I don't really care, but the thing is that TranslatableInterface does not extend EntityInterface and that method is type hint on EntityInterface (and then internally checks for TranslatableInterface).
The result is that this PHPStorm highlights this as incorrect. That said, I don't care which one it is. If you're OK with this then I am. A bit surprised that there wasn't more that we had to do.
Comment #27
dawehnerI guess we could just typehint for both, what do you think?
Comment #28
BerdirOr that. The main reason that I added the interface check at all is to avoid passing NULL (for non-existing entities) to that method. So just "if ($entity) {" would work too. Either way, a comment would probably make sense, something like "Ensure that translatable entities are set to the current language", or something like that. Suggestions on the wording and exact approach, @plach?
Comment #29
plachWhat about this?
Comment #30
dawehnerI am fine with that comment.
Rerolled with --3way
Comment #31
plachLooks good, thanks
Comment #32
alexpottLet's get some test coverage of this.
Comment #33
fran seva CreditAttribution: fran seva commentedI'm working in the test coverage.
The patch#30 needs reroll
I have resolved the conflict changing using randomMachineName(16) instead randomName(16).
The reroll is attached.
Comment #34
fran seva CreditAttribution: fran seva commentedComment #37
BerdirTagging novice for reroll and tests.
A test should check that a route that receives an entity as a route parameter should get it in the right language. So enable a module with entities, add a test route in a test module that accepts {node} or similar, then output the value of $entity->language()->getId() in the controller and check that is correct when access in diferent languages.
Comment #38
robertdbailey CreditAttribution: robertdbailey commentedRerolled patch. Will work on tests next.
Comment #39
realityloopComment #40
star-szrComment #41
pp CreditAttribution: pp commentedI enable Language, Content translation module.
Add a language
Add a test text field to account
Edit Admin profile and set the test text to English
Try to translate Account, and set test text to Hungarian
Test text is always Hungarian. I try user/1 and hu/user/1 path.
How do I test/review this issue?
Comment #42
broonI wrote a simple demo module for that, reporting the entity language of nodes when calling
/demo/entup/{nid}
.It returns
Node language ID: en
for all three languages (en,de,hu) in my test system when calling one ofApplying the patch via
patch -p1 < entity_upcasting-216095-38.patch
runs through without issues and applies correctly.The output of the module now reflects the correct language
See attached archive for using the demo module to generate the output mentioned above.
Comment #43
alexpottIt would be great to have an automated test for this.
Comment #44
robertdbailey CreditAttribution: robertdbailey commentedComment #45
robertdbailey CreditAttribution: robertdbailey commentedCreated a test that adds a language (German in this case) and assigns a prefix (de), and then it creates a node in English and its German translation and then verifies that the right translation is loaded by the router. The tests-only patch should fail, as the patch is not applied there; and the patch with tests should succeed. Please review.
Comment #46
tstoeckler@robertdbailey proved to me on his machine that the tests pass/fail as expected. Awesome!
I think we can knock this one out.
Comment #50
robertdbailey CreditAttribution: robertdbailey commentedreattempting patch test. Previous failure was:
FAILED: [[SimpleTest]]: [PHP 5.4 MySQL] Failed to run tests: failed attempting to get list of tests from run-tests.sh.
Comment #53
robertdbailey CreditAttribution: robertdbailey commentedSetting back to RTBC per review by @tstoeckler.
Comment #54
realityloopComment #55
plachAwesome work, RTBC +1.
Comment #56
alexpottCommitted b35d190 and pushed to 8.0.x. Thanks!
Comment #58
Gábor Hojtsy