Skip to content

Commit 457967c

Browse files
committed
Merge branch '2.3' into 2.7
* 2.3: [DependencyInjection] fix dumped YAML snytax Remove InputOption::VALUE_REQUIRED mode from $default parameter description as InputOption::setDefault() throws an exception only when called in InputOption::VALUE_NONE mode. In practice the $default value could still be accessed in InputOption::VALUE_REQUIRED mode in case InputOption was never set but accessed from InputDefinition::getOption() method [Form] Fixed violation mapping if multiple forms are using the same (or part of the same) property path [TwigBridge] Symfony 3.1 forward compatibility
2 parents 52343b0 + 3f749d6 commit 457967c

File tree

11 files changed

+63
-53
lines changed

11 files changed

+63
-53
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Bridge\Twig\Extension;
1313

1414
use Symfony\Component\Yaml\Dumper as YamlDumper;
15+
use Symfony\Component\Yaml\Yaml;
1516

1617
/**
1718
* Provides integration of the Yaml component with Twig.
@@ -40,7 +41,7 @@ public function encode($input, $inline = 0, $dumpObjects = false)
4041
}
4142

4243
if (defined('Symfony\Component\Yaml\Yaml::DUMP_OBJECT')) {
43-
$dumpObjects = (int) $dumpObjects;
44+
return $dumper->dump($input, $inline, 0, is_bool($dumpObjects) ? Yaml::DUMP_OBJECT : 0);
4445
}
4546

4647
return $dumper->dump($input, $inline, 0, false, $dumpObjects);

src/Symfony/Component/Console/Command/Command.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ public function addArgument($name, $mode = null, $description = '', $default = n
380380
* @param string $shortcut The shortcut (can be null)
381381
* @param int $mode The option mode: One of the InputOption::VALUE_* constants
382382
* @param string $description A description text
383-
* @param mixed $default The default value (must be null for InputOption::VALUE_REQUIRED or InputOption::VALUE_NONE)
383+
* @param mixed $default The default value (must be null for InputOption::VALUE_NONE)
384384
*
385385
* @return Command The current instance
386386
*/

src/Symfony/Component/Console/Input/InputOption.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class InputOption
3636
* @param string|array $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
3737
* @param int $mode The option mode: One of the VALUE_* constants
3838
* @param string $description A description text
39-
* @param mixed $default The default value (must be null for self::VALUE_REQUIRED or self::VALUE_NONE)
39+
* @param mixed $default The default value (must be null for self::VALUE_NONE)
4040
*
4141
* @throws \InvalidArgumentException If option mode is invalid or incompatible
4242
*/

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ private function addService($id, $definition)
6565
$class = substr($class, 1);
6666
}
6767

68-
$code .= sprintf(" class: %s\n", $class);
68+
$code .= sprintf(" class: %s\n", $this->dumper->dump($class));
6969
}
7070

7171
if (!$definition->isPublic()) {
@@ -101,7 +101,7 @@ private function addService($id, $definition)
101101
}
102102

103103
if ($definition->getFactoryClass(false)) {
104-
$code .= sprintf(" factory_class: %s\n", $definition->getFactoryClass(false));
104+
$code .= sprintf(" factory_class: %s\n", $this->dumper->dump($definition->getFactoryClass(false)));
105105
}
106106

107107
if ($definition->isLazy()) {

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

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

1414
use Symfony\Component\DependencyInjection\ContainerBuilder;
1515
use Symfony\Component\DependencyInjection\Dumper\YamlDumper;
16+
use Symfony\Component\Yaml\Yaml;
1617

1718
class YamlDumperTest extends \PHPUnit_Framework_TestCase
1819
{
@@ -27,17 +28,14 @@ public function testDump()
2728
{
2829
$dumper = new YamlDumper($container = new ContainerBuilder());
2930

30-
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services1.yml', $dumper->dump(), '->dump() dumps an empty container as an empty YAML file');
31-
32-
$container = new ContainerBuilder();
33-
$dumper = new YamlDumper($container);
31+
$this->assertEqualYamlStructure(self::$fixturesPath.'/yaml/services1.yml', $dumper->dump(), '->dump() dumps an empty container as an empty YAML file');
3432
}
3533

3634
public function testAddParameters()
3735
{
3836
$container = include self::$fixturesPath.'/containers/container8.php';
3937
$dumper = new YamlDumper($container);
40-
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services8.yml', $dumper->dump(), '->dump() dumps parameters');
38+
$this->assertEqualYamlStructure(self::$fixturesPath.'/yaml/services8.yml', $dumper->dump(), '->dump() dumps parameters');
4139
}
4240

4341
/**
@@ -65,7 +63,7 @@ public function testAddService()
6563
{
6664
$container = include self::$fixturesPath.'/containers/container9.php';
6765
$dumper = new YamlDumper($container);
68-
$this->assertEquals(str_replace('%path%', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR, file_get_contents(self::$fixturesPath.'/yaml/services9.yml')), $dumper->dump(), '->dump() dumps services');
66+
$this->assertEqualYamlStructure(str_replace('%path%', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR, file_get_contents(self::$fixturesPath.'/yaml/services9.yml')), $dumper->dump(), '->dump() dumps services');
6967

7068
$dumper = new YamlDumper($container = new ContainerBuilder());
7169
$container->register('foo', 'FooClass')->addArgument(new \stdClass());
@@ -77,4 +75,9 @@ public function testAddService()
7775
$this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
7876
}
7977
}
78+
79+
private function assertEqualYamlStructure($yaml, $expected, $message = '')
80+
{
81+
$this->assertEquals(Yaml::parse($expected), Yaml::parse($yaml), $message);
82+
}
8083
}

src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/legacy-services9.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ services:
1818

1919
configurator: sc_configure
2020
foo.baz:
21-
class: %baz_class%
22-
factory_class: %baz_class%
21+
class: '%baz_class%'
22+
factory_class: '%baz_class%'
2323
factory_method: getInstance
2424
configurator: ['%baz_class%', configureStatic1]
2525
factory_service:

src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services10.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ services:
66
class: BAR
77

88
project:
9-
test: %project.parameter.foo%
9+
test: '%project.parameter.foo%'

src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ services:
44
scope.container: { class: FooClass, scope: container }
55
scope.custom: { class: FooClass, scope: custom }
66
scope.prototype: { class: FooClass, scope: prototype }
7-
file: { class: FooClass, file: %path%/foo.php }
7+
file: { class: FooClass, file: '%path%/foo.php' }
88
arguments: { class: FooClass, arguments: [foo, '@foo', [true, false]] }
99
configurator1: { class: FooClass, configurator: sc_configure }
1010
configurator2: { class: FooClass, configurator: ['@baz', configure] }

src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,19 @@ services:
1818
factory: [Bar\FooClass, getInstance]
1919
configurator: sc_configure
2020
foo.baz:
21-
class: %baz_class%
21+
class: '%baz_class%'
2222
factory: ['%baz_class%', getInstance]
2323
configurator: ['%baz_class%', configureStatic1]
2424
bar:
2525
class: Bar\FooClass
2626
arguments: [foo, '@foo.baz', '%foo_bar%']
2727
configurator: ['@foo.baz', configure]
2828
foo_bar:
29-
class: %foo_class%
29+
class: '%foo_class%'
3030
scope: prototype
3131
method_call1:
3232
class: Bar\FooClass
33-
file: %path%foo.php
33+
file: '%path%foo.php'
3434
calls:
3535
- [setBar, ['@foo']]
3636
- [setBar, ['@?foo2']]

src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,9 @@ public function mapViolation(ConstraintViolation $violation, FormInterface $form
148148
*/
149149
private function matchChild(FormInterface $form, PropertyPathIteratorInterface $it)
150150
{
151-
// Remember at what property path underneath "data"
152-
// we are looking. Check if there is a child with that
153-
// path, otherwise increase path by one more piece
151+
$target = null;
154152
$chunk = '';
155-
$foundChild = null;
156-
$foundAtIndex = 0;
153+
$foundAtIndex = null;
157154

158155
// Construct mapping rules for the given form
159156
$rules = array();
@@ -165,17 +162,11 @@ private function matchChild(FormInterface $form, PropertyPathIteratorInterface $
165162
}
166163
}
167164

168-
// Skip forms inheriting their parent data when iterating the children
169-
$childIterator = new \RecursiveIteratorIterator(
165+
$children = iterator_to_array(new \RecursiveIteratorIterator(
170166
new InheritDataAwareIterator($form)
171-
);
172-
173-
// Make the path longer until we find a matching child
174-
while (true) {
175-
if (!$it->valid()) {
176-
return;
177-
}
167+
));
178168

169+
while ($it->valid()) {
179170
if ($it->isIndex()) {
180171
$chunk .= '['.$it->current().']';
181172
} else {
@@ -197,33 +188,27 @@ private function matchChild(FormInterface $form, PropertyPathIteratorInterface $
197188
}
198189
}
199190

200-
// Test children unless we already found one
201-
if (null === $foundChild) {
202-
foreach ($childIterator as $child) {
203-
/* @var FormInterface $child */
204-
$childPath = (string) $child->getPropertyPath();
205-
206-
// Child found, mark as return value
207-
if ($chunk === $childPath) {
208-
$foundChild = $child;
209-
$foundAtIndex = $it->key();
210-
}
191+
/** @var FormInterface $child */
192+
foreach ($children as $key => $child) {
193+
$childPath = (string) $child->getPropertyPath();
194+
if ($childPath === $chunk) {
195+
$target = $child;
196+
$foundAtIndex = $it->key();
197+
} elseif (0 === strpos($childPath, $chunk)) {
198+
continue;
211199
}
200+
201+
unset($children[$key]);
212202
}
213203

214-
// Add element to the chunk
215204
$it->next();
205+
}
216206

217-
// If we reached the end of the path or if there are no
218-
// more matching mapping rules, return the found child
219-
if (null !== $foundChild && (!$it->valid() || count($rules) === 0)) {
220-
// Reset index in case we tried to find mapping
221-
// rules further down the path
222-
$it->seek($foundAtIndex);
223-
224-
return $foundChild;
225-
}
207+
if (null !== $foundAtIndex) {
208+
$it->seek($foundAtIndex);
226209
}
210+
211+
return $target;
227212
}
228213

229214
/**

0 commit comments

Comments
 (0)