= ! % @ ` ]/x', $value): return sprintf("'%s'", str_replace('\'', '\'\'', $value)); case '' == $value: return "''"; case preg_match(self::getTimestampRegex(), $value): return "'$value'"; case in_array(strtolower($value), $trueValues): return "'$value'"; case in_array(strtolower($value), $falseValues): return "'$value'"; case in_array(strtolower($value), array('null', '~')): return "'$value'"; default: return $value; } } static protected function dumpArray($value) { $keys = array_keys($value); if ( (1 == count($keys) && '0' == $keys[0]) || (count($keys) > 1 && array_reduce($keys, create_function('$v,$w', 'return (integer) $v + $w;'), 0) == count($keys) * (count($keys) - 1) / 2)) { $output = array(); foreach ($value as $val) { $output[] = self::dump($val); } return sprintf('[%s]', implode(', ', $output)); } $output = array(); foreach ($value as $key => $val) { $output[] = sprintf('%s: %s', self::dump($key), self::dump($val)); } return sprintf('{ %s }', implode(', ', $output)); } static public function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true) { if (in_array($scalar[$i], $stringDelimiters)) { $output = self::parseQuotedScalar($scalar, $i); } else { if (!$delimiters) { $output = substr($scalar, $i); $i += strlen($output); if (false !== $strpos = strpos($output, ' #')) { $output = rtrim(substr($output, 0, $strpos)); } } else if (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) { $output = $match[1]; $i += strlen($output); } else { throw new InvalidArgumentException(sprintf('Malformed inline YAML string (%s).', $scalar)); } $output = $evaluate ? self::evaluateScalar($output) : $output; } return $output; } static protected function parseQuotedScalar($scalar, &$i) { if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) { throw new InvalidArgumentException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i))); } $output = substr($match[0], 1, strlen($match[0]) - 2); if ('"' == $scalar[$i]) { $output = str_replace(array('\\"', '\\n', '\\r'), array('"', "\n", "\r"), $output); } else { $output = str_replace('\'\'', '\'', $output); } $i += strlen($match[0]); return $output; } static protected function parseSequence($sequence, &$i = 0) { $output = array(); $len = strlen($sequence); $i += 1; while ($i < $len) { switch ($sequence[$i]) { case '[': $output[] = self::parseSequence($sequence, $i); break; case '{': $output[] = self::parseMapping($sequence, $i); break; case ']': return $output; case ',': case ' ': break; default: $isQuoted = in_array($sequence[$i], array('"', "'")); $value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i); if (!$isQuoted && false !== strpos($value, ': ')) { try { $value = self::parseMapping('{'.$value.'}'); } catch (InvalidArgumentException $e) { } } $output[] = $value; --$i; } ++$i; } throw new InvalidArgumentException(sprintf('Malformed inline YAML string %s', $sequence)); } static protected function parseMapping($mapping, &$i = 0) { $output = array(); $len = strlen($mapping); $i += 1; while ($i < $len) { switch ($mapping[$i]) { case ' ': case ',': ++$i; continue 2; case '}': return $output; } $key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false); $done = false; while ($i < $len) { switch ($mapping[$i]) { case '[': $output[$key] = self::parseSequence($mapping, $i); $done = true; break; case '{': $output[$key] = self::parseMapping($mapping, $i); $done = true; break; case ':': case ' ': break; default: $output[$key] = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i); $done = true; --$i; } ++$i; if ($done) { continue 2; } } } throw new InvalidArgumentException(sprintf('Malformed inline YAML string %s', $mapping)); } static protected function evaluateScalar($scalar) { $scalar = trim($scalar); if ('1.1' === sfYaml::getSpecVersion()) { $trueValues = array('true', 'on', '+', 'yes', 'y'); $falseValues = array('false', 'off', '-', 'no', 'n'); } else { $trueValues = array('true'); $falseValues = array('false'); } switch (true) { case 'null' == strtolower($scalar): case '' == $scalar: case '~' == $scalar: return null; case 0 === strpos($scalar, '!str'): return (string) substr($scalar, 5); case 0 === strpos($scalar, '! '): return intval(self::parseScalar(substr($scalar, 2))); case 0 === strpos($scalar, '!!php/object:'): return unserialize(substr($scalar, 13)); case ctype_digit($scalar): $raw = $scalar; $cast = intval($scalar); return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw); case in_array(strtolower($scalar), $trueValues): return true; case in_array(strtolower($scalar), $falseValues): return false; case is_numeric($scalar): return '0x' == $scalar[0].$scalar[1] ? hexdec($scalar) : floatval($scalar); case 0 == strcasecmp($scalar, '.inf'): case 0 == strcasecmp($scalar, '.NaN'): return -log(0); case 0 == strcasecmp($scalar, '-.inf'): return log(0); case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar): return floatval(str_replace(',', '', $scalar)); case preg_match(self::getTimestampRegex(), $scalar): return strtotime($scalar); default: return (string) $scalar; } } static protected function getTimestampRegex() { return <<[0-9][0-9][0-9][0-9]) -(?P[0-9][0-9]?) -(?P[0-9][0-9]?) (?:(?:[Tt]|[ \t]+) (?P[0-9][0-9]?) :(?P[0-9][0-9]) :(?P[0-9][0-9]) (?:\.(?P[0-9]*))? (?:[ \t]*(?PZ|(?P[-+])(?P[0-9][0-9]?) (?::(?P[0-9][0-9]))?))?)? $~x EOF; } }