@@ -249,46 +249,58 @@ private function doParse($value, $flags)
249
249
if ('<< ' === $ key ) {
250
250
$ mergeNode = true ;
251
251
$ allowOverwrite = true ;
252
- if (isset ($ values ['value ' ]) && 0 === strpos ( $ values ['value ' ], ' * ' ) ) {
252
+ if (isset ($ values ['value ' ]) && isset ( $ values [ ' value ' ][ 0 ]) && ' * ' === $ values ['value ' ][ 0 ] ) {
253
253
$ refName = substr (rtrim ($ values ['value ' ]), 1 );
254
254
if (!array_key_exists ($ refName , $ this ->refs )) {
255
255
throw new ParseException (sprintf ('Reference "%s" does not exist. ' , $ refName ), $ this ->getRealCurrentLineNb () + 1 , $ this ->currentLine );
256
256
}
257
257
258
258
$ refValue = $ this ->refs [$ refName ];
259
259
260
- if (!is_array ($ refValue )) {
260
+ if (is_array ($ refValue )) {
261
+ $ data += $ refValue ; // array union
262
+ } elseif ((bool ) (Yaml::PARSE_OBJECT_FOR_MAP & $ flags ) && $ refValue instanceof \stdClass) {
263
+ foreach ($ refValue as $ refValueKey => $ refValueValue ) {
264
+ if (!isset ($ data [$ refValueKey ])) {
265
+ $ data [$ refValueKey ] = $ refValueValue ;
266
+ }
267
+ }
268
+ } else {
261
269
throw new ParseException ('YAML merge keys used with a scalar value instead of an array. ' , $ this ->getRealCurrentLineNb () + 1 , $ this ->currentLine );
262
270
}
263
-
264
- $ data += $ refValue ; // array union
265
271
} else {
266
- if (isset ($ values ['value ' ]) && $ values [ ' value ' ] !== '' ) {
272
+ if (isset ($ values ['value ' ]) && '' !== $ values [ ' value ' ] ) {
267
273
$ value = $ values ['value ' ];
268
274
} else {
269
275
$ value = $ this ->getNextEmbedBlock ();
270
276
}
271
277
$ parsed = $ this ->parseBlock ($ this ->getRealCurrentLineNb () + 1 , $ value , $ flags );
272
278
273
- if (!is_array ($ parsed )) {
274
- throw new ParseException ('YAML merge keys used with a scalar value instead of an array. ' , $ this ->getRealCurrentLineNb () + 1 , $ this ->currentLine );
275
- }
276
-
277
- if (isset ($ parsed [0 ])) {
278
- // If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes
279
- // and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier
280
- // in the sequence override keys specified in later mapping nodes.
281
- foreach ($ parsed as $ parsedItem ) {
282
- if (!is_array ($ parsedItem )) {
283
- throw new ParseException ('Merge items must be arrays. ' , $ this ->getRealCurrentLineNb () + 1 , $ parsedItem );
279
+ if (is_array ($ parsed )) {
280
+ if (isset ($ parsed [0 ])) {
281
+ // If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes
282
+ // and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier
283
+ // in the sequence override keys specified in later mapping nodes.
284
+ foreach ($ parsed as $ parsedItem ) {
285
+ if (!is_array ($ parsedItem )) {
286
+ throw new ParseException ('Merge items must be arrays. ' , $ this ->getRealCurrentLineNb () + 1 , $ parsedItem );
287
+ }
288
+
289
+ $ data += $ parsedItem ; // array union
290
+ }
291
+ } else {
292
+ // If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the
293
+ // current mapping, unless the key already exists in it.
294
+ $ data += $ parsed ; // array union
295
+ }
296
+ } elseif ((bool ) (Yaml::PARSE_OBJECT_FOR_MAP & $ flags ) && $ parsed instanceof \stdClass) {
297
+ foreach ($ parsed as $ parsedKey => $ parsedValue ) {
298
+ if (!isset ($ data [$ parsedKey ])) {
299
+ $ data [$ parsedKey ] = $ parsedValue ;
284
300
}
285
-
286
- $ data += $ parsedItem ; // array union
287
301
}
288
302
} else {
289
- // If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the
290
- // current mapping, unless the key already exists in it.
291
- $ data += $ parsed ; // array union
303
+ throw new ParseException ('YAML merge keys used with a scalar value instead of an array. ' , $ this ->getRealCurrentLineNb () + 1 , $ this ->currentLine );
292
304
}
293
305
}
294
306
} elseif (isset ($ values ['value ' ]) && self ::preg_match ('#^&(?P<ref>[^ ]++) *+(?P<value>.*)#u ' , $ values ['value ' ], $ matches )) {
@@ -544,7 +556,7 @@ private function getNextEmbedBlock($indentation = null, $inSequence = false)
544
556
$ indent = $ this ->getCurrentLineIndentation ();
545
557
546
558
// terminate all block scalars that are more indented than the current line
547
- if (!empty ($ blockScalarIndentations ) && $ indent < $ previousLineIndentation && trim ($ this ->currentLine ) !== '' ) {
559
+ if (!empty ($ blockScalarIndentations ) && $ indent < $ previousLineIndentation && '' !== trim ($ this ->currentLine )) {
548
560
foreach ($ blockScalarIndentations as $ key => $ blockScalarIndentation ) {
549
561
if ($ blockScalarIndentation >= $ indent ) {
550
562
unset($ blockScalarIndentations [$ key ]);
@@ -680,7 +692,7 @@ private function parseValue($value, $flags, $context)
680
692
681
693
while ($ this ->moveToNextLine ()) {
682
694
// unquoted strings end before the first unindented line
683
- if (null === $ quotation && $ this ->getCurrentLineIndentation () === 0 ) {
695
+ if (null === $ quotation && 0 === $ this ->getCurrentLineIndentation ()) {
684
696
$ this ->moveToPreviousLine ();
685
697
686
698
break ;
@@ -876,7 +888,7 @@ private function isCurrentLineComment()
876
888
//checking explicitly the first char of the trim is faster than loops or strpos
877
889
$ ltrimmedLine = ltrim ($ this ->currentLine , ' ' );
878
890
879
- return '' !== $ ltrimmedLine && $ ltrimmedLine [ 0 ] === ' # ' ;
891
+ return '' !== $ ltrimmedLine && ' # ' === $ ltrimmedLine [ 0 ] ;
880
892
}
881
893
882
894
private function isCurrentLineLastLineInDocument ()
@@ -902,15 +914,15 @@ private function cleanup($value)
902
914
903
915
// remove leading comments
904
916
$ trimmedValue = preg_replace ('#^(\#.*?\n)+#s ' , '' , $ value , -1 , $ count );
905
- if ($ count == 1 ) {
917
+ if (1 === $ count ) {
906
918
// items have been removed, update the offset
907
919
$ this ->offset += substr_count ($ value , "\n" ) - substr_count ($ trimmedValue , "\n" );
908
920
$ value = $ trimmedValue ;
909
921
}
910
922
911
923
// remove start of the document marker (---)
912
924
$ trimmedValue = preg_replace ('#^\-\-\-.*?\n#s ' , '' , $ value , -1 , $ count );
913
- if ($ count == 1 ) {
925
+ if (1 === $ count ) {
914
926
// items have been removed, update the offset
915
927
$ this ->offset += substr_count ($ value , "\n" ) - substr_count ($ trimmedValue , "\n" );
916
928
$ value = $ trimmedValue ;
0 commit comments