1 <?php
2 /**
3 * @package Joomla.Platform
4 * @subpackage Application
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 */
9
10 defined('JPATH_PLATFORM') or die;
11
12 /**
13 * Basic Web application router class for the Joomla Platform.
14 *
15 * @since 12.2
16 * @deprecated 3.7.0 Use the `joomla/router` package via Composer instead
17 */
18 class JApplicationWebRouterBase extends JApplicationWebRouter
19 {
20 /**
21 * @var array An array of rules, each rule being an associative array('regex'=> $regex, 'vars' => $vars, 'controller' => $controller)
22 * for routing the request.
23 * @since 12.2
24 */
25 protected $maps = array();
26
27 /**
28 * Add a route map to the router. If the pattern already exists it will be overwritten.
29 *
30 * @param string $pattern The route pattern to use for matching.
31 * @param string $controller The controller name to map to the given pattern.
32 *
33 * @return JApplicationWebRouter This object for method chaining.
34 *
35 * @since 12.2
36 */
37 public function addMap($pattern, $controller)
38 {
39 // Sanitize and explode the pattern.
40 $pattern = explode('/', trim(parse_url((string) $pattern, PHP_URL_PATH), ' /'));
41
42 // Prepare the route variables
43 $vars = array();
44
45 // Initialize regular expression
46 $regex = array();
47
48 // Loop on each segment
49 foreach ($pattern as $segment)
50 {
51 // Match a splat with no variable.
52 if ($segment == '*')
53 {
54 $regex[] = '.*';
55 }
56 // Match a splat and capture the data to a named variable.
57 elseif ($segment[0] == '*')
58 {
59 $vars[] = substr($segment, 1);
60 $regex[] = '(.*)';
61 }
62 // Match an escaped splat segment.
63 elseif ($segment[0] == '\\' && $segment[1] == '*')
64 {
65 $regex[] = '\*' . preg_quote(substr($segment, 2));
66 }
67 // Match an unnamed variable without capture.
68 elseif ($segment == ':')
69 {
70 $regex[] = '[^/]*';
71 }
72 // Match a named variable and capture the data.
73 elseif ($segment[0] == ':')
74 {
75 $vars[] = substr($segment, 1);
76 $regex[] = '([^/]*)';
77 }
78 // Match a segment with an escaped variable character prefix.
79 elseif ($segment[0] == '\\' && $segment[1] == ':')
80 {
81 $regex[] = preg_quote(substr($segment, 1));
82 }
83 // Match the standard segment.
84 else
85 {
86 $regex[] = preg_quote($segment);
87 }
88 }
89
90 $this->maps[] = array(
91 'regex' => chr(1) . '^' . implode('/', $regex) . '$' . chr(1),
92 'vars' => $vars,
93 'controller' => (string) $controller,
94 );
95
96 return $this;
97 }
98
99 /**
100 * Add a route map to the router. If the pattern already exists it will be overwritten.
101 *
102 * @param array $maps A list of route maps to add to the router as $pattern => $controller.
103 *
104 * @return JApplicationWebRouter This object for method chaining.
105 *
106 * @since 12.2
107 */
108 public function addMaps($maps)
109 {
110 foreach ($maps as $pattern => $controller)
111 {
112 $this->addMap($pattern, $controller);
113 }
114
115 return $this;
116 }
117
118 /**
119 * Parse the given route and return the name of a controller mapped to the given route.
120 *
121 * @param string $route The route string for which to find and execute a controller.
122 *
123 * @return string The controller name for the given route excluding prefix.
124 *
125 * @since 12.2
126 * @throws InvalidArgumentException
127 */
128 protected function parseRoute($route)
129 {
130 $controller = false;
131
132 // Trim the query string off.
133 $route = preg_replace('/([^?]*).*/u', '\1', $route);
134
135 // Sanitize and explode the route.
136 $route = trim(parse_url($route, PHP_URL_PATH), ' /');
137
138 // If the route is empty then simply return the default route. No parsing necessary.
139 if ($route == '')
140 {
141 return $this->default;
142 }
143
144 // Iterate through all of the known route maps looking for a match.
145 foreach ($this->maps as $rule)
146 {
147 if (preg_match($rule['regex'], $route, $matches))
148 {
149 // If we have gotten this far then we have a positive match.
150 $controller = $rule['controller'];
151
152 // Time to set the input variables.
153 // We are only going to set them if they don't already exist to avoid overwriting things.
154 foreach ($rule['vars'] as $i => $var)
155 {
156 $this->input->def($var, $matches[$i + 1]);
157
158 // Don't forget to do an explicit set on the GET superglobal.
159 $this->input->get->def($var, $matches[$i + 1]);
160 }
161
162 $this->input->def('_rawRoute', $route);
163
164 break;
165 }
166 }
167
168 // We were unable to find a route match for the request. Panic.
169 if (!$controller)
170 {
171 throw new InvalidArgumentException(sprintf('Unable to handle request for route `%s`.', $route), 404);
172 }
173
174 return $controller;
175 }
176 }
177