Skip to content

Commit 07b755d

Browse files
committed
feat: extend web profiler config for replace on ajax requests
1 parent 78f4d9a commit 07b755d

File tree

8 files changed

+110
-9
lines changed

8 files changed

+110
-9
lines changed

src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
7.3
5+
---
6+
7+
* Add `ajax_replace` option for replacing toolbar on AJAX requests
8+
49
7.2
510
---
611

@@ -65,7 +70,7 @@ CHANGELOG
6570
-----
6671

6772
* added information about orphaned events
68-
* made the toolbar auto-update with info from ajax reponses when they set the
73+
* made the toolbar auto-update with info from ajax responses when they set the
6974
`Symfony-Debug-Toolbar-Replace header` to `1`
7075

7176
4.0.0

src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/Configuration.php

+10-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,16 @@ public function getConfigTreeBuilder(): TreeBuilder
3333

3434
$treeBuilder->getRootNode()
3535
->children()
36-
->booleanNode('toolbar')->defaultFalse()->end()
36+
->arrayNode('toolbar')
37+
->info('Profiler toolbar configuration')
38+
->canBeEnabled()
39+
->children()
40+
->booleanNode('ajax_replace')
41+
->defaultFalse()
42+
->info('Replace toolbar on AJAX requests')
43+
->end()
44+
->end()
45+
->end()
3746
->booleanNode('intercept_redirects')->defaultFalse()->end()
3847
->scalarNode('excluded_ajax_paths')->defaultValue('^/((index|app(_[\w]+)?)\.php/)?_wdt')->end()
3948
->end()

src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,12 @@ public function load(array $configs, ContainerBuilder $container): void
4646
$loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
4747
$loader->load('profiler.php');
4848

49-
if ($config['toolbar'] || $config['intercept_redirects']) {
49+
if ($config['toolbar']['enabled'] || $config['intercept_redirects']) {
5050
$loader->load('toolbar.php');
5151
$container->getDefinition('web_profiler.debug_toolbar')->replaceArgument(4, $config['excluded_ajax_paths']);
52+
$container->getDefinition('web_profiler.debug_toolbar')->replaceArgument(7, $config['toolbar']['ajax_replace']);
5253
$container->setParameter('web_profiler.debug_toolbar.intercept_redirects', $config['intercept_redirects']);
53-
$container->setParameter('web_profiler.debug_toolbar.mode', $config['toolbar'] ? WebDebugToolbarListener::ENABLED : WebDebugToolbarListener::DISABLED);
54+
$container->setParameter('web_profiler.debug_toolbar.mode', $config['toolbar']['enabled'] ? WebDebugToolbarListener::ENABLED : WebDebugToolbarListener::DISABLED);
5455
}
5556

5657
$container->getDefinition('debug.file_link_formatter')

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

+5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public function __construct(
4848
private string $excludedAjaxPaths = '^/bundles|^/_wdt',
4949
private ?ContentSecurityPolicyHandler $cspHandler = null,
5050
private ?DumpDataCollector $dumpDataCollector = null,
51+
private bool $ajaxReplace = false,
5152
) {
5253
}
5354

@@ -96,6 +97,10 @@ public function onKernelResponse(ResponseEvent $event): void
9697

9798
// do not capture redirects or modify XML HTTP Requests
9899
if ($request->isXmlHttpRequest()) {
100+
if (self::ENABLED === $this->mode && $this->ajaxReplace) {
101+
$response->headers->set('Symfony-Debug-Toolbar-Replace', '1');
102+
}
103+
99104
return;
100105
}
101106

src/Symfony/Bundle/WebProfilerBundle/Resources/config/schema/webprofiler-1.0.xsd

+8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99

1010
<xsd:complexType name="config">
1111
<xsd:attribute name="toolbar" type="xsd:boolean" />
12+
<xsd:sequence>
13+
<xsd:element name="toolbar" type="toolbar" minOccurs="0" maxOccurs="1" />
14+
</xsd:sequence>
1215
<xsd:attribute name="intercept-redirects" type="xsd:boolean" />
1316
</xsd:complexType>
17+
18+
<xsd:complexType name="toolbar">
19+
<xsd:attribute name="enabled" type="xsd:boolean" />
20+
<xsd:attribute name="ajax-replace" type="xsd:boolean" />
21+
</xsd:complexType>
1422
</xsd:schema>

src/Symfony/Bundle/WebProfilerBundle/Resources/config/toolbar.php

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
abstract_arg('paths that should be excluded from the AJAX requests shown in the toolbar'),
2626
service('web_profiler.csp.handler'),
2727
service('data_collector.dump')->ignoreOnInvalid(),
28+
abstract_arg('whether to replace toolbar on AJAX requests or not'),
2829
])
2930
->tag('kernel.event_subscriber')
3031
;

src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/ConfigurationTest.php

+31-5
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,46 @@ public static function getDebugModes()
3636
'options' => [],
3737
'expectedResult' => [
3838
'intercept_redirects' => false,
39-
'toolbar' => false,
39+
'toolbar' => [
40+
'enabled' => false,
41+
'ajax_replace' => false,
42+
],
4043
'excluded_ajax_paths' => '^/((index|app(_[\w]+)?)\.php/)?_wdt',
4144
],
4245
],
4346
[
4447
'options' => ['toolbar' => true],
4548
'expectedResult' => [
4649
'intercept_redirects' => false,
47-
'toolbar' => true,
50+
'toolbar' => [
51+
'enabled' => true,
52+
'ajax_replace' => false,
53+
],
4854
'excluded_ajax_paths' => '^/((index|app(_[\w]+)?)\.php/)?_wdt',
4955
],
5056
],
5157
[
5258
'options' => ['excluded_ajax_paths' => 'test'],
5359
'expectedResult' => [
5460
'intercept_redirects' => false,
55-
'toolbar' => false,
61+
'toolbar' => [
62+
'enabled' => false,
63+
'ajax_replace' => false,
64+
],
5665
'excluded_ajax_paths' => 'test',
5766
],
5867
],
68+
[
69+
'options' => ['toolbar' => ['ajax_replace' => true]],
70+
'expectedResult' => [
71+
'intercept_redirects' => false,
72+
'toolbar' => [
73+
'enabled' => true,
74+
'ajax_replace' => true,
75+
],
76+
'excluded_ajax_paths' => '^/((index|app(_[\w]+)?)\.php/)?_wdt',
77+
],
78+
],
5979
];
6080
}
6181

@@ -78,15 +98,21 @@ public static function getInterceptRedirectsConfiguration()
7898
'interceptRedirects' => true,
7999
'expectedResult' => [
80100
'intercept_redirects' => true,
81-
'toolbar' => false,
101+
'toolbar' => [
102+
'enabled' => false,
103+
'ajax_replace' => false,
104+
],
82105
'excluded_ajax_paths' => '^/((index|app(_[\w]+)?)\.php/)?_wdt',
83106
],
84107
],
85108
[
86109
'interceptRedirects' => false,
87110
'expectedResult' => [
88111
'intercept_redirects' => false,
89-
'toolbar' => false,
112+
'toolbar' => [
113+
'enabled' => false,
114+
'ajax_replace' => false,
115+
],
90116
'excluded_ajax_paths' => '^/((index|app(_[\w]+)?)\.php/)?_wdt',
91117
],
92118
],

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

+46
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,52 @@ public function testNullContentTypeWithNoDebugEnv()
357357
$this->expectNotToPerformAssertions();
358358
}
359359

360+
public function testAjaxReplaceHeaderOnDisabledToolbar()
361+
{
362+
$response = new Response();
363+
$event = new ResponseEvent($this->createMock(Kernel::class), new Request(), HttpKernelInterface::MAIN_REQUEST, $response);
364+
365+
$listener = new WebDebugToolbarListener($this->getTwigMock(), false, WebDebugToolbarListener::DISABLED, null, '', null, null, true);
366+
$listener->onKernelResponse($event);
367+
368+
$this->assertFalse($response->headers->has('Symfony-Debug-Toolbar-Replace'));
369+
}
370+
371+
public function testAjaxReplaceHeaderOnDisabledReplace()
372+
{
373+
$response = new Response();
374+
$event = new ResponseEvent($this->createMock(Kernel::class), new Request(), HttpKernelInterface::MAIN_REQUEST, $response);
375+
376+
$listener = new WebDebugToolbarListener($this->getTwigMock(), false, WebDebugToolbarListener::ENABLED, null, '', null, null);
377+
$listener->onKernelResponse($event);
378+
379+
$this->assertFalse($response->headers->has('Symfony-Debug-Toolbar-Replace'));
380+
}
381+
382+
public function testAjaxReplaceHeaderOnEnabledAndNonXHR()
383+
{
384+
$response = new Response();
385+
$event = new ResponseEvent($this->createMock(Kernel::class), new Request(), HttpKernelInterface::MAIN_REQUEST, $response);
386+
387+
$listener = new WebDebugToolbarListener($this->getTwigMock(), false, WebDebugToolbarListener::ENABLED, null, '', null, null, true);
388+
$listener->onKernelResponse($event);
389+
390+
$this->assertFalse($response->headers->has('Symfony-Debug-Toolbar-Replace'));
391+
}
392+
393+
public function testAjaxReplaceHeaderOnEnabledAndXHR()
394+
{
395+
$request = new Request();
396+
$request->headers->set('X-Requested-With', 'XMLHttpRequest');
397+
$response = new Response();
398+
$event = new ResponseEvent($this->createMock(Kernel::class), $request, HttpKernelInterface::MAIN_REQUEST, $response);
399+
400+
$listener = new WebDebugToolbarListener($this->getTwigMock(), false, WebDebugToolbarListener::ENABLED, null, '', null, null, true);
401+
$listener->onKernelResponse($event);
402+
403+
$this->assertEquals('1', $response->headers->get('Symfony-Debug-Toolbar-Replace'));
404+
}
405+
360406
protected function getTwigMock($render = 'WDT')
361407
{
362408
$templating = $this->createMock(Environment::class);

0 commit comments

Comments
 (0)