Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit dc3c142

Browse files
committed
introduce flags to customize the parser behavior
1 parent 80f3410 commit dc3c142

File tree

8 files changed

+207
-27
lines changed

8 files changed

+207
-27
lines changed

UPGRADE-3.1.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,21 @@ Serializer
3333
Yaml
3434
----
3535

36+
* Deprecated support for passing `true`/`false` as the third and fourth argument
37+
to the `parse()` methods to toggle object and object for map support.
38+
39+
Before:
40+
41+
```php
42+
Yaml::parse('{ "foo": "bar", "fiz": "cat" }', false, true, true);
43+
```
44+
45+
After:
46+
47+
```php
48+
Yaml::parse('{ "foo": "bar", "fiz": "cat" }', false, Yaml::PARSE_OBJECT | Yaml::PARSE_OBJECT_FOR_MAP);
49+
```
50+
3651
* Deprecated support for passing `true`/`false` as the third argument to the `dump()` methods to toggle object support.
3752

3853
Before:

UPGRADE-4.0.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,21 @@ Serializer
2424
Yaml
2525
----
2626

27+
* Removed support for passing `true`/`false` as the third and fourth argument
28+
to the `parse()` methods to toggle object and object for map support.
29+
30+
Before:
31+
32+
```php
33+
Yaml::parse('{ "foo": "bar", "fiz": "cat" }', false, true, true);
34+
```
35+
36+
After:
37+
38+
```php
39+
Yaml::parse('{ "foo": "bar", "fiz": "cat" }', false, Yaml::PARSE_OBJECT | Yaml::PARSE_OBJECT_FOR_MAP);
40+
```
41+
2742
* Removed support for passing `true`/`false` as the third argument to the `dump()` methods to toggle object support.
2843

2944
Before:

src/Symfony/Component/Yaml/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ CHANGELOG
44
3.1.0
55
-----
66

7+
* Added support for customizing the YAML parser behavior through an optional bit field:
8+
9+
```php
10+
Yaml::parse('{ "foo": "bar", "fiz": "cat" }', false, Yaml::PARSE_OBJECT | Yaml::PARSE_OBJECT_FOR_MAP);
11+
```
12+
713
* Added support for customizing the dumped YAML string through an optional bit field:
814

915
```php

src/Symfony/Component/Yaml/Inline.php

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,42 @@ class Inline
3232
*
3333
* @param string $value A YAML string
3434
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
35-
* @param bool $objectSupport true if object support is enabled, false otherwise
36-
* @param bool $objectForMap true if maps should return a stdClass instead of array()
35+
* @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
3736
* @param array $references Mapping of variable names to values
3837
*
3938
* @return array A PHP array representing the YAML string
4039
*
4140
* @throws ParseException
4241
*/
43-
public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false, $references = array())
42+
public static function parse($value, $exceptionOnInvalidType = false, $flags = 0, $references = array())
4443
{
44+
if (is_bool($flags)) {
45+
@trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT flag instead.', E_USER_DEPRECATED);
46+
47+
if ($flags) {
48+
$flags = Yaml::PARSE_OBJECT;
49+
} else {
50+
$flags = 0;
51+
}
52+
}
53+
54+
if (func_num_args() >= 4 && is_bool($references)) {
55+
@trigger_error('Passing a boolean flag to toggle object for map support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', E_USER_DEPRECATED);
56+
57+
if ($references) {
58+
$flags |= Yaml::PARSE_OBJECT_FOR_MAP;
59+
}
60+
61+
if (func_num_args() >= 5) {
62+
$references = func_get_arg(4);
63+
} else {
64+
$references = array();
65+
}
66+
}
67+
4568
self::$exceptionOnInvalidType = $exceptionOnInvalidType;
46-
self::$objectSupport = $objectSupport;
47-
self::$objectForMap = $objectForMap;
69+
self::$objectSupport = (bool) (Yaml::PARSE_OBJECT & $flags);
70+
self::$objectForMap = (bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags);
4871

4972
$value = trim($value);
5073

src/Symfony/Component/Yaml/Parser.php

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,32 @@ public function __construct($offset = 0)
4343
*
4444
* @param string $value A YAML string
4545
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
46-
* @param bool $objectSupport true if object support is enabled, false otherwise
47-
* @param bool $objectForMap true if maps should return a stdClass instead of array()
46+
* @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
4847
*
4948
* @return mixed A PHP value
5049
*
5150
* @throws ParseException If the YAML is not valid
5251
*/
53-
public function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false)
52+
public function parse($value, $exceptionOnInvalidType = false, $flags = 0)
5453
{
54+
if (is_bool($flags)) {
55+
@trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT flag instead.', E_USER_DEPRECATED);
56+
57+
if ($flags) {
58+
$flags = Yaml::PARSE_OBJECT;
59+
} else {
60+
$flags = 0;
61+
}
62+
}
63+
64+
if (func_num_args() >= 4) {
65+
@trigger_error('Passing a boolean flag to toggle object for map support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', E_USER_DEPRECATED);
66+
67+
if (func_get_arg(3)) {
68+
$flags |= Yaml::PARSE_OBJECT_FOR_MAP;
69+
}
70+
}
71+
5572
if (!preg_match('//u', $value)) {
5673
throw new ParseException('The YAML value does not appear to be valid UTF-8.');
5774
}
@@ -95,7 +112,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
95112
$c = $this->getRealCurrentLineNb() + 1;
96113
$parser = new self($c);
97114
$parser->refs = &$this->refs;
98-
$data[] = $parser->parse($this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport, $objectForMap);
115+
$data[] = $parser->parse($this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $flags);
99116
} else {
100117
if (isset($values['leadspaces'])
101118
&& preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $values['value'], $matches)
@@ -110,9 +127,9 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
110127
$block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + strlen($values['leadspaces']) + 1);
111128
}
112129

113-
$data[] = $parser->parse($block, $exceptionOnInvalidType, $objectSupport, $objectForMap);
130+
$data[] = $parser->parse($block, $exceptionOnInvalidType, $flags);
114131
} else {
115-
$data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context);
132+
$data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $flags, $context);
116133
}
117134
}
118135
if ($isRef) {
@@ -125,7 +142,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
125142
$context = 'mapping';
126143

127144
// force correct settings
128-
Inline::parse(null, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
145+
Inline::parse(null, $exceptionOnInvalidType, $flags, $this->refs);
129146
try {
130147
$key = Inline::parseScalar($values['key']);
131148
} catch (ParseException $e) {
@@ -169,7 +186,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
169186
$c = $this->getRealCurrentLineNb() + 1;
170187
$parser = new self($c);
171188
$parser->refs = &$this->refs;
172-
$parsed = $parser->parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap);
189+
$parsed = $parser->parse($value, $exceptionOnInvalidType, $flags);
173190

174191
if (!is_array($parsed)) {
175192
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
@@ -220,15 +237,15 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
220237
$c = $this->getRealCurrentLineNb() + 1;
221238
$parser = new self($c);
222239
$parser->refs = &$this->refs;
223-
$value = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport, $objectForMap);
240+
$value = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $flags);
224241
// Spec: Keys MUST be unique; first one wins.
225242
// But overwriting is allowed when a merge node is used in current block.
226243
if ($allowOverwrite || !isset($data[$key])) {
227244
$data[$key] = $value;
228245
}
229246
}
230247
} else {
231-
$value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context);
248+
$value = $this->parseValue($values['value'], $exceptionOnInvalidType, $flags, $context);
232249
// Spec: Keys MUST be unique; first one wins.
233250
// But overwriting is allowed when a merge node is used in current block.
234251
if ($allowOverwrite || !isset($data[$key])) {
@@ -247,7 +264,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
247264
// 1-liner optionally followed by newline(s)
248265
if (is_string($value) && $this->lines[0] === trim($value)) {
249266
try {
250-
$value = Inline::parse($this->lines[0], $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
267+
$value = Inline::parse($this->lines[0], $exceptionOnInvalidType, $flags, $this->refs);
251268
} catch (ParseException $e) {
252269
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
253270
$e->setSnippet($this->currentLine);
@@ -301,7 +318,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
301318
mb_internal_encoding($mbEncoding);
302319
}
303320

304-
if ($objectForMap && !is_object($data)) {
321+
if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && !is_object($data)) {
305322
$data = (object) $data;
306323
}
307324

@@ -464,15 +481,14 @@ private function moveToPreviousLine()
464481
*
465482
* @param string $value A YAML value
466483
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
467-
* @param bool $objectSupport True if object support is enabled, false otherwise
468-
* @param bool $objectForMap true if maps should return a stdClass instead of array()
484+
* @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
469485
* @param string $context The parser context (either sequence or mapping)
470486
*
471487
* @return mixed A PHP value
472488
*
473489
* @throws ParseException When reference does not exist
474490
*/
475-
private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $context)
491+
private function parseValue($value, $exceptionOnInvalidType, $flags, $context)
476492
{
477493
if (0 === strpos($value, '*')) {
478494
if (false !== $pos = strpos($value, '#')) {
@@ -495,7 +511,7 @@ private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $ob
495511
}
496512

497513
try {
498-
$parsedValue = Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
514+
$parsedValue = Inline::parse($value, $exceptionOnInvalidType, $flags, $this->refs);
499515

500516
if ('mapping' === $context && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) {
501517
throw new ParseException('A colon cannot be used in an unquoted mapping value.');

src/Symfony/Component/Yaml/Tests/InlineTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Yaml\Tests;
1313

1414
use Symfony\Component\Yaml\Inline;
15+
use Symfony\Component\Yaml\Yaml;
1516

1617
class InlineTest extends \PHPUnit_Framework_TestCase
1718
{
@@ -27,6 +28,17 @@ public function testParse($yaml, $value)
2728
* @dataProvider getTestsForParseWithMapObjects
2829
*/
2930
public function testParseWithMapObjects($yaml, $value)
31+
{
32+
$actual = Inline::parse($yaml, false, Yaml::PARSE_OBJECT_FOR_MAP);
33+
34+
$this->assertSame(serialize($value), serialize($actual));
35+
}
36+
37+
/**
38+
* @group legacy
39+
* @dataProvider getTestsForParseWithMapObjects
40+
*/
41+
public function testParseWithMapObjectsPassingTrue($yaml, $value)
3042
{
3143
$actual = Inline::parse($yaml, false, false, true);
3244

@@ -142,6 +154,15 @@ public function testParseScalarWithCorrectlyQuotedStringShouldReturnString()
142154
* @dataProvider getDataForParseReferences
143155
*/
144156
public function testParseReferences($yaml, $expected)
157+
{
158+
$this->assertSame($expected, Inline::parse($yaml, false, 0, array('var' => 'var-value')));
159+
}
160+
161+
/**
162+
* @group legacy
163+
* @dataProvider getDataForParseReferences
164+
*/
165+
public function testParseReferencesAsFifthArgument($yaml, $expected)
145166
{
146167
$this->assertSame($expected, Inline::parse($yaml, false, false, false, array('var' => 'var-value')));
147168
}
@@ -161,6 +182,19 @@ public function getDataForParseReferences()
161182
}
162183

163184
public function testParseMapReferenceInSequence()
185+
{
186+
$foo = array(
187+
'a' => 'Steve',
188+
'b' => 'Clark',
189+
'c' => 'Brian',
190+
);
191+
$this->assertSame(array($foo), Inline::parse('[*foo]', false, 0, array('foo' => $foo)));
192+
}
193+
194+
/**
195+
* @group legacy
196+
*/
197+
public function testParseMapReferenceInSequenceAsFifthArgument()
164198
{
165199
$foo = array(
166200
'a' => 'Steve',

0 commit comments

Comments
 (0)