Переглянути джерело

[Routing] Better nesting for RouteCollections in dumped URL matcher classes
With this change, a route prefixed with '/blogger' will be nested inside '/blog' (for example)

Lee McDermott 14 роки тому
батько
коміт
91f4097a09

+ 34 - 2
src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php

@@ -72,16 +72,47 @@ EOF;
     private function compileRoutes(RouteCollection $routes, $supportsRedirections, $parentPrefix = null)
     {
         $code = array();
-        foreach ($routes as $name => $route) {
+        
+        $routeIterator = $routes->getIterator();
+        $keys = array_keys($routeIterator->getArrayCopy());
+        
+        $i = 0;
+        
+        foreach ($routeIterator as $name => $route) {
+            $i++;
+            
             if ($route instanceof RouteCollection) {
                 $prefix = $route->getPrefix();
                 $optimizable = $prefix && count($route->all()) > 1 && false === strpos($route->getPrefix(), '{');
                 $indent = '';
                 if ($optimizable) {
+                    for ($j = $i; $j < count($keys); $j++) {
+                        if ($keys[$j] === null) continue;
+                      
+                        $testRoute = $routeIterator->offsetGet($keys[$j]);
+                        $isCollection = ($testRoute instanceof RouteCollection);
+
+                        $testPrefix = $isCollection ? $testRoute->getPrefix() : $testRoute->getPattern();
+
+                        if (0 === strpos($testPrefix, $prefix)) {
+                            $routeIterator->offsetUnset($keys[$j]);
+                        
+                            if ($isCollection) {
+                                $route->addCollection($testRoute);
+                            }
+                            else {
+                                $route->add($keys[$j], $testRoute);
+                            }
+                        
+                            $i++;
+                            $keys[$j] = null;
+                        }
+                    }
+                    
                     $code[] = sprintf("        if (0 === strpos(\$pathinfo, '%s')) {", $prefix);
                     $indent = '    ';
                 }
-
+                
                 foreach ($this->compileRoutes($route, $supportsRedirections, $prefix) as $line) {
                     foreach (explode("\n", $line) as $l) {
                         $code[] = $indent.$l;
@@ -89,6 +120,7 @@ EOF;
                 }
 
                 if ($optimizable) {
+                    $code[] = "            throw 0 < count(\$allow) ? new MethodNotAllowedException(array_unique(\$allow)) : new ResourceNotFoundException();";
                     $code[] = "        }\n";
                 }
             } else {