newer template

master
vitalif 2013-02-21 21:18:30 +00:00
parent a274138775
commit e1953bb666
1 changed files with 46 additions and 36 deletions

View File

@ -8,7 +8,7 @@
# Homepage: http://yourcmc.ru/wiki/VMX::Template # Homepage: http://yourcmc.ru/wiki/VMX::Template
# Author: Vitaliy Filippov, 2006-2013 # Author: Vitaliy Filippov, 2006-2013
# $Id: template.php 1356 2013-02-17 11:45:17Z vitalif $ # $Id$
class VMXTemplateState class VMXTemplateState
{ {
@ -63,9 +63,6 @@ class VMXTemplate
// Version of code classes, saved into static $version // Version of code classes, saved into static $version
const CODE_VERSION = 3; const CODE_VERSION = 3;
// Logged errors
var $errors = array();
// Data passed to the template // Data passed to the template
var $tpldata = array(); var $tpldata = array();
@ -92,18 +89,6 @@ class VMXTemplate
$this->options = new VMXTemplateOptions($options); $this->options = new VMXTemplateOptions($options);
} }
/**
* Log an error
*/
function error($e, $fatal = false)
{
$this->errors[] = $e;
if ($this->options->raise_error && $fatal)
die(__CLASS__." error: $e");
elseif ($this->options->print_error)
print __CLASS__." error: $e<br />";
}
/** /**
* Clear template data * Clear template data
*/ */
@ -277,7 +262,8 @@ class VMXTemplate
} }
if (!($text = $this->loadfile($fn))) if (!($text = $this->loadfile($fn)))
{ {
$this->error("couldn't load template file '$fn'", true); $e = error_get_last();
$this->options->error("couldn't load template file '$fn': ".$e['message'], true);
$this->failed[$fn] = true; $this->failed[$fn] = true;
return NULL; return NULL;
} }
@ -289,14 +275,14 @@ class VMXTemplate
$r = include($file); $r = include($file);
if ($r !== 1) if ($r !== 1)
{ {
$this->error("error including compiled template for '$fn'", true); $this->options->error("error including compiled template for '$fn'", true);
$this->failed[$fn] = true; $this->failed[$fn] = true;
return NULL; return NULL;
} }
if (!class_exists($class) || !isset($class::$version) || $class::$version < self::CODE_VERSION) if (!class_exists($class) || !isset($class::$version) || $class::$version < self::CODE_VERSION)
{ {
// Cache file from some older version - reset it // Cache file from some older version - reset it
$this->error("Please, clear template cache path after upgrading VMX::Template", true); $this->options->error("Please, clear template cache path after upgrading VMX::Template", true);
$this->failed[$fn] = true; $this->failed[$fn] = true;
return NULL; return NULL;
} }
@ -357,7 +343,7 @@ class VMXTemplate
$load = false; $load = false;
if (!($text = self::cache_get("U$fn")) || $this->options->reload) if (!($text = self::cache_get("U$fn")) || $this->options->reload)
{ {
$mtime = stat($fn); $mtime = @stat($fn);
$mtime = $mtime[9]; $mtime = $mtime[9];
if (!$text) if (!$text)
{ {
@ -375,7 +361,7 @@ class VMXTemplate
// Reload if file changed // Reload if file changed
if ($load) if ($load)
{ {
if ($fp = fopen($fn, "rb")) if ($fp = @fopen($fn, "rb"))
{ {
fseek($fp, 0, SEEK_END); fseek($fp, 0, SEEK_END);
$t = ftell($fp); $t = ftell($fp);
@ -518,7 +504,7 @@ class VMXTemplate
{ {
if (is_callable($sub)) if (is_callable($sub))
return call_user_func_array($sub, $args); return call_user_func_array($sub, $args);
$this->error("Unknown function: '$f'"); $this->parent->options->error("Unknown function: '$f'");
return NULL; return NULL;
} }
@ -727,14 +713,19 @@ class VMXTemplateOptions
var $filters = array(); // filter to run on output of every template var $filters = array(); // filter to run on output of every template
var $use_utf8 = true; // use UTF-8 for all string operations on template variables var $use_utf8 = true; // use UTF-8 for all string operations on template variables
var $raise_error = false; // die() on fatal template errors var $raise_error = false; // die() on fatal template errors
var $log_error = false; // send errors to standard error output
var $print_error = false; // print fatal template errors var $print_error = false; // print fatal template errors
var $strict_end = false; // require block name in ending instructions for FOR, BEGIN, SET and FUNCTION <!-- END block --> var $strict_end = false; // require block name in ending instructions for FOR, BEGIN, SET and FUNCTION <!-- END block -->
var $strip_space = false; // strip spaces from beginning and end of each line var $strip_space = false; // strip spaces from beginning and end of each line
var $compiletime_functions = array(); // custom compile-time functions (code generators) var $compiletime_functions = array(); // custom compile-time functions (code generators)
// Logged errors (not an option)
var $errors;
function __construct($options = array()) function __construct($options = array())
{ {
$this->set($options); $this->set($options);
$this->errors = array();
} }
function set($options) function set($options)
@ -763,6 +754,34 @@ class VMXTemplateOptions
} }
$this->root = preg_replace('!/*$!s', '/', $this->root); $this->root = preg_replace('!/*$!s', '/', $this->root);
} }
function __destruct()
{
if ($this->print_error && $this->errors && PHP_SAPI != 'cli')
{
print '<div id="template-errors" style="display: block; border: 1px solid black; padding: 8px; background: #fcc">'.
'VMXTemplate errors:<ul><li>'.
implode('</li><li>', array_map('html_pbr', $this->errors)).
'</li></ul>';
$fp = fopen("php://stderr", 'a');
fprintf($fp, "VMXTemplate errors:\n".implode("\n", $this->errors));
fclose($fp);
}
}
/**
* Log an error or a warning
*/
function error($e, $fatal = false)
{
$this->errors[] = $e;
if ($this->raise_error && $fatal)
die("VMXTemplate error: $e");
if ($this->log_error)
error_log("VMXTemplate error: $e");
elseif ($this->print_error && PHP_SAPI == 'cli')
print("VMXTemplate error: $e\n");
}
} }
/** /**
@ -785,7 +804,7 @@ class VMXTemplateParser
var $tokens, $tokpos, $tokline, $ptr; var $tokens, $tokpos, $tokline, $ptr;
// Possible tokens consisting of special characters // Possible tokens consisting of special characters
static $chartokens = '+ - = * / % ! , . < > ( ) { } [ ] | || && == != <= >= =>'; static $chartokens = '+ - = * / % ! , . < > ( ) { } [ ] | .. && == != <= >= =>';
// ops_and: ops_eq | ops_eq "&&" ops_and | ops_eq "AND" ops_and // ops_and: ops_eq | ops_eq "&&" ops_and | ops_eq "AND" ops_and
// ops_eq: ops_cmp | ops_cmp "==" ops_cmp | ops_cmp "!=" ops_cmp // ops_eq: ops_cmp | ops_cmp "==" ops_cmp | ops_cmp "!=" ops_cmp
@ -933,17 +952,7 @@ class VMXTemplateParser
function warn($text) function warn($text)
{ {
if ($this->options->print_error) $this->options->error($text);
{
if (PHP_SAPI == 'cli')
{
print "$text\n";
}
else
{
print htmlspecialchars($text).'<br />';
}
}
} }
function raise($msg) function raise($msg)
@ -1543,7 +1552,8 @@ $varref = \$item;
$varref_index = \$stack[count(\$stack)-1]++;"; $varref_index = \$stack[count(\$stack)-1]++;";
} }
// exp: ops_or | ops_or "|" exp // (concatenation)
// exp: ops_or | ops_or ".." exp
function parse_exp() function parse_exp()
{ {
if (strtolower($this->tok()) == '$not') if (strtolower($this->tok()) == '$not')
@ -1552,7 +1562,7 @@ $varref_index = \$stack[count(\$stack)-1]++;";
return '(!'.$this->parse_exp().')'; return '(!'.$this->parse_exp().')';
} }
$e = array($this->parse_or()); $e = array($this->parse_or());
while ($this->tok() == '|') while ($this->tok() == '..')
{ {
$this->ptr++; $this->ptr++;
$e[] = $this->parse_or(); $e[] = $this->parse_or();