diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index e26cb36..8155337 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -2458,9 +2458,13 @@ function drupal_container(Container $reset = NULL) { $container->register('config.storage', 'Drupal\Core\Config\DatabaseStorage') ->addArgument('%config.storage.options%'); + $container->register('config.subscriber.globalconf', 'Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber'); + $container->register('dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher') + ->addMethodCall('addSubscriber', array(new Reference('config.subscriber.globalconf'))); // Register configuration object factory. $container->register('config.factory', 'Drupal\Core\Config\ConfigFactory') - ->addArgument(new Reference('config.storage')); + ->addArgument(new Reference('config.storage')) + ->addArgument(new Reference('dispatcher')); } return $container; } diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php index 10bf925..8040daf 100644 --- a/core/lib/Drupal/Core/Config/Config.php +++ b/core/lib/Drupal/Core/Config/Config.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Config; use Drupal\Component\Utility\NestedArray; +use Symfony\Component\EventDispatcher\EventDispatcher; /** * Defines the default configuration object. @@ -50,13 +51,20 @@ class Config { protected $overriddenData; /** - * The storage used for reading and writing. + * The storage used to load and save this configuration object. * * @var Drupal\Core\Config\StorageInterface */ protected $storage; /** + * The event dispatcher used to notify subscribers. + * + * @var Symfony\Component\EventDispatcher\EventDispatcher + */ + protected $eventDispatcher; + + /** * Constructs a configuration object. * * @param string $name @@ -64,10 +72,21 @@ class Config { * @param Drupal\Core\Config\StorageInterface $storage * A storage controller object to use for reading and writing the * configuration data. + * @param Symfony\Component\EventDispatcher\EventDispatcher $event_dispatcher + * The event dispatcher used to notify subscribers. */ - public function __construct($name, StorageInterface $storage) { + public function __construct($name, StorageInterface $storage, EventDispatcher $event_dispatcher = NULL) { $this->name = $name; $this->storage = $storage; + $this->eventDispatcher = $event_dispatcher ? $event_dispatcher : drupal_container()->get('dispatcher'); + } + + /** + * Initializes a configuration object. + */ + public function init() { + $this->notify('init'); + return $this; } /** @@ -283,6 +302,7 @@ class Config { $this->isNew = FALSE; $this->setData($data); } + $this->notify('load'); return $this; } @@ -293,6 +313,7 @@ class Config { $this->sortByKey($this->data); $this->storage->write($this->name, $this->data); $this->isNew = FALSE; + $this->notify('save'); return $this; } @@ -324,6 +345,21 @@ class Config { $this->storage->delete($this->name); $this->isNew = TRUE; $this->resetOverriddenData(); + $this->notify('delete'); return $this; } + + /** + * Retrieve the storage used to load and save this configuration object. + */ + public function getStorage() { + return $this->storage; + } + + /** + * Dispatch a config event. + */ + protected function notify($config_event_name) { + $this->eventDispatcher->dispatch('config.' . $config_event_name, new ConfigEvent($this)); + } } diff --git a/core/lib/Drupal/Core/Config/ConfigEvent.php b/core/lib/Drupal/Core/Config/ConfigEvent.php new file mode 100644 index 0000000..aabd1d8 --- /dev/null +++ b/core/lib/Drupal/Core/Config/ConfigEvent.php @@ -0,0 +1,29 @@ +config = $config; + } + + /** + * Get configuration object. + */ + public function getConfig() { + return $this->config; + } +} diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php index 4bf5b62..ca36ce7 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactory.php +++ b/core/lib/Drupal/Core/Config/ConfigFactory.php @@ -7,6 +7,8 @@ namespace Drupal\Core\Config; +use Symfony\Component\EventDispatcher\EventDispatcher; + /** * Defines the configuration object factory. * @@ -30,14 +32,24 @@ class ConfigFactory { protected $storage; /** + * An event dispatcher instance to use for configuration events. + * + * @var Symfony\Component\EventDispatcher\EventDispatcher + */ + protected $eventDispatcher; + + /** * Constructs the Config factory. * * @param Drupal\Core\Config\StorageInterface $storage * The storage controller object to use for reading and writing * configuration data. + * @param Symfony\Component\EventDispatcher\EventDispatcher + * An event dispatcher instance to use for configuration events. */ - public function __construct(StorageInterface $storage) { + public function __construct(StorageInterface $storage, EventDispatcher $event_dispatcher) { $this->storage = $storage; + $this->eventDispatcher = $event_dispatcher; } /** @@ -70,13 +82,8 @@ class ConfigFactory { // @todo The decrease of CPU time is interesting, since that means that // ContainerBuilder involves plenty of function calls (which are known to // be slow in PHP). - $config = new Config($name, $this->storage); - - // Set overridden values from global $conf, if any. - if (isset($conf[$name])) { - $config->setOverride($conf[$name]); - } - return $config; + $config = new Config($name, $this->storage, $this->eventDispatcher); + return $config->init(); } } diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php index b0830a0..f8e8691 100644 --- a/core/lib/Drupal/Core/CoreBundle.php +++ b/core/lib/Drupal/Core/CoreBundle.php @@ -58,6 +58,7 @@ class CoreBundle extends Bundle $dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\LegacyControllerSubscriber()); $dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\FinishResponseSubscriber()); $dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\RequestCloseSubscriber()); + $dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber()); $container->set('content_negotiation', $content_negotation); $dispatcher->addSubscriber(\Drupal\Core\ExceptionController::getExceptionListener($container)); /* @@ -85,6 +86,7 @@ class CoreBundle extends Bundle ->addTag('kernel.event_subscriber'); $container->register('request_close_subscriber', 'Drupal\Core\EventSubscriber\RequestCloseSubscriber') ->addTag('kernel.event_subscriber'); + $container->register('config_global_override_subscriber', '\Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber'); $container->register('database', 'Drupal\Core\Database\Connection') ->setFactoryClass('Drupal\Core\Database\Database') ->setFactoryMethod('getConnection') diff --git a/core/lib/Drupal/Core/EventSubscriber/ConfigGlobalOverrideSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ConfigGlobalOverrideSubscriber.php new file mode 100644 index 0000000..899edfb --- /dev/null +++ b/core/lib/Drupal/Core/EventSubscriber/ConfigGlobalOverrideSubscriber.php @@ -0,0 +1,39 @@ +getConfig(); + if (isset($conf[$config->getName()])) { + $config->setOverride($conf[$config->getName()]); + } + } + + /** + * Implements EventSubscriberInterface::getSubscribedEvents(). + */ + static function getSubscribedEvents() { + $events['config.init'][] = array('configInit', 30); + return $events; + } +} diff --git a/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php b/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php new file mode 100644 index 0000000..64e27cd --- /dev/null +++ b/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php @@ -0,0 +1,53 @@ +getConfig(); + $language = language(LANGUAGE_TYPE_INTERFACE); + $locale_name = $this->getLocaleConfigName($config->getName(), $language); + if ($override = $config->getStorage()->read($locale_name)) { + $config->setOverride($override); + } + } + + /** + * Get configuration name for this language. + * + * It will be the same name with a prefix depending on language code: + * locale.config.LANGCODE.NAME + */ + public function getLocaleConfigName($name, $language) { + return 'locale.config.' . $language->langcode . '.' . $name; + } + + /** + * Implements EventSubscriberInterface::getSubscribedEvents(). + */ + static function getSubscribedEvents() { + $events['config.load'][] = array('configLoad', 20); + return $events; + } +} diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module index f7c22c1..86f776c 100644 --- a/core/modules/locale/locale.module +++ b/core/modules/locale/locale.module @@ -12,6 +12,7 @@ */ use Drupal\locale\LocaleLookup; +use Drupal\locale\LocaleConfigSubscriber; /** * Regular expression pattern used to localize JavaScript strings. @@ -879,3 +880,11 @@ function _locale_rebuild_js($langcode = NULL) { return TRUE; } } + +/** + * Implements hook_language_init(). + */ +function locale_language_init() { + // Add locale helper to configuration subscribers. + drupal_container()->get('dispatcher')->addSubscriber(new LocaleConfigSubscriber()); +}