|
1 <?php |
|
2 |
|
3 /* |
|
4 * This file is part of the Symfony package. |
|
5 * |
|
6 * (c) Fabien Potencier <fabien@symfony.com> |
|
7 * |
|
8 * For the full copyright and license information, please view the LICENSE |
|
9 * file that was distributed with this source code. |
|
10 */ |
|
11 |
|
12 namespace Symfony\Component\Routing; |
|
13 |
|
14 /** |
|
15 * A Route describes a route and its parameters. |
|
16 * |
|
17 * @author Fabien Potencier <fabien@symfony.com> |
|
18 * |
|
19 * @api |
|
20 */ |
|
21 class Route |
|
22 { |
|
23 private $pattern; |
|
24 private $defaults; |
|
25 private $requirements; |
|
26 private $options; |
|
27 private $compiled; |
|
28 |
|
29 static private $compilers = array(); |
|
30 |
|
31 /** |
|
32 * Constructor. |
|
33 * |
|
34 * Available options: |
|
35 * |
|
36 * * compiler_class: A class name able to compile this route instance (RouteCompiler by default) |
|
37 * |
|
38 * @param string $pattern The pattern to match |
|
39 * @param array $defaults An array of default parameter values |
|
40 * @param array $requirements An array of requirements for parameters (regexes) |
|
41 * @param array $options An array of options |
|
42 * |
|
43 * @api |
|
44 */ |
|
45 public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array()) |
|
46 { |
|
47 $this->setPattern($pattern); |
|
48 $this->setDefaults($defaults); |
|
49 $this->setRequirements($requirements); |
|
50 $this->setOptions($options); |
|
51 } |
|
52 |
|
53 /** |
|
54 * Returns the pattern. |
|
55 * |
|
56 * @return string The pattern |
|
57 */ |
|
58 public function getPattern() |
|
59 { |
|
60 return $this->pattern; |
|
61 } |
|
62 |
|
63 /** |
|
64 * Sets the pattern. |
|
65 * |
|
66 * This method implements a fluent interface. |
|
67 * |
|
68 * @param string $pattern The pattern |
|
69 * |
|
70 * @return Route The current Route instance |
|
71 */ |
|
72 public function setPattern($pattern) |
|
73 { |
|
74 $this->pattern = trim($pattern); |
|
75 |
|
76 // a route must start with a slash |
|
77 if (empty($this->pattern) || '/' !== $this->pattern[0]) { |
|
78 $this->pattern = '/'.$this->pattern; |
|
79 } |
|
80 |
|
81 return $this; |
|
82 } |
|
83 |
|
84 /** |
|
85 * Returns the options. |
|
86 * |
|
87 * @return array The options |
|
88 */ |
|
89 public function getOptions() |
|
90 { |
|
91 return $this->options; |
|
92 } |
|
93 |
|
94 /** |
|
95 * Sets the options. |
|
96 * |
|
97 * This method implements a fluent interface. |
|
98 * |
|
99 * @param array $options The options |
|
100 * |
|
101 * @return Route The current Route instance |
|
102 */ |
|
103 public function setOptions(array $options) |
|
104 { |
|
105 $this->options = array_merge(array( |
|
106 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler', |
|
107 ), $options); |
|
108 |
|
109 return $this; |
|
110 } |
|
111 |
|
112 /** |
|
113 * Sets an option value. |
|
114 * |
|
115 * This method implements a fluent interface. |
|
116 * |
|
117 * @param string $name An option name |
|
118 * @param mixed $value The option value |
|
119 * |
|
120 * @return Route The current Route instance |
|
121 * |
|
122 * @api |
|
123 */ |
|
124 public function setOption($name, $value) |
|
125 { |
|
126 $this->options[$name] = $value; |
|
127 |
|
128 return $this; |
|
129 } |
|
130 |
|
131 /** |
|
132 * Get an option value. |
|
133 * |
|
134 * @param string $name An option name |
|
135 * |
|
136 * @return mixed The option value |
|
137 */ |
|
138 public function getOption($name) |
|
139 { |
|
140 return isset($this->options[$name]) ? $this->options[$name] : null; |
|
141 } |
|
142 |
|
143 /** |
|
144 * Returns the defaults. |
|
145 * |
|
146 * @return array The defaults |
|
147 */ |
|
148 public function getDefaults() |
|
149 { |
|
150 return $this->defaults; |
|
151 } |
|
152 |
|
153 /** |
|
154 * Sets the defaults. |
|
155 * |
|
156 * This method implements a fluent interface. |
|
157 * |
|
158 * @param array $defaults The defaults |
|
159 * |
|
160 * @return Route The current Route instance |
|
161 */ |
|
162 public function setDefaults(array $defaults) |
|
163 { |
|
164 $this->defaults = array(); |
|
165 foreach ($defaults as $name => $default) { |
|
166 $this->defaults[(string) $name] = $default; |
|
167 } |
|
168 |
|
169 return $this; |
|
170 } |
|
171 |
|
172 /** |
|
173 * Gets a default value. |
|
174 * |
|
175 * @param string $name A variable name |
|
176 * |
|
177 * @return mixed The default value |
|
178 */ |
|
179 public function getDefault($name) |
|
180 { |
|
181 return isset($this->defaults[$name]) ? $this->defaults[$name] : null; |
|
182 } |
|
183 |
|
184 /** |
|
185 * Checks if a default value is set for the given variable. |
|
186 * |
|
187 * @param string $name A variable name |
|
188 * |
|
189 * @return Boolean true if the default value is set, false otherwise |
|
190 */ |
|
191 public function hasDefault($name) |
|
192 { |
|
193 return array_key_exists($name, $this->defaults); |
|
194 } |
|
195 |
|
196 /** |
|
197 * Sets a default value. |
|
198 * |
|
199 * @param string $name A variable name |
|
200 * @param mixed $default The default value |
|
201 * |
|
202 * @return Route The current Route instance |
|
203 * |
|
204 * @api |
|
205 */ |
|
206 public function setDefault($name, $default) |
|
207 { |
|
208 $this->defaults[(string) $name] = $default; |
|
209 |
|
210 return $this; |
|
211 } |
|
212 |
|
213 /** |
|
214 * Returns the requirements. |
|
215 * |
|
216 * @return array The requirements |
|
217 */ |
|
218 public function getRequirements() |
|
219 { |
|
220 return $this->requirements; |
|
221 } |
|
222 |
|
223 /** |
|
224 * Sets the requirements. |
|
225 * |
|
226 * This method implements a fluent interface. |
|
227 * |
|
228 * @param array $requirements The requirements |
|
229 * |
|
230 * @return Route The current Route instance |
|
231 */ |
|
232 public function setRequirements(array $requirements) |
|
233 { |
|
234 $this->requirements = array(); |
|
235 foreach ($requirements as $key => $regex) { |
|
236 $this->requirements[$key] = $this->sanitizeRequirement($key, $regex); |
|
237 } |
|
238 |
|
239 return $this; |
|
240 } |
|
241 |
|
242 /** |
|
243 * Returns the requirement for the given key. |
|
244 * |
|
245 * @param string $key The key |
|
246 * @return string The regex |
|
247 */ |
|
248 public function getRequirement($key) |
|
249 { |
|
250 return isset($this->requirements[$key]) ? $this->requirements[$key] : null; |
|
251 } |
|
252 |
|
253 /** |
|
254 * Sets a requirement for the given key. |
|
255 * |
|
256 * @param string $key The key |
|
257 * @param string $regex The regex |
|
258 * |
|
259 * @return Route The current Route instance |
|
260 * |
|
261 * @api |
|
262 */ |
|
263 public function setRequirement($key, $regex) |
|
264 { |
|
265 $this->requirements[$key] = $this->sanitizeRequirement($key, $regex); |
|
266 |
|
267 return $this; |
|
268 } |
|
269 |
|
270 /** |
|
271 * Compiles the route. |
|
272 * |
|
273 * @return CompiledRoute A CompiledRoute instance |
|
274 */ |
|
275 public function compile() |
|
276 { |
|
277 if (null !== $this->compiled) { |
|
278 return $this->compiled; |
|
279 } |
|
280 |
|
281 $class = $this->getOption('compiler_class'); |
|
282 |
|
283 if (!isset(static::$compilers[$class])) { |
|
284 static::$compilers[$class] = new $class; |
|
285 } |
|
286 |
|
287 return $this->compiled = static::$compilers[$class]->compile($this); |
|
288 } |
|
289 |
|
290 private function sanitizeRequirement($key, $regex) |
|
291 { |
|
292 if (is_array($regex)) { |
|
293 throw new \InvalidArgumentException(sprintf('Routing requirements must be a string, array given for "%s"', $key)); |
|
294 } |
|
295 |
|
296 if ('^' == $regex[0]) { |
|
297 $regex = substr($regex, 1); |
|
298 } |
|
299 |
|
300 if ('$' == substr($regex, -1)) { |
|
301 $regex = substr($regex, 0, -1); |
|
302 } |
|
303 |
|
304 return $regex; |
|
305 } |
|
306 } |