Problem/Motivation
If we have multi-language setup and want to create a view for non-translatable entities (entities with no langcode key) we will get a nice SQL exception as a notification that is not possible to do it. This started to fail since #2342045: Standard views base fields need to use same rendering as Field UI fields, for formatting, access checking, and translation consistency.
Steps to reproduce:
- Enable language_test, entity_test and content_translation modules. (Note: Make sure you have extension_discovery_scan_tests set to TRUE in your settings.php . This will allow you to install test modules)
- Go to admin/config/regional/language and add a new language.
- Edit NoLanguageEntityTest.php and add a Views data handler. Check #24 interdiff how to do it.
- After you make the annotation changes, we have to clear the cache. Go to admin/config/development/performance and hit "Clear all caches".
- Go to admin/structure/views/add, fill the view name, machine name. From View settings choose "Test entity without language support". Click the "Create a page", fill "Page title" and "Path" (e.g no-view) fields.
- Go to /no-view (or your custom) path.
- You should get an exception:
Drupal\Core\Database\DatabaseExceptionWrapper: Exception in test[tes]: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax...
Proposed resolution
Instead of the assumption made in TranslationLanguageRenderer that all entities have a langcode key, we should add a condition to check if it is the case. To complete the issue, we also have to provide tests.
Remaining tasks
Get the patch in.
User interface changes
No.
API changes
No.
No data model changes either.
RC Eval
This patch is just a bug fix. No data model changes, no API changes, no disruption. It has a test. It changes only a few lines of code, which are made clearer than they were and it fixes a bad assumption in those few lines of code. I think it blocks at least one contrib project. It should be good for RC.
Comment | File | Size | Author |
---|---|---|---|
#46 | 2453551-46.patch | 9.39 KB | edurenye |
#44 | interdiff-2453551-38-44.txt | 1.06 KB | edurenye |
#44 | 2453551-44.patch | 3.02 KB | edurenye |
#38 | 2453551-38-interdiff.txt | 978 bytes | mbovan |
#38 | 2453551-38.patch | 9.39 KB | mbovan |
Comments
Comment #1
BerdirComment #4
effulgentsia CreditAttribution: effulgentsia at Acquia commentedI presume that this issue is just about content entities, but I'm wondering if the above premise conflicts with the change being proposed in #2451885: Config entities need to ship with language or are assumed undefined, specifically, this claim from that patch's docs:
Does it make sense for us to say that content entities (which can be extended with fields) are allowed to not have a langcode, but config entities (which can be extended with third party settings) are not?
Comment #5
BerdirInteresting point.
It is now possible to add configurable fields to anything, so I can't prevent it, but there's no field_ui integration, so I don't really expect
Thinking about it, I guess I could make my source language the langcode, but not sure what I gain from that. A translation job *does* have a label that a user can enter, but it is a backend entity, nothing that is shown to normal users. There are filters in the default view, but nothing of the usual stuff (like displaying in the interface/content language) applies.
Config and content entities already have similar differences.. having a UUID for content entities is optional (aggregator feed items don't, they have a guid that is provided by the feed, but not a generated UUID) but required for config entities.
Comment #6
dawehnerDo we have any entity type without a language in core?
Comment #7
BerdirWe do I think although possibly more accidentally because we forgot to add it.
EntityTestFieldOverride for example doesn't have a langcode.
Comment #8
dawehnerI'd argue that for those we should on top not allow people to select the TranslationRenderer in the UI.
Comment #9
Gábor HojtsyComment #10
BerdirWe were able to fix our problem by changing the view by hand to use entity_default. Removing the contributed project blocker tag.
As suggested by @dawehner, a better fix might be to make sure that we use that renderer if there is no langcode key, and throw an exception if called for the other one, because that simply doesn't make sense.
Comment #11
jhodgdonRegarding #8's suggestion, ... what would happen if the base table for the view was for a translatable entity, and it had a relationship to an entity that wasn't?
Comment #12
plachJen has a good point in #11: the Translation renderer should be able to fall back to the Default language behavior if no
langcode
key is available. This way related non-translatable entities would be handled smoothly even if the translation renderer is configured in the view. I agree it should not be available if the view base table refers to a non-translatable entity type.I know this line was not introduced here, but we should be using
TableMappingInterface::getFieldTableName($langcode_key)
now.Setting to NW also for tests.
Comment #13
Saphyel CreditAttribution: Saphyel as a volunteer commentedI rerolled the patch.
Comment #14
plachThanks, setting back to needs work per #12.
Comment #15
Gábor HojtsyDoes not seem to be actually worked on.
Comment #16
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedDone, I'm not sure if I did this in the best way, but it works.
Now I will work on the tests.
Comment #19
andypostCore should support content entities without
langcode
key\Drupal\Core\Entity\Entity::language()
already returns\Drupal\Core\Language\LanguageInterface::LANGCODE_NOT_SPECIFIED
when nolangcode
key provided by annotation.Also views needs to care about relation, and do not try to add non-existing field to query
There's a lot of reasons to have conetnt entities in contrib without language.
+1
Comment #20
mbovan CreditAttribution: mbovan at MD Systems GmbH commentedRerolled and fixed some table mapping calls... Also, changed wrong variable type in
RendererBase
.Tests are still needed.
Comment #21
BerdirI still don't understand why this removes the break?
Needs work for tests.
Comment #22
mbovan CreditAttribution: mbovan at MD Systems GmbH commented^ As there is no loop anymore.
Comment #23
jhodgdonYeah, no loop => no break.
Leaving at Needs Work because this still needs a test.
Comment #24
mbovan CreditAttribution: mbovan at MD Systems GmbH commentedAdding tests... Btw, not sure whether
core/modules/language/src/Tests/
is right place for this test.Comment #26
jhodgdonThis test looks right to me!
But I'm not sure if it reproduces the problem in this issue. I think it does, but we really need an issue summary update, because the issue summary is difficult to understand (kind of garbled or incomplete or ... anyway not great).
Minor issue with the test:
This should probably have more correct information about the purpose of the test, which is to verify that entities without translation don't break Views. I don't think it's really about test language entities.
Comment #27
BerdirPff, the issue summary looks perfect to me! ;) (I wonder what I was drinking when I wrote that...)
I guess the test belongs in views module as the code is there as well?
It would probably be easier and definitely faster to just save that view as optional default config in the language_test module.
Probably wouldn't hurt to actually create an entity and make sure the title or so is shown there?
Same for the language, actually. Use the API, then we don't need an admin user and all that overhead. ConfigurableLanguage::createFromLangcode()->save() is all you need I think.
Comment #28
mbovan CreditAttribution: mbovan at MD Systems GmbH commentedMoved the test to View module and improved it a bit with API calls.
Comment #30
mbovan CreditAttribution: mbovan at MD Systems GmbH commentedUpdated the issue summary. Hope it's a bit more clear how to reproduce the bug.
Comment #31
jhodgdonThanks for the summary update! Much nicer.
Comment #32
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedLooks perfect now!
Comment #33
jhodgdonThis all looks good, but:
It seems like this code comment needs to be revised, since the code below it got revised. I don't think it matches any more.
Comment #34
BerdirWhat about dropping that code comment completely?
Unlike before, the code is pretty self-explanatory to me, we're using API methods whose names make it very clear what we are doing. I don't see that we could add something useful with a code comment there?
Comment #35
jhodgdonSure!
Comment #36
BerdirDid just that, but noticed the existing condition above.. what if we just combine that into a single if condition? It's not really visible in the patch but with the previous patch, we had two different checks and did them differently (nested if vs. early return).
Also improved the initial comment a bit.
Comment #37
jhodgdonNitpick: this comment line goes over 80 chars.
I would also change "in case" to "if", which would bring it down below 80 chars. ;)
Or maybe explain what the method is actually doing... something like:
In order to render in the translation language of the entity, we need to add the language code of the entity to the query. Skip if the site is not multilingual or the entity is not translatable.
Anyway, this is just the comment. I think the code looks great! Very clear.
Comment #38
mbovan CreditAttribution: mbovan at MD Systems GmbH commentedAdded the comment above.
Comment #39
jhodgdonThanks! But:
nitpick: comment line over 80 characters, please rewrap.
Comment #40
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedMy IDE says that it's just 80 characters and that it's fine.
Comment #43
jhodgdonHm. The line is 80 characters plus 1 for the \n at the end, totalling 81. dreditor complains, and that is what we normally go by... can you please rewrap? Thanks!
Comment #44
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedOk, done. I didn't know that, every day it's a school day.
Comment #45
jhodgdonThanks! but that patch is missing files
core/modules/language/tests/language_test/config/optional/views.view.no_entity_translation_view.yml
core/modules/views/src/Tests/Entity/ViewNonTranslatableEntityTest.php
from the previous patch.
Comment #46
edurenye CreditAttribution: edurenye at MD Systems GmbH commentedSorry, I didn't realize. My gitignore did not add them :(
Now should be fine.
Comment #47
jhodgdonThanks! Yes, you have to be careful when making a patch, if there are new files added rather than just changes to existing files.
Anyway... the latest patch looks perfect. As in previous patches, we have a clear test that fails without the patch, and passes with the patch. The code is cleaner than it was, and the comments are clear. Let's get this in.
It should be RC eligible -- no API change, no disruption, just a bug fix and I think it's a contrib blocker though I'm not the reporter so I'm not sure. Adding RC eval notes to issue summary.
Comment #51
effulgentsia CreditAttribution: effulgentsia at Acquia commentedDiscussed with the other committers, and +1 to this being sufficiently non-disruptive and sufficiently beneficial in terms of solving a fatal bug for the conditions that trigger it.
Comment #52
alexpottCommitted b412acf and pushed to 8.0.x. Thanks!