8000 Merge branch '4.1' · nowiko/symfony@c871857 · GitHub
[go: up one dir, main page]

Skip to content

Commit c871857

Browse files
Merge branch '4.1'
* 4.1: [VarDumper] Fix dumping by splitting Server/Connection out of Dumper/ServerDumper [HttpKernel] fix argument's error messages in ServiceValueResolver [DI] Avoid leaking unused env placeholders
2 parents df44236 + ac74c9a commit c871857

File tree

19 files changed

+315
-128
lines changed

19 files changed

+315
-128
lines changed

src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use Symfony\Component\DependencyInjection\Extension\Extension;
1818
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
1919
use Symfony\Component\DependencyInjection\Reference;
20-
use Symfony\Component\VarDumper\Dumper\ServerDumper;
2120

2221
/**
2322
* DebugExtension.
@@ -43,20 +42,21 @@ public function load(array $configs, ContainerBuilder $container)
4342
->addMethodCall('setMaxString', array($config['max_string_length']));
4443

4544
if (null === $config['dump_destination']) {
46-
//no-op
45+
$container->getDefinition('var_dumper.command.server_dump')
46+
->setClass(ServerDumpPlaceholderCommand::class)
47+
;
4748
} elseif (0 === strpos($config['dump_destination'], 'tcp://')) {
48-
$serverDumperHost = $config['dump_destination'];
4949
$container->getDefinition('debug.dump_listener')
50-
->replaceArgument(1, new Reference('var_dumper.server_dumper'))
50+
->replaceArgument(2, new Reference('var_dumper.server_connection'))
5151
;
5252
$container->getDefinition('data_collector.dump')
53-
->replaceArgument(4, new Reference('var_dumper.server_dumper'))
53+
->replaceArgument(4, new Reference('var_dumper.server_connection'))
5454
;
5555
$container->getDefinition('var_dumper.dump_server')
56-
->replaceArgument(0, $serverDumperHost)
56+
->replaceArgument(0, $config['dump_destination'])
5757
;
58-
$container->getDefinition('var_dumper.server_dumper')
59-
->replaceArgument(0, $serverDumperHost)
58+
$container->getDefinition('var_dumper.server_connection')
59+
->replaceArgument(0, $config['dump_destination'])
6060
;
6161
} else {
6262
$container->getDefinition('var_dumper.cli_dumper')
@@ -65,13 +65,9 @@ public function load(array $configs, ContainerBuilder $container)
6565
$container->getDefinition('data_collector.dump')
6666
->replaceArgument(4, new Reference('var_dumper.cli_dumper'))
6767
;
68-
}
69-
70-
if (!isset($serverDumperHost)) {
71-
$container->getDefinition('var_dumper.command.server_dump')->setClass(ServerDumpPlaceholderCommand::class);
72-
if (!class_exists(ServerDumper::class)) {
73-
$container->removeDefinition('var_dumper.command.server_dump');
74-
}
68+
$container->getDefinition('var_dumper.command.server_dump')
69+
->setClass(ServerDumpPlaceholderCommand::class)
70+
;
7571
}
7672
}
7773

src/Symfony/Bundle/DebugBundle/Resources/config/services.xml

Lines changed: 4 additions & 4 deletions
5C7
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@
2323
<argument type="service" id="debug.file_link_formatter" on-invalid="ignore"></argument>
2424
<argument>%kernel.charset%</argument>
2525
<argument type="service" id="request_stack" />
26-
<argument>null</argument><!-- var_dumper.cli_dumper or var_dumper.server_dumper when debug.dump_destination is set -->
26+
<argument>null</argument><!-- var_dumper.cli_dumper or var_dumper.server_connection when debug.dump_destination is set -->
2727
</service>
2828

2929
<service id="debug.dump_listener" class="Symfony\Component\HttpKernel\EventListener\DumpListener">
3030
<tag name="kernel.event_subscriber" />
3131
<argument type="service" id="var_dumper.cloner" />
3232
<argument type="service" id="var_dumper.cli_dumper" />
33+
<argument>null</argument>
3334
</service>
3435

3536
<service id="var_dumper.cloner" class="Symfony\Component\VarDumper\Cloner\VarCloner" public="true" />
@@ -50,9 +51,8 @@
5051
</call>
5152
</service>
5253

53-
<service id="var_dumper.server_dumper" class="Symfony\Component\VarDumper\Dumper\ServerDumper">
54-
<argument>null</argument> <!-- server host -->
55-
<argument type="service" id="var_dumper.cli_dumper" />
54+
<service id="var_dumper.server_connection" class="Symfony\Component\VarDumper\Server\Connection">
55+
<argument /> <!-- server host -->
5656
<argument type="collection">
5757
<argument type="service" key="source">
5858
<service class="Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider">

src/Symfony/Bundle/DebugBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"ext-xml": "*",
2121
"symfony/http-kernel": "~3.4|~4.0",
2222
"symfony/twig-bridge": "~3.4|~4.0",
23-
"symfony/var-dumper": "~4.1"
23+
"symfony/var-dumper": "^4.1.1"
2424
},
2525
"require-dev": {
2626
"symfony/config": "~3.4|~4.0",

src/Symfony/Component/DependencyInjection/Compiler/ValidateEnvPlaceholdersPass.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ public function process(ContainerBuilder $container)
8484
} finally {
8585
BaseNode::resetPlaceholders();
8686
}
87+
88+
$resolvingBag->clearUnusedEnvPlaceholders();
8789
}
8890

8991
private static function getType($value): string

src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ public function getUnusedEnvPlaceholders(): array
8787
return $this->unusedEnvPlaceholders;
8888
}
8989

90+
public function clearUnusedEnvPlaceholders()
91+
{
92+
$this->unusedEnvPlaceholders = array();
93+
}
94+
9095
/**
9196
* Merges the env placeholders of another EnvPlaceholderParameterBag.
9297
*/

src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php

Lines changed: 27 additions & 1 deletion
< 10000 tr class="diff-line-row">
Original file line numberDiff line numberDiff line change
@@ -226,14 +226,29 @@ public function testEnvWithVariableNode(): void
226226
public function testConfigurationWithoutRootNode(): void
227227
{
228228
$container = new ContainerBuilder();
229-
$container->registerExtension($ext = new EnvExtension(new EnvConfigurationWithoutRootNode()));
229+
$container->registerExtension(new EnvExtension(new EnvConfigurationWithoutRootNode()));
230230
$container->loadFromExtension('env_extension');
231231

232232
$this->doProcess($container);
233233

234234
$this->addToAssertionCount(1);
235235
}
236236

237+
public function testDiscardedEnvInConfig(): void
238+
{
239+
$container = new ContainerBuilder();
240+
$container->setParameter('env(BOOLISH)', '1');
241+
$container->setParameter('boolish', '%env(BOOLISH)%');
242+
$container->registerExtension(new EnvExtension());
243+
$container->prependExtensionConfig('env_extension', array(
244+
'array_node' => array('bool_force_cast' => '%boolish%'),
245+
));
246+
247+
$container->compile(true);
248+
249+
$this->assertSame('1', $container->getParameter('boolish'));
250+
}
251+
237252
private function doProcess(ContainerBuilder $container): void
238253
{
239254
(new MergeExtensionConfigurationPass())->process($container);
@@ -260,8 +275,19 @@ public function getConfigTreeBuilder()
260275
->ifTrue(function ($value) { return !is_array($value); })
261276
->then(function ($value) { return array('child_node' => $value); })
262277
->end()
278+
->beforeNormalization()
279+
->ifArray()
280+
->then(function (array $v) {
281+
if (isset($v['bool_force_cast'])) {
282+
$v['bool_force_cast'] = (bool) $v['bool_force_cast'];
283+
}
284+
285+
return $v;
286+
})
287+
->end()
263288
->children()
264289
->scalarNode('child_node')->end()
290+
->booleanNode('bool_force_cast')->end()
265291
->integerNode('int_unset_at_zero')
266292
->validate()
267293
->ifTrue(function ($value) { return 0 === $value; })

src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ServiceValueResolver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public function resolve(Request $request, ArgumentMetadata $argument)
6868
yield $this->container->get($controller)->get($argument->getName());
6969
} catch (RuntimeException $e) {
7070
$what = sprintf('argument $%s of "%s()"', $argument->getName(), $controller);
71-
$message = preg_replace('/service "service_locator\.[^"]++"/', $what, $e->getMessage());
71+
$message = preg_replace('/service "\.service_locator\.[^"]++"/', $what, $e->getMessage());
7272

7373
if ($e->getMessage() === $message) {
7474
$message = sprintf('Cannot resolve %s: %s', $what, $message);

src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider;
2222
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
2323
use Symfony\Component\VarDumper\Dumper\DataDumperInterface;
24-
use Symfony\Component\VarDumper\Dumper\ServerDumper;
24+
use Symfony\Component\VarDumper\Server\Connection;
2525

2626
/**
2727
* @author Nicolas Grekas <p@tchwork.com>
@@ -38,17 +38,18 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
3838
private $charset;
3939
private $requestStack;
4040
private $dumper;
41-
private $dumperIsInjected;
4241
private $sourceContextProvider;
4342

44-
public function __construct(Stopwatch $stopwatch = null, $fileLinkFormat = null, string $charset = null, RequestStack $requestStack = null, DataDumperInterface $dumper = null)
43+
/**
44+
* @param DataDumperInterface|Connection|null $dumper
45+
*/
46+
public function __construct(Stopwatch $stopwatch = null, $fileLinkFormat = null, string $charset = null, RequestStack $requestStack = null, $dumper = null)
4547
{
4648
$this->stopwatch = $stopwatch;
4749
$this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
4850
$this->charset = $charset ?: ini_get('php.output_encoding') ?: ini_get('default_charset') ?: 'UTF-8';
4951
$this->requestStack = $requestStack;
5052
$this->dumper = $dumper;
51-
$this->dumperIsInjected = null !== $dumper;
5253

5354
// All clones share these properties by reference:
5455
$this->rootRefs = array(
@@ -58,7 +59,7 @@ public function __construct(Stopwatch $stopwatch = null, $fileLinkFormat = null,
5859
&$this->clonesCount,
5960
);
6061

61-
$this->sourceContextProvider = $dumper instanceof ServerDumper && isset($dumper->getContextProviders()['source']) ? $dumper->getContextProviders()['source'] : new SourceContextProvider($this->charset);
62+
$this->sourceContextProvider = $dumper instanceof Connection && isset($dumper->getContextProviders()['source']) ? $dumper->getContextProviders()['source'] : new SourceContextProvider($this->charset);
6263
}
6364

6465
public function __clone()
@@ -71,14 +72,17 @@ public function dump(Data $data)
7172
if ($this->stopwatch) {
7273
$this->stopwatch->start('dump');
7374
}
74-
if ($this->isCollected && !$this->dumper) {
75-
$this->isCollected = false;
76-
}
7775

7876
list('name' => $name, 'file' => $file, 'line' => $line 325D , 'file_excerpt' => $fileExcerpt) = $this->sourceContextProvider->getContext();
7977

80-
if ($this->dumper) {
78+
if ($this->dumper instanceof Connection) {
79+
if (!$this->dumper->write($data)) {
80+
$this->isCollected = false;
81+
}
82+
} elseif ($this->dumper) {
8183
$this->doDump($this->dumper, $data, $name, $file, $line);
84+
} else {
85+
$this->isCollected = false;
8286
}
8387

8488
$this->data[] = compact('data', 'name', 'file', 'line', 'fileExcerpt');
@@ -141,9 +145,6 @@ public function serialize()
141145
$this->data = array();
142146
$this->dataCount = 0;
143147
$this->isCollected = true;
144-
if (!$this->dumperIsInjected) {
145-
$this->dumper = null;
146-
}
147148

148149
return $ser;
149150
}
@@ -245,7 +246,7 @@ private function doDump(DataDumperInterface $dumper, $data, $name, $file, $line)
245246
};
246247
$contextDumper = $contextDumper->bindTo($dumper, $dumper);
247248
$contextDumper($name, $file, $line, $this->fileLinkFormat);
248-
} elseif (!$dumper instanceof ServerDumper) {
249+
} else {
249250
$cloner = new VarCloner();
250251
$dumper->dump($cloner->cloneVar($name.' on line '.$line.':'));
251252
}

src/Symfony/Component/HttpKernel/EventListener/DumpListener.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1616
use Symfony\Component\VarDumper\Cloner\ClonerInterface;
1717
use Symfony\Component\VarDumper\Dumper\DataDumperInterface;
18+
use Symfony\Component\VarDumper\Server\Connection;
1819
use Symfony\Component\VarDumper\VarDumper;
1920

2021
/**
@@ -26,20 +27,27 @@ class DumpListener implements EventSubscriberInterface
2627
{
2728
private $cloner;
2829
private $dumper;
30+
private $connection;
2931

30-
public function __construct(ClonerInterface $cloner, DataDumperInterface $dumper)
32+
public function __construct(ClonerInterface $cloner, DataDumperInterface $dumper, Connection $connection = null)
3133
{
3234
$this->cloner = $cloner;
3335
$this->dumper = $dumper;
36+
$this->connection = $connection;
3437
}
3538

3639
public function configure()
3740
{
3841
$cloner = $this->cloner;
3942
$dumper = $this->dumper;
43+
$connection = $this->connection;
4044

41-
VarDumper::setHandler(function ($var) use ($cloner, $dumper) {
42-
$dumper->dump($cloner->cloneVar($var));
45+
VarDumper::setHandler(static function ($var) use ($cloner, $dumper, $connection) {
46+
$data = $cloner->cloneVar($var);
47+
48+
if (!$connection || !$connection->write($data)) {
49+
$dumper->dump($data);
50+
}
4351
});
4452
}
4553

src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
namespace Symfony\Component\HttpKernel\Tests\Controller\ArgumentResolver;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
1516
use Symfony\Component\DependencyInjection\ServiceLocator;
1617
use Symfony\Component\HttpFoundation\Request;
1718
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\ServiceValueResolver;
1819
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
20+
use Symfony\Component\HttpKernel\DependencyInjection\RegisterControllerArgumentLocatorsPass;
1921

2022
class ServiceValueResolverTest extends TestCase
2123
{
@@ -85,6 +87,25 @@ public function testControllerNameIsAnArray()
8587
$this->assertYieldEquals(array(new DummyService()), $resolver->resolve($request, $argument));
8688
}
8789

90+
/**
91+
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
92+
* @expectedExceptionMessage Cannot autowire argument $dummy of "Symfony\Component\HttpKernel\Tests\Controller\ArgumentResolver\DummyController::index()": it references class "Symfony\Component\HttpKernel\Tests\Controller\ArgumentResolver\DummyService" but no such service exists.
93+
*/
94+
public function testErrorIsTruncated()
95+
{
96+
$container = new ContainerBuilder();
97+
$container->addCompilerPass(new RegisterControllerArgumentLocatorsPass());
98+
99+
$container->register('argument_resolver.service', ServiceValueResolver::class)->addArgument(null)->setPublic(true);
100+
$container->register(DummyController::class)->addTag('controller.service_arguments')->setPublic(true);
101+
102+
$container->compile();
103+
104+
$request = $this->requestWithAttributes(array('_controller' => array(DummyController::class, 'index')));
105+
$argument = new ArgumentMetadata('dummy', DummyService::class, false, false, null);
106+
$container->get('argument_resolver.service')->resolve($request, $argument)->current();
107+
}
108+
88109
private function requestWithAttributes(array $attributes)
89110
{
90111
$request = Request::create('/');
@@ -110,3 +131,10 @@ private function assertYieldEquals(array $expected, \Generator $generator)
110131
class DummyService
111132
{
112133
}
134+
135+
class DummyController
136+
{
137+
public function index(DummyService $dummy)
138+
{
139+
}
140+
}

src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use Symfony\Component\HttpKernel\DataCollector\DumpDataCollector;
1818
use Symfony\Component\VarDumper\Cloner\Data;
1919
use Symfony\Component\VarDumper\Dumper\CliDumper;
20-
use Symfony\Component\VarDumper\Dumper\ServerDumper;
20+
use Symfony\Component\VarDumper\Server\Connection;
2121

2222
/**
2323
* @author Nicolas Grekas <p@tchwork.com>
@@ -57,13 +57,13 @@ public function testDump()
5757
$this->assertSame('a:2:{i:0;b:0;i:1;s:5:"UTF-8";}', $collector->serialize());
5858
}
5959

60-
public function testDumpWithServerDumper()
60+
public function testDumpWithServerConnection()
6161
{
6262
$data = new Data(array(array(123)));
6363

6464
// Server is up, server dumper is used
65-
$serverDumper = $this->getMockBuilder(ServerDumper::class)->disableOriginalConstructor()->getMock();
66-
$serverDumper->expects($this->once())->method('dump');
65+
$serverDumper = $this->getMockBuilder(Connection::class)->disableOriginalConstructor()->getMock();
66+
$serverDumper->expects($this->once())->method('write')->willReturn(true);
6767

6868
$collector = new DumpDataCollector(null, null, null, null, $serverDumper);
6969
$collector->dump($data);

src/Symfony/Component/HttpKernel/composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"symfony/stopwatch": "~3.4|~4.0",
3838
"symfony/templating": "~3.4|~4.0",
3939
"symfony/translation": "~3.4|~4.0",
40-
"symfony/var-dumper": "~4.1",
40+
"symfony/var-dumper": "^4.1.1",
4141
"psr/cache": "~1.0"
4242
},
4343
"provide": {
@@ -46,7 +46,7 @@
4646
"conflict": {
4747
"symfony/config": "<3.4",
4848
"symfony/dependency-injection": "<4.2",
49-
"symfony/var-dumper": "<4.1",
49+
"symfony/var-dumper": "<4.1.1",
5050
"twig/twig": "<1.34|<2.4,>=2"
5151
},
5252
"suggest": {

src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ public function dump(Data $data, $output = null)
164164
*/
165165
protected function dumpLine($depth)
166166
{
167-
call_user_func($this->lineDumper, $this->line, $depth, $this->indentPad);
167+
\call_user_func($this->lineDumper, $this->line, $depth, $this->indentPad);
168168
$this->line = '';
169169
}
170170

0 commit comments

Comments
 (0)
0