Browse Source

Refactor, add autoload mechanisme

master
Thierry 2 years ago
parent
commit
9d0887037f
20 changed files with 1679 additions and 60 deletions
  1. +2
    -0
      sites/tig12.net/commands/addfooter.yml
  2. +5
    -0
      sites/tig12.net/config.yml
  3. +18
    -0
      src/app/autoload.php
  4. +114
    -0
      src/app/jthAutoload_nonamespace.php
  5. +0
    -0
      src/commands/makenav.php
  6. +0
    -0
      src/commands/parsepage.php
  7. +141
    -0
      src/lib/dirs/jth_rscandir.php
  8. +0
    -0
      src/lib/patterns/command/Command.php
  9. +0
    -0
      src/lib/patterns/composite/Composite.php
  10. +0
    -0
      src/lib/patterns/composite/GOFDiagram2.java
  11. +0
    -0
      src/lib/patterns/composite/Leaf.php
  12. +0
    -0
      src/lib/patterns/composite/Node.php
  13. +50
    -0
      src/lib/yaml/jthYAML.php
  14. +10
    -0
      src/lib/yaml/symfony/README
  15. +135
    -0
      src/lib/yaml/symfony/sfYaml.php
  16. +60
    -0
      src/lib/yaml/symfony/sfYamlDumper.php
  17. +442
    -0
      src/lib/yaml/symfony/sfYamlInline.php
  18. +622
    -0
      src/lib/yaml/symfony/sfYamlParser.php
  19. +0
    -60
      src/php/run-tigsite.php
  20. +80
    -0
      src/run-tigsite.php

+ 2
- 0
sites/tig12.net/commands/addfooter.yml View File

@@ -0,0 +1,2 @@
files: /
footer:

+ 5
- 0
sites/tig12.net/config.yml View File

@@ -0,0 +1,5 @@
location: /home/thierry/dev/tig12/tig12.net/web
exclude:
- .git
- static
- x-templates

+ 18
- 0
src/app/autoload.php View File

@@ -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']);

+ 114
- 0
src/app/jthAutoload_nonamespace.php View File

@@ -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

src/php/commands/makenav.php → src/commands/makenav.php View File


src/php/commands/parsepage.php → src/commands/parsepage.php View File


+ 141
- 0
src/lib/dirs/jth_rscandir.php View File

@@ -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

src/php/lib/patterns/command/Command.php → src/lib/patterns/command/Command.php View File


src/php/lib/patterns/composite/Composite.php → src/lib/patterns/composite/Composite.php View File


src/php/lib/patterns/composite/GOFDiagram2.java → src/lib/patterns/composite/GOFDiagram2.java View File


src/php/lib/patterns/composite/Leaf.php → src/lib/patterns/composite/Leaf.php View File


src/php/lib/patterns/composite/Node.php → src/lib/patterns/composite/Node.php View File


+ 50
- 0
src/lib/yaml/jthYAML.php View File

@@ -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


+ 10
- 0
src/lib/yaml/symfony/README View File

@@ -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



+ 135
- 0
src/lib/yaml/symfony/sfYaml.php View File

@@ -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";
}

+ 60
- 0
src/lib/yaml/symfony/sfYamlDumper.php View File

@@ -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;
}
}

+ 442
- 0
src/lib/yaml/symfony/sfYamlInline.php View File

@@ -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;
}
}

+ 622
- 0
src/lib/yaml/symfony/sfYamlParser.php View File

@@ -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;
}
}

+ 0
- 60
src/php/run-tigsite.php View File

@@ -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";
}


+ 80
- 0
src/run-tigsite.php View File

@@ -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";
}


Loading…
Cancel
Save