diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php index 51ade6c..543417e 100644 --- a/core/lib/Drupal/Core/Config/Config.php +++ b/core/lib/Drupal/Core/Config/Config.php @@ -68,7 +68,9 @@ class Config extends StorableConfigBase { * The typed configuration manager service. */ public function __construct($name, StorageInterface $storage, EventDispatcherInterface $event_dispatcher, TypedConfigManagerInterface $typed_config) { - $this->name = $name; + // Calling parent constructor is needed for properly validate the + // configuration object name. + parent::__construct($name); $this->storage = $storage; $this->eventDispatcher = $event_dispatcher; $this->typedConfigManager = $typed_config; @@ -204,9 +206,6 @@ public function clear($key) { * {@inheritdoc} */ public function save() { - // Validate the configuration object name before saving. - static::validateName($this->name); - // If there is a schema for this configuration object, cast all values to // conform to the schema. if ($this->typedConfigManager->hasConfigSchema($this->name)) { diff --git a/core/lib/Drupal/Core/Config/ConfigBase.php b/core/lib/Drupal/Core/Config/ConfigBase.php index eee76a2..bc370a2 100644 --- a/core/lib/Drupal/Core/Config/ConfigBase.php +++ b/core/lib/Drupal/Core/Config/ConfigBase.php @@ -61,6 +61,18 @@ const MAX_NAME_LENGTH = 250; /** + * Constructs a configuration object. + * + * @param string $name + * The name of the configuration object being constructed. + */ + public function __construct($name) { + // Validate the configuration object name. + static::validateName($name); + $this->name = $name; + } + + /** * Returns the name of this configuration object. * * @return string @@ -80,6 +92,8 @@ public function getName() { * The configuration object. */ public function setName($name) { + // Validate the configuration object. + static::validateName($name); $this->name = $name; return $this; } @@ -87,6 +101,11 @@ public function setName($name) { /** * Validates the configuration object name. * + * A valid name must: + * - Be namespaced by its owner (i.e. contain at least one '.'). + * - Be shorter than Config::MAX_NAME_LENGTH characters. + * - Not contain any of the following characters: ? : * < > " ' / \ + * * @param string $name * The name of the configuration object. * @@ -95,7 +114,7 @@ public function setName($name) { * @see Config::MAX_NAME_LENGTH */ public static function validateName($name) { - // The name must be namespaced by owner. + // The name must be namespaced by its owner. if (strpos($name, '.') === FALSE) { throw new ConfigNameException(SafeMarkup::format('Missing namespace in Config object name @name.', array( '@name' => $name, diff --git a/core/modules/language/src/Config/LanguageConfigOverride.php b/core/modules/language/src/Config/LanguageConfigOverride.php index 5be48ad..8a88562 100644 --- a/core/modules/language/src/Config/LanguageConfigOverride.php +++ b/core/modules/language/src/Config/LanguageConfigOverride.php @@ -41,7 +41,9 @@ class LanguageConfigOverride extends StorableConfigBase { * The event dispatcher. */ public function __construct($name, StorageInterface $storage, TypedConfigManagerInterface $typed_config, EventDispatcherInterface $event_dispatcher) { - $this->name = $name; + // Calling parent constructor is needed for properly validate the + // configuration object name. + parent::__construct($name); $this->storage = $storage; $this->typedConfigManager = $typed_config; $this->eventDispatcher = $event_dispatcher; diff --git a/core/tests/Drupal/Tests/Core/Access/AccessResultTest.php b/core/tests/Drupal/Tests/Core/Access/AccessResultTest.php index 123888a..fb5fee4 100644 --- a/core/tests/Drupal/Tests/Core/Access/AccessResultTest.php +++ b/core/tests/Drupal/Tests/Core/Access/AccessResultTest.php @@ -433,7 +433,9 @@ public function testCacheTags() { $this->assertEquals($a, $b); // ::cacheUntilConfigurationChanges() convenience method. - $configuration = $this->getMock('\Drupal\Core\Config\ConfigBase'); + $configuration = $this->getMockBuilder('\Drupal\Core\Config\ConfigBase') + ->disableOriginalConstructor() + ->getMock(); $configuration->expects($this->any()) ->method('getCacheTags') ->will($this->returnValue(array('config:foo.bar.baz'))); diff --git a/core/tests/Drupal/Tests/Core/Config/ImmutableConfigTest.php b/core/tests/Drupal/Tests/Core/Config/ImmutableConfigTest.php index 8b0bbf8..f7c83de 100644 --- a/core/tests/Drupal/Tests/Core/Config/ImmutableConfigTest.php +++ b/core/tests/Drupal/Tests/Core/Config/ImmutableConfigTest.php @@ -28,13 +28,13 @@ protected function setUp() { $storage = $this->getMock('Drupal\Core\Config\StorageInterface'); $event_dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); $typed_config = $this->getMock('Drupal\Core\Config\TypedConfigManagerInterface'); - $this->config = new ImmutableConfig('test', $storage, $event_dispatcher, $typed_config); + $this->config = new ImmutableConfig('test.immutable_config', $storage, $event_dispatcher, $typed_config); } /** * @covers ::set * @expectedException \Drupal\Core\Config\ImmutableConfigException - * @expectedExceptionMessage Can not set values on immutable configuration test:name. Use \Drupal\Core\Config\ConfigFactoryInterface::getEditable() to retrieve a mutable configuration object + * @expectedExceptionMessage Can not set values on immutable configuration test.immutable_config:name. Use \Drupal\Core\Config\ConfigFactoryInterface::getEditable() to retrieve a mutable configuration object */ public function testSet() { $this->config->set('name', 'value'); @@ -43,7 +43,7 @@ public function testSet() { /** * @covers ::clear * @expectedException \Drupal\Core\Config\ImmutableConfigException - * @expectedExceptionMessage Can not clear name key in immutable configuration test. Use \Drupal\Core\Config\ConfigFactoryInterface::getEditable() to retrieve a mutable configuration object + * @expectedExceptionMessage Can not clear name key in immutable configuration test.immutable_config. Use \Drupal\Core\Config\ConfigFactoryInterface::getEditable() to retrieve a mutable configuration object */ public function testClear() { $this->config->clear('name'); @@ -52,7 +52,7 @@ public function testClear() { /** * @covers ::save * @expectedException \Drupal\Core\Config\ImmutableConfigException - * @expectedExceptionMessage Can not save immutable configuration test. Use \Drupal\Core\Config\ConfigFactoryInterface::getEditable() to retrieve a mutable configuration object + * @expectedExceptionMessage Can not save immutable configuration test.immutable_config. Use \Drupal\Core\Config\ConfigFactoryInterface::getEditable() to retrieve a mutable configuration object */ public function testSave() { $this->config->save(); @@ -61,7 +61,7 @@ public function testSave() { /** * @covers ::delete * @expectedException \Drupal\Core\Config\ImmutableConfigException - * @expectedExceptionMessage Can not delete immutable configuration test. Use \Drupal\Core\Config\ConfigFactoryInterface::getEditable() to retrieve a mutable configuration object + * @expectedExceptionMessage Can not delete immutable configuration test.immutable_config. Use \Drupal\Core\Config\ConfigFactoryInterface::getEditable() to retrieve a mutable configuration object */ public function testDelete() { $this->config->delete();