@@ -0,0 +1,2 @@ | |||
files: / | |||
footer: |
@@ -0,0 +1,5 @@ | |||
location: /home/thierry/dev/tig12/tig12.net/web | |||
exclude: | |||
- .git | |||
- static | |||
- x-templates |
@@ -0,0 +1,18 @@ | |||
<?php | |||
/****************************************************************************** | |||
@license GPL | |||
@author Thierry Graff | |||
@history 2019-02-18 05:39:28+01:00 : Creation | |||
********************************************************************************/ | |||
$DIR_SRC = dirname(__DIR__); | |||
require_once 'jthAutoload_nonamespace.php'; | |||
jthAutoload_nonamespace::init([ | |||
$DIR_SRC . '/lib', | |||
$DIR_SRC . '/commands', | |||
]); | |||
spl_autoload_register(['jthAutoload_nonamespace', 'autoload']); |
@@ -0,0 +1,114 @@ | |||
<?php | |||
// Software released under the General Public License (version 2 or later), available at | |||
// http://www.gnu.org/copyleft/gpl.html | |||
/****************************************************************************** | |||
JeTheme autoload for classes that are not namespaced | |||
Calling code must first call : | |||
self::init() | |||
and then : | |||
spl_autoload_register(['jthAutoload_nonamespace', 'autoload']); | |||
The directories passed to self::init() are recursively scanned to add all classes located in subdirectories. | |||
@licence GPL | |||
@copyright jetheme.org | |||
@history 2009-11-23 06:19:47, Thierry Graff : Creation | |||
@history 2017-03-08 11:10:30+01:00, Thierry Graff : clean, rename for coherence with other autoload | |||
********************************************************************************/ | |||
class jthAutoload_nonamespace{ | |||
/** Root directories where classes are located */ | |||
public static $dirs = []; | |||
/** array(class names => absolute paths of php files) */ | |||
private static $array = []; | |||
// ****************************************************** | |||
/** | |||
Builds self::$array | |||
@param $dirs array of strings : root directories where classes are located | |||
**/ | |||
public static function init($dirs){ | |||
self::$dirs = $dirs; | |||
foreach(self::$dirs as $dir){ | |||
self::load_dir($dir); | |||
} | |||
//echo "<pre>"; print_r(self::$array); echo "</pre>"; exit; | |||
} | |||
//********************* autoload ****************************** | |||
/** | |||
ze autoload method | |||
@param $className name of class to load | |||
**/ | |||
public static function autoload($className){ | |||
if(isset(self::$array[$className])){ | |||
require_once self::$array[$className]; | |||
} | |||
else{ | |||
// comment the following line if several autoloads are in the spl stack | |||
//error_log(self::$ERROR_MSG . "class name = '$className'"); | |||
} | |||
} | |||
// ****************************************************** | |||
/** | |||
Recursively scans a directory and adds the entries to self::$array | |||
@todo should have an exclude property to avoid hacking the code when specific dirs must be excluded | |||
**/ | |||
private static function load_dir($dir){ | |||
// dirty hacks to avoid loading some classes, locally handled by an other autoloader | |||
if(strpos($dir, 'phpgedcom/library') !== false){ | |||
return; | |||
} | |||
if(strpos($dir, 'twig/Twig') !== false){ | |||
return; | |||
} | |||
global $res; | |||
if($handler = opendir($dir)) { | |||
while(($sub = readdir($handler)) !== false) { | |||
if ($sub != "." && $sub != ".."){ | |||
$file = "$dir/$sub"; | |||
if(is_file($file)){ | |||
$filename = basename($file); | |||
// | |||
// personal filters can be added here | |||
if(substr($filename, -4) != '.php'){ | |||
continue; | |||
} | |||
if(substr($filename, 0, 2) == 'z.'){ | |||
continue; | |||
} | |||
/* if($filename != ucFirst($filename)){ | |||
continue; // convention : class names start by upper case | |||
} */ | |||
// end personal filters can be added here | |||
// | |||
$classname = substr(basename($file), 0, -4); | |||
// add filename to class variable | |||
self::$array[$classname] = $file; | |||
}elseif(is_dir($file)){ | |||
// | |||
// personal filters can be added here | |||
if($sub == '1.test-files' || $sub == '1.doc-files'){ | |||
continue; | |||
} | |||
$dirname = basename($file); | |||
if(substr($dirname, 0, 2) == 'z.'){ | |||
continue; | |||
} | |||
// end personal filters can be added here | |||
// | |||
self::load_dir($file); // recursive here | |||
} | |||
} | |||
} | |||
closedir($handler); | |||
} | |||
} | |||
}// end class |
@@ -0,0 +1,141 @@ | |||
<?php | |||
/** | |||
Similar to php function scandir(), with differences : | |||
- doesn't return '.' and '..' | |||
- returns absolute paths | |||
- can be recursive | |||
- options can be used to filter the results | |||
@param $dir string, required | |||
absolute path of the directory to scan | |||
@param $params associative array, can contain : | |||
- 'include' : string or array of simplified regular expressions | |||
default = array('*') | |||
- 'exclude' : string or array of simplified regular expressions | |||
default = [] | |||
"simplified regular expressions" means regex as understood by PHP fnmatch function | |||
If include is present and not exclude, returns only the included files | |||
If exclude is present and not include, returns everything but the excluded files | |||
If both exclude and include are present, returns the files that are included and not excluded | |||
- 'recursive' : boolean : indicates if subdirs should also be scanned | |||
default = true | |||
- 'return-files' : boolean : indicates if regular files should be returned | |||
default = true | |||
- 'return-dirs' : boolean : indicates if directories should be returned | |||
default = true | |||
- 'cut-path' : string Part of the absolute path to remove | |||
default = null | |||
Must not end by "/" | |||
ex : if $params['cut-path'] = '/home/me/a/long/path' | |||
will return strings like 'dir1/file1.txt' instead of '/home/me/a/long/path/dir1/file1.txt' | |||
@return An array containing the absolute (or relative if $params['cut-path'] is used) paths of files and/or dirs | |||
@todo convert $dir to $params['dir'] | |||
@todo handle param check in rscandir | |||
@licence GPL | |||
@copyright jetheme.org | |||
@history 2010-10-02T20:13:10+02:00, Thierry Graff : Creation | |||
@history 2013-05-19 23:47:54+02:00, Thierry Graff : add cut-path parameter | |||
**/ | |||
class jth_rscandir{ | |||
// *********************************************************** | |||
/** | |||
rscandir is only used to treat $params['cut-path'] | |||
The job is done by {@link rscandir2()} | |||
**/ | |||
public static function rscandir($dir, $params=[]){ | |||
// default values for parameters, and convert to arrays if necessary | |||
if(!isset($params['include'])){ | |||
$params['include'] = array('*'); | |||
} | |||
if(is_string($params['include'])){ | |||
$params['include'] = array($params['include']); | |||
} | |||
// | |||
if(!isset($params['exclude'])){ | |||
$params['exclude'] = []; | |||
} | |||
if(is_string($params['exclude'])){ | |||
$params['exclude'] = array($params['exclude']); | |||
} | |||
// | |||
if(!isset($params['recursive'])){ | |||
$params['recursive'] = true; | |||
} | |||
// | |||
if(!isset($params['return-files'])){ | |||
$params['return-files'] = true; | |||
} | |||
// | |||
if(!isset($params['return-dirs'])){ | |||
$params['return-dirs'] = true; | |||
} | |||
// do the job | |||
$dirs = self::rscandir2($dir, $params); | |||
// cut-path and return | |||
if(isset($params['cut-path'])){ | |||
$res = []; | |||
foreach($dirs as $dir){ | |||
$res[] = str_replace($params['cut-path'] . DS, '', $dir); | |||
} | |||
return $res; | |||
} | |||
return $dirs; | |||
}// end rscandir | |||
// *********************************************************** | |||
/** | |||
recursive | |||
**/ | |||
private static function rscandir2($dir, $params=[]){ | |||
// | |||
$res = []; | |||
$entries = scandir($dir); | |||
foreach($entries as $entry){ | |||
if($entry === '.' || $entry === '..'){ | |||
continue; | |||
} | |||
// | |||
$current = "$dir/$entry"; | |||
$basename = basename($current); | |||
// | |||
$keep = false; | |||
$excluded = false; | |||
for($i=0; $i < count($params['include']); $i++){ | |||
if(fnmatch($params['include'][$i], $basename)){ | |||
$keep = true; | |||
break; | |||
} | |||
} | |||
for($i=0; $i < count($params['exclude']); $i++){ | |||
if(fnmatch($params['exclude'][$i], $basename)){ | |||
$keep = false; | |||
$excluded = true; | |||
break; | |||
} | |||
} | |||
// | |||
if(is_file($current)){ | |||
if($keep && $params['return-files']){ | |||
$res[] = $current; | |||
} | |||
continue; | |||
} | |||
else if(is_dir($current)){ | |||
if($keep && $params['return-dirs']){ | |||
$res[] = $current; | |||
} | |||
if($params['recursive'] && !$excluded){ | |||
foreach(self::rscandir2($current, $params) as $entry2){ // recursive here | |||
$res[]=$entry2; | |||
} | |||
} | |||
} | |||
} | |||
return $res; | |||
}// end rscandir2 | |||
}// end class |
@@ -0,0 +1,50 @@ | |||
<?php | |||
// Software released under the General Public License (version 3 or later), available at | |||
// http://www.gnu.org/copyleft/gpl.html | |||
/******************************************************************************** | |||
@license GPL | |||
@copyright jetheme.org | |||
@history 2012, Thierry Graff : Creation | |||
********************************************************************************/ | |||
class jthYAML{ | |||
// ****************************************************** | |||
/** | |||
Parses a YAML file and returns an associative array | |||
@param $str yaml file path or yaml string to parse | |||
**/ | |||
public static function parse($str){ | |||
// BUG (or feature ?) : dates YYYY-MM-DD are converted to unix timestamp | |||
$yaml = new sfYamlParser(); | |||
if(is_file($str)){ | |||
return $yaml->parse(file_get_contents($str)); | |||
} | |||
return $yaml->parse($str); | |||
}// end parse | |||
// ****************************************************** | |||
/** | |||
Converts a php array to YAML | |||
@param $array php array to convert | |||
@param $filename If present, dumps the yaml in a file - may issue a warning if $filename is not writable | |||
@return if $filename = false, returns the resulting yaml string | |||
if $filename != false, returns the nb of bytes written or false if impossible to store | |||
**/ | |||
public static function dump($array, $filename=false){ | |||
$dumper = new sfYamlDumper(); | |||
$yaml = $dumper->dump($array, 50); | |||
if($filename){ | |||
return file_put_contents($filename, $yaml); // nb of bytes written or false | |||
} | |||
else{ | |||
return $yaml; | |||
} | |||
}// end dump | |||
}// end class | |||
@@ -0,0 +1,10 @@ | |||
Do NOT use directly from jetheme code | |||
instead use wrapper (façade) used by jetheme code : lib/php/jetheme/utils/YAML.php | |||
- Files sf*.php retrieved from http://components.symfony-project.org/yaml/ | |||
2010-10-12 ; fabpot-yaml-da53851 | |||
@@ -0,0 +1,135 @@ | |||
<?php | |||
/* | |||
* This file is part of the symfony package. | |||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com> | |||
* | |||
* For the full copyright and license information, please view the LICENSE | |||
* file that was distributed with this source code. | |||
*/ | |||
/** | |||
* sfYaml offers convenience methods to load and dump YAML. | |||
* | |||
* @package symfony | |||
* @subpackage yaml | |||
* @author Fabien Potencier <fabien.potencier@symfony-project.com> | |||
* @version SVN: $Id: sfYaml.class.php 8988 2008-05-15 20:24:26Z fabien $ | |||
*/ | |||
class sfYaml | |||
{ | |||
static protected | |||
$spec = '1.2'; | |||
/** | |||
* Sets the YAML specification version to use. | |||
* | |||
* @param string $version The YAML specification version | |||
*/ | |||
static public function setSpecVersion($version) | |||
{ | |||
if (!in_array($version, array('1.1', '1.2'))) | |||
{ | |||
throw new InvalidArgumentException(sprintf('Version %s of the YAML specifications is not supported', $version)); | |||
} | |||
self::$spec = $version; | |||
} | |||
/** | |||
* Gets the YAML specification version to use. | |||
* | |||
* @return string The YAML specification version | |||
*/ | |||
static public function getSpecVersion() | |||
{ | |||
return self::$spec; | |||
} | |||
/** | |||
* Loads YAML into a PHP array. | |||
* | |||
* The load method, when supplied with a YAML stream (string or file), | |||
* will do its best to convert YAML in a file into a PHP array. | |||
* | |||
* Usage: | |||
* <code> | |||
* $array = sfYaml::load('config.yml'); | |||
* print_r($array); | |||
* </code> | |||
* | |||
* @param string $input Path of YAML file or string containing YAML | |||
* | |||
* @return array The YAML converted to a PHP array | |||
* | |||
* @throws InvalidArgumentException If the YAML is not valid | |||
*/ | |||
public static function load($input) | |||
{ | |||
$file = ''; | |||
// if input is a file, process it | |||
if (strpos($input, "\n") === false && is_file($input)) | |||
{ | |||
$file = $input; | |||
ob_start(); | |||
$retval = include($input); | |||
$content = ob_get_clean(); | |||
// if an array is returned by the config file assume it's in plain php form else in YAML | |||
$input = is_array($retval) ? $retval : $content; | |||
} | |||
// if an array is returned by the config file assume it's in plain php form else in YAML | |||
if (is_array($input)) | |||
{ | |||
return $input; | |||
} | |||
require_once dirname(__FILE__).'/sfYamlParser.php'; | |||
$yaml = new sfYamlParser(); | |||
try | |||
{ | |||
$ret = $yaml->parse($input); | |||
} | |||
catch (Exception $e) | |||
{ | |||
throw new InvalidArgumentException(sprintf('Unable to parse %s: %s', $file ? sprintf('file "%s"', $file) : 'string', $e->getMessage())); | |||
} | |||
return $ret; | |||
} | |||
/** | |||
* Dumps a PHP array to a YAML string. | |||
* | |||
* The dump method, when supplied with an array, will do its best | |||
* to convert the array into friendly YAML. | |||
* | |||
* @param array $array PHP array | |||
* @param integer $inline The level where you switch to inline YAML | |||
* | |||
* @return string A YAML string representing the original PHP array | |||
*/ | |||
public static function dump($array, $inline = 2) | |||
{ | |||
require_once dirname(__FILE__).'/sfYamlDumper.php'; | |||
$yaml = new sfYamlDumper(); | |||
return $yaml->dump($array, $inline); | |||
} | |||
} | |||
/** | |||
* Wraps echo to automatically provide a newline. | |||
* | |||
* @param string $string The string to echo with new line | |||
*/ | |||
function echoln($string) | |||
{ | |||
echo $string."\n"; | |||
} |
@@ -0,0 +1,60 @@ | |||
<?php | |||
/* | |||
* This file is part of the symfony package. | |||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com> | |||
* | |||
* For the full copyright and license information, please view the LICENSE | |||
* file that was distributed with this source code. | |||
*/ | |||
require_once(dirname(__FILE__).'/sfYamlInline.php'); | |||
/** | |||
* sfYamlDumper dumps PHP variables to YAML strings. | |||
* | |||
* @package symfony | |||
* @subpackage yaml | |||
* @author Fabien Potencier <fabien.potencier@symfony-project.com> | |||
* @version SVN: $Id: sfYamlDumper.class.php 10575 2008-08-01 13:08:42Z nicolas $ | |||
*/ | |||
class sfYamlDumper | |||
{ | |||
/** | |||
* Dumps a PHP value to YAML. | |||
* | |||
* @param mixed $input The PHP value | |||
* @param integer $inline The level where you switch to inline YAML | |||
* @param integer $indent The level o indentation indentation (used internally) | |||
* | |||
* @return string The YAML representation of the PHP value | |||
*/ | |||
public function dump($input, $inline = 0, $indent = 0) | |||
{ | |||
$output = ''; | |||
$prefix = $indent ? str_repeat(' ', $indent) : ''; | |||
if ($inline <= 0 || !is_array($input) || empty($input)) | |||
{ | |||
$output .= $prefix.sfYamlInline::dump($input); | |||
} | |||
else | |||
{ | |||
$isAHash = array_keys($input) !== range(0, count($input) - 1); | |||
foreach ($input as $key => $value) | |||
{ | |||
$willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value); | |||
$output .= sprintf('%s%s%s%s', | |||
$prefix, | |||
$isAHash ? sfYamlInline::dump($key).':' : '-', | |||
$willBeInlined ? ' ' : "\n", | |||
$this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + 2) | |||
).($willBeInlined ? "\n" : ''); | |||
} | |||
} | |||
return $output; | |||
} | |||
} |
@@ -0,0 +1,442 @@ | |||
<?php | |||
/* | |||
* This file is part of the symfony package. | |||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com> | |||
* | |||
* For the full copyright and license information, please view the LICENSE | |||
* file that was distributed with this source code. | |||
*/ | |||
require_once dirname(__FILE__).'/sfYaml.php'; | |||
/** | |||
* sfYamlInline implements a YAML parser/dumper for the YAML inline syntax. | |||
* | |||
* @package symfony | |||
* @subpackage yaml | |||
* @author Fabien Potencier <fabien.potencier@symfony-project.com> | |||
* @version SVN: $Id: sfYamlInline.class.php 16177 2009-03-11 08:32:48Z fabien $ | |||
*/ | |||
class sfYamlInline | |||
{ | |||
const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')'; | |||
/** | |||
* Convert a YAML string to a PHP array. | |||
* | |||
* @param string $value A YAML string | |||
* | |||
* @return array A PHP array representing the YAML string | |||
*/ | |||
static public function load($value) | |||
{ | |||
$value = trim($value); | |||
if (0 == strlen($value)) | |||
{ | |||
return ''; | |||
} | |||
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) | |||
{ | |||
$mbEncoding = mb_internal_encoding(); | |||
mb_internal_encoding('ASCII'); | |||
} | |||
switch ($value[0]) | |||
{ | |||
case '[': | |||
$result = self::parseSequence($value); | |||
break; | |||
case '{': | |||
$result = self::parseMapping($value); | |||
break; | |||
default: | |||
$result = self::parseScalar($value); | |||
} | |||
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 | |||
* | |||
* @return string The YAML string representing the PHP array | |||
*/ | |||
static public function dump($value) | |||
{ | |||
if ('1.1' === sfYaml::getSpecVersion()) | |||
{ | |||
$trueValues = array('true', 'on', '+', 'yes', 'y'); | |||
$falseValues = array('false', 'off', '-', 'no', 'n'); | |||
} | |||
else | |||
{ | |||
$trueValues = array('true'); | |||
$falseValues = array('false'); | |||
} | |||
switch (true) | |||
{ | |||
case is_resource($value): | |||
throw new InvalidArgumentException('Unable to dump PHP resources in a YAML file.'); | |||
case is_object($value): | |||
return '!!php/object:'.serialize($value); | |||
case is_array($value): | |||
return self::dumpArray($value); | |||
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): | |||
return is_infinite($value) ? str_ireplace('INF', '.Inf', strval($value)) : (is_string($value) ? "'$value'" : $value); | |||
case false !== strpos($value, "\n") || false !== strpos($value, "\r"): | |||
return sprintf('"%s"', str_replace(array('"', "\n", "\r"), array('\\"', '\n', '\r'), $value)); | |||
case preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ - ? | < > = ! % @ ` ]/x', $value): | |||
return sprintf("'%s'", str_replace('\'', '\'\'', $value)); | |||
case '' == $value: | |||
return "''"; | |||
case preg_match(self::getTimestampRegex(), $value): | |||
return "'$value'"; | |||
case in_array(strtolower($value), $trueValues): | |||
return "'$value'"; | |||
case in_array(strtolower($value), $falseValues): | |||
return "'$value'"; | |||
case in_array(strtolower($value), array('null', '~')): | |||
return "'$value'"; | |||
default: | |||
return $value; | |||
} | |||
} | |||
/** | |||
* Dumps a PHP array to a YAML string. | |||
* | |||
* @param array $value The PHP array to dump | |||
* | |||
* @return string The YAML string representing the PHP array | |||
*/ | |||
static protected function dumpArray($value) | |||
{ | |||
// array | |||
$keys = array_keys($value); | |||
if ( | |||
(1 == count($keys) && '0' == $keys[0]) | |||
|| | |||
(count($keys) > 1 && array_reduce($keys, create_function('$v,$w', 'return (integer) $v + $w;'), 0) == count($keys) * (count($keys) - 1) / 2)) | |||
{ | |||
$output = []; | |||
foreach ($value as $val) | |||
{ | |||
$output[] = self::dump($val); | |||
} | |||
return sprintf('[%s]', implode(', ', $output)); | |||
} | |||
// mapping | |||
$output = []; | |||
foreach ($value as $key => $val) | |||
{ | |||
$output[] = sprintf('%s: %s', self::dump($key), self::dump($val)); | |||
} | |||
return sprintf('{ %s }', implode(', ', $output)); | |||
} | |||
/** | |||
* Parses a scalar to a YAML string. | |||
* | |||
* @param scalar $scalar | |||
* @param string $delimiters | |||
* @param array $stringDelimiter | |||
* @param integer $i | |||
* @param boolean $evaluate | |||
* | |||
* @return string A YAML string | |||
*/ | |||
static public function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true) | |||
{ | |||
if (in_array($scalar[$i], $stringDelimiters)) | |||
{ | |||
// quoted scalar | |||
$output = self::parseQuotedScalar($scalar, $i); | |||
} | |||
else | |||
{ | |||
// "normal" string | |||
if (!$delimiters) | |||
{ | |||
$output = substr($scalar, $i); | |||
$i += strlen($output); | |||
// remove comments | |||
if (false !== $strpos = strpos($output, ' #')) | |||
{ | |||
$output = rtrim(substr($output, 0, $strpos)); | |||
} | |||
} | |||
else if (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) | |||
{ | |||
$output = $match[1]; | |||
$i += strlen($output); | |||
} | |||
else | |||
{ | |||
throw new InvalidArgumentException(sprintf('Malformed inline YAML string (%s).', $scalar)); | |||
} | |||
$output = $evaluate ? self::evaluateScalar($output) : $output; | |||
} | |||
return $output; | |||
} | |||
/** | |||
* Parses a quoted scalar to YAML. | |||
* | |||
* @param string $scalar | |||
* @param integer $i | |||
* | |||
* @return string A YAML string | |||
*/ | |||
static protected function parseQuotedScalar($scalar, &$i) | |||
{ | |||
if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) | |||
{ | |||
throw new InvalidArgumentException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i))); | |||
} | |||
$output = substr($match[0], 1, strlen($match[0]) - 2); | |||
if ('"' == $scalar[$i]) | |||
{ | |||
// evaluate the string | |||
$output = str_replace(array('\\"', '\\n', '\\r'), array('"', "\n", "\r"), $output); | |||
} | |||
else | |||
{ | |||
// unescape ' | |||
$output = str_replace('\'\'', '\'', $output); | |||
} | |||
$i += strlen($match[0]); | |||
return $output; | |||
} | |||
/** | |||
* Parses a sequence to a YAML string. | |||
* | |||
* @param string $sequence | |||
* @param integer $i | |||
* | |||
* @return string A YAML string | |||
*/ | |||
static protected function parseSequence($sequence, &$i = 0) | |||
{ | |||
$output = []; | |||
$len = strlen($sequence); | |||
$i += 1; | |||
// [foo, bar, ...] | |||
while ($i < $len) | |||
{ | |||
switch ($sequence[$i]) | |||
{ | |||
case '[': | |||
// nested sequence | |||
$output[] = self::parseSequence($sequence, $i); | |||
break; | |||
case '{': | |||
// nested mapping | |||
$output[] = self::parseMapping($sequence, $i); | |||
break; | |||
case ']': | |||
return $output; | |||
case ',': | |||
case ' ': | |||
break; | |||
default: | |||
$isQuoted = in_array($sequence[$i], array('"', "'")); | |||
$value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i); | |||
if (!$isQuoted && false !== strpos($value, ': ')) | |||
{ | |||
// embedded mapping? | |||
try | |||
{ | |||
$value = self::parseMapping('{'.$value.'}'); | |||
} | |||
catch (InvalidArgumentException $e) | |||
{ | |||
// no, it's not | |||
} | |||
} | |||
$output[] = $value; | |||
--$i; | |||
} | |||
++$i; | |||
} | |||
throw new InvalidArgumentException(sprintf('Malformed inline YAML string %s', $sequence)); | |||
} | |||
/** | |||
* Parses a mapping to a YAML string. | |||
* | |||
* @param string $mapping | |||
* @param integer $i | |||
* | |||
* @return string A YAML string | |||
*/ | |||
static protected function parseMapping($mapping, &$i = 0) | |||
{ | |||
$output = []; | |||
$len = strlen($mapping); | |||
$i += 1; | |||
// {foo: bar, bar:foo, ...} | |||
while ($i < $len) | |||
{ | |||
switch ($mapping[$i]) | |||
{ | |||
case ' ': | |||
case ',': | |||
++$i; | |||
continue 2; | |||
case '}': | |||
return $output; | |||
} | |||
// key | |||
$key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false); | |||
// value | |||
$done = false; | |||
while ($i < $len) | |||
{ | |||
switch ($mapping[$i]) | |||
{ | |||
case '[': | |||
// nested sequence | |||
$output[$key] = self::parseSequence($mapping, $i); | |||
$done = true; | |||
break; | |||
case '{': | |||
// nested mapping | |||
$output[$key] = self::parseMapping($mapping, $i); | |||
$done = true; | |||
break; | |||
case ':': | |||
case ' ': | |||
break; | |||
default: | |||
$output[$key] = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i); | |||
$done = true; | |||
--$i; | |||
} | |||
++$i; | |||
if ($done) | |||
{ | |||
continue 2; | |||
} | |||
} | |||
} | |||
throw new InvalidArgumentException(sprintf('Malformed inline YAML string %s', $mapping)); | |||
} | |||
/** | |||
* Evaluates scalars and replaces magic values. | |||
* | |||
* @param string $scalar | |||
* | |||
* @return string A YAML string | |||
*/ | |||
static protected function evaluateScalar($scalar) | |||
{ | |||
$scalar = trim($scalar); | |||
if ('1.1' === sfYaml::getSpecVersion()) | |||
{ | |||
$trueValues = array('true', 'on', '+', 'yes', 'y'); | |||
$falseValues = array('false', 'off', '-', 'no', 'n'); | |||
} | |||
else | |||
{ | |||
$trueValues = array('true'); | |||
$falseValues = array('false'); | |||
} | |||
switch (true) | |||
{ | |||
case 'null' == strtolower($scalar): | |||
case '' == $scalar: | |||
case '~' == $scalar: | |||
return null; | |||
case 0 === strpos($scalar, '!str'): | |||
return (string) substr($scalar, 5); | |||
case 0 === strpos($scalar, '! '): | |||
return intval(self::parseScalar(substr($scalar, 2))); | |||
case 0 === strpos($scalar, '!!php/object:'): | |||
return unserialize(substr($scalar, 13)); | |||
case ctype_digit($scalar): | |||
$raw = $scalar; | |||
$cast = intval($scalar); | |||
return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw); | |||
case in_array(strtolower($scalar), $trueValues): | |||
return true; | |||
case in_array(strtolower($scalar), $falseValues): | |||
return false; | |||
case is_numeric($scalar): | |||
return '0x' == $scalar[0].$scalar[1] ? hexdec($scalar) : floatval($scalar); | |||
case 0 == strcasecmp($scalar, '.inf'): | |||
case 0 == strcasecmp($scalar, '.NaN'): | |||
return -log(0); | |||
case 0 == strcasecmp($scalar, '-.inf'): | |||
return log(0); | |||
case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar): | |||
return floatval(str_replace(',', '', $scalar)); | |||
case preg_match(self::getTimestampRegex(), $scalar): | |||
return strtotime($scalar); | |||
default: | |||
return (string) $scalar; | |||
} | |||
} | |||
static protected function getTimestampRegex() | |||
{ | |||
return <<<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; | |||
} | |||
} |
@@ -0,0 +1,622 @@ | |||
<?php | |||
/* | |||
* This file is part of the symfony package. | |||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com> | |||
* | |||
* For the full copyright and license information, please view the LICENSE | |||
* file that was distributed with this source code. | |||
*/ | |||
require_once(dirname(__FILE__).'/sfYamlInline.php'); | |||
if (!defined('PREG_BAD_UTF8_OFFSET_ERROR')) | |||
{ | |||
define('PREG_BAD_UTF8_OFFSET_ERROR', 5); | |||
} | |||
/** | |||
* sfYamlParser parses YAML strings to convert them to PHP arrays. | |||
* | |||
* @package symfony | |||
* @subpackage yaml | |||
* @author Fabien Potencier <fabien.potencier@symfony-project.com> | |||
* @version SVN: $Id: sfYamlParser.class.php 10832 2008-08-13 07:46:08Z fabien $ | |||
*/ | |||
class sfYamlParser | |||
{ | |||
protected | |||
$offset = 0, | |||
$lines = [], | |||
$currentLineNb = -1, | |||
$currentLine = '', | |||
$refs = []; | |||
/** | |||
* Constructor | |||
* | |||
* @param integer $offset The offset of YAML document (used for line numbers in error messages) | |||
*/ | |||
public function __construct($offset = 0) | |||
{ | |||
$this->offset = $offset; | |||
} | |||
/** | |||
* Parses a YAML string to a PHP value. | |||
* | |||
* @param string $value A YAML string | |||
* | |||
* @return mixed A PHP value | |||
* | |||
* @throws InvalidArgumentException If the YAML is not valid | |||
*/ | |||
public function parse($value) | |||
{ | |||
$this->currentLineNb = -1; | |||
$this->currentLine = ''; | |||
$this->lines = explode("\n", $this->cleanup($value)); | |||
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) | |||
{ | |||
$mbEncoding = mb_internal_encoding(); | |||
mb_internal_encoding('UTF-8'); | |||
} | |||
$data = []; | |||
while ($this->moveToNextLine()) | |||
{ | |||
if ($this->isCurrentLineEmpty()) | |||
{ | |||
continue; | |||
} | |||
// tab? | |||
if (preg_match('#^\t+#', $this->currentLine)) | |||
{ | |||
throw new InvalidArgumentException(sprintf('A YAML file cannot contain tabs as indentation at line %d (%s).', $this->getRealCurrentLineNb() + 1, $this->currentLine)); | |||
} | |||
$isRef = $isInPlace = $isProcessed = false; | |||
if (preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) | |||
{ | |||
if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) | |||
{ | |||
$isRef = $matches['ref']; | |||
$values['value'] = $matches['value']; | |||
} | |||
// array | |||
if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) | |||
{ | |||
$c = $this->getRealCurrentLineNb() + 1; | |||
$parser = new sfYamlParser($c); | |||
$parser->refs =& $this->refs; | |||
$data[] = $parser->parse($this->getNextEmbedBlock()); | |||
} | |||
else | |||
{ | |||
if (isset($values['leadspaces']) | |||
&& ' ' == $values['leadspaces'] | |||
&& preg_match('#^(?P<key>'.sfYamlInline::REGEX_QUOTED_STRING.'|[^ \'"\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $values['value'], $matches)) | |||
{ | |||
// this is a compact notation element, add to next block and parse | |||
$c = $this->getRealCurrentLineNb(); | |||
$parser = new sfYamlParser($c); | |||
$parser->refs =& $this->refs; | |||
$block = $values['value']; | |||
if (!$this->isNextLineIndented()) | |||
{ | |||
$block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + 2); | |||
} | |||
$data[] = $parser->parse($block); | |||
} | |||
else | |||
{ | |||
$data[] = $this->parseValue($values['value']); | |||
} | |||
} | |||
} | |||
else if (preg_match('#^(?P<key>'.sfYamlInline::REGEX_QUOTED_STRING.'|[^ \'"].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) | |||
{ | |||
$key = sfYamlInline::parseScalar($values['key']); | |||
if ('<<' === $key) | |||
{ | |||
if (isset($values['value']) && '*' === substr($values['value'], 0, 1)) | |||
{ | |||
$isInPlace = substr($values['value'], 1); | |||
if (!array_key_exists($isInPlace, $this->refs)) | |||
{ | |||
throw new InvalidArgumentException(sprintf('Reference "%s" does not exist at line %s (%s).', $isInPlace, $this->getRealCurrentLineNb() + 1, $this->currentLine)); | |||
} | |||
} | |||
else | |||
{ | |||
if (isset($values['value']) && $values['value'] !== '') | |||
{ | |||
$value = $values['value']; | |||
} | |||
else | |||
{ | |||
$value = $this->getNextEmbedBlock(); | |||
} | |||
$c = $this->getRealCurrentLineNb() + 1; | |||
$parser = new sfYamlParser($c); | |||
$parser->refs =& $this->refs; | |||
$parsed = $parser->parse($value); | |||
$merged = []; | |||
if (!is_array($parsed)) | |||
{ | |||
throw new InvalidArgumentException(sprintf("YAML merge keys used with a scalar value instead of an array at line %s (%s)", $this->getRealCurrentLineNb() + 1, $this->currentLine)); | |||
} | |||
else if (isset($parsed[0])) | |||
{ | |||
// Numeric array, merge individual elements | |||
foreach (array_reverse($parsed) as $parsedItem) | |||
{ | |||
if (!is_array($parsedItem)) | |||
{ | |||
throw new InvalidArgumentException(sprintf("Merge items must be arrays at line %s (%s).", $this->getRealCurrentLineNb() + 1, $parsedItem)); | |||
} | |||
$merged = array_merge($parsedItem, $merged); | |||
} | |||
} | |||
else | |||
{ | |||
// Associative array, merge | |||
$merged = array_merge($merge, $parsed); | |||
} | |||
$isProcessed = $merged; | |||
} | |||
} | |||
else if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) | |||
{ | |||
$isRef = $matches['ref']; | |||
$values['value'] = $matches['value']; | |||
} | |||
if ($isProcessed) | |||
{ | |||
// Merge keys | |||
$data = $isProcessed; | |||
} | |||
// hash | |||
else if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) | |||
{ | |||
// if next line is less indented or equal, then it means that the current value is null | |||
if ($this->isNextLineIndented()) | |||
{ | |||
$data[$key] = null; | |||
} | |||
else | |||
{ | |||
$c = $this->getRealCurrentLineNb() + 1; | |||
$parser = new sfYamlParser($c); | |||
$parser->refs =& $this->refs; | |||
$data[$key] = $parser->parse($this->getNextEmbedBlock()); | |||
} | |||
} | |||
else | |||
{ | |||
if ($isInPlace) | |||
{ | |||
$data = $this->refs[$isInPlace]; | |||
} | |||
else | |||
{ | |||
$data[$key] = $this->parseValue($values['value']); | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
// 1-liner followed by newline | |||
if (2 == count($this->lines) && empty($this->lines[1])) | |||
{ | |||
$value = sfYamlInline::load($this->lines[0]); | |||
if (is_array($value)) | |||
{ | |||
$first = reset($value); | |||
if ('*' === substr($first, 0, 1)) | |||
{ | |||
$data = []; | |||
foreach ($value as $alias) | |||
{ | |||
$data[] = $this->refs[substr($alias, 1)]; | |||
} | |||
$value = $data; | |||
} | |||
} | |||
if (isset($mbEncoding)) | |||
{ | |||
mb_internal_encoding($mbEncoding); | |||
} | |||
return $value; | |||
} | |||
switch (preg_last_error()) | |||
{ | |||
case PREG_INTERNAL_ERROR: | |||
$error = 'Internal PCRE error on line'; | |||
break; | |||
case PREG_BACKTRACK_LIMIT_ERROR: | |||
$error = 'pcre.backtrack_limit reached on line'; | |||
break; | |||
case PREG_RECURSION_LIMIT_ERROR: | |||
$error = 'pcre.recursion_limit reached on line'; | |||
break; | |||
case PREG_BAD_UTF8_ERROR: | |||
$error = 'Malformed UTF-8 data on line'; | |||
break; | |||
case PREG_BAD_UTF8_OFFSET_ERROR: | |||
$error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point on line'; | |||
break; | |||
default: | |||
$error = 'Unable to parse line'; | |||
} | |||
throw new InvalidArgumentException(sprintf('%s %d (%s).', $error, $this->getRealCurrentLineNb() + 1, $this->currentLine)); | |||
} | |||
if ($isRef) | |||
{ | |||
$this->refs[$isRef] = end($data); | |||
} | |||
} | |||
if (isset($mbEncoding)) | |||
{ | |||
mb_internal_encoding($mbEncoding); | |||
} | |||
return empty($data) ? null : $data; | |||
} | |||
/** | |||
* Returns the current line number (takes the offset into account). | |||
* | |||
* @return integer The current line number | |||
*/ | |||
protected function getRealCurrentLineNb() | |||
{ | |||
return $this->currentLineNb + $this->offset; | |||
} | |||
/** | |||
* Returns the current line indentation. | |||
* | |||
* @return integer The current line indentation | |||
*/ | |||
protected function getCurrentLineIndentation() | |||
{ | |||
return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' ')); | |||
} | |||
/** | |||
* Returns the next embed block of YAML. | |||
* | |||
* @param integer $indentation The indent level at which the block is to be read, or null for default | |||
* | |||
* @return string A YAML string | |||
*/ | |||
protected function getNextEmbedBlock($indentation = null) | |||
{ | |||
$this->moveToNextLine(); | |||
if (null === $indentation) | |||
{ | |||
$newIndent = $this->getCurrentLineIndentation(); | |||
if (!$this->isCurrentLineEmpty() && 0 == $newIndent) | |||
{ | |||
throw new InvalidArgumentException(sprintf('Indentation problem at line %d (%s)', $this->getRealCurrentLineNb() + 1, $this->currentLine)); | |||
} | |||
} | |||
else | |||
{ | |||
$newIndent = $indentation; | |||
} | |||
$data = array(substr($this->currentLine, $newIndent)); | |||
while ($this->moveToNextLine()) | |||
{ | |||
if ($this->isCurrentLineEmpty()) | |||
{ | |||
if ($this->isCurrentLineBlank()) | |||
{ | |||
$data[] = substr($this->currentLine, $newIndent); | |||
} | |||
continue; | |||
} | |||
$indent = $this->getCurrentLineIndentation(); | |||
if (preg_match('#^(?P<text> *)$#', $this->currentLine, $match)) | |||
{ | |||
// empty line | |||
$data[] = $match['text']; | |||
} | |||
else if ($indent >= $newIndent) | |||
{ | |||
$data[] = substr($this->currentLine, $newIndent); | |||
} | |||
else if (0 == $indent) | |||
{ | |||
$this->moveToPreviousLine(); | |||
break; | |||
} | |||
else | |||
{ | |||
throw new InvalidArgumentException(sprintf('Indentation problem at line %d (%s)', $this->getRealCurrentLineNb() + 1, $this->currentLine)); | |||
} | |||
} | |||
return implode("\n", $data); | |||
} | |||
/** | |||
* Moves the parser to the next line. | |||
*/ | |||
protected 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. | |||
*/ | |||
protected function moveToPreviousLine() | |||
{ | |||
$this->currentLine = $this->lines[--$this->currentLineNb]; | |||
} | |||
/** | |||
* Parses a YAML value. | |||
* | |||
* @param string $value A YAML value | |||
* | |||
* @return mixed A PHP value | |||
*/ | |||
protected function parseValue($value) | |||
{ | |||
if ('*' === substr($value, 0, 1)) | |||
{ | |||
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 InvalidArgumentException(sprintf('Reference "%s" does not exist (%s).', $value, $this->currentLine)); | |||
} | |||
return $this->refs[$value]; | |||
} | |||
if (preg_match('/^(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?$/', $value, $matches)) | |||
{ | |||
$modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : ''; | |||
return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), intval(abs($modifiers))); | |||
} | |||
else | |||
{ | |||
return sfYamlInline::load($value); | |||
} | |||
} | |||
/** | |||
* Parses a folded scalar. | |||
* | |||
* @param string $separator The separator that was used to begin this folded scalar (| or >) | |||
* @param string $indicator The indicator that was used to begin this folded scalar (+ or -) | |||
* @param integer $indentation The indentation that was used to begin this folded scalar | |||
* | |||
* @return string The text value | |||
*/ | |||
protected function parseFoldedScalar($separator, $indicator = '', $indentation = 0) | |||
{ | |||
$separator = '|' == $separator ? "\n" : ' '; | |||
$text = ''; | |||
$notEOF = $this->moveToNextLine(); | |||
while ($notEOF && $this->isCurrentLineBlank()) | |||
{ | |||
$text .= "\n"; | |||
$notEOF = $this->moveToNextLine(); | |||
} | |||
if (!$notEOF) | |||
{ | |||
return ''; | |||
} | |||
if (!preg_match('#^(?P<indent>'.($indentation ? str_repeat(' ', $indentation) : ' +').')(?P<text>.*)$#u', $this->currentLine, $matches)) | |||
{ | |||
$this->moveToPreviousLine(); | |||
return ''; | |||
} | |||
$textIndent = $matches['indent']; | |||
$previousIndent = 0; | |||
$text .= $matches['text'].$separator; | |||
while ($this->currentLineNb + 1 < count($this->lines)) | |||
{ | |||
$this->moveToNextLine(); | |||
if (preg_match('#^(?P<indent> {'.strlen($textIndent).',})(?P<text>.+)$#u', $this->currentLine, $matches)) | |||
{ | |||
if (' ' == $separator && $previousIndent != $matches['indent']) | |||
{ | |||
$text = substr($text, 0, -1)."\n"; | |||
} | |||
$previousIndent = $matches['indent']; | |||
$text .= str_repeat(' ', $diff = strlen($matches['indent']) - strlen($textIndent)).$matches['text'].($diff ? "\n" : $separator); | |||
} | |||
else if (preg_match('#^(?P<text> *)$#', $this->currentLine, $matches)) | |||
{ | |||
$text .= preg_replace('#^ {1,'.strlen($textIndent).'}#', '', $matches['text'])."\n"; | |||
} | |||
else | |||
{ | |||
$this->moveToPreviousLine(); | |||
break; | |||
} | |||
} | |||
if (' ' == $separator) | |||
{ | |||
// replace last separator by a newline | |||
$text = preg_replace('/ (\n*)$/', "\n$1", $text); | |||
} | |||
switch ($indicator) | |||
{ | |||
case '': | |||
$text = preg_replace('#\n+$#s', "\n", $text); | |||
break; | |||
case '+': | |||
break; | |||
case '-': | |||
$text = preg_replace('#\n+$#s', '', $text); | |||
break; | |||
} | |||
return $text; | |||
} | |||
/** | |||
* Returns true if the next line is indented. | |||
* | |||
* @return Boolean Returns true if the next line is indented, false otherwise | |||
*/ | |||
protected function isNextLineIndented() | |||
{ | |||
$currentIndentation = $this->getCurrentLineIndentation(); | |||
$notEOF = $this->moveToNextLine(); | |||
while ($notEOF && $this->isCurrentLineEmpty()) | |||
{ | |||
$notEOF = $this->moveToNextLine(); | |||
} | |||
if (false === $notEOF) | |||
{ | |||
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 Boolean Returns true if the current line is empty or if it is a comment line, false otherwise | |||
*/ | |||
protected function isCurrentLineEmpty() | |||
{ | |||
return $this->isCurrentLineBlank() || $this->isCurrentLineComment(); | |||
} | |||
/** | |||
* Returns true if the current line is blank. | |||
* | |||
* @return Boolean Returns true if the current line is blank, false otherwise | |||
*/ | |||
protected function isCurrentLineBlank() | |||
{ | |||
return '' == trim($this->currentLine, ' '); | |||
} | |||
/** | |||
* Returns true if the current line is a comment line. | |||
* | |||
* @return Boolean Returns true if the current line is a comment line, false otherwise | |||
*/ | |||
protected function isCurrentLineComment() | |||
{ | |||
//checking explicitly the first char of the trim is faster than loops or strpos | |||
$ltrimmedLine = ltrim($this->currentLine, ' '); | |||
return $ltrimmedLine[0] === '#'; | |||
} | |||
/** | |||
* Cleanups a YAML string to be parsed. | |||
* | |||
* @param string $value The input YAML string | |||
* | |||
* @return string A cleaned up YAML string | |||
*/ | |||
protected function cleanup($value) | |||
{ | |||
$value = str_replace(array("\r\n", "\r"), "\n", $value); | |||
if (!preg_match("#\n$#", $value)) | |||
{ | |||
$value .= "\n"; | |||
} | |||
// strip YAML header | |||
$count = 0; | |||
$value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#su', '', $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*$#s', '', $value); | |||
} | |||
return $value; | |||
} | |||
} |
@@ -1,60 +0,0 @@ | |||
<?php | |||
/******************************************************************************** | |||
CLI (command line interface) to use tigsite | |||
usage : php run-gauquelin5.php | |||
and follow the instructions | |||
@license GPL | |||
@copyright Thierry Graff | |||
@history 2019-02-02 02:40:27+01:00, Thierry Graff : creation | |||
********************************************************************************/ | |||
$USAGE = <<<USAGE | |||
usage : | |||
php {$argv[0]} <site> <action> | |||
Examples : | |||
php {$argv[0]} tig12 makenav maths/maths.html # Generate code to update site navigation in page maths/maths.html | |||
<action> : voir src/php/commands/ | |||
USAGE; | |||
// check arguments | |||
if(count($argv) != 3){ | |||
die($USAGE); | |||
} | |||
// check serie | |||
$serie = $argv[1]; | |||
if(!in_array($serie, $series)){ | |||
echo "!!! INVALID SERIE !!! : '$serie' - possible choices : '$series_str'\n"; | |||
exit; | |||
} | |||
// check action | |||
$action = $argv[2]; | |||
if(!in_array($action, $series_actions[$serie])){ | |||
echo "!!! INVALID ACTION FOR SERIE $serie !!! : - possible choices : '" . implode("' or '", $series_actions[$serie]) . "'\n"; | |||
exit; | |||
} | |||
// | |||
// run | |||
// | |||
define('DS', DIRECTORY_SEPARATOR); | |||
require_once __DIR__ . DS . 'src' . DS . 'init' . DS . 'init.php'; | |||
use gauquelin5\Gauquelin5; | |||
try{ | |||
echo Gauquelin5::action($action, $serie); /// here run action /// | |||
} | |||
catch(Exception $e){ | |||
echo 'Exception : ' . $e->getMessage() . "\n"; | |||
echo $e->getFile() . ' - line ' . $e->getLine() . "\n"; | |||
echo $e->getTraceAsString() . "\n"; | |||
} | |||
@@ -0,0 +1,80 @@ | |||
<?php | |||
/******************************************************************************** | |||
CLI (command line interface) to use tigsite | |||
usage : php run-gauquelin5.php | |||
and follow the instructions | |||
@license GPL | |||
@copyright Thierry Graff | |||
@history 2019-02-02 02:40:27+01:00, Thierry Graff : creation | |||
********************************************************************************/ | |||
define('DS', DIRECTORY_SEPARATOR); | |||
require_once 'app/autoload.php'; | |||
$USAGE = <<<USAGE | |||
Usage : | |||
php {$argv[0]} <site> <action> | |||
<site> : must be a sub-directory of sites/ | |||
<action> : must correspond to a yaml file of sites/<site>/commands/ | |||
Example : | |||
php {$argv[0]} tig12.net updatefooter # Adds a footer in alll site pages | |||
Uses the command file sites/tig12.net/commands/addfooter.yml | |||
USAGE; | |||
// | |||
// check arguments | |||
// | |||
if(count($argv) != 3){ | |||
echo "Invalid usage\n"; | |||
die($USAGE); | |||
} | |||
$siteName = $argv[1]; | |||
$command = $argv[2]; | |||
$ROOT = dirname(__DIR__); | |||
$siteDir = $ROOT . DS . 'sites' . DS . $siteName; | |||
if(!is_dir($siteDir)){ | |||
echo "Wrong site name : directory sites/$siteName does not exist\n"; | |||
exit; | |||
} | |||
$siteConfigFile = $siteDir . DS . 'config.yml'; | |||
if(!is_file($siteConfigFile)){ | |||
echo "Missing site configuration file : file sites/$siteName/config.yml does not exist\n"; | |||
exit; | |||
} | |||
$commandFile = $siteDir . DS . 'commands' . DS . $command . '.yml'; | |||
if(!is_file($commandFile)){ | |||
echo "Wrong command name : file sites/$siteName/commands/$command.yml does not exist\n"; | |||
exit; | |||
} | |||
// | |||
// run | |||
// | |||
$config = []; | |||
$config['site'] = jthYAML::parse($siteConfigFile); | |||
$config['command'] = jthYAML::parse($commandFile); | |||
echo "\n<pre>"; print_r($config); echo "</pre>\n"; | |||
exit; | |||
try{ | |||
} | |||
catch(Exception $e){ | |||
echo 'Exception : ' . $e->getMessage() . "\n"; | |||
echo $e->getFile() . ' - line ' . $e->getLine() . "\n"; | |||
echo $e->getTraceAsString() . "\n"; | |||
} | |||