Browse Source

Return a `Closure` from `routes.php` files.

This is cleaner than including the file within a method's context and making `$routes`
variable magically available.
ADmad 4 years ago
parent
commit
8aac86b1be

+ 5 - 1
src/Core/BasePlugin.php

@@ -18,6 +18,7 @@ namespace Cake\Core;
 use Cake\Console\CommandCollection;
 use Cake\Http\MiddlewareQueue;
 use Cake\Routing\RouteBuilder;
+use Closure;
 use InvalidArgumentException;
 use ReflectionClass;
 
@@ -258,7 +259,10 @@ class BasePlugin implements PluginInterface
     {
         $path = $this->getConfigPath() . 'routes.php';
         if (is_file($path)) {
-            require $path;
+            $return = require $path;
+            if ($return instanceof Closure) {
+                $return($routes);
+            }
         }
     }
 

+ 5 - 1
src/Http/BaseApplication.php

@@ -34,6 +34,7 @@ use Cake\Event\EventManagerInterface;
 use Cake\Routing\RouteBuilder;
 use Cake\Routing\Router;
 use Cake\Routing\RoutingApplicationInterface;
+use Closure;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 
@@ -194,7 +195,10 @@ abstract class BaseApplication implements
     {
         // Only load routes if the router is empty
         if (!Router::routes()) {
-            require $this->configDir . 'routes.php';
+            $return = require $this->configDir . 'routes.php';
+            if ($return instanceof Closure) {
+                $return($routes);
+            }
         }
     }
 

+ 3 - 2
tests/test_app/Plugin/TestPlugin/config/routes.php

@@ -1,13 +1,14 @@
 <?php
 
 use Cake\Core\Configure;
+use Cake\Routing\RouteBuilder;
 
 Configure::write('PluginTest.test_plugin.routes', 'loaded plugin routes');
 
-if (isset($routes)) {
+return function (RouteBuilder $routes) {
     $routes->get(
         '/test_plugin',
         ['controller' => 'TestPlugin', 'plugin' => 'TestPlugin', 'action' => 'index'],
         'test_plugin:index'
     );
-}
+};

+ 17 - 15
tests/test_app/config/routes.php

@@ -15,18 +15,20 @@
 
 use Cake\Routing\RouteBuilder;
 
-$routes->setExtensions('json');
-$routes->scope('/', function (RouteBuilder $routes): void {
-    $routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
-    $routes->connect(
-        '/some_alias',
-        [
-            'controller' => 'tests_apps',
-            'action' => 'some_method'],
-        [
-            '_name' => 'some_alias',
-            'routeClass' => 'InflectedRoute',
-        ]
-    );
-    $routes->fallbacks();
-});
+return function (RouteBuilder $routes) {
+    $routes->setExtensions('json');
+    $routes->scope('/', function (RouteBuilder $routes): void {
+        $routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
+        $routes->connect(
+            '/some_alias',
+            [
+                'controller' => 'tests_apps',
+                'action' => 'some_method'],
+            [
+                '_name' => 'some_alias',
+                'routeClass' => 'InflectedRoute',
+            ]
+        );
+        $routes->fallbacks();
+    });
+};

+ 6 - 2
tests/test_app/invalid_routes/routes.php

@@ -1,10 +1,14 @@
 <?php
 declare(strict_types=1);
 
+use Cake\Routing\RouteBuilder;
+
 /*
  * Test routes file with routes that trigger a missing route class error.
  * Application requests should have InvalidArgument error rendered.
  */
 
-$routes->setRouteClass('DoesNotExist');
-$routes->get('/', ['controller' => 'Pages']);
+return function (RouteBuilder $routes) {
+    $routes->setRouteClass('DoesNotExist');
+    $routes->get('/', ['controller' => 'Pages']);
+};