Commit d0518561 authored by catch's avatar catch

Issue #2215503 by Gábor Hojtsy, Wim Leers: Use services instead of event...

Issue #2215503 by Gábor Hojtsy, Wim Leers: Use services instead of event subscribers for config module overrides.
parent 1be69264
......@@ -34,13 +34,6 @@ final class ConfigEvents {
*/
const RENAME = 'config.rename';
/**
* Name of event fired when collecting overrides for configuration objects.
*
* @see \Drupal\Core\Config\ConfigFactory::loadModuleOverrides().
*/
const MODULE_OVERRIDES = 'config.module.overrides';
/**
* Name of event fired when validating in the configuration import process.
*
......
......@@ -10,6 +10,7 @@
use Drupal\Core\Language\Language;
use Drupal\Core\Language\LanguageDefault;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Drupal\Component\Utility\NestedArray;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
......@@ -70,6 +71,13 @@ class ConfigFactory implements ConfigFactoryInterface, EventSubscriberInterface
*/
protected $typedConfigManager;
/**
* An array of config factory override objects ordered by priority.
*
* @var \Drupal\Core\Config\ConfigFactoryOverrideInterface[]
*/
protected $configFactoryOverrides = array();
/**
* Constructs the Config factory.
*
......@@ -222,9 +230,13 @@ public function loadMultiple(array $names) {
* An array of overrides keyed by the configuration object name.
*/
protected function loadModuleOverrides(array $names) {
$configOverridesEvent = new ConfigModuleOverridesEvent($names, $this->language);
$this->eventDispatcher->dispatch(ConfigEvents::MODULE_OVERRIDES, $configOverridesEvent);
return $configOverridesEvent->getOverrides();
$overrides = array();
foreach ($this->configFactoryOverrides as $override) {
// Existing overrides take precedence since these will have been added
// by events with a higher priority.
$overrides = NestedArray::mergeDeepArray(array($override->loadOverrides($names), $overrides), TRUE);
}
return $overrides;
}
/**
......@@ -392,4 +404,11 @@ static function getSubscribedEvents() {
return $events;
}
/**
* {@inheritdoc}
*/
public function addOverride(ConfigFactoryOverrideInterface $config_factory_override) {
$this->configFactoryOverrides[] = $config_factory_override;
}
}
......@@ -191,4 +191,13 @@ public function getLanguageConfigName($langcode, $name);
*/
public function listAll($prefix = '');
/**
* Adds config factory override services.
*
* @param \Drupal\Core\Config\ConfigFactoryOverrideInterface $config_factory_override
* The config factory override service to add. It is added at the end of the
* priority list (lower priority relative to existing ones).
*/
public function addOverride(ConfigFactoryOverrideInterface $config_factory_override);
}
<?php
/**
* @file
* Contains \Drupal\Core\Config\ConfigFactoryOverrideInterface.
*/
namespace Drupal\Core\Config;
/**
* Defines the interface for a configuration factory override object.
*/
interface ConfigFactoryOverrideInterface {
/**
* Returns config overrides.
*
* @param array $names
* A list of configuration names that are being loaded.
*
* @return array
* An array keyed by configuration name of override data. Override data
* contains a nested array structure of overrides.
*/
public function loadOverrides($names);
}
<?php
/**
* @file
* Contains \Drupal\Core\Config\ConfigFactoryOverridePass.
*/
namespace Drupal\Core\Config;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* Adds services to the config factory service.
*
* @see \Drupal\Core\Config\ConfigFactory
* @see \Drupal\Core\Config\ConfigFactoryOverrideInterface
*/
class ConfigFactoryOverridePass implements CompilerPassInterface {
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container) {
$manager = $container->getDefinition('config.factory');
$services = array();
foreach ($container->findTaggedServiceIds('config.factory.override') as $id => $attributes) {
$priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
$services[] = array('id' => $id, 'priority' => $priority);
}
usort($services, array($this, 'compareServicePriorities'));
foreach ($services as $service) {
$manager->addMethodCall('addOverride', array(new Reference($service['id'])));
}
}
/**
* Compares services by priority for ordering.
*
* @param array $a
* Service to compare.
* @param array $b
* Service to compare.
*
* @return int
* Relative order of services to be used with usort. Higher priorities come
* first.
*/
private function compareServicePriorities($a, $b) {
if ($a['priority'] == $b['priority']) {
return 0;
}
return ($a['priority'] > $b['priority']) ? -1 : 1;
}
}
......@@ -8,6 +8,7 @@
namespace Drupal\Core;
use Drupal\Core\Cache\ListCacheBinsPass;
use Drupal\Core\Config\ConfigFactoryOverridePass;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\Compiler\ModifyServiceDefinitionsPass;
......@@ -78,6 +79,9 @@ public function register(ContainerBuilder $container) {
// Add the compiler pass that will process the tagged theme negotiator
// service.
$container->addCompilerPass(new ThemeNegotiatorPass());
// Add the compiler pass that will process the tagged config factory
// override services.
$container->addCompilerPass(new ConfigFactoryOverridePass());
// Add the compiler pass that will process tagged authentication services.
$container->addCompilerPass(new RegisterAuthenticationPass());
// Register Twig extensions.
......
services:
config_override_config_subscriber:
class: Drupal\config_override\EventSubscriber\ConfigModuleOverrideSubscriber
config_override.overrider:
class: Drupal\config_override\ConfigOverrider
tags:
- { name: event_subscriber }
config_override_low_priority_config_subscriber:
class: Drupal\config_override\EventSubscriber\ConfigModuleLowPriorityOverrideSubscriber
- { name: config.factory.override}
config_override.low_priority_overrider:
class: Drupal\config_override\ConfigOverriderLowPriority
tags:
- { name: event_subscriber }
- { name: config.factory.override, priority: -100 }
<?Php
<?php
/**
* @file
* Contains \Drupal\config_override\EventSubscriber\ConfigModuleOverrideSubscriber.
* Contains \Drupal\config_override\ConfigOverrider.
*/
namespace Drupal\config_override\EventSubscriber;
namespace Drupal\config_override;
use Drupal\Core\Config\ConfigEvents;
use Drupal\Core\Config\ConfigFactoryOverrideInterface;
use Drupal\Core\Config\ConfigModuleOverridesEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Tests module overrides for configuration.
*/
class ConfigModuleOverrideSubscriber implements EventSubscriberInterface {
class ConfigOverrider implements ConfigFactoryOverrideInterface {
public function onConfigModuleOverride(ConfigModuleOverridesEvent $event) {
/**
* {@inheritdoc}
*/
public function loadOverrides($names) {
$overrides = array();
if (!empty($GLOBALS['config_test_run_module_overrides'])) {
$names = $event->getNames();
if (in_array('system.site', $names)) {
$event->setOverride('system.site', array('name' => 'ZOMG overridden site name'));
$overrides = $overrides + array('system.site' => array('name' => 'ZOMG overridden site name'));
}
if (in_array('config_override.new', $names)) {
$event->setOverride('config_override.new', array('module' => 'override'));
$overrides = $overrides + array('config_override.new' => array('module' => 'override'));
}
}
return $overrides;
}
/**
* Registers the methods in this class that should be listeners.
*
* @return array
* An array of event listener definitions.
*/
static function getSubscribedEvents() {
$events[ConfigEvents::MODULE_OVERRIDES][] = array('onConfigModuleOverride', 40);
return $events;
}
}
<?php
/**
* @file
* Contains \Drupal\config_override\ConfigOverriderLowPriority.
*/
namespace Drupal\config_override;
use Drupal\Core\Config\ConfigFactoryOverrideInterface;
/**
* Tests module overrides for configuration.
*/
class ConfigOverriderLowPriority implements ConfigFactoryOverrideInterface {
/**
* {@inheritdoc}
*/
public function loadOverrides($names) {
$overrides = array();
if (!empty($GLOBALS['config_test_run_module_overrides'])) {
if (in_array('system.site', $names)) {
$overrides = array('system.site' =>
array(
'name' => 'Should not apply because of higher priority listener',
// This override should apply because it is not overridden by the
// higher priority listener.
'slogan' => 'Yay for overrides!',
)
);
}
}
return $overrides;
}
}
<?Php
/**
* @file
* Contains \Drupal\config_override\EventSubscriber\ConfigModuleLowPriorityOverrideSubscriber.
*/
namespace Drupal\config_override\EventSubscriber;
use Drupal\Core\Config\ConfigEvents;
use Drupal\Core\Config\ConfigModuleOverridesEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Tests module overrides for configuration.
*/
class ConfigModuleLowPriorityOverrideSubscriber implements EventSubscriberInterface {
public function onConfigModuleOverride(ConfigModuleOverridesEvent $event) {
if (!empty($GLOBALS['config_test_run_module_overrides'])) {
$names = $event->getNames();
if (in_array('system.site', $names)) {
$event->setOverride('system.site', array(
'name' => 'Should not apply because of higher priority listener',
// This override should apply because it is not overridden by the
// higher priority listener.
'slogan' => 'Yay for overrides!',
));
}
}
}
/**
* Registers the methods in this class that should be listeners.
*
* @return array
* An array of event listener definitions.
*/
static function getSubscribedEvents() {
$events[ConfigEvents::MODULE_OVERRIDES][] = array('onConfigModuleOverride', 35);
return $events;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment