diff --git a/src/ConfigRewriter.php b/src/ConfigRewriter.php index d34caee..bde7493 100644 --- a/src/ConfigRewriter.php +++ b/src/ConfigRewriter.php @@ -72,12 +72,12 @@ class ConfigRewriter implements ConfigRewriterInterface { // Config rewrites are stored in 'modulename/config/rewrite'. $dir_base = $extension->getPath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'rewrite'; - $languages = \Drupal::languageManager()->getLanguages(); // Rewrite configuration for the default language. $this->rewriteDirectoryConfig($extension, $dir_base); // Rewrite configuration for each enabled language. + $languages = \Drupal::languageManager()->getLanguages(); foreach ($languages as $langcode => $language) { $rewrite_dir = $dir_base . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR . $langcode; $this->rewriteDirectoryConfig($extension, $rewrite_dir, $langcode); @@ -102,43 +102,78 @@ class ConfigRewriter implements ConfigRewriterInterface { if (file_exists($rewrite_dir) && $files = $this->fileScanDirectory($rewrite_dir, '/^.*\.yml$/i', ['recurse' => FALSE])) { foreach ($files as $file) { // Parse the rewrites and retrieve the original config. - $rewrite = Yaml::parse(file_get_contents($rewrite_dir . DIRECTORY_SEPARATOR . $file->name . '.yml')); + $rewrite_data = Yaml::parse(file_get_contents($rewrite_dir . DIRECTORY_SEPARATOR . $file->name . '.yml')); if ($langcode) { /** @var \Drupal\language\Config\LanguageConfigOverride $original_config */ $config = $this->languageConfigFactoryOverride->getOverride($langcode, $file->name); $original_data = $config->get(); - $rewrite = $this->rewriteConfig($original_data, $rewrite); } else { $config = $this->configFactory->getEditable($file->name); $original_data = $config->getRawData(); - $rewrite = $this->rewriteConfig($original_data, $rewrite); } - // Unset 'config_rewrite' key before saving rewritten values. - if (isset($rewrite['config_rewrite'])) { - unset($rewrite['config_rewrite']); + // Check for an empty original data accompanied by a langcode. + // In this case, we assume we're writing a new language config override. + $lang_config_override = (empty($original_data) && $langcode ? true : false); + + // Check for non-empty original data that isn't identical to rewrite data. + $config_rewrite = (!empty($original_data) && ($rewrite_data != $original_data) ? true : false); + + // Log when original data is the same as the rewrite data. + if ($rewrite_data == $original_data) { + $this->logger->notice('@config has no changes to rewrite.', ['@config' => $file->name]); } - // Retain the original 'uuid' and '_core' keys if it's not explicitly - // asked to rewrite them. - if (isset($rewrite['config_rewrite_uuids'])) { - unset($rewrite['config_rewrite_uuids']); + // Log when the original data is non existent and can't be rewritten. + if (empty($original_data) && !$langcode) { + $this->logger->notice('@config does not exist to rewrite.', ['@config' => $file->name]); } - else { - foreach (['_core', 'uuid'] as $key) { - if (isset($original_data[$key])) { - $rewrite[$key] = $original_data[$key]; - } - } + + // Only make changes in the case of a proper config rewrite or a language config override. + if ($config_rewrite || $lang_config_override) { + $rewrite = $this->rewriteConfig($original_data, $rewrite_data); } - // Save the rewritten configuration data. - $result = $config->setData($rewrite)->save() ? 'rewritten' : 'not rewritten'; + // Save the rewritten configuration data (or don't). + if (isset($rewrite)) { + // Unset 'config_rewrite' key before saving rewritten values. + if (isset($rewrite['config_rewrite'])) { + unset($rewrite['config_rewrite']); + } + + // Retain the original 'uuid' and '_core' keys if it's not explicitly + // asked to rewrite them. + if (isset($rewrite['config_rewrite_uuids'])) { + unset($rewrite['config_rewrite_uuids']); + } + else { + foreach (['_core', 'uuid'] as $key) { + if (isset($original_data[$key])) { + $rewrite[$key] = $original_data[$key]; + } + } + } - // Log a message indicating whether the config was rewritten or not. - $log = $langcode ? '@config (@langcode) @result by @module' : '@config @result by @module'; - $this->logger->notice($log, ['@config' => $file->name, '@result' => $result, '@module' => $extension->getName()]); + // Attempt to save the configuration rewrite. + $result = $config->setData($rewrite)->save() ? 'rewritten' : 'not rewritten'; + + // Log a message indicating whether the config rewrite was saved or not. + $log = $langcode ? '@config (@langcode) @result by @module' : '@config @result by @module'; + $this->logger->notice($log, [ + '@config' => $file->name, + '@result' => $result, + '@module' => $extension->getName() + ]); + + // Do not retain previous rewrite info for next iteration of the loop. + unset($rewrite); + unset($config_rewrite); + unset($lang_config_override); + } + else { + $this->logger->notice('@config was not rewritten', ['@config' => $file->name]); + } } } } diff --git a/tests/modules/config_rewrite_test_rewrite/config/rewrite/user.role.test5.yml b/tests/modules/config_rewrite_test_rewrite/config/rewrite/user.role.test5.yml new file mode 100644 index 0000000..c96c41f --- /dev/null +++ b/tests/modules/config_rewrite_test_rewrite/config/rewrite/user.role.test5.yml @@ -0,0 +1,9 @@ +langcode: en +status: true +dependencies: { } +id: test5 +label: "Test 5 'replaces' nothing and should not import!" +weight: 0 +is_admin: false +permissions: + - 'change own username' diff --git a/tests/src/Kernel/ConfigRewriteTest.php b/tests/src/Kernel/ConfigRewriteTest.php index 7144f8f..77dd9f2 100644 --- a/tests/src/Kernel/ConfigRewriteTest.php +++ b/tests/src/Kernel/ConfigRewriteTest.php @@ -133,6 +133,9 @@ class ConfigRewriteTest extends KernelTestBase { ]; $user_role = $this->languageConfigFactoryOverride->getOverride('fr', 'user.role.test4')->get(); $this->assertEquals($user_role['label'], $expected_rewritten_data['label']); - } + // Test for non-existing config being accidentally written by a "rewrite." + $this->assertFalse($this->activeConfigStorage->read('user.role.test5')); + + } }