1: <?php
2: /**
3: * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
4: * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
5: *
6: * Licensed under The MIT License
7: * For full copyright and license information, please see the LICENSE.txt
8: * Redistributions of files must retain the above copyright notice.
9: *
10: * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
11: * @link https://cakephp.org CakePHP(tm) Project
12: * @since 3.0.0
13: * @license https://opensource.org/licenses/mit-license.php MIT License
14: */
15: namespace Cake\Routing\Route;
16:
17: use Cake\Utility\Inflector;
18:
19: /**
20: * This route class will transparently inflect the controller, action and plugin
21: * routing parameters, so that requesting `/my-plugin/my-controller/my-action`
22: * is parsed as `['plugin' => 'MyPlugin', 'controller' => 'MyController', 'action' => 'myAction']`
23: */
24: class DashedRoute extends Route
25: {
26: /**
27: * Flag for tracking whether or not the defaults have been inflected.
28: *
29: * Default values need to be inflected so that they match the inflections that
30: * match() will create.
31: *
32: * @var bool
33: */
34: protected $_inflectedDefaults = false;
35:
36: /**
37: * Camelizes the previously dashed plugin route taking into account plugin vendors
38: *
39: * @param string $plugin Plugin name
40: * @return string
41: */
42: protected function _camelizePlugin($plugin)
43: {
44: $plugin = str_replace('-', '_', $plugin);
45: if (strpos($plugin, '/') === false) {
46: return Inflector::camelize($plugin);
47: }
48: list($vendor, $plugin) = explode('/', $plugin, 2);
49:
50: return Inflector::camelize($vendor) . '/' . Inflector::camelize($plugin);
51: }
52:
53: /**
54: * Parses a string URL into an array. If it matches, it will convert the
55: * controller and plugin keys to their CamelCased form and action key to
56: * camelBacked form.
57: *
58: * @param string $url The URL to parse
59: * @param string $method The HTTP method.
60: * @return array|false An array of request parameters, or false on failure.
61: */
62: public function parse($url, $method = '')
63: {
64: $params = parent::parse($url, $method);
65: if (!$params) {
66: return false;
67: }
68: if (!empty($params['controller'])) {
69: $params['controller'] = Inflector::camelize($params['controller'], '-');
70: }
71: if (!empty($params['plugin'])) {
72: $params['plugin'] = $this->_camelizePlugin($params['plugin']);
73: }
74: if (!empty($params['action'])) {
75: $params['action'] = Inflector::variable(str_replace(
76: '-',
77: '_',
78: $params['action']
79: ));
80: }
81:
82: return $params;
83: }
84:
85: /**
86: * Dasherizes the controller, action and plugin params before passing them on
87: * to the parent class.
88: *
89: * @param array $url Array of parameters to convert to a string.
90: * @param array $context An array of the current request context.
91: * Contains information such as the current host, scheme, port, and base
92: * directory.
93: * @return bool|string Either false or a string URL.
94: */
95: public function match(array $url, array $context = [])
96: {
97: $url = $this->_dasherize($url);
98: if (!$this->_inflectedDefaults) {
99: $this->_inflectedDefaults = true;
100: $this->defaults = $this->_dasherize($this->defaults);
101: }
102:
103: return parent::match($url, $context);
104: }
105:
106: /**
107: * Helper method for dasherizing keys in a URL array.
108: *
109: * @param array $url An array of URL keys.
110: * @return array
111: */
112: protected function _dasherize($url)
113: {
114: foreach (['controller', 'plugin', 'action'] as $element) {
115: if (!empty($url[$element])) {
116: $url[$element] = Inflector::dasherize($url[$element]);
117: }
118: }
119:
120: return $url;
121: }
122: }
123: