Browse Source

Merge pull request #10711 from cakephp/3next-plugin-routes

3.next - Add RouteBuilder::loadPlugin.
Mark Story 8 years ago
parent
commit
47bbb660dc

+ 6 - 3
src/Core/Plugin.php

@@ -324,10 +324,13 @@ class Plugin
     }
 
     /**
-     * Loads the routes file for a plugin, or all plugins configured to load their respective routes file
+     * Loads the routes file for a plugin, or all plugins configured to load their respective routes file.
      *
-     * @param string|null $plugin name of the plugin, if null will operate on all plugins having enabled the
-     * loading of routes files
+     * If you need fine grained control over how routes are loaded for plugins, you
+     * can use {@see Cake\Routing\RouteBuilder::loadPlugin()}
+     *
+     * @param string|null $plugin name of the plugin, if null will operate on all
+     *   plugins having enabled the loading of routes files.
      * @return bool
      */
     public static function routes($plugin = null)

+ 33 - 0
src/Routing/RouteBuilder.php

@@ -16,6 +16,8 @@ namespace Cake\Routing;
 
 use BadMethodCallException;
 use Cake\Core\App;
+use Cake\Core\Exception\MissingPluginException;
+use Cake\Core\Plugin;
 use Cake\Routing\Route\Route;
 use Cake\Utility\Inflector;
 use InvalidArgumentException;
@@ -519,6 +521,37 @@ class RouteBuilder
     }
 
     /**
+     * Load routes from a plugin.
+     *
+     * The routes file will have a local variable named `$routes` made available which contains
+     * the current RouteBuilder instance.
+     *
+     * @param string $name The plugin name
+     * @param string $file The routes file to load. Defaults to `routes.php`
+     * @return void
+     * @throws \Cake\Core\Exception\MissingPluginException When the plugin has not been loaded.
+     * @throws \InvalidArgumentException When the plugin does not have a routes file.
+     */
+    public function loadPlugin($name, $file = 'routes.php')
+    {
+        if (!Plugin::loaded($name)) {
+            throw new MissingPluginException(['plugin' => $name]);
+        }
+
+        $path = Plugin::configPath($name) . DIRECTORY_SEPARATOR . $file;
+        if (!file_exists($path)) {
+            throw new InvalidArgumentException(sprintf(
+                'Cannot load routes for the plugin named %s. The %s file does not exist.',
+                $name,
+                $path
+            ));
+        }
+
+        $routes = $this;
+        include $path;
+    }
+
+    /**
      * Connects a new Route.
      *
      * Routes are a way of connecting request URLs to objects in your application.

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

@@ -14,6 +14,7 @@
  */
 namespace Cake\Test\TestCase\Routing;
 
+use Cake\Core\Plugin;
 use Cake\Routing\RouteBuilder;
 use Cake\Routing\RouteCollection;
 use Cake\Routing\Router;
@@ -41,6 +42,17 @@ class RouteBuilderTest extends TestCase
     }
 
     /**
+     * Teardown method
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        parent::tearDown();
+        Plugin::unload('TestPlugin');
+    }
+
+    /**
      * Test path()
      *
      * @return void
@@ -927,4 +939,44 @@ class RouteBuilderTest extends TestCase
         $result = $this->collection->parse('/articles/123');
         $this->assertEquals(['123'], $result['pass']);
     }
+
+    /**
+     * Test loading routes from a missing plugin
+     *
+     * @expectedException Cake\Core\Exception\MissingPluginException
+     * @return void
+     */
+    public function testLoadPluginBadPlugin()
+    {
+        $routes = new RouteBuilder($this->collection, '/');
+        $routes->loadPlugin('Nope');
+    }
+
+    /**
+     * Test loading routes from a missing file
+     *
+     * @expectedException InvalidArgumentException
+     * @expectedExceptionMessage Cannot load routes for the plugin named TestPlugin.
+     * @return void
+     */
+    public function testLoadPluginBadFile()
+    {
+        Plugin::load('TestPlugin');
+        $routes = new RouteBuilder($this->collection, '/');
+        $routes->loadPlugin('TestPlugin', 'nope.php');
+    }
+
+    /**
+     * Test loading routes with success
+     *
+     * @return void
+     */
+    public function testLoadPlugin()
+    {
+        Plugin::load('TestPlugin');
+        $routes = new RouteBuilder($this->collection, '/');
+        $routes->loadPlugin('TestPlugin');
+        $this->assertCount(1, $this->collection->routes());
+        $this->assertNotEmpty($this->collection->parse('/test_plugin'));
+    }
 }

+ 4 - 0
tests/test_app/Plugin/TestPlugin/config/routes.php

@@ -2,3 +2,7 @@
 use Cake\Core\Configure;
 
 Configure::write('PluginTest.test_plugin.routes', 'loaded plugin routes');
+
+if (isset($routes)) {
+    $routes->get('/test_plugin', ['controller' => 'TestPlugin', 'plugin' => 'TestPlugin', 'action' => 'index']);
+}