Skip to content

Commit 1188b4d

Browse files
committed
Merge branch '2.7' into 2.8
* 2.7: Regression test for missing controller arguments fix a test checking for a value [Form][DX] FileType "multiple" fixes fixed CS [TwigBundle] Fix twig loader registered twice [Console] Fix wrong handling of multiline arg/opt descriptions [DependencyInjection] PhpDumper.php: hasReference() should not search references in lazy service arguments. [Form] fixed "empty_value" option deprecation
2 parents 03c79be + e70dc64 commit 1188b4d

File tree

15 files changed

+197
-29
lines changed

15 files changed

+197
-29
lines changed

src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\TwigBundle\DependencyInjection\Compiler;
1313

14+
use Symfony\Component\DependencyInjection\Alias;
1415
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1516
use Symfony\Component\DependencyInjection\ContainerBuilder;
1617
use Symfony\Component\DependencyInjection\Reference;
@@ -73,7 +74,7 @@ public function process(ContainerBuilder $container)
7374
$loader->addTag('twig.loader');
7475
$loader->setMethodCalls($container->getDefinition('twig.loader.filesystem')->getMethodCalls());
7576

76-
$container->setDefinition('twig.loader.filesystem', $loader);
77+
$container->setAlias('twig.loader.filesystem', new Alias('twig.loader.native_filesystem', false));
7778
}
7879

7980
if ($container->has('assets.packages')) {

src/Symfony/Component/Console/Descriptor/TextDescriptor.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ protected function describeInputArgument(InputArgument $argument, array $options
3838
}
3939

4040
$totalWidth = isset($options['total_width']) ? $options['total_width'] : strlen($argument->getName());
41-
$spacingWidth = $totalWidth - strlen($argument->getName()) + 2;
41+
$spacingWidth = $totalWidth - strlen($argument->getName());
4242

43-
$this->writeText(sprintf(' <info>%s</info>%s%s%s',
43+
$this->writeText(sprintf(' <info>%s</info> %s%s%s',
4444
$argument->getName(),
4545
str_repeat(' ', $spacingWidth),
46-
// + 17 = 2 spaces + <info> + </info> + 2 spaces
47-
preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 17), $argument->getDescription()),
46+
// + 4 = 2 spaces before <info>, 2 spaces after </info>
47+
preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $argument->getDescription()),
4848
$default
4949
), $options);
5050
}
@@ -75,13 +75,13 @@ protected function describeInputOption(InputOption $option, array $options = arr
7575
sprintf('--%s%s', $option->getName(), $value)
7676
);
7777

78-
$spacingWidth = $totalWidth - strlen($synopsis) + 2;
78+
$spacingWidth = $totalWidth - strlen($synopsis);
7979

80-
$this->writeText(sprintf(' <info>%s</info>%s%s%s%s',
80+
$this->writeText(sprintf(' <info>%s</info> %s%s%s%s',
8181
$synopsis,
8282
str_repeat(' ', $spacingWidth),
83-
// + 17 = 2 spaces + <info> + </info> + 2 spaces
84-
preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 17), $option->getDescription()),
83+
// + 4 = 2 spaces before <info>, 2 spaces after </info>
84+
preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $option->getDescription()),
8585
$default,
8686
$option->isArray() ? '<comment> (multiple values allowed)</comment>' : ''
8787
), $options);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
<info>argument_name</info> multiline
2-
argument description
2+
argument description
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
<info>-o, --option_name=OPTION_NAME</info> multiline
2-
option description
2+
option description

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,18 @@ private function checkOutEdges(array $edges)
6060
$id = $node->getId();
6161

6262
if (empty($this->checkedNodes[$id])) {
63-
$searchKey = array_search($id, $this->currentPath);
64-
$this->currentPath[] = $id;
6563

66-
if (false !== $searchKey) {
67-
throw new ServiceCircularReferenceException($id, array_slice($this->currentPath, $searchKey));
68-
}
64+
// don't check circular dependencies for lazy services
65+
if (!$node->getValue() || !$node->getValue()->isLazy()) {
66+
$searchKey = array_search($id, $this->currentPath);
67+
$this->currentPath[] = $id;
68+
69+
if (false !== $searchKey) {
70+
throw new ServiceCircularReferenceException($id, array_slice($this->currentPath, $searchKey));
71+
}
6972

70-
$this->checkOutEdges($node->getOutEdges());
73+
$this->checkOutEdges($node->getOutEdges());
74+
}
7175

7276
$this->checkedNodes[$id] = true;
7377
array_pop($this->currentPath);

src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,13 @@ private function hasReference($id, array $arguments, $deep = false, array &$visi
13131313
$visited[$argumentId] = true;
13141314

13151315
$service = $this->container->getDefinition($argumentId);
1316+
1317+
// if the proxy manager is enabled, disable searching for references in lazy services,
1318+
// as these services will be instantiated lazily and don't have direct related references.
1319+
if ($service->isLazy() && !$this->getProxyDumper() instanceof NullDumper) {
1320+
continue;
1321+
}
1322+
13161323
$arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties());
13171324

13181325
if ($this->hasReference($id, $arguments, $deep, $visited)) {

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Tests\Dumper;
1313

14+
use DummyProxyDumper;
1415
use Symfony\Component\DependencyInjection\ContainerBuilder;
1516
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
1617
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
@@ -19,6 +20,8 @@
1920
use Symfony\Component\DependencyInjection\Variable;
2021
use Symfony\Component\ExpressionLanguage\Expression;
2122

23+
require_once __DIR__.'/../Fixtures/includes/classes.php';
24+
2225
class PhpDumperTest extends \PHPUnit_Framework_TestCase
2326
{
2427
protected static $fixturesPath;
@@ -294,4 +297,52 @@ public function testInitializePropertiesBeforeMethodCalls()
294297
$container = new \Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls();
295298
$this->assertTrue($container->get('bar')->callPassed(), '->dump() initializes properties before method calls');
296299
}
300+
301+
public function testCircularReferenceAllowanceForLazyServices()
302+
{
303+
$container = new ContainerBuilder();
304+
$container->register('foo', 'stdClass')->addArgument(new Reference('bar'));
305+
$container->register('bar', 'stdClass')->setLazy(true)->addArgument(new Reference('foo'));
306+
$container->compile();
307+
308+
$dumper = new PhpDumper($container);
309+
$dumper->dump();
310+
}
311+
312+
public function testCircularReferenceAllowanceForInlinedDefinitionsForLazyServices()
313+
{
314+
/*
315+
* test graph:
316+
* [connection] -> [event_manager] --> [entity_manager](lazy)
317+
* |
318+
* --(call)- addEventListener ("@lazy_service")
319+
*
320+
* [lazy_service](lazy) -> [entity_manager](lazy)
321+
*
322+
*/
323+
324+
$container = new ContainerBuilder();
325+
326+
$eventManagerDefinition = new Definition('stdClass');
327+
328+
$connectionDefinition = $container->register('connection', 'stdClass');
329+
$connectionDefinition->addArgument($eventManagerDefinition);
330+
331+
$container->register('entity_manager', 'stdClass')
332+
->setLazy(true)
333+
->addArgument(new Reference('connection'));
334+
335+
$lazyServiceDefinition = $container->register('lazy_service', 'stdClass');
336+
$lazyServiceDefinition->setLazy(true);
337+
$lazyServiceDefinition->addArgument(new Reference('entity_manager'));
338+
339+
$eventManagerDefinition->addMethodCall('addEventListener', array(new Reference('lazy_service')));
340+
341+
$container->compile();
342+
343+
$dumper = new PhpDumper($container);
344+
345+
$dumper->setProxyDumper(new DummyProxyDumper());
346+
$dumper->dump();
347+
}
297348
}

src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<?php
22

3+
use Symfony\Component\DependencyInjection\Definition;
4+
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper;
5+
36
function sc_configure($instance)
47
{
58
$instance->configure();
@@ -76,3 +79,21 @@ public function callPassed()
7679
return $this->callPassed;
7780
}
7881
}
82+
83+
class DummyProxyDumper implements ProxyDumper
84+
{
85+
public function isProxyCandidate(Definition $definition)
86+
{
87+
return false;
88+
}
89+
90+
public function getProxyFactoryCode(Definition $definition, $id)
91+
{
92+
return '';
93+
}
94+
95+
public function getProxyCode(Definition $definition)
96+
{
97+
return '';
98+
}
99+
}

src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@
3939

4040
class ChoiceType extends AbstractType
4141
{
42+
/**
43+
* @internal To be removed in 3.0
44+
*/
45+
const DEPRECATED_EMPTY_VALUE = '__deprecated_empty_value__';
46+
4247
/**
4348
* Caches created choice lists.
4449
*
@@ -344,7 +349,7 @@ public function configureOptions(OptionsResolver $resolver)
344349
};
345350

346351
$placeholderNormalizer = function (Options $options, $placeholder) use ($that) {
347-
if (!is_object($options['empty_value']) || !$options['empty_value'] instanceof \Exception) {
352+
if ($that::DEPRECATED_EMPTY_VALUE !== $options['empty_value']) {
348353
@trigger_error(sprintf('The form option "empty_value" of the "%s" form type (%s) is deprecated since version 2.6 and will be removed in 3.0. Use "placeholder" instead.', $that->getName(), __CLASS__), E_USER_DEPRECATED);
349354

350355
if (null === $placeholder || '' === $placeholder) {
@@ -396,7 +401,7 @@ public function configureOptions(OptionsResolver $resolver)
396401
'preferred_choices' => array(),
397402
'group_by' => null,
398403
'empty_data' => $emptyData,
399-
'empty_value' => new \Exception(), // deprecated
404+
'empty_value' => self::DEPRECATED_EMPTY_VALUE,
400405
'placeholder' => $placeholder,
401406
'error_bubbling' => false,
402407
'compound' => $compound,

src/Symfony/Component/Form/Extension/Core/Type/DateType.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ public function configureOptions(OptionsResolver $resolver)
191191
};
192192

193193
$placeholderNormalizer = function (Options $options, $placeholder) use ($placeholderDefault) {
194-
if (!is_object($options['empty_value']) || !$options['empty_value'] instanceof \Exception) {
194+
if (ChoiceType::DEPRECATED_EMPTY_VALUE !== $options['empty_value']) {
195195
@trigger_error('The form option "empty_value" is deprecated since version 2.6 and will be removed in 3.0. Use "placeholder" instead.', E_USER_DEPRECATED);
196196

197197
$placeholder = $options['empty_value'];
@@ -243,7 +243,7 @@ public function configureOptions(OptionsResolver $resolver)
243243
'format' => $format,
244244
'model_timezone' => null,
245245
'view_timezone' => null,
246-
'empty_value' => new \Exception(), // deprecated
246+
'empty_value' => ChoiceType::DEPRECATED_EMPTY_VALUE,
247247
'placeholder' => $placeholder,
248248
'html5' => true,
249249
// Don't modify \DateTime classes by reference, we treat

0 commit comments

Comments
 (0)