Bladeren bron

[Routing] fixed deep nested route collections (closes #770)

Fabien Potencier 14 jaren geleden
bovenliggende
commit
fe9ef5c68b

+ 6 - 2
src/Symfony/Component/Routing/RouteCollection.php

@@ -134,8 +134,12 @@ class RouteCollection implements \IteratorAggregate
 
         $this->prefix = $prefix.$this->prefix;
 
-        foreach ($this->all() as $route) {
-            $route->setPattern($prefix.$route->getPattern());
+        foreach ($this->routes as $name => $route) {
+            if ($route instanceof RouteCollection) {
+                $route->addPrefix($prefix);
+            } else {
+                $route->setPattern($prefix.$route->getPattern());
+            }
         }
     }
 

+ 18 - 0
tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher1.php

@@ -88,6 +88,24 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
             return array (  'def' => 'test',  '_route' => 'foofoo',);
         }
 
+        if (0 === strpos($pathinfo, '/a')) {
+            if (0 === strpos($pathinfo, '/a/b')) {
+                // foo
+                if (0 === strpos($pathinfo, '/a/b') && preg_match('#^/a/b/(?P<foo>[^/]+?)$#x', $pathinfo, $matches)) {
+                    $matches['_route'] = 'foo';
+                    return $matches;
+                }
+        
+                // bar
+                if (0 === strpos($pathinfo, '/a/b') && preg_match('#^/a/b/(?P<bar>[^/]+?)$#x', $pathinfo, $matches)) {
+                    $matches['_route'] = 'bar';
+                    return $matches;
+                }
+        
+            }
+    
+        }
+
         throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new NotFoundException();
     }
 }

+ 18 - 0
tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher2.php

@@ -100,6 +100,24 @@ class ProjectUrlMatcher extends Symfony\Tests\Component\Routing\Fixtures\Redirec
             return array (  'def' => 'test',  '_route' => 'foofoo',);
         }
 
+        if (0 === strpos($pathinfo, '/a')) {
+            if (0 === strpos($pathinfo, '/a/b')) {
+                // foo
+                if (0 === strpos($pathinfo, '/a/b') && preg_match('#^/a/b/(?P<foo>[^/]+?)$#x', $pathinfo, $matches)) {
+                    $matches['_route'] = 'foo';
+                    return $matches;
+                }
+        
+                // bar
+                if (0 === strpos($pathinfo, '/a/b') && preg_match('#^/a/b/(?P<bar>[^/]+?)$#x', $pathinfo, $matches)) {
+                    $matches['_route'] = 'bar';
+                    return $matches;
+                }
+        
+            }
+    
+        }
+
         // secure
         if ($pathinfo === '/secure') {
             if ($this->context->getScheme() !== 'https') {

+ 8 - 0
tests/Symfony/Tests/Component/Routing/Matcher/Dumper/PhpMatcherDumperTest.php

@@ -68,6 +68,14 @@ class PhpMatcherDumperTest extends \PHPUnit_Framework_TestCase
             array('def' => 'test')
         ));
 
+        // prefixes
+        $collection1 = new RouteCollection();
+        $collection1->add('foo', new Route('/{foo}'));
+        $collection1->add('bar', new Route('/{bar}'));
+        $collection2 = new RouteCollection();
+        $collection2->addCollection($collection1, '/b');
+        $collection->addCollection($collection2, '/a');
+
         $dumper = new PhpMatcherDumper($collection, new RequestContext());
         $this->assertStringEqualsFile(__DIR__.'/../../Fixtures/dumper/url_matcher1.php', $dumper->dump(), '->dump() dumps basic routes to the correct PHP file.');
 

+ 15 - 0
tests/Symfony/Tests/Component/Routing/Matcher/UrlMatcherTest.php

@@ -111,6 +111,21 @@ class UrlMatcherTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals(array('_route' => 'bar', 'bar' => 'bar'), $matcher->match('/'));
     }
 
+    public function testMatchWithPrefixes()
+    {
+        $collection1 = new RouteCollection();
+        $collection1->add('foo', new Route('/{foo}'));
+
+        $collection2 = new RouteCollection();
+        $collection2->addCollection($collection1, '/b');
+
+        $collection = new RouteCollection();
+        $collection->addCollection($collection2, '/a');
+
+        $matcher = new UrlMatcher($collection, new RequestContext(), array());
+        $this->assertEquals(array('_route' => 'foo', 'foo' => 'foo'), $matcher->match('/a/b/foo'));
+    }
+
     public function testMatchRegression()
     {
         $coll = new RouteCollection();