Problem/Motivation

When attempting to translate a field configuration, there's a fatal error:

Drupal\Core\Entity\EntityStorageException: The "user_fields" entity type does not exist. in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 756 of core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).

I encountered the bug when attemting to translate a field config of a field on the user entity. The problem seems to be that ConfigSource::getMapper() is using $job_item->getItemType() for both, the creation of a configMapper and to determine the entity type of the config entity that gets translated.

Proposed resolution

Make sure the entity type is determined correctly.

Comments

s_leu created an issue. See original summary.

giancarlosotelo’s picture

Status: Active » Needs review
StatusFileSize
new2.88 KB
new6.4 KB

This is a first step, I am adding test to expose the problem and I am trying to not change too much the code in order to avoid mayor changes.

The problem basically is that the configMapper is trying to get a definition of a 'field_config' that doesn't exist so instead of using the type of the job item we should use the type of the $config_mapper, it is the same with other entities but for field_config changes to the good one.

For the UI in the translation of tmgmt, as suggested by @berdir, I am adding a new option 'Field' that has every 'field_config' of entities and then can be translated.

But now the problem is that the translation is not saved, the same as #2566353: Translation is not saved from Account settings so probably we have to fix that in the other issue.

The last submitted patch, 2: translation_field_config-2564721-ONLYTEST.patch, failed testing.

The last submitted patch, 2: translation_field_config-2564721-ONLYTEST.patch, failed testing.

s_leu’s picture

I tested the patch on an out dated d8 instance and the field translation worked now. However when i click the "Needs review" link on the translations overview i get the following error:

Fatal error: Call to undefined method Drupal\Component\Utility\Html::escape() in modules/submodules/tmgmt/src/Form/JobItemForm.php on line 97

Not sure whether this is due to my out dated d8 or due to the code of TMGMT.

Besides this, the patch looks fine to me.

giancarlosotelo’s picture

It is related to the core, that function was added recently here #2550945: Add Html::escape() and SafeMarkup::checkPlain was removed so we changed that in #2555045: SafeMarkup::checkPlain is being removed.

miro_dietiker’s picture

Status: Needs review » Needs work

Unsure how qualified my response is here. I'm just trying to understand what we do...

  1. +++ b/sources/tmgmt_config/src/ConfigSourcePluginUi.php
    @@ -139,7 +139,7 @@ class ConfigSourcePluginUi extends SourcePluginUiBase {
    +      'title' => $entity->getEntityTypeId() == 'field_config' ? $label : $entity->link($label),
    

    This check still seems a bit odd to me. And thus at least need a comment why field_config have no link... EntityInterface guarantees that we can call link() on all entities. So we should fix this bug elsewhere. Otherwise it's not an entity at all?

  2. +++ b/sources/tmgmt_config/src/ConfigSourcePluginUi.php
    @@ -308,6 +307,9 @@ class ConfigSourcePluginUi extends SourcePluginUiBase {
    +      if ($type == 'field_config') {
    +        $type = $entities[reset($entity_ids)]->get('entity_type') . '_fields';
    

    Needs a comment about the problem.

  3. +++ b/sources/tmgmt_config/src/Plugin/tmgmt/Source/ConfigSource.php
    @@ -287,9 +287,9 @@ class ConfigSource extends SourcePluginBase implements ContainerFactoryPluginInt
    -    foreach ($entity_types as $entity_type_name => $entity_type) {
    ...
    +    foreach ($definitions as $definition_name => $definition) {
    

    Why is this change needed? I would expect that enumerating the entity types is more what we want than enumerating the mappings... (duplicates?)

giancarlosotelo’s picture

Status: Needs work » Needs review
StatusFileSize
new912 bytes
new6.63 KB

1. As far as I understand the problem here is that the entity is 'FieldConfig' and it have a link but we want to list the fields of 'fieldable' entities so this ones don't have a link and there are not entities. Added a comment.

2. Commented.

3. It was suggested by @berdir, there are duplicates for field_config but it was the only way to have 'Field' listed on the UI. Another option could be added this manually (?).

juanse254’s picture

Status: Needs review » Reviewed & tested by the community

Tested locally, everything seems to work just fine.

berdir’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/sources/tmgmt_config/src/ConfigSourcePluginUi.php
    @@ -139,7 +139,9 @@ class ConfigSourcePluginUi extends SourcePluginUiBase {
           'id' => $entity->id(),
    -      'title' => $entity->link($label),
    +      // If the entity type is FieldConfig, we list the field of the fieldable
    +      // entity type which doesn't have a link.
    +      'title' => $entity->getEntityTypeId() == 'field_config' ? $label : $entity->link($label),
    

    There is a better way to check this, the existence of a edit-form link template.

  2. +++ b/sources/tmgmt_config/src/ConfigSourcePluginUi.php
    @@ -308,6 +309,11 @@ class ConfigSourcePluginUi extends SourcePluginUiBase {
    +      if ($type == 'field_config') {
    +        $type = $entities[reset($entity_ids)]->get('entity_type') . '_fields';
    +      }
    

    You have $entity available here, why so complicated?

  3. +++ b/sources/tmgmt_config/src/Tests/ConfigSourceListTest.php
    @@ -330,4 +330,17 @@ class ConfigSourceListTest extends EntityTestBase {
     
    +  function testFieldConfigList() {
    

    Missing docblock.

  4. +++ b/sources/tmgmt_config/src/Tests/ConfigSourceListTest.php
    @@ -330,4 +330,17 @@ class ConfigSourceListTest extends EntityTestBase {
    +    $this->assertText(t('One job needs to be checked out.'));
    +    $this->drupalPostForm(NULL, array(), t('Submit to translator'));
    +
    +    // Make sure that we're back on the originally defined destination URL.
    +    $this->assertUrl('admin/tmgmt/sources/config/field_config');
    +
    

    We're not really asserting much here. Shouldn't we check that the translation was saved correctly?

  5. +++ b/sources/tmgmt_config/src/Tests/ConfigSourceUiTest.php
    @@ -252,6 +252,28 @@ class ConfigSourceUiTest extends EntityTestBase {
    +
    +    // Verify that the pending translation is shown.
    +    $this->clickLink(t('Needs review'));
    +    $this->drupalPostForm(NULL, array(), t('Save as completed'));
    

    Same. You don't need to check if the field config was translated in both, one of them is enough.

    But this one should at least also have some assertText() for a configuration message. This could end in an exception and you wouldn't notice.

giancarlosotelo’s picture

Status: Needs work » Needs review
StatusFileSize
new3.39 KB
new8.13 KB

1. Done.
2. I realized that if we want to request more than 1 translation, each one have a different type so this could lead to an error with this approach (?).
I added a new key to the items array to save the type and then this is used to add the job. I don't know if is the best way because the type doesn't change with other entities.
3. Added.
4,5. Added text to assert in one of the test.

Status: Needs review » Needs work

The last submitted patch, 11: translation_field_config-2564721-11.patch, failed testing.

edurenye’s picture

Status: Needs work » Reviewed & tested by the community

It' seems to work correcly, the code it's fine. The test fail are unrelated to this issue.

berdir’s picture

Priority: Normal » Major
Status: Reviewed & tested by the community » Fixed

Committed.

Status: Fixed » Needs work

The last submitted patch, 11: translation_field_config-2564721-11.patch, failed testing.

berdir’s picture

Status: Needs work » Fixed

Status: Fixed » Closed (fixed)

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