This commit is contained in:
Arnaud Le Blanc 2012-11-05 20:53:57 +01:00
parent 8366b8ab27
commit 6cd34570d7
22 changed files with 94 additions and 77 deletions

View File

@ -93,7 +93,7 @@ EOF
? implode(', ', $requirements['_method']) : $requirements['_method']
)
: 'ANY';
$hostname = null !== $route->getHostnamePattern()
$hostname = '' !== $route->getHostnamePattern()
? $route->getHostnamePattern() : 'ANY';
$maxName = max($maxName, strlen($name));

View File

@ -30,14 +30,14 @@ class CompiledRoute
/**
* Constructor.
*
* @param string $staticPrefix The static prefix of the compiled route
* @param string $regex The regular expression to use to match this route
* @param array $tokens An array of tokens to use to generate URL for this route
* @param array $pathVariables An array of path variables
* @param array $hostnameRegex Hostname regex
* @param array $hostnameTokens Hostname tokens
* @param array $hostnameVariables An array of hostname variables
* @param array $variables An array of variables (variables defined in the path and in the hostname patterns)
* @param string $staticPrefix The static prefix of the compiled route
* @param string $regex The regular expression to use to match this route
* @param array $tokens An array of tokens to use to generate URL for this route
* @param array $pathVariables An array of path variables
* @param array $hostnameRegex|null Hostname regex
* @param array $hostnameTokens Hostname tokens
* @param array $hostnameVariables An array of hostname variables
* @param array $variables An array of variables (variables defined in the path and in the hostname patterns)
*/
public function __construct($staticPrefix, $regex, array $tokens, array $pathVariables, $hostnameRegex = null, array $hostnameTokens = array(), array $hostnameVariables = array(), array $variables = array())
{
@ -74,7 +74,7 @@ class CompiledRoute
/**
* Returns the hostname regex
*
* @return string The hostname regex
* @return string|null The hostname regex or null
*/
public function getHostnameRegex()
{

View File

@ -101,7 +101,7 @@ abstract class AnnotationClassLoader implements LoaderInterface
'requirements' => array(),
'options' => array(),
'defaults' => array(),
'hostname_pattern' => null,
'hostname_pattern' => '',
);
$class = new \ReflectionClass($class);

View File

@ -70,7 +70,7 @@ class YamlFileLoader extends FileLoader
$defaults = isset($config['defaults']) ? $config['defaults'] : array();
$requirements = isset($config['requirements']) ? $config['requirements'] : array();
$options = isset($config['options']) ? $config['options'] : array();
$hostnamePattern = isset($config['hostname_pattern']) ? $config['hostname_pattern'] : null;
$hostnamePattern = isset($config['hostname_pattern']) ? $config['hostname_pattern'] : '';
$this->setCurrentDir(dirname($path));
$collection->addCollection($this->import($config['resource'], $type, false, $file), $prefix, $defaults, $requirements, $options, $hostnamePattern);

View File

@ -111,6 +111,7 @@ class ApacheMatcherDumper extends MatcherDumper
* @param Route $route The route
* @param array $options Options
* @param bool $hostnameRegexUnique Unique identifier for the hostname regex
*
* @return string The compiled route
*/
private function dumpRoute($name, $route, array $options, $hostnameRegexUnique)

View File

@ -102,7 +102,7 @@ class DumperCollection implements \IteratorAggregate
/**
* Returns true if the attribute is defined.
*
* @param string $name The attribute name
* @param string $name The attribute name
*
* @return Boolean true if the attribute is defined, false otherwise
*/
@ -117,7 +117,7 @@ class DumperCollection implements \IteratorAggregate
* @param string $name The attribute name
* @param mixed $default Default value is the attribute doesn't exist
*
* @return mixed The attribute value
* @return mixed The attribute value
*/
public function getAttribute($name, $default = null)
{
@ -138,7 +138,7 @@ class DumperCollection implements \IteratorAggregate
/**
* Sets multiple attributes.
*
* @param array $attributes The attributes
* @param array $attributes The attributes
*/
public function setAttributes($attributes)
{

View File

@ -144,9 +144,9 @@ EOF;
/**
* Generates PHP code recursively to match a tree of routes
*
* @param DumperPrefixCollection $routes A DumperPrefixCollection instance
* @param DumperPrefixCollection $routes A DumperPrefixCollection instance
* @param Boolean $supportsRedirections Whether redirections are supported by the base class
* @parma string $prefix Prefix of the parent collection
* @parma string $prefix Prefix of the parent collection
*
* @return string PHP code
*/
@ -302,7 +302,11 @@ EOF;
if ($hostnameMatches) {
$vars[] = '$hostnameMatches';
}
$matchesExpr = implode(' + ', $vars);
if (count($vars) > 1) {
$matchesExpr = 'array_merge(' . implode(', ', array_reverse($vars)) . ')';
} else {
$matchesExpr = current($vars);
}
$code .= sprintf(" return array_merge(\$this->mergeDefaults(%s, %s), array('_route' => '%s'));\n"
, $matchesExpr, str_replace("\n", '', var_export($route->getDefaults(), true)), $name);
@ -313,7 +317,7 @@ EOF;
$code .= " \$matches = \$hostnameMatches;\n";
} else {
if ($hostnameMatches) {
$code .= " \$matches = \$matches + \$hostnameMatches;\n";
$code .= " \$matches = array_merge(\$hostnameMatches, \$matches);\n";
}
}
@ -336,8 +340,8 @@ EOF;
/**
* Flattens a tree of routes to a single collection.
*
* @param RouteCollection $routes Collection of routes
* @param DumperCollection $to A DumperCollection to add routes to
* @param RouteCollection $routes Collection of routes
* @param DumperCollection $to A DumperCollection to add routes to
*
* @return DumperCollection
*/
@ -394,7 +398,7 @@ EOF;
* Routes order is preserved such that traversing the tree will traverse the
* routes in the origin order
*
* @param DumperCollection $collection A collection of routes
* @param DumperCollection $collection A collection of routes
*
* @return DumperPrefixCollection
*/

View File

@ -147,7 +147,7 @@ class UrlMatcher implements UrlMatcherInterface
continue;
}
return array_merge($this->mergeDefaults($hostnameMatches + $matches, $route->getDefaults()), array('_route' => $name));
return array_merge($this->mergeDefaults(array_merge($matches, $hostnameMatches), $route->getDefaults()), array('_route' => $name));
}
}

View File

@ -44,7 +44,7 @@ class Route implements \Serializable
*
* @api
*/
public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array(), $hostnamePattern = null)
public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array(), $hostnamePattern = '')
{
$this->setPattern($pattern);
$this->setDefaults($defaults);
@ -106,14 +106,24 @@ class Route implements \Serializable
return $this;
}
/**
* Returns the hostname pattern.
*
* @return string The pattern
*/
public function getHostnamePattern()
{
return $this->hostnamePattern;
}
/**
* Sets the hostname pattern.
*
* @param string $pattern The pattern
*/
public function setHostnamePattern($pattern)
{
$this->hostnamePattern = $pattern;
$this->hostnamePattern = (string) $pattern;
return $this;
}

View File

@ -42,7 +42,7 @@ class RouteCollection implements \IteratorAggregate, \Countable
$this->routes = array();
$this->resources = array();
$this->prefix = '';
$this->hostnamePattern = null;
$this->hostnamePattern = '';
}
public function __clone()
@ -185,18 +185,18 @@ class RouteCollection implements \IteratorAggregate, \Countable
/**
* Adds a route collection to the current set of routes (at the end of the current set).
*
* @param RouteCollection $collection A RouteCollection instance
* @param string $prefix An optional prefix to add before each pattern of the route collection
* @param array $defaults An array of default values
* @param array $requirements An array of requirements
* @param array $options An array of options
* @param string $hostnamePattern Hostname pattern
* @param RouteCollection $collection A RouteCollection instance
* @param string $prefix An optional prefix to add before each pattern of the route collection
* @param array $defaults An array of default values
* @param array $requirements An array of requirements
* @param array $options An array of options
* @param string $hostnamePattern Hostname pattern
*
* @throws \InvalidArgumentException When the RouteCollection already exists in the tree
*
* @api
*/
public function addCollection(RouteCollection $collection, $prefix = '', $defaults = array(), $requirements = array(), $options = array(), $hostnamePattern = null)
public function addCollection(RouteCollection $collection, $prefix = '', $defaults = array(), $requirements = array(), $options = array(), $hostnamePattern = '')
{
// prevent infinite loops by recursive referencing
$root = $this->getRoot();
@ -212,10 +212,7 @@ class RouteCollection implements \IteratorAggregate, \Countable
// necessarily already have it applied (depending on the order RouteCollections are added to each other)
$collection->addPrefix($this->getPrefix() . $prefix, $defaults, $requirements, $options);
// Allow child collection to have a different pattern
if (!$collection->getHostnamePattern()) {
$collection->setHostnamePattern($hostnamePattern);
}
$collection->setHostnamePattern($hostnamePattern);
$this->routes[] = $collection;
}
@ -268,6 +265,34 @@ class RouteCollection implements \IteratorAggregate, \Countable
return $this->prefix;
}
/**
* Returns the hostname pattern.
*
* @return string The pattern
*/
public function getHostnamePattern()
{
return $this->hostnamePattern;
}
/**
* Sets the hostname pattern on this collection and all children.
*
* @param string $pattern The pattern
*/
public function setHostnamePattern($pattern)
{
$this->hostnamePattern = $pattern;
if ('' === $pattern) {
return;
}
foreach ($this->routes as $name => $route) {
$route->setHostnamePattern($pattern);
}
}
/**
* Returns an array of resources loaded to build this collection.
*
@ -350,21 +375,4 @@ class RouteCollection implements \IteratorAggregate, \Countable
return false;
}
public function getHostnamePattern()
{
return $this->hostnamePattern;
}
public function setHostnamePattern($pattern)
{
$this->hostnamePattern = $pattern;
foreach ($this->routes as $name => $route) {
// Allow individual routes to have a different pattern
if (!$route->getHostnamePattern()) {
$route->setHostnamePattern($pattern);
}
}
}
}

View File

@ -46,7 +46,7 @@ class RouteCompiler implements RouteCompilerInterface
$hostnameRegex = null;
$hostnameTokens = array();
if (null !== $hostnamePattern = $route->getHostnamePattern()) {
if ('' !== $hostnamePattern = $route->getHostnamePattern()) {
$result = $this->compilePattern($route, $hostnamePattern, true);
$hostnameVariables = $result['variables'];

View File

@ -282,7 +282,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
// route13
if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?<name>[^/]++)$#s', $pathinfo, $matches)) {
$matches = $matches + $hostnameMatches;
$matches = array_merge($hostnameMatches, $matches);
$matches['_route'] = 'route13';
return $matches;
@ -290,7 +290,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
// route14
if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?<name>[^/]++)$#s', $pathinfo, $matches)) {
return array_merge($this->mergeDefaults($matches + $hostnameMatches, array ( 'var1' => 'val',)), array('_route' => 'route14'));
return array_merge($this->mergeDefaults(array_merge($hostnameMatches, $matches), array ( 'var1' => 'val',)), array('_route' => 'route14'));
}
}

View File

@ -294,7 +294,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
// route13
if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?<name>[^/]++)$#s', $pathinfo, $matches)) {
$matches = $matches + $hostnameMatches;
$matches = array_merge($hostnameMatches, $matches);
$matches['_route'] = 'route13';
return $matches;
@ -302,7 +302,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
// route14
if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?<name>[^/]++)$#s', $pathinfo, $matches)) {
return array_merge($this->mergeDefaults($matches + $hostnameMatches, array ( 'var1' => 'val',)), array('_route' => 'route14'));
return array_merge($this->mergeDefaults(array_merge($hostnameMatches, $matches), array ( 'var1' => 'val',)), array('_route' => 'route14'));
}
}

View File

@ -2,6 +2,6 @@ blog_show:
pattern: /blog/{slug}
defaults: { _controller: MyBlogBundle:Blog:show }
hostname_pattern: "{locale}.example.com"
requirements: { 'foo': '\d+' }
requirements: { 'locale': '\d+' }
options:
compiler_class: RouteCompiler

View File

@ -235,7 +235,7 @@ class UrlGeneratorTest extends \PHPUnit_Framework_TestCase
$routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => 'd+')));
$this->getGenerator($routes)->generate('test', array('foo' => 'bar'), true);
}
/**
* @expectedException Symfony\Component\Routing\Exception\InvalidParameterException
*/
@ -262,7 +262,7 @@ class UrlGeneratorTest extends \PHPUnit_Framework_TestCase
$routes = $this->getRoutes('test', new Route('/', array(), array('_scheme' => 'http')));
$this->assertEquals('http://localhost/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test'));
}
public function testPathWithTwoStartingSlashes()
{
$routes = $this->getRoutes('test', new Route('//path-and-not-domain'));

View File

@ -90,7 +90,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
$route = $routes['blog_show'];
$this->assertEquals('/blog/{slug}', $route->getPattern());
$this->assertEquals('MyBlogBundle:Blog:show', $route->getDefault('_controller'));
$this->assertEquals('\d+', $route->getRequirement('foo'));
$this->assertEquals('\d+', $route->getRequirement('locale'));
$this->assertEquals('{locale}.example.com', $route->getHostnamePattern());
$this->assertEquals('RouteCompiler', $route->getOption('compiler_class'));
}

View File

@ -22,4 +22,3 @@ class DumperCollectionTest extends \PHPUnit_Framework_TestCase
$this->assertSame($a, $c->getRoot());
}
}

View File

@ -112,4 +112,3 @@ EOF;
return $string;
}
}

View File

@ -14,7 +14,6 @@ namespace Symfony\Component\Routing\Tests\Matcher\Dumper;
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Matcher\Dumper\DumperCollection;
class PhpMatcherDumperTest extends \PHPUnit_Framework_TestCase
{
@ -165,13 +164,11 @@ class PhpMatcherDumperTest extends \PHPUnit_Framework_TestCase
$collection2 = new RouteCollection();
$route2 = new Route('/route2', array(), array(), array(), 'a.example.com');
$collection2->add('route2', $route2);
$route2 = new Route('/c2/route2', array(), array(), array(), 'a.example.com');
$collection1->add('route2', $route2);
$route3 = new Route('/route3', array(), array(), array(), 'b.example.com');
$collection2->add('route3', $route3);
$collection1->addCollection($collection2, '/c2');
$route3 = new Route('/c2/route3', array(), array(), array(), 'b.example.com');
$collection1->add('route3', $route3);
$route4 = new Route('/route4', array(), array(), array(), 'a.example.com');
$collection1->add('route4', $route4);

View File

@ -348,7 +348,7 @@ class UrlMatcherTest extends \PHPUnit_Framework_TestCase
$matcher = new UrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com'));
$this->assertEquals(array('foo' => 'bar', '_route' => 'foo', 'locale' => 'en'), $matcher->match('/foo/bar'));
$matcher = new UrlMatcher($coll, new RequestContext('', 'GET', 'en.example.net'));
$matcher = new UrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com'));
$this->assertEquals(array('foo' => 'bar', '_route' => 'bar', 'locale' => 'en'), $matcher->match('/bar/bar'));
}

View File

@ -309,6 +309,6 @@ class RouteCollectionTest extends \PHPUnit_Framework_TestCase
$collection->setHostnamePattern('{locale}.example.com');
$this->assertEquals('{locale}.example.com', $routea->getHostnamePattern());
$this->assertEquals('{locale}.example.net', $routeb->getHostnamePattern());
$this->assertEquals('{locale}.example.com', $routeb->getHostnamePattern());
}
}

View File

@ -197,7 +197,7 @@ class RouteCompilerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($hostnameRegex, str_replace(array("\n", ' '), '', $compiled->getHostnameRegex()), $name.' (hostname regex)');
$this->assertEquals($hostnameVariables, $compiled->getHostnameVariables(), $name.' (hostname variables)');
$this->assertEquals($hostnameTokens, $compiled->getHostnameTokens(), $name.' (hostname tokens)');
}
}
public function provideCompileWithHostnameData()
{
@ -247,8 +247,7 @@ class RouteCompilerTest extends \PHPUnit_Framework_TestCase
array('text', '.example'),
array('variable', '', '[^\.]++', 'locale'),
),
),
),
);
}
}