mirror of
https://github.com/easy-wi/developer.git
synced 2025-02-20 11:23:28 +08:00
#923 replace Spyc with Symfony YAML class
This commit is contained in:
parent
26516b102c
commit
ec05408859
@ -94,8 +94,8 @@ https://github.com/milesj/decoda
|
|||||||
Released under the MIT license
|
Released under the MIT license
|
||||||
http://opensource.org/licenses/MIT
|
http://opensource.org/licenses/MIT
|
||||||
|
|
||||||
* Spyc -- A Simple PHP YAML Class
|
* Symfony YAML
|
||||||
https://github.com/mustangostang/spyc/
|
https://github.com/symfony/yaml
|
||||||
Released under the MIT license
|
Released under the MIT license
|
||||||
http://opensource.org/licenses/MIT
|
http://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
@ -982,6 +982,7 @@ function showFileContextMenu(e,file,folder,isLin) {
|
|||||||
editableExts[14] = 'properties';
|
editableExts[14] = 'properties';
|
||||||
editableExts[15] = 'example';
|
editableExts[15] = 'example';
|
||||||
editableExts[16] = 'yml';
|
editableExts[16] = 'yml';
|
||||||
|
editableExts[16] = 'yaml';
|
||||||
editableExts[17] = 'json';
|
editableExts[17] = 'json';
|
||||||
|
|
||||||
globalContextHeight=12; // top and bottom padding
|
globalContextHeight=12; // top and bottom padding
|
||||||
|
@ -47,6 +47,12 @@ if (!class_exists('EasyWiFTP')) {
|
|||||||
include(EASYWIDIR . '/stuff/methods/class_ftp.php');
|
include(EASYWIDIR . '/stuff/methods/class_ftp.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!class_exists('Yaml')) {
|
||||||
|
include(EASYWIDIR . '/third_party/Symfony/autoloader_yaml.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
use Symfony\Component\Yaml\Yaml;
|
||||||
|
|
||||||
class AppServer {
|
class AppServer {
|
||||||
|
|
||||||
private $uniqueHex, $winCmds = array(), $shellScriptHeader, $shellScripts = array('user' => '', 'server' => array()), $commandReturns = array(), $undefinedRequiredVars = array();
|
private $uniqueHex, $winCmds = array(), $shellScriptHeader, $shellScripts = array('user' => '', 'server' => array()), $commandReturns = array(), $undefinedRequiredVars = array();
|
||||||
@ -600,7 +606,7 @@ class AppServer {
|
|||||||
$serverDir = ($this->appServerDetails['protectionModeStarted'] == 'Y') ? 'pserver/' : 'server/';
|
$serverDir = ($this->appServerDetails['protectionModeStarted'] == 'Y') ? 'pserver/' : 'server/';
|
||||||
$absolutePath = $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName'] . '/' . $serverDir . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port']);
|
$absolutePath = $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName'] . '/' . $serverDir . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port']);
|
||||||
|
|
||||||
$copyFileExtensions = array('xml', 'vdf', 'cfg', 'con', 'conf', 'config', 'ini', 'gam', 'txt', 'log', 'smx', 'sp', 'db', 'lang', 'lua', 'props', 'properties', 'json', 'example', 'html', 'yml');
|
$copyFileExtensions = array('xml', 'vdf', 'cfg', 'con', 'conf', 'config', 'ini', 'gam', 'txt', 'log', 'smx', 'sp', 'db', 'lang', 'lua', 'props', 'properties', 'json', 'example', 'html', 'yml', 'yaml');
|
||||||
|
|
||||||
if ($standalone and isset($scriptName)) {
|
if ($standalone and isset($scriptName)) {
|
||||||
$script = $this->shellScriptHeader;
|
$script = $this->shellScriptHeader;
|
||||||
@ -896,11 +902,39 @@ class AppServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function protectedYaml($replaceSettings, $parsedConfig) {
|
||||||
|
|
||||||
|
$customColumns = customColumns('G', $this->appServerDetails['id']);
|
||||||
|
|
||||||
|
foreach ($parsedConfig as $key => $value) {
|
||||||
|
|
||||||
|
if (is_array($value) or is_object($value)) {
|
||||||
|
|
||||||
|
$parsedConfig[$key] = $this->protectedYaml($replaceSettings, $value);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (is_string($value) and strpos($value, '%') !== false) {
|
||||||
|
$parsedConfig[$key] = str_replace($replaceSettings['placeholder'], $replaceSettings['replacePlaceholderWith'], $value);
|
||||||
|
} else {
|
||||||
|
$parsedConfig[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($customColumns as $customColumn) {
|
||||||
|
$parsedConfig[$key] = str_replace('%' . $customColumn['name'] . '%', $customColumn['value'], $parsedConfig[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $parsedConfig;
|
||||||
|
}
|
||||||
|
|
||||||
private function protectedSettingsToArray () {
|
private function protectedSettingsToArray () {
|
||||||
|
|
||||||
|
$protectedString = '';
|
||||||
$cvarProtectArray = array();
|
$cvarProtectArray = array();
|
||||||
$lendServerReplaceMents = array();
|
$lendServerReplaceMents = array();
|
||||||
$debugger= array();
|
$debugger = array();
|
||||||
|
|
||||||
$replaceSettings = $this->getReplacements();
|
$replaceSettings = $this->getReplacements();
|
||||||
@parse_ini_string($this->appServerDetails['template']['configedit'], true, INI_SCANNER_RAW);
|
@parse_ini_string($this->appServerDetails['template']['configedit'], true, INI_SCANNER_RAW);
|
||||||
@ -909,7 +943,11 @@ class AppServer {
|
|||||||
|
|
||||||
$line = str_replace(array("\r"), '', $line);
|
$line = str_replace(array("\r"), '', $line);
|
||||||
|
|
||||||
if (preg_match('/^(\[[\w\/\.\-\_]{1,}\]|\[[\w\/\.\-\_]{1,}\] (xml|ini|cfg|lua|json|ddot|yml|yaml))$/', $line)) {
|
if (preg_match('/^(\[[\w\/\.\-\_]{1,}\]|\[[\w\/\.\-\_]{1,}\] (xml|ini|cfg|lua|json|ddot|yml|Yaml|yaml))$/', $line)) {
|
||||||
|
|
||||||
|
if (strlen($protectedString) > 0 and isset($configPathAndFile) and !isset($cvarProtectArray[$configPathAndFile]['cvars']) and in_array($cvarProtectArray[$configPathAndFile]['type'], array('yml', 'yaml', 'Yaml'))) {
|
||||||
|
$cvarProtectArray[$configPathAndFile]['cvars'] = $this->protectedYaml($replaceSettings, Yaml::parse($protectedString));
|
||||||
|
}
|
||||||
|
|
||||||
$exploded = preg_split("/\s+/", $line, -1, PREG_SPLIT_NO_EMPTY);
|
$exploded = preg_split("/\s+/", $line, -1, PREG_SPLIT_NO_EMPTY);
|
||||||
|
|
||||||
@ -919,6 +957,8 @@ class AppServer {
|
|||||||
|
|
||||||
$cvarProtectArray[$configPathAndFile]['type'] = $cvarType;
|
$cvarProtectArray[$configPathAndFile]['type'] = $cvarType;
|
||||||
|
|
||||||
|
$protectedString = '';
|
||||||
|
|
||||||
} else if (isset($configPathAndFile) and isset($cvarProtectArray[$configPathAndFile]['type'])) {
|
} else if (isset($configPathAndFile) and isset($cvarProtectArray[$configPathAndFile]['type'])) {
|
||||||
|
|
||||||
unset($splitLine);
|
unset($splitLine);
|
||||||
@ -927,9 +967,9 @@ class AppServer {
|
|||||||
|
|
||||||
$splitLine = preg_split("/\s+/", $line, -1, PREG_SPLIT_NO_EMPTY);
|
$splitLine = preg_split("/\s+/", $line, -1, PREG_SPLIT_NO_EMPTY);
|
||||||
|
|
||||||
} else if ($cvarProtectArray[$configPathAndFile]['type'] == 'yml' or $cvarProtectArray[$configPathAndFile]['type'] == 'yaml') {
|
} else if (in_array($cvarProtectArray[$configPathAndFile]['type'], array('yml','yaml','Yaml'))) {
|
||||||
|
|
||||||
$splitLine = preg_split("/(?:(?<!-))\s*:\s*/", $line);
|
$protectedString .= $line . "\r\n";
|
||||||
|
|
||||||
} else if (in_array($cvarProtectArray[$configPathAndFile]['type'], array('ini','lua'))) {
|
} else if (in_array($cvarProtectArray[$configPathAndFile]['type'], array('ini','lua'))) {
|
||||||
|
|
||||||
@ -977,6 +1017,10 @@ class AppServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($protectedString) > 0 and isset($configPathAndFile) and !isset($cvarProtectArray[$configPathAndFile]['cvars']) and in_array($cvarProtectArray[$configPathAndFile]['type'], array('yml', 'yaml', 'Yaml'))) {
|
||||||
|
$cvarProtectArray[$configPathAndFile]['cvars'] = $this->protectedYaml($replaceSettings, Yaml::parse($protectedString));
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->appServerDetails['lendServer'] == 'Y') {
|
if ($this->appServerDetails['lendServer'] == 'Y') {
|
||||||
|
|
||||||
if ($this->appServerDetails['lendServer'] == 'Y') {
|
if ($this->appServerDetails['lendServer'] == 'Y') {
|
||||||
@ -1047,8 +1091,10 @@ class AppServer {
|
|||||||
foreach(array_keys($givenArray) as $key) {
|
foreach(array_keys($givenArray) as $key) {
|
||||||
|
|
||||||
if (is_array($givenArray[$key])) {
|
if (is_array($givenArray[$key])) {
|
||||||
$givenArray[$key] = $this->replaceArrayValues($givenArray[$key], $replacements);
|
|
||||||
}
|
$givenArray[$key] = $this->replaceArrayValues($givenArray[$key], ((is_array($replacements) or is_object($replacements)) and isset($replacements[$key])) ? $replacements[$key] : $replacements);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
if (isset($this->undefinedRequiredVars[$key])) {
|
if (isset($this->undefinedRequiredVars[$key])) {
|
||||||
unset($this->undefinedRequiredVars[$key]);
|
unset($this->undefinedRequiredVars[$key]);
|
||||||
@ -1058,6 +1104,7 @@ class AppServer {
|
|||||||
$givenArray[$key] = $replacements[$key];
|
$givenArray[$key] = $replacements[$key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $givenArray;
|
return $givenArray;
|
||||||
}
|
}
|
||||||
@ -1119,6 +1166,22 @@ class AppServer {
|
|||||||
return $iniString;
|
return $iniString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function addNotFoundVars($replacedArray, $key, $value) {
|
||||||
|
|
||||||
|
if (!isset($replacedArray[$key]) or (!is_array($replacedArray[$key]) and !is_object($replacedArray[$key]))) {
|
||||||
|
|
||||||
|
$replacedArray[$key] = $value;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
foreach ($replacedArray[$key] as $k => $v) {
|
||||||
|
$replacedArray[$key] = $this->addNotFoundVars($replacedArray[$key], $k, $v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $replacedArray;
|
||||||
|
}
|
||||||
|
|
||||||
private function replaceArray($stored, $replacements) {
|
private function replaceArray($stored, $replacements) {
|
||||||
|
|
||||||
if (!$stored) {
|
if (!$stored) {
|
||||||
@ -1128,14 +1191,14 @@ class AppServer {
|
|||||||
$replacedArray = $this->replaceArrayValues($stored, $replacements);
|
$replacedArray = $this->replaceArrayValues($stored, $replacements);
|
||||||
|
|
||||||
foreach ($this->undefinedRequiredVars as $key => $value) {
|
foreach ($this->undefinedRequiredVars as $key => $value) {
|
||||||
$replacedArray[$key] = $value;
|
$replacedArray = $this->addNotFoundVars($replacedArray, $key, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $replacedArray;
|
return $replacedArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function replaceYaml($stored, $replacements) {
|
private function replaceYaml($stored, $replacements) {
|
||||||
return Spyc::YAMLDump($this->replaceArray($stored, $replacements));
|
return Yaml::dump($this->replaceArray($stored, $replacements), 2, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function replaceJSON($stored, $replacements) {
|
private function replaceJSON($stored, $replacements) {
|
||||||
@ -1186,15 +1249,9 @@ class AppServer {
|
|||||||
|
|
||||||
$ftpObect->writeContentToTemp($this->replaceIni(@parse_ini_string($configFileContent, false, INI_SCANNER_RAW), $values['cvars']));
|
$ftpObect->writeContentToTemp($this->replaceIni(@parse_ini_string($configFileContent, false, INI_SCANNER_RAW), $values['cvars']));
|
||||||
|
|
||||||
} else if ($values['type'] === 'yml' or $values['type'] === 'yaml') {
|
} else if ($values['type'] === 'yml' or $values['type'] === 'Yaml' or $values['type'] === 'yaml') {
|
||||||
|
|
||||||
if (!class_exists('Spyc')) {
|
$ftpObect->writeContentToTemp($this->replaceYaml(Yaml::parse($configFileContent), $values['cvars']));
|
||||||
include(EASYWIDIR . '/third_party/spyc/Spyc.php');
|
|
||||||
}
|
|
||||||
|
|
||||||
$parsedConfig = Spyc::YAMLLoadString($configFileContent);
|
|
||||||
|
|
||||||
$ftpObect->writeContentToTemp($this->replaceYaml($parsedConfig, $values['cvars']));
|
|
||||||
|
|
||||||
} else if ($values['type'] == 'json') {
|
} else if ($values['type'] == 'json') {
|
||||||
|
|
||||||
@ -1206,9 +1263,7 @@ class AppServer {
|
|||||||
include(EASYWIDIR . '/stuff/methods/class_lua.php');
|
include(EASYWIDIR . '/stuff/methods/class_lua.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
$parsedConfig = Lua::luaToArray($configFileContent);
|
$ftpObect->writeContentToTemp($this->replaceLua(Lua::luaToArray($configFileContent), $values['cvars']));
|
||||||
|
|
||||||
$ftpObect->writeContentToTemp($this->replaceLua($parsedConfig, $values['cvars']));
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
77
third_party/Symfony/Component/Yaml/Dumper.php
vendored
Normal file
77
third_party/Symfony/Component/Yaml/Dumper.php
vendored
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Yaml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dumper dumps PHP variables to YAML strings.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class Dumper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The amount of spaces to use for indentation of nested nodes.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $indentation = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the indentation.
|
||||||
|
*
|
||||||
|
* @param int $num The amount of spaces to use for indentation of nested nodes
|
||||||
|
*/
|
||||||
|
public function setIndentation($num)
|
||||||
|
{
|
||||||
|
if ($num < 1) {
|
||||||
|
throw new \InvalidArgumentException('The indentation must be greater than zero.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->indentation = (int) $num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dumps a PHP value to YAML.
|
||||||
|
*
|
||||||
|
* @param mixed $input The PHP value
|
||||||
|
* @param int $inline The level where you switch to inline YAML
|
||||||
|
* @param int $indent The level of indentation (used internally)
|
||||||
|
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
|
||||||
|
* @param bool $objectSupport true if object support is enabled, false otherwise
|
||||||
|
*
|
||||||
|
* @return string The YAML representation of the PHP value
|
||||||
|
*/
|
||||||
|
public function dump($input, $inline = 0, $indent = 0, $exceptionOnInvalidType = false, $objectSupport = false)
|
||||||
|
{
|
||||||
|
$output = '';
|
||||||
|
$prefix = $indent ? str_repeat(' ', $indent) : '';
|
||||||
|
|
||||||
|
if ($inline <= 0 || !is_array($input) || empty($input)) {
|
||||||
|
$output .= $prefix.Inline::dump($input, $exceptionOnInvalidType, $objectSupport);
|
||||||
|
} else {
|
||||||
|
$isAHash = Inline::isHash($input);
|
||||||
|
|
||||||
|
foreach ($input as $key => $value) {
|
||||||
|
$willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value);
|
||||||
|
|
||||||
|
$output .= sprintf('%s%s%s%s',
|
||||||
|
$prefix,
|
||||||
|
$isAHash ? Inline::dump($key, $exceptionOnInvalidType, $objectSupport).':' : '-',
|
||||||
|
$willBeInlined ? ' ' : "\n",
|
||||||
|
$this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $exceptionOnInvalidType, $objectSupport)
|
||||||
|
).($willBeInlined ? "\n" : '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
}
|
99
third_party/Symfony/Component/Yaml/Escaper.php
vendored
Normal file
99
third_party/Symfony/Component/Yaml/Escaper.php
vendored
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Yaml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escaper encapsulates escaping rules for single and double-quoted
|
||||||
|
* YAML strings.
|
||||||
|
*
|
||||||
|
* @author Matthew Lewinski <matthew@lewinski.org>
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
class Escaper
|
||||||
|
{
|
||||||
|
// Characters that would cause a dumped string to require double quoting.
|
||||||
|
const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";
|
||||||
|
|
||||||
|
// Mapping arrays for escaping a double quoted string. The backslash is
|
||||||
|
// first to ensure proper escaping because str_replace operates iteratively
|
||||||
|
// on the input arrays. This ordering of the characters avoids the use of strtr,
|
||||||
|
// which performs more slowly.
|
||||||
|
private static $escapees = array('\\', '\\\\', '\\"', '"',
|
||||||
|
"\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
|
||||||
|
"\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f",
|
||||||
|
"\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
|
||||||
|
"\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f",
|
||||||
|
"\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9");
|
||||||
|
private static $escaped = array('\\\\', '\\"', '\\\\', '\\"',
|
||||||
|
'\\0', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a',
|
||||||
|
'\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f',
|
||||||
|
'\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17',
|
||||||
|
'\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f',
|
||||||
|
'\\N', '\\_', '\\L', '\\P');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a PHP value would require double quoting in YAML.
|
||||||
|
*
|
||||||
|
* @param string $value A PHP value
|
||||||
|
*
|
||||||
|
* @return bool True if the value would require double quotes
|
||||||
|
*/
|
||||||
|
public static function requiresDoubleQuoting($value)
|
||||||
|
{
|
||||||
|
return preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes and surrounds a PHP value with double quotes.
|
||||||
|
*
|
||||||
|
* @param string $value A PHP value
|
||||||
|
*
|
||||||
|
* @return string The quoted, escaped string
|
||||||
|
*/
|
||||||
|
public static function escapeWithDoubleQuotes($value)
|
||||||
|
{
|
||||||
|
return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a PHP value would require single quoting in YAML.
|
||||||
|
*
|
||||||
|
* @param string $value A PHP value
|
||||||
|
*
|
||||||
|
* @return bool True if the value would require single quotes
|
||||||
|
*/
|
||||||
|
public static function requiresSingleQuoting($value)
|
||||||
|
{
|
||||||
|
// Determines if a PHP value is entirely composed of a value that would
|
||||||
|
// require single quoting in YAML.
|
||||||
|
if (in_array(strtolower($value), array('null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determines if the PHP value contains any single characters that would
|
||||||
|
// cause it to require single quoting in YAML.
|
||||||
|
return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes and surrounds a PHP value with single quotes.
|
||||||
|
*
|
||||||
|
* @param string $value A PHP value
|
||||||
|
*
|
||||||
|
* @return string The quoted, escaped string
|
||||||
|
*/
|
||||||
|
public static function escapeWithSingleQuotes($value)
|
||||||
|
{
|
||||||
|
return sprintf("'%s'", str_replace('\'', '\'\'', $value));
|
||||||
|
}
|
||||||
|
}
|
21
third_party/Symfony/Component/Yaml/Exception/DumpException.php
vendored
Normal file
21
third_party/Symfony/Component/Yaml/Exception/DumpException.php
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Yaml\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception class thrown when an error occurs during dumping.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class DumpException extends RuntimeException
|
||||||
|
{
|
||||||
|
}
|
21
third_party/Symfony/Component/Yaml/Exception/ExceptionInterface.php
vendored
Normal file
21
third_party/Symfony/Component/Yaml/Exception/ExceptionInterface.php
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Yaml\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception interface for all exceptions thrown by the component.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
interface ExceptionInterface
|
||||||
|
{
|
||||||
|
}
|
146
third_party/Symfony/Component/Yaml/Exception/ParseException.php
vendored
Normal file
146
third_party/Symfony/Component/Yaml/Exception/ParseException.php
vendored
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Yaml\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception class thrown when an error occurs during parsing.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class ParseException extends RuntimeException
|
||||||
|
{
|
||||||
|
private $parsedFile;
|
||||||
|
private $parsedLine;
|
||||||
|
private $snippet;
|
||||||
|
private $rawMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param string $message The error message
|
||||||
|
* @param int $parsedLine The line where the error occurred
|
||||||
|
* @param int $snippet The snippet of code near the problem
|
||||||
|
* @param string $parsedFile The file name where the error occurred
|
||||||
|
* @param \Exception $previous The previous exception
|
||||||
|
*/
|
||||||
|
public function __construct($message, $parsedLine = -1, $snippet = null, $parsedFile = null, \Exception $previous = null)
|
||||||
|
{
|
||||||
|
$this->parsedFile = $parsedFile;
|
||||||
|
$this->parsedLine = $parsedLine;
|
||||||
|
$this->snippet = $snippet;
|
||||||
|
$this->rawMessage = $message;
|
||||||
|
|
||||||
|
$this->updateRepr();
|
||||||
|
|
||||||
|
parent::__construct($this->message, 0, $previous);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the snippet of code near the error.
|
||||||
|
*
|
||||||
|
* @return string The snippet of code
|
||||||
|
*/
|
||||||
|
public function getSnippet()
|
||||||
|
{
|
||||||
|
return $this->snippet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the snippet of code near the error.
|
||||||
|
*
|
||||||
|
* @param string $snippet The code snippet
|
||||||
|
*/
|
||||||
|
public function setSnippet($snippet)
|
||||||
|
{
|
||||||
|
$this->snippet = $snippet;
|
||||||
|
|
||||||
|
$this->updateRepr();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the filename where the error occurred.
|
||||||
|
*
|
||||||
|
* This method returns null if a string is parsed.
|
||||||
|
*
|
||||||
|
* @return string The filename
|
||||||
|
*/
|
||||||
|
public function getParsedFile()
|
||||||
|
{
|
||||||
|
return $this->parsedFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the filename where the error occurred.
|
||||||
|
*
|
||||||
|
* @param string $parsedFile The filename
|
||||||
|
*/
|
||||||
|
public function setParsedFile($parsedFile)
|
||||||
|
{
|
||||||
|
$this->parsedFile = $parsedFile;
|
||||||
|
|
||||||
|
$this->updateRepr();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the line where the error occurred.
|
||||||
|
*
|
||||||
|
* @return int The file line
|
||||||
|
*/
|
||||||
|
public function getParsedLine()
|
||||||
|
{
|
||||||
|
return $this->parsedLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the line where the error occurred.
|
||||||
|
*
|
||||||
|
* @param int $parsedLine The file line
|
||||||
|
*/
|
||||||
|
public function setParsedLine($parsedLine)
|
||||||
|
{
|
||||||
|
$this->parsedLine = $parsedLine;
|
||||||
|
|
||||||
|
$this->updateRepr();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function updateRepr()
|
||||||
|
{
|
||||||
|
$this->message = $this->rawMessage;
|
||||||
|
|
||||||
|
$dot = false;
|
||||||
|
if ('.' === substr($this->message, -1)) {
|
||||||
|
$this->message = substr($this->message, 0, -1);
|
||||||
|
$dot = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $this->parsedFile) {
|
||||||
|
if (PHP_VERSION_ID >= 50400) {
|
||||||
|
$jsonOptions = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
|
||||||
|
} else {
|
||||||
|
$jsonOptions = 0;
|
||||||
|
}
|
||||||
|
$this->message .= sprintf(' in %s', json_encode($this->parsedFile, $jsonOptions));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->parsedLine >= 0) {
|
||||||
|
$this->message .= sprintf(' at line %d', $this->parsedLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->snippet) {
|
||||||
|
$this->message .= sprintf(' (near "%s")', $this->snippet);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($dot) {
|
||||||
|
$this->message .= '.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
third_party/Symfony/Component/Yaml/Exception/RuntimeException.php
vendored
Normal file
21
third_party/Symfony/Component/Yaml/Exception/RuntimeException.php
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Yaml\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception class thrown when an error occurs during parsing.
|
||||||
|
*
|
||||||
|
* @author Romain Neutron <imprec@gmail.com>
|
||||||
|
*/
|
||||||
|
class RuntimeException extends \RuntimeException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
}
|
591
third_party/Symfony/Component/Yaml/Inline.php
vendored
Normal file
591
third_party/Symfony/Component/Yaml/Inline.php
vendored
Normal file
@ -0,0 +1,591 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Yaml;
|
||||||
|
|
||||||
|
use Symfony\Component\Yaml\Exception\ParseException;
|
||||||
|
use Symfony\Component\Yaml\Exception\DumpException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inline implements a YAML parser/dumper for the YAML inline syntax.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class Inline
|
||||||
|
{
|
||||||
|
const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
|
||||||
|
|
||||||
|
private static $exceptionOnInvalidType = false;
|
||||||
|
private static $objectSupport = false;
|
||||||
|
private static $objectForMap = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a YAML string to a PHP array.
|
||||||
|
*
|
||||||
|
* @param string $value A YAML string
|
||||||
|
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
|
||||||
|
* @param bool $objectSupport true if object support is enabled, false otherwise
|
||||||
|
* @param bool $objectForMap true if maps should return a stdClass instead of array()
|
||||||
|
* @param array $references Mapping of variable names to values
|
||||||
|
*
|
||||||
|
* @return array A PHP array representing the YAML string
|
||||||
|
*
|
||||||
|
* @throws ParseException
|
||||||
|
*/
|
||||||
|
public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false, $references = array())
|
||||||
|
{
|
||||||
|
self::$exceptionOnInvalidType = $exceptionOnInvalidType;
|
||||||
|
self::$objectSupport = $objectSupport;
|
||||||
|
self::$objectForMap = $objectForMap;
|
||||||
|
|
||||||
|
$value = trim($value);
|
||||||
|
|
||||||
|
if ('' === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) {
|
||||||
|
$mbEncoding = mb_internal_encoding();
|
||||||
|
mb_internal_encoding('ASCII');
|
||||||
|
}
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
switch ($value[0]) {
|
||||||
|
case '[':
|
||||||
|
$result = self::parseSequence($value, $i, $references);
|
||||||
|
++$i;
|
||||||
|
break;
|
||||||
|
case '{':
|
||||||
|
$result = self::parseMapping($value, $i, $references);
|
||||||
|
++$i;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$result = self::parseScalar($value, null, array('"', "'"), $i, true, $references);
|
||||||
|
}
|
||||||
|
|
||||||
|
// some comments are allowed at the end
|
||||||
|
if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) {
|
||||||
|
throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($mbEncoding)) {
|
||||||
|
mb_internal_encoding($mbEncoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dumps a given PHP variable to a YAML string.
|
||||||
|
*
|
||||||
|
* @param mixed $value The PHP variable to convert
|
||||||
|
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
|
||||||
|
* @param bool $objectSupport true if object support is enabled, false otherwise
|
||||||
|
*
|
||||||
|
* @return string The YAML string representing the PHP array
|
||||||
|
*
|
||||||
|
* @throws DumpException When trying to dump PHP resource
|
||||||
|
*/
|
||||||
|
public static function dump($value, $exceptionOnInvalidType = false, $objectSupport = false)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
case is_resource($value):
|
||||||
|
if ($exceptionOnInvalidType) {
|
||||||
|
throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'null';
|
||||||
|
case is_object($value):
|
||||||
|
if ($objectSupport) {
|
||||||
|
return '!php/object:'.serialize($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($exceptionOnInvalidType) {
|
||||||
|
throw new DumpException('Object support when dumping a YAML file has been disabled.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'null';
|
||||||
|
case is_array($value):
|
||||||
|
return self::dumpArray($value, $exceptionOnInvalidType, $objectSupport);
|
||||||
|
case null === $value:
|
||||||
|
return 'null';
|
||||||
|
case true === $value:
|
||||||
|
return 'true';
|
||||||
|
case false === $value:
|
||||||
|
return 'false';
|
||||||
|
case ctype_digit($value):
|
||||||
|
return is_string($value) ? "'$value'" : (int) $value;
|
||||||
|
case is_numeric($value):
|
||||||
|
$locale = setlocale(LC_NUMERIC, 0);
|
||||||
|
if (false !== $locale) {
|
||||||
|
setlocale(LC_NUMERIC, 'C');
|
||||||
|
}
|
||||||
|
if (is_float($value)) {
|
||||||
|
$repr = (string) $value;
|
||||||
|
if (is_infinite($value)) {
|
||||||
|
$repr = str_ireplace('INF', '.Inf', $repr);
|
||||||
|
} elseif (floor($value) == $value && $repr == $value) {
|
||||||
|
// Preserve float data type since storing a whole number will result in integer value.
|
||||||
|
$repr = '!!float '.$repr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$repr = is_string($value) ? "'$value'" : (string) $value;
|
||||||
|
}
|
||||||
|
if (false !== $locale) {
|
||||||
|
setlocale(LC_NUMERIC, $locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $repr;
|
||||||
|
|
||||||
|
case '' == $value:
|
||||||
|
return "''";
|
||||||
|
case Escaper::requiresDoubleQuoting($value):
|
||||||
|
return Escaper::escapeWithDoubleQuotes($value);
|
||||||
|
case Escaper::requiresSingleQuoting($value):
|
||||||
|
case preg_match(self::getHexRegex(), $value):
|
||||||
|
case preg_match(self::getTimestampRegex(), $value):
|
||||||
|
return Escaper::escapeWithSingleQuotes($value);
|
||||||
|
default:
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if given array is hash or just normal indexed array.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* @param array $value The PHP array to check
|
||||||
|
*
|
||||||
|
* @return bool true if value is hash array, false otherwise
|
||||||
|
*/
|
||||||
|
public static function isHash(array $value)
|
||||||
|
{
|
||||||
|
$expectedKey = 0;
|
||||||
|
|
||||||
|
foreach ($value as $key => $val) {
|
||||||
|
if ($key !== $expectedKey++) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dumps a PHP array to a YAML string.
|
||||||
|
*
|
||||||
|
* @param array $value The PHP array to dump
|
||||||
|
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
|
||||||
|
* @param bool $objectSupport true if object support is enabled, false otherwise
|
||||||
|
*
|
||||||
|
* @return string The YAML string representing the PHP array
|
||||||
|
*/
|
||||||
|
private static function dumpArray($value, $exceptionOnInvalidType, $objectSupport)
|
||||||
|
{
|
||||||
|
// array
|
||||||
|
if ($value && !self::isHash($value)) {
|
||||||
|
$output = array();
|
||||||
|
foreach ($value as $val) {
|
||||||
|
$output[] = self::dump($val, $exceptionOnInvalidType, $objectSupport);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf('[%s]', implode(', ', $output));
|
||||||
|
}
|
||||||
|
|
||||||
|
// hash
|
||||||
|
$output = array();
|
||||||
|
foreach ($value as $key => $val) {
|
||||||
|
$output[] = sprintf('%s: %s', self::dump($key, $exceptionOnInvalidType, $objectSupport), self::dump($val, $exceptionOnInvalidType, $objectSupport));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf('{ %s }', implode(', ', $output));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a scalar to a YAML string.
|
||||||
|
*
|
||||||
|
* @param string $scalar
|
||||||
|
* @param string $delimiters
|
||||||
|
* @param array $stringDelimiters
|
||||||
|
* @param int &$i
|
||||||
|
* @param bool $evaluate
|
||||||
|
* @param array $references
|
||||||
|
*
|
||||||
|
* @return string A YAML string
|
||||||
|
*
|
||||||
|
* @throws ParseException When malformed inline YAML string is parsed
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public static function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true, $references = array())
|
||||||
|
{
|
||||||
|
if (in_array($scalar[$i], $stringDelimiters)) {
|
||||||
|
// quoted scalar
|
||||||
|
$output = self::parseQuotedScalar($scalar, $i);
|
||||||
|
|
||||||
|
if (null !== $delimiters) {
|
||||||
|
$tmp = ltrim(substr($scalar, $i), ' ');
|
||||||
|
if (!in_array($tmp[0], $delimiters)) {
|
||||||
|
throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// "normal" string
|
||||||
|
if (!$delimiters) {
|
||||||
|
$output = substr($scalar, $i);
|
||||||
|
$i += strlen($output);
|
||||||
|
|
||||||
|
// remove comments
|
||||||
|
if (preg_match('/[ \t]+#/', $output, $match, PREG_OFFSET_CAPTURE)) {
|
||||||
|
$output = substr($output, 0, $match[0][1]);
|
||||||
|
}
|
||||||
|
} elseif (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) {
|
||||||
|
$output = $match[1];
|
||||||
|
$i += strlen($output);
|
||||||
|
} else {
|
||||||
|
throw new ParseException(sprintf('Malformed inline YAML string (%s).', $scalar));
|
||||||
|
}
|
||||||
|
|
||||||
|
// a non-quoted string cannot start with @ or ` (reserved) nor with a scalar indicator (| or >)
|
||||||
|
if ($output && ('@' === $output[0] || '`' === $output[0] || '|' === $output[0] || '>' === $output[0])) {
|
||||||
|
@trigger_error(sprintf('Not quoting the scalar "%s" starting with "%s" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $output, $output[0]), E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
// to be thrown in 3.0
|
||||||
|
// throw new ParseException(sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($evaluate) {
|
||||||
|
$output = self::evaluateScalar($output, $references);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a quoted scalar to YAML.
|
||||||
|
*
|
||||||
|
* @param string $scalar
|
||||||
|
* @param int &$i
|
||||||
|
*
|
||||||
|
* @return string A YAML string
|
||||||
|
*
|
||||||
|
* @throws ParseException When malformed inline YAML string is parsed
|
||||||
|
*/
|
||||||
|
private static function parseQuotedScalar($scalar, &$i)
|
||||||
|
{
|
||||||
|
if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
|
||||||
|
throw new ParseException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$output = substr($match[0], 1, strlen($match[0]) - 2);
|
||||||
|
|
||||||
|
$unescaper = new Unescaper();
|
||||||
|
if ('"' == $scalar[$i]) {
|
||||||
|
$output = $unescaper->unescapeDoubleQuotedString($output);
|
||||||
|
} else {
|
||||||
|
$output = $unescaper->unescapeSingleQuotedString($output);
|
||||||
|
}
|
||||||
|
|
||||||
|
$i += strlen($match[0]);
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a sequence to a YAML string.
|
||||||
|
*
|
||||||
|
* @param string $sequence
|
||||||
|
* @param int &$i
|
||||||
|
* @param array $references
|
||||||
|
*
|
||||||
|
* @return string A YAML string
|
||||||
|
*
|
||||||
|
* @throws ParseException When malformed inline YAML string is parsed
|
||||||
|
*/
|
||||||
|
private static function parseSequence($sequence, &$i = 0, $references = array())
|
||||||
|
{
|
||||||
|
$output = array();
|
||||||
|
$len = strlen($sequence);
|
||||||
|
++$i;
|
||||||
|
|
||||||
|
// [foo, bar, ...]
|
||||||
|
while ($i < $len) {
|
||||||
|
switch ($sequence[$i]) {
|
||||||
|
case '[':
|
||||||
|
// nested sequence
|
||||||
|
$output[] = self::parseSequence($sequence, $i, $references);
|
||||||
|
break;
|
||||||
|
case '{':
|
||||||
|
// nested mapping
|
||||||
|
$output[] = self::parseMapping($sequence, $i, $references);
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
return $output;
|
||||||
|
case ',':
|
||||||
|
case ' ':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$isQuoted = in_array($sequence[$i], array('"', "'"));
|
||||||
|
$value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i, true, $references);
|
||||||
|
|
||||||
|
// the value can be an array if a reference has been resolved to an array var
|
||||||
|
if (!is_array($value) && !$isQuoted && false !== strpos($value, ': ')) {
|
||||||
|
// embedded mapping?
|
||||||
|
try {
|
||||||
|
$pos = 0;
|
||||||
|
$value = self::parseMapping('{'.$value.'}', $pos, $references);
|
||||||
|
} catch (\InvalidArgumentException $e) {
|
||||||
|
// no, it's not
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$output[] = $value;
|
||||||
|
|
||||||
|
--$i;
|
||||||
|
}
|
||||||
|
|
||||||
|
++$i;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ParseException(sprintf('Malformed inline YAML string %s', $sequence));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a mapping to a YAML string.
|
||||||
|
*
|
||||||
|
* @param string $mapping
|
||||||
|
* @param int &$i
|
||||||
|
* @param array $references
|
||||||
|
*
|
||||||
|
* @return string A YAML string
|
||||||
|
*
|
||||||
|
* @throws ParseException When malformed inline YAML string is parsed
|
||||||
|
*/
|
||||||
|
private static function parseMapping($mapping, &$i = 0, $references = array())
|
||||||
|
{
|
||||||
|
$output = array();
|
||||||
|
$len = strlen($mapping);
|
||||||
|
++$i;
|
||||||
|
|
||||||
|
// {foo: bar, bar:foo, ...}
|
||||||
|
while ($i < $len) {
|
||||||
|
switch ($mapping[$i]) {
|
||||||
|
case ' ':
|
||||||
|
case ',':
|
||||||
|
++$i;
|
||||||
|
continue 2;
|
||||||
|
case '}':
|
||||||
|
if (self::$objectForMap) {
|
||||||
|
return (object) $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
// key
|
||||||
|
$key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false);
|
||||||
|
|
||||||
|
// value
|
||||||
|
$done = false;
|
||||||
|
|
||||||
|
while ($i < $len) {
|
||||||
|
switch ($mapping[$i]) {
|
||||||
|
case '[':
|
||||||
|
// nested sequence
|
||||||
|
$value = self::parseSequence($mapping, $i, $references);
|
||||||
|
// Spec: Keys MUST be unique; first one wins.
|
||||||
|
// Parser cannot abort this mapping earlier, since lines
|
||||||
|
// are processed sequentially.
|
||||||
|
if (!isset($output[$key])) {
|
||||||
|
$output[$key] = $value;
|
||||||
|
}
|
||||||
|
$done = true;
|
||||||
|
break;
|
||||||
|
case '{':
|
||||||
|
// nested mapping
|
||||||
|
$value = self::parseMapping($mapping, $i, $references);
|
||||||
|
// Spec: Keys MUST be unique; first one wins.
|
||||||
|
// Parser cannot abort this mapping earlier, since lines
|
||||||
|
// are processed sequentially.
|
||||||
|
if (!isset($output[$key])) {
|
||||||
|
$output[$key] = $value;
|
||||||
|
}
|
||||||
|
$done = true;
|
||||||
|
break;
|
||||||
|
case ':':
|
||||||
|
case ' ':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$value = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i, true, $references);
|
||||||
|
// Spec: Keys MUST be unique; first one wins.
|
||||||
|
// Parser cannot abort this mapping earlier, since lines
|
||||||
|
// are processed sequentially.
|
||||||
|
if (!isset($output[$key])) {
|
||||||
|
$output[$key] = $value;
|
||||||
|
}
|
||||||
|
$done = true;
|
||||||
|
--$i;
|
||||||
|
}
|
||||||
|
|
||||||
|
++$i;
|
||||||
|
|
||||||
|
if ($done) {
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ParseException(sprintf('Malformed inline YAML string %s', $mapping));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates scalars and replaces magic values.
|
||||||
|
*
|
||||||
|
* @param string $scalar
|
||||||
|
* @param array $references
|
||||||
|
*
|
||||||
|
* @return string A YAML string
|
||||||
|
*
|
||||||
|
* @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved
|
||||||
|
*/
|
||||||
|
private static function evaluateScalar($scalar, $references = array())
|
||||||
|
{
|
||||||
|
$scalar = trim($scalar);
|
||||||
|
$scalarLower = strtolower($scalar);
|
||||||
|
|
||||||
|
if (0 === strpos($scalar, '*')) {
|
||||||
|
if (false !== $pos = strpos($scalar, '#')) {
|
||||||
|
$value = substr($scalar, 1, $pos - 2);
|
||||||
|
} else {
|
||||||
|
$value = substr($scalar, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// an unquoted *
|
||||||
|
if (false === $value || '' === $value) {
|
||||||
|
throw new ParseException('A reference must contain at least one character.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!array_key_exists($value, $references)) {
|
||||||
|
throw new ParseException(sprintf('Reference "%s" does not exist.', $value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $references[$value];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
case 'null' === $scalarLower:
|
||||||
|
case '' === $scalar:
|
||||||
|
case '~' === $scalar:
|
||||||
|
return null;
|
||||||
|
case 'true' === $scalarLower:
|
||||||
|
return true;
|
||||||
|
case 'false' === $scalarLower:
|
||||||
|
return false;
|
||||||
|
// Optimise for returning strings.
|
||||||
|
case $scalar[0] === '+' || $scalar[0] === '-' || $scalar[0] === '.' || $scalar[0] === '!' || is_numeric($scalar[0]):
|
||||||
|
switch (true) {
|
||||||
|
case 0 === strpos($scalar, '!str'):
|
||||||
|
return (string) substr($scalar, 5);
|
||||||
|
case 0 === strpos($scalar, '! '):
|
||||||
|
return (int) self::parseScalar(substr($scalar, 2));
|
||||||
|
case 0 === strpos($scalar, '!php/object:'):
|
||||||
|
if (self::$objectSupport) {
|
||||||
|
return unserialize(substr($scalar, 12));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self::$exceptionOnInvalidType) {
|
||||||
|
throw new ParseException('Object support when parsing a YAML file has been disabled.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
case 0 === strpos($scalar, '!!php/object:'):
|
||||||
|
if (self::$objectSupport) {
|
||||||
|
return unserialize(substr($scalar, 13));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self::$exceptionOnInvalidType) {
|
||||||
|
throw new ParseException('Object support when parsing a YAML file has been disabled.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
case 0 === strpos($scalar, '!!float '):
|
||||||
|
return (float) substr($scalar, 8);
|
||||||
|
case ctype_digit($scalar):
|
||||||
|
$raw = $scalar;
|
||||||
|
$cast = (int) $scalar;
|
||||||
|
|
||||||
|
return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
|
||||||
|
case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)):
|
||||||
|
$raw = $scalar;
|
||||||
|
$cast = (int) $scalar;
|
||||||
|
|
||||||
|
return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw);
|
||||||
|
case is_numeric($scalar):
|
||||||
|
case preg_match(self::getHexRegex(), $scalar):
|
||||||
|
return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar;
|
||||||
|
case '.inf' === $scalarLower:
|
||||||
|
case '.nan' === $scalarLower:
|
||||||
|
return -log(0);
|
||||||
|
case '-.inf' === $scalarLower:
|
||||||
|
return log(0);
|
||||||
|
case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
|
||||||
|
return (float) str_replace(',', '', $scalar);
|
||||||
|
case preg_match(self::getTimestampRegex(), $scalar):
|
||||||
|
$timeZone = date_default_timezone_get();
|
||||||
|
date_default_timezone_set('UTC');
|
||||||
|
$time = strtotime($scalar);
|
||||||
|
date_default_timezone_set($timeZone);
|
||||||
|
|
||||||
|
return $time;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return (string) $scalar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a regex that matches a YAML date.
|
||||||
|
*
|
||||||
|
* @return string The regular expression
|
||||||
|
*
|
||||||
|
* @see http://www.yaml.org/spec/1.2/spec.html#id2761573
|
||||||
|
*/
|
||||||
|
private static function getTimestampRegex()
|
||||||
|
{
|
||||||
|
return <<<EOF
|
||||||
|
~^
|
||||||
|
(?P<year>[0-9][0-9][0-9][0-9])
|
||||||
|
-(?P<month>[0-9][0-9]?)
|
||||||
|
-(?P<day>[0-9][0-9]?)
|
||||||
|
(?:(?:[Tt]|[ \t]+)
|
||||||
|
(?P<hour>[0-9][0-9]?)
|
||||||
|
:(?P<minute>[0-9][0-9])
|
||||||
|
:(?P<second>[0-9][0-9])
|
||||||
|
(?:\.(?P<fraction>[0-9]*))?
|
||||||
|
(?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
|
||||||
|
(?::(?P<tz_minute>[0-9][0-9]))?))?)?
|
||||||
|
$~x
|
||||||
|
EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a regex that matches a YAML number in hexadecimal notation.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function getHexRegex()
|
||||||
|
{
|
||||||
|
return '~^0x[0-9a-f]++$~i';
|
||||||
|
}
|
||||||
|
}
|
19
third_party/Symfony/Component/Yaml/LICENSE
vendored
Normal file
19
third_party/Symfony/Component/Yaml/LICENSE
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2004-2016 Fabien Potencier
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished
|
||||||
|
to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
821
third_party/Symfony/Component/Yaml/Parser.php
vendored
Normal file
821
third_party/Symfony/Component/Yaml/Parser.php
vendored
Normal file
@ -0,0 +1,821 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Yaml;
|
||||||
|
|
||||||
|
use Symfony\Component\Yaml\Exception\ParseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser parses YAML strings to convert them to PHP arrays.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class Parser
|
||||||
|
{
|
||||||
|
const BLOCK_SCALAR_HEADER_PATTERN = '(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?';
|
||||||
|
// BC - wrongly named
|
||||||
|
const FOLDED_SCALAR_PATTERN = self::BLOCK_SCALAR_HEADER_PATTERN;
|
||||||
|
|
||||||
|
private $offset = 0;
|
||||||
|
private $totalNumberOfLines;
|
||||||
|
private $lines = array();
|
||||||
|
private $currentLineNb = -1;
|
||||||
|
private $currentLine = '';
|
||||||
|
private $refs = array();
|
||||||
|
private $skippedLineNumbers = array();
|
||||||
|
private $locallySkippedLineNumbers = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param int $offset The offset of YAML document (used for line numbers in error messages)
|
||||||
|
* @param int|null $totalNumberOfLines The overall number of lines being parsed
|
||||||
|
* @param int[] $skippedLineNumbers Number of comment lines that have been skipped by the parser
|
||||||
|
*/
|
||||||
|
public function __construct($offset = 0, $totalNumberOfLines = null, array $skippedLineNumbers = array())
|
||||||
|
{
|
||||||
|
$this->offset = $offset;
|
||||||
|
$this->totalNumberOfLines = $totalNumberOfLines;
|
||||||
|
$this->skippedLineNumbers = $skippedLineNumbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a YAML string to a PHP value.
|
||||||
|
*
|
||||||
|
* @param string $value A YAML string
|
||||||
|
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
|
||||||
|
* @param bool $objectSupport true if object support is enabled, false otherwise
|
||||||
|
* @param bool $objectForMap true if maps should return a stdClass instead of array()
|
||||||
|
*
|
||||||
|
* @return mixed A PHP value
|
||||||
|
*
|
||||||
|
* @throws ParseException If the YAML is not valid
|
||||||
|
*/
|
||||||
|
public function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false)
|
||||||
|
{
|
||||||
|
if (!preg_match('//u', $value)) {
|
||||||
|
throw new ParseException('The YAML value does not appear to be valid UTF-8.');
|
||||||
|
}
|
||||||
|
$this->currentLineNb = -1;
|
||||||
|
$this->currentLine = '';
|
||||||
|
$value = $this->cleanup($value);
|
||||||
|
$this->lines = explode("\n", $value);
|
||||||
|
|
||||||
|
if (null === $this->totalNumberOfLines) {
|
||||||
|
$this->totalNumberOfLines = count($this->lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) {
|
||||||
|
$mbEncoding = mb_internal_encoding();
|
||||||
|
mb_internal_encoding('UTF-8');
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
$context = null;
|
||||||
|
$allowOverwrite = false;
|
||||||
|
while ($this->moveToNextLine()) {
|
||||||
|
if ($this->isCurrentLineEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tab?
|
||||||
|
if ("\t" === $this->currentLine[0]) {
|
||||||
|
throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
$isRef = $mergeNode = false;
|
||||||
|
if (preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) {
|
||||||
|
if ($context && 'mapping' == $context) {
|
||||||
|
throw new ParseException('You cannot define a sequence item when in a mapping', $this->getRealCurrentLineNb() + 1, $this->currentLine);
|
||||||
|
}
|
||||||
|
$context = 'sequence';
|
||||||
|
|
||||||
|
if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
|
||||||
|
$isRef = $matches['ref'];
|
||||||
|
$values['value'] = $matches['value'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// array
|
||||||
|
if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
|
||||||
|
$data[] = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport, $objectForMap);
|
||||||
|
} else {
|
||||||
|
if (isset($values['leadspaces'])
|
||||||
|
&& preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $values['value'], $matches)
|
||||||
|
) {
|
||||||
|
// this is a compact notation element, add to next block and parse
|
||||||
|
$block = $values['value'];
|
||||||
|
if ($this->isNextLineIndented()) {
|
||||||
|
$block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + strlen($values['leadspaces']) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data[] = $this->parseBlock($this->getRealCurrentLineNb(), $block, $exceptionOnInvalidType, $objectSupport, $objectForMap);
|
||||||
|
} else {
|
||||||
|
$data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($isRef) {
|
||||||
|
$this->refs[$isRef] = end($data);
|
||||||
|
}
|
||||||
|
} elseif (preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values) && (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))) {
|
||||||
|
if ($context && 'sequence' == $context) {
|
||||||
|
throw new ParseException('You cannot define a mapping item when in a sequence', $this->currentLineNb + 1, $this->currentLine);
|
||||||
|
}
|
||||||
|
$context = 'mapping';
|
||||||
|
|
||||||
|
// force correct settings
|
||||||
|
Inline::parse(null, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
|
||||||
|
try {
|
||||||
|
$key = Inline::parseScalar($values['key']);
|
||||||
|
} catch (ParseException $e) {
|
||||||
|
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
|
||||||
|
$e->setSnippet($this->currentLine);
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert float keys to strings, to avoid being converted to integers by PHP
|
||||||
|
if (is_float($key)) {
|
||||||
|
$key = (string) $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('<<' === $key) {
|
||||||
|
$mergeNode = true;
|
||||||
|
$allowOverwrite = true;
|
||||||
|
if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
|
||||||
|
$refName = substr($values['value'], 1);
|
||||||
|
if (!array_key_exists($refName, $this->refs)) {
|
||||||
|
throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
$refValue = $this->refs[$refName];
|
||||||
|
|
||||||
|
if (!is_array($refValue)) {
|
||||||
|
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($refValue as $key => $value) {
|
||||||
|
if (!isset($data[$key])) {
|
||||||
|
$data[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isset($values['value']) && $values['value'] !== '') {
|
||||||
|
$value = $values['value'];
|
||||||
|
} else {
|
||||||
|
$value = $this->getNextEmbedBlock();
|
||||||
|
}
|
||||||
|
$parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $exceptionOnInvalidType, $objectSupport, $objectForMap);
|
||||||
|
|
||||||
|
if (!is_array($parsed)) {
|
||||||
|
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($parsed[0])) {
|
||||||
|
// If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes
|
||||||
|
// 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.
|
||||||
|
foreach ($parsed as $parsedItem) {
|
||||||
|
if (!is_array($parsedItem)) {
|
||||||
|
throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($parsedItem as $key => $value) {
|
||||||
|
if (!isset($data[$key])) {
|
||||||
|
$data[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the
|
||||||
|
// current mapping, unless the key already exists in it.
|
||||||
|
foreach ($parsed as $key => $value) {
|
||||||
|
if (!isset($data[$key])) {
|
||||||
|
$data[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
|
||||||
|
$isRef = $matches['ref'];
|
||||||
|
$values['value'] = $matches['value'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($mergeNode) {
|
||||||
|
// Merge keys
|
||||||
|
} elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
|
||||||
|
// hash
|
||||||
|
// if next line is less indented or equal, then it means that the current value is null
|
||||||
|
if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
|
||||||
|
// Spec: Keys MUST be unique; first one wins.
|
||||||
|
// But overwriting is allowed when a merge node is used in current block.
|
||||||
|
if ($allowOverwrite || !isset($data[$key])) {
|
||||||
|
$data[$key] = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport, $objectForMap);
|
||||||
|
// Spec: Keys MUST be unique; first one wins.
|
||||||
|
// But overwriting is allowed when a merge node is used in current block.
|
||||||
|
if ($allowOverwrite || !isset($data[$key])) {
|
||||||
|
$data[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context);
|
||||||
|
// Spec: Keys MUST be unique; first one wins.
|
||||||
|
// But overwriting is allowed when a merge node is used in current block.
|
||||||
|
if ($allowOverwrite || !isset($data[$key])) {
|
||||||
|
$data[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($isRef) {
|
||||||
|
$this->refs[$isRef] = $data[$key];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// multiple documents are not supported
|
||||||
|
if ('---' === $this->currentLine) {
|
||||||
|
throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1-liner optionally followed by newline(s)
|
||||||
|
if (is_string($value) && $this->lines[0] === trim($value)) {
|
||||||
|
try {
|
||||||
|
$value = Inline::parse($this->lines[0], $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
|
||||||
|
} catch (ParseException $e) {
|
||||||
|
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
|
||||||
|
$e->setSnippet($this->currentLine);
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($mbEncoding)) {
|
||||||
|
mb_internal_encoding($mbEncoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (preg_last_error()) {
|
||||||
|
case PREG_INTERNAL_ERROR:
|
||||||
|
$error = 'Internal PCRE error.';
|
||||||
|
break;
|
||||||
|
case PREG_BACKTRACK_LIMIT_ERROR:
|
||||||
|
$error = 'pcre.backtrack_limit reached.';
|
||||||
|
break;
|
||||||
|
case PREG_RECURSION_LIMIT_ERROR:
|
||||||
|
$error = 'pcre.recursion_limit reached.';
|
||||||
|
break;
|
||||||
|
case PREG_BAD_UTF8_ERROR:
|
||||||
|
$error = 'Malformed UTF-8 data.';
|
||||||
|
break;
|
||||||
|
case PREG_BAD_UTF8_OFFSET_ERROR:
|
||||||
|
$error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$error = 'Unable to parse.';
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ParseException($error, $this->getRealCurrentLineNb() + 1, $this->currentLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($mbEncoding)) {
|
||||||
|
mb_internal_encoding($mbEncoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($objectForMap && !is_object($data) && 'mapping' === $context) {
|
||||||
|
$object = new \stdClass();
|
||||||
|
|
||||||
|
foreach ($data as $key => $value) {
|
||||||
|
$object->$key = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $object;
|
||||||
|
}
|
||||||
|
|
||||||
|
return empty($data) ? null : $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parseBlock($offset, $yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap)
|
||||||
|
{
|
||||||
|
$skippedLineNumbers = $this->skippedLineNumbers;
|
||||||
|
|
||||||
|
foreach ($this->locallySkippedLineNumbers as $lineNumber) {
|
||||||
|
if ($lineNumber < $offset) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$skippedLineNumbers[] = $lineNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parser = new self($offset, $this->totalNumberOfLines, $skippedLineNumbers);
|
||||||
|
$parser->refs = &$this->refs;
|
||||||
|
|
||||||
|
return $parser->parse($yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current line number (takes the offset into account).
|
||||||
|
*
|
||||||
|
* @return int The current line number
|
||||||
|
*/
|
||||||
|
private function getRealCurrentLineNb()
|
||||||
|
{
|
||||||
|
$realCurrentLineNumber = $this->currentLineNb + $this->offset;
|
||||||
|
|
||||||
|
foreach ($this->skippedLineNumbers as $skippedLineNumber) {
|
||||||
|
if ($skippedLineNumber > $realCurrentLineNumber) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++$realCurrentLineNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $realCurrentLineNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current line indentation.
|
||||||
|
*
|
||||||
|
* @return int The current line indentation
|
||||||
|
*/
|
||||||
|
private function getCurrentLineIndentation()
|
||||||
|
{
|
||||||
|
return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the next embed block of YAML.
|
||||||
|
*
|
||||||
|
* @param int $indentation The indent level at which the block is to be read, or null for default
|
||||||
|
* @param bool $inSequence True if the enclosing data structure is a sequence
|
||||||
|
*
|
||||||
|
* @return string A YAML string
|
||||||
|
*
|
||||||
|
* @throws ParseException When indentation problem are detected
|
||||||
|
*/
|
||||||
|
private function getNextEmbedBlock($indentation = null, $inSequence = false)
|
||||||
|
{
|
||||||
|
$oldLineIndentation = $this->getCurrentLineIndentation();
|
||||||
|
$blockScalarIndentations = array();
|
||||||
|
|
||||||
|
if ($this->isBlockScalarHeader()) {
|
||||||
|
$blockScalarIndentations[] = $this->getCurrentLineIndentation();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->moveToNextLine()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $indentation) {
|
||||||
|
$newIndent = $this->getCurrentLineIndentation();
|
||||||
|
|
||||||
|
$unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem();
|
||||||
|
|
||||||
|
if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) {
|
||||||
|
throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$newIndent = $indentation;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
if ($this->getCurrentLineIndentation() >= $newIndent) {
|
||||||
|
$data[] = substr($this->currentLine, $newIndent);
|
||||||
|
} else {
|
||||||
|
$this->moveToPreviousLine();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($inSequence && $oldLineIndentation === $newIndent && isset($data[0][0]) && '-' === $data[0][0]) {
|
||||||
|
// the previous line contained a dash but no item content, this line is a sequence item with the same indentation
|
||||||
|
// and therefore no nested list or mapping
|
||||||
|
$this->moveToPreviousLine();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$isItUnindentedCollection = $this->isStringUnIndentedCollectionItem();
|
||||||
|
|
||||||
|
if (empty($blockScalarIndentations) && $this->isBlockScalarHeader()) {
|
||||||
|
$blockScalarIndentations[] = $this->getCurrentLineIndentation();
|
||||||
|
}
|
||||||
|
|
||||||
|
$previousLineIndentation = $this->getCurrentLineIndentation();
|
||||||
|
|
||||||
|
while ($this->moveToNextLine()) {
|
||||||
|
$indent = $this->getCurrentLineIndentation();
|
||||||
|
|
||||||
|
// terminate all block scalars that are more indented than the current line
|
||||||
|
if (!empty($blockScalarIndentations) && $indent < $previousLineIndentation && trim($this->currentLine) !== '') {
|
||||||
|
foreach ($blockScalarIndentations as $key => $blockScalarIndentation) {
|
||||||
|
if ($blockScalarIndentation >= $this->getCurrentLineIndentation()) {
|
||||||
|
unset($blockScalarIndentations[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($blockScalarIndentations) && !$this->isCurrentLineComment() && $this->isBlockScalarHeader()) {
|
||||||
|
$blockScalarIndentations[] = $this->getCurrentLineIndentation();
|
||||||
|
}
|
||||||
|
|
||||||
|
$previousLineIndentation = $indent;
|
||||||
|
|
||||||
|
if ($isItUnindentedCollection && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) {
|
||||||
|
$this->moveToPreviousLine();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->isCurrentLineBlank()) {
|
||||||
|
$data[] = substr($this->currentLine, $newIndent);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we ignore "comment" lines only when we are not inside a scalar block
|
||||||
|
if (empty($blockScalarIndentations) && $this->isCurrentLineComment()) {
|
||||||
|
// remember ignored comment lines (they are used later in nested
|
||||||
|
// parser calls to determine real line numbers)
|
||||||
|
//
|
||||||
|
// CAUTION: beware to not populate the global property here as it
|
||||||
|
// will otherwise influence the getRealCurrentLineNb() call here
|
||||||
|
// for consecutive comment lines and subsequent embedded blocks
|
||||||
|
$this->locallySkippedLineNumbers[] = $this->getRealCurrentLineNb();
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($indent >= $newIndent) {
|
||||||
|
$data[] = substr($this->currentLine, $newIndent);
|
||||||
|
} elseif (0 == $indent) {
|
||||||
|
$this->moveToPreviousLine();
|
||||||
|
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode("\n", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the parser to the next line.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function moveToNextLine()
|
||||||
|
{
|
||||||
|
if ($this->currentLineNb >= count($this->lines) - 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->currentLine = $this->lines[++$this->currentLineNb];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the parser to the previous line.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function moveToPreviousLine()
|
||||||
|
{
|
||||||
|
if ($this->currentLineNb < 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->currentLine = $this->lines[--$this->currentLineNb];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a YAML value.
|
||||||
|
*
|
||||||
|
* @param string $value A YAML value
|
||||||
|
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
|
||||||
|
* @param bool $objectSupport True if object support is enabled, false otherwise
|
||||||
|
* @param bool $objectForMap true if maps should return a stdClass instead of array()
|
||||||
|
* @param string $context The parser context (either sequence or mapping)
|
||||||
|
*
|
||||||
|
* @return mixed A PHP value
|
||||||
|
*
|
||||||
|
* @throws ParseException When reference does not exist
|
||||||
|
*/
|
||||||
|
private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $context)
|
||||||
|
{
|
||||||
|
if (0 === strpos($value, '*')) {
|
||||||
|
if (false !== $pos = strpos($value, '#')) {
|
||||||
|
$value = substr($value, 1, $pos - 2);
|
||||||
|
} else {
|
||||||
|
$value = substr($value, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!array_key_exists($value, $this->refs)) {
|
||||||
|
throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->refs[$value];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('/^'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) {
|
||||||
|
$modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';
|
||||||
|
|
||||||
|
return $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$parsedValue = Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
|
||||||
|
|
||||||
|
if ('mapping' === $context && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) {
|
||||||
|
@trigger_error(sprintf('Using a colon in the unquoted mapping value "%s" in line %d is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $value, $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
// to be thrown in 3.0
|
||||||
|
// throw new ParseException('A colon cannot be used in an unquoted mapping value.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $parsedValue;
|
||||||
|
} catch (ParseException $e) {
|
||||||
|
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
|
||||||
|
$e->setSnippet($this->currentLine);
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a block scalar.
|
||||||
|
*
|
||||||
|
* @param string $style The style indicator that was used to begin this block scalar (| or >)
|
||||||
|
* @param string $chomping The chomping indicator that was used to begin this block scalar (+ or -)
|
||||||
|
* @param int $indentation The indentation indicator that was used to begin this block scalar
|
||||||
|
*
|
||||||
|
* @return string The text value
|
||||||
|
*/
|
||||||
|
private function parseBlockScalar($style, $chomping = '', $indentation = 0)
|
||||||
|
{
|
||||||
|
$notEOF = $this->moveToNextLine();
|
||||||
|
if (!$notEOF) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$isCurrentLineBlank = $this->isCurrentLineBlank();
|
||||||
|
$blockLines = array();
|
||||||
|
|
||||||
|
// leading blank lines are consumed before determining indentation
|
||||||
|
while ($notEOF && $isCurrentLineBlank) {
|
||||||
|
// newline only if not EOF
|
||||||
|
if ($notEOF = $this->moveToNextLine()) {
|
||||||
|
$blockLines[] = '';
|
||||||
|
$isCurrentLineBlank = $this->isCurrentLineBlank();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine indentation if not specified
|
||||||
|
if (0 === $indentation) {
|
||||||
|
if (preg_match('/^ +/', $this->currentLine, $matches)) {
|
||||||
|
$indentation = strlen($matches[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($indentation > 0) {
|
||||||
|
$pattern = sprintf('/^ {%d}(.*)$/', $indentation);
|
||||||
|
|
||||||
|
while (
|
||||||
|
$notEOF && (
|
||||||
|
$isCurrentLineBlank ||
|
||||||
|
preg_match($pattern, $this->currentLine, $matches)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if ($isCurrentLineBlank && strlen($this->currentLine) > $indentation) {
|
||||||
|
$blockLines[] = substr($this->currentLine, $indentation);
|
||||||
|
} elseif ($isCurrentLineBlank) {
|
||||||
|
$blockLines[] = '';
|
||||||
|
} else {
|
||||||
|
$blockLines[] = $matches[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// newline only if not EOF
|
||||||
|
if ($notEOF = $this->moveToNextLine()) {
|
||||||
|
$isCurrentLineBlank = $this->isCurrentLineBlank();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif ($notEOF) {
|
||||||
|
$blockLines[] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($notEOF) {
|
||||||
|
$blockLines[] = '';
|
||||||
|
$this->moveToPreviousLine();
|
||||||
|
} elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) {
|
||||||
|
$blockLines[] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// folded style
|
||||||
|
if ('>' === $style) {
|
||||||
|
$text = '';
|
||||||
|
$previousLineIndented = false;
|
||||||
|
$previousLineBlank = false;
|
||||||
|
|
||||||
|
for ($i = 0; $i < count($blockLines); ++$i) {
|
||||||
|
if ('' === $blockLines[$i]) {
|
||||||
|
$text .= "\n";
|
||||||
|
$previousLineIndented = false;
|
||||||
|
$previousLineBlank = true;
|
||||||
|
} elseif (' ' === $blockLines[$i][0]) {
|
||||||
|
$text .= "\n".$blockLines[$i];
|
||||||
|
$previousLineIndented = true;
|
||||||
|
$previousLineBlank = false;
|
||||||
|
} elseif ($previousLineIndented) {
|
||||||
|
$text .= "\n".$blockLines[$i];
|
||||||
|
$previousLineIndented = false;
|
||||||
|
$previousLineBlank = false;
|
||||||
|
} elseif ($previousLineBlank || 0 === $i) {
|
||||||
|
$text .= $blockLines[$i];
|
||||||
|
$previousLineIndented = false;
|
||||||
|
$previousLineBlank = false;
|
||||||
|
} else {
|
||||||
|
$text .= ' '.$blockLines[$i];
|
||||||
|
$previousLineIndented = false;
|
||||||
|
$previousLineBlank = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$text = implode("\n", $blockLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
// deal with trailing newlines
|
||||||
|
if ('' === $chomping) {
|
||||||
|
$text = preg_replace('/\n+$/', "\n", $text);
|
||||||
|
} elseif ('-' === $chomping) {
|
||||||
|
$text = preg_replace('/\n+$/', '', $text);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the next line is indented.
|
||||||
|
*
|
||||||
|
* @return bool Returns true if the next line is indented, false otherwise
|
||||||
|
*/
|
||||||
|
private function isNextLineIndented()
|
||||||
|
{
|
||||||
|
$currentIndentation = $this->getCurrentLineIndentation();
|
||||||
|
$EOF = !$this->moveToNextLine();
|
||||||
|
|
||||||
|
while (!$EOF && $this->isCurrentLineEmpty()) {
|
||||||
|
$EOF = !$this->moveToNextLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($EOF) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret = false;
|
||||||
|
if ($this->getCurrentLineIndentation() > $currentIndentation) {
|
||||||
|
$ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->moveToPreviousLine();
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the current line is blank or if it is a comment line.
|
||||||
|
*
|
||||||
|
* @return bool Returns true if the current line is empty or if it is a comment line, false otherwise
|
||||||
|
*/
|
||||||
|
private function isCurrentLineEmpty()
|
||||||
|
{
|
||||||
|
return $this->isCurrentLineBlank() || $this->isCurrentLineComment();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the current line is blank.
|
||||||
|
*
|
||||||
|
* @return bool Returns true if the current line is blank, false otherwise
|
||||||
|
*/
|
||||||
|
private function isCurrentLineBlank()
|
||||||
|
{
|
||||||
|
return '' == trim($this->currentLine, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the current line is a comment line.
|
||||||
|
*
|
||||||
|
* @return bool Returns true if the current line is a comment line, false otherwise
|
||||||
|
*/
|
||||||
|
private function isCurrentLineComment()
|
||||||
|
{
|
||||||
|
//checking explicitly the first char of the trim is faster than loops or strpos
|
||||||
|
$ltrimmedLine = ltrim($this->currentLine, ' ');
|
||||||
|
|
||||||
|
return '' !== $ltrimmedLine && $ltrimmedLine[0] === '#';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isCurrentLineLastLineInDocument()
|
||||||
|
{
|
||||||
|
return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanups a YAML string to be parsed.
|
||||||
|
*
|
||||||
|
* @param string $value The input YAML string
|
||||||
|
*
|
||||||
|
* @return string A cleaned up YAML string
|
||||||
|
*/
|
||||||
|
private function cleanup($value)
|
||||||
|
{
|
||||||
|
$value = str_replace(array("\r\n", "\r"), "\n", $value);
|
||||||
|
|
||||||
|
// strip YAML header
|
||||||
|
$count = 0;
|
||||||
|
$value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u', '', $value, -1, $count);
|
||||||
|
$this->offset += $count;
|
||||||
|
|
||||||
|
// remove leading comments
|
||||||
|
$trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
|
||||||
|
if ($count == 1) {
|
||||||
|
// items have been removed, update the offset
|
||||||
|
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
|
||||||
|
$value = $trimmedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove start of the document marker (---)
|
||||||
|
$trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
|
||||||
|
if ($count == 1) {
|
||||||
|
// items have been removed, update the offset
|
||||||
|
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
|
||||||
|
$value = $trimmedValue;
|
||||||
|
|
||||||
|
// remove end of the document marker (...)
|
||||||
|
$value = preg_replace('#\.\.\.\s*$#', '', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the next line starts unindented collection.
|
||||||
|
*
|
||||||
|
* @return bool Returns true if the next line starts unindented collection, false otherwise
|
||||||
|
*/
|
||||||
|
private function isNextLineUnIndentedCollection()
|
||||||
|
{
|
||||||
|
$currentIndentation = $this->getCurrentLineIndentation();
|
||||||
|
$notEOF = $this->moveToNextLine();
|
||||||
|
|
||||||
|
while ($notEOF && $this->isCurrentLineEmpty()) {
|
||||||
|
$notEOF = $this->moveToNextLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false === $notEOF) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret = false;
|
||||||
|
if (
|
||||||
|
$this->getCurrentLineIndentation() == $currentIndentation
|
||||||
|
&&
|
||||||
|
$this->isStringUnIndentedCollectionItem()
|
||||||
|
) {
|
||||||
|
$ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->moveToPreviousLine();
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the string is un-indented collection item.
|
||||||
|
*
|
||||||
|
* @return bool Returns true if the string is un-indented collection item, false otherwise
|
||||||
|
*/
|
||||||
|
private function isStringUnIndentedCollectionItem()
|
||||||
|
{
|
||||||
|
return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- ');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether or not the current line is the header of a block scalar.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function isBlockScalarHeader()
|
||||||
|
{
|
||||||
|
return (bool) preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~', $this->currentLine);
|
||||||
|
}
|
||||||
|
}
|
156
third_party/Symfony/Component/Yaml/Unescaper.php
vendored
Normal file
156
third_party/Symfony/Component/Yaml/Unescaper.php
vendored
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Yaml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unescaper encapsulates unescaping rules for single and double-quoted
|
||||||
|
* YAML strings.
|
||||||
|
*
|
||||||
|
* @author Matthew Lewinski <matthew@lewinski.org>
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
class Unescaper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Parser and Inline assume UTF-8 encoding, so escaped Unicode characters
|
||||||
|
* must be converted to that encoding.
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.5, to be removed in 3.0
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
const ENCODING = 'UTF-8';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regex fragment that matches an escaped character in a double quoted string.
|
||||||
|
*/
|
||||||
|
const REGEX_ESCAPED_CHARACTER = '\\\\(x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|.)';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unescapes a single quoted string.
|
||||||
|
*
|
||||||
|
* @param string $value A single quoted string
|
||||||
|
*
|
||||||
|
* @return string The unescaped string
|
||||||
|
*/
|
||||||
|
public function unescapeSingleQuotedString($value)
|
||||||
|
{
|
||||||
|
return str_replace('\'\'', '\'', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unescapes a double quoted string.
|
||||||
|
*
|
||||||
|
* @param string $value A double quoted string
|
||||||
|
*
|
||||||
|
* @return string The unescaped string
|
||||||
|
*/
|
||||||
|
public function unescapeDoubleQuotedString($value)
|
||||||
|
{
|
||||||
|
$self = $this;
|
||||||
|
$callback = function ($match) use ($self) {
|
||||||
|
return $self->unescapeCharacter($match[0]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// evaluate the string
|
||||||
|
return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unescapes a character that was found in a double-quoted string.
|
||||||
|
*
|
||||||
|
* @param string $value An escaped character
|
||||||
|
*
|
||||||
|
* @return string The unescaped character
|
||||||
|
*
|
||||||
|
* @internal This method is public to be usable as callback. It should not
|
||||||
|
* be used in user code. Should be changed in 3.0.
|
||||||
|
*/
|
||||||
|
public function unescapeCharacter($value)
|
||||||
|
{
|
||||||
|
switch ($value[1]) {
|
||||||
|
case '0':
|
||||||
|
return "\x0";
|
||||||
|
case 'a':
|
||||||
|
return "\x7";
|
||||||
|
case 'b':
|
||||||
|
return "\x8";
|
||||||
|
case 't':
|
||||||
|
return "\t";
|
||||||
|
case "\t":
|
||||||
|
return "\t";
|
||||||
|
case 'n':
|
||||||
|
return "\n";
|
||||||
|
case 'v':
|
||||||
|
return "\xB";
|
||||||
|
case 'f':
|
||||||
|
return "\xC";
|
||||||
|
case 'r':
|
||||||
|
return "\r";
|
||||||
|
case 'e':
|
||||||
|
return "\x1B";
|
||||||
|
case ' ':
|
||||||
|
return ' ';
|
||||||
|
case '"':
|
||||||
|
return '"';
|
||||||
|
case '/':
|
||||||
|
return '/';
|
||||||
|
case '\\':
|
||||||
|
return '\\';
|
||||||
|
case 'N':
|
||||||
|
// U+0085 NEXT LINE
|
||||||
|
return "\xC2\x85";
|
||||||
|
case '_':
|
||||||
|
// U+00A0 NO-BREAK SPACE
|
||||||
|
return "\xC2\xA0";
|
||||||
|
case 'L':
|
||||||
|
// U+2028 LINE SEPARATOR
|
||||||
|
return "\xE2\x80\xA8";
|
||||||
|
case 'P':
|
||||||
|
// U+2029 PARAGRAPH SEPARATOR
|
||||||
|
return "\xE2\x80\xA9";
|
||||||
|
case 'x':
|
||||||
|
return self::utf8chr(hexdec(substr($value, 2, 2)));
|
||||||
|
case 'u':
|
||||||
|
return self::utf8chr(hexdec(substr($value, 2, 4)));
|
||||||
|
case 'U':
|
||||||
|
return self::utf8chr(hexdec(substr($value, 2, 8)));
|
||||||
|
default:
|
||||||
|
@trigger_error('Not escaping a backslash in a double-quoted string is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the UTF-8 character for the given code point.
|
||||||
|
*
|
||||||
|
* @param int $c The unicode code point
|
||||||
|
*
|
||||||
|
* @return string The corresponding UTF-8 character
|
||||||
|
*/
|
||||||
|
private static function utf8chr($c)
|
||||||
|
{
|
||||||
|
if (0x80 > $c %= 0x200000) {
|
||||||
|
return chr($c);
|
||||||
|
}
|
||||||
|
if (0x800 > $c) {
|
||||||
|
return chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F);
|
||||||
|
}
|
||||||
|
if (0x10000 > $c) {
|
||||||
|
return chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
|
||||||
|
}
|
||||||
|
|
||||||
|
return chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
|
||||||
|
}
|
||||||
|
}
|
100
third_party/Symfony/Component/Yaml/Yaml.php
vendored
Normal file
100
third_party/Symfony/Component/Yaml/Yaml.php
vendored
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@Symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Yaml;
|
||||||
|
|
||||||
|
use Symfony\Component\Yaml\Exception\ParseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Yaml offers convenience methods to load and dump YAML.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@Symfony.com>
|
||||||
|
*/
|
||||||
|
class Yaml
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Parses YAML into a PHP value.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* <code>
|
||||||
|
* $array = Yaml::parse(file_get_contents('config.yml'));
|
||||||
|
* print_r($array);
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* As this method accepts both plain strings and file names as an input,
|
||||||
|
* you must validate the input before calling this method. Passing a file
|
||||||
|
* as an input is a deprecated feature and will be removed in 3.0.
|
||||||
|
*
|
||||||
|
* Note: the ability to pass file names to the Yaml::parse method is deprecated since version 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead.
|
||||||
|
*
|
||||||
|
* @param string $input Path to a YAML file or a string containing YAML
|
||||||
|
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
|
||||||
|
* @param bool $objectSupport True if object support is enabled, false otherwise
|
||||||
|
* @param bool $objectForMap True if maps should return a stdClass instead of array()
|
||||||
|
*
|
||||||
|
* @return mixed The YAML converted to a PHP value
|
||||||
|
*
|
||||||
|
* @throws ParseException If the YAML is not valid
|
||||||
|
*/
|
||||||
|
public static function parse($input, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false)
|
||||||
|
{
|
||||||
|
// if input is a file, process it
|
||||||
|
$file = '';
|
||||||
|
if (strpos($input, "\n") === false && is_file($input)) {
|
||||||
|
@trigger_error('The ability to pass file names to the '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
if (false === is_readable($input)) {
|
||||||
|
throw new ParseException(sprintf('Unable to parse "%s" as the file is not readable.', $input));
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $input;
|
||||||
|
$input = file_get_contents($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
$yaml = new Parser();
|
||||||
|
|
||||||
|
try {
|
||||||
|
return $yaml->parse($input, $exceptionOnInvalidType, $objectSupport, $objectForMap);
|
||||||
|
} catch (ParseException $e) {
|
||||||
|
if ($file) {
|
||||||
|
$e->setParsedFile($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dumps a PHP value to a YAML string.
|
||||||
|
*
|
||||||
|
* The dump method, when supplied with an array, will do its best
|
||||||
|
* to convert the array into friendly YAML.
|
||||||
|
*
|
||||||
|
* @param mixed $input The PHP value
|
||||||
|
* @param int $inline The level where you switch to inline YAML
|
||||||
|
* @param int $indent The amount of spaces to use for indentation of nested nodes
|
||||||
|
* @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
|
||||||
|
* @param bool $objectSupport true if object support is enabled, false otherwise
|
||||||
|
*
|
||||||
|
* @return string A YAML string representing the original PHP value
|
||||||
|
*/
|
||||||
|
public static function dump($input, $inline = 2, $indent = 4, $exceptionOnInvalidType = false, $objectSupport = false)
|
||||||
|
{
|
||||||
|
if ($indent < 1) {
|
||||||
|
throw new \InvalidArgumentException('The indentation must be greater than zero.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$yaml = new Dumper();
|
||||||
|
$yaml->setIndentation($indent);
|
||||||
|
|
||||||
|
return $yaml->dump($input, $inline, 0, $exceptionOnInvalidType, $objectSupport);
|
||||||
|
}
|
||||||
|
}
|
63
third_party/Symfony/autoloader_yaml.php
vendored
Normal file
63
third_party/Symfony/autoloader_yaml.php
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||||
|
* use, copy, modify, and distribute this software in source code or binary
|
||||||
|
* form for use in connection with the web services and APIs provided by
|
||||||
|
* Facebook.
|
||||||
|
*
|
||||||
|
* As with any software that integrates with the Facebook platform, your use
|
||||||
|
* of this software is subject to the Facebook Developer Principles and
|
||||||
|
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||||
|
* shall be included in all copies or substantial portions of the software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modified by Ulrich Block to auto load Symfony Yaml without composer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the autoloader for the Symfony Yaml classes.
|
||||||
|
* Based off the official PSR-4 autoloader example found here:
|
||||||
|
* https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md
|
||||||
|
*
|
||||||
|
* @param string $class The fully-qualified class name.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
spl_autoload_register(function ($class)
|
||||||
|
{
|
||||||
|
// project-specific namespace prefix
|
||||||
|
$prefix = 'Symfony\\Component\\Yaml\\';
|
||||||
|
|
||||||
|
// does the class use the namespace prefix?
|
||||||
|
$len = strlen($prefix);
|
||||||
|
|
||||||
|
if (strncmp($prefix, $class, $len) !== 0) {
|
||||||
|
// no, move to the next registered autoloader
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the relative class name
|
||||||
|
$relativeClass = substr($class, $len);
|
||||||
|
|
||||||
|
// replace the namespace prefix with the base directory, replace namespace
|
||||||
|
// separators with directory separators in the relative class name, append
|
||||||
|
// with .php
|
||||||
|
$file = EASYWIDIR . '/third_party/Symfony/Component/Yaml/' . str_replace('\\', '/', $relativeClass) . '.php';
|
||||||
|
|
||||||
|
// if the file exists, require it
|
||||||
|
if (file_exists($file) and !class_exists($file)) {
|
||||||
|
require $file;
|
||||||
|
}
|
||||||
|
});
|
2
third_party/hybridauth/Hybrid/Auth.php
vendored
2
third_party/hybridauth/Hybrid/Auth.php
vendored
@ -354,7 +354,7 @@ class Hybrid_Auth {
|
|||||||
public static function redirect($url, $mode = "PHP") {
|
public static function redirect($url, $mode = "PHP") {
|
||||||
Hybrid_Logger::info("Enter Hybrid_Auth::redirect( $url, $mode )");
|
Hybrid_Logger::info("Enter Hybrid_Auth::redirect( $url, $mode )");
|
||||||
|
|
||||||
// Ensure session is saved before sending response, see https://github.com/symfony/symfony/pull/12341
|
// Ensure session is saved before sending response, see https://github.com/Symfony/Symfony/pull/12341
|
||||||
if ((PHP_VERSION_ID >= 50400 && PHP_SESSION_ACTIVE === session_status()) || (PHP_VERSION_ID < 50400 && isset($_SESSION) && session_id())) {
|
if ((PHP_VERSION_ID >= 50400 && PHP_SESSION_ACTIVE === session_status()) || (PHP_VERSION_ID < 50400 && isset($_SESSION) && session_id())) {
|
||||||
session_write_close();
|
session_write_close();
|
||||||
}
|
}
|
||||||
|
1160
third_party/spyc/Spyc.php
vendored
1160
third_party/spyc/Spyc.php
vendored
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user