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

Skip to content

Commit 534eaed

Browse files
committed
parse merge keys with PARSE_OBJECT_FOR_MAP flag
1 parent cb2a1a3 commit 534eaed

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

src/Symfony/Component/Yaml/Parser.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,14 +249,18 @@ private function doParse($value, $flags)
249249
if ('<<' === $key) {
250250
$mergeNode = true;
251251
$allowOverwrite = true;
252-
if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
252+
if (isset($values['value'][0]) && '*' === $values['value'][0]) {
253253
$refName = substr(rtrim($values['value']), 1);
254254
if (!array_key_exists($refName, $this->refs)) {
255255
throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine);
256256
}
257257

258258
$refValue = $this->refs[$refName];
259259

260+
if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $refValue instanceof \stdClass) {
261+
$refValue = (array) $refValue;
262+
}
263+
260264
if (!is_array($refValue)) {
261265
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
262266
}
@@ -270,6 +274,10 @@ private function doParse($value, $flags)
270274
}
271275
$parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $flags);
272276

277+
if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsed instanceof \stdClass) {
278+
$parsed = (array) $parsed;
279+
}
280+
273281
if (!is_array($parsed)) {
274282
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
275283
}
@@ -279,6 +287,10 @@ private function doParse($value, $flags)
279287
// and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier
280288
// in the sequence override keys specified in later mapping nodes.
281289
foreach ($parsed as $parsedItem) {
290+
if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsedItem instanceof \stdClass) {
291+
$parsedItem = (array) $parsedItem;
292+
}
293+
282294
if (!is_array($parsedItem)) {
283295
throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem);
284296
}
@@ -902,15 +914,15 @@ private function cleanup($value)
902914

903915
// remove leading comments
904916
$trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
905-
if (1 == $count) {
917+
if (1 === $count) {
906918
// items have been removed, update the offset
907919
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
908920
$value = $trimmedValue;
909921
}
910922

911923
// remove start of the document marker (---)
912924
$trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
913-
if (1 == $count) {
925+
if (1 === $count) {
914926
// items have been removed, update the offset
915927
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
916928
$value = $trimmedValue;

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,6 +1865,43 @@ public function testPhpConstantTagMappingKeyWithKeysCastToStrings()
18651865

18661866
$this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT | Yaml::PARSE_KEYS_AS_STRINGS));
18671867
}
1868+
1869+
public function testMergeKeysWhenMappingsAreParsedAsObjects()
1870+
{
1871+
$yaml = <<<YAML
1872+
foo: &FOO
1873+
bar: 1
1874+
bar: &BAR
1875+
baz: 2
1876+
<<: *FOO
1877+
baz:
1878+
baz_foo: 3
1879+
<<:
1880+
baz_bar: 4
1881+
foobar:
1882+
bar: ~
1883+
<<: [*FOO, *BAR]
1884+
YAML;
1885+
$expected = (object) array(
1886+
'foo' => (object) array(
1887+
'bar' => 1,
1888+
),
1889+
'bar' => (object) array(
1890+
'baz' => 2,
1891+
'bar' => 1,
1892+
),
1893+
'baz' => (object) array(
1894+
'baz_foo' => 3,
1895+
'baz_bar' => 4,
1896+
),
1897+
'foobar' => (object) array(
1898+
'bar' => null,
1899+
'baz' => 2,
1900+
),
1901+
);
1902+
1903+
$this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP));
1904+
}
18681905
}
18691906

18701907
class B

0 commit comments

Comments
 (0)