Skip to content

Commit 7d94e29

Browse files
committed
[WebProfilerBundle] Try to display the most useful panel by default
1 parent 2b71c6f commit 7d94e29

File tree

3 files changed

+119
-5
lines changed

3 files changed

+119
-5
lines changed

src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
use Symfony\Component\HttpFoundation\Request;
1818
use Symfony\Component\HttpFoundation\Response;
1919
use Symfony\Component\HttpFoundation\Session\Flash\AutoExpireFlashBag;
20+
use Symfony\Component\HttpKernel\DataCollector\DumpDataCollector;
21+
use Symfony\Component\HttpKernel\DataCollector\ExceptionDataCollector;
2022
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
2123
use Symfony\Component\HttpKernel\Profiler\Profiler;
2224
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
@@ -78,7 +80,7 @@ public function panelAction(Request $request, $token)
7880
$this->cspHandler->disableCsp();
7981
}
8082

81-
$panel = $request->query->get('panel', 'request');
83+
$panel = $request->query->get('panel');
8284
$page = $request->query->get('page', 'home');
8385

8486
if ('latest' === $token && $latest = current($this->profiler->find(null, null, 1, null, null, null))) {
@@ -89,6 +91,22 @@ public function panelAction(Request $request, $token)
8991
return new Response($this->twig->render('@WebProfiler/Profiler/info.html.twig', ['about' => 'no_token', 'token' => $token, 'request' => $request]), 200, ['Content-Type' => 'text/html']);
9092
}
9193

94+
if (null === $panel) {
95+
$panel = 'request';
96+
97+
foreach ($profile->getCollectors() as $collector) {
98+
if ($collector instanceof ExceptionDataCollector && $collector->hasException()) {
99+
$panel = $collector->getName();
100+
101+
break;
102+
}
103+
104+
if ($collector instanceof DumpDataCollector && $collector->getDumpsCount() > 0) {
105+
$panel = $collector->getName();
106+
}
107+
}
108+
}
109+
92110
if (!$profile->hasCollector($panel)) {
93111
throw new NotFoundHttpException(sprintf('Panel "%s" is not available for token "%s".', $panel, $token));
94112
}

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@
267267
if (request.profilerUrl) {
268268
profilerCell.textContent = '';
269269
var profilerLink = document.createElement('a');
270-
profilerLink.setAttribute('href', request.statusCode < 400 ? request.profilerUrl : request.profilerUrl + '?panel=exception');
270+
profilerLink.setAttribute('href', request.profilerUrl);
271271
profilerLink.textContent = request.profile;
272272
profilerCell.appendChild(profilerLink);
273273
}

src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,16 @@
1515
use Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController;
1616
use Symfony\Bundle\WebProfilerBundle\Csp\ContentSecurityPolicyHandler;
1717
use Symfony\Component\HttpFoundation\Request;
18+
use Symfony\Component\HttpFoundation\Response;
19+
use Symfony\Component\HttpKernel\DataCollector\DumpDataCollector;
20+
use Symfony\Component\HttpKernel\DataCollector\ExceptionDataCollector;
21+
use Symfony\Component\HttpKernel\DataCollector\RequestDataCollector;
1822
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
1923
use Symfony\Component\HttpKernel\Profiler\Profile;
24+
use Symfony\Component\HttpKernel\Profiler\Profiler;
25+
use Twig\Environment;
26+
use Twig\Loader\LoaderInterface;
27+
use Twig\Loader\SourceContextLoaderInterface;
2028

2129
class ProfilerControllerTest extends TestCase
2230
{
@@ -185,17 +193,105 @@ public function provideCspVariants()
185193
];
186194
}
187195

188-
private function createController($profiler, $twig, $withCSP): ProfilerController
196+
/**
197+
* @dataProvider defaultPanelProvider
198+
*/
199+
public function testDefaultPanel(string $expectedPanel, Profile $profile)
200+
{
201+
$profiler = $this->createMock(Profiler::class);
202+
$profiler
203+
->expects($this->atLeastOnce())
204+
->method('loadProfile')
205+
->with($profile->getToken())
206+
->willReturn($profile);
207+
208+
$profiler
209+
->expects($this->atLeastOnce())
210+
->method('has')
211+
->with($this->logicalXor($collectorsNames = array_keys($profile->getCollectors())))
212+
->willReturn(true);
213+
214+
if (Environment::MAJOR_VERSION > 1) {
215+
$loader = $this->createMock(LoaderInterface::class);
216+
$loader
217+
->expects($this->atLeastOnce())
218+
->method('exists')
219+
->with($this->logicalXor($expectedTemplate = 'expected_template.html.twig', 'other_template.html.twig'))
220+
->willReturn(true);
221+
} else {
222+
$loader = $this->createMock(SourceContextLoaderInterface::class);
223+
}
224+
225+
$twig = $this->createMock(Environment::class);
226+
$twig
227+
->expects($this->atLeastOnce())
228+
->method('getLoader')
229+
->willReturn($loader);
230+
$twig
231+
->expects($this->once())
232+
->method('render')
233+
->with($expectedTemplate);
234+
235+
$this
236+
->createController($profiler, $twig, false, array_map(function (string $collectorName) use ($expectedPanel, $expectedTemplate): array {
237+
if ($collectorName === $expectedPanel) {
238+
return [$expectedPanel, $expectedTemplate];
239+
}
240+
241+
return [$collectorName, 'other_template.html.twig'];
242+
}, $collectorsNames))
243+
->panelAction(new Request(), $profile->getToken());
244+
}
245+
246+
public function defaultPanelProvider(): \Generator
247+
{
248+
// Test default behavior
249+
$profile = new Profile('xxxxxx');
250+
$profile->addCollector($requestDataCollector = new RequestDataCollector());
251+
yield [$requestDataCollector->getName(), $profile];
252+
253+
// Test exception
254+
$profile = new Profile('xxxxxx');
255+
$profile->addCollector($exceptionDataCollector = new ExceptionDataCollector());
256+
$exceptionDataCollector->collect(new Request(), new Response(), new \DomainException());
257+
yield [$exceptionDataCollector->getName(), $profile];
258+
259+
// Test exception priority
260+
$dumpDataCollector = $this->createMock(DumpDataCollector::class);
261+
$dumpDataCollector
262+
->expects($this->atLeastOnce())
263+
->method('getName')
264+
->willReturn('dump');
265+
$dumpDataCollector
266+
->expects($this->atLeastOnce())
267+
->method('getDumpsCount')
268+
->willReturn(1);
269+
$profile = new Profile('xxxxxx');
270+
$profile->setCollectors([$exceptionDataCollector, $dumpDataCollector]);
271+
yield [$exceptionDataCollector->getName(), $profile];
272+
273+
// Test exception priority when defined afterwards
274+
$profile = new Profile('xxxxxx');
275+
$profile->setCollectors([$dumpDataCollector, $exceptionDataCollector]);
276+
yield [$exceptionDataCollector->getName(), $profile];
277+
278+
// Test dump
279+
$profile = new Profile('xxxxxx');
280+
$profile->addCollector($dumpDataCollector);
281+
yield [$dumpDataCollector->getName(), $profile];
282+
}
283+
284+
private function createController($profiler, $twig, $withCSP, array $templates = []): ProfilerController
189285
{
190286
$urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock();
191287

192288
if ($withCSP) {
193289
$nonceGenerator = $this->getMockBuilder('Symfony\Bundle\WebProfilerBundle\Csp\NonceGenerator')->getMock();
194290
$nonceGenerator->method('generate')->willReturn('dummy_nonce');
195291

196-
return new ProfilerController($urlGenerator, $profiler, $twig, [], new ContentSecurityPolicyHandler($nonceGenerator));
292+
return new ProfilerController($urlGenerator, $profiler, $twig, $templates, new ContentSecurityPolicyHandler($nonceGenerator));
197293
}
198294

199-
return new ProfilerController($urlGenerator, $profiler, $twig, []);
295+
return new ProfilerController($urlGenerator, $profiler, $twig, $templates);
200296
}
201297
}

0 commit comments

Comments
 (0)
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