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

Skip to content

Commit 4d6fe5c

Browse files
feature #33783 [WebProfilerBundle] Try to display the most useful panel by default (fancyweb)
This PR was merged into the 4.4 branch. Discussion ---------- [WebProfilerBundle] Try to display the most useful panel by default | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | no | New feature? | yes | Deprecations? | yes | Tickets | - | License | MIT | Doc PR | - Alternative to #32491, the goal stays the same. I think reserving a data collector name is fine, isn'it ? It's not likely that end users use this name (that's why I added an underscore) + shouldn't be hard for them to just rename it. I don't think adding a configuration option to toggle the "_best" behavior is useful, should be by default for DX IMHO. Not adding an extension point for now (for end users to set their panel as the "best"), maybe later if someone request it? Commits ------- a45dd98 [WebProfilerBundle] Try to display the most useful panel by default
2 parents e3aed10 + a45dd98 commit 4d6fe5c

File tree

4 files changed

+130
-10
lines changed

4 files changed

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

192290
if ($withCSP) {
193291
$nonceGenerator = $this->getMockBuilder('Symfony\Bundle\WebProfilerBundle\Csp\NonceGenerator')->getMock();
194292
$nonceGenerator->method('generate')->willReturn('dummy_nonce');
195293

196-
return new ProfilerController($urlGenerator, $profiler, $twig, [], new ContentSecurityPolicyHandler($nonceGenerator));
294+
return new ProfilerController($urlGenerator, $profiler, $twig, $templates, new ContentSecurityPolicyHandler($nonceGenerator));
197295
}
198296

199-
return new ProfilerController($urlGenerator, $profiler, $twig, []);
297+
return new ProfilerController($urlGenerator, $profiler, $twig, $templates);
200298
}
201299
}

src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateManagerTest.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
use Symfony\Bundle\WebProfilerBundle\Tests\TestCase;
1616
use Symfony\Component\HttpKernel\Profiler\Profile;
1717
use Twig\Environment;
18-
use Twig\Source;
18+
use Twig\Loader\LoaderInterface;
19+
use Twig\Loader\SourceContextLoaderInterface;
1920

2021
/**
2122
* Test for TemplateManager class.
@@ -104,11 +105,14 @@ protected function mockTwigEnvironment()
104105
{
105106
$this->twigEnvironment = $this->getMockBuilder('Twig\Environment')->disableOriginalConstructor()->getMock();
106107

107-
if (interface_exists('Twig\Loader\SourceContextLoaderInterface')) {
108-
$loader = $this->getMockBuilder('Twig\Loader\SourceContextLoaderInterface')->getMock();
108+
if (Environment::MAJOR_VERSION > 1) {
109+
$loader = $this->createMock(LoaderInterface::class);
110+
$loader
111+
->expects($this->any())
112+
->method('exists')
113+
->willReturn(true);
109114
} else {
110-
$loader = $this->getMockBuilder('Twig\Loader\LoaderInterface')->getMock();
111-
$loader->method('getSourceContext')->willReturn(new Source('source-code', 'source-name'));
115+
$loader = $this->createMock(SourceContextLoaderInterface::class);
112116
}
113117

114118
$this->twigEnvironment->expects($this->any())->method('getLoader')->willReturn($loader);

0 commit comments

Comments
 (0)