Browse Source

Add middlewareGroup

Michael Hoffmann 8 years ago
parent
commit
56b3fbc81d

+ 14 - 0
src/Routing/RouteBuilder.php

@@ -925,4 +925,18 @@ class RouteBuilder
 
         return $this;
     }
+
+    /**
+     * Apply a set of middleware to a group
+     *
+     * @param string $name Name of the middleware group
+     * @param array $names Names of the middleware
+     * @return $this
+     */
+    public function middlewareGroup($name, array $middlewareNames)
+    {
+        $this->_collection->middlewareGroup($name, $middlewareNames);
+
+        return $this;
+    }
 }

+ 57 - 3
src/Routing/RouteCollection.php

@@ -67,6 +67,13 @@ class RouteCollection
     protected $_middleware = [];
 
     /**
+     * A map of middleware group names and the related middleware names.
+     *
+     * @var array
+     */
+    protected $_middlewareGroups = [];
+
+    /**
      * A map of paths and the list of applicable middleware.
      *
      * @var array
@@ -425,6 +432,47 @@ class RouteCollection
     }
 
     /**
+     * Add middleware to a middleware group
+     *
+     * @param string $name Name of the middleware group
+     * @param array $names Names of the middleware
+     * @return $this
+     */
+    public function middlewareGroup($name, $middlewareNames)
+    {
+        if ($this->hasMiddleware($name)) {
+            $message = "Cannot add middle ware group '$name' . A middleware by this name has already been registered.";
+            throw new RuntimeException($message);
+        }
+        if ($this->hasMiddlewareGroup($name)) {
+            $message = "Cannot add middle ware group '$name' . A middleware group by this name has already been added.";
+            throw new RuntimeException($message);
+        }
+
+        foreach ($middlewareNames as $middlewareName) {
+            if (!$this->hasMiddleware($middlewareName)) {
+                $message = "Cannot add '$middlewareName' middleware to group '$name'. It has not been registered.";
+                throw new RuntimeException($message);
+            }
+        }
+
+        $this->_middlewareGroups[$name] = $middlewareNames;
+
+        return $this;
+    }
+
+    /**
+     * Check if the named middleware group has been created.
+     *
+     * @param string $name The name of the middleware group to check.
+     * @return bool
+     */
+    public function hasMiddlewareGroup($name)
+    {
+        return array_key_exists($name, $this->_middlewareGroups);
+    }
+
+    /**
      * Check if the named middleware has been registered.
      *
      * @param string $name The name of the middleware to check.
@@ -445,9 +493,15 @@ class RouteCollection
     public function applyMiddleware($path, array $middleware)
     {
         foreach ($middleware as $name) {
-            if (!$this->hasMiddleware($name)) {
-                $message = "Cannot apply '$name' middleware to path '$path'. It has not been registered.";
-                throw new RuntimeException($message);
+            if (!$this->hasMiddleware($name) && !$this->hasMiddlewareGroup($name)) {
+                if (!$this->hasMiddleware($name)) {
+                    $message = "Cannot apply '$name' middleware to path '$path'. It has not been registered.";
+                    throw new RuntimeException($message);
+                }
+                if (!$this->hasMiddlewareGroup($name)) {
+                    $message = "Cannot apply '$name' middleware group to path '$path'. It has not been added.";
+                    throw new RuntimeException($message);
+                }
             }
         }
         // Matches route element pattern in Cake\Routing\Route

+ 36 - 0
tests/TestCase/Routing/RouteBuilderTest.php

@@ -842,6 +842,42 @@ class RouteBuilderTest extends TestCase
         $routes->registerMiddleware('bad', 'strlen');
     }
 
+
+    /**
+     * Test middleware group
+     *
+     * @return void
+     */
+    public function testMiddlewareGroup()
+    {
+        $func = function () {
+        };
+        $routes = new RouteBuilder($this->collection, '/api');
+        $routes->registerMiddleware('test', $func);
+        $routes->registerMiddleware('test_two', $func);
+        $result = $routes->middlewareGroup('group', ['test', 'test_two']);
+
+
+        $this->assertSame($result, $routes);
+        $this->assertTrue($this->collection->hasMiddlewareGroup('group'));
+    }
+
+    /**
+     * Test overlap between middleware name and group name
+     *
+     * @expectedException \RuntimeException
+     * @expectedExceptionMessage Cannot add middle ware group 'test' . A middleware by this name has already been registered.
+     * @return void
+     */
+    public function testMiddlewareGroupOverlap()
+    {
+        $func = function () {
+        };
+        $routes = new RouteBuilder($this->collection, '/api');
+        $routes->registerMiddleware('test', $func);
+        $result = $routes->middlewareGroup('test', ['test']);
+    }
+
     /**
      * Test applying middleware to a scope when it doesn't exist
      *

+ 20 - 0
tests/TestCase/Routing/RouteCollectionTest.php

@@ -665,6 +665,26 @@ class RouteCollectionTest extends TestCase
     }
 
     /**
+     * Test adding a middleware group to the collection.
+     *
+     * @return void
+     */
+    public function testMiddlewareGroup()
+    {
+        $this->collection->registerMiddleware('closure', function () {});
+
+        $mock = $this->getMockBuilder('\stdClass')
+            ->setMethods(['__invoke'])
+            ->getMock();
+        $result = $this->collection->registerMiddleware('callable', $mock);
+        $this->collection->registerMiddleware('callable', $mock);
+
+        $routes->groupMiddleware('group', ['closure', 'callable']);
+
+        $this->assertTrue($this->collection->hasMiddlewareGroup('group'));
+    }
+
+    /**
      * Test adding middleware with a placeholder in the path.
      *
      * @return void