Verzeichnisstruktur phpBB-3.1.0
- Veröffentlicht
- 27.10.2014
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
ApacheMatcherDumper.php
001 <?php
002
003 /*
004 * This file is part of the Symfony package.
005 *
006 * (c) Fabien Potencier <fabien@symfony.com>
007 *
008 * For the full copyright and license information, please view the LICENSE
009 * file that was distributed with this source code.
010 */
011
012 namespace Symfony\Component\Routing\Matcher\Dumper;
013
014 use Symfony\Component\Routing\Route;
015
016 /**
017 * Dumps a set of Apache mod_rewrite rules.
018 *
019 * @author Fabien Potencier <fabien@symfony.com>
020 * @author Kris Wallsmith <kris@symfony.com>
021 */
022 class ApacheMatcherDumper extends MatcherDumper
023 {
024 /**
025 * Dumps a set of Apache mod_rewrite rules.
026 *
027 * Available options:
028 *
029 * * script_name: The script name (app.php by default)
030 * * base_uri: The base URI ("" by default)
031 *
032 * @param array $options An array of options
033 *
034 * @return string A string to be used as Apache rewrite rules
035 *
036 * @throws \LogicException When the route regex is invalid
037 */
038 public function dump(array $options = array())
039 {
040 $options = array_merge(array(
041 'script_name' => 'app.php',
042 'base_uri' => '',
043 ), $options);
044
045 $options['script_name'] = self::escape($options['script_name'], ' ', '\\');
046
047 $rules = array("# skip \"real\" requests\nRewriteCond %{REQUEST_FILENAME} -f\nRewriteRule .* - [QSA,L]");
048 $methodVars = array();
049 $hostRegexUnique = 0;
050 $prevHostRegex = '';
051
052 foreach ($this->getRoutes()->all() as $name => $route) {
053 $compiledRoute = $route->compile();
054 $hostRegex = $compiledRoute->getHostRegex();
055
056 if (null !== $hostRegex && $prevHostRegex !== $hostRegex) {
057 $prevHostRegex = $hostRegex;
058 $hostRegexUnique++;
059
060 $rule = array();
061
062 $regex = $this->regexToApacheRegex($hostRegex);
063 $regex = self::escape($regex, ' ', '\\');
064
065 $rule[] = sprintf('RewriteCond %%{HTTP:Host} %s', $regex);
066
067 $variables = array();
068 $variables[] = sprintf('E=__ROUTING_host_%s:1', $hostRegexUnique);
069
070 foreach ($compiledRoute->getHostVariables() as $i => $variable) {
071 $variables[] = sprintf('E=__ROUTING_host_%s_%s:%%%d', $hostRegexUnique, $variable, $i+1);
072 }
073
074 $variables = implode(',', $variables);
075
076 $rule[] = sprintf('RewriteRule .? - [%s]', $variables);
077
078 $rules[] = implode("\n", $rule);
079 }
080
081 $rules[] = $this->dumpRoute($name, $route, $options, $hostRegexUnique);
082
083 if ($req = $route->getRequirement('_method')) {
084 $methods = explode('|', strtoupper($req));
085 $methodVars = array_merge($methodVars, $methods);
086 }
087 }
088 if (0 < count($methodVars)) {
089 $rule = array('# 405 Method Not Allowed');
090 $methodVars = array_values(array_unique($methodVars));
091 if (in_array('GET', $methodVars) && !in_array('HEAD', $methodVars)) {
092 $methodVars[] = 'HEAD';
093 }
094 foreach ($methodVars as $i => $methodVar) {
095 $rule[] = sprintf('RewriteCond %%{ENV:_ROUTING__allow_%s} =1%s', $methodVar, isset($methodVars[$i + 1]) ? ' [OR]' : '');
096 }
097 $rule[] = sprintf('RewriteRule .* %s [QSA,L]', $options['script_name']);
098
099 $rules[] = implode("\n", $rule);
100 }
101
102 return implode("\n\n", $rules)."\n";
103 }
104
105 /**
106 * Dumps a single route
107 *
108 * @param string $name Route name
109 * @param Route $route The route
110 * @param array $options Options
111 * @param bool $hostRegexUnique Unique identifier for the host regex
112 *
113 * @return string The compiled route
114 */
115 private function dumpRoute($name, $route, array $options, $hostRegexUnique)
116 {
117 $compiledRoute = $route->compile();
118
119 // prepare the apache regex
120 $regex = $this->regexToApacheRegex($compiledRoute->getRegex());
121 $regex = '^'.self::escape(preg_quote($options['base_uri']).substr($regex, 1), ' ', '\\');
122
123 $methods = $this->getRouteMethods($route);
124
125 $hasTrailingSlash = (!$methods || in_array('HEAD', $methods)) && '/$' === substr($regex, -2) && '^/$' !== $regex;
126
127 $variables = array('E=_ROUTING_route:'.$name);
128 foreach ($compiledRoute->getHostVariables() as $variable) {
129 $variables[] = sprintf('E=_ROUTING_param_%s:%%{ENV:__ROUTING_host_%s_%s}', $variable, $hostRegexUnique, $variable);
130 }
131 foreach ($compiledRoute->getPathVariables() as $i => $variable) {
132 $variables[] = 'E=_ROUTING_param_'.$variable.':%'.($i + 1);
133 }
134 foreach ($this->normalizeValues($route->getDefaults()) as $key => $value) {
135 $variables[] = 'E=_ROUTING_default_'.$key.':'.strtr($value, array(
136 ':' => '\\:',
137 '=' => '\\=',
138 '\\' => '\\\\',
139 ' ' => '\\ ',
140 ));
141 }
142 $variables = implode(',', $variables);
143
144 $rule = array("# $name");
145
146 // method mismatch
147 if (0 < count($methods)) {
148 $allow = array();
149 foreach ($methods as $method) {
150 $allow[] = 'E=_ROUTING_allow_'.$method.':1';
151 }
152
153 if ($compiledRoute->getHostRegex()) {
154 $rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_host_%s} =1", $hostRegexUnique);
155 }
156
157 $rule[] = "RewriteCond %{REQUEST_URI} $regex";
158 $rule[] = sprintf("RewriteCond %%{REQUEST_METHOD} !^(%s)$ [NC]", implode('|', $methods));
159 $rule[] = sprintf('RewriteRule .* - [S=%d,%s]', $hasTrailingSlash ? 2 : 1, implode(',', $allow));
160 }
161
162 // redirect with trailing slash appended
163 if ($hasTrailingSlash) {
164 if ($compiledRoute->getHostRegex()) {
165 $rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_host_%s} =1", $hostRegexUnique);
166 }
167
168 $rule[] = 'RewriteCond %{REQUEST_URI} '.substr($regex, 0, -2).'$';
169 $rule[] = 'RewriteRule .* $0/ [QSA,L,R=301]';
170 }
171
172 // the main rule
173
174 if ($compiledRoute->getHostRegex()) {
175 $rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_host_%s} =1", $hostRegexUnique);
176 }
177
178 $rule[] = "RewriteCond %{REQUEST_URI} $regex";
179 $rule[] = "RewriteRule .* {$options['script_name']} [QSA,L,$variables]";
180
181 return implode("\n", $rule);
182 }
183
184 /**
185 * Returns methods allowed for a route
186 *
187 * @param Route $route The route
188 *
189 * @return array The methods
190 */
191 private function getRouteMethods(Route $route)
192 {
193 $methods = array();
194 if ($req = $route->getRequirement('_method')) {
195 $methods = explode('|', strtoupper($req));
196 // GET and HEAD are equivalent
197 if (in_array('GET', $methods) && !in_array('HEAD', $methods)) {
198 $methods[] = 'HEAD';
199 }
200 }
201
202 return $methods;
203 }
204
205 /**
206 * Converts a regex to make it suitable for mod_rewrite
207 *
208 * @param string $regex The regex
209 *
210 * @return string The converted regex
211 */
212 private function regexToApacheRegex($regex)
213 {
214 $regexPatternEnd = strrpos($regex, $regex[0]);
215
216 return preg_replace('/\?P<.+?>/', '', substr($regex, 1, $regexPatternEnd - 1));
217 }
218
219 /**
220 * Escapes a string.
221 *
222 * @param string $string The string to be escaped
223 * @param string $char The character to be escaped
224 * @param string $with The character to be used for escaping
225 *
226 * @return string The escaped string
227 */
228 private static function escape($string, $char, $with)
229 {
230 $escaped = false;
231 $output = '';
232 foreach (str_split($string) as $symbol) {
233 if ($escaped) {
234 $output .= $symbol;
235 $escaped = false;
236 continue;
237 }
238 if ($symbol === $char) {
239 $output .= $with.$char;
240 continue;
241 }
242 if ($symbol === $with) {
243 $escaped = true;
244 }
245 $output .= $symbol;
246 }
247
248 return $output;
249 }
250
251 /**
252 * Normalizes an array of values.
253 *
254 * @param array $values
255 *
256 * @return string[]
257 */
258 private function normalizeValues(array $values)
259 {
260 $normalizedValues = array();
261 foreach ($values as $key => $value) {
262 if (is_array($value)) {
263 foreach ($value as $index => $bit) {
264 $normalizedValues[sprintf('%s[%s]', $key, $index)] = $bit;
265 }
266 } else {
267 $normalizedValues[$key] = (string) $value;
268 }
269 }
270
271 return $normalizedValues;
272 }
273 }
274