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