mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-03 09:54:27 +02:00
Reworking, simplifying, and speeding up cache implementation.
Fixing the infelicity where you couldn't have '|' and ':' inside quoted modifier arguments.
This commit is contained in:
@@ -5,7 +5,7 @@ require_once "PEAR.php";
|
||||
/**
|
||||
* Config_File class.
|
||||
*
|
||||
* @version 1.2.2
|
||||
* @version 1.2.3
|
||||
* @author Andrei Zmievski <andrei@ispi.net>
|
||||
* @access public
|
||||
*
|
||||
|
3
NEWS
3
NEWS
@@ -1,3 +1,6 @@
|
||||
- modifier arguments can now contain | and : characters inside quoted
|
||||
strings. (Andrei)
|
||||
|
||||
Version 1.2.2
|
||||
-------------
|
||||
- fixed bug that would not respect nested template directories and would
|
||||
|
2
README
2
README
@@ -2,7 +2,7 @@ NAME:
|
||||
|
||||
Smarty - the PHP compiling template engine
|
||||
|
||||
VERSION: 1.2.2
|
||||
VERSION: 1.2.3
|
||||
|
||||
AUTHORS:
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* File: Smarty.addons.php
|
||||
* Author: Monte Ohrt <monte@ispi.net>
|
||||
* Andrei Zmievski <andrei@ispi.net>
|
||||
* Version: 1.2.2
|
||||
* Version: 1.2.3
|
||||
* Copyright: 2001 ispi of Lincoln, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
175
Smarty.class.php
175
Smarty.class.php
@@ -5,7 +5,7 @@
|
||||
* Author: Monte Ohrt <monte@ispi.net>
|
||||
* Andrei Zmievski <andrei@ispi.net>
|
||||
*
|
||||
* Version: 1.2.2
|
||||
* Version: 1.2.3
|
||||
* Copyright: 2001 ispi of Lincoln, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -49,19 +49,16 @@ class Smarty
|
||||
// initially compiled. Leave set to true
|
||||
// during development. true/false
|
||||
|
||||
var $compile_force = false; // force templates to compile every time.
|
||||
var $force_compile = false; // force templates to compile every time.
|
||||
// overrides compile_check. true/false
|
||||
var $allow_url_compile = true; // allow forced recompile from URL ?compile_force=1
|
||||
|
||||
// NOTE: all cache directives override
|
||||
// compiling directives. If a cached version
|
||||
// is available, that will be used regardless
|
||||
// of compile settings.
|
||||
var $cache_engine = true; // whether to use caching or not. true/false
|
||||
var $cache_expire = 3600; // number of seconds cached content will expire.
|
||||
var $caching = true; // whether to use caching or not. true/false
|
||||
var $cache_lifetime = 3600; // number of seconds cached content will persist.
|
||||
// 0 = never expires. default is one hour (3600)
|
||||
var $cache_force = false; // force caches to expire every time. true/false
|
||||
var $allow_url_cache = true; // allow forced cache expire from URL ?cache_force=1
|
||||
|
||||
var $template_dir = "./templates"; // name of directory for templates
|
||||
var $compile_dir = "./templates_c"; // name of directory for compiled templates
|
||||
@@ -73,6 +70,7 @@ class Smarty
|
||||
var $allow_php = false; // whether or not to allow embedded php
|
||||
// in the templates. By default, php tags
|
||||
// are escaped. true/false
|
||||
|
||||
var $left_delimiter = "{"; // template tag delimiters.
|
||||
var $right_delimiter = "}";
|
||||
|
||||
@@ -198,57 +196,63 @@ class Smarty
|
||||
|
||||
function display($tpl_file)
|
||||
{
|
||||
print $this->fetch($tpl_file);
|
||||
$this->fetch($tpl_file, true);
|
||||
}
|
||||
|
||||
/*======================================================================*\
|
||||
Function: fetch()
|
||||
Purpose: executes & returns the template results
|
||||
Purpose: executes & returns or displays the template results
|
||||
\*======================================================================*/
|
||||
|
||||
function fetch($tpl_file)
|
||||
function fetch($tpl_file, $display = false)
|
||||
{
|
||||
global $HTTP_GET_VARS,$PHP_SELF;
|
||||
|
||||
if($this->cache_engine)
|
||||
{
|
||||
if($this->allow_url_cache && $HTTP_GET_VARS["cache_force"])
|
||||
$this->cache_force = true;
|
||||
global $PHP_SELF;
|
||||
|
||||
if($this->caching) {
|
||||
// cache id = template path + the invoked script
|
||||
$cache_file = $this->cache_dir."/".urlencode($tpl_file."@".$PHP_SELF).".che";
|
||||
$cache_file = $this->cache_dir."/".urlencode($tpl_file."@".$PHP_SELF).".cache";
|
||||
if(!$this->cache_force &&
|
||||
(file_exists($cache_file) &&
|
||||
($this->cache_expire == 0 ||
|
||||
(mktime() - filectime($cache_file) <= $this->cache_expire)
|
||||
)))
|
||||
{
|
||||
($this->cache_lifetime == 0 ||
|
||||
(mktime() - filemtime($cache_file) <= $this->cache_lifetime)
|
||||
))) {
|
||||
$results = $this->_read_file($cache_file);
|
||||
$results = $this->_process_cached_inserts($results);
|
||||
if ($display) {
|
||||
print $results;
|
||||
return;
|
||||
} else
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
|
||||
if($this->allow_url_compile && $HTTP_GET_VARS["compile_force"])
|
||||
$this->compile_force = true;
|
||||
|
||||
ob_start();
|
||||
// compile files
|
||||
$this->_compile($this->template_dir);
|
||||
//assemble compile directory path to file
|
||||
$_compile_file = $this->compile_dir."/".$tpl_file.".php";
|
||||
|
||||
extract($this->_tpl_vars);
|
||||
|
||||
// if we just need to display the results, don't perform output
|
||||
// buferring - for speed
|
||||
if ($display && !$this->caching)
|
||||
include($_compile_file);
|
||||
else {
|
||||
ob_start();
|
||||
include($_compile_file);
|
||||
$results = ob_get_contents();
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
if($this->cache_engine)
|
||||
{
|
||||
if($this->caching) {
|
||||
$this->_write_file($cache_file, $results);
|
||||
$results = $this->_process_cached_inserts($results);
|
||||
}
|
||||
|
||||
if ($display) {
|
||||
print $results;
|
||||
return;
|
||||
} else
|
||||
return $results;
|
||||
}
|
||||
|
||||
@@ -259,7 +263,7 @@ class Smarty
|
||||
|
||||
function _compile($tpl_dir)
|
||||
{
|
||||
if($this->compile_check || $this->compile_force)
|
||||
if($this->compile_check || $this->force_compile)
|
||||
{
|
||||
if($this->_traverse_files($tpl_dir, 0))
|
||||
return true;
|
||||
@@ -338,8 +342,8 @@ class Smarty
|
||||
}
|
||||
}
|
||||
|
||||
// compile the template file if none exists or has been modified or compile_force
|
||||
if (!file_exists($compile_dir."/".$tpl_file_name) || $this->compile_force ||
|
||||
// compile the template file if none exists or has been modified or recompile is forced
|
||||
if ($this->force_compile || !file_exists($compile_dir."/".$tpl_file_name) ||
|
||||
($this->_modified_file($filepath, $compile_dir."/".$tpl_file_name))) {
|
||||
if (!$this->_compile_file($filepath, $compile_dir."/".$tpl_file_name))
|
||||
return false;
|
||||
@@ -432,37 +436,28 @@ class Smarty
|
||||
|
||||
function _process_cached_inserts($results)
|
||||
{
|
||||
preg_match_all('!\{\{\{insert_cache (.*)\}\}\}!Uis', $results, $match);
|
||||
|
||||
preg_match_all("/\{\{\{insert_cache name=([^ ]+) (.*)\}\}\}/Uis",$results,$match);
|
||||
list($cached_inserts, $insert_args) = $match;
|
||||
|
||||
$fulltags = $match[0];
|
||||
$names = $match[1];
|
||||
$args = $match[2];
|
||||
for ($i = 0; $i < count($cached_inserts); $i++) {
|
||||
$attrs = $this->_parse_attrs($insert_args[$i], false);
|
||||
$name = $this->_dequote($attrs['name']);
|
||||
|
||||
for($curr_tag = 0; $curr_tag < count($fulltags); $curr_tag++)
|
||||
{
|
||||
$attrs = $this->_parse_attrs($args[$curr_tag]);
|
||||
$name = substr($attrs['name'], 1, -1);
|
||||
|
||||
if (empty($names[$curr_tag])) {
|
||||
if (empty($name)) {
|
||||
$this->_syntax_error("missing insert name");
|
||||
}
|
||||
|
||||
$arg_list = array();
|
||||
foreach ($attrs as $arg_name => $arg_value) {
|
||||
if ($arg_name == 'name') continue;
|
||||
if (is_bool($arg_value))
|
||||
$arg_value = $arg_value ? 'true' : 'false';
|
||||
$arg_list[] = "'$arg_name' => $arg_value";
|
||||
$arg_list[$arg_name] = $arg_value;
|
||||
}
|
||||
|
||||
$evalcode = "print insert_".$names[$curr_tag]."(array(".implode(',', (array)$arg_list)."));";
|
||||
$function_name = 'insert_' . $name;
|
||||
$replace = $function_name($arg_list);
|
||||
|
||||
ob_start();
|
||||
eval($evalcode);
|
||||
$replace = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
$results = str_replace($fulltags[$curr_tag],$replace,$results);
|
||||
$results = str_replace($cached_inserts[$i], $replace, $results);
|
||||
}
|
||||
|
||||
return $results;
|
||||
@@ -474,9 +469,11 @@ class Smarty
|
||||
if ($template_tag{0} == '*' && $template_tag{strlen($template_tag)-1} == '*')
|
||||
return "";
|
||||
|
||||
$qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
|
||||
|
||||
/* Split tag into two parts: command and the arguments. */
|
||||
preg_match('/^(
|
||||
(?:"[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | (?>[^"\'\s]+))+
|
||||
(?: ' . $qstr_regexp . ' | (?>[^"\'\s]+))+
|
||||
)
|
||||
(?:\s+(.*))?
|
||||
/xs', $template_tag, $match);
|
||||
@@ -484,9 +481,9 @@ class Smarty
|
||||
|
||||
/* If the tag name matches a variable or section property definition,
|
||||
we simply process it. */
|
||||
if (preg_match('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:[^|]+)?)*$!', $tag_command) || // if a variable
|
||||
preg_match('!^#(\w+)#(?>\|@?\w+(:[^|]+)?)*$!', $tag_command) || // or a configuration variable
|
||||
preg_match('!^%\w+\.\w+%(?>\|@?\w+(:[^|]+)?)*$!', $tag_command)) { // or a section property
|
||||
if (preg_match('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command) || // if a variable
|
||||
preg_match('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command) || // or a configuration variable
|
||||
preg_match('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command)) { // or a section property
|
||||
settype($tag_command, 'array');
|
||||
$this->_parse_vars_props($tag_command);
|
||||
return "<?php print $tag_command[0]; ?>";
|
||||
@@ -571,13 +568,13 @@ class Smarty
|
||||
$attrs = $this->_parse_attrs($tag_args);
|
||||
$name = substr($attrs['name'], 1, -1);
|
||||
|
||||
if($this->cache_engine)
|
||||
return "<?php print \"{{{insert_cache ".addslashes($tag_args)."}}}\"; ?>";
|
||||
|
||||
if (empty($name)) {
|
||||
$this->_syntax_error("missing insert name");
|
||||
}
|
||||
|
||||
if($this->caching)
|
||||
return "{{{insert_cache $tag_args}}}";
|
||||
|
||||
foreach ($attrs as $arg_name => $arg_value) {
|
||||
if ($arg_name == 'name') continue;
|
||||
if (is_bool($arg_value))
|
||||
@@ -855,7 +852,7 @@ class Smarty
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
function _parse_attrs($tag_args)
|
||||
function _parse_attrs($tag_args, $quote = true)
|
||||
{
|
||||
/* Tokenize tag attributes. */
|
||||
preg_match_all('/(?:"[^"\\\\]*(?:\\\\.[^"\\\\]*)*" |
|
||||
@@ -868,9 +865,9 @@ class Smarty
|
||||
|
||||
$attrs = array();
|
||||
/* Parse state:
|
||||
0 - expecting attr name
|
||||
1 - expecting '=' or another attr name
|
||||
2 - expecting attr value (not '=') */
|
||||
0 - expecting attribute name
|
||||
1 - expecting '='
|
||||
2 - expecting attribute value (not '=') */
|
||||
$state = 0;
|
||||
|
||||
foreach ($tokens as $token) {
|
||||
@@ -886,12 +883,7 @@ class Smarty
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* If the token is a valid identifier, the previously set
|
||||
attribute name does not need an argument. We put it in
|
||||
the attrs array, set the new attribute name to the
|
||||
current token and don't switch state.
|
||||
|
||||
If the token is '=', then we go to state 2. */
|
||||
/* If the token is '=', then we go to state 2. */
|
||||
if ($token == '=') {
|
||||
$state = 2;
|
||||
} else
|
||||
@@ -911,7 +903,7 @@ class Smarty
|
||||
/* If the token is not variable (doesn't start with
|
||||
'$', '#', or '%') and not enclosed in single or
|
||||
double quotes we single-quote it. */
|
||||
else if (!in_array($token{0}, $var_delims) &&
|
||||
else if ($quote && !in_array($token{0}, $var_delims) &&
|
||||
!(($token{0} == '"' || $token[0] == "'") &&
|
||||
$token{strlen($token)-1} == $token{0}))
|
||||
$token = "'".$token."'";
|
||||
@@ -943,17 +935,19 @@ class Smarty
|
||||
|
||||
function _parse_vars_props(&$tokens)
|
||||
{
|
||||
$qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
|
||||
|
||||
/* preg_grep() was fixed to return keys properly in 4.0.4 and later. To
|
||||
allow people to use older versions of PHP we emulate preg_grep() and
|
||||
use the version check to see what function to call. */
|
||||
if (strnatcmp(PHP_VERSION, '4.0.4') >= 0) {
|
||||
$var_exprs = preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:[^|]+)?)*$!', $tokens);
|
||||
$conf_var_exprs = preg_grep('!^#(\w+)#(?>\|@?\w+(:[^|]+)?)*$!', $tokens);
|
||||
$sect_prop_exprs = preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:[^|]+)?)*$!', $tokens);
|
||||
$var_exprs = preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens);
|
||||
$conf_var_exprs = preg_grep('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens);
|
||||
$sect_prop_exprs = preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens);
|
||||
} else {
|
||||
$var_exprs = $this->_preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:[^|]+)?)*$!', $tokens);
|
||||
$conf_var_exprs = $this->_preg_grep('!^#(\w+)#(?>\|@?\w+(:[^|]+)?)*$!', $tokens);
|
||||
$sect_prop_exprs = $this->_preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:[^|]+)?)*$!', $tokens);
|
||||
$var_exprs = $this->_preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens);
|
||||
$conf_var_exprs = $this->_preg_grep('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens);
|
||||
$sect_prop_exprs = $this->_preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens);
|
||||
}
|
||||
|
||||
if (count($var_exprs)) {
|
||||
@@ -977,9 +971,9 @@ class Smarty
|
||||
|
||||
function _parse_var($var_expr)
|
||||
{
|
||||
$modifiers = explode('|', substr($var_expr, 1));
|
||||
list($var_ref, $modifiers) = explode('|', substr($var_expr, 1), 2);
|
||||
|
||||
$sections = explode('/', array_shift($modifiers));
|
||||
$sections = explode('/', $var_ref);
|
||||
$props = explode('.', array_pop($sections));
|
||||
$var_name = array_shift($props);
|
||||
|
||||
@@ -999,9 +993,9 @@ class Smarty
|
||||
|
||||
function _parse_conf_var($conf_var_expr)
|
||||
{
|
||||
$modifiers = explode('|', $conf_var_expr);
|
||||
list($var_ref, $modifiers) = explode('|', $conf_var_expr, 2);
|
||||
|
||||
$var_name = substr(array_shift($modifiers), 1, -1);
|
||||
$var_name = substr($var_ref, 1, -1);
|
||||
|
||||
$output = "\$_config['$var_name']";
|
||||
|
||||
@@ -1012,9 +1006,9 @@ class Smarty
|
||||
|
||||
function _parse_section_prop($section_prop_expr)
|
||||
{
|
||||
$modifiers = explode('|', $section_prop_expr);
|
||||
list($var_ref, $modifiers) = explode('|', $section_prop_expr, 2);
|
||||
|
||||
preg_match('!%(\w+)\.(\w+)%!', array_shift($modifiers), $match);
|
||||
preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
|
||||
$section_name = $match[1];
|
||||
$prop_name = $match[2];
|
||||
|
||||
@@ -1025,11 +1019,16 @@ class Smarty
|
||||
return $output;
|
||||
}
|
||||
|
||||
function _parse_modifiers(&$output, $modifiers)
|
||||
function _parse_modifiers(&$output, $modifier_string)
|
||||
{
|
||||
foreach ($modifiers as $modifier) {
|
||||
$modifier = explode(':', $modifier);
|
||||
$modifier_name = array_shift($modifier);
|
||||
$qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
|
||||
preg_match_all('!\|@?(\w+)((?::(?:'. $qstr_regexp . '|[^|]+))*)!', '|' . $modifier_string, $match);
|
||||
list(, $modifiers, $modifier_arg_strings) = $match;
|
||||
|
||||
for ($i = 0; $i < count($modifiers); $i++) {
|
||||
$modifier_name = $modifiers[$i];
|
||||
preg_match_all('!:(' . $qstr_regexp . '|[^|]+)!', $modifier_arg_strings[$i], $match);
|
||||
$modifier_args = $match[1];
|
||||
|
||||
if ($modifier_name{0} == '@') {
|
||||
$map_array = 'false';
|
||||
@@ -1050,10 +1049,10 @@ class Smarty
|
||||
if (!isset($mod_func_name))
|
||||
$mod_func_name = $modifier_name;
|
||||
|
||||
$this->_parse_vars_props($modifier);
|
||||
$this->_parse_vars_props($modifier_args);
|
||||
|
||||
if (count($modifier) > 0)
|
||||
$modifier_args = ', '.implode(', ', $modifier);
|
||||
if (count($modifier_args) > 0)
|
||||
$modifier_args = ', '.implode(', ', $modifier_args);
|
||||
else
|
||||
$modifier_args = '';
|
||||
|
||||
@@ -1071,6 +1070,8 @@ class Smarty
|
||||
if (($string{0} == "'" || $string{0} == '"') &&
|
||||
$string{strlen($string)-1} == $string{0})
|
||||
return substr($string, 1, -1);
|
||||
else
|
||||
return $string;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -4,7 +4,9 @@ require("Smarty.class.php");
|
||||
|
||||
$smarty = new Smarty;
|
||||
|
||||
$smarty->cache_engine = false;
|
||||
$smarty->caching = false;
|
||||
|
||||
$smarty->assign(now, time());
|
||||
|
||||
$smarty->assign("Name","Fred Irving Johnathan Bradley Peppergill");
|
||||
$smarty->assign("FirstName",array("John","Mary","James","Henry"));
|
||||
@@ -19,4 +21,11 @@ $smarty->assign("now",time());
|
||||
|
||||
$smarty->display("index.tpl");
|
||||
|
||||
function insert_foo($args)
|
||||
{
|
||||
extract($args);
|
||||
|
||||
return "test $arg1";
|
||||
}
|
||||
|
||||
?>
|
||||
|
@@ -48,3 +48,5 @@ testing strip tags
|
||||
</PRE>
|
||||
|
||||
test: {$now|date_format:"%I:%M %p"}
|
||||
|
||||
{insert name = foo arg1=5}
|
||||
|
@@ -14,7 +14,7 @@
|
||||
<address><email>andrei@ispi.net</email></address>
|
||||
</affiliation>
|
||||
</author>
|
||||
<edition>Version 1.2.2</edition>
|
||||
<edition>Version 1.2.3</edition>
|
||||
<copyright><year>2001</year><holder>ispi of Lincoln, Inc.</holder></copyright>
|
||||
</bookinfo>
|
||||
<chapter>
|
||||
|
11
index.php
11
index.php
@@ -4,7 +4,9 @@ require("Smarty.class.php");
|
||||
|
||||
$smarty = new Smarty;
|
||||
|
||||
$smarty->cache_engine = false;
|
||||
$smarty->caching = false;
|
||||
|
||||
$smarty->assign(now, time());
|
||||
|
||||
$smarty->assign("Name","Fred Irving Johnathan Bradley Peppergill");
|
||||
$smarty->assign("FirstName",array("John","Mary","James","Henry"));
|
||||
@@ -19,4 +21,11 @@ $smarty->assign("now",time());
|
||||
|
||||
$smarty->display("index.tpl");
|
||||
|
||||
function insert_foo($args)
|
||||
{
|
||||
extract($args);
|
||||
|
||||
return "test $arg1";
|
||||
}
|
||||
|
||||
?>
|
||||
|
@@ -5,7 +5,7 @@ require_once "PEAR.php";
|
||||
/**
|
||||
* Config_File class.
|
||||
*
|
||||
* @version 1.2.2
|
||||
* @version 1.2.3
|
||||
* @author Andrei Zmievski <andrei@ispi.net>
|
||||
* @access public
|
||||
*
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* Author: Monte Ohrt <monte@ispi.net>
|
||||
* Andrei Zmievski <andrei@ispi.net>
|
||||
*
|
||||
* Version: 1.2.2
|
||||
* Version: 1.2.3
|
||||
* Copyright: 2001 ispi of Lincoln, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -49,19 +49,16 @@ class Smarty
|
||||
// initially compiled. Leave set to true
|
||||
// during development. true/false
|
||||
|
||||
var $compile_force = false; // force templates to compile every time.
|
||||
var $force_compile = false; // force templates to compile every time.
|
||||
// overrides compile_check. true/false
|
||||
var $allow_url_compile = true; // allow forced recompile from URL ?compile_force=1
|
||||
|
||||
// NOTE: all cache directives override
|
||||
// compiling directives. If a cached version
|
||||
// is available, that will be used regardless
|
||||
// of compile settings.
|
||||
var $cache_engine = true; // whether to use caching or not. true/false
|
||||
var $cache_expire = 3600; // number of seconds cached content will expire.
|
||||
var $caching = true; // whether to use caching or not. true/false
|
||||
var $cache_lifetime = 3600; // number of seconds cached content will persist.
|
||||
// 0 = never expires. default is one hour (3600)
|
||||
var $cache_force = false; // force caches to expire every time. true/false
|
||||
var $allow_url_cache = true; // allow forced cache expire from URL ?cache_force=1
|
||||
|
||||
var $template_dir = "./templates"; // name of directory for templates
|
||||
var $compile_dir = "./templates_c"; // name of directory for compiled templates
|
||||
@@ -73,6 +70,7 @@ class Smarty
|
||||
var $allow_php = false; // whether or not to allow embedded php
|
||||
// in the templates. By default, php tags
|
||||
// are escaped. true/false
|
||||
|
||||
var $left_delimiter = "{"; // template tag delimiters.
|
||||
var $right_delimiter = "}";
|
||||
|
||||
@@ -198,57 +196,63 @@ class Smarty
|
||||
|
||||
function display($tpl_file)
|
||||
{
|
||||
print $this->fetch($tpl_file);
|
||||
$this->fetch($tpl_file, true);
|
||||
}
|
||||
|
||||
/*======================================================================*\
|
||||
Function: fetch()
|
||||
Purpose: executes & returns the template results
|
||||
Purpose: executes & returns or displays the template results
|
||||
\*======================================================================*/
|
||||
|
||||
function fetch($tpl_file)
|
||||
function fetch($tpl_file, $display = false)
|
||||
{
|
||||
global $HTTP_GET_VARS,$PHP_SELF;
|
||||
|
||||
if($this->cache_engine)
|
||||
{
|
||||
if($this->allow_url_cache && $HTTP_GET_VARS["cache_force"])
|
||||
$this->cache_force = true;
|
||||
global $PHP_SELF;
|
||||
|
||||
if($this->caching) {
|
||||
// cache id = template path + the invoked script
|
||||
$cache_file = $this->cache_dir."/".urlencode($tpl_file."@".$PHP_SELF).".che";
|
||||
$cache_file = $this->cache_dir."/".urlencode($tpl_file."@".$PHP_SELF).".cache";
|
||||
if(!$this->cache_force &&
|
||||
(file_exists($cache_file) &&
|
||||
($this->cache_expire == 0 ||
|
||||
(mktime() - filectime($cache_file) <= $this->cache_expire)
|
||||
)))
|
||||
{
|
||||
($this->cache_lifetime == 0 ||
|
||||
(mktime() - filemtime($cache_file) <= $this->cache_lifetime)
|
||||
))) {
|
||||
$results = $this->_read_file($cache_file);
|
||||
$results = $this->_process_cached_inserts($results);
|
||||
if ($display) {
|
||||
print $results;
|
||||
return;
|
||||
} else
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
|
||||
if($this->allow_url_compile && $HTTP_GET_VARS["compile_force"])
|
||||
$this->compile_force = true;
|
||||
|
||||
ob_start();
|
||||
// compile files
|
||||
$this->_compile($this->template_dir);
|
||||
//assemble compile directory path to file
|
||||
$_compile_file = $this->compile_dir."/".$tpl_file.".php";
|
||||
|
||||
extract($this->_tpl_vars);
|
||||
|
||||
// if we just need to display the results, don't perform output
|
||||
// buferring - for speed
|
||||
if ($display && !$this->caching)
|
||||
include($_compile_file);
|
||||
else {
|
||||
ob_start();
|
||||
include($_compile_file);
|
||||
$results = ob_get_contents();
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
if($this->cache_engine)
|
||||
{
|
||||
if($this->caching) {
|
||||
$this->_write_file($cache_file, $results);
|
||||
$results = $this->_process_cached_inserts($results);
|
||||
}
|
||||
|
||||
if ($display) {
|
||||
print $results;
|
||||
return;
|
||||
} else
|
||||
return $results;
|
||||
}
|
||||
|
||||
@@ -259,7 +263,7 @@ class Smarty
|
||||
|
||||
function _compile($tpl_dir)
|
||||
{
|
||||
if($this->compile_check || $this->compile_force)
|
||||
if($this->compile_check || $this->force_compile)
|
||||
{
|
||||
if($this->_traverse_files($tpl_dir, 0))
|
||||
return true;
|
||||
@@ -338,8 +342,8 @@ class Smarty
|
||||
}
|
||||
}
|
||||
|
||||
// compile the template file if none exists or has been modified or compile_force
|
||||
if (!file_exists($compile_dir."/".$tpl_file_name) || $this->compile_force ||
|
||||
// compile the template file if none exists or has been modified or recompile is forced
|
||||
if ($this->force_compile || !file_exists($compile_dir."/".$tpl_file_name) ||
|
||||
($this->_modified_file($filepath, $compile_dir."/".$tpl_file_name))) {
|
||||
if (!$this->_compile_file($filepath, $compile_dir."/".$tpl_file_name))
|
||||
return false;
|
||||
@@ -432,37 +436,28 @@ class Smarty
|
||||
|
||||
function _process_cached_inserts($results)
|
||||
{
|
||||
preg_match_all('!\{\{\{insert_cache (.*)\}\}\}!Uis', $results, $match);
|
||||
|
||||
preg_match_all("/\{\{\{insert_cache name=([^ ]+) (.*)\}\}\}/Uis",$results,$match);
|
||||
list($cached_inserts, $insert_args) = $match;
|
||||
|
||||
$fulltags = $match[0];
|
||||
$names = $match[1];
|
||||
$args = $match[2];
|
||||
for ($i = 0; $i < count($cached_inserts); $i++) {
|
||||
$attrs = $this->_parse_attrs($insert_args[$i], false);
|
||||
$name = $this->_dequote($attrs['name']);
|
||||
|
||||
for($curr_tag = 0; $curr_tag < count($fulltags); $curr_tag++)
|
||||
{
|
||||
$attrs = $this->_parse_attrs($args[$curr_tag]);
|
||||
$name = substr($attrs['name'], 1, -1);
|
||||
|
||||
if (empty($names[$curr_tag])) {
|
||||
if (empty($name)) {
|
||||
$this->_syntax_error("missing insert name");
|
||||
}
|
||||
|
||||
$arg_list = array();
|
||||
foreach ($attrs as $arg_name => $arg_value) {
|
||||
if ($arg_name == 'name') continue;
|
||||
if (is_bool($arg_value))
|
||||
$arg_value = $arg_value ? 'true' : 'false';
|
||||
$arg_list[] = "'$arg_name' => $arg_value";
|
||||
$arg_list[$arg_name] = $arg_value;
|
||||
}
|
||||
|
||||
$evalcode = "print insert_".$names[$curr_tag]."(array(".implode(',', (array)$arg_list)."));";
|
||||
$function_name = 'insert_' . $name;
|
||||
$replace = $function_name($arg_list);
|
||||
|
||||
ob_start();
|
||||
eval($evalcode);
|
||||
$replace = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
$results = str_replace($fulltags[$curr_tag],$replace,$results);
|
||||
$results = str_replace($cached_inserts[$i], $replace, $results);
|
||||
}
|
||||
|
||||
return $results;
|
||||
@@ -474,9 +469,11 @@ class Smarty
|
||||
if ($template_tag{0} == '*' && $template_tag{strlen($template_tag)-1} == '*')
|
||||
return "";
|
||||
|
||||
$qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
|
||||
|
||||
/* Split tag into two parts: command and the arguments. */
|
||||
preg_match('/^(
|
||||
(?:"[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | (?>[^"\'\s]+))+
|
||||
(?: ' . $qstr_regexp . ' | (?>[^"\'\s]+))+
|
||||
)
|
||||
(?:\s+(.*))?
|
||||
/xs', $template_tag, $match);
|
||||
@@ -484,9 +481,9 @@ class Smarty
|
||||
|
||||
/* If the tag name matches a variable or section property definition,
|
||||
we simply process it. */
|
||||
if (preg_match('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:[^|]+)?)*$!', $tag_command) || // if a variable
|
||||
preg_match('!^#(\w+)#(?>\|@?\w+(:[^|]+)?)*$!', $tag_command) || // or a configuration variable
|
||||
preg_match('!^%\w+\.\w+%(?>\|@?\w+(:[^|]+)?)*$!', $tag_command)) { // or a section property
|
||||
if (preg_match('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command) || // if a variable
|
||||
preg_match('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command) || // or a configuration variable
|
||||
preg_match('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command)) { // or a section property
|
||||
settype($tag_command, 'array');
|
||||
$this->_parse_vars_props($tag_command);
|
||||
return "<?php print $tag_command[0]; ?>";
|
||||
@@ -571,13 +568,13 @@ class Smarty
|
||||
$attrs = $this->_parse_attrs($tag_args);
|
||||
$name = substr($attrs['name'], 1, -1);
|
||||
|
||||
if($this->cache_engine)
|
||||
return "<?php print \"{{{insert_cache ".addslashes($tag_args)."}}}\"; ?>";
|
||||
|
||||
if (empty($name)) {
|
||||
$this->_syntax_error("missing insert name");
|
||||
}
|
||||
|
||||
if($this->caching)
|
||||
return "{{{insert_cache $tag_args}}}";
|
||||
|
||||
foreach ($attrs as $arg_name => $arg_value) {
|
||||
if ($arg_name == 'name') continue;
|
||||
if (is_bool($arg_value))
|
||||
@@ -855,7 +852,7 @@ class Smarty
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
function _parse_attrs($tag_args)
|
||||
function _parse_attrs($tag_args, $quote = true)
|
||||
{
|
||||
/* Tokenize tag attributes. */
|
||||
preg_match_all('/(?:"[^"\\\\]*(?:\\\\.[^"\\\\]*)*" |
|
||||
@@ -868,9 +865,9 @@ class Smarty
|
||||
|
||||
$attrs = array();
|
||||
/* Parse state:
|
||||
0 - expecting attr name
|
||||
1 - expecting '=' or another attr name
|
||||
2 - expecting attr value (not '=') */
|
||||
0 - expecting attribute name
|
||||
1 - expecting '='
|
||||
2 - expecting attribute value (not '=') */
|
||||
$state = 0;
|
||||
|
||||
foreach ($tokens as $token) {
|
||||
@@ -886,12 +883,7 @@ class Smarty
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* If the token is a valid identifier, the previously set
|
||||
attribute name does not need an argument. We put it in
|
||||
the attrs array, set the new attribute name to the
|
||||
current token and don't switch state.
|
||||
|
||||
If the token is '=', then we go to state 2. */
|
||||
/* If the token is '=', then we go to state 2. */
|
||||
if ($token == '=') {
|
||||
$state = 2;
|
||||
} else
|
||||
@@ -911,7 +903,7 @@ class Smarty
|
||||
/* If the token is not variable (doesn't start with
|
||||
'$', '#', or '%') and not enclosed in single or
|
||||
double quotes we single-quote it. */
|
||||
else if (!in_array($token{0}, $var_delims) &&
|
||||
else if ($quote && !in_array($token{0}, $var_delims) &&
|
||||
!(($token{0} == '"' || $token[0] == "'") &&
|
||||
$token{strlen($token)-1} == $token{0}))
|
||||
$token = "'".$token."'";
|
||||
@@ -943,17 +935,19 @@ class Smarty
|
||||
|
||||
function _parse_vars_props(&$tokens)
|
||||
{
|
||||
$qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
|
||||
|
||||
/* preg_grep() was fixed to return keys properly in 4.0.4 and later. To
|
||||
allow people to use older versions of PHP we emulate preg_grep() and
|
||||
use the version check to see what function to call. */
|
||||
if (strnatcmp(PHP_VERSION, '4.0.4') >= 0) {
|
||||
$var_exprs = preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:[^|]+)?)*$!', $tokens);
|
||||
$conf_var_exprs = preg_grep('!^#(\w+)#(?>\|@?\w+(:[^|]+)?)*$!', $tokens);
|
||||
$sect_prop_exprs = preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:[^|]+)?)*$!', $tokens);
|
||||
$var_exprs = preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens);
|
||||
$conf_var_exprs = preg_grep('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens);
|
||||
$sect_prop_exprs = preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens);
|
||||
} else {
|
||||
$var_exprs = $this->_preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:[^|]+)?)*$!', $tokens);
|
||||
$conf_var_exprs = $this->_preg_grep('!^#(\w+)#(?>\|@?\w+(:[^|]+)?)*$!', $tokens);
|
||||
$sect_prop_exprs = $this->_preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:[^|]+)?)*$!', $tokens);
|
||||
$var_exprs = $this->_preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens);
|
||||
$conf_var_exprs = $this->_preg_grep('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens);
|
||||
$sect_prop_exprs = $this->_preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens);
|
||||
}
|
||||
|
||||
if (count($var_exprs)) {
|
||||
@@ -977,9 +971,9 @@ class Smarty
|
||||
|
||||
function _parse_var($var_expr)
|
||||
{
|
||||
$modifiers = explode('|', substr($var_expr, 1));
|
||||
list($var_ref, $modifiers) = explode('|', substr($var_expr, 1), 2);
|
||||
|
||||
$sections = explode('/', array_shift($modifiers));
|
||||
$sections = explode('/', $var_ref);
|
||||
$props = explode('.', array_pop($sections));
|
||||
$var_name = array_shift($props);
|
||||
|
||||
@@ -999,9 +993,9 @@ class Smarty
|
||||
|
||||
function _parse_conf_var($conf_var_expr)
|
||||
{
|
||||
$modifiers = explode('|', $conf_var_expr);
|
||||
list($var_ref, $modifiers) = explode('|', $conf_var_expr, 2);
|
||||
|
||||
$var_name = substr(array_shift($modifiers), 1, -1);
|
||||
$var_name = substr($var_ref, 1, -1);
|
||||
|
||||
$output = "\$_config['$var_name']";
|
||||
|
||||
@@ -1012,9 +1006,9 @@ class Smarty
|
||||
|
||||
function _parse_section_prop($section_prop_expr)
|
||||
{
|
||||
$modifiers = explode('|', $section_prop_expr);
|
||||
list($var_ref, $modifiers) = explode('|', $section_prop_expr, 2);
|
||||
|
||||
preg_match('!%(\w+)\.(\w+)%!', array_shift($modifiers), $match);
|
||||
preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
|
||||
$section_name = $match[1];
|
||||
$prop_name = $match[2];
|
||||
|
||||
@@ -1025,11 +1019,16 @@ class Smarty
|
||||
return $output;
|
||||
}
|
||||
|
||||
function _parse_modifiers(&$output, $modifiers)
|
||||
function _parse_modifiers(&$output, $modifier_string)
|
||||
{
|
||||
foreach ($modifiers as $modifier) {
|
||||
$modifier = explode(':', $modifier);
|
||||
$modifier_name = array_shift($modifier);
|
||||
$qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
|
||||
preg_match_all('!\|@?(\w+)((?::(?:'. $qstr_regexp . '|[^|]+))*)!', '|' . $modifier_string, $match);
|
||||
list(, $modifiers, $modifier_arg_strings) = $match;
|
||||
|
||||
for ($i = 0; $i < count($modifiers); $i++) {
|
||||
$modifier_name = $modifiers[$i];
|
||||
preg_match_all('!:(' . $qstr_regexp . '|[^|]+)!', $modifier_arg_strings[$i], $match);
|
||||
$modifier_args = $match[1];
|
||||
|
||||
if ($modifier_name{0} == '@') {
|
||||
$map_array = 'false';
|
||||
@@ -1050,10 +1049,10 @@ class Smarty
|
||||
if (!isset($mod_func_name))
|
||||
$mod_func_name = $modifier_name;
|
||||
|
||||
$this->_parse_vars_props($modifier);
|
||||
$this->_parse_vars_props($modifier_args);
|
||||
|
||||
if (count($modifier) > 0)
|
||||
$modifier_args = ', '.implode(', ', $modifier);
|
||||
if (count($modifier_args) > 0)
|
||||
$modifier_args = ', '.implode(', ', $modifier_args);
|
||||
else
|
||||
$modifier_args = '';
|
||||
|
||||
@@ -1071,6 +1070,8 @@ class Smarty
|
||||
if (($string{0} == "'" || $string{0} == '"') &&
|
||||
$string{strlen($string)-1} == $string{0})
|
||||
return substr($string, 1, -1);
|
||||
else
|
||||
return $string;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -48,3 +48,5 @@ testing strip tags
|
||||
</PRE>
|
||||
|
||||
test: {$now|date_format:"%I:%M %p"}
|
||||
|
||||
{insert name = foo arg1=5}
|
||||
|
Reference in New Issue
Block a user