|
0
|
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\Matcher\Dumper; |
|
|
13 |
|
|
|
14 |
use Symfony\Component\Routing\Route; |
|
|
15 |
|
|
|
16 |
/** |
|
|
17 |
* Dumps a set of Apache mod_rewrite rules. |
|
|
18 |
* |
|
|
19 |
* @author Fabien Potencier <fabien@symfony.com> |
|
|
20 |
* @author Kris Wallsmith <kris@symfony.com> |
|
|
21 |
*/ |
|
|
22 |
class ApacheMatcherDumper extends MatcherDumper |
|
|
23 |
{ |
|
|
24 |
/** |
|
|
25 |
* Dumps a set of Apache mod_rewrite rules. |
|
|
26 |
* |
|
|
27 |
* Available options: |
|
|
28 |
* |
|
|
29 |
* * script_name: The script name (app.php by default) |
|
|
30 |
* * base_uri: The base URI ("" by default) |
|
|
31 |
* |
|
|
32 |
* @param array $options An array of options |
|
|
33 |
* |
|
|
34 |
* @return string A string to be used as Apache rewrite rules |
|
|
35 |
*/ |
|
|
36 |
public function dump(array $options = array()) |
|
|
37 |
{ |
|
|
38 |
$options = array_merge(array( |
|
|
39 |
'script_name' => 'app.php', |
|
|
40 |
'base_uri' => '', |
|
|
41 |
), $options); |
|
|
42 |
|
|
|
43 |
$rules = array("# skip \"real\" requests\nRewriteCond %{REQUEST_FILENAME} -f\nRewriteRule .* - [QSA,L]"); |
|
|
44 |
$methodVars = array(); |
|
|
45 |
|
|
|
46 |
foreach ($this->getRoutes()->all() as $name => $route) { |
|
|
47 |
$compiledRoute = $route->compile(); |
|
|
48 |
|
|
|
49 |
// prepare the apache regex |
|
|
50 |
$regex = preg_replace('/\?P<.+?>/', '', substr(str_replace(array("\n", ' '), '', $compiledRoute->getRegex()), 1, -2)); |
|
|
51 |
$regex = '^'.preg_quote($options['base_uri']).substr($regex, 1); |
|
|
52 |
|
|
|
53 |
$hasTrailingSlash = '/$' == substr($regex, -2) && '^/$' != $regex; |
|
|
54 |
|
|
|
55 |
$variables = array('E=_ROUTING__route:'.$name); |
|
|
56 |
foreach ($compiledRoute->getVariables() as $i => $variable) { |
|
|
57 |
$variables[] = 'E=_ROUTING_'.$variable.':%'.($i + 1); |
|
|
58 |
} |
|
|
59 |
foreach ($route->getDefaults() as $key => $value) { |
|
|
60 |
// todo: a more legit way to escape the value? |
|
|
61 |
$variables[] = 'E=_ROUTING_'.$key.':'.strtr($value, array( |
|
|
62 |
':' => '\\:', |
|
|
63 |
'=' => '\\=', |
|
|
64 |
'\\' => '\\\\', |
|
|
65 |
' ' => '\\ ', |
|
|
66 |
)); |
|
|
67 |
} |
|
|
68 |
$variables = implode(',', $variables); |
|
|
69 |
|
|
|
70 |
$rule = array("# $name"); |
|
|
71 |
|
|
|
72 |
// method mismatch |
|
|
73 |
if ($req = $route->getRequirement('_method')) { |
|
|
74 |
$methods = explode('|', strtoupper($req)); |
|
|
75 |
// GET and HEAD are equivalent |
|
|
76 |
if (in_array('GET', $methods) && !in_array('HEAD', $methods)) { |
|
|
77 |
$methods[] = 'HEAD'; |
|
|
78 |
} |
|
|
79 |
$allow = array(); |
|
|
80 |
foreach ($methods as $method) { |
|
|
81 |
$methodVars[] = $method; |
|
|
82 |
$allow[] = 'E=_ROUTING__allow_'.$method.':1'; |
|
|
83 |
} |
|
|
84 |
|
|
|
85 |
$rule[] = "RewriteCond %{REQUEST_URI} $regex"; |
|
|
86 |
$rule[] = sprintf("RewriteCond %%{REQUEST_METHOD} !^(%s)$ [NC]", implode('|', $methods)); |
|
|
87 |
$rule[] = sprintf('RewriteRule .* - [S=%d,%s]', $hasTrailingSlash ? 2 : 1, implode(',', $allow)); |
|
|
88 |
} |
|
|
89 |
|
|
|
90 |
// redirect with trailing slash appended |
|
|
91 |
if ($hasTrailingSlash) { |
|
|
92 |
$rule[] = 'RewriteCond %{REQUEST_URI} '.substr($regex, 0, -2).'$'; |
|
|
93 |
$rule[] = 'RewriteRule .* $0/ [QSA,L,R=301]'; |
|
|
94 |
} |
|
|
95 |
|
|
|
96 |
// the main rule |
|
|
97 |
$rule[] = "RewriteCond %{REQUEST_URI} $regex"; |
|
|
98 |
$rule[] = "RewriteRule .* {$options['script_name']} [QSA,L,$variables]"; |
|
|
99 |
|
|
|
100 |
$rules[] = implode("\n", $rule); |
|
|
101 |
} |
|
|
102 |
|
|
|
103 |
if (0 < count($methodVars)) { |
|
|
104 |
$rule = array('# 405 Method Not Allowed'); |
|
|
105 |
$methodVars = array_values(array_unique($methodVars)); |
|
|
106 |
foreach ($methodVars as $i => $methodVar) { |
|
|
107 |
$rule[] = sprintf('RewriteCond %%{_ROUTING__allow_%s} !-z%s', $methodVar, isset($methodVars[$i + 1]) ? ' [OR]' : ''); |
|
|
108 |
} |
|
|
109 |
$rule[] = sprintf('RewriteRule .* %s [QSA,L]', $options['script_name']); |
|
|
110 |
|
|
|
111 |
$rules[] = implode("\n", $rule); |
|
|
112 |
} |
|
|
113 |
|
|
|
114 |
return implode("\n\n", $rules)."\n"; |
|
|
115 |
} |
|
|
116 |
} |