Commit c4501b3a authored by effulgentsia's avatar effulgentsia
Browse files

Issue #2597628 by plach, jhedstrom, alexpott, Gábor Hojtsy: Enabling...

Issue #2597628 by plach, jhedstrom, alexpott, Gábor Hojtsy: Enabling translation for menu links / taxonomy terms results in "Entity/field definitions" -- "Mismatch detected" on reports/status page
parent f0bd339e
......@@ -591,22 +591,36 @@ protected function getEntitySchemaTables() {
* storage definitions.
*/
protected function getEntitySchemaData(ContentEntityTypeInterface $entity_type, array $schema) {
$schema_data = array();
$entity_type_id = $entity_type->id();
$keys = array('indexes', 'unique keys');
$unused_keys = array_flip(array('description', 'fields', 'foreign keys'));
// Collect all possible field schema identifiers for shared table fields.
// These will be used to detect entity schema data in the subsequent loop.
$field_schema_identifiers = [];
$storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
$table_mapping = $this->storage->getTableMapping($storage_definitions);
foreach ($storage_definitions as $field_name => $storage_definition) {
if ($table_mapping->allowsSharedTableStorage($storage_definition)) {
// Make sure both base identifier names and suffixed names are listed.
$name = $this->getFieldSchemaIdentifierName($entity_type_id, $field_name);
$field_schema_identifiers[$name] = $name;
foreach ($storage_definition->getColumns() as $key => $columns) {
$name = $this->getFieldSchemaIdentifierName($entity_type_id, $field_name, $key);
$field_schema_identifiers[$name] = $name;
}
}
}
// Extract entity schema data from the Schema API definition.
$schema_data = [];
$keys = ['indexes', 'unique keys'];
$unused_keys = array_flip(['description', 'fields', 'foreign keys']);
foreach ($schema as $table_name => $table_schema) {
$table_schema = array_diff_key($table_schema, $unused_keys);
foreach ($keys as $key) {
// Exclude data generated from field storage definitions, we will check
// that separately.
if (!empty($table_schema[$key])) {
$data_keys = array_keys($table_schema[$key]);
$entity_keys = array_filter($data_keys, function ($key) use ($entity_type_id) {
return strpos($key, $entity_type_id . '_field__') !== 0;
});
$table_schema[$key] = array_intersect_key($table_schema[$key], array_flip($entity_keys));
if ($field_schema_identifiers && !empty($table_schema[$key])) {
$table_schema[$key] = array_diff_key($table_schema[$key], $field_schema_identifiers);
}
}
$schema_data[$table_name] = array_filter($table_schema);
......
<?php
/**
* @file
* Contains \Drupal\content_translation\Tests\ContentTranslationEnableTest.
*/
namespace Drupal\content_translation\Tests;
use Drupal\simpletest\WebTestBase;
/**
* Test enabling content translation after other modules.
*
* @group content_translation
*/
class ContentTranslationEnableTest extends WebTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['entity_test', 'menu_link_content'];
/**
* Tests that entity schemas are up-to-date after enabling translation.
*/
public function testEnable() {
$this->drupalLogin($this->rootUser);
// Enable modules and make sure the related config entity type definitions
// are installed.
$edit = [
'modules[Multilingual][content_translation][enable]' => TRUE,
'modules[Multilingual][language][enable]' => TRUE,
];
$this->drupalPostForm('admin/modules', $edit, t('Install'));
// No pending updates should be available.
$this->drupalGet('admin/reports/status');
$requirement_value = $this->cssSelect("tr.system-status-report__entry th:contains('Entity/field definitions') + td");
$this->assertEqual(t('Up to date'), trim((string) $requirement_value[0]));
// Enable content translation on entity types that have will have a
// content_translation_uid.
$edit = [
'entity_types[menu_link_content]' => TRUE,
'settings[menu_link_content][menu_link_content][translatable]' => TRUE,
'entity_types[entity_test_mul]' => TRUE,
'settings[entity_test_mul][entity_test_mul][translatable]' => TRUE,
];
$this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
// No pending updates should be available.
$this->drupalGet('admin/reports/status');
$requirement_value = $this->cssSelect("tr.system-status-report__entry th:contains('Entity/field definitions') + td");
$this->assertEqual(t('Up to date'), trim((string) $requirement_value[0]));
}
}
......@@ -104,6 +104,20 @@ protected function addBaseField($type = 'string') {
$this->state->set('entity_test_update.additional_base_field_definitions', $definitions);
}
/**
* Adds a long-named base field to the 'entity_test_update' entity type.
*/
protected function addLongNameBaseField() {
$key = 'entity_test_update.additional_base_field_definitions';
$definitions = $this->state->get($key, []);
$definitions['new_long_named_entity_reference_base_field'] = BaseFieldDefinition::create('entity_reference')
->setName('new_long_named_entity_reference_base_field')
->setLabel(t('A new long-named base field'))
->setSetting('target_type', 'user')
->setSetting('handler', 'default');
$this->state->set($key, $definitions);
}
/**
* Adds a new revisionable base field to the 'entity_test_update' entity type.
*
......
......@@ -18,6 +18,7 @@
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionEvents;
use Drupal\Core\Language\LanguageInterface;
use Drupal\entity_test\Entity\EntityTestUpdate;
/**
* Tests EntityDefinitionUpdateManager functionality.
......@@ -796,4 +797,17 @@ public function testBaseFieldEntityKeyUpdateWithExistingData() {
}
}
/**
* Check that field schema is correctly handled with long-named fields.
*/
function testLongNameFieldIndexes() {
$this->addLongNameBaseField();
$entity_type_id = 'entity_test_update';
$entity_type = $this->entityManager->getDefinition($entity_type_id);
$definitions = EntityTestUpdate::baseFieldDefinitions($entity_type);
$name = 'new_long_named_entity_reference_base_field';
$this->entityDefinitionUpdateManager->installFieldStorageDefinition($name, $entity_type_id, 'entity_test', $definitions[$name]);
$this->assertFalse($this->entityDefinitionUpdateManager->needsUpdates(), 'Entity and field schema data are correctly detected.');
}
}
......@@ -144,14 +144,14 @@ function testStatusReport() {
// Check that the status report initially displays no error.
$this->drupalGet('admin/reports/status');
$this->assertNoRaw('Out of date');
$this->assertNoRaw('Mismatch detected');
$this->assertNoRaw('Mismatched entity and/or field definitions');
// Enable an entity update and check that we have a dedicated status report
// item.
$this->container->get('state')->set('entity_test.remove_name_field', TRUE);
$this->drupalGet('admin/reports/status');
$this->assertNoRaw('Out of date');
$this->assertRaw('Mismatch detected');
$this->assertRaw('Mismatched entity and/or field definitions');
// Enable a db update and check that now the entity update status report
// item is no longer displayed. We assume an update function will fix the
......@@ -159,13 +159,13 @@ function testStatusReport() {
$this->enableUpdates('entity_test', 'status_report', 8001);
$this->drupalGet('admin/reports/status');
$this->assertRaw('Out of date');
$this->assertNoRaw('Mismatch detected');
$this->assertRaw('Mismatched entity and/or field definitions');
// Apply db updates and check that entity updates were not applied.
$this->applyUpdates();
$this->drupalGet('admin/reports/status');
$this->assertNoRaw('Out of date');
$this->assertRaw('Mismatch detected');
$this->assertRaw('Mismatched entity and/or field definitions');
// Check that en exception would be triggered when trying to apply them with
// existing data.
......@@ -181,7 +181,7 @@ function testStatusReport() {
// Check the status report is the same after trying to apply updates.
$this->drupalGet('admin/reports/status');
$this->assertNoRaw('Out of date');
$this->assertRaw('Mismatch detected');
$this->assertRaw('Mismatched entity and/or field definitions');
// Delete entity data, enable a new update, run updates again and check that
// entity updates were not applied even when no data exists.
......@@ -190,7 +190,7 @@ function testStatusReport() {
$this->applyUpdates();
$this->drupalGet('admin/reports/status');
$this->assertNoRaw('Out of date');
$this->assertRaw('Mismatch detected');
$this->assertRaw('Mismatched entity and/or field definitions');
}
/**
......
......@@ -641,15 +641,15 @@ function system_requirements($phase) {
$requirements['update']['description'] = t('Some modules have database schema updates to install. You should run the <a href=":update">database update script</a> immediately.', array(':update' => \Drupal::url('system.db_update')));
}
// Verify that no entity updates are pending after running every DB update.
if (!isset($requirements['update']['severity']) && \Drupal::entityDefinitionUpdateManager()->needsUpdates()) {
$requirements['entity_update'] = array(
'title' => t('Entity/field definitions'),
'value' => t('Mismatch detected'),
'severity' => REQUIREMENT_ERROR,
// @todo Provide details: https://www.drupal.org/node/2554911
'description' => t('Mismatched entity and/or field definitions.'),
);
$requirements['entity_update'] = [
'title' => t('Entity/field definitions'),
'value' => t('Up to date'),
];
// Verify that no entity updates are pending.
if (\Drupal::entityDefinitionUpdateManager()->needsUpdates()) {
$requirements['entity_update']['severity'] = REQUIREMENT_ERROR;
// @todo Provide details: https://www.drupal.org/node/2554911
$requirements['entity_update']['value'] = t('Mismatched entity and/or field definitions');
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment