Problem/Motivation
The Content Translation module implements most of its business logic based on translation metadata such as the source language, the translation publication status, the translation authoring information and so on. Currently these metadata items are stored in a table holding values for any entity type and they are not exposed through regular field definitions.
This has several drawbacks:
- Metadata storage is not swappable, as SQL storage is hard-coded.
- Metadata items do not have access to all the benefits of being fields, such as automatic REST or Rules integration.
- Some information is duplicated because there's currently no way to have entity-type-specific customizations.
- The current implementation is deprecated and is an example of how things should NOT be done in Drupal 8.
Proposed resolution
Introduce a wrapper class dealing with metadata and use the Content Translation handler to expose field definitions for each metadata item. This entity translation wrapper provides methods to access the various metadata values. This integrates pretty well with our regular entity-type-specific interfaces and could even serve as a pattern for modules adding new base fields. This approach allows to provide an alternative set of field definitions for each entity type and retrieve field values accordingly or even implement more complex logic on top of those. For instance node translation metadata is mapped this way:
- Translation source -> New node base (translatable) field
- Translation outdated status -> New node base (translatable) field
- Translation published status -> Node published status (translatable field)
- Translation author -> Node author (translatable field)
- Translation creation time -> Node creation time (translatable field)
- Translation modification time -> Node modification time (translatable field)
The current custom storage is replaced by our regular entity storage.
Remaining tasks
Reviews
User interface changes
Like we already do for nodes, widgets for the translation name, status and created on the comment form were hidden, as the native ones are used.
API changes
Data access for metadata items has changed from a custom entity property to regular field access. Actual access is performed by the translation metadata wrapper.
Beta phase evaluation
Issue category | Task because the functionality already exists and is not broken, although implemented through D7-style code. |
---|---|
Issue priority | Major because this provides the first actual usage in core of new the Entity Storage Update API. Not critical because we could release Drupal 8 with the current code without introducing functional problems. |
Prioritized changes | The main goal of this issue is reducing fragility by providing the first core implementation of a new core API and serving as an example for contrib module authors. This was specifically approved by a branch maintainer in #98. |
Disruption | Disruptive for contributed and custom modules doing very specific things with content translation metadata, which should be a fairly small number. |
Comment | File | Size | Author |
---|---|---|---|
#152 | interdiff.txt | 3.45 KB | Gábor Hojtsy |
#152 | ct-metadata_fields-1916790-152.patch | 77.74 KB | Gábor Hojtsy |
#149 | ct-metadata_fields-1916790-149.patch | 76.54 KB | plach |
#146 | ct-metadata_fields-1916790-146.patch | 76.3 KB | plach |
Comments
Comment #1
plachComment #2
plachComment #3
plachAnother one I'll try to kick off.
Comment #4
plachComment #5
Gábor HojtsyI'm not sure this will even be possible at this point? And menu items are not yet converted.
Comment #6
plachIt should still be possible, I guess. We have lots of stuff that are still to be declared as fields in the move to NG entities.
Comment #7
penyaskitoI'll try this one, I have @plach close for advice.
Comment #8
penyaskitoThere is a discussion going on about if we should add the translation fields to the entity or if we should create a "translation_entity" or alike, so we are postponing this one on that discussion.
For now what I have is the fields implementation that are attached and I hope we can reuse that.
Comment #9
penyaskitoTypo, wrong type.
Comment #10
plachAfter the entity storge discussion we agreed to proceed with making these regular fields on the entity. For now we will probably keep our current custom storage, but we can proceed with the original plan and make ET metadata regular fields. Sorry for not reporting earlier :(
Comment #11
plachWorking a bit on this, as we need it in #597236: Add entity caching to core. No test fixed yet.
Comment #13
plachSome test fixes
Comment #14
plachtagging
Comment #16
plachThis one should be better.
Comment #18
plachThis should fix the last failures.
Comment #19
plachJust a minor fix.
Comment #20
fagohm, so we need to answer one question first: Should be translation metadata part of the entity?
If yes, then this is a good step into the right direction. But moreover, I think this should move to use extensible entity storage once it is re-usable by modules without having configurable fields. That way it's ensured the entity can be stored in non-sql storage engines (as plach points out above also).
However - if the answer to above question is no, it shouldn't be declared as entity fields, but as separate entities - i.e. translation info entities or so. If you consider the content entity living in mongo and this data in sql, it shows that this really is a separate entity that just happens to hold additional information about another one.
Comment #21
plachTotally +1 on #20.
I think translation metadata should definitely be part of the entity: this would be consistent with revision metadata (revision_uid, revision_created, ...).
Related discussion: #1807800: Add status and authoring information as generic entity translation metadata.
Comment #22
plachI was also wondering whether it would make sense to namespace field names.
Comment #23
plachComment #24
plachComment #25
Gábor HojtsyI don't really know the right answer to #20, I'm inclined to agree that the data is related to the entity the same way revisions are...
As for the actual patch, I think it may be confusing to have a content translation provided translation author/created/status, etc. field while an entity may very well have those as translatable properties. So where is the real data then?! I'd assume the status of the translation would be the "translated" status property value. No?
Comment #26
plachThis was the conclusion of #1807800-57: Add status and authoring information as generic entity translation metadata:
Letting alone the storage, which may still change in the future, what we would be missing is the node alteration- Are we still ok with this plan?
Comment #27
plachRerolled
Comment #29
plachSorry, wrong patch
Comment #30
plachComment #31
penyaskitoI don't know if its dreditor or my chrome installation, but I hate when dreditor dont paste :___(
We should use $account->hasPermission() here
Why the uid is a special case?
This todo should be a issue somewhere, but unrelated to this patch AFAIK.
\Drupal::currentUser()
Comment #32
plachThanks, here is an updated patch.
Yep, totally, a novice issue would be great :)
Because it's an entity reference and it needs to be set using the
target_id
property. I removed the special casing on get, though.Comment #33
aspilicious CreditAttribution: aspilicious commented32: et-metadata_fields-1916790-32.patch queued for re-testing.
Comment #35
plachRerolled
Comment #36
amateescu CreditAttribution: amateescu commented@plach, you can now use
FieldItemInterface::getMainPropertyName()
which will return 'target_id' for entity reference fields :)Comment #37
plachFixed #36 and updated field definitions to the new object format.
Comment #39
amateescu CreditAttribution: amateescu commentedI can't speak for the rest of the patch as I'm not too familiar with this area but the interdiff in #37 looks good :)
Comment #40
BerdirI think it would be better to make this a single field of a new field type, than then has status, created, changed, source and so on as field item properties.
That's quite a number of classes less that have to be created. And it should make it easy to move the hook_entity_*() implementations to methods of that field type/item class. (except load)
That should also make some of that code quite a bit easier, you should be able to replace those foreach statements with $item/$this->getValue() and setValue().
It should also bring you closer to being able to store this like a configurable field without being one.
Until then, there's still a problem with loading the values, in combination with #597236: Add entity caching to core. Right now, entities coming from the cache need to go through hook_entity_load(), as there's a lot of stuff that's not a field yet. Maybe we can avoid that, I don't know yet. The problem is that there's not really a way to load those values in an efficient way from within the field item class.
Comment #41
plachI had a discussion about this with @Berdir in IRC, where in the end we both agreed we need @fago's feedback on #26 and #40.
Here is the full log:
Comment #42
plachComment #43
fagoI must say that the "megafield" approach seems quite natural too me and does away with all that translation_* prefixed fields, so DX wise I'd see it as a plus.
I like the performance advantages of the megafield as well, but I share the concern of plach regarding formatter and widgets.
This eases doing a common formatter, which formats all of the fields in a good readable summary, it doesn't necessarily make things easier at the widget side. We could still try re-using the separate widgets by implementing a "composite" widget that just comes up with field definitions and forwards them to the individual widgets.
Thus, given the performance implications I'd agree with berdir that a megafield makes sense here. This together with the dx benefits, outweighs the formatting/widget difficulties imho.
Thinking ahead, something like a field-collection-ng would make most sense here imo, i.e. field-collection leveraging regular host-entity field storage, but doing a collection entity which is used for rendering/formatting.
Apart from that this shows us the disadvantages from having Widgets/Formatters bound to the item level when they really are about individual values.
Comment #44
fagoComment #45
das-peter CreditAttribution: das-peter commentedre-rolling
Comment #46
das-peter CreditAttribution: das-peter commentedRe-roll done. Start reviewing.
Comment #47
das-peter CreditAttribution: das-peter commentedWhile reviewing the patch I was wondering why we've the table
content_translation
.As far as I can tell all the data that are held in this table could reside in the
data_table
of an entity type too.The missing fields would be
source_language
,translation_outdated
and maybetranslation_status
to provide a translation specific status besides the entity status.Those fields would be mandatory for translation support, but the others e.g. uid could be optional and thus handled similar to the title field right now.
With this the discussion about fields / "megafields" would be obsolete too and as far as I know we could have a widget for all of those fields.
Please tell me if I'm on the total wrong track or if the I could work on changing the approach.
Comment #48
YesCT CreditAttribution: YesCT commented@plach Did @fago's comment in #43 give you want you needed?
What should happen next here?
Comment #49
jibranI reviewed the patch but haven't find any doc related issue.
Comment #50
YesCT CreditAttribution: YesCT commentedjust rerolling.
nothing really to note (unless it fails).
just for the record:
1.
conflict in NodeTranslationUITest:
assertEqual should have separate arguments to compare (not == in the first arg).
so resolved like:
2.
conflict in ContentTranslationUITest
context like change ->entityTypeId
resolved like:
3.
then similar:
resolved like:
4.
in ContentTranslationController
resolved like:
5.
conflict in content_translation.module
resolved like
6.
conflict
resolved like
7.
conflict in content_translation.admin.inc
was just adding:
so resolved like:
8.
also
resolved like:
Comment #52
YesCT CreditAttribution: YesCT commentedFatal error: Call to undefined method Drupal\comment\Entity\Comment::getPropertyDefinitions() in /var/lib/drupaltestbot/sites/default/files/checkout/core/modules/content_translation/content_translation.module on line 716
Fatal error: Call to undefined method Drupal\entity_test\Entity\EntityTestMul::getPropertyDefinitions() in /var/lib/drupaltestbot/sites/default/files/checkout/core/modules/content_translation/content_translation.module on line 716
...
I'l try and fix those.
Comment #53
BerdirThat is getFieldDefinitions now
Comment #54
YesCT CreditAttribution: YesCT commentedgot distracted with irc. back to this.
ah, #2002134: Move TypedData metadata introspection from data objects to definition objects
huh, only one in the patch. easier than I thought. let's see what the testbot says.
I think there are still some type things.
Comment #56
YesCT CreditAttribution: YesCT commentedI wont get to this till later.
Comment #57
herom CreditAttribution: herom commentedfixing a bit.
Comment #59
plachPlease be aware that the patch currently an approach that is not what berdir and fago were suggesting. I am not sure I agree with their proposed solution, but probably it would be better to make sure we are all on the same page before working more on this.
Comment #60
BerdirYeah...
There are two open questions..
First is if this should be a collection of fields or a single one. Both approaches have their advantages and disadvantages, a single field would require less code to get/set the values but it's unclear how to do deal with widgets then.
The other one is how and what exactly even makes sense. Which is quite a tricky question. See #47. If you look at node, then status/created/changed seems duplicated, and it's very unclear what the difference between the node fields and the translation metadata is, if you do a query, which one should you filter on if you want to see published translations? Same for created/changed...
On the other side, assuming you would translate user fields, for whatever reason, status will not be a translatable field (that would be too crazy ;)), so there a per translation status might be useful again? I'm a bit lost... :)
Also, note that #597236: Add entity caching to core is now capable of dealing with this, fields or not, so from a performance perspective, this doesn't matter much anymore. It still is relevant for #1977266: Fix ContentEntityBase::__get() to not return by reference, though.
Comment #61
andypostAnother big question here about language for the fields, that one raised in #2201051: Convert path.module form alters to a field widget
Entity could change its language during submit/save so all fields need a way to update their language somehow
Comment #62
andypostMaybe making a
Translation
entity with base fields could help with widgets?I see no big difference between "mega-field-collection" and entity like
MenuLink
Comment #63
plachJust spoke with @xjm about this and she suggested me to mark this as beta target.
Comment #64
Wim Leers#597236: Add entity caching to core is RTBC and is about to be committed. It replaces
hook_entity_load()
withhook_entity_storage_load()
, to deal with uncacheable data. Comment statistics is the first use case, this is the second. If #2304939: Stop loading comment statistics into entity object and this issue land, we might be able to removehook_entity_storage_load()
, which would make the API simpler. Unless we want to keep it because there are valid contrib use cases.In any case, something worth keeping into account when pushing this forward :)
Comment #65
martin107 CreditAttribution: martin107 commentedPatch no longer applies and is quite badly out of date... given the open nature of the questions being asked ... I am not sure a reroll is best maybe #57 should be regarded as an interesting place to harvest large code snippets.
Comment #66
plachI spoke with @fago and @berdir some time ago and if I am not mistaken, their performance concerns are now obsoleted by the latest HEAD code. Thus we should be able to go on with the approach currently implemented in the latest patches. We should probably wait for #1498720: [meta] Make the entity storage system handle changes in the entity and field schema definitions, so we can get rid of the
{content_translation}
table and just exploit entity (field) storage.Comment #67
andypostThe problem with
{content_translation}
table that it allows to store only integer entity IDs.I think there's no reason to wait for #1498720: [meta] Make the entity storage system handle changes in the entity and field schema definitions
Supposed route:
1) Implement special field type "translation" with no_ui setting, configurable field is translatable by default so probably the setting for the field should inherit bundle translatable settings
2) Attach the field dynamically according to translatable entity's status
3) Try to use base field override to proxy the translation field to base field and clean-up after #1498720 is in
Then just ideas:
4) widget could replace language element...
5) field default value and purge needs some love and tests
Comment #68
plachI'd really prefer not to have a translation field type, I see no reason for it to exist. We have revision metadata which is just a set of regular "primitive" fields. We can do exactly the same with translation metadata. We should not feel constrained by the current implementation, which is derived from D7 where we implemented a completely different solution. If we don't want to wait for #1498720: [meta] Make the entity storage system handle changes in the entity and field schema definitions that's fine, then the current patch is mostly ready: we just need to mark fields as custom storage and retain the
{content_translation}
table until we are able store translation metadata in the entity schema.Comment #69
plachHere is a manual reroll (I skipped some unrelated changes). Tomorrow I will address
My plan is declaring translation field overlapping with node fields as computed (just for nodes) and keeping them in sync. This way we'd avoid the double storage and actually we'd have an identity between
$node->uid
and$node->translation_uid
which could just be ignored, except where explicitly needed (only in CT I'd guess).Comment #71
plachJust a work in progress.
Comment #72
andypostIt's a great step forward, computed/proxy fields are nice .. except
status
because some entities does not have published status or have a different state model.otoh having a one field should help with loading the data by one query and caching - the field also could define its schema depending on base entity interfaces
For uid there's
EntityOwnerInterface
for changed -
EntityChangedInterface
Comment #73
BerdirYou should use hook_entity_storage_load(), so that it is then part of the cached entity.
Comment #74
plachThis implies non critical storage schema changes, so it's definitely beta deadline. Also, this belongs to the CT queue.
Comment #75
plachWorking on this...
Comment #76
plachI was finally able to complete my work here. I followed the approach started in the previous patch but I made it more flexible/reliable/consistent by introducing a new (optional) entity handler dealing with translation metadata. Basically it's a wrapper for the translation object that provides methods to access the various metadata values. I think it integrates pretty well with our regular entity-type-specific interfaces and could even serve as a pattern for modules adding new base fields. This allow subclasses to provide an alternative set of field definitions and retrieve field values accordingly or even implement more complex logic on top of those. For instance node translation metadata is currently mapped this way:
This patch also removes CT's custom field storage and exploits our brand new storage schema handler. Things are working reasonably well, but there are still a few issues that I could use feedback on, or that could be addressed in separate, non beta-bound, issues:
EntityOwnerInterface
andEntityChangedInterface
in the base content translation metadata handler implementation. I am wondering whether it's reasonable to ask a user to manually enable metadata fields for translation, before things start working in the (most commonly) intended way. Might this be an indicator that the translation status and node per-language status should be handled separately? And if not what could be a reasonable UX to make things work smoothly?Last but not least I am experiencing a weird exception when trying to attach some base fields to the
{user_field_data}
table. These are the problematic ones:Despite this things seem to work properly so, unless someone has some brilliant suggestion to fix this, I am wondering whether it would be ok to add a @todo to investigate these errors separately and avoid holding up the issue on them.
I am not attaching an interdiff as I touched almost every line of the previous patch, sorry.
Comment #78
plachThis should be green.
Comment #79
Gábor HojtsyBut we built the integrated UI to enable all the fields for translatability at once? I don't get how this situation arises?
Comment #80
plachDiscussed this with Gabor in IRC:
Comment #81
plachThis fixes #76.4 by automatically creating field columns when settings are saved. Field definitions are kept also when translation is disabled for all bundles so we don't have to cope with field purging, which is not supported yet (see #2282119: Make the Entity Field API handle field purging). This might be a desirable behavior so data is not lost if translation is enabled again, but we can discuss that in a separate issue.
Comment #82
plachComment #85
plachQuick reroll + some new stuff. I will provide an interdiff later, I have to board a plane now.
Comment #87
plachThis should be green again. I did a few merges meanwhile, I will post an interdiff soon with an explanation of the lastest changes.
Comment #88
plachThis is the interdiff since #81 excluding rerolls/merges. Basically I added some logic in the base metadata handler so that all core content entity types are correctly handled, avoiding field data duplication. This required also to fix the comment translation UI to remove the translation name, status and created widgets as the native ones are used.
The metadata handler for now relies on the existence of field definitions with well-known names, we should probably add interfaces for the publishing status and created metadata, so we can fix that. Follow-up work :)
This should be ready to go, hopefully.
Comment #89
plachCreated #2347301: "Data truncated for column" exceptions thrown when adding fields to the user entity type and updated the related comment.
Comment #90
plachUpdated issue summary.
Comment #91
plachComment #92
andypostwe can use here field access
suppose name is fragile but can;t remember exactly is this set differently for anonymous and authorized. maybe check here is needed... maybe could be moved to boilerplate code for EntityAuthoredInterface
good catch
any reason for the full object?
Comment #93
andypostis not equal
2 todo
yay
contentTranslationManager better
the same
is there a actual status? this could be used for "draft"
yep
where ... +and CTfield column = some data
Comment #94
plachRestored issue summary, and addressed #92.2.
1. We cannot use field access there, since there are no corresponding fields defined
4. Just to have symmetric accessors, no technical reason
Quoting @andypost from IRC:
Comment #95
plachOops, the patch
Comment #96
larowlanrtbc by proxy, 3am need for sleep took it's toll
Comment #97
andypostThe polish in #93 is just 2am
Comment #98
catchDiscussed this with Plach and Alex Pott today. There's no contrib module-facing API change here (unless you do very specific things with translation metadata form elements similar to the comment hunks in the patch, which isn't going to affect most modules).
So making this beta target/D8 upgrade path. I don't think I'd want to do it once we're supporting the upgrade path though so it'd have to go in before that.
The @todo with the try/catch looks like it'd be fixed by #2232477: Fatal when adding new fields with NOT NULL constraints in a base table that contains existing entities. That bug isn't introduced here but would be happier committing here with that issue fixed and no @todo if we can.
Comment #99
fagoDid a first review since a while - remarks/questions below:
That's strange, why does it only return already installed definitions. How can those be ever added then?
I do not fully get this. So this a handler which has an instance per translation?
If this is a factory, shouldn't it be called create something ?
This method has the same summary as the one before - but it seems to be different?
What is a native published status vs non native? Both sits on the entity objects, so both are "native" imo. Why not just call all those methods "hasWHATEVER" ?
This is talking about handlers but then the interface is nothing about handlers ? Also, if it's just adding some additional logic that is not customized by entity type it probably shouldn't be a handler, but a service.
?!? Why does it talk about profiles if it is about users? We already have "account" and "user", please do not start using another noun for it ;)
Comment #100
plachJust a reroll for now.
Comment #102
plach@fago:
1: Installed definitions are taken into account only when no bundle is enabled for translation: this allows to keep field data around if a bundle is disabled and then enabled again. See the updated comment in the interdiff.
3: Not necessarily: the entity manager handler factory method is called
::getHandler()
. I think::getTranslationMetadata()
makes way more sense DX-wise.5: Fixed.
7: Fixed. We have
ProfileForm
andProfileTranslationHandler
(which is tied to that form), but translation metadata is not tied to forms, so I guessUserTranslationMetadata
makes more sense.2/4/6:
Quoting from the
ContentTranslationMetadataInterface
PHP docs:The main point of the current approach is that every entity type may need to implement translation metadata in a different way, relying on a different set of field definitions or even on completely custom logic, thus a service is really not viable here. In most places the metadata handler acts as a content translation metadata wrapper (this concept may sound familiar to you ;), providing an interface to access translation metadata in the same way entity-type-specific interfaces do for "native" base fields. I think this approach works well and could even become a pattern for contrib modules adding base fields to entity types. We could even add the concept of wrapper as a section in the Entity plugin definition and a helper factory method to the entity manager, if we decided this is a good pattern.
There are also a few cases where just the field definitions are needed, so the metadata handler does not require to act as a wrapper. This is why I added two factory methods: in Java I would exploit overloading to give them the same name but different signatures. We could also conflate them into a single method and remove type hinting but I am not sure the result would be cleaner.
Comment #103
plachComment #104
plach@fago:
Is #102 fine? Can we go back to RTBC?
Comment #105
plachComment #106
plachThe last paragraph in #102 is what might need some additional thought, but IMO #102 addresses @fago's review so back to RTBC...
Comment #107
plachAssigning to @catch per #98.
Comment #108
plachRemoving exception handling as the related error should be fixed by #2232477: Fatal when adding new fields with NOT NULL constraints in a base table that contains existing entities.
Comment #110
plachWorking on the test failures, sorry for the noise.
Comment #112
plachThis should fix the new failure reported in #102. The other three test failures will be fixed by #2232477: Fatal when adding new fields with NOT NULL constraints in a base table that contains existing entities (checked locally).
Comment #114
plachComment #115
fagoah, I see. I had to look at the code though to understand the flow - it's actually not returning last installed definitions at all - but just determines whether to add/return the metadata fields. So maybe the comment could say something like
Still not sure about the handler as wrapper thing. Let's discuss it with berdir in person? :)
Comment #116
plachDiscussed this with @fago and @berdir, I'm going to:
content_translation_
Comment #117
plachThis should address #115 and#116
Comment #118
plachComment #119
fagoThanks! I took a look at the changes. Here some remarks:
Should link to https://www.drupal.org/node/2232477. Also, we do postpone committing this one on the mentioned issue, right?
As discussed, setting the default can/should happen in hook_entity_type_build()
handler
handler
Should be ContentTranslationMetadataWrapper (and same for the interface) such that the name already reflects it's wrapping it?
Should clarify it's about the metadata fields only.
Should use $translation->hasField() as it's better readable. We can do away with $this->fieldDefinitionNames then I think.
Should be user translation handler.
Not sure about that. Blocked users are not accessible aka published either?
Comment #120
plach1: That was just needed to ensure tests are still passing, I will remove it again now.
2: I don't agree with that, sorry:
hook_entity_type_build()
should be implemented by methods implementing the CT API, this is the only way to ensure CT enters a value only when an explicit one is not defined.5: Thinking about it, IMO there's no need to expose that implementation detail in the interface name. This way it's more concise and meaningful, because we stress on metadata not on wrapper.
8: That would be an unnecessary API change, that class has not been introduced here.
9: That would mean tying the visibility of a biography field with the ability of a user to log in, that would not make much sense to me. The user status is not translatable obviously, if we went this way it would not be possible to have per-language translation visibility for users and unpublishing a translation would block the user :)
Comment #121
fagoSo the way I understood our discussion was that CT provides the default via the build, and modules can alter the default. But yeah, it seems to be better to have the modules implement the build and leave the alter to other modules that need to alter.
Imo, this is no implementation detail, but a fact that every dev making use of the interface has to understand - so have it in the name helps by clearly communicating it.
I see, missed that.
That's already the case if you look at UserAccessControlHandler:
Comment #122
plachI agree with the view part, but consider the other way around: unpublishing a translation would block the user, while I might just want to make the translation not accessible while it's being completed.
Comment #123
fagoI see, makes sense.
Comment #124
plachThis should address #119.
Comment #125
plachReviewing my own patch:
We need to update this comment.
node > comment
This documentation is outdated.
These can be one single line.
Comment #126
fagoLooked at the interdiff and patch once again - looks both solid to me. Given we can remove this with #2232477 being fixed, this should be ready as well. (Not setting RTBC for now because of that only).
Comment #127
plachThanks! Here is a reroll while we wait for #2232477: Fatal when adding new fields with NOT NULL constraints in a base table that contains existing entities.
Comment #129
plachFixed failing test, still waiting for #2232477: Fatal when adding new fields with NOT NULL constraints in a base table that contains existing entities.
Comment #130
plachComment #131
plachThis fixes #126 and addresses the case where values coming from the DB are actually NULL. If green should be ready to go as per #126.
Comment #132
plachUnused
Comment #133
plachGreen, anyone willing to move this back to RTBC? :)
Comment #134
jibranA very minor issue.
Can we rename this to contentTranslationManager?
Comment #135
plachNot sure it's worth: it's a bit long and we are using a
$manager
variable everywhere else.Comment #136
fagoGreat to see it working without the hack, RTBC then.
Comment #138
plachRerolled
Comment #139
plachRemoved merge leftover.
Comment #140
plachAdded beta evaluation and updated the issue summary.
Comment #141
Gábor HojtsyThanks for the reroll. Back to RTBC.
Comment #142
plachAdded draft CR at https://www.drupal.org/node/2404255
Comment #143
alexpottSo we need a test which makes an entity type translatable through the config importer. At the very least if that occurs we need to inform the user that db updates needs to be performed. Maybe even better would be to actually run the updates.
Comment #144
plachGood point, the attached patch applies the updates after config import has been finished and provides test coverage for that.
Just a note: the quote above is outdated, as updates are applied when submitting the configuration form now.
Comment #145
plachJust a reroll. Any chance to get a final review?
Comment #146
plachFixed DI in the new service.
A note for reviewers: I introduced a new service dealing with updates to avoid changing existing interfaces or introducing new ones, as this area could still change a bit after #2346013: Improve DX of manually applying entity/field storage definition updates. Since we have no official policy about what constitutes a public API, not providing an interface is a way to say "hey, this is not for public use, do not rely on it".
Comment #147
plachHopefully this is good enough to go back to Alex directly...
Comment #149
plachRerolled
Comment #150
plachGreen, back to RTBC
Comment #151
alexpottSome minor nits.
This is unneeded - ContentLanguageSettingsForm::submitForm() adds exactly the same message.
Unnecessary blank line
Comment line wrapping needs redoing.
Comment #152
Gábor HojtsyIndeed. Removing that message, extra line and rewrapping.
Comment #153
plachRTBC +1 :)
Comment #154
plachComment #155
alexpottCommitted 920382d and pushed to 8.0.x. Thanks!
Thank you for adding the beta evaluation to the issue summary.
Comment #158
plach/me weeps softly ;)
Comment #159
miro_dietikerI was confused about the messages above / commit / revert sequence. They are in wrong order.
17df2c5 is the final commit. c15cf7d reverted the one from before.
Comment #160
Gábor Hojtsy/me hands stack of napkins to @plach
Thanks for your persistence!
Comment #161
plach:)
Comment #163
penyaskitoThanks!!
Comment #164
plachRelated clean-up: #2479815: Remove obsolete ContentEntityInterface::initTranslation() method.