[ Index ] |
PHP Cross Reference of phpBB-3.1.12-deutsch |
[Summary view] [Print] [Text view]
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 * @throws \LogicException When the route regex is invalid 37 */ 38 public function dump(array $options = array()) 39 { 40 $options = array_merge(array( 41 'script_name' => 'app.php', 42 'base_uri' => '', 43 ), $options); 44 45 $options['script_name'] = self::escape($options['script_name'], ' ', '\\'); 46 47 $rules = array("# skip \"real\" requests\nRewriteCond %{REQUEST_FILENAME} -f\nRewriteRule .* - [QSA,L]"); 48 $methodVars = array(); 49 $hostRegexUnique = 0; 50 $prevHostRegex = ''; 51 52 foreach ($this->getRoutes()->all() as $name => $route) { 53 $compiledRoute = $route->compile(); 54 $hostRegex = $compiledRoute->getHostRegex(); 55 56 if (null !== $hostRegex && $prevHostRegex !== $hostRegex) { 57 $prevHostRegex = $hostRegex; 58 ++$hostRegexUnique; 59 60 $rule = array(); 61 62 $regex = $this->regexToApacheRegex($hostRegex); 63 $regex = self::escape($regex, ' ', '\\'); 64 65 $rule[] = sprintf('RewriteCond %%{HTTP:Host} %s', $regex); 66 67 $variables = array(); 68 $variables[] = sprintf('E=__ROUTING_host_%s:1', $hostRegexUnique); 69 70 foreach ($compiledRoute->getHostVariables() as $i => $variable) { 71 $variables[] = sprintf('E=__ROUTING_host_%s_%s:%%%d', $hostRegexUnique, $variable, $i + 1); 72 } 73 74 $variables = implode(',', $variables); 75 76 $rule[] = sprintf('RewriteRule .? - [%s]', $variables); 77 78 $rules[] = implode("\n", $rule); 79 } 80 81 $rules[] = $this->dumpRoute($name, $route, $options, $hostRegexUnique); 82 83 if ($req = $route->getRequirement('_method')) { 84 $methods = explode('|', strtoupper($req)); 85 $methodVars = array_merge($methodVars, $methods); 86 } 87 } 88 if (0 < count($methodVars)) { 89 $rule = array('# 405 Method Not Allowed'); 90 $methodVars = array_values(array_unique($methodVars)); 91 if (in_array('GET', $methodVars) && !in_array('HEAD', $methodVars)) { 92 $methodVars[] = 'HEAD'; 93 } 94 foreach ($methodVars as $i => $methodVar) { 95 $rule[] = sprintf('RewriteCond %%{ENV:_ROUTING__allow_%s} =1%s', $methodVar, isset($methodVars[$i + 1]) ? ' [OR]' : ''); 96 } 97 $rule[] = sprintf('RewriteRule .* %s [QSA,L]', $options['script_name']); 98 99 $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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |