diff --git a/core/includes/file.inc b/core/includes/file.inc index b38cf14..a7b1568 100644 --- a/core/includes/file.inc +++ b/core/includes/file.inc @@ -1521,7 +1521,7 @@ function drupal_tempnam($directory, $prefix) { * A string containing the path to the temporary directory. */ function file_directory_temp() { - $config = \Drupal::config('system.file'); + $config = \Drupal::config('system.file', FALSE); $temporary_directory = $config->get('path.temporary'); if (empty($temporary_directory)) { $temporary_directory = file_directory_os_temp(); diff --git a/core/includes/install.inc b/core/includes/install.inc index 7b52cd3..6ef0221 100644 --- a/core/includes/install.inc +++ b/core/includes/install.inc @@ -624,7 +624,7 @@ function drupal_install_system($install_state) { // Ensure default language is saved. if (isset($install_state['parameters']['langcode'])) { - \Drupal::config('system.site') + \Drupal::config('system.site', FALSE) ->set('langcode', $install_state['parameters']['langcode']) ->save(); } diff --git a/core/includes/module.inc b/core/includes/module.inc index ff11244..a2e84c5 100644 --- a/core/includes/module.inc +++ b/core/includes/module.inc @@ -212,7 +212,7 @@ function drupal_required_modules() { */ function module_set_weight($module, $weight) { // Update the module weight in the config file that contains it. - $extension_config = \Drupal::config('core.extension'); + $extension_config = \Drupal::config('core.extension', FALSE); if ($extension_config->get("module.$module") !== NULL) { $extension_config ->set("module.$module", $weight) diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php index 141686f..9ebc89d 100644 --- a/core/lib/Drupal.php +++ b/core/lib/Drupal.php @@ -297,12 +297,14 @@ public static function lock() { * The name of the configuration object to retrieve. The name corresponds to * a configuration file. For @code \Drupal::config('book.admin') @endcode, the config * object returned will contain the contents of book.admin configuration file. + * @param bool $immutable + * (optional) Create an immutable configuration object. Defaults to TRUE. * * @return \Drupal\Core\Config\Config * A configuration object. */ - public static function config($name) { - return static::$container->get('config.factory')->get($name); + public static function config($name, $immutable = TRUE) { + return static::$container->get('config.factory')->get($name, $immutable); } /** diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php index 970a500..ca48456 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactory.php +++ b/core/lib/Drupal/Core/Config/ConfigFactory.php @@ -104,12 +104,12 @@ public function getOverrideState() { /** * {@inheritdoc} */ - public function get($name) { - if ($config = $this->loadMultiple(array($name))) { + public function get($name, $immutable = TRUE) { + if ($config = $this->loadMultiple(array($name), $immutable)) { return $config[$name]; } else { - $cache_key = $this->getConfigCacheKey($name); + $cache_key = $this->getConfigCacheKey($name, $immutable); // If the config object has been deleted it will already exist in the // cache but self::loadMultiple does not return such objects. // @todo Explore making ConfigFactory a listener to the config.delete @@ -118,7 +118,7 @@ public function get($name) { // If the configuration object does not exist in the configuration // storage or static cache create a new object and add it to the static // cache. - $this->cache[$cache_key] = new Config($name, $this->storage, $this->eventDispatcher, $this->typedConfigManager); + $this->cache[$cache_key] = $this->createConfigObject($name, $immutable); if ($this->useOverrides) { // Get and apply any overrides. @@ -139,13 +139,13 @@ public function get($name) { /** * {@inheritdoc} */ - public function loadMultiple(array $names) { + public function loadMultiple(array $names, $immutable = TRUE) { $list = array(); foreach ($names as $key => $name) { // @todo: Deleted configuration stays in $this->cache, only return // configuration objects that are not new. - $cache_key = $this->getConfigCacheKey($name); + $cache_key = $this->getConfigCacheKey($name, $immutable); if (isset($this->cache[$cache_key]) && !$this->cache[$cache_key]->isNew()) { $list[$name] = $this->cache[$cache_key]; unset($names[$key]); @@ -164,9 +164,9 @@ public function loadMultiple(array $names) { } foreach ($storage_data as $name => $data) { - $cache_key = $this->getConfigCacheKey($name); + $cache_key = $this->getConfigCacheKey($name, $immutable); - $this->cache[$cache_key] = new Config($name, $this->storage, $this->eventDispatcher, $this->typedConfigManager); + $this->cache[$cache_key] = $this->createConfigObject($name, $immutable); $this->cache[$cache_key]->initWithData($data); if ($this->useOverrides) { if (isset($module_overrides[$name])) { @@ -226,15 +226,15 @@ public function reset($name = NULL) { /** * {@inheritdoc} */ - public function rename($old_name, $new_name) { + public function rename($old_name, $new_name, $immutable = TRUE) { $this->storage->rename($old_name, $new_name); - $old_cache_key = $this->getConfigCacheKey($old_name); - if (isset($this->cache[$old_cache_key])) { + $old_cache_keys = $this->getConfigCacheKeys($old_name); + foreach ($old_cache_keys as $old_cache_key) { unset($this->cache[$old_cache_key]); } // Prime the cache and load the configuration with the correct overrides. - $config = $this->get($new_name); + $config = $this->get($new_name, $immutable); $this->eventDispatcher->dispatch(ConfigEvents::RENAME, new ConfigRenameEvent($config, $old_name)); return $config; } @@ -260,12 +260,14 @@ public function getCacheKeys() { * * @param string $name * The name of the configuration object. + * @param bool $immutable + * Whether or not the object is mutable. * * @return string * The cache key. */ - protected function getConfigCacheKey($name) { - return $name . ':' . implode(':', $this->getCacheKeys()); + protected function getConfigCacheKey($name, $immutable) { + return $name . ':' . implode(':', $this->getCacheKeys()) . ':' . ($immutable ? static::IMMUTABLE: static::MUTABLE); } /** @@ -333,4 +335,22 @@ public function addOverride(ConfigFactoryOverrideInterface $config_factory_overr $this->configFactoryOverrides[] = $config_factory_override; } + /** + * Creates a configuration object. + * + * @param string $name + * Configuration object name. + * @param bool $immutable + * Determines whether a mutable or immutable config object is returned. + * + * @return \Drupal\Core\Config\Config|\Drupal\Core\Config\ImmutableConfig + * The configuration object. + */ + protected function createConfigObject($name, $immutable) { + if ($immutable) { + return new ImmutableConfig($name, $this->storage, $this->eventDispatcher, $this->typedConfigManager); + } + return new Config($name, $this->storage, $this->eventDispatcher, $this->typedConfigManager); + + } } diff --git a/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php b/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php index d51e023..4749be2 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php +++ b/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php @@ -15,6 +15,16 @@ interface ConfigFactoryInterface { /** + * Constant used in static cache keys for mutable config objects. + */ + const MUTABLE = 'mutable'; + + /** + * Constant used in static cache keys for immutable config objects. + */ + const IMMUTABLE = 'immutable'; + + /** * Sets the override state. * * @param bool $state @@ -37,11 +47,13 @@ public function getOverrideState(); * * @param string $name * The name of the configuration object to construct. + * @param bool $immutable + * (optional) Create an immutable configuration object. Defaults to TRUE. * * @return \Drupal\Core\Config\Config * A configuration object. */ - public function get($name); + public function get($name, $immutable = TRUE); /** * Returns a list of configuration objects for the given names. @@ -51,11 +63,13 @@ public function get($name); * * @param array $names * List of names of configuration objects. + * @param bool $immutable + * (optional) Create an immutable configuration object. Defaults to TRUE. * * @return \Drupal\Core\Config\Config[] * List of successfully loaded configuration objects, keyed by name. */ - public function loadMultiple(array $names); + public function loadMultiple(array $names, $immutable = TRUE); /** * Resets and re-initializes configuration objects. Internal use only. @@ -75,11 +89,13 @@ public function reset($name = NULL); * The old name of the configuration object. * @param string $new_name * The new name of the configuration object. + * @param bool $immutable + * (optional) Create an immutable configuration object. Defaults to TRUE. * * @return \Drupal\Core\Config\Config * The renamed config object. */ - public function rename($old_name, $new_name); + public function rename($old_name, $new_name, $immutable = TRUE); /** * The cache keys associated with the state of the config factory. diff --git a/core/lib/Drupal/Core/Config/ConfigManager.php b/core/lib/Drupal/Core/Config/ConfigManager.php index a97cf72..a4bdeb7 100644 --- a/core/lib/Drupal/Core/Config/ConfigManager.php +++ b/core/lib/Drupal/Core/Config/ConfigManager.php @@ -224,7 +224,7 @@ public function uninstall($type, $name) { $config_names = $this->configFactory->listAll($name . '.'); foreach ($config_names as $config_name) { - $this->configFactory->get($config_name)->delete(); + $this->configFactory->get($config_name, FALSE)->delete(); } // Remove any matching configuration from collections. diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php index a031ac8..cebadaa 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php @@ -243,10 +243,10 @@ protected function doSave($id, EntityInterface $entity) { // - Storage needs to access the original object. // - The object needs to be renamed/copied in ConfigFactory and reloaded. // - All instances of the object need to be renamed. - $config = $this->configFactory->rename($prefix . $id, $prefix . $entity->id()); + $config = $this->configFactory->rename($prefix . $id, $prefix . $entity->id(), FALSE); } else { - $config = $this->configFactory->get($prefix . $id); + $config = $this->configFactory->get($prefix . $id, FALSE); } // Retrieve the desired properties and set them in config. diff --git a/core/lib/Drupal/Core/Config/ImmutableConfig.php b/core/lib/Drupal/Core/Config/ImmutableConfig.php new file mode 100644 index 0000000..828f8ba --- /dev/null +++ b/core/lib/Drupal/Core/Config/ImmutableConfig.php @@ -0,0 +1,45 @@ +get('module') ?: array(); if (!$module_list = array_intersect_key($module_list, $installed_modules)) { // Nothing to do. All modules already uninstalled. @@ -380,7 +380,7 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) { drupal_uninstall_schema($module); // Remove the module's entry from the config. - $extension_config = \Drupal::config('core.extension'); + $extension_config = \Drupal::config('core.extension', FALSE); $extension_config->clear("module.$module")->save(); // Update the module handler to remove the module. diff --git a/core/lib/Drupal/Core/Extension/ThemeHandler.php b/core/lib/Drupal/Core/Extension/ThemeHandler.php index 8beb184..d4bc2af 100644 --- a/core/lib/Drupal/Core/Extension/ThemeHandler.php +++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php @@ -179,7 +179,7 @@ public function setDefault($name) { if (!isset($list[$name])) { throw new \InvalidArgumentException("$name theme is not installed."); } - $this->configFactory->get('system.theme') + $this->configFactory->get('system.theme', FALSE) ->set('default', $name) ->save(); return $this; @@ -189,7 +189,7 @@ public function setDefault($name) { * {@inheritdoc} */ public function install(array $theme_list, $install_dependencies = TRUE) { - $extension_config = $this->configFactory->get('core.extension'); + $extension_config = $this->configFactory->get('core.extension', FALSE); $theme_data = $this->rebuildThemeData(); diff --git a/core/lib/Drupal/Core/Form/ConfigFormBase.php b/core/lib/Drupal/Core/Form/ConfigFormBase.php index f58bc11..c93ec2f 100644 --- a/core/lib/Drupal/Core/Form/ConfigFormBase.php +++ b/core/lib/Drupal/Core/Form/ConfigFormBase.php @@ -70,7 +70,8 @@ protected function config($name) { $config_factory = $this->configFactory(); $old_state = $config_factory->getOverrideState(); $config_factory->setOverrideState(FALSE); - $config = $config_factory->get($name); + // Get a mutable object from the factory. + $config = $config_factory->get($name, FALSE); $config_factory->setOverrideState($old_state); return $config; } diff --git a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php index 750e967..ba55764 100644 --- a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php +++ b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php @@ -8,7 +8,7 @@ namespace Drupal\Core\Installer\Form; use Drupal\Core\Extension\ModuleInstallerInterface; -use Drupal\Core\Form\FormBase; +use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Locale\CountryManagerInterface; use Drupal\Core\State\StateInterface; @@ -18,7 +18,7 @@ /** * Provides the site configuration form. */ -class SiteConfigureForm extends FormBase { +class SiteConfigureForm extends ConfigFormBase { /** * The user storage. diff --git a/core/lib/Drupal/Core/Menu/StaticMenuLinkOverrides.php b/core/lib/Drupal/Core/Menu/StaticMenuLinkOverrides.php index ebde906..71ddf7e 100644 --- a/core/lib/Drupal/Core/Menu/StaticMenuLinkOverrides.php +++ b/core/lib/Drupal/Core/Menu/StaticMenuLinkOverrides.php @@ -54,7 +54,7 @@ public function __construct(ConfigFactoryInterface $config_factory) { */ protected function getConfig() { if (empty($this->config)) { - $this->config = $this->configFactory->get($this->configName); + $this->config = $this->configFactory->get($this->configName, FALSE); } return $this->config; } @@ -80,7 +80,7 @@ public function loadOverride($id) { * {@inheritdoc} */ public function deleteMultipleOverrides(array $ids) { - $all_overrides = $this->getConfig()->get('definitions'); + $all_overrides = $this->getConfig()->getOriginal('definitions', FALSE); $save = FALSE; foreach ($ids as $id) { $id = static::encodeId($id); @@ -135,7 +135,7 @@ public function saveOverride($id, array $definition) { $definition = array_intersect_key($definition, $expected); if ($definition) { $id = static::encodeId($id); - $all_overrides = $this->getConfig()->get('definitions'); + $all_overrides = $this->getConfig()->getOriginal('definitions', FALSE); // Combine with any existing data. $all_overrides[$id] = $definition + $this->loadOverride($id); $this->getConfig()->set('definitions', $all_overrides)->save(); diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module index a77c102..b128f8a 100644 --- a/core/modules/shortcut/shortcut.module +++ b/core/modules/shortcut/shortcut.module @@ -409,7 +409,7 @@ function shortcut_themes_installed($theme_list) { // Theme settings are not configuration entities and cannot depend on modules // so to set a module-specific setting, we need to set it with logic. if (\Drupal::moduleHandler()->moduleExists('shortcut')) { - \Drupal::config('seven.settings')->set('third_party_settings.shortcut.module_link', TRUE)->save(); + \Drupal::config('seven.settings', FALSE)->set('third_party_settings.shortcut.module_link', TRUE)->save(); } } } diff --git a/core/modules/simpletest/src/KernelTestBase.php b/core/modules/simpletest/src/KernelTestBase.php index f26c5d4..4714b41 100644 --- a/core/modules/simpletest/src/KernelTestBase.php +++ b/core/modules/simpletest/src/KernelTestBase.php @@ -203,7 +203,7 @@ protected function setUp() { $this->enableModules($modules); } // In order to use theme functions default theme config needs to exist. - \Drupal::config('system.theme')->set('default', 'classy'); + \Drupal::config('system.theme', FALSE)->set('default', 'classy')->save(); // Tests based on this class are entitled to use Drupal's File and // StreamWrapper APIs. @@ -477,7 +477,7 @@ protected function disableModules(array $modules) { // Unset the list of modules in the extension handler. $module_handler = $this->container->get('module_handler'); $module_filenames = $module_handler->getModuleList(); - $extension_config = $this->container->get('config.factory')->get('core.extension'); + $extension_config = $this->container->get('config.factory')->get('core.extension', FALSE); foreach ($modules as $module) { unset($module_filenames[$module]); $extension_config->clear('module.' . $module); diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php index 77c725b..eb6cee3 100644 --- a/core/modules/simpletest/src/WebTestBase.php +++ b/core/modules/simpletest/src/WebTestBase.php @@ -873,7 +873,7 @@ protected function setUp() { // UI. If declared in settings.php, they would no longer be configurable. file_prepare_directory($this->private_files_directory, FILE_CREATE_DIRECTORY); file_prepare_directory($this->temp_files_directory, FILE_CREATE_DIRECTORY); - $config->get('system.file') + $config->get('system.file', FALSE) ->set('path.private', $this->private_files_directory) ->set('path.temporary', $this->temp_files_directory) ->save(); @@ -882,7 +882,7 @@ protected function setUp() { // tests from sending out emails and collect them in state instead. // While this should be enforced via settings.php prior to installation, // some tests expect to be able to test mail system implementations. - $config->get('system.mail') + $config->get('system.mail', FALSE) ->set('interface.default', 'test_mail_collector') ->save(); @@ -890,10 +890,10 @@ protected function setUp() { // environment optimizations for all tests to avoid needless overhead and // ensure a sane default experience for test authors. // @see https://drupal.org/node/2259167 - $config->get('system.logging') + $config->get('system.logging', FALSE) ->set('error_level', 'verbose') ->save(); - $config->get('system.performance') + $config->get('system.performance', FALSE) ->set('css.preprocess', FALSE) ->set('js.preprocess', FALSE) ->save(); diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 5a1c545..cc1b147 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -622,7 +622,7 @@ function system_install() { \Drupal::state()->set('system.cron_key', $cron_key); // Populate the site UUID. - \Drupal::config('system.site') + \Drupal::config('system.site', FALSE) ->set('uuid', \Drupal::service('uuid')->generate()) ->save(); } diff --git a/core/profiles/minimal/minimal.install b/core/profiles/minimal/minimal.install index 52bea38..08de1db 100644 --- a/core/profiles/minimal/minimal.install +++ b/core/profiles/minimal/minimal.install @@ -13,8 +13,8 @@ */ function minimal_install() { // Disable the user pictures on nodes. - \Drupal::config('system.theme.global')->set('features.node_user_picture', FALSE)->save(); + \Drupal::config('system.theme.global', FALSE)->set('features.node_user_picture', FALSE)->save(); // Allow visitor account creation, but with administrative approval. - \Drupal::config('user.settings')->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(); + \Drupal::config('user.settings', FALSE)->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(); } diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install index 645587b..7620c9a 100644 --- a/core/profiles/standard/standard.install +++ b/core/profiles/standard/standard.install @@ -22,10 +22,10 @@ function standard_install() { \Drupal::service('entity.definition_update_manager')->applyUpdates(); // Set front page to "node". - \Drupal::config('system.site')->set('page.front', 'node')->save(); + \Drupal::config('system.site', FALSE)->set('page.front', 'node')->save(); // Allow visitor account creation with administrative approval. - $user_settings = \Drupal::config('user.settings'); + $user_settings = \Drupal::config('user.settings', FALSE); $user_settings->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(); // Enable default permissions for system roles. @@ -71,5 +71,5 @@ function standard_install() { $shortcut->save(); // Enable the admin theme. - \Drupal::config('node.settings')->set('use_admin_theme', '1')->save(); + \Drupal::config('node.settings', FALSE)->set('use_admin_theme', '1')->save(); }