diff --git a/core/core.services.yml b/core/core.services.yml index a2d373c..4d8da94 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -75,25 +75,11 @@ services: arguments: ['@config.cachedstorage.storage', '@cache.config'] tags: - { name: persist } - config.context.factory: - class: Drupal\Core\Config\Context\ConfigContextFactory - arguments: ['@event_dispatcher', '@uuid'] - config.context: - class: Drupal\Core\Config\Context\ContextInterface - tags: - - { name: persist } - factory_method: get - factory_service: config.context.factory - config.context.free: - class: Drupal\Core\Config\Context\ContextInterface - factory_method: get - factory_service: config.context.factory - arguments: [Drupal\Core\Config\Context\FreeConfigContext] config.factory: class: Drupal\Core\Config\ConfigFactory tags: - { name: persist } - arguments: ['@config.storage', '@config.context', '@config.typed'] + arguments: ['@config.storage', '@event_dispatcher', '@config.typed'] config.storage.staging: class: Drupal\Core\Config\FileStorage factory_class: Drupal\Core\Config\FileStorageFactory @@ -617,7 +603,7 @@ services: arguments: ['@module_handler'] date: class: Drupal\Core\Datetime\Date - arguments: ['@entity.manager', '@language_manager', '@string_translation'] + arguments: ['@entity.manager', '@language_manager', '@string_translation', '@config.factory'] feed.bridge.reader: class: Drupal\Component\Bridge\ZfExtensionManagerSfContainer calls: diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 91d12af..1568f45 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -138,24 +138,19 @@ const DRUPAL_BOOTSTRAP_PAGE_CACHE = 2; /** - * Fourth bootstrap phase: initialize database layer. + * Fourth bootstrap phase: initialize the variable system. */ -const DRUPAL_BOOTSTRAP_DATABASE = 3; +const DRUPAL_BOOTSTRAP_VARIABLES = 3; /** - * Fifth bootstrap phase: initialize the variable system. + * Fifth bootstrap phase: load code for subsystems and modules. */ -const DRUPAL_BOOTSTRAP_VARIABLES = 4; - -/** - * Sixth bootstrap phase: load code for subsystems and modules. - */ -const DRUPAL_BOOTSTRAP_CODE = 5; +const DRUPAL_BOOTSTRAP_CODE = 4; /** * Final bootstrap phase: initialize language, path, theme, and modules. */ -const DRUPAL_BOOTSTRAP_FULL = 6; +const DRUPAL_BOOTSTRAP_FULL = 5; /** * Role ID for anonymous users; should match what's in the "role" table. @@ -1748,7 +1743,6 @@ function drupal_anonymous_user() { * - DRUPAL_BOOTSTRAP_CONFIGURATION: Initializes configuration. * - DRUPAL_BOOTSTRAP_KERNEL: Initalizes a kernel. * - DRUPAL_BOOTSTRAP_PAGE_CACHE: Tries to serve a cached page. - * - DRUPAL_BOOTSTRAP_DATABASE: Initializes the database layer. * - DRUPAL_BOOTSTRAP_VARIABLES: Initializes the variable system. * - DRUPAL_BOOTSTRAP_CODE: Loads code for subsystems and modules. * - DRUPAL_BOOTSTRAP_FULL: Fully loads Drupal. Validates and fixes input @@ -1766,7 +1760,6 @@ function drupal_bootstrap($phase = NULL, $new_phase = TRUE) { DRUPAL_BOOTSTRAP_CONFIGURATION, DRUPAL_BOOTSTRAP_KERNEL, DRUPAL_BOOTSTRAP_PAGE_CACHE, - DRUPAL_BOOTSTRAP_DATABASE, DRUPAL_BOOTSTRAP_VARIABLES, DRUPAL_BOOTSTRAP_CODE, DRUPAL_BOOTSTRAP_FULL, @@ -1809,10 +1802,6 @@ function drupal_bootstrap($phase = NULL, $new_phase = TRUE) { _drupal_bootstrap_page_cache(); break; - case DRUPAL_BOOTSTRAP_DATABASE: - _drupal_bootstrap_database(); - break; - case DRUPAL_BOOTSTRAP_VARIABLES: _drupal_bootstrap_variables(); break; @@ -2015,6 +2004,7 @@ function _drupal_bootstrap_page_cache() { global $user; require_once __DIR__ . '/cache.inc'; + require_once __DIR__ . '/database.inc'; // Check for a cache mode force from settings.php. if (settings()->get('page_cache_without_database')) { $cache_enabled = TRUE; @@ -2089,15 +2079,6 @@ function _drupal_initialize_db_test_prefix() { } /** - * Initializes the database system by loading database.inc. - */ -function _drupal_bootstrap_database() { - // Initialize the database system. Note that the connection - // won't be initialized until it is actually requested. - require_once __DIR__ . '/database.inc'; -} - -/** * Loads system variables and all enabled bootstrap modules. */ function _drupal_bootstrap_variables() { diff --git a/core/includes/config.inc b/core/includes/config.inc index c7fca03..e4fb08f 100644 --- a/core/includes/config.inc +++ b/core/includes/config.inc @@ -3,12 +3,14 @@ use Drupal\Component\Utility\Unicode; use Drupal\Core\Config\Config; use Drupal\Core\Config\ConfigException; +use Drupal\Core\Language\Language; use Drupal\Core\Config\ExtensionInstallStorage; use Drupal\Core\Config\Context\FreeConfigContext; use Drupal\Core\Config\FileStorage; use Drupal\Core\Config\StorageInterface; use Drupal\Core\Entity\EntityTypeInterface; use Symfony\Component\Yaml\Dumper; +use Symfony\Component\EventDispatcher\EventDispatcher; /** * @file @@ -66,17 +68,18 @@ function ($value) use ($name) { if (!empty($config_to_install)) { $entity_manager = Drupal::service('entity.manager'); $config_factory = Drupal::service('config.factory'); - $context = new FreeConfigContext(Drupal::service('event_dispatcher'), Drupal::service('uuid')); $target_storage = Drupal::service('config.storage'); $typed_config = Drupal::service('config.typed'); - $config_factory->enterContext($context); + $event_dispatcher = Drupal::service('event_dispatcher'); + + $config_factory->disableOverrides(); foreach ($config_to_install as $name) { // Only import new config. if ($target_storage->exists($name)) { continue; } - $new_config = new Config($name, $target_storage, $context, $typed_config); + $new_config = new Config($name, $target_storage, $event_dispatcher, $typed_config); $data = $source_storage->read($name); if ($data !== FALSE) { $new_config->setData($data); @@ -90,11 +93,8 @@ function ($value) use ($name) { else { $new_config->save(); } - - // Reset static cache on the config factory. - $config_factory->reset($name); + $config_factory->enableOverrides(); } - $config_factory->leaveContext(); } } @@ -146,54 +146,6 @@ function config($name) { } /** - * Sets the config context on the config factory. - * - * This allows configuration objects to be created using special configuration - * contexts eg. global override free or locale using a user preferred language. - * Calling this function affects all subsequent calls to \Drupal::config() until - * config_context_leave() is called. - * - * @see config_context_leave() - * @see \Drupal\Core\Config\ConfigFactory - * - * @param string $context_name - * The name of the config context service on the container or a fully - * qualified class implementing \Drupal\Core\Config\Context\ContextInterface. - * - * @return \Drupal\Core\Config\Context\ContextInterface - * The configuration context object. - */ -function config_context_enter($context_name) { - $container = \Drupal::getContainer(); - if ($container->has($context_name)) { - $context = $container->get($context_name); - } - elseif (class_exists($context_name) && in_array('Drupal\Core\Config\Context\ContextInterface', class_implements($context_name))) { - $context = $container - ->get('config.context.factory') - ->get($context_name); - } - else { - throw new ConfigException(sprintf('Unknown config context service or class: %s', $context_name)); - } - $container - ->get('config.factory') - ->enterContext($context); - return $context; -} - -/** - * Leaves the current config context returning to the previous context. - * - * @see config_context_enter() - * @see \Drupal\Core\Config\ConfigFactory - */ -function config_context_leave() { - \Drupal::service('config.factory') - ->leaveContext(); -} - -/** * Returns the entity type of a configuration object. * * @param string $name diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index b44c59a..3890b1d 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -378,13 +378,6 @@ function install_begin_request(&$install_state) { $container->register('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher'); $container->register('config.storage', 'Drupal\Core\Config\InstallStorage'); - $container->register('config.context.factory', 'Drupal\Core\Config\Context\ConfigContextFactory') - ->addArgument(new Reference('event_dispatcher')) - ->addArgument(new Reference('uuid')); - - $container->register('config.context', 'Drupal\Core\Config\Context\ContextInterface') - ->setFactoryService(new Reference('config.context.factory')) - ->setFactoryMethod('get'); $container->register('config.storage.schema', 'Drupal\Core\Config\Schema\SchemaStorage'); @@ -394,7 +387,7 @@ function install_begin_request(&$install_state) { $container->register('config.factory', 'Drupal\Core\Config\ConfigFactory') ->addArgument(new Reference('config.storage')) - ->addArgument(new Reference('config.context')) + ->addArgument(new Reference('event_dispatcher')) ->addArgument(new Reference('config.typed')); // Register the 'language_manager' service. @@ -2103,12 +2096,13 @@ function install_configure_form($form, &$form_state, &$install_state) { drupal_set_message(t('All necessary changes to %dir and %file have been made, so you should remove write permissions to them now in order to avoid security risks. If you are unsure how to do so, consult the online handbook.', array('%dir' => $settings_dir, '%file' => $settings_file, '@handbook_url' => 'http://drupal.org/server-permissions')), 'warning'); } - drupal_add_library('system', 'drupal.system'); + $form['#attached']['library'][] = array('system', 'drupal.system'); // Add JavaScript time zone detection. - drupal_add_library('system', 'drupal.timezone'); + $form['#attached']['library'][] = array('system', 'drupal.timezone'); // We add these strings as settings because JavaScript translation does not // work during installation. - drupal_add_js(array('copyFieldValue' => array('edit-site-mail' => array('edit-account-mail'))), 'setting'); + $js = array('copyFieldValue' => array('edit-site-mail' => array('edit-account-mail'))); + $form['#attached']['js'][] = array('data' => $js, 'type' => 'setting'); // Cache a fully-built schema. This is necessary for any invocation of // index.php because: (1) setting cache table entries requires schema diff --git a/core/includes/menu.inc b/core/includes/menu.inc index 856c424..b0a14cb 100644 --- a/core/includes/menu.inc +++ b/core/includes/menu.inc @@ -2563,7 +2563,7 @@ function menu_router_rebuild() { function menu_router_build($save = FALSE) { // Ensure that all configuration used to build the menu items are loaded // without overrides. - config_context_enter('config.context.free'); + \Drupal::configFactory()->disableOverrides(); // We need to manually call each module so that we can know which module // a given item came from. $callbacks = array(); @@ -2578,8 +2578,8 @@ function menu_router_build($save = FALSE) { } // Alter the menu as defined in modules, keys are like user/%user. drupal_alter('menu', $callbacks); - // Return to the original context before menu building. - config_context_leave(); + // Re-enable configuration overrides. + \Drupal::configFactory()->enableOverrides(); foreach ($callbacks as $path => $router_item) { // If the menu item is a default local task and incorrectly references a // route, remove it. diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 3db84a9..37f04f9 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -91,7 +91,6 @@ function drupal_theme_initialize() { return; } - drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE); $themes = list_themes(); // @todo Let the theme.negotiator listen to the kernel request event. @@ -237,9 +236,15 @@ function _drupal_theme_initialize($theme, $base_theme = array()) { } // Add scripts used by this theme. + $js = array(); foreach ($final_scripts as $script) { - drupal_add_js($script, array('group' => JS_THEME, 'every_page' => TRUE)); + $js['#attached']['js'][] = array( + 'data' => $script, + 'group' => JS_THEME, + 'every_page' => TRUE, + ); } + drupal_render($js); $theme_engine = NULL; diff --git a/core/includes/update.inc b/core/includes/update.inc index 73f9b7f..b17624f 100644 --- a/core/includes/update.inc +++ b/core/includes/update.inc @@ -142,7 +142,7 @@ function update_prepare_d8_bootstrap() { } // Bootstrap the database. - drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE); + require_once __DIR__ . '/database.inc'; // module.inc is not yet loaded but there are calls to module_config_sort() // below. diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php index 9c14801..6af2411 100644 --- a/core/lib/Drupal.php +++ b/core/lib/Drupal.php @@ -242,6 +242,19 @@ public static function config($name) { } /** + * Retrieves the configuration factory. + * + * This is mostly used to change the override settings on the configuration + * factory. For example, changing the language, or turning all overrides on + * or off. + * + * @return \Drupal\Core\Config\ConfigFactory + */ + public static function configFactory() { + return static::$container->get('config.factory'); + } + + /** * Returns a queue for the given queue name. * * The following values can be set in your settings.php file's $settings diff --git a/core/lib/Drupal/Component/Utility/Crypt.php b/core/lib/Drupal/Component/Utility/Crypt.php index 6d101c2..ea008bd 100644 --- a/core/lib/Drupal/Component/Utility/Crypt.php +++ b/core/lib/Drupal/Component/Utility/Crypt.php @@ -71,21 +71,25 @@ public static function randomBytes($count) { /** * Calculates a base-64 encoded, URL-safe sha-256 hmac. * - * @param string $data - * String to be validated with the hmac. - * @param string $key - * A secret string key. + * @param mixed $data + * Scalar value to be validated with the hmac. + * @param mixed $key + * A secret key, this can be any scalar value. * * @return string * A base-64 encoded sha-256 hmac, with + replaced with -, / with _ and * any = padding characters removed. */ public static function hmacBase64($data, $key) { - // Casting $data and $key to strings here is necessary to avoid empty string + // $data and $key being strings here is necessary to avoid empty string // results of the hash function if they are not scalar values. As this - // function is used in security-critical contexts like token validation it is - // important that it never returns an empty string. - $hmac = base64_encode(hash_hmac('sha256', (string) $data, (string) $key, TRUE)); + // function is used in security-critical contexts like token validation it + // is important that it never returns an empty string. + if (!is_scalar($data) || !is_scalar($key)) { + throw new \InvalidArgumentException('Both parameters passed to \Drupal\Component\Utility\Crypt::hmacBase64 must be scalar values.'); + } + + $hmac = base64_encode(hash_hmac('sha256', $data, $key, TRUE)); // Modify the hmac so it's safe to use in URLs. return strtr($hmac, array('+' => '-', '/' => '_', '=' => '')); } diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php index f04bbe0..679f729 100644 --- a/core/lib/Drupal/Core/Config/Config.php +++ b/core/lib/Drupal/Core/Config/Config.php @@ -10,10 +10,11 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\String; use Drupal\Core\Config\ConfigNameException; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\TypedData\PrimitiveInterface; use Drupal\Core\TypedData\Type\FloatInterface; use Drupal\Core\TypedData\Type\IntegerInterface; +use Drupal\Core\Language\Language; +use Symfony\Component\EventDispatcher\EventDispatcher; /** * Defines the default configuration object. @@ -33,6 +34,20 @@ class Config { const MAX_NAME_LENGTH = 250; /** + * An event dispatcher instance to use for configuration events. + * + * @var \Symfony\Component\EventDispatcher\EventDispatcher + */ + protected $eventDispatcher; + + /** + * The language object used to override configuration data. + * + * @var Drupal\Core\Language\Language + */ + protected $language; + + /** * The name of the configuration object. * * @var string @@ -54,25 +69,32 @@ class Config { protected $data; /** - * The current runtime data ($data + $overrides from Config Context). + * The current runtime data. * * @var array */ protected $overriddenData; /** - * The storage used to load and save this configuration object. + * The current language overrides. * - * @var \Drupal\Core\Config\StorageInterface + * @var array */ - protected $storage; + protected $languageOverrides; /** - * The configuration context used for this configuration object. + * The current module overrides. * - * @var \Drupal\Core\Config\Context\ContextInterface + * @var array */ - protected $context; + protected $moduleOverrides; + + /** + * The storage used to load and save this configuration object. + * + * @var \Drupal\Core\Config\StorageInterface + */ + protected $storage; /** * Whether the configuration object has already been loaded. @@ -103,28 +125,19 @@ class Config { * @param \Drupal\Core\Config\StorageInterface $storage * A storage controller object to use for reading and writing the * configuration data. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context used for this configuration object. + * @param \Symfony\Component\EventDispatcher\EventDispatcher $event_dispatcher + * An event dispatcher instance to use for configuration events. * @param \Drupal\Core\Config\TypedConfigManager $typed_config * The typed configuration manager service. + * @param Drupal\Core\Language\Language $language + * The language object used to override configuration data. */ - public function __construct($name, StorageInterface $storage, ContextInterface $context, TypedConfigManager $typed_config) { + public function __construct($name, StorageInterface $storage, EventDispatcher $event_dispatcher, TypedConfigManager $typed_config, Language $language = NULL) { $this->name = $name; $this->storage = $storage; - $this->context = $context; + $this->eventDispatcher = $event_dispatcher; $this->typedConfigManager = $typed_config; - } - - /** - * Initializes a configuration object. - * - * @return \Drupal\Core\Config\Config - * The configuration object. - */ - public function init() { - $this->isLoaded = FALSE; - $this->notify('init'); - return $this; + $this->language = $language; } /** @@ -138,10 +151,11 @@ public function init() { */ public function initWithData(array $data) { $this->isLoaded = TRUE; + $this->settingsOverrides = array(); + $this->languageOverrides = array(); + $this->moduleOverrides = array(); $this->isNew = FALSE; - $this->notify('init'); $this->replaceData($data); - $this->notify('load'); return $this; } @@ -294,7 +308,7 @@ protected function replaceData(array $data) { } /** - * Sets overridden data for this configuration object. + * Sets settings.php overrides this configuration object. * * The overridden data only applies to this configuration object. * @@ -304,8 +318,38 @@ protected function replaceData(array $data) { * @return \Drupal\Core\Config\Config * The configuration object. */ - public function setOverride(array $data) { - $this->context->setOverrides($this->getName(), $data); + public function setSettingsOverride(array $data) { + $this->settingsOverrides = $data; + $this->resetOverriddenData(); + return $this; + } + + /** + * Sets module overrides for this configuration object. + * + * @param array $data + * The overridden values of the configuration data. + * + * @return Drupal\Core\Config\Config + * The configuration object. + */ + public function setModuleOverride(array $data) { + $this->moduleOverrides = $data; + $this->resetOverriddenData(); + return $this; + } + + /** + * Sets language overrides for this configuration object. + * + * @param array $data + * The overridden values of the configuration data. + * + * @return Drupal\Core\Config\Config + * The configuration object. + */ + public function setLanguageOverride(array $data) { + $this->languageOverrides = $data; $this->resetOverriddenData(); return $this; } @@ -313,16 +357,24 @@ public function setOverride(array $data) { /** * Sets the current data for this configuration object. * - * Merges overridden configuration data into the original data. + * Configuration overrides operate at three distinct layers: locale, modules + * and settings.php, with the last of these winning. Overrides in + * settings.php win over values provided by modules. Overrides provided by + * modules win over locale. * * @return \Drupal\Core\Config\Config * The configuration object. */ protected function setOverriddenData() { $this->overriddenData = $this->data; - $overrides = $this->context->getOverrides($this->getName()); - if (is_array($overrides)) { - $this->overriddenData = NestedArray::mergeDeepArray(array($this->overriddenData, $overrides), TRUE); + if (isset($this->languageOverrides) && is_array($this->languageOverrides)) { + $this->overriddenData = NestedArray::mergeDeepArray(array($this->overriddenData, $this->languageOverrides), TRUE); + } + if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) { + $this->overriddenData = NestedArray::mergeDeepArray(array($this->overriddenData, $this->moduleOverrides), TRUE); + } + if (isset($this->settingsOverrides) && is_array($this->settingsOverrides)) { + $this->overriddenData = NestedArray::mergeDeepArray(array($this->overriddenData, $this->settingsOverrides), TRUE); } return $this; } @@ -411,7 +463,6 @@ public function load() { $this->isNew = FALSE; $this->replaceData($data); } - $this->notify('load'); $this->isLoaded = TRUE; return $this; } @@ -478,7 +529,7 @@ public function getStorage() { * The configuration event name. */ protected function notify($config_event_name) { - $this->context->notify($config_event_name, $this); + $this->eventDispatcher->dispatch('config.' . $config_event_name, new ConfigEvent($this)); } /** @@ -604,4 +655,29 @@ protected function castValue($key, $value) { return $value; } + /** + * Returns the language object for this Config object. + * + * @return \Drupal\Core\Language\Language + */ + public function getLanguage() { + return $this->language; + } + + /** + * Get configuration name for this language. + * + * It will be the same name with a prefix depending on language code: + * language.config.LANGCODE.NAME + * + * @return string + * The localized config name. + */ + public function getLanguageConfigName() { + if (!isset($this->language)) { + throw new ConfigException("No language set, cannot return language config name for '{$this->name}'"); + } + return 'language.config.' . $this->language->id . '.' . $this->getName(); + } } + diff --git a/core/lib/Drupal/Core/Config/ConfigEvent.php b/core/lib/Drupal/Core/Config/ConfigEvent.php index 4cfac2e..5b07098 100644 --- a/core/lib/Drupal/Core/Config/ConfigEvent.php +++ b/core/lib/Drupal/Core/Config/ConfigEvent.php @@ -2,7 +2,6 @@ namespace Drupal\Core\Config; -use Drupal\Core\Config\Context\ContextInterface; use Symfony\Component\EventDispatcher\Event; class ConfigEvent extends Event { @@ -15,23 +14,13 @@ class ConfigEvent extends Event { protected $config; /** - * Configuration context object. - * - * @var \Drupal\Core\Config\Context\ContextInterface - */ - protected $context; - - /** * Constructs a configuration event object. * - * @param \Drupal\Core\Config\Context\ContextInterface - * Configuration context object. * @param \Drupal\Core\Config\Config - * (optional) Configuration object. + * Configuration object. */ - public function __construct(ContextInterface $context, Config $config = NULL) { + public function __construct(Config $config) { $this->config = $config; - $this->context = $context; } /** @@ -40,14 +29,5 @@ public function __construct(ContextInterface $context, Config $config = NULL) { public function getConfig() { return $this->config; } - - /** - * Gets configuration context object. - * - * @return \Drupal\Core\Config\Context\ContextInterface - * Configuration context. - */ - public function getContext() { - return $this->context; - } } + diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php index 7b1e97c..b79695c 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactory.php +++ b/core/lib/Drupal/Core/Config/ConfigFactory.php @@ -7,8 +7,10 @@ namespace Drupal\Core\Config; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Config\TypedConfigManager; +use Drupal\Core\Language\Language; +use Drupal\Core\Config\ConfigModuleOverridesEvent; +use Symfony\Component\EventDispatcher\EventDispatcher; /** * Defines the configuration object factory. @@ -21,13 +23,7 @@ * Each configuration object gets a storage controller object injected, which * is used for reading and writing the configuration data. * - * @see \Drupal\Core\Config\StorageInterface - * - * A configuration context is an object containing parameters that will be - * available to the configuration plug-ins for them to customize the - * configuration data in different ways. - * - * @see \Drupal\Core\Config\Context\ContextInterface + * @see Drupal\Core\Config\StorageInterface */ class ConfigFactory { @@ -39,11 +35,25 @@ class ConfigFactory { protected $storage; /** - * A stack of configuration contexts the last being the context in use. + * An event dispatcher instance to use for configuration events. * - * @var array + * @var \Symfony\Component\EventDispatcher\EventDispatcher + */ + protected $eventDispatcher; + + /** + * A flag indicating if we should use overrides. + * + * @var boolean + */ + protected $useOverrides = TRUE; + + /** + * The language object used to override configuration data. + * + * @var Drupal\Core\Language\Language */ - protected $contextStack = array(); + protected $language; /** * Cached configuration objects. @@ -64,19 +74,38 @@ class ConfigFactory { * * @param \Drupal\Core\Config\StorageInterface $storage * The configuration storage engine. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * Configuration context object. + * @param \Symfony\Component\EventDispatcher\EventDispatcher $event_dispatcher + * An event dispatcher instance to use for configuration events. * @param \Drupal\Core\Config\TypedConfigManager $typed_config * The typed configuration manager. + * @param \Drupal\Core\Language\Language + * The language for this configuration. */ - public function __construct(StorageInterface $storage, ContextInterface $context, TypedConfigManager $typed_config) { + public function __construct(StorageInterface $storage, EventDispatcher $event_dispatcher, TypedConfigManager $typed_config, Language $language = NULL) { $this->storage = $storage; + $this->eventDispatcher = $event_dispatcher; $this->typedConfigManager = $typed_config; - $this->enterContext($context); + $this->language = $language; + } + + /** + * Disable overrides when loading configuration objects. + */ + public function disableOverrides() { + $this->useOverrides = FALSE; + $this->reset(); + } + + /** + * Enable overrides when loading configuration objects. + */ + public function enableOverrides() { + $this->useOverrides = TRUE; + $this->reset(); } /** - * Returns a configuration object for a given name and context. + * Returns a configuration object for a given name. * * @param string $name * The name of the configuration object to construct. @@ -85,18 +114,21 @@ public function __construct(StorageInterface $storage, ContextInterface $context * A configuration object. */ public function get($name) { - $context = $this->getContext(); - $cache_key = $this->getCacheKey($name, $context); - if (isset($this->cache[$cache_key])) { + $names = array($name); + if ($config = $this->loadMultiple($names)) { + return $config[$name]; + } + else { + $cache_key = $this->getCacheKey($name); + if (!isset($this->cache[$cache_key])) { + $this->cache[$cache_key] = new Config($name, $this->storage, $this->eventDispatcher, $this->typedConfigManager, $this->language); + } return $this->cache[$cache_key]; } - - $this->cache[$cache_key] = new Config($name, $this->storage, $context, $this->typedConfigManager); - return $this->cache[$cache_key]->init(); } /** - * Returns a list of configuration objects for a given names and context. + * Returns a list of configuration objects for the given names. * * This will pre-load all requested configuration objects does not create * new configuration objects. @@ -108,13 +140,14 @@ public function get($name) { * List of successfully loaded configuration objects, keyed by name. */ public function loadMultiple(array $names) { - $context = $this->getContext(); + global $conf; $list = array(); + foreach ($names as $key => $name) { - $cache_key = $this->getCacheKey($name, $context); // @todo: Deleted configuration stays in $this->cache, only return // config entities that are not new. + $cache_key = $this->getCacheKey($name); if (isset($this->cache[$cache_key]) && !$this->cache[$cache_key]->isNew()) { $list[$name] = $this->cache[$cache_key]; unset($names[$key]); @@ -123,18 +156,64 @@ public function loadMultiple(array $names) { // Pre-load remaining configuration files. if (!empty($names)) { - $storage_data = $this->storage->readMultiple($names); + if ($this->useOverrides) { + // In order to make just one call to storage, add in language names. + // Keep track of them separately, so we can get language override data + // returned from storage and set it on new Config objects. + $language_names = $this->getLanguageConfigNames($names); + $storage_data = $this->storage->readMultiple(array_merge($names, array_values($language_names))); + $moduleOverrides = $this->loadModuleOverrides($names); + } + else { + $language_names = array(); + $moduleOverrides = array(); + $storage_data = $this->storage->readMultiple($names); + } + foreach ($storage_data as $name => $data) { - $cache_key = $this->getCacheKey($name, $context); - $this->cache[$cache_key] = new Config($name, $this->storage, $context, $this->typedConfigManager); + if (in_array($name, $language_names)) { + // Language override configuration is not regular configuration and + // therefore not cached or overridden. + continue; + } + $cache_key = $this->getCacheKey($name); + + $this->cache[$cache_key] = new Config($name, $this->storage, $this->eventDispatcher, $this->typedConfigManager, $this->language); $this->cache[$cache_key]->initWithData($data); + if ($this->useOverrides) { + if (isset($language_names[$name]) && isset($storage_data[$language_names[$name]])) { + $this->cache[$cache_key]->setLanguageOverride($storage_data[$language_names[$name]]); + } + if (isset($moduleOverrides[$name])) { + $this->cache[$cache_key]->setModuleOverride($moduleOverrides[$name]); + } + if (isset($conf[$name])) { + $this->cache[$cache_key]->setSettingsOverride($conf[$name]); + } + } $list[$name] = $this->cache[$cache_key]; } } + return $list; } /** + * Get arbitrary overrides for the named configuration objects from modules. + * + * @param array $names + * The names of the configuration objects to get overrides for. + * + * @return array + * An array of overrides keyed by the configuration object name. + */ + protected function loadModuleOverrides(array $names) { + $configOverridesEvent = new ConfigModuleOverridesEvent($names, $this->language); + $this->eventDispatcher->dispatch('config.module.overrides', $configOverridesEvent); + return $configOverridesEvent->getOverrides(); + } + + /** * Resets and re-initializes configuration objects. Internal use only. * * @param string $name @@ -146,7 +225,7 @@ public function loadMultiple(array $names) { */ public function reset($name = NULL) { if ($name) { - // Clear the cached configuration object in all contexts. + // Clear all cached configuration for this name. foreach ($this->getCacheKeys($name) as $cache_key) { unset($this->cache[$cache_key]); } @@ -174,103 +253,126 @@ public function reset($name = NULL) { * The renamed config object. */ public function rename($old_name, $new_name) { - $context = $this->getContext(); - $old_cache_key = $this->getCacheKey($old_name, $context); - $new_cache_key = $this->getCacheKey($new_name, $context); + $this->storage->rename($old_name, $new_name); + $old_cache_key = $this->getCacheKey($old_name); if (isset($this->cache[$old_cache_key])) { - $config = $this->cache[$old_cache_key]; unset($this->cache[$old_cache_key]); } - else { - // Create the config object if it's not yet loaded into the static cache. - $config = new Config($old_name, $this->storage, $context, $this->typedConfigManager); - } - $this->cache[$new_cache_key] = $config; - $this->storage->rename($old_name, $new_name); - return $this->cache[$new_cache_key]->setName($new_name)->init(); + $new_cache_key = $this->getCacheKey($new_name); + $this->cache[$new_cache_key] = new Config($new_name, $this->storage, $this->eventDispatcher, $this->typedConfigManager, $this->language); + $this->cache[$new_cache_key]->load(); + return $this->cache[$new_cache_key]; } /** - * Sets the config context by adding it to the context stack. + * Gets the cache key for a given config name. * - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context to add. + * @param string $name + * The name of the configuration object. * - * @return \Drupal\Core\Config\ConfigFactory - * The config factory object. + * @return string + * The cache key. */ - public function enterContext(ContextInterface $context) { - // Initialize the context as it is being entered. - $this->contextStack[] = $context->init(); - return $this; + public function getCacheKey($name) { + if (isset($this->language)) { + return $this->language->id . ":$name"; + } + else { + return $name; + } } /** - * Gets the current config context. + * Gets all the cache keys that match the provided config name. + * + * @param string $name + * The name of the configuration object. * - * @return \Drupal\Core\Config\Context\ContextInterface $context - * The current configuration context. + * @return array + * An array of cache keys that match the provided config name. */ - public function getContext() { - return end($this->contextStack); + public function getCacheKeys($name) { + return array_filter(array_keys($this->cache), function($key) use ($name) { + // Match only $name directly, or LANGCODE:$name. + return preg_match('/^([a-z]+:)?' . preg_quote($name) . '$/', $key); + }); } /** - * Leaves the current context by removing it from the context stack. + * Clears the config factory static cache. * * @return \Drupal\Core\Config\ConfigFactory * The config factory object. */ - public function leaveContext() { - // Ensure at least one context is left on the stack. We already ensured - // there is at least one context set by taking the initial one in the - // constructor. - if (count($this->contextStack) > 1) { - array_pop($this->contextStack); - } + public function clearStaticCache() { + $this->cache = array(); return $this; } /** - * Gets the cache key for a given config name in a particular context. + * Set the language to be injected in to Config objects. * - * @param string $name - * The name of the configuration object. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context. + * @param Language $language * - * @return string - * The cache key. + * @return ConfigFactory */ - public function getCacheKey($name, ContextInterface $context) { - return $name . ':' . $context->getUuid(); + public function setLanguage(Language $language = NULL) { + $this->language = $language; + return $this; } /** - * Gets all the cache keys that match the provided config name. + * Get the language to be injected in to Config objects. * - * @param string $name - * The name of the configuration object. + * @return \Drupal\Core\Language\Language + */ + public function getLanguage() { + return $this->language; + } + + /** + * Get configuration names for this language. + * + * It will be the same name with a prefix depending on language code: + * language.config.LANGCODE.NAME + * + * @param string $names + * A list of configuration object names. * * @return array - * An array of cache keys that match the provided config name. + * The localized config names, keyed by configuration object name. */ - public function getCacheKeys($name) { - $cache_keys = array_keys($this->cache); - return array_filter($cache_keys, function($key) use ($name) { - return ( strpos($key, $name) !== false ); - }); + public function getLanguageConfigNames(array $names) { + $language_names = array(); + if (isset($this->language)) { + foreach ($names as $name) { + if (strpos($name, 'lanuguage.config.') === 0) { + continue; + } + $language_names[$name] = 'language.config.' . $this->language->id . '.' . $name; + } + } + return $language_names; } /** - * Clears the config factory static cache. + * Get configuration name for this language. * - * @return \Drupal\Core\Config\ConfigFactory - * The config factory object. + * It will be the same name with a prefix depending on language code: + * language.config.LANGCODE.NAME + * + * @param string $name + * The name of the config object. + * + * @return string + * The localized config name. */ - public function clearStaticCache() { - $this->cache = array(); - return $this; + public function getLanguageConfigName($name) { + if (!isset($this->language) || strpos($name, 'language.config.') === 0) { + return FALSE; + } + return 'language.config.' . $this->language->id . '.' . $name; } } + diff --git a/core/lib/Drupal/Core/Config/ConfigImporter.php b/core/lib/Drupal/Core/Config/ConfigImporter.php index dd5b9bb..0feabdf 100644 --- a/core/lib/Drupal/Core/Config/ConfigImporter.php +++ b/core/lib/Drupal/Core/Config/ConfigImporter.php @@ -7,7 +7,6 @@ namespace Drupal\Core\Config; -use Drupal\Core\Config\Context\FreeConfigContext; use Drupal\Core\Config\TypedConfigManager; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Lock\LockBackendInterface; @@ -55,13 +54,6 @@ class ConfigImporter { protected $eventDispatcher; /** - * The configuration context. - * - * @var \Drupal\Core\Config\Context\ContextInterface - */ - protected $context; - - /** * The configuration factory. * * @var \Drupal\Core\Config\ConfigFactory @@ -138,10 +130,6 @@ public function __construct(StorageComparerInterface $storage_comparer, EventDis $this->uuidService = $uuid_service; $this->typedConfigManager = $typed_config; $this->processed = $this->storageComparer->getEmptyChangelist(); - // Use an override free context for importing so that overrides to do not - // pollute the imported data. The context is hard coded to ensure this is - // the case. - $this->context = new FreeConfigContext($this->eventDispatcher, $this->uuidService); } /** @@ -235,7 +223,6 @@ public function import() { // Ensure that the changes have been validated. $this->validate(); - $this->configFactory->enterContext($this->context); if (!$this->lock->acquire(static::ID)) { // Another process is synchronizing configuration. throw new ConfigImporterException(sprintf('%s is already importing', static::ID)); @@ -248,9 +235,6 @@ public function import() { // The import is now complete. $this->lock->release(static::ID); $this->reset(); - // Leave the context used during import and clear the ConfigFactory's - // static cache. - $this->configFactory->leaveContext()->reset(); } return $this; } @@ -278,7 +262,7 @@ public function validate() { protected function importConfig() { foreach (array('delete', 'create', 'update') as $op) { foreach ($this->getUnprocessed($op) as $name) { - $config = new Config($name, $this->storageComparer->getTargetStorage(), $this->context, $this->typedConfigManager); + $config = new Config($name, $this->storageComparer->getTargetStorage(), $this->eventDispatcher, $this->typedConfigManager); if ($op == 'delete') { $config->delete(); } @@ -311,11 +295,11 @@ protected function importInvokeOwner() { // Validate the configuration object name before importing it. // Config::validateName($name); if ($entity_type = config_get_entity_type_by_name($name)) { - $old_config = new Config($name, $this->storageComparer->getTargetStorage(), $this->context, $this->typedConfigManager); + $old_config = new Config($name, $this->storageComparer->getTargetStorage(), $this->eventDispatcher, $this->typedConfigManager); $old_config->load(); $data = $this->storageComparer->getSourceStorage()->read($name); - $new_config = new Config($name, $this->storageComparer->getTargetStorage(), $this->context, $this->typedConfigManager); + $new_config = new Config($name, $this->storageComparer->getTargetStorage(), $this->eventDispatcher, $this->typedConfigManager); if ($data !== FALSE) { $new_config->setData($data); } diff --git a/core/lib/Drupal/Core/Config/ConfigModuleOverridesEvent.php b/core/lib/Drupal/Core/Config/ConfigModuleOverridesEvent.php new file mode 100644 index 0000000..fd70cc9 --- /dev/null +++ b/core/lib/Drupal/Core/Config/ConfigModuleOverridesEvent.php @@ -0,0 +1,76 @@ +names = $names; + $this->language = $language; + $this->overrides = array(); + } + + /** + * Get configuration names. + */ + public function getNames() { + return $this->names; + } + + /** + * Get configuration language. + */ + public function getLanguage() { + return $this->language; + } + + /** + * Get configuration overrides. + */ + public function getOverrides() { + return $this->overrides; + } + + /** + * Set a configuration override for the given name. + */ + public function setOverride($name, $value) { + if (in_array($name, $this->names)) { + $this->overrides[$name] = $value; + } + return $this; + } +} + diff --git a/core/lib/Drupal/Core/Config/Context/ConfigContext.php b/core/lib/Drupal/Core/Config/Context/ConfigContext.php deleted file mode 100644 index 128165b..0000000 --- a/core/lib/Drupal/Core/Config/Context/ConfigContext.php +++ /dev/null @@ -1,141 +0,0 @@ -eventDispatcher = $event_dispatcher; - $this->uuidService = $uuid; - } - - /** - * Implements \Drupal\Core\Config\Context\ContextInterface::init(). - */ - public function init() { - // Reset existing overrides and get a UUID for this context. - $this->overrides = array(); - $this->setUuid(); - // Notify event listeners that a configuration context has been created. - $this->notify('context', NULL); - return $this; - } - - /** - * Implements \Drupal\Core\Config\Context\ContextInterface::get(). - */ - public function get($key) { - return array_key_exists($key, $this->data) ? $this->data[$key] : NULL; - } - - /** - * Implements \Drupal\Core\Config\Context\ContextInterface::set(). - */ - public function set($key, $value) { - $this->data[$key] = $value; - } - - /** - * Implements \Drupal\Core\Config\Context\ContextInterface::setUuid(). - */ - public function setUuid() { - $this->uuid = $this->uuidService->generate(); - } - - /** - * Implements \Drupal\Core\Config\Context\ContextInterface::getUuid(). - */ - public function getUuid() { - return $this->uuid; - } - - /** - * Implements \Drupal\Core\Config\Context\ContextInterface::notify(). - */ - public function notify($config_event_name, Config $config = NULL) { - $this->eventDispatcher->dispatch('config.' . $config_event_name, new ConfigEvent($this, $config)); - } - - /** - * Implements \Drupal\Core\Config\Context\ContextInterface::setOverride(). - */ - public function setOverrides($config_name, $data) { - if (!isset($this->overrides[$config_name])) { - $this->overrides[$config_name] = $data; - } - else { - $this->overrides[$config_name] = NestedArray::mergeDeepArray(array($this->overrides[$config_name], $data), TRUE); - } - } - - /** - * Implements \Drupal\Core\Config\Context\ContextInterface::getOverrides(). - */ - public function getOverrides($config_name) { - if (isset($this->overrides[$config_name])) { - return $this->overrides[$config_name]; - } - return FALSE; - } - -} diff --git a/core/lib/Drupal/Core/Config/Context/ConfigContextFactory.php b/core/lib/Drupal/Core/Config/Context/ConfigContextFactory.php deleted file mode 100644 index de3fd7b..0000000 --- a/core/lib/Drupal/Core/Config/Context/ConfigContextFactory.php +++ /dev/null @@ -1,74 +0,0 @@ -eventDispatcher = $event_dispatcher; - $this->uuidService = $uuid; - } - - /** - * Returns a configuration context object. - * - * @param string $class - * (Optional) The name of the configuration class to use. Defaults to - * Drupal\Core\Config\Context\ConfigContext - * - * @return \Drupal\Core\Config\Context\ContextInterface $context - * (Optional) The configuration context to use. - */ - public function get($class = NULL) { - if (!$class) { - $class = 'Drupal\Core\Config\Context\ConfigContext'; - } - if (class_exists($class)) { - $context = new $class($this->eventDispatcher, $this->uuidService); - } - else { - throw new ConfigException(sprintf('Unknown config context class: %s', $class)); - } - return $context; - } - -} diff --git a/core/lib/Drupal/Core/Config/Context/ContextInterface.php b/core/lib/Drupal/Core/Config/Context/ContextInterface.php deleted file mode 100644 index e37d2d0..0000000 --- a/core/lib/Drupal/Core/Config/Context/ContextInterface.php +++ /dev/null @@ -1,101 +0,0 @@ -set(self::LANGUAGE_KEY, $language); - // Re-initialize since the language change changes the context - // fundamentally. - $this->init(); - return $this; - } - -} diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php b/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php index 458d765..dc4d4fe 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php @@ -356,7 +356,7 @@ public function save(EntityInterface $entity) { // - Storage controller 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. - $this->configFactory->rename($prefix . $id, $prefix . $entity->id()); + $config = $this->configFactory->rename($prefix . $id, $prefix . $entity->id()); } // Build an ID if none is set. diff --git a/core/lib/Drupal/Core/Datetime/Date.php b/core/lib/Drupal/Core/Datetime/Date.php index 0510fa4..34b8632 100644 --- a/core/lib/Drupal/Core/Datetime/Date.php +++ b/core/lib/Drupal/Core/Datetime/Date.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Datetime; use Drupal\Component\Utility\Xss; +use Drupal\Core\Config\ConfigFactory; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Language\Language; @@ -40,6 +41,13 @@ class Date { */ protected $languageManager; + /** + * The configuration factory. + * + * @var \Drupal\Core\Config\ConfigFactory + */ + protected $configFactory; + protected $country = NULL; protected $dateFormats = array(); @@ -72,10 +80,11 @@ class Date { * @param \Drupal\Core\StringTranslation\TranslationInterface $translation * The string translation. */ - public function __construct(EntityManagerInterface $entity_manager, LanguageManager $language_manager, TranslationInterface $translation) { + public function __construct(EntityManagerInterface $entity_manager, LanguageManager $language_manager, TranslationInterface $translation, ConfigFactory $config_factory) { $this->dateFormatStorage = $entity_manager->getStorageController('date_format'); $this->languageManager = $language_manager; $this->stringTranslation = $translation; + $this->configFactory = $config_factory; } /** @@ -205,11 +214,10 @@ protected function t($string, array $args = array(), array $options = array()) { protected function dateFormat($format, $langcode) { if (!isset($this->dateFormats[$format][$langcode])) { // Enter a language specific context so the right date format is loaded. - $language_context = config_context_enter('Drupal\Core\Config\Context\LanguageConfigContext'); - $language_context->setLanguage(new Language(array('id' => $langcode))); - + $original_language = $this->configFactory->getLanguage(); + $this->configFactory->setLanguage(new Language(array('id' => $langcode))); $this->dateFormats[$format][$langcode] = $this->dateFormatStorage->load($format); - config_context_leave(); + $this->configFactory->setLanguage($original_language); } return $this->dateFormats[$format][$langcode]; } diff --git a/core/lib/Drupal/Core/Form/ConfigFormBase.php b/core/lib/Drupal/Core/Form/ConfigFormBase.php index 5c69835..6fca58e 100644 --- a/core/lib/Drupal/Core/Form/ConfigFormBase.php +++ b/core/lib/Drupal/Core/Form/ConfigFormBase.php @@ -8,7 +8,6 @@ namespace Drupal\Core\Form; use Drupal\Core\Config\ConfigFactory; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Form\FormBase; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -29,12 +28,9 @@ * * @param \Drupal\Core\Config\ConfigFactory $config_factory * The factory for configuration objects. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context to use. */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context) { + public function __construct(ConfigFactory $config_factory) { $this->configFactory = $config_factory; - $this->configFactory->enterContext($context); } /** @@ -42,8 +38,7 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con */ public static function create(ContainerInterface $container) { return new static( - $container->get('config.factory'), - $container->get('config.context.free') + $container->get('config.factory') ); } @@ -78,7 +73,7 @@ protected function config($name) { if (!$this->configFactory) { $container = $this->container(); $this->configFactory = $container->get('config.factory'); - $this->configFactory->enterContext($container->get('config.context.free')); + $this->configFactory->disableOverrides(); } return $this->configFactory->get($name); } diff --git a/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php index e6526f2..a7dfbc0 100644 --- a/core/lib/Drupal/Core/Language/LanguageManager.php +++ b/core/lib/Drupal/Core/Language/LanguageManager.php @@ -236,7 +236,7 @@ protected function getLanguageTypes() { * @return \Drupal\Core\Language\Language * A language object. */ - protected function getLanguageDefault() { + public function getLanguageDefault() { $default_info = variable_get('language_default', array( 'id' => 'en', 'name' => 'English', diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php b/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php index 1c59201..5fc015b 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php @@ -9,7 +9,6 @@ use Drupal\aggregator\Plugin\AggregatorPluginManager; use Drupal\Component\Utility\String; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Config\ConfigFactory; use Drupal\Core\Plugin\PluginFormInterface; use Drupal\Core\StringTranslation\TranslationInterface; @@ -51,8 +50,6 @@ class SettingsForm extends ConfigFormBase { * * @param \Drupal\Core\Config\ConfigFactory $config_factory * The factory for configuration objects. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context to use. * @param \Drupal\aggregator\Plugin\AggregatorPluginManager $fetcher_manager * The aggregator fetcher plugin manager. * @param \Drupal\aggregator\Plugin\AggregatorPluginManager $parser_manager @@ -62,8 +59,8 @@ class SettingsForm extends ConfigFormBase { * @param \Drupal\Core\StringTranslation\TranslationInterface $translation_manager * The string translation manager. */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context, AggregatorPluginManager $fetcher_manager, AggregatorPluginManager $parser_manager, AggregatorPluginManager $processor_manager, TranslationInterface $translation_manager) { - parent::__construct($config_factory, $context); + public function __construct(ConfigFactory $config_factory, AggregatorPluginManager $fetcher_manager, AggregatorPluginManager $parser_manager, AggregatorPluginManager $processor_manager, TranslationInterface $translation_manager) { + parent::__construct($config_factory); $this->translationManager = $translation_manager; $this->managers = array( 'fetcher' => $fetcher_manager, @@ -84,7 +81,6 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('config.context.free'), $container->get('plugin.manager.aggregator.fetcher'), $container->get('plugin.manager.aggregator.parser'), $container->get('plugin.manager.aggregator.processor'), diff --git a/core/modules/aggregator/tests/Drupal/aggregator/Tests/Plugin/AggregatorPluginSettingsBaseTest.php b/core/modules/aggregator/tests/Drupal/aggregator/Tests/Plugin/AggregatorPluginSettingsBaseTest.php index 9c120c3..139a5ba 100644 --- a/core/modules/aggregator/tests/Drupal/aggregator/Tests/Plugin/AggregatorPluginSettingsBaseTest.php +++ b/core/modules/aggregator/tests/Drupal/aggregator/Tests/Plugin/AggregatorPluginSettingsBaseTest.php @@ -67,7 +67,6 @@ public function setUp() { $this->settingsForm = new SettingsForm( $this->configFactory, - $this->getMock('Drupal\Core\Config\Context\ContextInterface'), $this->managers['fetcher'], $this->managers['parser'], $this->managers['processor'], diff --git a/core/modules/book/lib/Drupal/book/Tests/BookTest.php b/core/modules/book/lib/Drupal/book/Tests/BookTest.php index 93c5c78..21fc988 100644 --- a/core/modules/book/lib/Drupal/book/Tests/BookTest.php +++ b/core/modules/book/lib/Drupal/book/Tests/BookTest.php @@ -434,9 +434,9 @@ function testBookNodeTypeChange() { // 'page', // ); // @endcode - $current_config = \Drupal::config('book.settings')->init()->get(); + $current_config = \Drupal::config('book.settings')->get(); $this->drupalPostForm('admin/structure/book/settings', array(), t('Save configuration')); - $this->assertIdentical($current_config, \Drupal::config('book.settings')->init()->get()); + $this->assertIdentical($current_config, \Drupal::config('book.settings')->get()); // Change the name, machine name and description. $edit = array( @@ -455,9 +455,9 @@ function testBookNodeTypeChange() { // 'zebra', // ); // @endcode - $current_config = \Drupal::config('book.settings')->init()->get(); + $current_config = \Drupal::config('book.settings')->get(); $this->drupalPostForm('admin/structure/book/settings', array(), t('Save configuration')); - $this->assertIdentical($current_config, \Drupal::config('book.settings')->init()->get()); + $this->assertIdentical($current_config, \Drupal::config('book.settings')->get()); $edit = array( 'name' => 'Animal book', @@ -473,9 +473,9 @@ function testBookNodeTypeChange() { // 'zebra', // ); // @endcode - $current_config = \Drupal::config('book.settings')->init()->get(); + $current_config = \Drupal::config('book.settings')->get(); $this->drupalPostForm('admin/structure/book/settings', array(), t('Save configuration')); - $this->assertIdentical($current_config, \Drupal::config('book.settings')->init()->get()); + $this->assertIdentical($current_config, \Drupal::config('book.settings')->get()); // Ensure that after all the node type changes book.settings:child_type has // the expected value. diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigExportImportUITest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigExportImportUITest.php index a214b63..9095b7d 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigExportImportUITest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigExportImportUITest.php @@ -48,11 +48,6 @@ class ConfigExportImportUITest extends WebTestBase { */ protected $admin_role; - /** - * Sort methods alphabetically in order to allow for a predictable sequence. - */ - const SORT_METHODS = TRUE; - public static $modules = array('config'); public static function getInfo() { @@ -73,52 +68,31 @@ protected function setUp() { } /** - * Tests a simple site configuration export case: site slogan. + * Tests a simple site export import case. */ - function testExport() { - $this->siteUuid = \Drupal::config('system.site')->get('uuid'); - - // Create a role for second round. - $this->admin_role = $this->drupalCreateRole(array('synchronize configuration', 'import configuration')); - $this->slogan = $this->randomString(16); + public function testExportImport() { + $this->originalSlogan = \Drupal::config('system.site')->get('slogan'); + $this->newSlogan = $this->randomString(16); + $this->assertNotEqual($this->newSlogan, $this->originalSlogan); \Drupal::config('system.site') - ->set('slogan', $this->slogan) + ->set('slogan', $this->newSlogan) ->save(); + $this->assertEqual(\Drupal::config('system.site')->get('slogan'), $this->newSlogan); + $this->drupalPostForm('admin/config/development/configuration/full/export', array(), 'Export'); $this->tarball = $this->drupalGetContent(); - } - /** - * Tests importing the tarball to ensure changes made it over. - */ - function testImport() { - $filename = 'temporary://' . $this->randomName(); - file_put_contents($filename, $this->tarball); - $this->doImport($filename); - // Now that the role is imported, change the slogan and re-import with a non-root user. - $web_user = $this->drupalCreateUser(); - $web_user->addRole($this->admin_role); - $web_user->save(); - $this->drupalLogin($web_user); \Drupal::config('system.site') - ->set('slogan', $this->randomString(16)) + ->set('slogan', $this->originalSlogan) ->save(); - $this->doImport($filename); - } - - /** - * Import a tarball and assert the data is correct. - * - * @param string $filename - * The name of the tarball containing the configuration to be imported. - */ - protected function doImport($filename) { - // The site UUIDs must match for the import to work. - \Drupal::config('system.site')->set('uuid', $this->siteUuid)->save(); + $this->assertEqual(\Drupal::config('system.site')->get('slogan'), $this->originalSlogan); - $this->assertNotEqual($this->slogan, \Drupal::config('system.site')->get('slogan')); + $filename = 'temporary://' . $this->randomName(); + file_put_contents($filename, $this->tarball); $this->drupalPostForm('admin/config/development/configuration/full/import', array('files[import_tarball]' => $filename), 'Upload'); $this->drupalPostForm(NULL, array(), 'Import all'); - $this->assertEqual($this->slogan, \Drupal::config('system.site')->get('slogan')); + + $this->assertEqual(\Drupal::config('system.site')->get('slogan'), $this->newSlogan); } } + diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php index 6af6295..de7fc7f 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php @@ -62,7 +62,8 @@ function setUp() { $this->container->get('entity.manager'), $this->container->get('lock'), $this->container->get('uuid'), - $this->container->get('config.typed') + $this->container->get('config.typed'), + $this->container->get('module_handler') ); $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.staging')); } @@ -229,6 +230,7 @@ function testUpdated() { $this->configImporter->reset()->import(); // Verify the values were updated. + \Drupal::configFactory()->reset($name); $config = \Drupal::config($name); $this->assertIdentical($config->get('foo'), 'beer'); $config = \Drupal::config($dynamic_name); diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php index 1062ea5..992c1bd 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php @@ -47,6 +47,8 @@ function testModuleInstallation() { $this->installConfig(array('config_test')); // Verify that default module config exists. + \Drupal::configFactory()->reset($default_config); + \Drupal::configFactory()->reset($default_configuration_entity); $config = \Drupal::config($default_config); $this->assertIdentical($config->isNew(), FALSE); $config = \Drupal::config($default_configuration_entity); diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php index 3bb7839..0fd3f5e 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php @@ -49,6 +49,8 @@ function testIntegrationModuleReinstallation() { \Drupal::moduleHandler()->install(array('config_integration_test')); // Verify that default module config exists. + \Drupal::configFactory()->reset($default_config); + \Drupal::configFactory()->reset($default_configuration_entity); $config_static = \Drupal::config($default_config); $this->assertIdentical($config_static->isNew(), FALSE); $this->assertIdentical($config_static->get('foo'), 'default setting'); @@ -82,6 +84,8 @@ function testIntegrationModuleReinstallation() { \Drupal::moduleHandler()->install(array('config_integration_test')); // Verify the integration module's config was re-installed. + \Drupal::configFactory()->reset($default_config); + \Drupal::configFactory()->reset($default_configuration_entity); $config_static = \Drupal::config($default_config); $this->assertIdentical($config_static->isNew(), FALSE); $this->assertIdentical($config_static->get('foo'), 'default setting'); diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php b/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php index 24edb76..02646d3 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php @@ -35,263 +35,32 @@ public function setUp() { parent::setUp(); config_install_default_config('module', 'config_test'); config_install_default_config('module', 'locale'); + \Drupal::configFactory()->setLanguage(language_default()); } /** - * Tests basic locale override. - */ - function testConfigLocaleOverride() { - $name = 'config_test.system'; - // The default language is en so the config key should be localised. - $config = \Drupal::config($name); - $this->assertIdentical($config->get('foo'), 'en bar'); - $this->assertIdentical($config->get('404'), 'herp'); - - // Ensure that we get the expected value when we avoid overrides. - config_context_enter('config.context.free'); - $config_admin = \Drupal::config($name); - $this->assertIdentical($config_admin->get('foo'), 'bar'); - $this->assertIdentical($config_admin->get('404'), 'herp'); - - // Leave the non override context. - config_context_leave(); - $config = \Drupal::config($name); - $this->assertIdentical($config->get('foo'), 'en bar'); - $this->assertIdentical($config->get('404'), 'herp'); - } - - /** - * Tests locale override based on user's preferred language. + * Tests locale override based on language. */ - function testConfigLocaleUserOverride() { - $this->installSchema('system', 'variable'); - $this->installConfig(array('language')); - language_save(new Language(array( - 'name' => 'French', - 'id' => 'fr', - ))); - language_save(new Language(array( - 'name' => 'English', - 'id' => 'en', - ))); - language_save(new Language(array( - 'name' => 'German', - 'id' => 'de', - ))); - - $this->installSchema('user', 'users'); - $account = entity_create('user', array( - 'name' => 'French user', - 'mail' => 'test@example.com', - 'created' => REQUEST_TIME, - 'status' => 1, - 'preferred_langcode' => 'fr', - )); - - $user_config_context = config_context_enter('Drupal\user\UserConfigContext'); - $user_config_context->setAccount($account); - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), 'fr bar'); - // Ensure the non-overriden value is still the same. - $this->assertIdentical($config->get('404'), 'herp'); - - // Ensure that we get the expected value when we leave the user context. The - // locale overrides contain an English override too, so although we are not - // in a user based language override context, the English language override - // applies due to the negotiated language for the page. - config_context_leave(); - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), 'en bar'); - - $account = entity_create('user', array( - 'name' => 'German user', - 'mail' => 'test@example.com', - 'created' => REQUEST_TIME, - 'status' => 1, - 'preferred_langcode' => 'de', - )); - - $config_factory = \Drupal::service('config.factory'); - $config_factory->enterContext($user_config_context->setAccount($account)); - // Should not have to re-initialize the configuration object to get new - // overrides as the new context will have a different uuid. - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), 'de bar'); - - // Enter an english context on top of the german context. - $account = entity_create('user', array( - 'name' => 'English user', - 'mail' => 'test@example.com', - 'created' => REQUEST_TIME, - 'status' => 1, - 'preferred_langcode' => 'en', - )); - // Create a new user config context to stack on top of the existign one. - $en_user_config_context = config_context_enter('Drupal\user\UserConfigContext'); - $en_user_config_context->setAccount($account); - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), 'en bar'); - - // Ensure that we get the expected value when we leave the english user - // context. - config_context_leave(); - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), 'de bar'); - - // Ensure that we get the expected value when we leave the german user - // context. - config_context_leave(); - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), 'en bar'); - - // Ensure that we cannot leave the default context. - config_context_leave(); + function testConfigLocaleLanguageOverride() { $config = \Drupal::config('config_test.system'); $this->assertIdentical($config->get('foo'), 'en bar'); - } - /** - * Tests locale override based on language. - */ - function testConfigLocaleLanguageOverride() { - $this->installSchema('system', 'variable'); - $this->installConfig(array('language')); language_save(new Language(array( 'name' => 'French', 'id' => 'fr', ))); language_save(new Language(array( - 'name' => 'English', - 'id' => 'en', - ))); - language_save(new Language(array( 'name' => 'German', 'id' => 'de', ))); - $language = language_load('fr'); - $language_config_context = config_context_enter('Drupal\Core\Config\Context\LanguageConfigContext'); - $language_config_context->setLanguage($language); + \Drupal::configFactory()->setLanguage(language_load('fr')); $config = \Drupal::config('config_test.system'); $this->assertIdentical($config->get('foo'), 'fr bar'); - // Ensure the non-overridden value is still the same. - $this->assertIdentical($config->get('404'), 'herp'); - - // Ensure that we get the expected value when we leave the language context. The - // locale overrides contain an English override too, so although we are not - // in a language override context, the English language override - // applies due to the negotiated language for the page. - config_context_leave(); - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), 'en bar'); - - $config_factory = \Drupal::service('config.factory'); - $language = language_load('de'); - $config_factory->enterContext($language_config_context->setLanguage($language)); - // Should not have to re-initialize the configuration object to get new - // overrides as the new context will have a different uuid. - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), 'de bar'); - - // Enter an english context on top of the german context. - $language = language_load('en'); - // Create a new language config context to stack on top of the existing one. - $en_language_config_context = config_context_enter('Drupal\Core\Config\Context\LanguageConfigContext'); - $en_language_config_context->setLanguage($language); - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), 'en bar'); - // Ensure that we get the expected value when we leave the english - // language context. - config_context_leave(); + \Drupal::configFactory()->setLanguage(language_load('de')); $config = \Drupal::config('config_test.system'); $this->assertIdentical($config->get('foo'), 'de bar'); - - // Ensure that we get the expected value when we leave the german - // language context. - config_context_leave(); - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), 'en bar'); - - // Ensure that we cannot leave the default context. - config_context_leave(); - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), 'en bar'); - } - - /** - * Tests locale override in combination with global overrides. - */ - function testConfigLocaleUserAndGlobalOverride() { - global $conf; - - // Globally override value for the keys in config_test.system. Although we - // override the foo key, there are also language overrides, which trump - // global overrides so the 'foo' key override will never surface. - $conf['config_test.system']['foo'] = 'global bar'; - $conf['config_test.system']['404'] = 'global herp'; - - $this->installSchema('system', 'variable'); - $this->installConfig(array('language')); - language_save(new Language(array( - 'name' => 'French', - 'id' => 'fr', - ))); - - $this->installSchema('user', 'users'); - $account = entity_create('user', array( - 'name' => 'French user', - 'mail' => 'test@example.com', - 'created' => REQUEST_TIME, - 'status' => 1, - 'preferred_langcode' => 'fr', - )); - - $user_config_context = config_context_enter('Drupal\user\UserConfigContext'); - $user_config_context->setAccount($account); - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), 'fr bar'); - // Ensure the value overriden from global $conf works. - $this->assertIdentical($config->get('404'), 'global herp'); - - // Ensure that we get the expected value when we leave the user context. The - // locale overrides contain an English override too, so although we are not - // in a user based language override context, the English language override - // applies due to the negotiated language for the page. - config_context_leave(); - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), 'en bar'); - // Global override should still apply. - $this->assertIdentical($config->get('404'), 'global herp'); - - // Ensure that we cannot leave the default context. - config_context_leave(); - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), 'en bar'); - // Global override should still apply. - $this->assertIdentical($config->get('404'), 'global herp'); - - // Ensure that we get the expected value when we avoid overrides. - config_context_enter('config.context.free'); - $config_admin = \Drupal::config('config_test.system'); - // Language override should not apply anymore. - $this->assertIdentical($config_admin->get('foo'), 'bar'); - // Global override should not apply. - $this->assertIdentical($config_admin->get('404'), 'herp'); - config_context_leave(); - } - - /** - * Tests config_context_enter() invalid context name handling. - */ - function testInvalidContextName() { - $message = 'Expected ConfigException was thrown for an invalid context_name argument.'; - try { - config_context_enter('invalid.config.context'); - $this->fail($message); - } - catch (ConfigException $e) { - $this->pass($message); - } } } + diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigModuleOverridesTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigModuleOverridesTest.php new file mode 100644 index 0000000..e6dad5b --- /dev/null +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigModuleOverridesTest.php @@ -0,0 +1,47 @@ + 'Module overrides', + 'description' => 'Tests that modules can override configuration with event subscribers.', + 'group' => 'Configuration', + ); + } + + public function testSimpleModuleOverrides() { + $GLOBALS['config_test_run_module_overrides'] = TRUE; + $name = 'system.site'; + $overridden_name = 'ZOMG overridden site name'; + $non_overridden_name = 'ZOMG this name is on disk mkay'; + $config_factory = $this->container->get('config.factory'); + $config_factory + ->get($name) + ->set('name', $non_overridden_name) + ->save(); + + $config_factory->disableOverrides(); + $this->assertEqual($non_overridden_name, $config_factory->get('system.site')->get('name')); + + $config_factory->enableOverrides(); + $this->assertEqual($overridden_name, $config_factory->get('system.site')->get('name')); + + unset($GLOBALS['config_test_run_module_overrides']); + } +} + diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigOverrideTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigOverrideTest.php index a6016c3..25b0ff1 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigOverrideTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigOverrideTest.php @@ -61,14 +61,6 @@ function testConfOverride() { $this->assertFalse(isset($data['baz'])); $this->assertIdentical($data['404'], $expected_original_data['404']); - // Enter an override-free context to ensure the original data remains. - config_context_enter('config.context.free'); - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), $expected_original_data['foo']); - $this->assertIdentical($config->get('baz'), $expected_original_data['baz']); - $this->assertIdentical($config->get('404'), $expected_original_data['404']); - config_context_leave(); - // Get the configuration object in an overriden context (the one set by // default). $config = \Drupal::config('config_test.system'); @@ -100,14 +92,6 @@ function testConfOverride() { $this->assertIdentical($config->get('baz'), $conf['config_test.system']['baz']); $this->assertIdentical($config->get('404'), $conf['config_test.system']['404']); - // Enter an override-free context to ensure the original data remains saved. - config_context_enter('config.context.free'); - $config = \Drupal::config('config_test.system'); - $this->assertIdentical($config->get('foo'), $expected_original_data['foo']); - $this->assertIdentical($config->get('baz'), $expected_original_data['baz']); - $this->assertIdentical($config->get('404'), $expected_original_data['404']); - config_context_leave(); - // Write file to staging. $staging = $this->container->get('config.storage.staging'); $expected_new_data = array( diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigSnapshotTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigSnapshotTest.php index d9504b2..34743d5 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigSnapshotTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigSnapshotTest.php @@ -79,6 +79,7 @@ function testSnapshot() { $this->configImporter()->import(); // Verify changed config was properly imported. + \Drupal::configFactory()->reset($config_name); $this->assertIdentical(\Drupal::config($config_name)->get($config_key), $new_data); // Verify that a new snapshot was created which and that it matches diff --git a/core/modules/config/tests/config_test/config_test.services.yml b/core/modules/config/tests/config_test/config_test.services.yml new file mode 100644 index 0000000..ac60fd4 --- /dev/null +++ b/core/modules/config/tests/config_test/config_test.services.yml @@ -0,0 +1,6 @@ +services: + config_test_config_subscriber: + class: Drupal\config_test\EventSubscriber\ConfigModuleOverrideSubscriber + tags: + - { name: event_subscriber } + diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/EventSubscriber/ConfigModuleOverrideSubscriber.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/EventSubscriber/ConfigModuleOverrideSubscriber.php new file mode 100644 index 0000000..5302045 --- /dev/null +++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/EventSubscriber/ConfigModuleOverrideSubscriber.php @@ -0,0 +1,42 @@ +getNames(); + $language = $event->getLanguage(); + $overrides = $event->getOverrides(); + $overridden_name = 'ZOMG overridden site name'; + + if (in_array('system.site', $names)) { + $event->setOverride('system.site', array('name' => $overridden_name)); + } + } + } + + /** + * Registers the methods in this class that should be listeners. + * + * @return array + * An array of event listener definitions. + */ + static function getSubscribedEvents() { + $events['config.module.overrides'][] = array('onConfigLoadMultiple', 40); + return $events; + } +} + diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php index e559ea1..50aaa88 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php @@ -9,6 +9,7 @@ use Drupal\config_translation\ConfigMapperManagerInterface; use Drupal\Core\Config\Config; +use Drupal\Core\Config\ConfigFactory; use Drupal\Core\Config\Schema\Element; use Drupal\Core\Config\TypedConfigManager; use Drupal\Core\Extension\ModuleHandlerInterface; @@ -92,12 +93,15 @@ * The translation storage object. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler to invoke the alter hook. + * @param \Drupal\Core\Config\ConfigFactory + * The config factory. */ - public function __construct(TypedConfigManager $typed_config_manager, ConfigMapperManagerInterface $config_mapper_manager, StringStorageInterface $locale_storage, ModuleHandlerInterface $module_handler) { + public function __construct(TypedConfigManager $typed_config_manager, ConfigMapperManagerInterface $config_mapper_manager, StringStorageInterface $locale_storage, ModuleHandlerInterface $module_handler, ConfigFactory $config_factory) { $this->typedConfigManager = $typed_config_manager; $this->configMapperManager = $config_mapper_manager; $this->localeStorage = $locale_storage; $this->moduleHandler = $module_handler; + $this->configFactory = $config_factory; } /** @@ -108,7 +112,8 @@ public static function create(ContainerInterface $container) { $container->get('config.typed'), $container->get('plugin.manager.config_translation.mapper'), $container->get('locale.storage'), - $container->get('module_handler') + $container->get('module_handler'), + $container->get('config.factory') ); } @@ -158,20 +163,16 @@ public function buildForm(array $form, array &$form_state, Request $request = NU $this->language = $language; $this->sourceLanguage = $this->mapper->getLanguageWithFallback(); - // Make sure we are in the override free configuration context. For example, - // visiting the configuration page in another language would make those - // language overrides active by default. But we need the original values. - config_context_enter('config.context.free'); // Get base language configuration to display in the form before entering // into the language context for the form. This avoids repetitively going // in and out of the language context to get original values later. + $this->configFactory->disableOverrides(); $this->baseConfigData = $this->mapper->getConfigData(); - // Leave override free context. - config_context_leave(); + $this->configFactory->enableOverrides(); - // Enter context for the translation target language requested and generate - // form with translation data in that language. - config_context_enter('Drupal\Core\Config\Context\LanguageConfigContext')->setLanguage($this->language); + // Set the translation target language on the configuration factory. + $original_language = $this->configFactory->getLanguage(); + $this->configFactory->setLanguage($this->language); // Add some information to the form state for easier form altering. $form_state['config_translation_mapper'] = $this->mapper; @@ -196,9 +197,8 @@ public function buildForm(array $form, array &$form_state, Request $request = NU '#button_type' => 'primary', ); - // Leave the language context so that configuration accessed later in the - // request is displayed in the correct language. - config_context_leave(); + // Set the configuration language back. + $this->configFactory->setLanguage($original_language); return $form; } @@ -209,9 +209,8 @@ public function buildForm(array $form, array &$form_state, Request $request = NU public function submitForm(array &$form, array &$form_state) { $form_values = $form_state['values']['config_names']; - // For the form submission handling, use the override free context. - config_context_enter('config.context.free'); - + // For the form submission handling, use the raw data. + $this->configFactory->disableOverrides(); foreach ($this->mapper->getConfigNames() as $name) { // Set configuration values based on form submission and source values. $base_config = $this->config($name); @@ -229,8 +228,7 @@ public function submitForm(array &$form, array &$form_state) { $translation_config->save(); } } - - config_context_leave(); + $this->configFactory->enableOverrides(); $form_state['redirect_route'] = array( 'route_name' => $this->mapper->getOverviewRoute(), diff --git a/core/modules/language/lib/Drupal/language/Form/ContentLanguageSettingsForm.php b/core/modules/language/lib/Drupal/language/Form/ContentLanguageSettingsForm.php index 6cd8514..7162eea 100644 --- a/core/modules/language/lib/Drupal/language/Form/ContentLanguageSettingsForm.php +++ b/core/modules/language/lib/Drupal/language/Form/ContentLanguageSettingsForm.php @@ -8,7 +8,6 @@ namespace Drupal\language\Form; use Drupal\Core\Config\ConfigFactory; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Form\ConfigFormBase; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -30,13 +29,11 @@ class ContentLanguageSettingsForm extends ConfigFormBase { * * @param \Drupal\Core\Config\ConfigFactory $config_factory * The config factory. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context to use. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context, EntityManagerInterface $entity_manager) { - parent::__construct($config_factory, $context); + public function __construct(ConfigFactory $config_factory, EntityManagerInterface $entity_manager) { + parent::__construct($config_factory); $this->entityManager = $entity_manager; } @@ -47,7 +44,6 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('config.context.free'), $container->get('entity.manager') ); } diff --git a/core/modules/language/lib/Drupal/language/Form/NegotiationBrowserForm.php b/core/modules/language/lib/Drupal/language/Form/NegotiationBrowserForm.php index 2271b14..0537a6a 100644 --- a/core/modules/language/lib/Drupal/language/Form/NegotiationBrowserForm.php +++ b/core/modules/language/lib/Drupal/language/Form/NegotiationBrowserForm.php @@ -8,7 +8,6 @@ namespace Drupal\language\Form; use Drupal\Core\Config\ConfigFactory; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\ConfigFormBase; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -31,8 +30,8 @@ class NegotiationBrowserForm extends ConfigFormBase { * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context, ModuleHandlerInterface $module_handler) { - parent::__construct($config_factory, $context); + public function __construct(ConfigFactory $config_factory, ModuleHandlerInterface $module_handler) { + parent::__construct($config_factory); $this->moduleHandler = $module_handler; } @@ -42,7 +41,6 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('config.context.free'), $container->get('module_handler') ); } @@ -196,5 +194,5 @@ protected function language_get_browser_drupal_langcode_mappings() { } return $config->get(); } - } + diff --git a/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php b/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php index 11fa899..4cfe5dd 100644 --- a/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php +++ b/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php @@ -6,10 +6,7 @@ namespace Drupal\locale; -use Drupal\Core\Config\Config; -use Drupal\Core\Config\Context\ConfigContext; -use Drupal\Core\Config\Context\ContextInterface; -use Drupal\Core\Config\ConfigEvent; +use Drupal\Core\Config\ConfigFactory; use Drupal\Core\Config\StorageDispatcher; use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageManager; @@ -18,7 +15,6 @@ use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; - /** * Locale Config helper * @@ -34,80 +30,28 @@ class LocaleConfigSubscriber implements EventSubscriberInterface { protected $languageManager; /** - * Default configuration context. - * - * @var \Drupal\Core\Config\Context\ContextInterface - */ - protected $defaultConfigContext; - - /** * Constructs a LocaleConfigSubscriber object. * * @param \Drupal\Core\Language\LanguageManager $language_manager * The language manager service. - * @param \Drupal\Core\Config\Context\ConfigContext $config_context - * The configuration context service. + * @param \Drupal\Core\Config\ConfigFactory $config_factory + * The configuration object factory. */ - public function __construct(LanguageManager $language_manager, ContextInterface $config_context) { + public function __construct(LanguageManager $language_manager, ConfigFactory $config_factory) { $this->languageManager = $language_manager; - $this->defaultConfigContext = $config_context; - } - - /** - * Initializes configuration context with language. - * - * @param \Drupal\Core\Config\ConfigEvent $event - * The Event to process. - */ - public function configContext(ConfigEvent $event) { - $context = $event->getContext(); - - // If there is a language set explicitly in the current context, use it. - // Otherwise check if there is a user set in the current context, - // to set the language based on the preferred language of the user. - // Otherwise set it based on the negotiated interface language. - if ($language = $context->get('language')) { - $context->set('locale.language', $language); - } - elseif ($account = $context->get('user.account')) { - $context->set('locale.language', language_load($account->getPreferredLangcode())); - } - elseif ($language = $this->languageManager->getLanguage(Language::TYPE_INTERFACE)) { - $context->set('locale.language', $language); - } + $this->configFactory = $config_factory; } /** - * Override configuration values with localized data. - * - * @param \Drupal\Core\Config\ConfigEvent $event - * The Event to process. - */ - public function configLoad(ConfigEvent $event) { - $context = $event->getContext(); - if ($language = $context->get('locale.language')) { - $config = $event->getConfig(); - $locale_name = $this->getLocaleConfigName($config->getName(), $language); - // Check to see if the config storage has an appropriately named file - // containing override data. - if ($override = $event->getConfig()->getStorage()->read($locale_name)) { - $config->setOverride($override); - } - } - } - - /** - * Sets the negotiated interface language on the default configuration context. + * Sets the negotiated interface language on the configuration factory. * * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event * Kernel event to respond to. */ - public function onKernelRequestSetDefaultConfigContextLocale(GetResponseEvent $event) { - // Re-initialize the default configuration context to ensure any cached - // configuration object are reset and can be translated. This will invoke - // the config context event which will retrieve the negotiated language - // from the language manager in configContext(). - $this->defaultConfigContext->init(); + public function onKernelRequestSetDefaultConfigLanguage(GetResponseEvent $event) { + if ($this->languageManager->isMultiLingual()) { + $this->configFactory->setLanguage($this->languageManager->getLanguage()); + } } /** @@ -132,11 +76,8 @@ public function getLocaleConfigName($name, Language $language) { * Implements EventSubscriberInterface::getSubscribedEvents(). */ static function getSubscribedEvents() { - $events['config.context'][] = array('configContext', 20); - $events['config.load'][] = array('configLoad', 20); - // Set the priority above the one from the RouteListener (priority 32) - // so ensure that the context is cleared before the routing system steps in. - $events[KernelEvents::REQUEST][] = array('onKernelRequestSetDefaultConfigContextLocale', 48); + $events[KernelEvents::REQUEST][] = array('onKernelRequestSetDefaultConfigLanguage', 48); return $events; } } + diff --git a/core/modules/locale/lib/Drupal/locale/ParamConverter/LocaleAdminPathConfigEntityConverter.php b/core/modules/locale/lib/Drupal/locale/ParamConverter/LocaleAdminPathConfigEntityConverter.php index 1be24be..6488eb4 100644 --- a/core/modules/locale/lib/Drupal/locale/ParamConverter/LocaleAdminPathConfigEntityConverter.php +++ b/core/modules/locale/lib/Drupal/locale/ParamConverter/LocaleAdminPathConfigEntityConverter.php @@ -9,6 +9,8 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Route; +use Drupal\Core\Config\ConfigFactory; +use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\ParamConverter\EntityConverter; use Drupal\Core\ParamConverter\ParamConverterInterface; @@ -29,17 +31,33 @@ class LocaleAdminPathConfigEntityConverter extends EntityConverter { /** + * The config factory. + * + * @var \Drupal\Core\Config\ConfigFactory + */ + protected $configFactory; + + /** + * Constructs a new EntityConverter. + * + * @param \Drupal\Core\Entity\EntityManagerInterface $entityManager + * The entity manager. + */ + public function __construct(EntityManagerInterface $entity_manager, ConfigFactory $config_factory) { + $this->configFactory = $config_factory; + parent::__construct($entity_manager); + } + + /** * {@inheritdoc} */ public function convert($value, $definition, $name, array $defaults, Request $request) { $entity_type = substr($definition['type'], strlen('entity:')); if ($storage = $this->entityManager->getStorageController($entity_type)) { - // Enter the override-free context, so we can ensure no overrides are - // applied. - config_context_enter('config.context.free'); + // Make sure no overrides are loaded. + $this->configFactory->disableOverrides(); $entity = $storage->load($value); - // Leave the override-free context. - config_context_leave(); + $this->configFactory->enableOverrides(); return $entity; } } diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php index 0970b9c..c797133 100644 --- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php @@ -89,7 +89,6 @@ function testConfigTranslation() { $translation = $wrapper->getTranslation($langcode); $properties = $translation->getProperties(); $this->assertEqual(count($properties), 1, 'Got the right number of properties after translation'); -// $this->assertEqual($properties['name']->getValue(), $site_name, 'Got the right translation for site name after translation'); // Check the translated site name is displayed. $this->drupalGet($langcode); diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationUiTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationUiTest.php index d02f763..5c67d4e 100644 --- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationUiTest.php +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationUiTest.php @@ -109,7 +109,8 @@ function testStringTranslation() { ); $this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations')); $this->assertText(t('The strings have been saved.'), 'The strings have been saved.'); - $this->assertEqual($this->getUrl(), url('admin/config/regional/translate', array('absolute' => TRUE)), 'Correct page redirection.'); + $url_bits = explode('?', $this->getUrl()); + $this->assertEqual($url_bits[0], url('admin/config/regional/translate', array('absolute' => TRUE)), 'Correct page redirection.'); $search = array( 'string' => $name, 'langcode' => $langcode, diff --git a/core/modules/locale/locale.services.yml b/core/modules/locale/locale.services.yml index f831989..4d5792c 100644 --- a/core/modules/locale/locale.services.yml +++ b/core/modules/locale/locale.services.yml @@ -3,12 +3,12 @@ services: class: Drupal\locale\LocaleConfigSubscriber tags: - { name: event_subscriber } - arguments: ['@language_manager', '@config.context'] + arguments: ['@language_manager', '@config.factory'] paramconverter.configentity_admin: class: Drupal\locale\ParamConverter\LocaleAdminPathConfigEntityConverter tags: - { name: paramconverter, priority: 5 } - arguments: ['@entity.manager'] + arguments: ['@entity.manager', '@config.factory'] locale.config.typed: class: Drupal\locale\LocaleConfigManager arguments: ['@config.storage', '@config.storage.schema', '@config.storage.installer', '@locale.storage'] diff --git a/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php b/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php index 0d3e115..d0acb03 100644 --- a/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php +++ b/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php @@ -8,7 +8,6 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Config\ConfigFactory; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\KeyValueStore\StateInterface; use Drupal\Core\Plugin\PluginFormInterface; @@ -54,8 +53,6 @@ class SearchSettingsForm extends ConfigFormBase { * * @param \Drupal\Core\Config\ConfigFactory $config_factory * The configuration factory object that manages search settings. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The context interface * @param \Drupal\search\SearchPluginManager $manager * The manager for search plugins. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler @@ -63,8 +60,8 @@ class SearchSettingsForm extends ConfigFormBase { * @param \Drupal\Core\KeyValueStore\StateInterface $state * The state key/value store interface, gives access to state based config settings. */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context, SearchPluginManager $manager, ModuleHandlerInterface $module_handler, StateInterface $state) { - parent::__construct($config_factory, $context); + public function __construct(ConfigFactory $config_factory, SearchPluginManager $manager, ModuleHandlerInterface $module_handler, StateInterface $state) { + parent::__construct($config_factory); $this->searchSettings = $config_factory->get('search.settings'); $this->searchPluginManager = $manager; $this->moduleHandler = $module_handler; @@ -77,7 +74,6 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('config.context.free'), $container->get('plugin.manager.search'), $container->get('module_handler'), $container->get('state') diff --git a/core/modules/simpletest/simpletest.theme.inc b/core/modules/simpletest/simpletest.theme.inc index 4ee0261..1743b74 100644 --- a/core/modules/simpletest/simpletest.theme.inc +++ b/core/modules/simpletest/simpletest.theme.inc @@ -132,7 +132,12 @@ function theme_simpletest_test_table($variables) { } // Add js array of settings. - drupal_add_js(array('simpleTest' => $js), 'setting'); + $attached = array(); + $attached['#attached']['js'][] = array( + 'data' => array('simpleTest' => $js), + 'type' => 'setting', + ); + drupal_render($attached); if (empty($rows)) { return '' . t('No tests to display.') . ''; diff --git a/core/modules/statistics/lib/Drupal/statistics/StatisticsSettingsForm.php b/core/modules/statistics/lib/Drupal/statistics/StatisticsSettingsForm.php index e8646cd..2f4d9f7 100644 --- a/core/modules/statistics/lib/Drupal/statistics/StatisticsSettingsForm.php +++ b/core/modules/statistics/lib/Drupal/statistics/StatisticsSettingsForm.php @@ -6,7 +6,6 @@ namespace Drupal\statistics; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Config\ConfigFactory; @@ -29,13 +28,11 @@ class StatisticsSettingsForm extends ConfigFormBase { * * @param \Drupal\Core\Config\ConfigFactory $config_factory * The factory for configuration objects. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context to use. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler. */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context, ModuleHandlerInterface $module_handler) { - parent::__construct($config_factory, $context); + public function __construct(ConfigFactory $config_factory, ModuleHandlerInterface $module_handler) { + parent::__construct($config_factory); $this->moduleHandler = $module_handler; } @@ -46,7 +43,6 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('config.context.free'), $container->get('module_handler') ); } @@ -95,5 +91,5 @@ public function submitForm(array &$form, array &$form_state) { parent::submitForm($form, $form_state); } - } + diff --git a/core/modules/system/lib/Drupal/system/Form/CronForm.php b/core/modules/system/lib/Drupal/system/Form/CronForm.php index 5d94762..6a070e0 100644 --- a/core/modules/system/lib/Drupal/system/Form/CronForm.php +++ b/core/modules/system/lib/Drupal/system/Form/CronForm.php @@ -8,7 +8,6 @@ namespace Drupal\system\Form; use Drupal\Core\Config\ConfigFactory; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\KeyValueStore\StateInterface; use Drupal\Core\Form\ConfigFormBase; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -31,13 +30,11 @@ class CronForm extends ConfigFormBase { * * @param \Drupal\Core\Config\ConfigFactory $config_factory * The factory for configuration objects. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context used for this configuration object. * @param \Drupal\Core\KeyValueStore\StateInterface $state - * The state key value store. + * The state keyvalue collection to use. */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context, StateInterface $state) { - parent::__construct($config_factory, $context); + public function __construct(ConfigFactory $config_factory, StateInterface $state) { + parent::__construct($config_factory); $this->state = $state; } @@ -47,7 +44,6 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('config.context.free'), $container->get('state') ); } diff --git a/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php b/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php index 6e3ebeb..0b6beaa 100644 --- a/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php +++ b/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php @@ -8,7 +8,6 @@ namespace Drupal\system\Form; use Drupal\Core\Config\ConfigFactory; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\ImageToolkit\ImageToolkitManager; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -30,13 +29,11 @@ class ImageToolkitForm extends ConfigFormBase { * * @param \Drupal\Core\Config\ConfigFactory $config_factory * The factory for configuration objects. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context used for this configuration object. * @param \Drupal\Core\ImageToolkit\ImageToolkitManager $manager * The image toolkit plugin manager. */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context, ImageToolkitManager $manager) { - parent::__construct($config_factory, $context); + public function __construct(ConfigFactory $config_factory, ImageToolkitManager $manager) { + parent::__construct($config_factory); foreach ($manager->getAvailableToolkits() as $id => $definition) { $this->availableToolkits[$id] = $manager->createInstance($id); @@ -49,7 +46,6 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('config.context.free'), $container->get('image.toolkit.manager') ); } diff --git a/core/modules/system/lib/Drupal/system/Form/PerformanceForm.php b/core/modules/system/lib/Drupal/system/Form/PerformanceForm.php index f596078..cc114bf 100644 --- a/core/modules/system/lib/Drupal/system/Form/PerformanceForm.php +++ b/core/modules/system/lib/Drupal/system/Form/PerformanceForm.php @@ -9,7 +9,6 @@ use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Config\ConfigFactory; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Cache\CacheBackendInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -30,12 +29,10 @@ class PerformanceForm extends ConfigFormBase { * * @param \Drupal\Core\Config\ConfigFactory $config_factory * The factory for configuration objects. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context used for this configuration object. * @param \Drupal\Core\Cache\CacheBackendInterface $page_cache */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context, CacheBackendInterface $page_cache) { - parent::__construct($config_factory, $context); + public function __construct(ConfigFactory $config_factory, CacheBackendInterface $page_cache) { + parent::__construct($config_factory); $this->pageCache = $page_cache; } @@ -46,7 +43,6 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('config.context.free'), $container->get('cache.page') ); } diff --git a/core/modules/system/lib/Drupal/system/Form/RegionalForm.php b/core/modules/system/lib/Drupal/system/Form/RegionalForm.php index a75ff7f..2ca6acf 100644 --- a/core/modules/system/lib/Drupal/system/Form/RegionalForm.php +++ b/core/modules/system/lib/Drupal/system/Form/RegionalForm.php @@ -8,7 +8,6 @@ namespace Drupal\system\Form; use Drupal\Core\Config\ConfigFactory; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Locale\CountryManagerInterface; use Drupal\Core\Form\ConfigFormBase; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -30,13 +29,11 @@ class RegionalForm extends ConfigFormBase { * * @param \Drupal\Core\Config\ConfigFactory $config_factory * The factory for configuration objects. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context used for this configuration object. * @param \Drupal\Core\Locale\CountryManagerInterface $country_manager * The country manager. */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context, CountryManagerInterface $country_manager) { - parent::__construct($config_factory, $context); + public function __construct(ConfigFactory $config_factory, CountryManagerInterface $country_manager) { + parent::__construct($config_factory); $this->countryManager = $country_manager; } @@ -46,7 +43,6 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('config.context.free'), $container->get('country_manager') ); } diff --git a/core/modules/system/lib/Drupal/system/Form/SiteInformationForm.php b/core/modules/system/lib/Drupal/system/Form/SiteInformationForm.php index 34e3584..aca83c3 100644 --- a/core/modules/system/lib/Drupal/system/Form/SiteInformationForm.php +++ b/core/modules/system/lib/Drupal/system/Form/SiteInformationForm.php @@ -8,7 +8,6 @@ namespace Drupal\system\Form; use Drupal\Core\Config\ConfigFactory; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Path\AliasManagerInterface; use Drupal\Core\Form\ConfigFormBase; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -30,13 +29,11 @@ class SiteInformationForm extends ConfigFormBase { * * @param \Drupal\Core\Config\ConfigFactory $config_factory * The factory for configuration objects. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context used for this configuration object. * @param \Drupal\Core\Path\AliasManagerInterface $alias_manager * The path alias manager. */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context, AliasManagerInterface $alias_manager) { - parent::__construct($config_factory, $context); + public function __construct(ConfigFactory $config_factory, AliasManagerInterface $alias_manager) { + parent::__construct($config_factory); $this->aliasManager = $alias_manager; } @@ -47,7 +44,6 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('config.context.free'), $container->get('path.alias_manager') ); } diff --git a/core/modules/system/lib/Drupal/system/Form/SiteMaintenanceModeForm.php b/core/modules/system/lib/Drupal/system/Form/SiteMaintenanceModeForm.php index 693dc28..535ecfd 100644 --- a/core/modules/system/lib/Drupal/system/Form/SiteMaintenanceModeForm.php +++ b/core/modules/system/lib/Drupal/system/Form/SiteMaintenanceModeForm.php @@ -8,7 +8,6 @@ namespace Drupal\system\Form; use Drupal\Core\Config\ConfigFactory; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\KeyValueStore\StateInterface; use Drupal\Core\Form\ConfigFormBase; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -30,13 +29,11 @@ class SiteMaintenanceModeForm extends ConfigFormBase { * * @param \Drupal\Core\Config\ConfigFactory $config_factory * The factory for configuration objects. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context to use. * @param \Drupal\Core\KeyValueStore\StateInterface $state * The state keyvalue collection to use. */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context, StateInterface $state) { - parent::__construct($config_factory, $context); + public function __construct(ConfigFactory $config_factory, StateInterface $state) { + parent::__construct($config_factory); $this->state = $state; } @@ -46,7 +43,6 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('config.context.free'), $container->get('state') ); } diff --git a/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php b/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php index ec76227..dc1490a 100644 --- a/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php +++ b/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php @@ -12,7 +12,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Drupal\Core\Cache\Cache; use Drupal\Core\Config\ConfigFactory; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\ConfigFormBase; @@ -33,13 +32,11 @@ class ThemeSettingsForm extends ConfigFormBase { * * @param \Drupal\Core\Config\ConfigFactory $config_factory * The factory for configuration objects. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context to use. * @param \Drupal\Core\Extension\ModuleHandlerInterface * The module handler instance to use. */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context, ModuleHandlerInterface $module_handler) { - parent::__construct($config_factory, $context); + public function __construct(ConfigFactory $config_factory, ModuleHandlerInterface $module_handler) { + parent::__construct($config_factory); $this->moduleHandler = $module_handler; } @@ -50,7 +47,6 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('config.context.free'), $container->get('module_handler') ); } diff --git a/core/modules/system/lib/Drupal/system/SystemConfigSubscriber.php b/core/modules/system/lib/Drupal/system/SystemConfigSubscriber.php index f9965f9..237473a 100644 --- a/core/modules/system/lib/Drupal/system/SystemConfigSubscriber.php +++ b/core/modules/system/lib/Drupal/system/SystemConfigSubscriber.php @@ -9,8 +9,6 @@ use Drupal\Core\Config\Config; use Drupal\Core\Config\ConfigImporterEvent; use Drupal\Core\Config\ConfigImporterException; -use Drupal\Core\Config\Context\ConfigContext; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Config\ConfigEvent; use Drupal\Core\Config\StorageDispatcher; use Symfony\Component\EventDispatcher\EventSubscriberInterface; diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php index 3a11ccc..3f584aa 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php @@ -37,6 +37,9 @@ public static function getInfo() { function setUp() { parent::setUp(); + // There are dependencies in drupal_get_js() on the theme layer so we need + // to initialize it. + drupal_theme_initialize(); // Disable preprocessing $config = \Drupal::config('system.performance'); diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php index f3985e0..12d02b0 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php @@ -29,6 +29,13 @@ public static function getInfo() { ); } + function setUp() { + parent::setUp(); + // There are dependencies in drupal_get_js() on the theme layer so we need + // to initialize it. + drupal_theme_initialize(); + } + /** * Tests the output drupal_render() for some elementary input values. */ diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterRebuildTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterRebuildTest.php index 849c1ef..7cb4df5 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterRebuildTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterRebuildTest.php @@ -48,8 +48,7 @@ function setUp() { */ public function testMenuRouterRebuildContext() { // Enter a language context before rebuilding the menu router tables. - $language_context = config_context_enter('Drupal\Core\Config\Context\LanguageConfigContext'); - $language_context->setLanguage(language_load('nl')); + \Drupal::configFactory()->setLanguage(language_load('nl')); menu_router_rebuild(); // Check that the language context was not used for building the menu item. diff --git a/core/modules/system/system.module b/core/modules/system/system.module index d922cd9..c68117b 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -419,7 +419,7 @@ function system_element_info() { ); $types['password_confirm'] = array( '#input' => TRUE, - '#process' => array('form_process_password_confirm', 'user_form_process_password_confirm'), + '#process' => array('form_process_password_confirm'), '#theme_wrappers' => array('form_element'), ); $types['textarea'] = array( diff --git a/core/modules/system/tests/modules/test_page_test/test_page_test.module b/core/modules/system/tests/modules/test_page_test/test_page_test.module index 5911afb..7933a85 100644 --- a/core/modules/system/tests/modules/test_page_test/test_page_test.module +++ b/core/modules/system/tests/modules/test_page_test/test_page_test.module @@ -18,9 +18,13 @@ function test_page_test_menu() { * @deprecated Use \Drupal\test_page_test\Controller\TestPageTestController::testPage() */ function test_page_test_page() { - drupal_add_js(array('test-setting' => 'azAZ09();.,\\\/-_{}'), array('type' => 'setting')); + $attached['js'][] = array( + 'data' => array('test-setting' => 'azAZ09();.,\\\/-_{}'), + 'type' => 'setting', + ); return array( '#title' => t('Test page'), '#markup' => t('Test page text.'), + '#attached' => $attached, ); } diff --git a/core/modules/user/lib/Drupal/user/AccountFormController.php b/core/modules/user/lib/Drupal/user/AccountFormController.php index 4983b0f..eca2eb2 100644 --- a/core/modules/user/lib/Drupal/user/AccountFormController.php +++ b/core/modules/user/lib/Drupal/user/AccountFormController.php @@ -99,6 +99,7 @@ public function form(array $form, array &$form_state) { '#type' => 'password_confirm', '#size' => 25, '#description' => $this->t('To change the current user password, enter the new password in both fields.'), + '#pre_render' => array('user_form_pre_render_password_confirm'), ); // To skip the current password field, the user must have logged in via a @@ -146,6 +147,7 @@ public function form(array $form, array &$form_state) { '#type' => 'password_confirm', '#size' => 25, '#description' => $this->t('Provide a password for the new account in both fields.'), + '#pre_render' => array('user_form_pre_render_password_confirm'), '#required' => TRUE, ); } diff --git a/core/modules/user/lib/Drupal/user/AccountSettingsForm.php b/core/modules/user/lib/Drupal/user/AccountSettingsForm.php index ace1834..20ae102 100644 --- a/core/modules/user/lib/Drupal/user/AccountSettingsForm.php +++ b/core/modules/user/lib/Drupal/user/AccountSettingsForm.php @@ -9,7 +9,6 @@ use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Config\ConfigFactory; -use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Extension\ModuleHandler; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -30,13 +29,11 @@ class AccountSettingsForm extends ConfigFormBase { * * @param \Drupal\Core\Config\ConfigFactory $config_factory * The factory for configuration objects. - * @param \Drupal\Core\Config\Context\ContextInterface $context - * The configuration context. * @param \Drupal\Core\Extension\ModuleHandler $module_handler * The module handler. */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context, ModuleHandler $module_handler) { - parent::__construct($config_factory, $context); + public function __construct(ConfigFactory $config_factory, ModuleHandler $module_handler) { + parent::__construct($config_factory); $this->moduleHandler = $module_handler; } @@ -46,7 +43,6 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('config.context.free'), $container->get('module_handler') ); } diff --git a/core/modules/user/lib/Drupal/user/UserConfigContext.php b/core/modules/user/lib/Drupal/user/UserConfigContext.php deleted file mode 100644 index 1d5f497..0000000 --- a/core/modules/user/lib/Drupal/user/UserConfigContext.php +++ /dev/null @@ -1,45 +0,0 @@ -set(self::USER_KEY, $account); - // Re-initialize since the user change changes the context fundamentally. - $this->init(); - return $this; - } - -} diff --git a/core/modules/user/user.module b/core/modules/user/user.module index f6a30cb..2d134be 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -1339,12 +1339,10 @@ function user_mail($key, &$message, $params) { $langcode = $message['langcode']; $variables = array('user' => $params['account']); - // Get configuration objects customized for the user specified in $params as - // this user is not necessarily the same as the one triggering the mail. This - // allows the configuration objects to be localized for the user's language if - // the locale module is enabled. - $user_config_context = config_context_enter('Drupal\user\UserConfigContext'); - $user_config_context->setAccount($params['account']); + $original_language = \Drupal::configFactory()->getLanguage(); + + $language = language_load($params['account']->getPreferredLangcode()); + \Drupal::configFactory()->setLanguage($language); $mail_config = \Drupal::config('user.mail'); // We do not sanitize the token replacement, since the output of this @@ -1353,8 +1351,7 @@ function user_mail($key, &$message, $params) { $message['subject'] .= $token_service->replace($mail_config->get($key . '.subject'), $variables, $token_options); $message['body'][] = $token_service->replace($mail_config->get($key . '.body'), $variables, $token_options); - // Return the previous config context. - config_context_leave(); + \Drupal::configFactory()->setLanguage($original_language); } /** @@ -1699,13 +1696,10 @@ function _user_mail_notify($op, $account, $langcode = NULL) { /** * Form element process handler for client-side password validation. * - * This #process handler is automatically invoked for 'password_confirm' form - * elements to add the JavaScript and string translations for dynamic password - * validation. - * - * @see system_element_info() + * This #pre_render handler is added to the user registration form to add the + * JavaScript and string translations for dynamic password validation. */ -function user_form_process_password_confirm($element) { +function user_form_pre_render_password_confirm($element) { $password_settings = array( 'confirmTitle' => t('Passwords match:'), 'confirmSuccess' => t('yes'), diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php index 7915204..ddcc1fa 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php @@ -7,6 +7,7 @@ namespace Drupal\views\Plugin\views\display; +use Drupal\Component\Utility\String; use Drupal\views\ViewExecutable; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -86,11 +87,17 @@ public function execute() { * Overrides \Drupal\views\Plugin\views\display\PathPluginBase::preview(). */ public function preview() { + $output = $this->view->render(); + if (!empty($this->view->live_preview)) { - return '
' . check_plain($this->view->render()) . '
'; + $output = array( + '#prefix' => '
',
+        '#markup' => String::checkPlain($output),
+        '#suffix' => '
', + ); } - return $this->view->render(); + return $output; } /** diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Tests/PreviewTest.php b/core/modules/views_ui/lib/Drupal/views_ui/Tests/PreviewTest.php index 7f13413..77cc434 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/Tests/PreviewTest.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/Tests/PreviewTest.php @@ -77,6 +77,21 @@ function testPreviewUI() { $this->assertText('Test header text', 'Rendered header text found'); $this->assertText('Test footer text', 'Rendered footer text found.'); $this->assertText('Test empty text', 'Rendered empty text found.'); + + // Test feed preview. + $view = array(); + $view['label'] = $this->randomName(16); + $view['id'] = strtolower($this->randomName(16)); + $view['page[create]'] = 1; + $view['page[title]'] = $this->randomName(16); + $view['page[path]'] = $this->randomName(16); + $view['page[feed]'] = 1; + $view['page[feed_properties][path]'] = $this->randomName(16); + $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); + $this->clickLink(t('Feed')); + $this->drupalPostForm(NULL, array(), t('Update preview')); + $result = $this->xpath('//div[@id="views-live-preview"]/pre'); + $this->assertTrue(strpos($result[0], '' . $view['page[title]'] . ''), 'The Feed RSS preview was rendered.'); } /** diff --git a/core/tests/Drupal/Tests/Component/Utility/CryptTest.php b/core/tests/Drupal/Tests/Component/Utility/CryptTest.php index 9bde39f..ee0d602 100644 --- a/core/tests/Drupal/Tests/Component/Utility/CryptTest.php +++ b/core/tests/Drupal/Tests/Component/Utility/CryptTest.php @@ -73,6 +73,21 @@ public function testHmacBase64($data, $key, $expected_hmac) { } /** + * Tests the hmacBase64 method with invalid parameters. + * + * @param string $data + * Data to hash. + * @param string $key + * Key to use in hashing process. + * + * @dataProvider providerTestHmacBase64Invalid + * @expectedException InvalidArgumentException + */ + public function testHmacBase64Invalid($data, $key) { + Crypt::hmacBase64($data, $key); + } + + /** * Provides data for self::testHashBase64(). * * @return array Test data. @@ -105,4 +120,39 @@ public function providerTestHmacBase64() { ); } + /** + * Provides data for self::testHmacBase64(). + * + * @return array Test data. + */ + public function providerTestHmacBase64Invalid() { + return array( + array(new \stdClass(), new \stdClass()), + array(new \stdClass(), 'string'), + array(new \stdClass(), 1), + array(new \stdClass(), 0), + array(NULL, new \stdClass()), + array('string', new \stdClass()), + array(1, new \stdClass()), + array(0, new \stdClass()), + array(array(), array()), + array(array(), NULL), + array(array(), 'string'), + array(array(), 1), + array(array(), 0), + array(NULL, array()), + array(1, array()), + array(0, array()), + array('string', array()), + array(array(), NULL), + array(NULL, NULL), + array(NULL, 'string'), + array(NULL, 1), + array(NULL, 0), + array(1, NULL), + array(0, NULL), + array('string', NULL), + ); + } + } diff --git a/core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php b/core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php index 0db8f21..3a6d75c 100644 --- a/core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php +++ b/core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php @@ -97,33 +97,58 @@ public function testValidate() { * The token to be validated. * @param mixed $value * (optional) An additional value to base the token on. - * @param mixed $expected - * (optional) The expected result of validate(). Defaults to FALSE. * * @dataProvider providerTestValidateParameterTypes */ - public function testValidateParameterTypes($token, $value = '', $expected = FALSE) { + public function testValidateParameterTypes($token, $value) { // The following check might throw PHP fatals and notices, so we disable // error assertions. set_error_handler(function () {return TRUE;}); - $this->assertSame($expected, $this->generator->validate($token, $value)); + $this->assertFalse($this->generator->validate($token, $value)); restore_error_handler(); } /** - * Provides data for the validate test. + * Provides data for testValidateParameterTypes. * * @return array * An array of data used by the test. */ public function providerTestValidateParameterTypes() { return array( + array(array(), ''), + array(TRUE, 'foo'), + array(0, 'foo'), + ); + } + + /** + * Tests CsrfTokenGenerator::validate() with invalid parameter types. + * + * @param mixed $token + * The token to be validated. + * @param mixed $value + * (optional) An additional value to base the token on. + * + * @dataProvider providerTestInvalidParameterTypes + * @expectedException InvalidArgumentException + */ + public function testInvalidParameterTypes($token, $value = '') { + $this->generator->validate($token, $value); + } + + /** + * Provides data for testInvalidParameterTypes. + * + * @return array + * An array of data used by the test. + */ + public function providerTestInvalidParameterTypes() { + return array( array(NULL, new \stdClass()), array(0, array()), array('', array()), - array(array()), - array(TRUE, 'foo'), - array(0, 'foo'), + array(array(), array()), ); } diff --git a/core/tests/Drupal/Tests/Core/Datetime/DateTest.php b/core/tests/Drupal/Tests/Core/Datetime/DateTest.php index 32d2103..55f2471 100644 --- a/core/tests/Drupal/Tests/Core/Datetime/DateTest.php +++ b/core/tests/Drupal/Tests/Core/Datetime/DateTest.php @@ -65,7 +65,7 @@ protected function setUp() { ->getMock(); $this->stringTranslation = $this->getMock('Drupal\Core\StringTranslation\TranslationInterface'); - $this->date = new Date($this->entityManager, $this->languageManager, $this->stringTranslation); + $this->date = new Date($this->entityManager, $this->languageManager, $this->stringTranslation, $this->getConfigFactoryStub()); } /**