Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3a9322e

Browse files
committed
Show welcome message if no routes configuration is available
1 parent 5e2f869 commit 3a9322e

File tree

7 files changed

+284
-0
lines changed

7 files changed

+284
-0
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\EventListener;
13+
14+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15+
use Symfony\Component\HttpFoundation\Response;
16+
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
17+
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
18+
use Symfony\Component\HttpKernel\Kernel;
19+
use Symfony\Component\HttpKernel\KernelEvents;
20+
use Symfony\Component\Routing\Exception\NoConfigurationException;
21+
22+
/**
23+
* Show welcome page if no routing configuration is available.
24+
*
25+
* @author Yonel Ceruto <[email protected]>
26+
*/
27+
class NoRoutingConfigurationSubscriber implements EventSubscriberInterface
28+
{
29+
private $projectDir;
30+
31+
public function __construct($projectDir)
32+
{
33+
$this->projectDir = $projectDir;
34+
}
35+
36+
public function onKernelException(GetResponseForExceptionEvent $event)
37+
{
38+
$exception = $event->getException();
39+
if ($exception instanceof NotFoundHttpException && $exception->getPrevious() instanceof NoConfigurationException) {
40+
$event->setResponse(new Response($this->getContent()));
41+
}
42+
}
43+
44+
/**
45+
* {@inheritdoc}
46+
*/
47+
public static function getSubscribedEvents()
48+
{
49+
return array(
50+
KernelEvents::EXCEPTION => 'onKernelException',
51+
);
52+
}
53+
54+
private function getContent()
55+
{
56+
$charset = ini_get('default_charset') ?: 'UTF-8';
57+
58+
return <<<EOF
59+
<!DOCTYPE html>
60+
<html>
61+
<head>
62+
<meta charset="$charset" />
63+
<title>Welcome!</title>
64+
{$this->getStylesheet()}
65+
</head>
66+
<body>
67+
{$this->getBody()}
68+
</body>
69+
</html>
70+
EOF;
71+
}
72+
73+
private function getStylesheet()
74+
{
75+
return <<<EOF
76+
<style>
77+
body { background: #F5F5F5; font: 18px/1.5 sans-serif; }
78+
h1, h2 { line-height: 1.2; margin: 0 0 .5em; }
79+
h1 { font-size: 36px; }
80+
h2 { font-size: 21px; margin-bottom: 1em; }
81+
p { margin: 0 0 1em 0; }
82+
a { color: #0000F0; }
83+
a:hover { text-decoration: none; }
84+
code { background: #F5F5F5; max-width: 100px; padding: 2px 6px; word-wrap: break-word; }
85+
#wrapper { background: #FFF; margin: 1em auto; max-width: 800px; width: 95%; }
86+
#container { padding: 2em; }
87+
#welcome, #status { margin-bottom: 2em; }
88+
#welcome h1 span { display: block; font-size: 75%; }
89+
#comment { font-size: 14px; text-align: center; color: #777777; background: #FEFFEA; padding: 10px; }
90+
#comment p { margin-bottom: 0; }
91+
#icon-status, #icon-book { float: left; height: 64px; margin-right: 1em; margin-top: -4px; width: 64px; }
92+
#icon-book { display: none; }
93+
94+
@media (min-width: 768px) {
95+
#wrapper { width: 80%; margin: 2em auto; }
96+
#icon-book { display: inline-block; }
97+
#status a, #next a { display: block; }
98+
99+
@-webkit-keyframes fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }
100+
@keyframes fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }
101+
.sf-toolbar { opacity: 0; -webkit-animation: fade-in 1s .2s forwards; animation: fade-in 1s .2s forwards;}
102+
}
103+
</style>
104+
EOF;
105+
}
106+
107+
private function getBody()
108+
{
109+
$version = Kernel::VERSION;
110+
$baseDir = realpath($this->projectDir).DIRECTORY_SEPARATOR;
111+
$docVersion = substr(Kernel::VERSION, 0, 3);
112+
113+
return <<<EOF
114+
<div id="wrapper">
115+
<div id="container">
116+
<div id="welcome">
117+
<h1><span>Welcome to</span> Symfony $version</h1>
118+
</div>
119+
120+
<div id="status">
121+
<p>
122+
<svg id="icon-status" width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68z" fill="#759E1A"/></svg>
123+
124+
Your application is now ready. You can start working on it at:<br>
125+
<code>$baseDir</code>
126+
</p>
127+
</div>
128+
129+
<div id="next">
130+
<h2>What's next?</h2>
131+
<p>
132+
<svg id="icon-book" version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="-12.5 9 64 64" enable-background="new -12.5 9 64 64" xml:space="preserve">
133+
<path fill="#AAA" d="M6.8,40.8c2.4,0.8,4.5-0.7,4.9-2.5c0.2-1.2-0.3-2.1-1.3-3.2l-0.8-0.8c-0.4-0.5-0.6-1.3-0.2-1.9
134+
c0.4-0.5,0.9-0.8,1.8-0.5c1.3,0.4,1.9,1.3,2.9,2.2c-0.4,1.4-0.7,2.9-0.9,4.2l-0.2,1c-0.7,4-1.3,6.2-2.7,7.5
135+
c-0.3,0.3-0.7,0.5-1.3,0.6c-0.3,0-0.4-0.3-0.4-0.3c0-0.3,0.2-0.3,0.3-0.4c0.2-0.1,0.5-0.3,0.4-0.8c0-0.7-0.6-1.3-1.3-1.3
136+
c-0.6,0-1.4,0.6-1.4,1.7s1,1.9,2.4,1.8c0.8,0,2.5-0.3,4.2-2.5c2-2.5,2.5-5.4,2.9-7.4l0.5-2.8c0.3,0,0.5,0.1,0.8,0.1
137+
c2.4,0.1,3.7-1.3,3.7-2.3c0-0.6-0.3-1.2-0.9-1.2c-0.4,0-0.8,0.3-1,0.8c-0.1,0.6,0.8,1.1,0.1,1.5c-0.5,0.3-1.4,0.6-2.7,0.4l0.3-1.3
138+
c0.5-2.6,1-5.7,3.2-5.8c0.2,0,0.8,0,0.8,0.4c0,0.2,0,0.2-0.2,0.5c-0.2,0.3-0.3,0.4-0.2,0.7c0,0.7,0.5,1.1,1.2,1.1
139+
c0.9,0,1.2-1,1.2-1.4c0-1.2-1.2-1.8-2.6-1.8c-1.5,0.1-2.8,0.9-3.7,2.1c-1.1,1.3-1.8,2.9-2.3,4.5c-0.9-0.8-1.6-1.8-3.1-2.3
140+
c-1.1-0.7-2.3-0.5-3.4,0.3c-0.5,0.4-0.8,1-1,1.6c-0.4,1.5,0.4,2.9,0.8,3.4l0.9,1c0.2,0.2,0.6,0.8,0.4,1.5c-0.3,0.8-1.2,1.3-2.1,1
141+
c-0.4-0.2-1-0.5-0.9-0.9c0.1-0.2,0.2-0.3,0.3-0.5s0.1-0.3,0.1-0.3c0.2-0.6-0.1-1.4-0.7-1.6c-0.6-0.2-1.2,0-1.3,0.8
142+
C4.3,38.4,4.7,40,6.8,40.8z M46.1,20.9c0-4.2-3.2-7.5-7.1-7.5h-3.8C34.8,10.8,32.7,9,30.2,9L-2.3,9.1c-2.8,0.1-4.9,2.4-4.9,5.4
143+
L-7,58.6c0,4.8,8.1,13.9,11.6,14.1l34.7-0.1c3.9,0,7-3.4,7-7.6L46.1,20.9z M-0.3,36.4c0-8.6,6.5-15.6,14.5-15.6
144+
c8,0,14.5,7,14.5,15.6S22.1,52,14.2,52C6.1,52-0.3,45-0.3,36.4z M42.1,65.1c0,1.8-1.5,3.1-3.1,3.1H4.6c-0.7,0-3-1.8-4.5-4.4h30.4
145+
c2.8,0,5-2.4,5-5.4V17.9h3.7c1.6,0,2.9,1.4,2.9,3.1V65.1L42.1,65.1z"/>
146+
</svg>
147+
148+
Read the documentation to learn
149+
<a href="https://symfony.com/doc/$docVersion/page_creation.html">
150+
How to create your first page in Symfony
151+
</a>
152+
</p>
153+
</div>
154+
</div>
155+
<div id="comment">
156+
<p>
157+
You're seeing this message because you have debug mode enabled and you haven't configured any URLs.
158+
</p>
159+
</div>
160+
</div>
161+
EOF;
162+
}
163+
}

src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,10 @@
2424
<argument type="service" id="debug.argument_resolver.inner" />
2525
<argument type="service" id="debug.stopwatch" />
2626
</service>
27+
28+
<service id="debug.no_routing_configuration_subscriber" class="Symfony\Bundle\FrameworkBundle\EventListener\NoRoutingConfigurationSubscriber">
29+
<argument>%kernel.project_dir%</argument>
30+
<tag name="kernel.event_subscriber" />
31+
</service>
2732
</services>
2833
</container>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\EventListener;
13+
14+
use Symfony\Bundle\FrameworkBundle\EventListener\NoRoutingConfigurationSubscriber;
15+
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
16+
use Symfony\Component\HttpFoundation\Request;
17+
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
18+
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
19+
use Symfony\Component\HttpKernel\HttpKernelInterface;
20+
use Symfony\Component\Routing\Exception\NoConfigurationException;
21+
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
22+
23+
class NoRoutingConfigurationSubscriberTest extends TestCase
24+
{
25+
public function testResponse()
26+
{
27+
$httpKernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
28+
29+
$exception = new NotFoundHttpException('No route found', new NoConfigurationException());
30+
$event = new GetResponseForExceptionEvent($httpKernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $exception);
31+
$subscriber = new NoRoutingConfigurationSubscriber('/');
32+
$subscriber->onKernelException($event);
33+
34+
$this->assertTrue($event->hasResponse());
35+
$this->assertContains('Welcome', $event->getResponse()->getContent());
36+
}
37+
38+
public function testNoResponse()
39+
{
40+
$httpKernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
41+
42+
$exception = new NotFoundHttpException('No route found', new ResourceNotFoundException());
43+
$event = new GetResponseForExceptionEvent($httpKernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $exception);
44+
$subscriber = new NoRoutingConfigurationSubscriber('/');
45+
$subscriber->onKernelException($event);
46+
47+
$this->assertFalse($event->hasResponse());
48+
}
49+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Routing\Exception;
13+
14+
/**
15+
* Exception thrown when no routes are configured.
16+
*
17+
* @author Yonel Ceruto <[email protected]>
18+
*/
19+
class NoConfigurationException extends ResourceNotFoundException
20+
{
21+
}

src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,12 @@ private function compileRoutes(RouteCollection $routes, $supportsRedirections)
155155
}
156156
}
157157

158+
if ('' === $code) {
159+
$code .= " if ('/' === \$pathinfo) {\n";
160+
$code .= " throw new Symfony\Component\Routing\Exception\NoConfigurationException();\n";
161+
$code .= " }\n";
162+
}
163+
158164
return $code;
159165
}
160166

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
4+
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
5+
use Symfony\Component\Routing\RequestContext;
6+
7+
/**
8+
* This class has been auto-generated
9+
* by the Symfony Routing Component.
10+
*/
11+
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
12+
{
13+
public function __construct(RequestContext $context)
14+
{
15+
$this->context = $context;
16+
}
17+
18+
public function match($pathinfo)
19+
{
20+
$allow = array();
21+
$pathinfo = rawurldecode($pathinfo);
22+
$trimmedPathinfo = rtrim($pathinfo, '/');
23+
$context = $this->context;
24+
$request = $this->request;
25+
$requestMethod = $canonicalMethod = $context->getMethod();
26+
$scheme = $context->getScheme();
27+
28+
if ('HEAD' === $requestMethod) {
29+
$canonicalMethod = 'GET';
30+
}
31+
32+
33+
if ('/' === $pathinfo) {
34+
throw new Symfony\Component\Routing\Exception\NoConfigurationException();
35+
}
36+
37+
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
38+
}
39+
}

src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ public function getRouteCollections()
374374
$trailingSlashCollection->add('regex_not_trailing_slash_POST_method', new Route('/not-trailing/regex/post-method/{param}', array(), array(), array(), '', array(), array('POST')));
375375

376376
return array(
377+
array(new RouteCollection(), 'url_matcher0.php', array()),
377378
array($collection, 'url_matcher1.php', array()),
378379
array($redirectCollection, 'url_matcher2.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')),
379380
array($rootprefixCollection, 'url_matcher3.php', array()),

0 commit comments

Comments
 (0)