Browse Source

Add DashedRoute class.

ADmad 11 years ago
parent
commit
3bfa4ca217
2 changed files with 272 additions and 0 deletions
  1. 107 0
      src/Routing/Route/DashedRoute.php
  2. 165 0
      tests/TestCase/Routing/Route/DashedRouteTest.php

+ 107 - 0
src/Routing/Route/DashedRoute.php

@@ -0,0 +1,107 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Routing\Route;
+
+use Cake\Routing\Route\Route;
+use Cake\Utility\Inflector;
+
+/**
+ * This route class will transparently inflect the controller, action and plugin
+ * routing parameters, so that requesting `/my-plugin/my-controller/my-action`
+ * is parsed as `['plugin' => 'MyPlugin', 'controller' => 'MyController', 'action' => 'myAction']`
+ */
+class DashedRoute extends Route {
+
+/**
+ * Flag for tracking whether or not the defaults have been inflected.
+ *
+ * Default values need to be inflected so that they match the inflections that
+ * match() will create.
+ *
+ * @var bool
+ */
+	protected $_inflectedDefaults = false;
+
+/**
+ * Parses a string URL into an array. If it mathes, it will convert the
+ * controller, action and plugin keys to their camelized form.
+ *
+ * @param string $url The URL to parse
+ * @return mixed false on failure, or an array of request parameters
+ */
+	public function parse($url) {
+		$params = parent::parse($url);
+		if (!$params) {
+			return false;
+		}
+		if (!empty($params['controller'])) {
+			$params['controller'] = Inflector::camelize(str_replace(
+				'-',
+				'_',
+				$params['controller']
+			));
+		}
+		if (!empty($params['plugin'])) {
+			$params['plugin'] = Inflector::camelize(str_replace(
+				'-',
+				'_',
+				$params['plugin']
+			));
+		}
+		if (!empty($params['action'])) {
+			$params['action'] = Inflector::variable(str_replace(
+				'-',
+				'_',
+				$params['action']
+			));
+		}
+		return $params;
+	}
+
+/**
+ * Dasherizes the controller, action and plugin params before passing them on
+ * to the parent class.
+ *
+ * @param array $url Array of parameters to convert to a string.
+ * @param array $context An array of the current request context.
+ *   Contains information such as the current host, scheme, port, and base
+ *   directory.
+ * @return mixed either false or a string URL.
+ */
+	public function match(array $url, array $context = array()) {
+		$url = $this->_dasherize($url);
+		if (!$this->_inflectedDefaults) {
+			$this->_inflectedDefaults = true;
+			$this->defaults = $this->_dasherize($this->defaults);
+		}
+		return parent::match($url, $context);
+	}
+
+/**
+ * Helper method for dasherizing keys in a URL array.
+ *
+ * @param array $url An array of URL keys.
+ * @return array
+ */
+	protected function _dasherize($url) {
+		foreach (['controller', 'plugin', 'action'] as $element) {
+			if (!empty($url[$element])) {
+				$url[$element] = Inflector::dasherize($url[$element]);
+			}
+		}
+		return $url;
+	}
+
+}

+ 165 - 0
tests/TestCase/Routing/Route/DashedRouteTest.php

@@ -0,0 +1,165 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Test\TestCase\Routing\Route;
+
+use Cake\Core\App;
+use Cake\Routing\Router;
+use Cake\Routing\Route\DashedRoute;
+use Cake\TestSuite\TestCase;
+
+/**
+ * Test case for DashedRoute
+ */
+class DashedRouteTest extends TestCase {
+
+/**
+ * test that routes match their pattern.
+ *
+ * @return void
+ */
+	public function testMatchBasic() {
+		$route = new DashedRoute('/:controller/:action/:id', ['plugin' => null]);
+		$result = $route->match(['controller' => 'Posts', 'action' => 'myView', 'plugin' => null]);
+		$this->assertFalse($result);
+
+		$result = $route->match([
+			'plugin' => null,
+			'controller' => 'Posts',
+			'action' => 'myView',
+			0
+		]);
+		$this->assertFalse($result);
+
+		$result = $route->match([
+			'plugin' => null,
+			'controller' => 'MyPosts',
+			'action' => 'myView',
+			'id' => 1
+		]);
+		$this->assertEquals('/my-posts/my-view/1', $result);
+
+		$route = new DashedRoute('/', ['controller' => 'Pages', 'action' => 'myDisplay', 'home']);
+		$result = $route->match(['controller' => 'Pages', 'action' => 'myDisplay', 'home']);
+		$this->assertEquals('/', $result);
+
+		$result = $route->match(['controller' => 'Pages', 'action' => 'display', 'about']);
+		$this->assertFalse($result);
+
+		$route = new DashedRoute('/blog/:action', ['controller' => 'Posts']);
+		$result = $route->match(['controller' => 'Posts', 'action' => 'myView']);
+		$this->assertEquals('/blog/my-view', $result);
+
+		$result = $route->match(['controller' => 'Posts', 'action' => 'myView', 'id' => 2]);
+		$this->assertEquals('/blog/my-view?id=2', $result);
+
+		$result = $route->match(['controller' => 'Posts', 'action' => 'myView', 1]);
+		$this->assertFalse($result);
+
+		$route = new DashedRoute('/foo/:controller/:action', ['action' => 'index']);
+		$result = $route->match(['controller' => 'Posts', 'action' => 'myView']);
+		$this->assertEquals('/foo/posts/my-view', $result);
+
+		$route = new DashedRoute('/:plugin/:id/*', ['controller' => 'Posts', 'action' => 'myView']);
+		$result = $route->match([
+			'plugin' => 'TestPlugin',
+			'controller' => 'Posts',
+			'action' => 'myView',
+			'id' => '1'
+		]);
+		$this->assertEquals('/test-plugin/1/', $result);
+
+		$result = $route->match([
+			'plugin' => 'TestPlugin',
+			'controller' => 'Posts',
+			'action' => 'myView',
+			'id' => '1',
+			'0'
+		]);
+		$this->assertEquals('/test-plugin/1/0', $result);
+
+		$result = $route->match([
+			'plugin' => 'TestPlugin',
+			'controller' => 'Nodes',
+			'action' => 'myView',
+			'id' => 1
+		]);
+		$this->assertFalse($result);
+
+		$result = $route->match([
+			'plugin' => 'TestPlugin',
+			'controller' => 'Posts',
+			'action' => 'edit',
+			'id' => 1
+		]);
+		$this->assertFalse($result);
+
+		$route = new DashedRoute('/admin/subscriptions/:action/*', [
+			'controller' => 'Subscribe', 'prefix' => 'admin'
+		]);
+		$result = $route->match([
+			'controller' => 'Subscribe',
+			'prefix' => 'admin',
+			'action' => 'editAdminE',
+			1
+		]);
+		$expected = '/admin/subscriptions/edit-admin-e/1';
+		$this->assertEquals($expected, $result);
+	}
+
+/**
+ * test the parse method of DashedRoute.
+ *
+ * @return void
+ */
+	public function testParse() {
+		$route = new DashedRoute(
+			'/:controller/:action/:id',
+			['controller' => 'Testing4', 'id' => null],
+			['id' => Router::ID]
+		);
+		$route->compile();
+		$result = $route->parse('/my-posts/my-view/1');
+		$this->assertEquals('MyPosts', $result['controller']);
+		$this->assertEquals('myView', $result['action']);
+		$this->assertEquals('1', $result['id']);
+
+		$route = new DashedRoute(
+			'/admin/:controller',
+			['prefix' => 'admin', 'admin' => 1, 'action' => 'index']
+		);
+		$route->compile();
+		$result = $route->parse('/admin/');
+		$this->assertFalse($result);
+
+		$result = $route->parse('/admin/my-posts');
+		$this->assertEquals('MyPosts', $result['controller']);
+		$this->assertEquals('index', $result['action']);
+
+		$route = new DashedRoute(
+			'/media/search/*',
+			['controller' => 'Media', 'action' => 'searchIt']
+		);
+		$result = $route->parse('/media/search');
+		$this->assertEquals('Media', $result['controller']);
+		$this->assertEquals('searchIt', $result['action']);
+		$this->assertEquals([], $result['pass']);
+
+		$result = $route->parse('/media/search/tv_shows');
+		$this->assertEquals('Media', $result['controller']);
+		$this->assertEquals('searchIt', $result['action']);
+		$this->assertEquals(['tv_shows'], $result['pass']);
+	}
+
+}