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) {
|
if ('<<' === $key) {
|
||||||
$mergeNode = true;
|
$mergeNode = true;
|
||||||
$allowOverwrite = 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);
|
$refName = substr(rtrim($values['value']), 1);
|
||||||
if (!array_key_exists($refName, $this->refs)) {
|
if (!array_key_exists($refName, $this->refs)) {
|
||||||
throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine);
|
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];
|
$refValue = $this->refs[$refName];
|
||||||
|
|
||||||
|
if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $refValue instanceof \stdClass) {
|
||||||
|
$refValue = (array) $refValue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_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);
|
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);
|
$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)) {
|
if (!is_array($parsed)) {
|
||||||
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
|
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
|
// 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.
|
// in the sequence override keys specified in later mapping nodes.
|
||||||
foreach ($parsed as $parsedItem) {
|
foreach ($parsed as $parsedItem) {
|
||||||
|
if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsedItem instanceof \stdClass) {
|
||||||
|
$parsedItem = (array) $parsedItem;
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_array($parsedItem)) {
|
if (!is_array($parsedItem)) {
|
||||||
throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem);
|
throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem);
|
||||||
}
|
}
|
||||||
@ -902,7 +914,7 @@ class Parser
|
|||||||
|
|
||||||
// remove leading comments
|
// remove leading comments
|
||||||
$trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
|
$trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
|
||||||
if (1 == $count) {
|
if (1 === $count) {
|
||||||
// items have been removed, update the offset
|
// items have been removed, update the offset
|
||||||
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
|
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
|
||||||
$value = $trimmedValue;
|
$value = $trimmedValue;
|
||||||
@ -910,7 +922,7 @@ class Parser
|
|||||||
|
|
||||||
// remove start of the document marker (---)
|
// remove start of the document marker (---)
|
||||||
$trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
|
$trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
|
||||||
if (1 == $count) {
|
if (1 === $count) {
|
||||||
// items have been removed, update the offset
|
// items have been removed, update the offset
|
||||||
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
|
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
|
||||||
$value = $trimmedValue;
|
$value = $trimmedValue;
|
||||||
|
@ -1865,6 +1865,43 @@ YAML;
|
|||||||
|
|
||||||
$this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT | Yaml::PARSE_KEYS_AS_STRINGS));
|
$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
|
class B
|
||||||
|
Reference in New Issue
Block a user