Browse Source

Add events hook to plugins.

This adds consistency between application hooks and plugin hooks.
Mark Story 8 years ago
parent
commit
0cbab2a29b

+ 3 - 0
src/Console/CommandRunner.php

@@ -183,6 +183,8 @@ class CommandRunner implements EventDispatcherInterface
      * Application bootstrap wrapper.
      *
      * Calls `bootstrap()` and `events()` if application implements `EventApplicationInterface`.
+     * After the application is bootstrapped and events are attached, plugins are bootstrapped
+     * and have their events attached.
      *
      * @return void
      */
@@ -195,6 +197,7 @@ class CommandRunner implements EventDispatcherInterface
         }
         if ($this->app instanceof PluginApplicationInterface) {
             $this->app->pluginBootstrap();
+            $this->app->pluginEvents();
         }
     }
 

+ 14 - 0
src/Core/PluginApp.php

@@ -33,6 +33,13 @@ class PluginApp implements PluginInterface
     protected $bootstrapEnabled = true;
 
     /**
+     * Are events enabled.
+     *
+     * @var bool
+     */
+    protected $eventsEnabled = true;
+
+    /**
      * Load routes or not
      *
      * @var bool
@@ -255,4 +262,11 @@ class PluginApp implements PluginInterface
     {
         return $middleware;
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function events($events)
+    {
+    }
 }

+ 7 - 0
src/Core/PluginApplicationInterface.php

@@ -58,4 +58,11 @@ interface PluginApplicationInterface
      * @return \Cake\Console\CommandCollection
      */
     public function pluginConsole($commands);
+
+    /**
+     * Run events hook for plugins
+     *
+     * @return void
+     */
+    public function pluginEvents();
 }

+ 13 - 5
src/Core/PluginInterface.php

@@ -18,9 +18,9 @@ namespace Cake\Core;
 interface PluginInterface
 {
     /**
-     * The list of valid hooks
+     * List of valid hooks.
      */
-    const VALID_HOOKS = ['routes', 'bootstrap', 'console', 'middleware'];
+    const VALID_HOOKS = ['routes', 'bootstrap', 'console', 'middleware', 'events'];
 
     /**
      * Get the name of this plugin.
@@ -60,7 +60,7 @@ interface PluginInterface
     public function bootstrap();
 
     /**
-     * Add a plugins console commands
+     * Add console commands for the plugin.
      *
      * @param \Cake\Console\CommandCollection $commands The command collection to update
      * @return \Cake\Console\CommandCollection
@@ -68,7 +68,7 @@ interface PluginInterface
     public function console($commands);
 
     /**
-     * Add a plugins middleware
+     * Add middleware for the plugin.
      *
      * @param \Cake\Http\MiddlewareQueue $middleware The middleware queue to update.
      * @return \Cake\Http\MiddlewareQueue
@@ -76,7 +76,7 @@ interface PluginInterface
     public function middleware($middleware);
 
     /**
-     * Add a routes
+     * Add routes for the plugin.
      *
      * @param \Cake\Routing\RouteBuilder $routes The route builder to update.
      * @return \Cake\Routing\RouteBuilder
@@ -84,6 +84,14 @@ interface PluginInterface
     public function routes($routes);
 
     /**
+     * Add events for the plugin.
+     *
+     * @param \Cake\Event\EventManager $events The application's event manager
+     * @return void
+     */
+    public function events($events);
+
+    /**
      * Disables the named hook
      *
      * @param string $hook The hook to disable

+ 12 - 0
src/Http/BaseApplication.php

@@ -81,6 +81,18 @@ abstract class BaseApplication implements
     /**
      * {@inheritDoc}
      */
+    public function pluginEvents()
+    {
+        $events = $this->getEventManager();
+
+        foreach ($this->plugins->with('events') as $plugin) {
+            $plugin->events($events);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public function pluginMiddleware($middleware)
     {
         foreach ($this->plugins->with('middleware') as $plugin) {

+ 3 - 0
src/Http/Server.php

@@ -103,6 +103,8 @@ class Server implements EventDispatcherInterface
      * Application bootstrap wrapper.
      *
      * Calls `bootstrap()` and `events()` if application implements `EventApplicationInterface`.
+     * After the application is bootstrapped and events are attached, plugins are bootstrapped
+     * and have their events attached.
      *
      * @return void
      */
@@ -115,6 +117,7 @@ class Server implements EventDispatcherInterface
         }
         if ($this->app instanceof PluginApplicationInterface) {
             $this->app->pluginBootstrap();
+            $this->app->pluginEvents();
         }
     }
 

+ 6 - 4
tests/TestCase/Console/CommandRunnerTest.php

@@ -394,14 +394,16 @@ class CommandRunnerTest extends TestCase
     public function testRunCallsPluginHookMethods()
     {
         $app = $this->getMockBuilder(BaseApplication::class)
-            ->setMethods(['middleware', 'bootstrap', 'pluginBootstrap', 'pluginConsole'])
+            ->setMethods(['middleware', 'bootstrap', 'pluginBootstrap', 'pluginEvents', 'pluginConsole'])
             ->setConstructorArgs([$this->config])
             ->getMock();
-        $app->expects($this->once())
-            ->method('pluginBootstrap');
+
+        $app->expects($this->at(0))->method('bootstrap');
+        $app->expects($this->at(1))->method('pluginBootstrap');
+        $app->expects($this->at(2))->method('pluginEvents');
 
         $commands = new CommandCollection();
-        $app->expects($this->once())
+        $app->expects($this->at(3))
             ->method('pluginConsole')
             ->with($this->isinstanceOf(CommandCollection::class))
             ->will($this->returnCallback(function ($commands) {

+ 8 - 0
tests/TestCase/Core/PluginAppTest.php

@@ -16,6 +16,7 @@ namespace Cake\Test\TestCase\Core;
 use Cake\Console\CommandCollection;
 use Cake\Core\Plugin;
 use Cake\Core\PluginApp;
+use Cake\Event\EventManager;
 use Cake\Http\MiddlewareQueue;
 use Cake\TestSuite\TestCase;
 use Company\TestPluginThree\Plugin as TestPluginThree;
@@ -85,6 +86,13 @@ class PluginAppTest extends TestCase
         $this->assertSame($commands, $plugin->console($commands));
     }
 
+    public function testEvents()
+    {
+        $plugin = new PluginApp();
+        $events = new EventManager();
+        $this->assertNull($plugin->events($events));
+    }
+
     public function testConstructorArguments()
     {
         $plugin = new PluginApp([

+ 5 - 3
tests/TestCase/Http/ServerTest.php

@@ -121,12 +121,14 @@ class ServerTest extends TestCase
         $request = $request->withHeader('X-pass', 'request header');
 
         $app = $this->getMockBuilder(MiddlewareApplication::class)
-            ->setMethods(['pluginBootstrap', 'pluginMiddleware'])
+            ->setMethods(['pluginBootstrap', 'pluginEvents', 'pluginMiddleware'])
             ->setConstructorArgs([$this->config])
             ->getMock();
-        $app->expects($this->once())
+        $app->expects($this->at(0))
             ->method('pluginBootstrap');
-        $app->expects($this->once())
+        $app->expects($this->at(1))
+            ->method('pluginBootstrap');
+        $app->expects($this->at(2))
             ->method('pluginMiddleware')
             ->with($this->isInstanceOf(MiddlewareQueue::class))
             ->will($this->returnCallback(function ($middleware) {