From 1ba97fcf577de9508e3ff2081e43c16032bc1fd3 Mon Sep 17 00:00:00 2001 From: Nathaniel Catchpole Date: Tue, 23 Aug 2016 08:43:52 +0100 Subject: [PATCH] Issue #2776357 by alexpott: Upgrade path for Config translation synchronization failure --- .../Update/ConfigOverridesUpdateTest.php | 56 +++++++++++++++++++ core/modules/system/system.install | 23 ++++++++ .../update/drupal-8.config-override-fix.php | 37 ++++++++++++ .../tests/fixtures/update/es-system.cron.yml | 1 + .../fixtures/update/es-views.view.content.yml | 15 +++++ 5 files changed, 132 insertions(+) create mode 100644 core/modules/system/src/Tests/Update/ConfigOverridesUpdateTest.php create mode 100644 core/modules/system/tests/fixtures/update/drupal-8.config-override-fix.php create mode 100644 core/modules/system/tests/fixtures/update/es-system.cron.yml create mode 100644 core/modules/system/tests/fixtures/update/es-views.view.content.yml diff --git a/core/modules/system/src/Tests/Update/ConfigOverridesUpdateTest.php b/core/modules/system/src/Tests/Update/ConfigOverridesUpdateTest.php new file mode 100644 index 00000000000..6efa3182d62 --- /dev/null +++ b/core/modules/system/src/Tests/Update/ConfigOverridesUpdateTest.php @@ -0,0 +1,56 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../tests/fixtures/update/drupal-8.filled.standard.php.gz', + __DIR__ . '/../../../tests/fixtures/update/drupal-8.config-override-fix.php', + ]; + } + + /** + * Tests that configuration has been updated. + */ + public function testUpdatedSite() { + $key_to_be_removed = 'display.default.display_options.fields.nid'; + /** @var \Drupal\Core\Config\Config $config_override */ + $language_config_override = \Drupal::service('language.config_factory_override'); + $config_override = $language_config_override->getOverride('es', 'views.view.content'); + $this->assertEqual('Spanish ID', $config_override->get($key_to_be_removed)['label'], 'The spanish override for the missing field exists before updating.'); + // Since the above view will be fixed by other updates that fix views + // configuration for example, + // views_post_update_update_cacheability_metadata(), also test configuration + // that has yet to be modified in an update path. + $config_override = $language_config_override->getOverride('es', 'system.cron'); + $this->assertEqual('Should be cleaned by system_update_8200', $config_override->get('bogus_key'), 'The spanish override in system.cron exists before updating.'); + + $this->runUpdates(); + + /** @var \Drupal\Core\Config\Config $config_override */ + $config_override = \Drupal::service('language.config_factory_override')->getOverride('es', 'views.view.content'); + $this->assertNull($config_override->get($key_to_be_removed), 'The spanish override for the missing field has been removed.'); + $config_override = $language_config_override->getOverride('es', 'system.cron'); + $this->assertTrue($config_override->isNew(), 'After updating the system.cron spanish override does not exist.'); + $this->assertTrue(empty($config_override->get()), 'After updating the system.cron spanish override has no data.'); + + // Test that the spanish overrides still work. + $this->drupalLogin($this->createUser(['access content overview'])); + $this->drupalGet('admin/content', ['language' => \Drupal::languageManager()->getLanguage('es')]); + $this->assertText('Spanish Title'); + $this->assertText('Spanish Author'); + } + +} diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 7f8bc24919b..178110517be 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -1657,3 +1657,26 @@ function system_update_8014() { /** * @} End of "addtogroup updates-8.0.0-rc". */ + +/** + * Fix configuration overrides to not override non existing keys. + */ +function system_update_8200(&$sandbox) { + $config_factory = \Drupal::configFactory(); + if (!array_key_exists('config_names', $sandbox)) { + $sandbox['config_names'] = $config_factory->listAll(); + $sandbox['max'] = count($sandbox['config_names']); + } + + // Get a list of 50 to work on at a time. + $config_names_to_process = array_slice($sandbox['config_names'], 0, 50); + // Preload in a single query. + $config_factory->loadMultiple($config_names_to_process); + foreach ($config_names_to_process as $config_name) { + $config_factory->getEditable($config_name)->save(); + } + + // Update the list of names to process. + $sandbox['config_names'] = array_diff($sandbox['config_names'], $config_names_to_process); + $sandbox['#finished'] = empty($sandbox['config_names']) ? 1 : ($sandbox['max'] - count($sandbox['config_names'])) / $sandbox['max']; +} diff --git a/core/modules/system/tests/fixtures/update/drupal-8.config-override-fix.php b/core/modules/system/tests/fixtures/update/drupal-8.config-override-fix.php new file mode 100644 index 00000000000..f631bf9b92b --- /dev/null +++ b/core/modules/system/tests/fixtures/update/drupal-8.config-override-fix.php @@ -0,0 +1,37 @@ +delete('config') + ->condition('name', $config_name) + ->condition('collection', 'language.es') + ->execute(); + $connection->insert('config') + ->fields(['data', 'name', 'collection']) + ->values([ + 'name' => $config_name, + 'data' => serialize($config), + 'collection' => 'language.es', + ]) + ->execute(); +} diff --git a/core/modules/system/tests/fixtures/update/es-system.cron.yml b/core/modules/system/tests/fixtures/update/es-system.cron.yml new file mode 100644 index 00000000000..09d0f82f375 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/es-system.cron.yml @@ -0,0 +1 @@ +bogus_key: 'Should be cleaned by system_update_8200' diff --git a/core/modules/system/tests/fixtures/update/es-views.view.content.yml b/core/modules/system/tests/fixtures/update/es-views.view.content.yml new file mode 100644 index 00000000000..d9c9cce2d54 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/es-views.view.content.yml @@ -0,0 +1,15 @@ +label: 'Spanish Content' +description: 'Spanish Find and manage content.' +display: + default: + display_options: + fields: + title: + label: 'Spanish Title' + name: + label: 'Spanish Author' + nid: + label: 'Spanish ID' + display_title: 'Spanish Master' + page_1: + display_title: 'Spanish Page'