diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php index ffdc760..74326c0 100644 --- a/core/lib/Drupal/Core/Config/ConfigInstaller.php +++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php @@ -260,9 +260,16 @@ protected function createConfiguration($collection, array $config_to_create) { } else { $new_config = new Config($name, $this->getActiveStorages($collection), $this->eventDispatcher, $this->typedConfig); + // Create a copy of the original configuration for later reference. + if ($collection == StorageInterface::DEFAULT_COLLECTION) { + $config_copy = new Config($name, $this->getActiveStorages(StorageInterface::ORIGINAL_COPY_COLLECTION), $this->eventDispatcher, $this->typedConfig); + } } if ($config_to_create[$name] !== FALSE) { $new_config->setData($config_to_create[$name]); + if (isset($config_copy)) { + $config_copy->setData($config_to_create[$name])->save(); + } } if ($config_entity_support && $entity_type = $this->configManager->getEntityTypeIdByName($name)) { // If we are syncing do not create configuration entities. Pluggable diff --git a/core/lib/Drupal/Core/Config/FileStorage.php b/core/lib/Drupal/Core/Config/FileStorage.php index f404480..1816ec9 100644 --- a/core/lib/Drupal/Core/Config/FileStorage.php +++ b/core/lib/Drupal/Core/Config/FileStorage.php @@ -231,7 +231,7 @@ public function deleteAll($prefix = '') { } if ($success && $this->collection != StorageInterface::DEFAULT_COLLECTION) { // Remove empty directories. - if (!(new \FilesystemIterator($this->getCollectionDirectory()))->valid()) { + if (file_exists($this->getCollectionDirectory()) && !(new \FilesystemIterator($this->getCollectionDirectory()))->valid()) { drupal_rmdir($this->getCollectionDirectory()); } } diff --git a/core/lib/Drupal/Core/Config/StorageInterface.php b/core/lib/Drupal/Core/Config/StorageInterface.php index f6145b8..b9ec918 100644 --- a/core/lib/Drupal/Core/Config/StorageInterface.php +++ b/core/lib/Drupal/Core/Config/StorageInterface.php @@ -21,6 +21,11 @@ const DEFAULT_COLLECTION = ''; /** + * Collection for storing copies of original configuration. + */ + const ORIGINAL_COPY_COLLECTION = 'originalcopy'; + + /** * Returns whether a configuration object exists. * * @param string $name diff --git a/core/modules/config/src/Tests/ConfigExportUITest.php b/core/modules/config/src/Tests/ConfigExportUITest.php index 1a679de..b015617 100644 --- a/core/modules/config/src/Tests/ConfigExportUITest.php +++ b/core/modules/config/src/Tests/ConfigExportUITest.php @@ -9,6 +9,7 @@ use Drupal\Component\Serialization\Yaml; use Drupal\Core\Archiver\Tar; +use Drupal\Core\Config\StorageInterface; use Drupal\simpletest\WebTestBase; /** @@ -65,6 +66,11 @@ function testExport() { foreach ($storage_active->listAll() as $config_name) { $config_files[] = $config_name . '.yml'; } + // Add configuration copies to the list of expected files. + $copy_collection = $storage_active->createCollection(StorageInterface::ORIGINAL_COPY_COLLECTION); + foreach ($copy_collection->listAll() as $config_name) { + $config_files[] = 'originalcopy/' . $config_name . '.yml'; + } // Assert that the downloaded archive file contents are the same as the test // site active store. $this->assertIdentical($archive_contents, $config_files); diff --git a/core/modules/config/src/Tests/ConfigInstallTest.php b/core/modules/config/src/Tests/ConfigInstallTest.php index 9a903a1..1bea593 100644 --- a/core/modules/config/src/Tests/ConfigInstallTest.php +++ b/core/modules/config/src/Tests/ConfigInstallTest.php @@ -177,6 +177,7 @@ public function testCollectionInstallationCollections() { public function testCollectionInstallationCollectionConfigEntity() { $collections = array( 'entity', + StorageInterface::ORIGINAL_COPY_COLLECTION, ); \Drupal::state()->set('config_collection_install_test.collection_names', $collections); // Install the test module. diff --git a/core/modules/config/tests/config_import_test/src/EventSubscriber.php b/core/modules/config/tests/config_import_test/src/EventSubscriber.php index 0be4f97..3549ed3 100644 --- a/core/modules/config/tests/config_import_test/src/EventSubscriber.php +++ b/core/modules/config/tests/config_import_test/src/EventSubscriber.php @@ -10,6 +10,7 @@ use Drupal\Core\Config\ConfigCrudEvent; use Drupal\Core\Config\ConfigEvents; use Drupal\Core\Config\ConfigImporterEvent; +use Drupal\Core\Config\StorageInterface; use Drupal\Core\State\StateInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -58,7 +59,7 @@ public function onConfigImporterValidate(ConfigImporterEvent $event) { */ public function onConfigSave(ConfigCrudEvent $event) { $config = $event->getConfig(); - if ($config->getName() == 'action.settings') { + if ($config->getStorage()->getCollectionName() == StorageInterface::DEFAULT_COLLECTION && $config->getName() == 'action.settings') { $values = $this->state->get('ConfigImportUITest.action.settings.recursion_limit', array()); $values[] = $config->get('recursion_limit'); $this->state->set('ConfigImportUITest.action.settings.recursion_limit', $values); @@ -90,7 +91,7 @@ public function onConfigSave(ConfigCrudEvent $event) { */ public function onConfigDelete(ConfigCrudEvent $event) { $config = $event->getConfig(); - if ($config->getName() == 'action.settings') { + if ($config->getStorage()->getCollectionName() == StorageInterface::DEFAULT_COLLECTION && $config->getName() == 'action.settings') { $value = $this->state->get('ConfigImportUITest.action.settings.delete', 0); $this->state->set('ConfigImportUITest.action.settings.delete', $value + 1); } diff --git a/core/modules/simpletest/src/TestBase.php b/core/modules/simpletest/src/TestBase.php index b621140..4bfa323 100644 --- a/core/modules/simpletest/src/TestBase.php +++ b/core/modules/simpletest/src/TestBase.php @@ -1633,9 +1633,15 @@ public function configImporter() { * The target config storage service. */ public function copyConfig(StorageInterface $source_storage, StorageInterface $target_storage) { - $target_storage->deleteAll(); - foreach ($source_storage->listAll() as $name) { - $target_storage->write($name, $source_storage->read($name)); + $collections = $source_storage->getAllCollectionNames(); + $collections[] = StorageInterface::DEFAULT_COLLECTION; + foreach ($collections as $collection) { + $source_collection = $source_storage->createCollection($collection); + $target_collection = $target_storage->createCollection($collection); + $target_collection->deleteAll(); + foreach ($source_collection->listAll() as $name) { + $target_collection->write($name, $source_collection->read($name)); + } } }