diff --git a/UPGRADE-3.4.md b/UPGRADE-3.4.md index 503e74922c..68b21db3e2 100644 --- a/UPGRADE-3.4.md +++ b/UPGRADE-3.4.md @@ -30,13 +30,13 @@ FrameworkBundle require symfony/stopwatch` in your `dev` environment. * Using the `KERNEL_DIR` environment variable or the automatic guessing based - on the `phpunit.xml` / `phpunit.xml.dist` file location is deprecated since 3.4. + on the `phpunit.xml` / `phpunit.xml.dist` file location is deprecated since 3.4. Set the `KERNEL_CLASS` environment variable to the fully-qualified class name - of your Kernel instead. Not setting the `KERNEL_CLASS` environment variable - will throw an exception on 4.0 unless you override the `KernelTestCase::createKernel()` + of your Kernel instead. Not setting the `KERNEL_CLASS` environment variable + will throw an exception on 4.0 unless you override the `KernelTestCase::createKernel()` or `KernelTestCase::getKernelClass()` method. - - * The `KernelTestCase::getPhpUnitXmlDir()` and `KernelTestCase::getPhpUnitCliConfigArgument()` + + * The `KernelTestCase::getPhpUnitXmlDir()` and `KernelTestCase::getPhpUnitCliConfigArgument()` methods are deprecated since 3.4 and will be removed in 4.0. * The `--no-prefix` option of the `translation:update` command is deprecated and @@ -83,7 +83,7 @@ TwigBridge * deprecated the `Symfony\Bridge\Twig\Form\TwigRenderer` class, use the `FormRenderer` class from the Form component instead - * deprecated `Symfony\Bridge\Twig\Command\DebugCommand::set/getTwigEnvironment` and the ability + * deprecated `Symfony\Bridge\Twig\Command\DebugCommand::set/getTwigEnvironment` and the ability to pass a command name as first argument * deprecated `Symfony\Bridge\Twig\Command\LintCommand::set/getTwigEnvironment` and the ability @@ -95,7 +95,7 @@ TwigBundle * deprecated the `Symfony\Bundle\TwigBundle\Command\DebugCommand` class, use the `DebugCommand` class from the Twig bridge instead - * deprecated relying on the `ContainerAwareInterface` implementation for + * deprecated relying on the `ContainerAwareInterface` implementation for `Symfony\Bundle\TwigBundle\Command\LintCommand` Validator @@ -111,3 +111,30 @@ Yaml * Using the non-specific tag `!` is deprecated and will have a different behavior in 4.0. Use a plain integer or `!!float` instead. + + * Using the `Yaml::PARSE_KEYS_AS_STRINGS` flag is deprecated as it will be + removed in 4.0. + + Before: + + ```php + $yaml = <<yamlParser->parse(file_get_contents($file), Yaml::PARSE_CONSTANT | Yaml::PARSE_CUSTOM_TAGS | Yaml::PARSE_KEYS_AS_STRINGS); + $configuration = $this->yamlParser->parse(file_get_contents($file), Yaml::PARSE_CONSTANT | Yaml::PARSE_CUSTOM_TAGS); } catch (ParseException $e) { throw new InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $file), 0, $e); } diff --git a/src/Symfony/Component/Routing/Loader/YamlFileLoader.php b/src/Symfony/Component/Routing/Loader/YamlFileLoader.php index 7ae5e84d10..31314011b9 100644 --- a/src/Symfony/Component/Routing/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Routing/Loader/YamlFileLoader.php @@ -17,7 +17,6 @@ use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Yaml\Exception\ParseException; use Symfony\Component\Yaml\Parser as YamlParser; use Symfony\Component\Config\Loader\FileLoader; -use Symfony\Component\Yaml\Yaml; /** * YamlFileLoader loads Yaml routing files. @@ -59,7 +58,7 @@ class YamlFileLoader extends FileLoader } try { - $parsedConfig = $this->yamlParser->parse(file_get_contents($path), Yaml::PARSE_KEYS_AS_STRINGS); + $parsedConfig = $this->yamlParser->parse(file_get_contents($path)); } catch (ParseException $e) { throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $path), 0, $e); } diff --git a/src/Symfony/Component/Serializer/Mapping/Loader/YamlFileLoader.php b/src/Symfony/Component/Serializer/Mapping/Loader/YamlFileLoader.php index 20a1d48aad..e3afa47632 100644 --- a/src/Symfony/Component/Serializer/Mapping/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Serializer/Mapping/Loader/YamlFileLoader.php @@ -15,7 +15,6 @@ use Symfony\Component\Serializer\Exception\MappingException; use Symfony\Component\Serializer\Mapping\AttributeMetadata; use Symfony\Component\Serializer\Mapping\ClassMetadataInterface; use Symfony\Component\Yaml\Parser; -use Symfony\Component\Yaml\Yaml; /** * YAML File Loader. @@ -114,7 +113,7 @@ class YamlFileLoader extends FileLoader $this->yamlParser = new Parser(); } - $classes = $this->yamlParser->parse(file_get_contents($this->file), Yaml::PARSE_KEYS_AS_STRINGS); + $classes = $this->yamlParser->parse(file_get_contents($this->file)); if (empty($classes)) { return array(); diff --git a/src/Symfony/Component/Translation/Loader/YamlFileLoader.php b/src/Symfony/Component/Translation/Loader/YamlFileLoader.php index 5897767b6b..41e390d0e9 100644 --- a/src/Symfony/Component/Translation/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Translation/Loader/YamlFileLoader.php @@ -15,7 +15,6 @@ use Symfony\Component\Translation\Exception\InvalidResourceException; use Symfony\Component\Translation\Exception\LogicException; use Symfony\Component\Yaml\Parser as YamlParser; use Symfony\Component\Yaml\Exception\ParseException; -use Symfony\Component\Yaml\Yaml; /** * YamlFileLoader loads translations from Yaml files. @@ -40,7 +39,7 @@ class YamlFileLoader extends FileLoader } try { - $messages = $this->yamlParser->parse(file_get_contents($resource), Yaml::PARSE_KEYS_AS_STRINGS); + $messages = $this->yamlParser->parse(file_get_contents($resource)); } catch (ParseException $e) { throw new InvalidResourceException(sprintf('Error parsing YAML, invalid file "%s"', $resource), 0, $e); } diff --git a/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php index f1727d3704..ff6c65d05e 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php @@ -116,7 +116,7 @@ class YamlFileLoader extends FileLoader private function parseFile($path) { try { - $classes = $this->yamlParser->parse(file_get_contents($path), Yaml::PARSE_KEYS_AS_STRINGS | Yaml::PARSE_CONSTANT); + $classes = $this->yamlParser->parse(file_get_contents($path), Yaml::PARSE_CONSTANT); } catch (ParseException $e) { throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $path), 0, $e); } diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index 6a911e9090..ef14528a46 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -490,7 +490,7 @@ class Inline @trigger_error('Omitting the key of a mapping is deprecated and will throw a ParseException in 4.0.', E_USER_DEPRECATED); } - if (!(Yaml::PARSE_KEYS_AS_STRINGS & $flags)) { + if (!$isKeyQuoted) { $evaluatedKey = self::evaluateScalar($key, $flags, $references); if ('' !== $key && $evaluatedKey !== $key && !is_string($evaluatedKey) && !is_int($evaluatedKey)) { diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 82db443e05..8bb19fbb06 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -86,6 +86,10 @@ class Parser } } + if (Yaml::PARSE_KEYS_AS_STRINGS & $flags) { + @trigger_error('Using the Yaml::PARSE_KEYS_AS_STRINGS flag is deprecated since version 3.4 as it will be removed in 4.0. Quote your keys when they are evaluable instead.', E_USER_DEPRECATED); + } + if (false === preg_match('//u', $value)) { throw new ParseException('The YAML value does not appear to be valid UTF-8.'); } @@ -236,7 +240,7 @@ class Parser throw $e; } - if (!(Yaml::PARSE_KEYS_AS_STRINGS & $flags) && !is_string($key) && !is_int($key)) { + if (!is_string($key) && !is_int($key)) { $keyType = is_numeric($key) ? 'numeric key' : 'non-string key'; @trigger_error(sprintf('Implicit casting of %s to string is deprecated since version 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Quote your evaluable mapping keys instead.', $keyType), E_USER_DEPRECATED); } diff --git a/src/Symfony/Component/Yaml/Tests/DumperTest.php b/src/Symfony/Component/Yaml/Tests/DumperTest.php index 1c80bec650..329cfbe3a6 100644 --- a/src/Symfony/Component/Yaml/Tests/DumperTest.php +++ b/src/Symfony/Component/Yaml/Tests/DumperTest.php @@ -125,7 +125,7 @@ EOF; // TODO } else { eval('$expected = '.trim($test['php']).';'); - $this->assertSame($expected, $this->parser->parse($this->dumper->dump($expected, 10), Yaml::PARSE_KEYS_AS_STRINGS), $test['test']); + $this->assertSame($expected, $this->parser->parse($this->dumper->dump($expected, 10)), $test['test']); } } } diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index b48263f8cd..3448113021 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -385,8 +385,8 @@ class InlineTest extends TestCase array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')), // mappings - array('{foo: bar,bar: foo,false: false,null: null,integer: 12}', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_KEYS_AS_STRINGS), - array('{ foo : bar, bar : foo, false : false, null : null, integer : 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_KEYS_AS_STRINGS), + array('{foo: bar,bar: foo,"false": false, "null": null,integer: 12}', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)), + array('{ foo : bar, bar : foo, "false" : false, "null" : null, integer : 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)), array('{foo: \'bar\', bar: \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')), array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')), array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', array('foo\'' => 'bar', 'bar"' => 'foo: bar')), @@ -456,8 +456,8 @@ class InlineTest extends TestCase array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')), // mappings - array('{foo: bar,bar: foo,false: false,null: null,integer: 12}', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_OBJECT_FOR_MAP | Yaml::PARSE_KEYS_AS_STRINGS), - array('{ foo : bar, bar : foo, false : false, null : null, integer : 12 }', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_OBJECT_FOR_MAP | Yaml::PARSE_KEYS_AS_STRINGS), + array('{foo: bar,bar: foo,"false": false,"null": null,integer: 12}', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_OBJECT_FOR_MAP), + array('{ foo : bar, bar : foo, "false" : false, "null" : null, integer : 12 }', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_OBJECT_FOR_MAP), array('{foo: \'bar\', bar: \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')), array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')), array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', (object) array('foo\'' => 'bar', 'bar"' => 'foo: bar')), @@ -538,7 +538,7 @@ class InlineTest extends TestCase array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')), // mappings - array('{ foo: bar, bar: foo, \'false\': false, \'null\': null, integer: 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_KEYS_AS_STRINGS), + array('{ foo: bar, bar: foo, \'false\': false, \'null\': null, integer: 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)), array('{ foo: bar, bar: \'foo: bar\' }', array('foo' => 'bar', 'bar' => 'foo: bar')), // nested sequences and mappings @@ -554,7 +554,7 @@ class InlineTest extends TestCase array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')), - array('{ foo: { bar: { 1: 2, baz: 3 } } }', array('foo' => array('bar' => array(1 => 2, 'baz' => 3))), Yaml::PARSE_KEYS_AS_STRINGS), + array('{ foo: { bar: { 1: 2, baz: 3 } } }', array('foo' => array('bar' => array(1 => 2, 'baz' => 3)))), ); } @@ -739,11 +739,14 @@ class InlineTest extends TestCase } /** + * @group legacy + * @expectedDeprecation Using the Yaml::PARSE_KEYS_AS_STRINGS flag is deprecated since version 3.4 as it will be removed in 4.0. Quote your keys when they are evaluable instead. + * @expectedDeprecation Implicit casting of incompatible mapping keys to strings is deprecated since version 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Quote your evaluable mapping keys instead. * @dataProvider getNotPhpCompatibleMappingKeyData */ public function testExplicitStringCastingOfMappingKeys($yaml, $expected) { - $this->assertSame($expected, Inline::parse($yaml, Yaml::PARSE_KEYS_AS_STRINGS)); + $this->assertSame($expected, Yaml::parse($yaml, Yaml::PARSE_KEYS_AS_STRINGS)); } public function getNotPhpCompatibleMappingKeyData() diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index b75fd1b324..1baa79bc35 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -71,6 +71,8 @@ class ParserTest extends TestCase } /** + * @group legacy + * @expectedDeprecationMessage Using the Yaml::PARSE_KEYS_AS_STRINGS flag is deprecated since version 3.4 as it will be removed in 4.0. Quote your keys when they are evaluable * @dataProvider getNonStringMappingKeysData */ public function testNonStringMappingKeys($expected, $yaml, $comment) @@ -510,14 +512,10 @@ EOF; /** * @dataProvider getObjectForMapTests */ - public function testObjectForMap($yaml, $expected, $explicitlyParseKeysAsStrings = false) + public function testObjectForMap($yaml, $expected) { $flags = Yaml::PARSE_OBJECT_FOR_MAP; - if ($explicitlyParseKeysAsStrings) { - $flags |= Yaml::PARSE_KEYS_AS_STRINGS; - } - $this->assertEquals($expected, $this->parser->parse($yaml, $flags)); } @@ -577,18 +575,18 @@ YAML; $expected->map = new \stdClass(); $expected->map->{1} = 'one'; $expected->map->{2} = 'two'; - $tests['numeric-keys'] = array($yaml, $expected, true); + $tests['numeric-keys'] = array($yaml, $expected); $yaml = <<<'YAML' map: - 0: one - 1: two + '0': one + '1': two YAML; $expected = new \stdClass(); $expected->map = new \stdClass(); $expected->map->{0} = 'one'; $expected->map->{1} = 'two'; - $tests['zero-indexed-numeric-keys'] = array($yaml, $expected, true); + $tests['zero-indexed-numeric-keys'] = array($yaml, $expected); return $tests; } @@ -1120,37 +1118,29 @@ EOF; $this->assertEquals($expected, $this->parser->parse($yaml)); } - public function testExplicitStringCastingOfFloatKeys() + public function testExplicitStringCasting() { $yaml = <<<'EOF' -foo: - 1.2: "bar" - 1.3: "baz" -EOF; - - $expected = array( - 'foo' => array( - '1.2' => 'bar', - '1.3' => 'baz', - ), - ); - - $this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_KEYS_AS_STRINGS)); - } - - public function testExplicitStringCastingOfBooleanKeys() - { - $yaml = <<<'EOF' -true: foo -false: bar +'1.2': "bar" +!!str 1.3: "baz" + +'true': foo +!!str false: bar + +!!str null: 'null' +'~': 'null' EOF; $expected = array( + '1.2' => 'bar', + '1.3' => 'baz', 'true' => 'foo', 'false' => 'bar', + 'null' => 'null', + '~' => 'null', ); - $this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_KEYS_AS_STRINGS)); + $this->assertEquals($expected, $this->parser->parse($yaml)); } /** @@ -1843,6 +1833,10 @@ YAML; $this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT)); } + /** + * @group legacy + * @expectedDeprecation Using the Yaml::PARSE_KEYS_AS_STRINGS flag is deprecated since version 3.4 as it will be removed in 4.0. Quote your keys when they are evaluable instead. + */ public function testPhpConstantTagMappingKeyWithKeysCastToStrings() { $yaml = <<