Skip to content

Commit

Permalink
[Routing] added hostname matching support to UrlGenerator
Browse files Browse the repository at this point in the history
  • Loading branch information
arnaud-lb committed Nov 12, 2012
1 parent 7a15e00 commit 805806a
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 5 deletions.
Expand Up @@ -91,6 +91,7 @@ private function generateDeclaredRoutes()
$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)));
}
Expand All @@ -113,9 +114,9 @@ public function generate(\$name, \$parameters = array(), \$absolute = false)
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;
}
Expand Down
34 changes: 31 additions & 3 deletions src/Symfony/Component/Routing/Generator/UrlGenerator.php
Expand Up @@ -122,14 +122,14 @@ public function generate($name, $parameters = array(), $absolute = false)
// 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);
Expand Down Expand Up @@ -185,6 +185,25 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa
$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, '', '&')) {
Expand All @@ -198,15 +217,24 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa
$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();
} elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) {
$port = ':'.$this->context->getHttpsPort();
}

$url = $scheme.'://'.$this->context->getHost().$port.$url;
$url = $scheme.'://'.$host.$port.$url;
}
}

Expand Down
Expand Up @@ -15,6 +15,7 @@
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
{
Expand Down

0 comments on commit 805806a

Please sign in to comment.