diff --git a/core/includes/config.inc b/core/includes/config.inc index 347bf85..90c542d 100644 --- a/core/includes/config.inc +++ b/core/includes/config.inc @@ -117,6 +117,7 @@ function config_sync_get_changes(StorageInterface $source_storage, StorageInterf function config_sync_changes(array $config_changes, StorageInterface $source_storage, StorageInterface $target_storage) { foreach (array('delete', 'create', 'change') as $op) { foreach ($config_changes[$op] as $name) { + Config::checkNamespace($name); if ($op == 'delete') { $target_storage->delete($name); } @@ -188,6 +189,7 @@ function config_import_invoke_owner(array $config_changes, StorageInterface $sou // handle dependencies correctly. foreach (array('delete', 'create', 'change') as $op) { foreach ($config_changes[$op] as $key => $name) { + Config::checkNamespace($name); // Extract owner from configuration object name. $module = strtok($name, '.'); // Check whether the module implements hook_config_import() and ask it to diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php index 10bf925..82582e9 100644 --- a/core/lib/Drupal/Core/Config/Config.php +++ b/core/lib/Drupal/Core/Config/Config.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Config; +use Drupal\Core\Config\ConfigException; use Drupal\Component\Utility\NestedArray; /** @@ -290,6 +291,9 @@ class Config { * Saves the configuration object. */ public function save() { + // All configuration objects need to be namespaced by extension, as it would + // be impossible to maintain them otherwise. + $this->checkNamespace($this->name); $this->sortByKey($this->data); $this->storage->write($this->name, $this->data); $this->isNew = FALSE; @@ -326,4 +330,14 @@ class Config { $this->resetOverriddenData(); return $this; } + /** + * Checks if a configuration object is namespaced by extension. + * + * @throws Drupal\Core\Config\ConfigException + */ + public static function checkNamespace($name) { + if (strpos($name, '.') === FALSE) { + throw new ConfigException(format_string('Missing namespace in Config name @name', array('@name' => $name))); + } + } } diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php index 37aa854..42e7513 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php @@ -8,6 +8,7 @@ namespace Drupal\config\Tests; use Drupal\Core\Config\DatabaseStorage; +use Drupal\Core\Config\ConfigException; use Drupal\simpletest\WebTestBase; /** @@ -112,4 +113,29 @@ class ConfigCRUDTest extends WebTestBase { // their order must be identical. $this->assertIdentical($new_config->get(), $config->get()); } + + /** + * Tests saving a config object without a namespace. + */ + function testNamespace() { + $name = 'nonamespace'; + try { + $config = config($name); + $config->save(); + $this->fail('Expected ConfigException was not thrown.'); + } + catch (ConfigException $e) { + $this->pass('Expected ConfigException was thrown.'); + } + + $name = 'config.namespace'; + try { + $config = config($name); + $config->save(); + $this->pass('ConfigException was not thrown.'); + } + catch (ConfigException $e) { + $this->fail('ConfigException was thrown.'); + } + } }