Problem/Motivation

As discovered in #2820848-64: Make BlockContent entities publishable, Content Translation metadata fields ('content_translation_source', 'content_translation_outdated', 'content_translation_status') do not use an initial value for entities that exist prior to enabling CT on an entity type.

This poses a problem if anyone needs to rely on that data for example when making an entity type publishable by adding a 'real' status field.

Proposed resolution

Make CT use an initial value (#2346019: Handle initial values when creating a new field storage definition) for those fields and fix existing inaccurate data.

Remaining tasks

Write tests.
Review.

User interface changes

Nope.

API changes

Nope.

Data model changes

Nope.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

amateescu created an issue. See original summary.

amateescu’s picture

Status: Active » Needs review
Issue tags: +Needs tests
FileSize
4.74 KB

This should do the trick.

We also need to write tests for the update function, but for that we need a new test database dump which is also required in a few other issues, so I will post a separate issue for it.

Note that the patch depends on #2346019: Handle initial values when creating a new field storage definition, so I'm just setting it to NR in order to get some initial reactions on it.

amateescu’s picture

Title: Use initial values for content translation metadata fields and fix existing data » [PP-2] Use initial values for content translation metadata fields and fix existing data
amateescu’s picture

Ok, now that we have the issue which adds new test db dumps, here's a test for this patch!

Now this depends on the following issues, so I'm posting a combined patch as well:

#2856808: Break out the 'entity_test_update' entity type into its own module and add additional test db dumps
#2841291: Fix NOT NULL handling in the entity storage and 'primary key' changes when updating the storage definition of an identifier field
#2346019: Handle initial values when creating a new field storage definition

No interdiff because the only change is the added test.

amateescu’s picture

Title: [PP-2] Use initial values for content translation metadata fields and fix existing data » [PP-3] Use initial values for content translation metadata fields and fix existing data

Also, there's no need for a test-only patch because we're introducing new functionality that cannot be tested without the other changes in the patch.

Status: Needs review » Needs work

The last submitted patch, 4: 2854732-4-combined.patch, failed testing.

amateescu’s picture

Status: Needs work » Postponed

Ok, there are a few failures that need to be fixed but let's wait for some of the dependencies to land first.

jibran’s picture

Just walk by review.

  1. +++ b/core/modules/content_translation/content_translation.install
    @@ -62,3 +64,64 @@ function content_translation_update_8002() {
    +      $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType($entity_type_id);
    

    EDUM can be stored in a variable outside of the loop.

  2. +++ b/core/modules/content_translation/content_translation.install
    @@ -62,3 +64,64 @@ function content_translation_update_8002() {
    +            ->fields(['content_translation_outdated' => 0])
    ...
    +            ->fields(['content_translation_status' => 1])
    
    +++ b/core/modules/content_translation/src/ContentTranslationHandler.php
    @@ -117,14 +117,16 @@ public function getFieldDefinitions() {
    +      ->setInitialValue(0);
    
    @@ -143,7 +145,8 @@ public function getFieldDefinitions() {
    +        ->setInitialValue(1);
    

    Should we use constants here?

amateescu’s picture

Status: Postponed » Needs review
FileSize
9.29 KB
420.18 KB
2.58 KB
6.05 KB

Only one of the fails from #4 is caused by this patch: since content translation metadata fields always have initial data now, TaxonomyTermViewTest needs to remove all the nodes before trying to uninstall the CT module.

Another fail is caused by me not using the latest version of the patch from the 'entity_test_update' issue, specifically the interdiff in #2856808-11: Break out the 'entity_test_update' entity type into its own module and add additional test db dumps.

And ContextualFilterTest was just a random fail.

--

#8.1: Fixed.
#8.2: We don't have any constants to use there.

jibran’s picture

Thank you for addressing the feedback.
#8.2: I think EntityPublishedInterface should add those constants instead of NodeInterface and should be used here. Toughts?

amateescu’s picture

@jibran, nope, we specifically designed EntityPublishedInterface to *not* have constants for published/not published. You can read the issue that introduced it for more details :)

amateescu’s picture

Title: [PP-3] Use initial values for content translation metadata fields and fix existing data » [PP-4] Use initial values for content translation metadata fields and fix existing data
FileSize
9.26 KB
81.93 KB

Status: Needs review » Needs work

The last submitted patch, 12: 2854732-12-combined.patch, failed testing.

amateescu’s picture

Status: Needs work » Needs review
FileSize
421.07 KB

I forgot to include #2856808: Break out the 'entity_test_update' entity type into its own module and add additional test db dumps in the combined patch. This is not even funny anymore :(

Status: Needs review » Needs work

The last submitted patch, 14: 2854732-14-combined.patch, failed testing.

jibran’s picture

Title: [PP-4] Use initial values for content translation metadata fields and fix existing data » [PP-3] Use initial values for content translation metadata fields and fix existing data
jibran’s picture

Title: [PP-3] Use initial values for content translation metadata fields and fix existing data » [PP-2] Use initial values for content translation metadata fields and fix existing data
amateescu’s picture

Title: [PP-2] Use initial values for content translation metadata fields and fix existing data » [PP-1] Use initial values for content translation metadata fields and fix existing data
Status: Needs work » Needs review
FileSize
9.26 KB
28.52 KB
amateescu’s picture

Title: [PP-1] Use initial values for content translation metadata fields and fix existing data » Use initial values for content translation metadata fields and fix existing data
FileSize
9.26 KB
timmillwood’s picture

Status: Needs review » Reviewed & tested by the community

Struggling to find any issues.

Wim Leers’s picture

Yeah, I don't know this code, but I have to say that this patch looks super solid :)

tstoeckler’s picture

Status: Reviewed & tested by the community » Needs work

Awesome, thanks! Needs work for 3. only.

  1. +++ b/core/modules/content_translation/content_translation.install
    @@ -44,3 +46,57 @@ function content_translation_update_8001() {
    +      $storage_definitions = $last_installed_schema_repository->getLastInstalledFieldStorageDefinitions($entity_type_id);
    ...
    +        if (isset($storage_definitions['content_translation_source'])) {
    ...
    +        if (isset($storage_definitions['content_translation_outdated'])) {
    ...
    +        if (isset($storage_definitions['content_translation_status'])) {
    

    Minor, but you could avoid having to fetch the schema repository manually by doing $entity_definition_update_manager->getFieldStorageDefinition(). I don't feel strongly about this, though, so feel free to leave as is.

  2. +++ b/core/modules/content_translation/src/ContentTranslationHandler.php
    @@ -117,14 +117,16 @@ public function getFieldDefinitions() {
           ->setDefaultValue(LanguageInterface::LANGCODE_NOT_SPECIFIED)
           ->setRevisionable(TRUE)
    -      ->setTranslatable(TRUE);
    +      ->setTranslatable(TRUE)
    +      ->setInitialValue(LanguageInterface::LANGCODE_NOT_SPECIFIED);
    

    Minor, but any reason not to put the initial value directly after the default value?

  3. +++ b/core/modules/content_translation/src/ContentTranslationHandler.php
    @@ -117,14 +117,16 @@ public function getFieldDefinitions() {
    +      ->setTranslatable(TRUE)
    +      ->setInitialValue(0);
    
    @@ -143,7 +145,8 @@ public function getFieldDefinitions() {
    +        ->setTranslatable(TRUE)
    +        ->setInitialValue(1);
    

    Let's use TRUE for the initial value, as well.

amateescu’s picture

Status: Needs work » Needs review
FileSize
9.07 KB
1.79 KB

Re #22:

1. $entity_definition_update_manager->getFieldStorageDefinition() clones the definition object and, tbh, I'd rather not have that overhead in a memory sensitive place like an update function..

2. and 3. Sure thing, fixed :)

tstoeckler’s picture

Status: Needs review » Reviewed & tested by the community

Perfect, thank you!

timmillwood’s picture

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 23: 2854732-23.patch, failed testing. View results

Wim Leers’s picture

That seems to not work:

General error: 1366 Incorrect integer value: '' for column 'content_translation_outdated'
amateescu’s picture

Status: Needs work » Needs review
FileSize
10.03 KB
986 bytes

That's easy to fix ;)

tstoeckler’s picture

+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
@@ -1712,7 +1712,7 @@ protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $st
       if ($initial_value && isset($initial_value[$field_column_name])) {
...
+        $schema['fields'][$schema_field_name]['initial'] = drupal_schema_get_field_value($column_schema, $initial_value[$field_column_name]);
       }
       elseif (!empty($initial_value_from_field)) {
         $schema['fields'][$schema_field_name]['initial_from_field'] = $initial_value_from_field[$field_column_name];

Nice fix. I thought whether the elseif-branch should get the same treatment, and I think it should. But I also found it strange that the conditions are set up differently - i.e. I would have expected the elseif to be $initial_valu_from_field && isset($initial_value_from_field[$field_column_name]). But that's a preexisting issue so shouldn't be tackled here, and, thus, maybe we should leave that entire branch alone. Not sure, so leaving at Needs review.

amateescu’s picture

@tstoeckler, the elseif branch doesn't need the same treatment because the value in $initial_value_from_field[$field_column_name] is provided by $table_mapping->getColumnNames() so it is always a string containing a table column name, not an arbitrary value provided in code like we have for $initial_value[$field_column_name].

As for why the if checks are different, that's because isset() doesn't throw any notices when looking for an non-existent array key, which can happen with $initial_value[$field_column_name], but for $initial_value_from_field[$field_column_name] we always know that the array key exists because the field types are the same so they have the exact same column names in their schema :)

timmillwood’s picture

Status: Needs review » Reviewed & tested by the community

It looks as though we're ready to go back to RTBC.

tstoeckler’s picture

Wow, thank you for #30!!! That makes a lot of sense, totally missed that the two are inherently different beasts. Awesome explanation. RTBC++

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 28: 2854732-28.patch, failed testing. View results

amateescu’s picture

Status: Needs work » Needs review
FileSize
10.07 KB

Rerolled for the conversion of TaxonomyTermViewTest to a functional test.

timmillwood’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC then!

  • catch committed 1023dda on 8.4.x
    Issue #2854732 by amateescu, jibran, tstoeckler: Use initial values for...
catch’s picture

Status: Reviewed & tested by the community » Fixed
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
@@ -1712,7 +1712,7 @@ protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $st
+        $schema['fields'][$schema_field_name]['initial'] = drupal_schema_get_field_value($column_schema, $initial_value[$field_column_name]);

Had to double check drupal_schema_get_field_value() wasn't deprecated, it isn't. Issue for that is #2124069: Convert schema.inc to the update.update_hook_registry service (UpdateHookRegistry).

Patch looks great, couldn't find anything to complain about. Committed/pushed to 8.4.x, thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.