diff --git a/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php index dce1741..035d402 100644 --- a/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php +++ b/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Plugin\Discovery; use Drupal\Component\Plugin\Discovery\DiscoveryInterface; +use Drupal\Core\Extension\ModuleHandlerInterface; /** * Provides a hook-based plugin discovery class. @@ -22,13 +23,23 @@ class HookDiscovery implements DiscoveryInterface { protected $hook; /** + * The module handler used to find and execute the plugin hook. + * + * @var \Drupal\Core\Extension\ModuleHandlerInterface + */ + protected $moduleHandler; + + /** * Constructs a Drupal\Core\Plugin\Discovery\HookDiscovery object. * + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler. * @param string $hook * The Drupal hook that a module can implement in order to interface to * this discovery class. */ - function __construct($hook) { + function __construct(ModuleHandlerInterface $module_handler, $hook) { + $this->moduleHandler = $module_handler; $this->hook = $hook; } @@ -45,9 +56,9 @@ public function getDefinition($plugin_id) { */ public function getDefinitions() { $definitions = array(); - foreach (\Drupal::moduleHandler()->getImplementations($this->hook) as $module) { - $function = $module . '_' . $this->hook; - foreach ($function() as $plugin_id => $definition) { + foreach ($this->moduleHandler->getImplementations($this->hook) as $module) { + $result = $this->moduleHandler->invoke($module, $this->hook); + foreach ($result as $plugin_id => $definition) { $definition['module'] = $module; $definitions[$plugin_id] = $definition; } diff --git a/core/tests/Drupal/Tests/Core/Plugin/Discovery/HookDiscoveryTest.php b/core/tests/Drupal/Tests/Core/Plugin/Discovery/HookDiscoveryTest.php new file mode 100644 index 0000000..3a120c8 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Plugin/Discovery/HookDiscoveryTest.php @@ -0,0 +1,150 @@ + 'Hook Discovery', + 'description' => 'Tests the hook plugin discovery class.', + 'group' => 'Plugin', + ); + } + + /** + * {@inheritdoc} + */ + protected function setUp() { + $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); + $this->hookDiscovery = new HookDiscovery($this->moduleHandler, 'test_plugin'); + } + + /** + * Tests the getDefinitions() method without any plugins. + * + * @see \Drupal\Core\Plugin\Discovery::getDefinitions() + */ + public function testGetDefinitionsWithoutPlugins() { + $this->moduleHandler->expects($this->once()) + ->method('getImplementations') + ->with('test_plugin') + ->will($this->returnValue(array())); + + $this->assertCount(0, $this->hookDiscovery->getDefinitions()); + } + + /** + * Tests the getDefinitions() method with some plugins. + * + * @see \Drupal\Core\Plugin\Discovery::getDefinitions() + */ + public function testGetDefinitions() { + $this->moduleHandler->expects($this->once()) + ->method('getImplementations') + ->with('test_plugin') + ->will($this->returnValue(array('hook_discovery_test', 'hook_discovery_test2'))); + + $this->moduleHandler->expects($this->at(1)) + ->method('invoke') + ->with('hook_discovery_test', 'test_plugin') + ->will($this->returnValue(hook_discovery_test_test_plugin())); + $this->moduleHandler->expects($this->at(2)) + ->method('invoke') + ->with('hook_discovery_test2', 'test_plugin') + ->will($this->returnValue(hook_discovery_test2_test_plugin())); + + $definitions = $this->hookDiscovery->getDefinitions(); + + $this->assertCount(3, $definitions); + $this->assertEquals($definitions['test_id_1']['class'], 'Drupal\plugin_test\Plugin\plugin_test\fruit\Apple'); + $this->assertEquals($definitions['test_id_2']['class'], 'Drupal\plugin_test\Plugin\plugin_test\fruit\Orange'); + $this->assertEquals($definitions['test_id_3']['class'], 'Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry'); + + // Ensure that the module was set. + $this->assertEquals($definitions['test_id_1']['module'], 'hook_discovery_test'); + $this->assertEquals($definitions['test_id_2']['module'], 'hook_discovery_test'); + $this->assertEquals($definitions['test_id_3']['module'], 'hook_discovery_test2'); + } + + /** + * Tests the getDefinition method with some plugins. + * + * @see \Drupal\Core\Plugin\Discovery::getDefinition() + */ + public function testGetDefinition() { + $this->moduleHandler->expects($this->exactly(4)) + ->method('getImplementations') + ->with('test_plugin') + ->will($this->returnValue(array('hook_discovery_test', 'hook_discovery_test2'))); + + $this->moduleHandler->expects($this->any()) + ->method('invoke') + ->will($this->returnValueMap(array( + array('hook_discovery_test', 'test_plugin', array(), hook_discovery_test_test_plugin()), + array('hook_discovery_test2', 'test_plugin', array(), hook_discovery_test2_test_plugin()), + ) + )); + + $this->assertNull($this->hookDiscovery->getDefinition('test_non_existant')); + + $plugin_definition = $this->hookDiscovery->getDefinition('test_id_1'); + $this->assertEquals($plugin_definition['class'], 'Drupal\plugin_test\Plugin\plugin_test\fruit\Apple'); + $this->assertEquals($plugin_definition['module'], 'hook_discovery_test'); + + $plugin_definition = $this->hookDiscovery->getDefinition('test_id_2'); + $this->assertEquals($plugin_definition['class'], 'Drupal\plugin_test\Plugin\plugin_test\fruit\Orange'); + $this->assertEquals($plugin_definition['module'], 'hook_discovery_test'); + + $plugin_definition = $this->hookDiscovery->getDefinition('test_id_3'); + $this->assertEquals($plugin_definition['class'], 'Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry'); + $this->assertEquals($plugin_definition['module'], 'hook_discovery_test2'); + } + +} + +} + +namespace { + function hook_discovery_test_test_plugin() { + return array( + 'test_id_1' => array('class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Apple'), + 'test_id_2' => array('class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Orange'), + ); + } + function hook_discovery_test2_test_plugin() { + return array( + 'test_id_3' => array('class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry'), + ); + } +}