8000 Merge branch '2.8' into 3.1 · symfony/symfony@73099f3 · GitHub
[go: up one dir, main page]

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 73099f3

Browse files
Merge branch '2.8' into 3.1
* 2.8: [Twig] Fix deprecations with Twig 1.29 Fixed typo Fix email address fix the docblock in regard to the role argument [VarDumper] fix tests when xdebug is enabled Fix merge [Cache] Fix dumping SplDoublyLinkedList iter mode [Console] fixed PHP7 Errors when not using Dispatcher 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 [WebProfilerBundle] Fix dump block is unfairly restrained [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 Cast result to int before adding to it
2 parents 4317a7a + 7f633d1 commit 73099f3

File tree

32 files changed

+330
-62
lines changed

32 files changed

+330
-62
lines changed

src/Symfony/Bridge/Twig/Tests/Translation/TwigExtractorTest.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@ public function getExtractData()
7272
}
7373

7474
/**
75-
* @expectedException \Twig_Error
76-
* @expectedExceptionMessageRegExp /Unclosed "block" in ".*extractor(\/|\\)syntax_error\.twig" at line 1/
75+
* @expectedException \Twig_Error
7776
* @dataProvider resourcesWithSyntaxErrorsProvider
7877
*/
7978
public function testExtractSyntaxError($resources)
@@ -82,7 +81,19 @@ public function testExtractSyntaxError($resources)
8281
$twig->addExtension(new TranslationExtension($this->getMock('Symfony\Component\Translation\TranslatorInterface')));
8382

8483
$extractor = new TwigExtractor($twig);
85-
$extractor->extract($resources, new MessageCatalogue('en'));
84+
85+
try {
86+
$extractor->extract($resources, new MessageCatalogue('en'));
87+
} catch (\Twig_Error $e) {
88+
if (method_exists($e, 'getSourceContext')) {
89+
$this->assertSame(dirname(__DIR__).strtr('/Fixtures/extractor/syntax_error.twig', '/', DIRECTORY_SEPARATOR), $e->getFile());
90+
$this->assertSame(1, $e->getLine());
91+
$this->assertSame('Unclosed "block".', $e->getMessage());
92+
} else {
93+
$this->expectExceptionMessageRegExp('/Unclosed "block" in ".*extractor(\\/|\\\\)syntax_error\\.twig" at line 1/');
94+
}
95+
throw $e;
96+
}
8697
}
8798

8899
/**

src/Symfony/Bridge/Twig/Translation/TwigExtractor.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,14 @@ public function extract($resource, MessageCatalogue $catalogue)
6161
try {
6262
$this->extractTemplate(file_get_contents($file->getPathname()), $catalogue);
6363
} catch (\Twig_Error $e) {
64-
if ($file instanceof SplFileInfo) {
65-
$e->setTemplateName($file->getRelativePathname());
66-
} elseif ($file instanceof \SplFileInfo) {
67-
$e->setTemplateName($file->getRealPath() ?: $file->getPathname());
64+
if ($file instanceof \SplFileInfo) {
65+
$path = $file->getRealPath() ?: $file->getPathname();
66+
$name = $file instanceof SplFileInfo ? $file->getRelativePathname() : $path;
67+
if (method_exists($e, 'setSourceContext')) {
68+
$e->setSourceContext(new \Twig_Source('', $name, $path));
69+
} else {
70+
$e->setTemplateName($name);
71+
}
6872
}
6973

7074
throw $e;

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;
@@ -69,7 +70,7 @@ public function process(ContainerBuilder $container)
6970
$loader->addTag('twig.loader');
7071
$loader->setMethodCalls($container->getDefinition('twig.loader.filesystem')->getMethodCalls());
7172

72-
$container->setDefinition('twig.loader.filesystem', $loader);
73+
$container->setAlias('twig.loader.filesystem', new Alias('twig.loader.native_filesystem', false));
7374
}
7475

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

src/Symfony/Bundle/TwigBundle/TwigEngine.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@ public function render($name, array $parameters = array())
5252
if ($name instanceof TemplateReference) {
5353
try {
5454
// try to get the real name of the template where the error occurred
55-
$e->setTemplateName(sprintf('%s', $this->locator->locate($this->parser->parse($e->getTemplateName()))));
55+ $name = $e->getTemplateName();
56+
$path = (string) $this->locator->locate($this->parser->parse($name));
57+
if (method_exists($e, 'setSourceContext')) {
58+
$e->setSourceContext(new \Twig_Source('', $name, $path));
59+
} else {
60+
$e->setTemplateName($path);
61+
}
5662
} catch (\Exception $e2) {
5763
}
5864
}

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.css.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
padding-bottom: 2px;
1010
}
1111
.sf-reset .traces li {
12-
ccolor: #222;
12+
color: #222;
1313
font-size: 14px;
1414
padding: 5px 0;
1515
list-style-type: decimal;

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,11 @@
113113
<ul id="menu-profiler">
114114
{% for name, template in templates %}
115115
{% set menu -%}
116-
{% with { collector: profile.getcollector(name), profiler_markup_version: profiler_markup_version } %}
117-
{{- block('menu', template) -}}
118-
{% endwith %}
116+
{% if block('menu', template) is defined %}
117+
{% with { collector: profile.getcollector(name), profiler_markup_version: profiler_markup_version } %}
118+
{{- block('menu', template) -}}
119+
{% endwith %}
120+
{% endif %}
119121
{%- endset %}
120122
{% if menu is not empty %}
121123
<li class="{{ name }} {{ name == panel ? 'selected' : '' }}">

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,11 +366,13 @@
366366
border-color: #777;
367367
border-radius: 0;
368368
margin: 6px 0 12px 0;
369-
width: 200px;
370369
}
371370
.sf-toolbar-block-dump pre.sf-dump:last-child {
372371
margin-bottom: 0;
373372
}
373+
.sf-toolbar-block-dump .sf-toolbar-info-piece {
374+
display: block;
375+
}
374376
.sf-toolbar-block-dump .sf-toolbar-info-piece .sf-toolbar-file-line {
375377
color: #AAA;
376378
margin-left: 4px;

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,17 @@
2626

2727
<div id="sfToolbarMainContent-{{ token }}" class="sf-toolbarreset clear-fix" data-no-turbolink>
2828
{% for name, template in templates %}
29-
{% with {
30-
collector: profile.getcollector(name),
31-
profiler_url: profiler_url,
32-
token: profile.token,
33-
name: name,
34-
profiler_markup_version: profiler_markup_version
35-
} %}
36-
{{ block('toolbar', template) }}
37-
{% endwith %}
29+
{% if block('toolbar', template) is defined %}
30+
{% with {
31+
collector: profile.getcollector(name),
32+
profiler_url: profiler_url,
33+
token: profile.token,
34+
name: name,
35+
profiler_markup_version: profiler_markup_version
36+
} %}
37+
{{ block('toolbar', template) }}
38+
{% endwith %}
39+
{% endif %}
3840
{% endfor %}
3941

4042
{% if 'normal' != position %}

src/Symfony/Component/Console/Application.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,13 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI
817817
}
818818

819819
if (null === $this->dispatcher) {
820-
return $command->run($input, $output);
820+
try {
821+
return $command->run($input, $output);
822+
} catch (\Exception $e) {
823+
throw $e;
824+
} catch (\Throwable $e) {
825+
throw new FatalThrowableError($e);
826+
}
821827
}
822828

823829
// bind before the console.command event, so the listeners have access to input options/arguments

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);

src/Symfony/Component/Console/Tests/ApplicationTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,24 @@ public function testRunDispatchesAllEventsWithException()
952952
$this->assertContains('before.foo.caught.after.', $tester->getDisplay());
953953
}
954954

955+
public function testRunWithError()
956+
{
957+
$this->setExpectedException('Exception', 'dymerr');
958+
959+
$application = new Application();
960+
$application->setAutoExit(false);
961+
$application->setCatchExceptions(false);
962+
963+
$application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) {
964+
$output->write('dym.');
965+
966+
throw new \Error('dymerr');
967+
});
968+
969+
$tester = new ApplicationTester($application);
970+
$tester->run(array('command' => 'dym'));
971+
}
972+
955973
/**
956974
* @expectedException \LogicException
957975
* @expectedExceptionMessage caught
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
@@ -1201,6 +1201,13 @@ private function hasReference($id, array $arguments, $deep = false, array &$visi
12011201
$visited[$argumentId] = true;
12021202

12031203
$service = $this->container->getDefinition($argumentId);
1204+
1205+
// if the proxy manager is enabled, disable searching for references in lazy services,
1206+
// as these services will be instantiated lazily and don't have direct related references.
1207+
if ($service->isLazy() && !$this->getProxyDumper() instanceof NullDumper) {
1208+
continue;
1209+
}
1210+
12041211
$arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties());
12051212

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

src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -346,21 +346,22 @@ private function getArgumentsAsPhp(\DOMElement $node, $name, $lowercase = true)
346346
$arg->setAttribute('key', $arg->getAttribute('name'));
347347
}
348348

349-
if (!$arg->hasAttribute('key')) {
350-
$key = !$arguments ? 0 : max(array_keys($arguments)) + 1;
351-
} else {
352-
$key = $arg->getAttribute('key');
353-
}
354-
355-
// parameter keys are case insensitive
356-
if ('parameter' == $name && $lowercase) {
357-
$key = strtolower( 10000 $key);
358-
}
359-
360349
// this is used by DefinitionDecorator to overwrite a specific
361350
// argument of the parent definition
362351
if ($arg->hasAttribute('index')) {
363352
$key = 'index_'.$arg->getAttribute('index');
353+
} elseif (!$arg->hasAttribute('key')) {
354+
// Append an empty argument, then fetch its key to overwrite it later
355+
$arguments[] = null;
356+
$keys = array_keys($arguments);
357+
$key = array_pop($keys);
358+
} else {
359+
$key = $arg->getAttribute('key');
360+
361+
// parameter keys are case insensitive
362+
if ('parameter' == $name && $lowercase) {
363+
$key = strtolower($key);
364+
}
364365
}
365366

366367
switch ($arg->getAttribute('type')) {

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;
@@ -314,4 +317,52 @@ public function testInitializePropertiesBeforeMethodCalls()
314317
$container = new \Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls();
315318
$this->assertTrue($container->get('bar')->callPassed(), '->dump() initializes properties before method calls');
316319
}
320+
321+
public function testCircularReferenceAllowanceForLazyServices()
322+
{
323+
$container = new ContainerBuilder();
324+
$container->register('foo', 'stdClass')->addArgument(new Reference('bar'));
325+
$container->register('bar', 'stdClass')->setLazy(true)->addArgument(new Reference('foo'));
326+
$container->compile();
327+
328+
$dumper = new PhpDumper($container);
329+
$dumper->dump();
330+
}
331+
332+
public function testCircularReferenceAllowanceForInlinedDefinitionsForLazyServices()
333+
{
334+
/*
335+
* test graph:
336+
* [connection] -> [event_manager] --> [entity_manager](lazy)
337+
* |
338+
* --(call)- addEventListener ("@lazy_service")
339+
*
340+
* [lazy_service](lazy) -> [entity_manager](lazy)
341+
*
342+
*/
343+
344+
$container = new ContainerBuilder();
345+
346+
$eventManagerDefinition = new Definition('stdClass');
347+
348+
$connectionDefinition = $container->register('connection', 'stdClass');
349+
$connectionDefinition->addArgument($eventManagerDefinition);
350+
351+
$container->register('entity_manager', 'stdClass')
352+
->setLazy(true)
353+
->addArgument(new Reference('connection'));
354+
355+
$lazyServiceDefinition = $container->register('lazy_service', 'stdClass');
356+
$lazyServiceDefinition->setLazy(true);
357+
$lazyServiceDefinition->addArgument(new Reference('entity_manager'));
358+
359+
$eventManagerDefinition->addMethodCall('addEventListener', array(new Reference('lazy_service')));
360+
361+
$container->compile();
362+
363+
$dumper = new PhpDumper($container);
364+
365+
$dumper->setProxyDumper(new DummyProxyDumper());
366+
$dumper->dump();
367+
}
317368
}

0 commit comments

Comments
 (0)
0