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