[Routing] added hostname matching support to UrlGenerator

This commit is contained in:
Arnaud Le Blanc 2012-04-14 19:20:48 +02:00
parent 7a15e006e6
commit 805806a1e8
3 changed files with 35 additions and 5 deletions

View File

@ -91,6 +91,7 @@ EOF;
$properties[] = $route->getDefaults();
$properties[] = $route->getRequirements();
$properties[] = $compiledRoute->getTokens();
$properties[] = $compiledRoute->getHostnameTokens();
$routes .= sprintf(" '%s' => %s,\n", $name, str_replace("\n", '', var_export($properties, true)));
}
@ -113,9 +114,9 @@ EOF;
throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', \$name));
}
list(\$variables, \$defaults, \$requirements, \$tokens) = self::\$declaredRoutes[\$name];
list(\$variables, \$defaults, \$requirements, \$tokens, \$hostnameTokens) = self::\$declaredRoutes[\$name];
return \$this->doGenerate(\$variables, \$defaults, \$requirements, \$tokens, \$parameters, \$name, \$absolute);
return \$this->doGenerate(\$variables, \$defaults, \$requirements, \$tokens, \$parameters, \$name, \$absolute, \$hostnameTokens);
}
EOF;
}

View File

@ -122,14 +122,14 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
// the Route has a cache of its own and is not recompiled as long as it does not get modified
$compiledRoute = $route->compile();
return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $absolute);
return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $absolute, $compiledRoute->getHostnameTokens());
}
/**
* @throws MissingMandatoryParametersException When route has some missing mandatory parameters
* @throws InvalidParameterException When a parameter value is not correct
*/
protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute)
protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute, $hostnameTokens)
{
$variables = array_flip($variables);
$mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters);
@ -185,6 +185,25 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
$url = substr($url, 0, -1) . '%2E';
}
if ($hostnameTokens) {
$host = '';
foreach ($hostnameTokens as $token) {
if ('variable' === $token[0]) {
if (in_array($tparams[$token[3]], array(null, '', false), true)) {
// check requirement
if ($tparams[$token[3]] && !preg_match('#^'.$token[2].'$#', $tparams[$token[3]])) {
throw new InvalidParameterException(sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given).', $token[3], $name, $token[2], $tparams[$token[3]]));
}
}
$host = $token[1].$tparams[$token[3]].$host;
} elseif ('text' === $token[0]) {
$host = $token[1].$host;
}
}
}
// add a query string if needed
$extra = array_diff_key($parameters, $variables);
if ($extra && $query = http_build_query($extra, '', '&')) {
@ -198,7 +217,16 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
$scheme = $req;
}
if ($hostnameTokens) {
$absolute = true;
}
if ($absolute) {
if (!$hostnameTokens) {
$host = $this->context->getHost();
}
$port = '';
if ('http' === $scheme && 80 != $this->context->getHttpPort()) {
$port = ':'.$this->context->getHttpPort();
@ -206,7 +234,7 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
$port = ':'.$this->context->getHttpsPort();
}
$url = $scheme.'://'.$this->context->getHost().$port.$url;
$url = $scheme.'://'.$host.$port.$url;
}
}

View File

@ -15,6 +15,7 @@ use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Matcher\Dumper\DumperCollection;
class PhpGeneratorDumperTest extends \PHPUnit_Framework_TestCase
{