Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 66c5c12

Browse filesBrowse files
committed
[WebProfilerBundle] Add special "_best" panel
1 parent 2b71c6f commit 66c5c12
Copy full SHA for 66c5c12

File tree

7 files changed

+127
-9
lines changed
Filter options

7 files changed

+127
-9
lines changed

‎UPGRADE-4.4.md

Copy file name to clipboardExpand all lines: UPGRADE-4.4.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ WebProfilerBundle
344344

345345
* Deprecated the `ExceptionController` class in favor of `ExceptionErrorController`
346346
* Deprecated the `TemplateManager::templateExists()` method
347+
* The `_best` data collector name is reserved for internal usage.
347348

348349
WebServerBundle
349350
---------------

‎src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ CHANGELOG
1212
* deprecated the `ExceptionController` in favor of `ExceptionPanelController`
1313
* marked all classes of the WebProfilerBundle as internal
1414
* added a section with the stamps of a message after it is dispatched in the Messenger panel
15+
* Added the special `_best` panel that display the most useful panel depending of the collected data.
16+
* The `_best` data collector name is reserved for internal usage.
1517

1618
4.3.0
1719
-----

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php
+21-1Lines changed: 21 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', $defaultPanel = 'request');
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,24 @@ 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 ($profile->hasCollector($bestPanel = '_best')) {
95+
@trigger_error(sprintf('The "%s" data collector name is reserved for internal usage since Symfony 4.4. Please rename it.', $bestPanel), E_USER_DEPRECATED);
96+
} elseif ($bestPanel === $panel) {
97+
$panel = $defaultPanel;
98+
99+
foreach ($profile->getCollectors() as $collector) {
100+
if ($collector instanceof ExceptionDataCollector && $collector->hasException()) {
101+
$panel = $collector->getName();
102+
103+
break;
104+
}
105+
106+
if ($collector instanceof DumpDataCollector && $collector->getDumpsCount() > 0) {
107+
$panel = $collector->getName();
108+
}
109+
}
110+
}
111+
92112
if (!$profile->hasCollector($panel)) {
93113
throw new NotFoundHttpException(sprintf('Panel "%s" is not available for token "%s".', $panel, $token));
94114
}

‎src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public function onKernelResponse(FilterResponseEvent $event)
6969
try {
7070
$response->headers->set(
7171
'X-Debug-Token-Link',
72-
$this->urlGenerator->generate('_profiler', ['token' => $response->headers->get('X-Debug-Token')], UrlGeneratorInterface::ABSOLUTE_URL)
72+
$this->urlGenerator->generate('_profiler', ['token' => $response->headers->get('X-Debug-Token'), 'panel' => '_best'], UrlGeneratorInterface::ABSOLUTE_URL)
7373
);
7474
} catch (\Exception $e) {
7575
$response->headers->set('X-Debug-Error', \get_class($e).': '.preg_replace('/\s+/', ' ', $e->getMessage()));

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig
+1-1Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php
+98-3Lines changed: 98 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\SourceContextLoaderInterface;
27+
use Twig\Source;
2028

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

188-
private function createController($profiler, $twig, $withCSP): ProfilerController
196+
/**
197+
* @dataProvider bestPanelProvider
198+
*/
199+
public function testBestPanel(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+
$loader = $this->createMock(SourceContextLoaderInterface::class);
215+
$loader
216+
->expects($this->atLeastOnce())
217+
->method('getSourceContext')
218+
->with($this->logicalXor($expectedTemplate = 'expected_template.html.twig', 'other_template.html.twig'))
219+
->willReturn(new Source('foo', 'bar'));
220+
221+
$twig = $this->createMock(Environment::class);
222+
$twig
223+
->expects($this->atLeastOnce())
224+
->method('getLoader')
225+
->willReturn($loader);
226+
$twig
227+
->expects($this->once())
228+
->method('render')
229+
->with($expectedTemplate);
230+
231+
$request = new Request();
232+
$request->query->set('panel', '_best');
233+
234+
$this
235+
->createController($profiler, $twig, false, array_map(function (string $collectorName) use ($expectedPanel, $expectedTemplate): array {
236+
if ($collectorName === $expectedPanel) {
237+
return [$expectedPanel, $expectedTemplate];
238+
}
239+
240+
return [$collectorName, 'other_template.html.twig'];
241+
}, $collectorsNames))
242+
->panelAction($request, $profile->getToken());
243+
}
244+
245+
public function bestPanelProvider(): \Generator
246+
{
247+
// Test default behavior
248+
$profile = new Profile('xxxxxx');
249+
$profile->addCollector($requestDataCollector = new RequestDataCollector());
250+
yield [$requestDataCollector->getName(), $profile];
251+
252+
// Test exception
253+
$profile = new Profile('xxxxxx');
254+
$profile->addCollector($exceptionDataCollector = new ExceptionDataCollector());
255+
$exceptionDataCollector->collect(new Request(), new Response(), new \DomainException());
256+
yield [$exceptionDataCollector->getName(), $profile];
257+
258+
// Test exception priority
259+
$dumpDataCollector = $this->createMock(DumpDataCollector::class);
260+
$dumpDataCollector
261+
->expects($this->atLeastOnce())
262+
->method('getName')
263+
->willReturn('dump');
264+
$dumpDataCollector
265+
->expects($this->atLeastOnce())
266+
->method('getDumpsCount')
267+
->willReturn(1);
268+
$profile = new Profile('xxxxxx');
269+
$profile->setCollectors([$exceptionDataCollector, $dumpDataCollector]);
270+
yield [$exceptionDataCollector->getName(), $profile];
271+
272+
// Test exception priority when defined afterwards
273+
$profile = new Profile('xxxxxx');
274+
$profile->setCollectors([$dumpDataCollector, $exceptionDataCollector]);
275+
yield [$exceptionDataCollector->getName(), $profile];
276+
277+
// Test dump
278+
$profile = new Profile('xxxxxx');
279+
$profile->addCollector($dumpDataCollector);
280+
yield [$dumpDataCollector->getName(), $profile];
281+
}
282+
283+
private function createController($profiler, $twig, $withCSP, array $templates = []): ProfilerController
189284
{
190285
$urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock();
191286

192287
if ($withCSP) {
193288
$nonceGenerator = $this->getMockBuilder('Symfony\Bundle\WebProfilerBundle\Csp\NonceGenerator')->getMock();
194289
$nonceGenerator->method('generate')->willReturn('dummy_nonce');
195290

196-
return new ProfilerController($urlGenerator, $profiler, $twig, [], new ContentSecurityPolicyHandler($nonceGenerator));
291+
return new ProfilerController($urlGenerator, $profiler, $twig, $templates, new ContentSecurityPolicyHandler($nonceGenerator));
197292
}
198293

199-
return new ProfilerController($urlGenerator, $profiler, $twig, []);
294+
return new ProfilerController($urlGenerator, $profiler, $twig, $templates);
200295
}
201296
}

‎src/Symfony/Bundle/WebProfilerBundle/Tests/EventListener/WebDebugToolbarListenerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/WebProfilerBundle/Tests/EventListener/WebDebugToolbarListenerTest.php
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ public function testXDebugUrlHeader()
243243
$urlGenerator
244244
->expects($this->once())
245245
->method('generate')
246-
->with('_profiler', ['token' => 'xxxxxxxx'], UrlGeneratorInterface::ABSOLUTE_URL)
246+
->with('_profiler', ['token' => 'xxxxxxxx', 'panel' => '_best'], UrlGeneratorInterface::ABSOLUTE_URL)
247247
->willReturn('http://mydomain.com/_profiler/xxxxxxxx')
248248
;
249249

@@ -264,7 +264,7 @@ public function testThrowingUrlGenerator()
264264
$urlGenerator
265265
->expects($this->once())
266266
->method('generate')
267-
->with('_profiler', ['token' => 'xxxxxxxx'])
267+
->with('_profiler', ['token' => 'xxxxxxxx', 'panel' => '_best'])
268268
->willThrowException(new \Exception('foo'))
269269
;
270270

@@ -285,7 +285,7 @@ public function testThrowingErrorCleanup()
285285
$urlGenerator
286286
->expects($this->once())
287287
->method('generate')
288-
->with('_profiler', ['token' => 'xxxxxxxx'])
288+
->with('_profiler', ['token' => 'xxxxxxxx', 'panel' => '_best'])
289289
->willThrowException(new \Exception("This\nmultiline\r\ntabbed text should\tcome out\r on\n \ta single plain\r\nline"))
290290
;
291291

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.