diff --git a/core/includes/config.inc b/core/includes/config.inc index 95d4d83..8649256 100644 --- a/core/includes/config.inc +++ b/core/includes/config.inc @@ -79,14 +79,20 @@ function config_get_storage_names_with_prefix($prefix = '') { * object returned will contain the contents of book.admin configuration file. * @param string $class * (optional) The name of the class to use for the configuration object. + * Defaults to Drupal\Core\Config\ConfigObject. * - * @return + * @return Drupal\Core\Config\ConfigObject * An instance of the class specified in the $class parameter. - * - * @todo Replace with DI container. */ -function config($name, $class = NULL) { +function config($name, $class = 'Drupal\Core\Config\ConfigObject') { + // @todo Factory needs to be instantiated to prevent statics from being shared + // with parent environment in tests. Replace with DI container. + $factory = &drupal_static(__FUNCTION__); + + if (!isset($factory)) { + $factory = new ConfigFactory(); + } // @todo Do not reload an already loaded config object. // @todo Make it possible to skip load for known to be new config objects? - return ConfigFactory::get($name, $class); + return $factory->get($name, $class)->load(); } diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php index 1004fdd..3490582 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactory.php +++ b/core/lib/Drupal/Core/Config/ConfigFactory.php @@ -26,7 +26,7 @@ class ConfigFactory { * * @var array */ - protected static $storageManagers = array(); + protected $storageManagers = array(); /** * Instantiated configuration objects. @@ -36,7 +36,7 @@ class ConfigFactory { * * @var array */ - protected static $configObjects = array(); + protected $configObjects = array(); /** * Returns a configuration object for a given name. @@ -47,6 +47,7 @@ class ConfigFactory { * The name of the configuration object to construct. * @param string $class * (optional) The name of the class to use for the configuration object. + * Defaults to Drupal\Core\Config\ConfigObject. * @param string $manager_class * (optional) The name of the storage manager class to use. Defaults to * Drupal\Core\Config\DrupalConfig. @@ -54,39 +55,15 @@ class ConfigFactory { * @return Drupal\Core\Config\ConfigObject * A configuration object with the given $name. */ - public static function get($name, $class = NULL, $manager_class = 'Drupal\Core\Config\DrupalConfig') { + public function get($name, $class = 'Drupal\Core\Config\ConfigObject', $manager_class = 'Drupal\Core\Config\DrupalConfig') { // Instantiate the storage manager. - if (!isset(self::$storageManagers[$manager_class])) { - self::$storageManagers[$manager_class] = new $manager_class(); + if (!isset($this->storageManagers[$manager_class])) { + $this->storageManagers[$manager_class] = new $manager_class(); } - // Instantiate the configuration object, specific to the storage manager. - // @todo Config objects may need to be removed from this stack when deleted. - if (!isset(self::$configObjects[$manager_class][$name])) { - // If no explicit configuration object class was passed, determine the class - // name to use based on the configuration data. - if (!isset($class)) { - $storage = self::$storageManagers[$manager_class]->selectStorage('read', $name); - $data = $storage->read($name); - if (!empty($data['config_class'])) { - $class = $data['config_class']; - } - else { - $class = 'Drupal\Core\Config\ConfigObject'; - } - } - - self::$configObjects[$manager_class][$name] = new $class($name, self::$storageManagers[$manager_class]); - - // If we loaded data already, set it. - if (isset($data)) { - self::$configObjects[$manager_class][$name]->setData($data !== FALSE ? $data : array()); - } - // Otherwise, load it. - else { - self::$configObjects[$manager_class][$name]->load(); - } + if (!isset($this->configObjects[$manager_class][$name])) { + $this->configObjects[$manager_class][$name] = new $class($name, $this->storageManagers[$manager_class]); } - return self::$configObjects[$manager_class][$name]; + return $this->configObjects[$manager_class][$name]; } } diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php new file mode 100644 index 0000000..5e5b926 --- /dev/null +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php @@ -0,0 +1,88 @@ + 'CRUD operations', + 'description' => 'Tests CRUD operations on configuration objects.', + 'group' => 'Configuration', + ); + } + + /** + * Tests CRUD operations. + */ + function testCRUD() { + $storage = new DatabaseStorage(); + $name = 'config_test.crud'; + + // Create a new configuration object. + $config = config($name); + $config->set('value', 'initial'); + $config->save(); + + // Verify the active store contains the saved value. + $actual_data = $storage->read($name); + $this->assertIdentical($actual_data, array('value' => 'initial')); + + // Update the configuration object instance. + $config->set('value', 'instance-update'); + $config->save(); + + // Verify the active store contains the updated value. + $actual_data = $storage->read($name); + $this->assertIdentical($actual_data, array('value' => 'instance-update')); + + // Verify a call to config() immediately returns the updated value. + $new_config = config($name); + $this->assertIdentical($new_config->get(), $config->get()); + + // Verify config() returned the existing config instance. + $this->assertIdentical($new_config, $config); + + // Delete the configuration object. + $config->delete(); + + // Verify the configuration object is empty. + $this->assertIdentical($config->get(), array()); + + // Verify the active store contains no value. + $actual_data = $storage->read($name); + $this->assertIdentical($actual_data, array()); + + // Verify config() returns no data. + $new_config = config($name); + $this->assertIdentical($new_config->get(), $config->get()); + + // Verify config() returned the existing config instance. + $this->assertIdentical($new_config, $config); + + // Re-create the configuration object. + $config->set('value', 're-created'); + $config->save(); + + // Verify the active store contains the updated value. + $actual_data = $storage->read($name); + $this->assertIdentical($actual_data, array('value' => 're-created')); + + // Verify a call to config() immediately returns the updated value. + $new_config = config($name); + $this->assertIdentical($new_config->get(), $config->get()); + + // Verify config() returned the existing config instance. + $this->assertIdentical($new_config, $config); + } +}