parse merge keys with PARSE_OBJECT_FOR_MAP flag
This commit is contained in:
parent
cb2a1a3786
commit
534eaed7ae
@ -249,7 +249,7 @@ class Parser
|
||||
if ('<<' === $key) {
|
||||
$mergeNode = true;
|
||||
$allowOverwrite = true;
|
||||
if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
|
||||
if (isset($values['value'][0]) && '*' === $values['value'][0]) {
|
||||
$refName = substr(rtrim($values['value']), 1);
|
||||
if (!array_key_exists($refName, $this->refs)) {
|
||||
throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine);
|
||||
@ -257,6 +257,10 @@ class Parser
|
||||
|
||||
$refValue = $this->refs[$refName];
|
||||
|
||||
if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $refValue instanceof \stdClass) {
|
||||
$refValue = (array) $refValue;
|
||||
}
|
||||
|
||||
if (!is_array($refValue)) {
|
||||
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
|
||||
}
|
||||
@ -270,6 +274,10 @@ class Parser
|
||||
}
|
||||
$parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $flags);
|
||||
|
||||
if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsed instanceof \stdClass) {
|
||||
$parsed = (array) $parsed;
|
||||
}
|
||||
|
||||
if (!is_array($parsed)) {
|
||||
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
|
||||
}
|
||||
@ -279,6 +287,10 @@ class Parser
|
||||
// and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier
|
||||
// in the sequence override keys specified in later mapping nodes.
|
||||
foreach ($parsed as $parsedItem) {
|
||||
if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsedItem instanceof \stdClass) {
|
||||
$parsedItem = (array) $parsedItem;
|
||||
}
|
||||
|
||||
if (!is_array($parsedItem)) {
|
||||
throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem);
|
||||
}
|
||||
@ -902,7 +914,7 @@ class Parser
|
||||
|
||||
// remove leading comments
|
||||
$trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
|
||||
if (1 == $count) {
|
||||
if (1 === $count) {
|
||||
// items have been removed, update the offset
|
||||
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
|
||||
$value = $trimmedValue;
|
||||
@ -910,7 +922,7 @@ class Parser
|
||||
|
||||
// remove start of the document marker (---)
|
||||
$trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
|
||||
if (1 == $count) {
|
||||
if (1 === $count) {
|
||||
// items have been removed, update the offset
|
||||
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
|
||||
$value = $trimmedValue;
|
||||
|
@ -1865,6 +1865,43 @@ YAML;
|
||||
|
||||
$this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT | Yaml::PARSE_KEYS_AS_STRINGS));
|
||||
}
|
||||
|
||||
public function testMergeKeysWhenMappingsAreParsedAsObjects()
|
||||
{
|
||||
$yaml = <<<YAML
|
||||
foo: &FOO
|
||||
bar: 1
|
||||
bar: &BAR
|
||||
baz: 2
|
||||
<<: *FOO
|
||||
baz:
|
||||
baz_foo: 3
|
||||
<<:
|
||||
baz_bar: 4
|
||||
foobar:
|
||||
bar: ~
|
||||
<<: [*FOO, *BAR]
|
||||
YAML;
|
||||
$expected = (object) array(
|
||||
'foo' => (object) array(
|
||||
'bar' => 1,
|
||||
),
|
||||
'bar' => (object) array(
|
||||
'baz' => 2,
|
||||
'bar' => 1,
|
||||
),
|
||||
'baz' => (object) array(
|
||||
'baz_foo' => 3,
|
||||
'baz_bar' => 4,
|
||||
),
|
||||
'foobar' => (object) array(
|
||||
'bar' => null,
|
||||
'baz' => 2,
|
||||
),
|
||||
);
|
||||
|
||||
$this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP));
|
||||
}
|
||||
}
|
||||
|
||||
class B
|
||||
|
Reference in New Issue
Block a user