8000 Merge branch '4.0' · symfony/symfony@19b03b5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 19b03b5

Browse files
Merge branch '4.0'
* 4.0: [DI] Fix missing unset leading to false-positive circular ref [DI] Fix deep-inlining of non-shared refs parse newlines in quoted multiline strings Fix collision between view properties and form fields Fix collision between view properties and form fields [SecurityBundle] Fix compat with HttpFoundation >=3.4 [DI] turn $private to protected in dumped container, to make cache:clear BC Fix collision between view properties and form fields
2 parents e566998 + 8849fb9 commit 19b03b5

36 files changed

+279
-42
lines changed

src/Symfony/Bridge/Twig/Extension/FormExtension.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Bridge\Twig\TokenParser\FormThemeTokenParser;
1515
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
16+
use Symfony\Component\Form\FormView;
1617
use Twig\Extension\AbstractExtension;
1718
use Twig\TwigFilter;
1819
use Twig\TwigFunction;
@@ -72,9 +73,15 @@ public function getTests()
7273
{
7374
return array(
7475
new TwigTest('selectedchoice', 'Symfony\Bridge\Twig\Extension\twig_is_selected_choice'),
76+
new TwigTest('rootform', array($this, 'isRootForm')),
7577
);
7678
}
7779

80+
public function isRootForm(FormView $formView)
81+
{
82+
return null === $formView->parent;
83+
}
84+
7885
/**
7986
* {@inheritdoc}
8087
*/

src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,12 @@
140140

141141
{% block form_errors -%}
142142
{% if errors|length > 0 -%}
143-
{% if form.parent %}<span class="help-block">{% else %}<div class="alert alert-danger">{% endif %}
143+
{% if form is not rootform %}<span class="help-block">{% else %}<div class="alert alert-danger">{% endif %}
144144
<ul class="list-unstyled">
145145
{%- for error in errors -%}
146146
<li><span class="glyphicon glyphicon-exclamation-sign"></span> {{ error.message }}</li>
147147
{%- endfor -%}
148148
</ul>
149-
{% if form.parent %}</span>{% else %}</div>{% endif %}
149+
{% if form is not rootform %}</span>{% else %}</div>{% endif %}
150150
{%- endif %}
151151
{%- endblock form_errors %}

src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@
173173

174174
{% block form_errors -%}
175175
{%- if errors|length > 0 -%}
176-
<div class="{% if form.parent %}invalid-feedback{% else %}alert alert-danger{% endif %}">
176+
<div class="{% if form is not rootform %}invalid-feedback{% else %}alert alert-danger{% endif %}">
177177
<ul class="list-unstyled mb-0">
178178
{%- for error in errors -%}
179179
<li>{{ error.message }}</li>

src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
{%- block form_widget_compound -%}
1717
<div {{ block('widget_container_attributes') }}>
18-
{%- if form.parent is empty -%}
18+
{%- if form is rootform -%}
1919
{{ form_errors(form) }}
2020
{%- endif -%}
2121
{{- block('form_rows') -}}
@@ -349,7 +349,7 @@
349349
{% endif %}
350350
{%- endfor %}
351351

352-
{% if not form.methodRendered and form.parent is null %}
352+
{% if not form.methodRendered and form is rootform %}
353353
{%- do form.setMethodRendered() -%}
354354
{% set method = method|upper %}
355355
{%- if method in ["GET", "POST"] -%}

src/Symfony/Bridge/Twig/Resources/views/Form/form_table_layout.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
{%- block form_widget_compound -%}
3333
<table {{ block('widget_container_attributes') }}>
34-
{%- if form.parent is empty and errors|length > 0 -%}
34+
{%- if form is rootform and errors|length > 0 -%}
3535
<tr>
3636
<td colspan="2">
3737
{{- form_errors(form) -}}

src/Symfony/Bridge/Twig/Resources/views/Form/foundation_5_layout.html.twig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,11 +318,11 @@
318318

319319
{% block form_errors -%}
320320
{% if errors|length > 0 -%}
321-
{% if form.parent %}<small class="error">{% else %}<div data-alert class="alert-box alert">{% endif %}
321+
{% if form is not rootform %}<small class="error">{% else %}<div data-alert class="alert-box alert">{% endif %}
322322
{%- for error in errors -%}
323323
{{ error.message }}
324324
{% if not loop.last %}, {% endif %}
325325
{%- endfor -%}
326-
{% if form.parent %}</small>{% else %}</div>{% endif %}
326+
{% if form is not rootform %}</small>{% else %}</div>{% endif %}
327327
{%- endif %}
328328
{%- endblock form_errors %}

src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionDivLayoutTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,23 @@ public function testStartTagHasActionAttributeWhenActionIsZero()
149149
$this->assertSame('<form name="form" method="get" action="0">', $html);
150150
}
151151

152+
public function isRootFormProvider()
153+
{
154+
return array(
155+
array(true, new FormView()),
156+
array(false, new FormView(new FormView())),
157+
);
158+
}
159+
160+
/**
161+
* @dataProvider isRootFormProvider
162+
*/
163+
public function testIsRootForm($expected, FormView $formView)
164+
{
165+
$extension = new FormExtension();
166+
$this->assertSame($expected, $extension->isRootForm($formView));
167+
}
168+
152169
protected function renderForm(FormView $view, array $vars = array())
153170
{
154171
return (string) $this->renderer->renderBlock($view, 'form', $vars);

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

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
1515
use Symfony\Component\DependencyInjection\Definition;
16+
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
1617
use Symfony\Component\DependencyInjection\Reference;
1718

1819
/**
@@ -23,6 +24,7 @@
2324
class InlineServiceDefinitionsPass extends AbstractRecursivePass implements RepeatablePassInterface
2425
{
2526
private $repeatedPass;
27+
private $cloningIds = array();
2628

2729
/**
2830
* {@inheritdoc}
@@ -41,17 +43,43 @@ protected function processValue($value, $isRoot = false)
4143
// Reference found in ArgumentInterface::getValues() are not inlineable
4244
return $value;
4345
}
44-
if ($value instanceof Reference && $this->container->hasDefinition($id = (string) $value)) {
45-
$definition = $this->container->getDefinition($id);
4646

47-
if ($this->isInlineableDefinition($id, $definition, $this->container->getCompiler()->getServiceReferenceGraph())) {
48-
$this->container->log($this, sprintf('Inlined service "%s" to "%s".', $id, $this->currentId));
49-
50-
return $definition->isShared() ? $definition : clone $definition;
47+
if ($value instanceof Definition && $this->cloningIds) {
48+
if ($value->isShared()) {
49+
return $value;
5150
}
51+
$value = clone $value;
52+
}
53+
54+
if (!$value instanceof Reference || !$this->container->hasDefinition($id = (string) $value)) {
55+
return parent::processValue($value, $isRoot);
56+
}
57+
58+
$definition = $this->container->getDefinition($id);
59+
60+
if (!$this->isInlineableDefinition($id, $definition, $this->container->getCompiler()->getServiceReferenceGraph())) {
61+
return $value;
5262
}
5363

54-
return parent::processValue($value, $isRoot);
64+
$this->container->log($this, sprintf('Inlined service "%s" to "%s".', $id, $this->currentId));
65+
66+
if ($definition->isShared()) {
67+
return $definition;
68+
}
69+
70+
if (isset($this->cloningIds[$id])) {
71+
$ids = array_keys($this->cloningIds);
72+
$ids[] = $id;
73+
74+
throw new ServiceCircularReferenceException($id, array_slice($ids, array_search($id, $ids)));
75+
}
76+
77+
$this->cloningIds[$id] = true;
78+
try {
79+
return $this->processValue($definition);
80+
} finally {
81+
unset($this->cloningIds[$id]);
82+
}
5583
}
5684

5785
/**

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,11 @@ class $class extends $baseClass
878878
{
879879
private \$parameters;
880880
private \$targetDirs = array();
881-
private \$privates = array();
881+
882+
/*{$this->docStar}
883+
* @internal but protected for BC on cache:clear
884+
*/
885+
protected \$privates = array();
882886
883887
public function __construct()
884888
{
@@ -1062,7 +1066,7 @@ private function addAliases(): string
10621066
return $code." );\n";
10631067
}
10641068

1065-
private function addInlineRequires() :string
1069+
private function addInlineRequires(): string
10661070
{
10671071
if (!$this->hotPathTag || !$this->inlineRequires) {
10681072
return '';

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,60 @@ public function testProcessInlinesMixedServicesLoop()
111111
$this->assertEquals($container->getDefinition('foo')->getArgument(0), $container->getDefinition('bar'));
112112
}
113113

114+
/**
115+
* @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
116+
* @expectedExceptionMessage Circular reference detected for service "bar", path: "bar -> foo -> bar".
117+
*/
118+
public function testProcessThrowsOnNonSharedLoops()
119+
{
120+
$container = new ContainerBuilder();
121+
$container
122+
->register('foo')
123+
->addArgument(new Reference('bar'))
124+
->setShared(false)
125+
;
126+
$container
127+
->register('bar')
128+
->setShared(false)
129+
->addMethodCall('setFoo', array(new Reference('foo')))
130+
;
131+
132+
$this->process($container);
133+
}
134+
135+
public function testProcessNestedNonSharedServices()
136+
{
137+
$container = new ContainerBuilder();
138+
$container
139+
->register('foo')
140+
->addArgument(new Reference('bar1'))
141+
->addArgument(new Reference('bar2'))
142+
;
143+
$container
144+
->register('bar1')
145+
->setShared(false)
146+
->addArgument(new Reference('baz'))
147+
;
148+
$container
149+
->register('bar2')
150+
->setShared(false)
151+
->addArgument(new Reference('baz'))
152+
;
153+
$container
154+
->register('baz')
155+
->setShared(false)
156+
;
157+
158+
$this->process($container);
159+
160+
$baz1 = $container->getDefinition('foo')->getArgument(0)->getArgument(0);
161+
$baz2 = $container->getDefinition('foo')->getArgument(1)->getArgument(0);
162+
163+
$this->assertEquals($container->getDefinition('baz'), $baz1);
164+
$this->assertEquals($container->getDefinition('baz'), $baz2);
165+
$this->assertNotSame($baz1, $baz2);
166+
}
167+
114168
public function testProcessInlinesIfMultipleReferencesButAllFromTheSameDefinition()
115169
{
116170
$container = new ContainerBuilder();

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ class Container extends \Symfony\Component\DependencyInjection\Dump\AbstractCont
2020
{
2121
private $parameters;
2222
private $targetDirs = array();
23-
private $privates = array();
23+
24+
/**
25+
* @internal but protected for BC on cache:clear
26+
*/
27+
protected $privates = array();
2428

2529
public function __construct()
2630
{

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ class ProjectServiceContainer extends Container
1818
{
1919
private $parameters;
2020
private $targetDirs = array();
21-
private $privates = array();
21+
22+
/**
23+
* @internal but protected for BC on cache:clear
24+
*/
25+
protected $privates 4E34 = array();
2226

2327
public function __construct()
2428
{

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services10.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ class ProjectServiceContainer extends Container
1818
{
1919
private $parameters;
2020
private $targetDirs = array();
21-
private $privates = array();
21+
22+
/**
23+
* @internal but protected for BC on cache:clear
24+
*/
25+
protected $privates = array();
2226

2327
public function __construct()
2428
{

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ class ProjectServiceContainer extends Container
1818
{
1919
private $parameters;
2020
private $targetDirs = array();
21-
private $privates = array();
21+
22+
/**
23+
* @internal but protected for BC on cache:clear
24+
*/
25+
protected $privates = array();
2226

2327
public function __construct()
2428
{

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services13.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ class ProjectServiceContainer extends Container
1818
{
1919
private $parameters;
2020
private $targetDirs = array();
21-
private $privates = array();
21+
22+
/**
23+
* @internal but protected for BC on cache:clear
24+
*/
25+
protected $privates = array();
2226

2327
public function __construct()
2428
{

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services19.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ class ProjectServiceContainer extends Container
1818
{
1919
private $parameters;
2020
private $targetDirs = array();
21-
private $privates = array();
21+
22+
/**
23+
* @internal but protected for BC on cache:clear
24+
*/
25+
protected $privates = array();
2226

2327
public function __construct()
2428
{

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services24.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ class ProjectServiceContainer extends Container
1818
{
1919
private $parameters;
2020
private $targetDirs = array();
21-
private $privates = array();
21+
22+
/**
23+
* @internal but protected for BC on cache:clear
24+
*/
25+
protected $privates = array();
2226

2327
public function __construct()
2428
{

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services26.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ class Symfony_DI_PhpDumper_Test_EnvParameters extends Container
1818
{
1919
private $parameters;
2020
private $targetDirs = array();
21-
private $privates = array();
21+
22+
/**
23+
* @internal but protected for BC on cache:clear
24+
*/
25+
protected $privates = array();
2226

2327
public function __construct()
2428
{

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services33.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ class ProjectServiceContainer extends Container
1818
{
1919
private $parameters;
2020
private $targetDirs = array();
21-
private $privates = array();
21+
22+
/**
23+
* @internal but protected for BC on cache:clear
24+
*/
25+
protected $privates = array();
2226

2327
public function __construct()
2428
{

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ class ProjectServiceContainer extends Container
1818
{
1919
private $parameters;
2020
private $targetDirs = array();
21-
private $privates = array();
21+
22+
/**
23+
* @internal but protected for BC on cache:clear
24+
*/
25+
protected $privates = array();
2226

2327
public function __construct()
2428
{

0 commit comments

Comments
 (0)
0