commit 3f00114484cafe08e8fc0c2ef6da28527904c833 Author: Bart Feenstra Date: Fri Jan 10 11:47:57 2014 +0100 They see me re-rollin'. They testin'. diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 46fbcbc..2a3b13b 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -423,7 +423,8 @@ function install_begin_request(&$install_state) { // Register a module handler for managing enabled modules. $container - ->register('module_handler', 'Drupal\Core\Extension\ModuleHandler'); + ->register('module_handler', 'Drupal\Core\Extension\ModuleHandler') + ->addArgument(new Reference('event_dispatcher')); // Register the Guzzle HTTP client for fetching translation files from a // remote translation server such as localization.drupal.org. diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php index 098b165..1816fcc 100644 --- a/core/lib/Drupal/Core/CoreServiceProvider.php +++ b/core/lib/Drupal/Core/CoreServiceProvider.php @@ -95,13 +95,15 @@ protected function registerModuleHandler(ContainerBuilder $container) { if ($container->getParameter('kernel.environment') == 'install') { // During installation we use the non-cached version. $container->register('module_handler', 'Drupal\Core\Extension\ModuleHandler') + ->addArgument(new Reference('event_dispatcher')) ->addArgument('%container.modules%'); } else { $container->register('module_handler', 'Drupal\Core\Extension\CachedModuleHandler') - ->addArgument('%container.modules%') + ->addArgument(new Reference('event_dispatcher')) ->addArgument(new Reference('state')) - ->addArgument(new Reference('cache.bootstrap')); + ->addArgument(new Reference('cache.bootstrap')) + ->addArgument('%container.modules%'); } } diff --git a/core/lib/Drupal/Core/DependencyInjection/UpdateServiceProvider.php b/core/lib/Drupal/Core/DependencyInjection/UpdateServiceProvider.php index ee637ea..5092456 100644 --- a/core/lib/Drupal/Core/DependencyInjection/UpdateServiceProvider.php +++ b/core/lib/Drupal/Core/DependencyInjection/UpdateServiceProvider.php @@ -34,6 +34,7 @@ public function register(ContainerBuilder $container) { ->register('config.storage', 'Drupal\Core\Config\FileStorage') ->addArgument(config_get_config_directory(CONFIG_ACTIVE_DIRECTORY)); $container->register('module_handler', 'Drupal\Core\Extension\UpdateModuleHandler') + ->addArgument(new Reference('event_dispatcher')) ->addArgument('%container.modules%'); $container ->register("cache_factory", 'Drupal\Core\Cache\MemoryBackendFactory'); diff --git a/core/lib/Drupal/Core/Extension/CachedModuleHandler.php b/core/lib/Drupal/Core/Extension/CachedModuleHandler.php index 0def7f3..7ebcf6c 100644 --- a/core/lib/Drupal/Core/Extension/CachedModuleHandler.php +++ b/core/lib/Drupal/Core/Extension/CachedModuleHandler.php @@ -9,6 +9,7 @@ use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\KeyValueStore\StateInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Class that manages enabled modules in a Drupal installation. @@ -39,8 +40,8 @@ class CachedModuleHandler extends ModuleHandler implements CachedModuleHandlerIn /** * Constructs a new CachedModuleHandler object. */ - public function __construct(array $module_list = array(), StateInterface $state, CacheBackendInterface $bootstrap_cache) { - parent::__construct($module_list); + public function __construct(EventDispatcherInterface $event_dispatcher, StateInterface $state, CacheBackendInterface $bootstrap_cache, array $module_list = array()) { + parent::__construct($event_dispatcher, $module_list); $this->state = $state; $this->bootstrapCache = $bootstrap_cache; } diff --git a/core/lib/Drupal/Core/Extension/HookEvent.php b/core/lib/Drupal/Core/Extension/HookEvent.php new file mode 100644 index 0000000..3ec934e --- /dev/null +++ b/core/lib/Drupal/Core/Extension/HookEvent.php @@ -0,0 +1,49 @@ +returnValues[] = $value; + } + + /** + * Returns the collected return values from all listeners to this hook event. + * + * @return mixed[] + */ + public function getReturnValues() { + return $this->returnValues; + } + +} + diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php index 5b3d2b9..ac7ca8c 100644 --- a/core/lib/Drupal/Core/Extension/ModuleHandler.php +++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Extension; use Drupal\Component\Graph\Graph; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Yaml\Parser; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Cache\CacheBackendInterface; @@ -65,8 +66,17 @@ class ModuleHandler implements ModuleHandlerInterface { protected $alterFunctions; /** + * Event dispatcher to use for hook events. + * + * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface + */ + protected $dispatcher; + + /** * Constructs a ModuleHandler object. * + * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher + * The event dispatcher that should be used for firing hook events. * @param array $module_list * An associative array whose keys are the names of installed modules and * whose values are the module filenames. This is normally the @@ -75,7 +85,8 @@ class ModuleHandler implements ModuleHandlerInterface { * @see \Drupal\Core\DrupalKernel * @see \Drupal\Core\CoreServiceProvider */ - public function __construct(array $module_list = array()) { + public function __construct(EventDispatcherInterface $dispatcher, array $module_list = array()) { + $this->dispatcher = $dispatcher; $this->moduleList = $module_list; } @@ -277,6 +288,8 @@ public function invoke($module, $hook, $args = array()) { */ public function invokeAll($hook, $args = array()) { $return = array(); + + // Invoke procedural hook implementations. $implementations = $this->getImplementations($hook); foreach ($implementations as $module) { $function = $module . '_' . $hook; @@ -291,6 +304,18 @@ public function invokeAll($hook, $args = array()) { } } + // Dispatch the event. + $event = new HookEvent($hook, $args); + $this->dispatcher->dispatch("hook.{$hook}", $event); + foreach ($event->getReturnValues() as $result) { + if (is_array($result)) { + $return = NestedArray::mergeDeep($return, $result); + } + else { + $return[] = $result; + } + } + return $return; } diff --git a/core/tests/Drupal/Tests/Core/Extension/HookEventUnitTest.php b/core/tests/Drupal/Tests/Core/Extension/HookEventUnitTest.php new file mode 100644 index 0000000..8ff1a6d --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Extension/HookEventUnitTest.php @@ -0,0 +1,64 @@ + '', + 'group' => 'System', + 'name' => '\Drupal\Core\Extension\HookEvent', + ); + } + + /** + * {@inheritdoc} + */ + function setUp() { + $this->hookEvent = new HookEvent(); + } + + /** + * Tests getReturnValues(). + */ + public function testGetReturnValues() { + $this->assertSame(array(), $this->hookEvent->getReturnValues()); + } + + /** + * Tests setReturnValue(). + * + * @depends testGetReturnValues + */ + public function testSetReturnValue() { + $value = $this->randomName(); + + $this->hookEvent->setReturnValue($value); + $this->assertSame(array($value), $this->hookEvent->getReturnValues()); + } + +} diff --git a/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerUnitTest.php b/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerUnitTest.php index 49ab1f8..637f033 100644 --- a/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerUnitTest.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\Core\Extension\ModuleHanderUnitTest. + * Contains \Drupal\Core\Extension\ModuleHandlerUnitTest. */ namespace Drupal\Tests\Core\Extension; @@ -13,7 +13,6 @@ use Drupal\Core\Extension\ModuleHandler; use Drupal\Tests\UnitTestCase; -use PHPUnit_Framework_Error_Notice; /** * Tests the ModuleHandler class. @@ -22,6 +21,23 @@ */ class ModuleHandlerUnitTest extends UnitTestCase { + /** + * Contains the event dispatcher used for testing. + * + * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $eventDispatcher; + + /** + * Contains the module handler under test. + * + * @var \Drupal\Core\Extension\ModuleHandler + */ + protected $moduleHandler; + + /** + * {@inheritdoc} + */ public static function getInfo() { return array( 'name' => 'ModuleHandler functionality', @@ -30,9 +46,13 @@ public static function getInfo() { ); } + /** + * {@inheritdoc} + */ function setUp() { - parent::setUp(); - $this->moduleHandler = new ModuleHandler; + $this->eventDispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface'); + + $this->moduleHandler = new ModuleHandler($this->eventDispatcher); } /** @@ -43,4 +63,17 @@ public function testLoadInclude() { $this->assertFalse($this->moduleHandler->loadInclude('foo', 'inc')); } + /** + * Tests invokeAll(). + */ + public function testInvokeAll() { + $hook = $this->randomName(); + + $this->eventDispatcher->expects($this->once()) + ->method('dispatch') + ->with('hook.' . $hook); + + $this->moduleHandler->invokeAll($hook); + } + } diff --git a/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php b/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php index 47384ac..5e609d1 100644 --- a/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php +++ b/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php @@ -79,8 +79,10 @@ protected function getLocalTaskManager($module_dirs, $route_name, $route_params) $property->setAccessible(TRUE); $property->setValue($manager, $accessManager); + $this->eventDispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface'); $this->moduleHandler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandlerInterface') ->disableOriginalConstructor() + ->setConstructorArgs(array($this->eventDispatcher)) ->getMock(); $pluginDiscovery = new YamlDiscovery('local_tasks', $module_dirs); diff --git a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php index 3e86b66..ace779d 100644 --- a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php +++ b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php @@ -80,7 +80,9 @@ public function testDefaultPluginManager() { * Tests the plugin manager with no cache and altering. */ public function testDefaultPluginManagerWithAlter() { - $module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandler'); + $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler') + ->disableOriginalConstructor() + ->getMock(); // Configure the stub. $alter_hook_name = $this->randomName(); diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php old mode 100644 new mode 100755