diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml index 6856512e20349..d92cb1164ac90 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml @@ -109,6 +109,8 @@ + %kernel.project_dir% + %kernel.debug% diff --git a/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php b/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php index 16f31a2d947a7..a8f7dd7e7ed97 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php @@ -12,13 +12,16 @@ namespace Symfony\Component\HttpKernel\EventListener; use Psr\Log\LoggerInterface; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; +use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Exception\MethodNotAllowedException; +use Symfony\Component\Routing\Exception\NoConfigurationException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Matcher\UrlMatcherInterface; use Symfony\Component\Routing\Matcher\RequestMatcherInterface; @@ -31,6 +34,7 @@ * Initializes the context from the request and sets request attributes based on a matching route. * * @author Fabien Potencier + * @author Yonel Ceruto */ class RouterListener implements EventSubscriberInterface { @@ -38,16 +42,20 @@ class RouterListener implements EventSubscriberInterface private $context; private $logger; private $requestStack; + private $projectDir; + private $debug; /** * @param UrlMatcherInterface|RequestMatcherInterface $matcher The Url or Request matcher * @param RequestStack $requestStack A RequestStack instance * @param RequestContext|null $context The RequestContext (can be null when $matcher implements RequestContextAwareInterface) * @param LoggerInterface|null $logger The logger + * @param string $projectDir + * @param bool $debug * * @throws \InvalidArgumentException */ - public function __construct($matcher, RequestStack $requestStack, RequestContext $context = null, LoggerInterface $logger = null) + public function __construct($matcher, RequestStack $requestStack, RequestContext $context = null, LoggerInterface $logger = null, $projectDir = null, $debug = true) { if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) { throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.'); @@ -61,6 +69,8 @@ public function __construct($matcher, RequestStack $requestStack, RequestContext $this->context = $context ?: $matcher->getContext(); $this->requestStack = $requestStack; $this->logger = $logger; + $this->projectDir = $projectDir; + $this->debug = $debug; } private function setCurrentRequest(Request $request = null) @@ -114,6 +124,12 @@ public function onKernelRequest(GetResponseEvent $event) unset($parameters['_route'], $parameters['_controller']); $request->attributes->set('_route_params', $parameters); } catch (ResourceNotFoundException $e) { + if ($this->debug && $e instanceof NoConfigurationException) { + $event->setResponse($this->createWelcomeResponse()); + + return; + } + $message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getPathInfo()); if ($referer = $request->headers->get('referer')) { @@ -135,4 +151,16 @@ public static function getSubscribedEvents() KernelEvents::FINISH_REQUEST => array(array('onKernelFinishRequest', 0)), ); } + + private function createWelcomeResponse() + { + $version = Kernel::VERSION; + $baseDir = realpath($this->projectDir).DIRECTORY_SEPARATOR; + $docVersion = substr(Kernel::VERSION, 0, 3); + + ob_start(); + include __DIR__.'/../Resources/welcome.html.php'; + + return new Response(ob_get_clean(), Response::HTTP_NOT_FOUND); + } } diff --git a/src/Symfony/Component/HttpKernel/Resources/welcome.html.php b/src/Symfony/Component/HttpKernel/Resources/welcome.html.php new file mode 100644 index 0000000000000..d8c37beb56ae2 --- /dev/null +++ b/src/Symfony/Component/HttpKernel/Resources/welcome.html.php @@ -0,0 +1,84 @@ + + + + + Welcome! + + + +
+
+
+

Welcome to Symfony

+
+ +
+

+ + + Your application is now ready. You can start working on it at:
+ +

+
+ + +
+
+

+ You're seeing this message because you have debug mode enabled and you haven't configured any URLs. +

+
+
+ + diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php index a40e57998dee2..8ef2dc29f7a25 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php @@ -24,6 +24,7 @@ use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\HttpKernel; use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\Routing\Exception\NoConfigurationException; use Symfony\Component\Routing\RequestContext; class RouterListenerTest extends TestCase @@ -185,4 +186,26 @@ public function testWithBadRequest() $response = $kernel->handle($request); $this->assertSame(400, $response->getStatusCode()); } + + public function testNoRoutingConfigurationResponse() + { + $requestStack = new RequestStack(); + + $requestMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\RequestMatcherInterface')->getMock(); + $requestMatcher + ->expects($this->once()) + ->method('matchRequest') + ->willThrowException(new NoConfigurationException()) + ; + + $dispatcher = new EventDispatcher(); + $dispatcher->addSubscriber(new RouterListener($requestMatcher, $requestStack, new RequestContext())); + + $kernel = new HttpKernel($dispatcher, new ControllerResolver(), $requestStack, new ArgumentResolver()); + + $request = Request::create('http://localhost/'); + $response = $kernel->handle($request); + $this->assertSame(404, $response->getStatusCode()); + $this->assertContains('Welcome', $response->getContent()); + } } diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index a372edb588601..888cd3f23852d 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -33,7 +33,7 @@ "symfony/expression-language": "~2.8|~3.0|~4.0", "symfony/finder": "~2.8|~3.0|~4.0", "symfony/process": "~2.8|~3.0|~4.0", - "symfony/routing": "~2.8|~3.0|~4.0", + "symfony/routing": "~3.4|~4.0", "symfony/stopwatch": "~2.8|~3.0|~4.0", "symfony/templating": "~2.8|~3.0|~4.0", "symfony/translation": "~2.8|~3.0|~4.0", diff --git a/src/Symfony/Component/Routing/CHANGELOG.md b/src/Symfony/Component/Routing/CHANGELOG.md index 3785709d42425..e278f8b1e5936 100644 --- a/src/Symfony/Component/Routing/CHANGELOG.md +++ b/src/Symfony/Component/Routing/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 3.4.0 ----- + * Added `NoConfigurationException`. * Added the possibility to define a prefix for all routes of a controller via @Route(name="prefix_") * Added support for prioritized routing loaders. * Add matched and default parameters to redirect responses diff --git a/src/Symfony/Component/Routing/Exception/NoConfigurationException.php b/src/Symfony/Component/Routing/Exception/NoConfigurationException.php new file mode 100644 index 0000000000000..333bc74331460 --- /dev/null +++ b/src/Symfony/Component/Routing/Exception/NoConfigurationException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Exception; + +/** + * Exception thrown when no routes are configured. + * + * @author Yonel Ceruto + */ +class NoConfigurationException extends ResourceNotFoundException +{ +} diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php index 589e4f75390aa..aaa352d22c069 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php @@ -155,6 +155,12 @@ private function compileRoutes(RouteCollection $routes, $supportsRedirections) } } + if ('' === $code) { + $code .= " if ('/' === \$pathinfo) {\n"; + $code .= " throw new Symfony\Component\Routing\Exception\NoConfigurationException();\n"; + $code .= " }\n"; + } + return $code; } diff --git a/src/Symfony/Component/Routing/Matcher/RequestMatcherInterface.php b/src/Symfony/Component/Routing/Matcher/RequestMatcherInterface.php index b5def3d468ab3..097929555d7e5 100644 --- a/src/Symfony/Component/Routing/Matcher/RequestMatcherInterface.php +++ b/src/Symfony/Component/Routing/Matcher/RequestMatcherInterface.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Routing\Matcher; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Routing\Exception\NoConfigurationException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Exception\MethodNotAllowedException; @@ -32,6 +33,7 @@ interface RequestMatcherInterface * * @return array An array of parameters * + * @throws NoConfigurationException If no routing configuration could be found * @throws ResourceNotFoundException If no matching resource could be found * @throws MethodNotAllowedException If a matching resource was found but the request method is not allowed */ diff --git a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php index 12c15c68917ae..abd04c4208edf 100644 --- a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php +++ b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Routing\Matcher; use Symfony\Component\Routing\Exception\MethodNotAllowedException; +use Symfony\Component\Routing\Exception\NoConfigurationException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RequestContext; @@ -91,6 +92,10 @@ public function match($pathinfo) return $ret; } + if (0 === count($this->routes) && '/' === $pathinfo) { + throw new NoConfigurationException(); + } + throw 0 < count($this->allow) ? new MethodNotAllowedException(array_unique($this->allow)) : new ResourceNotFoundException(sprintf('No routes found for "%s".', $pathinfo)); @@ -123,6 +128,7 @@ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterfac * * @return array An array of parameters * + * @throws NoConfigurationException If no routing configuration could be found * @throws ResourceNotFoundException If the resource could not be found * @throws MethodNotAllowedException If the resource was found but the request method is not allowed */ diff --git a/src/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php b/src/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php index af38662fea930..2c7c3135bc66f 100644 --- a/src/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php +++ b/src/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Routing\Matcher; +use Symfony\Component\Routing\Exception\NoConfigurationException; use Symfony\Component\Routing\RequestContextAwareInterface; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Exception\MethodNotAllowedException; @@ -32,6 +33,7 @@ interface UrlMatcherInterface extends RequestContextAwareInterface * * @return array An array of parameters * + * @throws NoConfigurationException If no routing configuration could be found * @throws ResourceNotFoundException If the resource could not be found * @throws MethodNotAllowedException If the resource was found but the request method is not allowed */ diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher0.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher0.php new file mode 100644 index 0000000000000..0fa8ea45e0a15 --- /dev/null +++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher0.php @@ -0,0 +1,39 @@ +context = $context; + } + + public function match($pathinfo) + { + $allow = array(); + $pathinfo = rawurldecode($pathinfo); + $trimmedPathinfo = rtrim($pathinfo, '/'); + $context = $this->context; + $request = $this->request; + $requestMethod = $canonicalMethod = $context->getMethod(); + $scheme = $context->getScheme(); + + if ('HEAD' === $requestMethod) { + $canonicalMethod = 'GET'; + } + + + if ('/' === $pathinfo) { + throw new Symfony\Component\Routing\Exception\NoConfigurationException(); + } + + throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException(); + } +} diff --git a/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php b/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php index 4fb65f4a11a47..8b32e0cd3d194 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php @@ -374,6 +374,7 @@ public function getRouteCollections() $trailingSlashCollection->add('regex_not_trailing_slash_POST_method', new Route('/not-trailing/regex/post-method/{param}', array(), array(), array(), '', array(), array('POST'))); return array( + array(new RouteCollection(), 'url_matcher0.php', array()), array($collection, 'url_matcher1.php', array()), array($redirectCollection, 'url_matcher2.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')), array($rootprefixCollection, 'url_matcher3.php', array()), diff --git a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php index 1eeb5d4360cde..8545c2c29d83d 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php @@ -427,4 +427,15 @@ public function testHostIsCaseInsensitive() $matcher = new UrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com')); $this->assertEquals(array('_route' => 'foo', 'locale' => 'en'), $matcher->match('/')); } + + /** + * @expectedException \Symfony\Component\Routing\Exception\NoConfigurationException + */ + public function testNoConfiguration() + { + $coll = new RouteCollection(); + + $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher->match('/'); + } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy