Parses a YAML string to a PHP value.
{
$this->currentLineNb = -1;
$this->currentLine = '';
$this->lines = explode(
"\n", $this->
cleanup($value));
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2)
{
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('UTF-8');
}
$data = array();
{
{
continue;
}
if (preg_match('#^\t+#', $this->currentLine))
{
throw new InvalidArgumentException(sprintf(
'A YAML file cannot contain tabs as indentation at line %d (%s).', $this->
getRealCurrentLineNb() + 1, $this->currentLine));
}
$isRef = $isInPlace = $isProcessed = false;
if (preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+?))?\s*$#u', $this->currentLine, $values))
{
if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches))
{
$isRef = $matches['ref'];
$values['value'] = $matches['value'];
}
if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#'))
{
$parser->refs =& $this->refs;
}
else
{
if (isset($values['leadspaces'])
&& ' ' == $values['leadspaces']
&& preg_match('#^(?P<key>'.sfYamlInline::REGEX_QUOTED_STRING.'|[^ \'"\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $values['value'], $matches))
{
$parser->refs =& $this->refs;
$block = $values['value'];
{
}
$data[] = $parser->parse($block);
}
else
{
}
}
}
else if (preg_match('#^(?P<key>'.sfYamlInline::REGEX_QUOTED_STRING.'|[^ \'"].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values))
{
if ('<<' === $key)
{
if (isset($values['value']) && '*' === substr($values['value'], 0, 1))
{
$isInPlace = substr($values['value'], 1);
if (!array_key_exists($isInPlace, $this->refs))
{
throw new InvalidArgumentException(sprintf(
'Reference "%s" does not exist at line %s (%s).', $isInPlace, $this->
getRealCurrentLineNb() + 1, $this->currentLine));
}
}
else
{
if (isset($values['value']) && $values['value'] !== '')
{
$value = $values['value'];
}
else
{
}
$parser->refs =& $this->refs;
$parsed = $parser->parse($value);
$merged = array();
if (!is_array($parsed))
{
throw new InvalidArgumentException(sprintf(
"YAML merge keys used with a scalar value instead of an array at line %s (%s)", $this->
getRealCurrentLineNb() + 1, $this->currentLine));
}
else if (isset($parsed[0]))
{
foreach (array_reverse($parsed) as $parsedItem)
{
if (!is_array($parsedItem))
{
throw new InvalidArgumentException(sprintf(
"Merge items must be arrays at line %s (%s).", $this->
getRealCurrentLineNb() + 1, $parsedItem));
}
$merged = array_merge($parsedItem, $merged);
}
}
else
{
$merged = array_merge($merge, $parsed);
}
$isProcessed = $merged;
}
}
else if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches))
{
$isRef = $matches['ref'];
$values['value'] = $matches['value'];
}
if ($isProcessed)
{
$data = $isProcessed;
}
else if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#'))
{
{
$data[$key] = null;
}
else
{
$parser->refs =& $this->refs;
}
}
else
{
if ($isInPlace)
{
$data = $this->refs[$isInPlace];
}
else
{
$data[$key] = $this->
parseValue($values[
'value']);
}
}
}
else
{
if (2 == count($this->lines) && empty($this->lines[1]))
{
if (is_array($value))
{
$first = reset($value);
if ('*' === substr($first, 0, 1))
{
$data = array();
foreach ($value as $alias)
{
$data[] = $this->refs[substr($alias, 1)];
}
$value = $data;
}
}
if (isset($mbEncoding))
{
mb_internal_encoding($mbEncoding);
}
return $value;
}
switch (preg_last_error())
{
case PREG_INTERNAL_ERROR:
$error = 'Internal PCRE error on line';
break;
case PREG_BACKTRACK_LIMIT_ERROR:
$error = 'pcre.backtrack_limit reached on line';
break;
case PREG_RECURSION_LIMIT_ERROR:
$error = 'pcre.recursion_limit reached on line';
break;
case PREG_BAD_UTF8_ERROR:
$error = 'Malformed UTF-8 data on line';
break;
case PREG_BAD_UTF8_OFFSET_ERROR:
$error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point on line';
break;
default:
$error = 'Unable to parse line';
}
throw new InvalidArgumentException(sprintf(
'%s %d (%s).', $error, $this->
getRealCurrentLineNb() + 1, $this->currentLine));
}
if ($isRef)
{
$this->refs[$isRef] = end($data);
}
}
if (isset($mbEncoding))
{
mb_internal_encoding($mbEncoding);
}
return empty($data) ? null : $data;
}