@@ -32,12 +32,13 @@ class Inline
32
32
* @param string $value A YAML string
33
33
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
34
34
* @param bool $objectSupport true if object support is enabled, false otherwise
35
+ * @param array $references Mapping of variable names to values
35
36
*
36
37
* @return array A PHP array representing the YAML string
37
38
*
38
39
* @throws ParseException
39
40
*/
40
- public static function parse ($ value , $ exceptionOnInvalidType = false , $ objectSupport = false )
41
+ public static function parse ($ value , $ exceptionOnInvalidType = false , $ objectSupport = false , $ references = array () )
41
42
{
42
43
self ::$ exceptionOnInvalidType = $ exceptionOnInvalidType ;
43
44
self ::$ objectSupport = $ objectSupport ;
@@ -56,15 +57,15 @@ public static function parse($value, $exceptionOnInvalidType = false, $objectSup
56
57
$ i = 0 ;
57
58
switch ($ value [0 ]) {
58
59
case '[ ' :
59
- $ result = self ::parseSequence ($ value , $ i );
60
+ $ result = self ::parseSequence ($ value , $ i, $ references );
60
61
++$ i ;
61
62
break ;
62
63
case '{ ' :
63
- $ result = self ::parseMapping ($ value , $ i );
64
+ $ result = self ::parseMapping ($ value , $ i, $ references );
64
65
++$ i ;
65
66
break ;
66
67
default :
67
- $ result = self ::parseScalar ($ value , null , array ('" ' , "' " ), $ i );
68
+ $ result = self ::parseScalar ($ value , null , array ('" ' , "' " ), $ i, true , $ references );
68
69
}
69
70
70
71
// some comments are allowed at the end
@@ -184,14 +185,15 @@ private static function dumpArray($value, $exceptionOnInvalidType, $objectSuppor
184
185
* @param scalar $scalar
185
186
* @param string $delimiters
186
187
* @param array $stringDelimiters
187
- * @param int &$i
188
- * @param bool $evaluate
188
+ * @param int &$i
189
+ * @param bool $evaluate
190
+ * @param array $references
189
191
*
190
192
* @return string A YAML string
191
193
*
192
194
* @throws ParseException When malformed inline YAML string is parsed
193
195
*/
194
- public static function parseScalar ($ scalar , $ delimiters = null , $ stringDelimiters = array ('" ' , "' " ), &$ i = 0 , $ evaluate = true )
196
+ public static function parseScalar ($ scalar , $ delimiters = null , $ stringDelimiters = array ('" ' , "' " ), &$ i = 0 , $ evaluate = true , $ references = array () )
195
197
{
196
198
if (in_array ($ scalar [$ i ], $ stringDelimiters )) {
197
199
// quoted scalar
@@ -221,7 +223,7 @@ public static function parseScalar($scalar, $delimiters = null, $stringDelimiter
221
223
}
222
224
223
225
if ($ evaluate ) {
224
- $ output = self ::evaluateScalar ($ output );
226
+ $ output = self ::evaluateScalar ($ output, $ references );
225
227
}
226
228
}
227
229
@@ -262,13 +264,14 @@ private static function parseQuotedScalar($scalar, &$i)
262
264
* Parses a sequence to a YAML string.
263
265
*
264
266
* @param string $sequence
265
- * @param int &$i
267
+ * @param int &$i
268
+ * @param array $references
266
269
*
267
270
* @return string A YAML string
268
271
*
269
272
* @throws ParseException When malformed inline YAML string is parsed
270
273
*/
271
- private static function parseSequence ($ sequence , &$ i = 0 )
274
+ private static function parseSequence ($ sequence , &$ i = 0 , $ references = array () )
272
275
{
273
276
$ output = array ();
274
277
$ len = strlen ($ sequence );
@@ -279,11 +282,11 @@ private static function parseSequence($sequence, &$i = 0)
279
282
switch ($ sequence [$ i ]) {
280
283
case '[ ' :
281
284
// nested sequence
282
- $ output [] = self ::parseSequence ($ sequence , $ i );
285
+ $ output [] = self ::parseSequence ($ sequence , $ i, $ references );
283
286
break ;
284
287
case '{ ' :
285
288
// nested mapping
286
- $ output [] = self ::parseMapping ($ sequence , $ i );
289
+ $ output [] = self ::parseMapping ($ sequence , $ i, $ references );
287
290
break ;
288
291
case '] ' :
289
292
return $ output ;
@@ -292,12 +295,14 @@ private static function parseSequence($sequence, &$i = 0)
292
295
break ;
293
296
default :
294
297
$ isQuoted = in_array ($ sequence [$ i ], array ('" ' , "' " ));
295
- $ value = self ::parseScalar ($ sequence , array (', ' , '] ' ), array ('" ' , "' " ), $ i );
298
+ $ value = self ::parseScalar ($ sequence , array (', ' , '] ' ), array ('" ' , "' " ), $ i, true , $ references );
296
299
297
- if (!$ isQuoted && false !== strpos ($ value , ': ' )) {
300
+ // the value can be an array if a reference has been resolved to an array var
301
+ if (!is_array ($ value ) && !$ isQuoted && false !== strpos ($ value , ': ' )) {
298
302
// embedded mapping?
299
303
try {
300
- $ value = self ::parseMapping ('{ ' .$ value .'} ' );
304
+ $ pos = 0 ;
305
+ $ value = self ::parseMapping ('{ ' .$ value .'} ' , $ pos , $ references );
301
306
} catch (\InvalidArgumentException $ e ) {
302
307
// no, it's not
303
308
}
@@ -318,13 +323,14 @@ private static function parseSequence($sequence, &$i = 0)
318
323
* Parses a mapping to a YAML string.
319
324
*
320
325
* @param string $mapping
321
- * @param int &$i
326
+ * @param int &$i
327
+ * @param array $references
322
328
*
323
329
* @return string A YAML string
324
330
*
325
331
* @throws ParseException When malformed inline YAML string is parsed
326
332
*/
327
- private static function parseMapping ($ mapping , &$ i = 0 )
333
+ private static function parseMapping ($ mapping , &$ i = 0 , $ references = array () )
328
334
{
329
335
$ output = array ();
330
336
$ len = strlen ($ mapping );
@@ -350,19 +356,19 @@ private static function parseMapping($mapping, &$i = 0)
350
356
switch ($ mapping [$ i ]) {
351
357
case '[ ' :
352
358
// nested sequence
353
- $ output [$ key ] = self ::parseSequence ($ mapping , $ i );
359
+ $ output [$ key ] = self ::parseSequence ($ mapping , $ i, $ references );
354
360
$ done = true ;
355
361
break ;
356
362
case '{ ' :
357
363
// nested mapping
358
- $ output [$ key ] = self ::parseMapping ($ mapping , $ i );
364
+ $ output [$ key ] = self ::parseMapping ($ mapping , $ i, $ references );
359
365
$ done = true ;
360
366
break ;
361
367
case ': ' :
362
368
case ' ' :
363
369
break ;
364
370
default :
365
- $ output [$ key ] = self ::parseScalar ($ mapping , array (', ' , '} ' ), array ('" ' , "' " ), $ i );
371
+ $ output [$ key ] = self ::parseScalar ($ mapping , array (', ' , '} ' ), array ('" ' , "' " ), $ i, true , $ references );
366
372
$ done = true ;
367
373
--$ i ;
368
374
}
@@ -382,15 +388,31 @@ private static function parseMapping($mapping, &$i = 0)
382
388
* Evaluates scalars and replaces magic values.
383
389
*
384
390
* @param string $scalar
391
+ * @param array $references
385
392
*
386
393
* @return string A YAML string
387
394
*
388
395
* @throws ParseException when object parsing support was disabled and the parser detected a PHP object
389
396
*/
390
- private static function evaluateScalar ($ scalar )
397
+ private static function evaluateScalar ($ scalar, $ references = array () )
391
398
{
392
399
$ scalar = trim ($ scalar );
393
400
$ scalarLower = strtolower ($ scalar );
401
+
402
+ if (0 === strpos ($ scalar , '* ' )) {
403
+ if (false !== $ pos = strpos ($ scalar , '# ' )) {
404
+ $ value = substr ($ scalar , 1 , $ pos - 2 );
405
+ } else {
406
+ $ value = substr ($ scalar , 1 );
407
+ }
408
+
409
+ if (!array_key_exists ($ value , $ references )) {
410
+ throw new ParseException (sprintf ('Reference "%s" does not exist. ' , $ value ));
411
+ }
412
+
413
+ return $ references [$ value ];
414
+ }
415
+
394
416
switch (true ) {
395
417
case 'null ' === $ scalarLower :
396
418
case '' === $ scalar :
0 commit comments