Implemented plugin architecture.

This commit is contained in:
andrey
2002-01-31 20:49:40 +00:00
parent 70b076bf0b
commit e6fc0e5291
69 changed files with 3561 additions and 1706 deletions

View File

@@ -6,4 +6,5 @@ Monte Ohrt <monte@ispi.net>
Andrei Zmievski <andrei@php.net> Andrei Zmievski <andrei@php.net>
- rewrote parser from scratch - rewrote parser from scratch
- maintains code base - maintains code base
- plugin architecture
- wrote Config_File class - wrote Config_File class

View File

@@ -3,7 +3,8 @@ Monte Ohrt <monte@ispi.net>:
concept" implementation, and maintains documentation & code base. concept" implementation, and maintains documentation & code base.
Andrei Zmievski <andrei@php.net>: Andrei Zmievski <andrei@php.net>:
Rewrote parser from scratch and maintains code base. Rewrote parser from scratch, developed plugin architecture, and maintains
code base.
Anne Holz <anne@ispi.net>: Anne Holz <anne@ispi.net>:
Provided creative input with respect to web design. Provided creative input with respect to web design.
@@ -18,5 +19,5 @@ A special thanks goes to the members of the php-template mailing list and the
smarty mailing list, too numerous to list, who are sharing and bringing many smarty mailing list, too numerous to list, who are sharing and bringing many
ideas to the table and contributing source code. ideas to the table and contributing source code.
Rasmus Lerdorf <rasmus@php.net>: For starting what eventually became Rasmus Lerdorf <rasmus@php.net>: For starting what eventually became the
the coolest programming language ever. coolest programming language ever.

View File

@@ -9,7 +9,7 @@ require_once "PEAR.php";
* @author Andrei Zmievski <andrei@php.net> * @author Andrei Zmievski <andrei@php.net>
* @access public * @access public
* *
* Copyright: 2001 ispi of Lincoln, Inc. * Copyright: 2001,2002 ispi of Lincoln, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

2
README
View File

@@ -64,6 +64,6 @@ DESCRIPTION:
* arbitrary template sources (flat files, databases, etc.) * arbitrary template sources (flat files, databases, etc.)
COPYRIGHT: COPYRIGHT:
Copyright (c) 2001 ispi of Lincoln, Inc. All rights reserved. Copyright (c) 2001,2002 ispi of Lincoln, Inc. All rights reserved.
This software is released under the GNU Lesser General Public License. This software is released under the GNU Lesser General Public License.
Please read the disclaimer at the top of the Smarty.class.php file. Please read the disclaimer at the top of the Smarty.class.php file.

View File

@@ -1,891 +0,0 @@
<?php
/*
* Project: Smarty: the PHP compiled template engine
* File: Smarty.addons.php
* Author: Monte Ohrt <monte@ispi.net>
* Andrei Zmievski <andrei@php.net>
* Version: 1.5.2
* Copyright: 2001 ispi of Lincoln, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You may contact the authors of Smarty by e-mail at:
* monte@ispi.net
* andrei@php.net
*
* Or, write to:
* Monte Ohrt
* Directory of Technology, ispi
* 237 S. 70th suite 220
* Lincoln, NE 68510
*
* The latest version of Smarty can be obtained from:
* http://www.phpinsider.com
*
*/
/*============================================*\
Modifiers
\*============================================*/
/*======================================================================*\
Function: smarty_mod_escape
Purpose: Escape the string according to escapement type
\*======================================================================*/
function smarty_mod_escape($string, $esc_type = 'html')
{
switch ($esc_type) {
case 'html':
return htmlspecialchars($string, ENT_QUOTES);
case 'url':
return urlencode($string);
case 'quotes':
// escape unescaped single quotes
return preg_replace("%(?<!\\\\)'%", "\\'", $string);
default:
return $string;
}
}
/*======================================================================*\
Function: smarty_mod_truncate
Purpose: Truncate a string to a certain length if necessary,
optionally splitting in the middle of a word, and
appending the $etc string.
\*======================================================================*/
function smarty_mod_truncate($string, $length = 80, $etc = '...', $break_words = false)
{
if ($length == 0)
return '';
if (strlen($string) > $length) {
$length -= strlen($etc);
$fragment = substr($string, 0, $length+1);
if ($break_words)
$fragment = substr($fragment, 0, -1);
else
$fragment = preg_replace('/\s+(\S+)?$/', '', $fragment);
return $fragment.$etc;
} else
return $string;
}
/*======================================================================*\
Function: smarty_mod_spacify
Purpose: add spaces between characters in a string
\*======================================================================*/
function smarty_mod_spacify($string, $spacify_char = ' ')
{
return implode($spacify_char, preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY));
}
/*======================================================================*\
Function: smarty_mod_date_format
Purpose: format datestamps via strftime
\*======================================================================*/
function smarty_mod_date_format($string, $format="%b %e, %Y")
{
return strftime($format, smarty_make_timestamp($string));
}
/*======================================================================*\
Function: smarty_make_timestamp
Purpose: used by other smarty functions to make a timestamp
from a string of characters.
\*======================================================================*/
function smarty_make_timestamp($string)
{
if(empty($string)) {
$string = "now";
}
$time = strtotime($string);
if (is_numeric($time) && $time != -1)
return $time;
// is mysql timestamp format of YYYYMMDDHHMMSS?
if (is_numeric($string) && strlen($string) == 14) {
$time = mktime(substr($string,8,2),substr($string,10,2),substr($string,12,2),
substr($string,4,2),substr($string,6,2),substr($string,0,4));
return $time;
}
// can't decipher, just return it
return $string;
}
/*======================================================================*\
Function: smarty_mod_string_format
Purpose: format strings via sprintf
\*======================================================================*/
function smarty_mod_string_format($string, $format)
{
return sprintf($format, $string);
}
/*======================================================================*\
Function: smarty_mod_replace
Purpose: simple search/replace
\*======================================================================*/
function smarty_mod_replace($string, $search, $replace)
{
return str_replace($search, $replace, $string);
}
/*======================================================================*\
Function: smarty_mod_regex_replace
Purpose: regular epxression search/replace
\*======================================================================*/
function smarty_mod_regex_replace($string, $search, $replace)
{
return preg_replace($search, $replace, $string);
}
/*======================================================================*\
Function: smarty_mod_strip_tags
Purpose: strip html tags from text
\*======================================================================*/
function smarty_mod_strip_tags($string, $replace_with_space = true)
{
if ($replace_with_space)
return preg_replace('!<[^>]*?>!', ' ', $string);
else
return strip_tags($string);
}
/*======================================================================*\
Function: smarty_mod_default
Purpose: designate default text for empty variables
\*======================================================================*/
function smarty_mod_default($string, $default="")
{
if (empty($string))
return $default;
else
return $string;
}
/*======================================================================*\
Function: smarty_func_assign
Purpose: assign a value to a template variable
\*======================================================================*/
function smarty_func_assign($args, &$smarty_obj)
{
extract($args);
if (empty($var)) {
$smarty_obj->_trigger_error_msg("assign: missing 'var' parameter");
return;
}
if (!in_array('value', array_keys($args))) {
$smarty_obj->_trigger_error_msg("assign: missing 'value' parameter");
return;
}
$smarty_obj->assign($var, $value);
return true;
}
/*============================================*\
Custom tag functions
\*============================================*/
/*======================================================================*\
Function: smarty_func_html_options
Purpose: Prints the list of <option> tags generated from
the passed parameters
\*======================================================================*/
function smarty_func_html_options()
{
$print_result = true;
extract(func_get_arg(0));
$html_result = "";
settype($selected, 'array');
if (isset($options)) {
settype($options, 'array');
foreach ($options as $key => $value) {
$html_result .= "<option value=\"$key\"";
if (in_array($key, $selected))
$html_result .= " selected=\"selected\"";
$html_result .= ">$value</option>\n";
}
} else {
settype($output, 'array');
settype($values, 'array');
for ($i = 0; $i < count($output); $i++) {
/* By default, check value against $selected */
$sel_check = $values[$i];
$html_result .= "<option";
if ($i < count($values))
$html_result .= " value=\"".$values[$i]."\"";
else
$sel_check = $output[$i]; /* if more outputs than values, then
check output against $selected */
if (in_array($sel_check, $selected))
$html_result .= " selected";
$html_result .= ">".$output[$i]."</option>\n";
}
}
if ($print_result)
print $html_result;
else
return $html_result;
}
/*======================================================================*\
Function: smarty_func_html_select_date
Purpose: Prints the dropdowns for date selection.
\*======================================================================*/
function smarty_func_html_select_date()
{
/* Default values. */
$prefix = "Date_";
$time = time();
$start_year = strftime("%Y");
$end_year = $start_year;
$display_days = true;
$display_months = true;
$display_years = true;
$month_format = "%B";
$day_format = "%02d";
$year_as_text = false;
/* Display years in reverse order? Ie. 2000,1999,.... */
$reverse_years = false;
/* Should the select boxes be part of an array when returned from PHP?
e.g. setting it to "birthday", would create "birthday[Day]",
"birthday[Month]" & "birthday[Year]". Can be combined with prefix */
$field_array = null;
/* <select size>'s of the different <select> tags.
If not set, uses default dropdown. */
$day_size = null;
$month_size = null;
$year_size = null;
/* Unparsed attributes common to *ALL* the <select>/<input> tags.
An example might be in the template: all_extra ='class ="foo"'. */
$all_extra = null;
/* Separate attributes for the tags. */
$day_extra = null;
$month_extra = null;
$year_extra = null;
/* Order in which to display the fields.
"D" -> day, "M" -> month, "Y" -> year. */
$field_order = 'MDY';
/* String printed between the different fields. */
$field_separator = "\n";
extract(func_get_arg(0));
$time = smarty_make_timestamp($time);
$field_order = strtoupper($field_order);
$html_result = $month_result = $day_result = $year_result = "";
if ($display_months) {
$month_names = array();
for ($i = 1; $i <= 12; $i++)
$month_names[] = strftime($month_format, mktime(0, 0, 0, $i, 1, 2000));
$month_result .= '<select name=';
if (null !== $field_array){
$month_result .= '"' . $field_array . '[' . $prefix . 'Month]"';
} else {
$month_result .= '"' . $prefix . 'Month"';
}
if (null !== $month_size){
$month_result .= ' size="' . $month_size . '"';
}
if (null !== $month_extra){
$month_result .= ' ' . $month_extra;
}
if (null !== $all_extra){
$month_result .= ' ' . $all_extra;
}
$month_result .= '>'."\n";
$month_result .= smarty_func_html_options(array('output' => $month_names,
'values' => range(1, 12),
'selected' => strftime("%m", $time),
'print_result' => false));
$month_result .= '</select>';
}
if ($display_days) {
$days = range(1, 31);
for ($i = 0; $i < count($days); $i++)
$days[$i] = sprintf($day_format, $days[$i]);
$day_result .= '<select name=';
if (null !== $field_array){
$day_result .= '"' . $field_array . '[' . $prefix . 'Day]"';
} else {
$day_result .= '"' . $prefix . 'Day"';
}
if (null !== $day_size){
$day_result .= ' size="' . $day_size . '"';
}
if (null !== $all_extra){
$day_result .= ' ' . $all_extra;
}
if (null !== $day_extra){
$day_result .= ' ' . $day_extra;
}
$day_result .= '>'."\n";
$day_result .= smarty_func_html_options(array('output' => $days,
'values' => range(1, 31),
'selected' => strftime("%d", $time),
'print_result' => false));
$day_result .= '</select>';
}
if ($display_years) {
if (null !== $field_array){
$year_name = $field_array . '[' . $prefix . 'Year]';
} else {
$year_name = $prefix . 'Year';
}
if ($year_as_text) {
$year_result .= '<input type="text" name="' . $year_name . '" value="'.strftime('%Y', $time).'" size="4" maxlength="4"';
if (null !== $all_extra){
$year_result .= ' ' . $all_extra;
}
if (null !== $year_extra){
$year_result .= ' ' . $year_extra;
}
$year_result .= '>';
} else {
$years = range((int)$start_year, (int)$end_year);
if ($reverse_years) {
rsort($years, SORT_NUMERIC);
}
$year_result .= '<select name="' . $year_name . '"';
if (null !== $year_size){
$year_result .= ' size="' . $year_size . '"';
}
if (null !== $all_extra){
$year_result .= ' ' . $all_extra;
}
if (null !== $year_extra){
$year_result .= ' ' . $year_extra;
}
$year_result .= '>'."\n";
$year_result .= smarty_func_html_options(array('output' => $years,
'values' => $years,
'selected' => strftime("%Y", $time),
'print_result' => false));
$year_result .= '</select>';
}
}
// Loop thru the field_order field
for ($i = 0; $i <= 2; $i++){
$c = substr($field_order, $i, 1);
switch ($c){
case 'D':
$html_result .= $day_result;
break;
case 'M':
$html_result .= $month_result;
break;
case 'Y':
$html_result .= $year_result;
break;
}
// Add the field seperator
$html_result .= $field_separator;
}
print $html_result;
}
/*======================================================================*\
Function: smarty_func_html_select_time
Purpose: Prints the dropdowns for time selection
\*======================================================================*/
function smarty_func_html_select_time()
{
/* Default values. */
$prefix = "Time_";
$time = time();
$display_hours = true;
$display_minutes = true;
$display_seconds = true;
$display_meridian = true;
$use_24_hours = true;
$minute_interval = 1;
$second_interval = 1;
/* Should the select boxes be part of an array when returned from PHP?
e.g. setting it to "birthday", would create "birthday[Hour]",
"birthday[Minute]", "birthday[Seconds]" & "birthday[Meridian]".
Can be combined with prefix. */
$field_array = null;
extract(func_get_arg(0));
$time = smarty_make_timestamp($time);
$html_result = '';
if ($display_hours) {
$hours = $use_24_hours ? range(0, 23) : range(1, 12);
$hour_fmt = $use_24_hours ? '%H' : '%I';
for ($i = 0; $i < count($hours); $i++)
$hours[$i] = sprintf('%02d', $hours[$i]);
$html_result .= '<select name=';
if (null !== $field_array) {
$html_result .= '"' . $field_array . '[' . $prefix . 'Hour]">'."\n";
} else {
$html_result .= '"' . $prefix . 'Hour">'."\n";
}
$html_result .= smarty_func_html_options(array('output' => $hours,
'values' => $hours,
'selected' => strftime($hour_fmt, $time),
'print_result' => false));
$html_result .= "</select>\n";
}
if ($display_minutes) {
$all_minutes = range(0, 59);
for ($i = 0; $i < count($all_minutes); $i+= $minute_interval)
$minutes[] = sprintf('%02d', $all_minutes[$i]);
$selected = intval(floor(strftime('%M', $time) / $minute_interval) * $minute_interval);
$html_result .= '<select name=';
if (null !== $field_array) {
$html_result .= '"' . $field_array . '[' . $prefix . 'Minute]">'."\n";
} else {
$html_result .= '"' . $prefix . 'Minute">'."\n";
}
$html_result .= smarty_func_html_options(array('output' => $minutes,
'values' => $minutes,
'selected' => $selected,
'print_result' => false));
$html_result .= "</select>\n";
}
if ($display_seconds) {
$all_seconds = range(0, 59);
for ($i = 0; $i < count($all_seconds); $i+= $second_interval)
$seconds[] = sprintf('%02d', $all_seconds[$i]);
$selected = intval(floor(strftime('%S', $time) / $second_interval) * $second_interval);
$html_result .= '<select name=';
if (null !== $field_array) {
$html_result .= '"' . $field_array . '[' . $prefix . 'Second]">'."\n";
} else {
$html_result .= '"' . $prefix . 'Second">'."\n";
}
$html_result .= smarty_func_html_options(array('output' => $seconds,
'values' => $seconds,
'selected' => $selected,
'print_result' => false));
$html_result .= "</select>\n";
}
if ($display_meridian && !$use_24_hours) {
$html_result .= '<select name=';
if (null !== $field_array) {
$html_result .= '"' . $field_array . '[' . $prefix . 'Meridian]">'."\n";
} else {
$html_result .= '"' . $prefix . 'Meridian">'."\n";
}
$html_result .= smarty_func_html_options(array('output' => array('AM', 'PM'),
'values' => array('am', 'pm'),
'selected' => strtolower(strftime('%p', $time)),
'print_result' => false));
$html_result .= "</select>\n";
}
print $html_result;
}
/*======================================================================*\
Function: smarty_func_math
Purpose: allow math computations in template
\*======================================================================*/
function smarty_func_math($args, &$smarty_obj) {
// be sure equation parameter is present
if (empty($args["equation"])) {
$smarty_obj->_trigger_error_msg("math: missing equation parameter");
return;
}
$equation = $args["equation"];
// make sure parenthesis are balanced
if (substr_count($equation,"(") != substr_count($equation,")")) {
$smarty_obj->_trigger_error_msg("math: unbalanced parenthesis");
return;
}
// match all vars in equation, make sure all are passed
preg_match_all("![a-zA-Z][a-zA-Z0-9]*!",$equation, $match);
$allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10',
'max','min','pi','pow','rand','round','sin','sqrt','srand','tan');
foreach($match[0] as $curr_var) {
if (!in_array($curr_var,array_keys($args)) && !in_array($curr_var, $allowed_funcs)) {
$smarty_obj->_trigger_error_msg("math: parameter $curr_var not passed as argument");
return;
}
}
foreach($args as $key => $val) {
if ($key != "equation" && $key != "format" && $key != "assign") {
// make sure value is not empty
if (strlen($val)==0) {
$smarty_obj->_trigger_error_msg("math: parameter $key is empty");
return;
}
if (!is_numeric($val)) {
$smarty_obj->_trigger_error_msg("math: parameter $key: is not numeric");
return;
}
$equation = preg_replace("/\b$key\b/",$val, $equation);
}
}
eval("\$smarty_math_result = ".$equation.";");
if (empty($args["format"])) {
if (empty($args["assign"])) {
echo $smarty_math_result;
} else {
$smarty_obj->assign($args["assign"],$smarty_math_result);
}
} else {
if (empty($args["assign"])){
printf($args["format"],$smarty_math_result);
} else {
$smarty_obj->assign($assign,sprintf($args["format"],$smarty_math_result));
}
}
}
/*======================================================================*\
Function: smarty_func_fetch
Purpose: fetch file, web or ftp data and display results
\*======================================================================*/
function smarty_func_fetch($args, &$smarty_obj) {
extract($args);
if (empty($file)) {
$smarty_obj->_trigger_error_msg("parameter 'file' cannot be empty");
return;
}
if ($smarty_obj->security && !preg_match('!^(http|ftp)://!', $file)) {
// make sure fetched file comes from secure directory
foreach ($smarty_obj->secure_dir as $curr_dir) {
if (substr(realpath($file), 0, strlen(realpath($curr_dir))) == realpath($curr_dir)) {
$resource_is_secure = true;
break;
}
}
if (!$resource_is_secure) {
$smarty_obj->_trigger_error_msg("(secure mode) fetch '$file' is not allowed");
return;
}
if (!@is_readable($file)) {
$smarty_obj->_trigger_error_msg("fetch cannot read file '$file'");
return;
}
}
if (!empty($assign)) {
ob_start();
readfile($file);
$smarty_obj->assign($assign,ob_get_contents());
ob_end_clean();
} else {
readfile($file);
}
}
/*======================================================================*\
Function: smarty_mod_count_characters
Purpose: count the number of characters in a text
\*======================================================================*/
function smarty_mod_count_characters($string, $include_spaces=false) {
if ($include_spaces)
return(strlen($string));
return preg_match_all("/[^\s]/",$string, $match);
}
/*======================================================================*\
Function: smarty_mod_count_words
Purpose: count the number of words in a text
\*======================================================================*/
function smarty_mod_count_words($string) {
// split text by ' ',\r,\n,\f,\t
$split_array = preg_split("/\s+/",$string);
// count matches that contain alphanumerics
$word_count = preg_grep("/[a-zA-Z0-9]/",$split_array);
return count($word_count);
}
/*======================================================================*\
Function: smarty_mod_count_sentences
Purpose: count the number of sentences in a text
\*======================================================================*/
function smarty_mod_count_sentences($string, $include_spaces=false) {
// find periods with a word before but not after.
return preg_match_all("/[^\s]\.(?!\w)/",$string, $match);
}
/*======================================================================*\
Function: smarty_mod_count_paragraphs
Purpose: count the number of sentences in a text
\*======================================================================*/
function smarty_mod_count_paragraphs($string, $include_spaces=false) {
// count \r or \n characters
return count( preg_split("/[\r\n]+/",$string) );
}
/*======================================================================*\
Function: smarty_func_counter
Purpose: print out a counter value
\*======================================================================*/
function smarty_func_counter($args, &$smarty_obj) {
static $count = array();
static $skipval = array();
static $dir = array();
static $id = "default";
static $printval = array();
static $assign = "";
extract($args);
if (!isset($id))
$id = "default";
if (isset($start))
$count[$id] = $start;
else if (!isset($count[$id]))
$count[$id]=1;
if (!isset($print))
$printval[$id]=true;
else
$printval[$id]=$print;
if (!empty($assign)) {
$printval[$id] = false;
$smarty_obj->assign($assign, $count[$id]);
}
if ($printval[$id])
echo $count[$id];
if (isset($skip))
$skipval[$id] = $skip;
else if (empty($skipval[$id]))
$skipval[$id] = 1;
if (isset($direction))
$dir[$id] = $direction;
else if (!isset($dir[$id]))
$dir[$id] = "up";
if ($dir[$id] == "down")
$count[$id] -= $skipval[$id];
else
$count[$id] += $skipval[$id];
return true;
}
/*======================================================================*\
Function: smarty_func_assign_debug_info
Purpose: assign debug info to the template
\*======================================================================*/
function smarty_func_assign_debug_info($args, &$smarty_obj) {
$assigned_vars = $smarty_obj->_tpl_vars;
ksort($assigned_vars);
if (is_array($smarty_obj->_config[0])) {
$config_vars = $smarty_obj->_config[0];
ksort($config_vars);
$smarty_obj->assign("_debug_config_keys", array_keys($config_vars));
$smarty_obj->assign("_debug_config_vals", array_values($config_vars));
}
$included_templates = $smarty_obj->_smarty_debug_info;
$smarty_obj->assign("_debug_keys", array_keys($assigned_vars));
$smarty_obj->assign("_debug_vals", array_values($assigned_vars));
$smarty_obj->assign("_debug_tpls", $included_templates);
return true;
}
/*======================================================================*\
Function: smarty_func_debug_print_var
Purpose: prints variable (or array) contents to the console
\*======================================================================*/
function smarty_mod_debug_print_var($var, $depth=0, $length=40) {
if (is_array($var)) {
$results = "<b>Array (".count($var).")</b>";
foreach ($var as $curr_key => $curr_val) {
$return = smarty_mod_debug_print_var($curr_val, $depth+1);
$results .= '<br>\r'.str_repeat('&nbsp;', $depth*2)."<b>$curr_key</b> =&gt; $return";
}
return $results;
} else {
if (empty($var)) {
return '<i>empty</i>';
}
if (strlen($var) > $length ) {
$results = substr($var, 0, $length-3).'...';
} else {
$results = $var;
}
$results = preg_replace("![\r\t\n]!", " ", $results);
$results = htmlspecialchars(htmlspecialchars($results));
return $results;
}
}
/*======================================================================*\
Function: smarty_func_overlib_init
Purpose: initialize use of overlib
\*======================================================================*/
function smarty_func_overlib_init($args, &$smarty_obj) {
// be sure to place overlib.js where Smarty can locate it.
// overlib.js came with the distribution of Smarty.
echo '<DIV ID="overDiv" STYLE="position:absolute; visibility:hidden; z-index:1000;"></DIV>'."\n".'<SCRIPT LANGUAGE=javascript>'."\n".'<!--'."\n";
readfile(SMARTY_DIR."overlib.js",1);
echo '// -->'."\n".'</SCRIPT>'."\n";
return;
}
/*======================================================================*\
Function: smarty_func_overlib
Purpose: make text pop up in windows via overlib
\*======================================================================*/
function smarty_func_overlib($args, &$smarty_obj) {
extract($args);
if (empty($text) && !isset($inarray) && empty($function)) {
$smarty_obj->_trigger_error_msg("overlib: attribute 'text' or 'inarray' or 'function' required");
return false;
}
if (empty($trigger)) { $trigger = "onMouseOver"; }
echo $trigger.'="return overlib(\''.str_replace("'","\'",$text).'\'';
if ($sticky) { echo ",STICKY"; }
if (!empty($caption)) { echo ",CAPTION,'".str_replace("'","\'",$caption)."'"; }
if (!empty($fgcolor)) { echo ",FGCOLOR,'$fgcolor'"; }
if (!empty($bgcolor)) { echo ",BGCOLOR,'$bgcolor'"; }
if (!empty($textcolor)) { echo ",TEXTCOLOR,'$textcolor'"; }
if (!empty($capcolor)) { echo ",CAPCOLOR,'$capcolor'"; }
if (!empty($closecolor)) { echo ",CLOSECOLOR,'$closecolor'"; }
if (!empty($textfont)) { echo ",TEXTFONT,'$textfont'"; }
if (!empty($captionfont)) { echo ",CAPTIONFONT,'$captionfont'"; }
if (!empty($closefont)) { echo ",CLOSEFONT,'$closefont'"; }
if (!empty($textsize)) { echo ",TEXTSIZE,$textsize"; }
if (!empty($captionsize)) { echo ",CAPTIONSIZE,$captionsize"; }
if (!empty($closesize)) { echo ",CLOSESIZE,$closesize"; }
if (!empty($width)) { echo ",WIDTH,$width"; }
if (!empty($height)) { echo ",HEIGHT,$height"; }
if (!empty($left)) { echo ",LEFT"; }
if (!empty($right)) { echo ",RIGHT"; }
if (!empty($center)) { echo ",CENTER"; }
if (!empty($above)) { echo ",ABOVE"; }
if (!empty($below)) { echo ",BELOW"; }
if (isset($border)) { echo ",BORDER,$border"; }
if (isset($offsetx)) { echo ",OFFSETX,$offsetx"; }
if (isset($offsety)) { echo ",OFFSETY,$offsety"; }
if (!empty($fgbackground)) { echo ",FGBACKGROUND,'$fgbackground'"; }
if (!empty($bgbackground)) { echo ",BGBACKGROUND,'$bgbackground'"; }
if (!empty($closetext)) { echo ",CLOSETEXT,'".str_replace("'","\'",$closetext)."'"; }
if (!empty($noclose)) { echo ",NOCLOSE"; }
if (!empty($status)) { echo ",STATUS,'".str_replace("'","\'",$status)."'"; }
if (!empty($autostatus)) { echo ",AUTOSTATUS"; }
if (!empty($autostatuscap)) { echo ",AUTOSTATUSCAP"; }
if (isset($inarray)) { echo ",INARRAY,'$inarray'"; }
if (isset($caparray)) { echo ",CAPARRAY,'$caparray'"; }
if (!empty($capicon)) { echo ",CAPICON,'$capicon'"; }
if (!empty($snapx)) { echo ",SNAPX,$snapx"; }
if (!empty($snapy)) { echo ",SNAPY,$snapy"; }
if (isset($fixx)) { echo ",FIXX,$fixx"; }
if (isset($fixy)) { echo ",FIXY,$fixy"; }
if (!empty($background)) { echo ",BACKGROUND,'$background'"; }
if (!empty($padx)) { echo ",PADX,$padx"; }
if (!empty($pady)) { echo ",PADY,$pady"; }
if (!empty($fullhtml)) { echo ",FULLHTML"; }
if (!empty($frame)) { echo ",FRAME,'$frame'"; }
if (isset($timeout)) { echo ",TIMEOUT,$timeout"; }
if (!empty($function)) { echo ",FUNCTION,'$function'"; }
if (isset($delay)) { echo ",DELAY,$delay"; }
if (!empty($hauto)) { echo ",HAUTO"; }
if (!empty($vauto)) { echo ",VAUTO"; }
echo ');" onMouseOut="nd();"';
return;
}
/*======================================================================*\
Function: smarty_mod_wordwrap
Purpose: wrap words to a specific column width
Input: $string - string of text to wrap
$width - column width to wrap to
$cut - whether or not to cut a word on the boundary
\*======================================================================*/
function smarty_mod_wordwrap($string, $width=80, $break="\n",$cut=false) {
return wordwrap($string,$width,$break,$cut);
}
/*======================================================================*\
Function: smarty_mod_indent
Purpose: indent each line a specific number of characters
Input: $string - string of text to indent
$width - number of chars to indent
$indent_char - character to indent with (can be a tab \t)
\*======================================================================*/
function smarty_mod_indent($string, $width=4, $indent_char=' ') {
return preg_replace("/(^|\n)/","\\1".str_repeat($indent_char,$width),$string);
}
/* vim: set expandtab: */
?>

View File

@@ -1,5 +1,4 @@
<?php <?php
/* /*
* Project: Smarty: the PHP compiling template engine * Project: Smarty: the PHP compiling template engine
* File: Smarty.class.php * File: Smarty.class.php
@@ -7,7 +6,7 @@
* Andrei Zmievski <andrei@php.net> * Andrei Zmievski <andrei@php.net>
* *
* Version: 1.5.2 * Version: 1.5.2
* Copyright: 2001 ispi of Lincoln, Inc. * Copyright: 2001,2002 ispi of Lincoln, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -48,7 +47,7 @@ if (!defined('SMARTY_DIR')) {
define('SMARTY_DIR', ''); define('SMARTY_DIR', '');
} }
require_once SMARTY_DIR.'Smarty.addons.php'; //require_once SMARTY_DIR.'Smarty.addons.php';
define('SMARTY_PHP_PASSTHRU', 0); define('SMARTY_PHP_PASSTHRU', 0);
define('SMARTY_PHP_QUOTE', 1); define('SMARTY_PHP_QUOTE', 1);
@@ -67,6 +66,7 @@ class Smarty
var $template_dir = './templates'; // name of directory for templates var $template_dir = './templates'; // name of directory for templates
var $compile_dir = './templates_c'; // name of directory for compiled templates var $compile_dir = './templates_c'; // name of directory for compiled templates
var $config_dir = './configs'; // directory where config files are located var $config_dir = './configs'; // directory where config files are located
var $plugins_dir = './plugins'; // directory where plugins are kept
var $debugging = false; // enable debugging console true/false var $debugging = false; // enable debugging console true/false
var $debug_tpl = 'file:debug.tpl'; // path to debug console template var $debug_tpl = 'file:debug.tpl'; // path to debug console template
@@ -133,53 +133,12 @@ class Smarty
var $left_delimiter = '{'; // template tag delimiters. var $left_delimiter = '{'; // template tag delimiters.
var $right_delimiter = '}'; var $right_delimiter = '}';
var $compiler_funcs = array(
);
var $custom_funcs = array( 'html_options' => 'smarty_func_html_options',
'html_select_date' => 'smarty_func_html_select_date',
'html_select_time' => 'smarty_func_html_select_time',
'math' => 'smarty_func_math',
'fetch' => 'smarty_func_fetch',
'counter' => 'smarty_func_counter',
'assign' => 'smarty_func_assign',
'popup_init' => 'smarty_func_overlib_init',
'popup' => 'smarty_func_overlib',
'assign_debug_info' => 'smarty_func_assign_debug_info'
);
var $custom_mods = array( 'lower' => 'strtolower',
'upper' => 'strtoupper',
'capitalize' => 'ucwords',
'escape' => 'smarty_mod_escape',
'truncate' => 'smarty_mod_truncate',
'spacify' => 'smarty_mod_spacify',
'date_format' => 'smarty_mod_date_format',
'string_format' => 'smarty_mod_string_format',
'replace' => 'smarty_mod_replace',
'regex_replace' => 'smarty_mod_regex_replace',
'strip_tags' => 'smarty_mod_strip_tags',
'default' => 'smarty_mod_default',
'count_characters' => 'smarty_mod_count_characters',
'count_words' => 'smarty_mod_count_words',
'count_sentences' => 'smarty_mod_count_sentences',
'count_paragraphs' => 'smarty_mod_count_paragraphs',
'wordwrap' => 'smarty_mod_wordwrap',
'indent' => 'smarty_mod_indent',
'debug_print_var' => 'smarty_mod_debug_print_var'
);
var $show_info_header = false; // display HTML info header at top of page output var $show_info_header = false; // display HTML info header at top of page output
var $show_info_include = false; // display HTML comments at top & bottom of var $show_info_include = false; // display HTML comments at top & bottom of
// each included template // each included template
var $compiler_class = 'Smarty_Compiler'; // the compiler class used by var $compiler_class = 'Smarty_Compiler'; // the compiler class used by
// Smarty to compile templates // Smarty to compile templates
var $resource_funcs = array(); // functions that resource handlers are mapped to
var $prefilter_funcs = array(); // functions that templates are filtered through
// before being compiled
var $postfilter_funcs = array(); // functions that compiled templates are filtered
// through after compilation
var $request_vars_order = "EGPCS"; // the order in which request variables are var $request_vars_order = "EGPCS"; // the order in which request variables are
// registered, similar to variables_order // registered, similar to variables_order
@@ -208,6 +167,14 @@ class Smarty
var $_smarty_debug_id = 'SMARTY_DEBUG'; // text in URL to enable debug mode var $_smarty_debug_id = 'SMARTY_DEBUG'; // text in URL to enable debug mode
var $_smarty_debug_info = array(); // debugging information for debug console var $_smarty_debug_info = array(); // debugging information for debug console
var $_cache_info = array(); // info that makes up a cache file var $_cache_info = array(); // info that makes up a cache file
var $_plugins = array( // table keeping track of plugins
'modifier' => array(),
'function' => array(),
'compiler' => array(),
'prefilter' => array(),
'postfilter'=> array(),
'resource' => array(),
'insert' => array());
/*======================================================================*\ /*======================================================================*\
@@ -301,7 +268,8 @@ class Smarty
\*======================================================================*/ \*======================================================================*/
function register_function($function, $function_impl) function register_function($function, $function_impl)
{ {
$this->custom_funcs[$function] = $function_impl; $this->_plugins['function'][$function] =
array($function_impl, null, null, false);
} }
/*======================================================================*\ /*======================================================================*\
@@ -310,7 +278,7 @@ class Smarty
\*======================================================================*/ \*======================================================================*/
function unregister_function($function) function unregister_function($function)
{ {
unset($this->custom_funcs[$function]); unset($this->_plugins['function'][$function]);
} }
/*======================================================================*\ /*======================================================================*\
@@ -319,7 +287,8 @@ class Smarty
\*======================================================================*/ \*======================================================================*/
function register_compiler_function($function, $function_impl) function register_compiler_function($function, $function_impl)
{ {
$this->compiler_funcs[$function] = $function_impl; $this->_plugins['compiler'][$function] =
array($function_impl, null, null, false);
} }
/*======================================================================*\ /*======================================================================*\
@@ -328,7 +297,7 @@ class Smarty
\*======================================================================*/ \*======================================================================*/
function unregister_compiler_function($function) function unregister_compiler_function($function)
{ {
unset($this->compiler_funcs[$function]); unset($this->_plugins['compiler'][$function]);
} }
/*======================================================================*\ /*======================================================================*\
@@ -337,7 +306,8 @@ class Smarty
\*======================================================================*/ \*======================================================================*/
function register_modifier($modifier, $modifier_impl) function register_modifier($modifier, $modifier_impl)
{ {
$this->custom_mods[$modifier] = $modifier_impl; $this->_plugins['modifier'][$modifier] =
array($modifier_impl, null, null, false);
} }
/*======================================================================*\ /*======================================================================*\
@@ -346,25 +316,26 @@ class Smarty
\*======================================================================*/ \*======================================================================*/
function unregister_modifier($modifier) function unregister_modifier($modifier)
{ {
unset($this->custom_mods[$modifier]); unset($this->_plugins['modifier'][$modifier]);
} }
/*======================================================================*\ /*======================================================================*\
Function: register_resource Function: register_resource
Purpose: Registers a resource to fetch a template Purpose: Registers a resource to fetch a template
\*======================================================================*/ \*======================================================================*/
function register_resource($name, $function_name) function register_resource($type, $functions)
{ {
$this->resource_funcs[$name] = $function_name; $this->_plugins['resource'][$type] =
array((array)$functions, false);
} }
/*======================================================================*\ /*======================================================================*\
Function: unregister_resource Function: unregister_resource
Purpose: Unregisters a resource Purpose: Unregisters a resource
\*======================================================================*/ \*======================================================================*/
function unregister_resource($name) function unregister_resource($type)
{ {
unset($this->resource_funcs[$name]); unset($this->_plugins['resource'][$type]);
} }
/*======================================================================*\ /*======================================================================*\
@@ -372,24 +343,19 @@ class Smarty
Purpose: Registers a prefilter function to apply Purpose: Registers a prefilter function to apply
to a template before compiling to a template before compiling
\*======================================================================*/ \*======================================================================*/
function register_prefilter($function_name) function register_prefilter($function)
{ {
$this->prefilter_funcs[] = $function_name; $this->_plugins['prefilter'][$function]
= array($function, null, null, false);
} }
/*======================================================================*\ /*======================================================================*\
Function: unregister_prefilter Function: unregister_prefilter
Purpose: Unregisters a prefilter function Purpose: Unregisters a prefilter function
\*======================================================================*/ \*======================================================================*/
function unregister_prefilter($function_name) function unregister_prefilter($function)
{ {
$tmp_array = array(); unset($this->_plugins['prefilter'][$function]);
foreach($this->prefilter_funcs as $curr_func) {
if ($curr_func != $function_name) {
$tmp_array[] = $curr_func;
}
}
$this->prefilter_funcs = $tmp_array;
} }
/*======================================================================*\ /*======================================================================*\
@@ -397,24 +363,19 @@ class Smarty
Purpose: Registers a postfilter function to apply Purpose: Registers a postfilter function to apply
to a compiled template after compilation to a compiled template after compilation
\*======================================================================*/ \*======================================================================*/
function register_postfilter($function_name) function register_postfilter($function)
{ {
$this->postfilter_funcs[] = $function_name; $this->_plugins['postfilter'][$function]
= array($function, null, null, false);
} }
/*======================================================================*\ /*======================================================================*\
Function: unregister_postfilter Function: unregister_postfilter
Purpose: Unregisters a postfilter function Purpose: Unregisters a postfilter function
\*======================================================================*/ \*======================================================================*/
function unregister_postfilter($function_name) function unregister_postfilter($function)
{ {
$tmp_array = array(); unset($this->_plugins['postfilter'][$function]);
foreach($this->postfilter_funcs as $curr_func) {
if ($curr_func != $function_name) {
$tmp_array[] = $curr_func;
}
}
$this->postfilter_funcs = $tmp_array;
} }
/*======================================================================*\ /*======================================================================*\
@@ -466,6 +427,7 @@ class Smarty
if (!isset($compile_id)) if (!isset($compile_id))
$compile_id = $this->compile_id; $compile_id = $this->compile_id;
return $this->_read_cache_file($tpl_file, $cache_id, $compile_id, $results); return $this->_read_cache_file($tpl_file, $cache_id, $compile_id, $results);
} }
@@ -541,11 +503,9 @@ class Smarty
$this->_inclusion_depth = 0; $this->_inclusion_depth = 0;
if ($this->caching) { if ($this->caching) {
$this->_cache_info[] = array('template', $_smarty_tpl_file);
if ($this->_read_cache_file($_smarty_tpl_file, $_smarty_cache_id, $_smarty_compile_id, $_smarty_results)) { if ($this->_read_cache_file($_smarty_tpl_file, $_smarty_cache_id, $_smarty_compile_id, $_smarty_results)) {
if ( $this->_cache_info['insert_tags'] ) { if (@count($this->_cache_info['insert_tags'])) {
$this->_load_plugins($this->_cache_info['insert_tags']);
$_smarty_results = $this->_process_cached_inserts($_smarty_results); $_smarty_results = $this->_process_cached_inserts($_smarty_results);
} }
if ($_smarty_display) { if ($_smarty_display) {
@@ -556,12 +516,12 @@ class Smarty
$_smarty_results .= $this->_generate_debug_output(); $_smarty_results .= $this->_generate_debug_output();
} }
if( $this->check_if_modified ) { if ($this->check_if_modified) {
global $HTTP_IF_MODIFIED_SINCE; global $HTTP_IF_MODIFIED_SINCE;
$last_modified_date = substr($HTTP_IF_MODIFIED_SINCE,0,strpos($HTTP_IF_MODIFIED_SINCE,'GMT')+3); $last_modified_date = substr($HTTP_IF_MODIFIED_SINCE,0,strpos($HTTP_IF_MODIFIED_SINCE,'GMT')+3);
$gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT'; $gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
if( !$this->_cache_info['insert_tags'] if (@count($this->_cache_info['insert_tags']) == 0
&& $gmt_mtime == $last_modified_date ) { && $gmt_mtime == $last_modified_date) {
header("HTTP/1.1 304 Not Modified"); header("HTTP/1.1 304 Not Modified");
} }
} }
@@ -572,6 +532,9 @@ class Smarty
} else { } else {
return $_smarty_results; return $_smarty_results;
} }
} else {
$this->_cache_info = array();
$this->_cache_info['template'][] = $_smarty_tpl_file;
} }
} }
@@ -600,15 +563,6 @@ class Smarty
$compile_path = $this->_get_compile_path($_smarty_tpl_file); $compile_path = $this->_get_compile_path($_smarty_tpl_file);
$_smarty_trusted = false;
if ($this->security) {
$this->_parse_file_path($this->template_dir, $_smarty_tpl_file, $resource_type, $resource_name);
if ($this->_is_trusted($resource_type, $resource_name)) {
$_smarty_trusted = true;
$this->security = false;
}
}
// if we just need to display the results, don't perform output // if we just need to display the results, don't perform output
// buffering - for speed // buffering - for speed
if ($_smarty_display && !$this->caching) { if ($_smarty_display && !$this->caching) {
@@ -618,7 +572,9 @@ class Smarty
if ($this->show_info_include) { if ($this->show_info_include) {
echo "\n<!-- SMARTY_BEGIN: ".$_smarty_tpl_file." -->\n"; echo "\n<!-- SMARTY_BEGIN: ".$_smarty_tpl_file." -->\n";
} }
include($compile_path); include($compile_path);
if ($this->show_info_include) { if ($this->show_info_include) {
echo "\n<!-- SMARTY_END: ".$_smarty_tpl_file." -->\n"; echo "\n<!-- SMARTY_END: ".$_smarty_tpl_file." -->\n";
} }
@@ -631,7 +587,9 @@ class Smarty
if ($this->show_info_include) { if ($this->show_info_include) {
echo "\n<!-- SMARTY_BEGIN: ".$_smarty_tpl_file." -->\n"; echo "\n<!-- SMARTY_BEGIN: ".$_smarty_tpl_file." -->\n";
} }
include($compile_path); include($compile_path);
if ($this->show_info_include) { if ($this->show_info_include) {
echo "\n<!-- SMARTY_END: ".$_smarty_tpl_file." -->\n"; echo "\n<!-- SMARTY_END: ".$_smarty_tpl_file." -->\n";
} }
@@ -639,9 +597,6 @@ class Smarty
$_smarty_results = ob_get_contents(); $_smarty_results = ob_get_contents();
ob_end_clean(); ob_end_clean();
} }
if ($_smarty_trusted) {
$this->security = true;
}
if ($this->caching) { if ($this->caching) {
$this->_write_cache_file($_smarty_tpl_file, $_smarty_cache_id, $_smarty_compile_id, $_smarty_results); $this->_write_cache_file($_smarty_tpl_file, $_smarty_cache_id, $_smarty_compile_id, $_smarty_results);
@@ -650,8 +605,7 @@ class Smarty
if ($_smarty_display) { if ($_smarty_display) {
if (isset($_smarty_results)) { echo $_smarty_results; } if (isset($_smarty_results)) { echo $_smarty_results; }
if ($this->debugging) if ($this->debugging) {
{
// capture time for debugging info // capture time for debugging info
$this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = ($this->_get_microtime() - $debug_start_time); $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = ($this->_get_microtime() - $debug_start_time);
@@ -729,19 +683,19 @@ function _generate_debug_output() {
/*======================================================================*\ /*======================================================================*\
Function: _is_trusted() Function: _is_trusted()
Purpose: determines if a template is within the trusted_dir or not. Purpose: determines if a resource is trusted or not
\*======================================================================*/ \*======================================================================*/
function _is_trusted($resource_type, $resource_name) function _is_trusted($resource_type, $resource_name)
{ {
$_smarty_trusted = false; $_smarty_trusted = false;
if ($resource_type == 'file') {
if (!empty($this->trusted_dir)) { if (!empty($this->trusted_dir)) {
// see if template file is within a trusted directory. If so, // see if template file is within a trusted directory. If so,
// disable security during the execution of the template. // disable security during the execution of the template.
if ($resource_type == 'file') {
if (!empty($this->trusted_dir)) { if (!empty($this->trusted_dir)) {
foreach ((array)$this->trusted_dir as $curr_dir) { foreach ((array)$this->trusted_dir as $curr_dir) {
if ( !empty($curr_dir) && is_readable ($curr_dir)) { if (!empty($curr_dir) && is_readable ($curr_dir)) {
if (substr(realpath($resource_name),0, strlen(realpath($curr_dir))) == realpath($curr_dir)) { if (substr(realpath($resource_name),0, strlen(realpath($curr_dir))) == realpath($curr_dir)) {
$_smarty_trusted = true; $_smarty_trusted = true;
break; break;
@@ -749,20 +703,22 @@ function _is_trusted($resource_type, $resource_name)
} }
} }
} }
}
} else { } else {
// resource is not on local file system // resource is not on local file system
$_smarty_trusted = false; $resource_func = $this->_plugins['resource'][$resource_type][0][3];
} $_smarty_trusted = $resource_func($resource_name, $this);
} }
return $_smarty_trusted; return $_smarty_trusted;
} }
/*======================================================================*\ /*======================================================================*\
Function: _is_secure() Function: _is_secure()
Purpose: determins if a template is secure or not. Purpose: determines if a resource is secure or not.
\*======================================================================*/ \*======================================================================*/
function _is_secure($resource_type, $resource_name) { function _is_secure($resource_type, $resource_name)
{
if (!$this->security || $this->security_settings['INCLUDE_ANY']) { if (!$this->security || $this->security_settings['INCLUDE_ANY']) {
return true; return true;
} }
@@ -781,11 +737,62 @@ function _is_trusted($resource_type, $resource_name)
} }
} else { } else {
// resource is not on local file system // resource is not on local file system
$_smarty_secure = true; $resource_func = $this->_plugins['resource'][$resource_type][0][2];
$_smarty_secure = $resource_func($resource_name, $_smarty_secure, $this);
} }
return $_smarty_secure; return $_smarty_secure;
} }
/*======================================================================*\
Function: _get_php_resource
Purpose: Retrieves PHP script resource
\*======================================================================*/
function _get_php_resource($resource, &$resource_type, &$php_resource)
{
$this->_parse_file_path($this->trusted_dir, $resource, $resource_type, $resource_name);
/*
* Find out if the resource exists.
*/
$readable = true;
if ($resource_type == 'file' && !@is_file($resource_name)) {
$readable = false;
} else if ($resource_type != 'file') {
$resource_func = $this->_plugins['resource'][$resource_type][0][0];
$readable = $resource_func($resource_name, $template_source, $this);
}
/*
* Set the error function, depending on which class calls us.
*/
if (method_exists($this, '_syntax_error')) {
$error_func = '_syntax_error';
} else {
$error_func = '_trigger_error_msg';
}
if ($readable) {
if ($this->security) {
if (!$this->_is_trusted($resource_type, $resource_name)) {
$this->$error_func("(secure mode) '$resource_type:$resource_name' is not trusted");
return false;
}
}
} else {
$this->$error_func("'$resource_type: $resource_name' is not readable");
return false;
}
if ($resource_type == 'file') {
$php_resource = $resource_name;
} else {
$php_resource = $template_source;
}
return true;
}
/*======================================================================*\ /*======================================================================*\
@@ -873,8 +880,8 @@ function _is_trusted($resource_type, $resource_name)
Function: _parse_file_path Function: _parse_file_path
Purpose: parse out the type and name from the template resource Purpose: parse out the type and name from the template resource
\*======================================================================*/ \*======================================================================*/
function _parse_file_path($file_base_path, $file_path, &$resource_type, &$resource_name) { function _parse_file_path($file_base_path, $file_path, &$resource_type, &$resource_name)
{
// split tpl_path by the first colon // split tpl_path by the first colon
$file_path_parts = explode(':', $file_path, 2); $file_path_parts = explode(':', $file_path, 2);
@@ -885,14 +892,17 @@ function _is_trusted($resource_type, $resource_name)
} else { } else {
$resource_type = $file_path_parts[0]; $resource_type = $file_path_parts[0];
$resource_name = $file_path_parts[1]; $resource_name = $file_path_parts[1];
if ($resource_type != 'file') {
$this->_load_resource_plugin($resource_type);
}
} }
if ($resource_type == 'file') { if ($resource_type == 'file') {
if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $resource_name)) { if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $resource_name)) {
// relative pathname to $file_base_path // relative pathname to $file_base_path
// use the first directory where the file is found // use the first directory where the file is found
foreach((array)$file_base_path as $curr_path) { foreach ((array)$file_base_path as $curr_path) {
if(@is_file($curr_path.'/'.$resource_name)) { if (@is_file($curr_path.'/'.$resource_name)) {
$resource_name = $curr_path.'/'.$resource_name; $resource_name = $curr_path.'/'.$resource_name;
return true; return true;
} }
@@ -912,10 +922,10 @@ function _is_trusted($resource_type, $resource_name)
Purpose: fetch the template info. Gets timestamp, and source Purpose: fetch the template info. Gets timestamp, and source
if get_source is true if get_source is true
\*======================================================================*/ \*======================================================================*/
function _fetch_template_info($tpl_path, &$template_source, &$template_timestamp, $get_source=true) function _fetch_template_info($tpl_path, &$template_source, &$template_timestamp, $get_source = true)
{ {
$_return = false; $_return = false;
if($this->_parse_file_path($this->template_dir, $tpl_path, $resource_type, $resource_name)) { if ($this->_parse_file_path($this->template_dir, $tpl_path, $resource_type, $resource_name)) {
switch ($resource_type) { switch ($resource_type) {
case 'file': case 'file':
if (@is_file($resource_name)) { if (@is_file($resource_name)) {
@@ -926,22 +936,26 @@ function _is_trusted($resource_type, $resource_name)
$_return = true; $_return = true;
} }
break; break;
default: default:
if (isset($this->resource_funcs[$resource_type])) { // call resource functions to fetch the template source and timestamp
$funcname = $this->resource_funcs[$resource_type]; if ($get_source) {
if (function_exists($funcname)) { $resource_func = $this->_plugins['resource'][$resource_type][0][0];
// call the function to fetch the template $_source_return = $resource_func($resource_name, $template_source, $this);
$_return = $funcname($resource_name, $template_source, $template_timestamp, $get_source, $this); } else {
} $_source_return = true;
} }
$resource_func = $this->_plugins['resource'][$resource_type][0][1];
$_timestamp_return = $resource_func($resource_name, $template_timestamp, $this);
$_return = $_source_return && $_timestamp_return;
break; break;
} }
} }
if(!$_return) { if (!$_return) {
// see if we can get a template with the default template handler // see if we can get a template with the default template handler
if(!empty($this->default_template_handler_func)) { if (!empty($this->default_template_handler_func)) {
if(!function_exists($this->default_template_handler_func)) { if (!function_exists($this->default_template_handler_func)) {
$this->_trigger_error_msg("default template handler function \"$this->default_template_handler_func\" doesn't exist."); $this->_trigger_error_msg("default template handler function \"$this->default_template_handler_func\" doesn't exist.");
$_return = false; $_return = false;
} }
@@ -950,14 +964,15 @@ function _is_trusted($resource_type, $resource_name)
} }
} }
if(!$_return) { if (!$_return) {
$this->_trigger_error_msg("unable to read template resource: \"$tpl_path\""); $this->_trigger_error_msg("unable to read template resource: \"$tpl_path\"");
} elseif ($_return && $this->security && !$this->_is_secure($resource_type, $resource_name) && !$this->_is_trusted($resource_type, $resource_name)) { } else if ($_return && $this->security && !$this->_is_secure($resource_type, $resource_name)) {
$this->_trigger_error_msg("(secure mode) accessing \"$tpl_path\" is not allowed"); $this->_trigger_error_msg("(secure mode) accessing \"$tpl_path\" is not allowed");
$template_source = null; $template_source = null;
$template_timestamp = null; $template_timestamp = null;
return false; return false;
} }
return $_return; return $_return;
} }
@@ -974,22 +989,19 @@ function _is_trusted($resource_type, $resource_name)
$smarty_compiler->template_dir = $this->template_dir; $smarty_compiler->template_dir = $this->template_dir;
$smarty_compiler->compile_dir = $this->compile_dir; $smarty_compiler->compile_dir = $this->compile_dir;
$smarty_compiler->plugins_dir = $this->plugins_dir;
$smarty_compiler->config_dir = $this->config_dir; $smarty_compiler->config_dir = $this->config_dir;
$smarty_compiler->force_compile = $this->force_compile; $smarty_compiler->force_compile = $this->force_compile;
$smarty_compiler->caching = $this->caching; $smarty_compiler->caching = $this->caching;
$smarty_compiler->php_handling = $this->php_handling; $smarty_compiler->php_handling = $this->php_handling;
$smarty_compiler->left_delimiter = $this->left_delimiter; $smarty_compiler->left_delimiter = $this->left_delimiter;
$smarty_compiler->right_delimiter = $this->right_delimiter; $smarty_compiler->right_delimiter = $this->right_delimiter;
$smarty_compiler->custom_funcs = $this->custom_funcs;
$smarty_compiler->custom_mods = $this->custom_mods;
$smarty_compiler->_version = $this->_version; $smarty_compiler->_version = $this->_version;
$smarty_compiler->prefilter_funcs = $this->prefilter_funcs;
$smarty_compiler->postfilter_funcs = $this->postfilter_funcs;
$smarty_compiler->compiler_funcs = $this->compiler_funcs;
$smarty_compiler->security = $this->security; $smarty_compiler->security = $this->security;
$smarty_compiler->secure_dir = $this->secure_dir; $smarty_compiler->secure_dir = $this->secure_dir;
$smarty_compiler->security_settings = $this->security_settings; $smarty_compiler->security_settings = $this->security_settings;
$smarty_compiler->trusted_dir = $this->trusted_dir; $smarty_compiler->trusted_dir = $this->trusted_dir;
$smarty_compiler->_plugins = &$this->_plugins;
if ($smarty_compiler->_compile_file($tpl_file, $template_source, $template_compiled)) if ($smarty_compiler->_compile_file($tpl_file, $template_source, $template_compiled))
return true; return true;
@@ -1019,14 +1031,6 @@ function _is_trusted($resource_type, $resource_name)
array_unshift($this->_config, $this->_config[0]); array_unshift($this->_config, $this->_config[0]);
$compile_path = $this->_get_compile_path($_smarty_include_tpl_file); $compile_path = $this->_get_compile_path($_smarty_include_tpl_file);
$this->_parse_file_path($this->template_dir, $_smarty_include_tpl_file, $resource_type, $resource_name);
if ($this->security && $this->_is_trusted($resource_type, $resource_name)) {
$_smarty_trusted = true;
$this->security = false;
} else {
$_smarty_trusted = false;
}
if ($this->_process_template($_smarty_include_tpl_file, $compile_path)) { if ($this->_process_template($_smarty_include_tpl_file, $compile_path)) {
if ($this->show_info_include) { if ($this->show_info_include) {
echo "\n<!-- SMARTY_BEGIN: ".$_smarty_include_tpl_file." -->\n"; echo "\n<!-- SMARTY_BEGIN: ".$_smarty_include_tpl_file." -->\n";
@@ -1037,10 +1041,6 @@ function _is_trusted($resource_type, $resource_name)
} }
} }
if ($_smarty_trusted) {
$this->security = true;
}
array_shift($this->_config); array_shift($this->_config);
$this->_inclusion_depth--; $this->_inclusion_depth--;
@@ -1050,7 +1050,7 @@ function _is_trusted($resource_type, $resource_name)
} }
if ($this->caching) { if ($this->caching) {
$this->_cache_info[] = array('template', $_smarty_include_tpl_file); $this->_cache_info['template'][] = $_smarty_include_tpl_file;
} }
} }
@@ -1065,7 +1065,7 @@ function _is_trusted($resource_type, $resource_name)
} }
if ($this->caching) { if ($this->caching) {
$this->_cache_info[] = array('config', $file); $this->_cache_info['config'][] = $file;
} }
if (!isset($this->_config[0]['files'][$file])) { if (!isset($this->_config[0]['files'][$file])) {
@@ -1111,7 +1111,6 @@ function _is_trusted($resource_type, $resource_name)
\*======================================================================*/ \*======================================================================*/
function _process_cached_inserts($results) function _process_cached_inserts($results)
{ {
preg_match_all('!'.$this->_smarty_md5.'{insert_cache (.*)}'.$this->_smarty_md5.'!Uis', preg_match_all('!'.$this->_smarty_md5.'{insert_cache (.*)}'.$this->_smarty_md5.'!Uis',
$results, $match); $results, $match);
list($cached_inserts, $insert_args) = $match; list($cached_inserts, $insert_args) = $match;
@@ -1127,21 +1126,19 @@ function _is_trusted($resource_type, $resource_name)
unset($args['name']); unset($args['name']);
if (isset($args['script'])) { if (isset($args['script'])) {
$this->_parse_file_path($this->trusted_dir, $this->_dequote($args['script']), $resource_type, $resource_name); if (!$this->_get_php_resource($this->_dequote($args['script']), $resource_type, $php_resource)) {
if ($this->security) {
if( $resource_type != 'file' || !@is_file($resource_name)) {
$this->_syntax_error("insert: $resource_type: $resource_name is not readable"); return false;
}
if (!$this->_is_trusted($resource_type, $resource_name)) {
$this->_syntax_error("insert: $resource_type: $resource_name is not trusted");
return false; return false;
} }
if ($resource_type == 'file') {
include_once($php_resource);
} else {
eval($php_resource);
} }
include_once($resource_name);
unset($args['script']); unset($args['script']);
} }
$function_name = 'insert_' . $name; $function_name = $this->_plugins['insert'][$name][0];
$replace = $function_name($args, $this); $replace = $function_name($args, $this);
$results = str_replace($cached_inserts[$i], $replace, $results); $results = str_replace($cached_inserts[$i], $replace, $results);
@@ -1169,24 +1166,30 @@ function _run_insert_handler($args)
if ($this->caching) { if ($this->caching) {
$arg_string = serialize($args); $arg_string = serialize($args);
$name = $args['name'];
if (!isset($this->_cache_info['insert_tags'][$name])) {
$this->_cache_info['insert_tags'][$name] = array('insert',
$name,
$this->_plugins['insert'][$name][1],
$this->_plugins['insert'][$name][2],
false);
}
return $this->_smarty_md5."{insert_cache $arg_string}".$this->_smarty_md5; return $this->_smarty_md5."{insert_cache $arg_string}".$this->_smarty_md5;
} else { } else {
$function_name = 'insert_'.$args['name'];
if (isset($args['script'])) { if (isset($args['script'])) {
$this->_parse_file_path($this->trusted_dir, $this->_dequote($args['script']), $resource_type, $resource_name); if (!$this->_get_php_resource($this->_dequote($args['script']), $resource_type, $php_resource)) {
if ($this->security) {
if ( $resource_type != 'file' || !@is_file($resource_name) ) {
$this->_syntax_error("insert: $resource_type: $resource_name is not readable");
return false; return false;
} }
if ( !$this->_is_trusted($resource_type, $resource_name) ) {
$this->_syntax_error("insert: $resource_type: $resource_name is not trusted");
return false;
}
}
include_once($resource_name);
}
if ($resource_type == 'file') {
include_once($php_resource);
} else {
eval($php_resource);
}
unset($args['script']);
}
$function_name = $this->_plugins['insert'][$args['name']][0];
$content = $function_name($args, $this); $content = $function_name($args, $this);
if ($this->debugging) { if ($this->debugging) {
$this->_smarty_debug_info[] = array('type' => 'insert', $this->_smarty_debug_info[] = array('type' => 'insert',
@@ -1194,8 +1197,9 @@ function _run_insert_handler($args)
'depth' => $this->_inclusion_depth, 'depth' => $this->_inclusion_depth,
'exec_time' => $this->_get_microtime() - $debug_start_time); 'exec_time' => $this->_get_microtime() - $debug_start_time);
} }
if (!empty($args["assign"])) { if (!empty($args["assign"])) {
$this->assign($args["assign"],$content); $this->assign($args["assign"], $content);
} else { } else {
return $content; return $content;
} }
@@ -1210,7 +1214,9 @@ function _run_insert_handler($args)
function _run_mod_handler() function _run_mod_handler()
{ {
$args = func_get_args(); $args = func_get_args();
list($func_name, $map_array) = array_splice($args, 0, 2); list($modifier_name, $map_array) = array_splice($args, 0, 2);
list($func_name, $tpl_file, $tpl_line) =
$this->_plugins['modifier'][$modifier_name];
$var = $args[0]; $var = $args[0];
if ($map_array && is_array($var)) { if ($map_array && is_array($var)) {
@@ -1409,11 +1415,6 @@ function _run_insert_handler($args)
\*======================================================================*/ \*======================================================================*/
function _write_cache_file($tpl_file, $cache_id, $compile_id, $results) function _write_cache_file($tpl_file, $cache_id, $compile_id, $results)
{ {
// determine if insert tags are present
if (strpos($results,$this->_smarty_md5)) {
$this->_cache_info['insert_tags'] = true;
}
// put timestamp in cache header // put timestamp in cache header
$this->_cache_info['timestamp'] = time(); $this->_cache_info['timestamp'] = time();
@@ -1450,7 +1451,6 @@ function _run_insert_handler($args)
} }
if (!empty($this->cache_handler_func)) { if (!empty($this->cache_handler_func)) {
// use cache_handler function // use cache_handler function
$funcname = $this->cache_handler_func; $funcname = $this->cache_handler_func;
$funcname('read', $this, $results, $tpl_file, $cache_id, $compile_id); $funcname('read', $this, $results, $tpl_file, $cache_id, $compile_id);
@@ -1485,25 +1485,24 @@ function _run_insert_handler($args)
} }
if ($this->compile_check) { if ($this->compile_check) {
foreach ($this->_cache_info as $curr_cache_info) { foreach ($this->_cache_info['template'] as $template_dep) {
switch ($curr_cache_info[0]) { $this->_fetch_template_info($template_dep, $template_source, $template_timestamp, false);
case 'template':
$this->_fetch_template_info($curr_cache_info[1], $template_source, $template_timestamp, false);
if ($cache_timestamp < $template_timestamp) { if ($cache_timestamp < $template_timestamp) {
// template file has changed, regenerate cache // template file has changed, regenerate cache
return false; return false;
} }
break; }
case 'config': if (isset($this->_cache_info['config'])) {
if ($cache_timestamp < filemtime($this->config_dir.'/'.$curr_cache_info[1])) { foreach ($this->_cache_info['config'] as $config_dep) {
if ($cache_timestamp < filemtime($this->config_dir.'/'.$config_dep)) {
// config file file has changed, regenerate cache // config file file has changed, regenerate cache
return false; return false;
} }
break;
} }
} }
} }
$results = $cache_split[1]; $results = $cache_split[1];
return true; return true;
} else { } else {
@@ -1513,6 +1512,181 @@ function _run_insert_handler($args)
} }
/*======================================================================*\
Function: _load_plugins
Purpose: Load requested plugins
\*======================================================================*/
function _load_plugins($plugins)
{
foreach ($plugins as $plugin_info) {
list($type, $name, $tpl_file, $tpl_line) = $plugin_info;
$plugin = &$this->_plugins[$type][$name];
/*
* We do not load plugin more than once for each instance of Smarty.
* The following code checks for that. The plugin can also be
* registered dynamically at runtime, in which case template file
* and line number will be unknown, so we fill them in.
*
* The final element of the info array is a flag that indicates
* whether the dynamically registered plugin function has been
* checked for existence yet or not.
*/
if (isset($plugin)) {
if (!$plugin[3]) {
if (!function_exists($plugin[0])) {
$this->_trigger_plugin_error("$type '$name' is not implemented", $tpl_file, $tpl_line);
} else {
$plugin[1] = $tpl_file;
$plugin[2] = $tpl_line;
$plugin[3] = true;
}
}
continue;
} else if ($type == 'insert') {
/*
* For backwards compatibility, we check for insert functions in
* the symbol table before trying to load them as a plugin.
*/
$plugin_func = 'insert_' . $name;
if (function_exists($plugin_func)) {
$plugin = array($plugin_func, $tpl_file, $tpl_line, true);
continue;
}
}
$plugin_file = $this->plugins_dir .
'/' .
$type .
'.' .
$name .
'.php';
$found = true;
if (!file_exists($plugin_file) || !is_readable($plugin_file)) {
$message = "could not load plugin file $plugin_file\n";
$found = false;
}
/*
* If plugin file is found, it -must- provide the properly named
* plugin function. In case it doesn't, simply output the error and
* do not fall back on any other method.
*/
if ($found) {
include_once $plugin_file;
$plugin_func = 'smarty_' . $type . '_' . $name;
if (!function_exists($plugin_func)) {
$this->_trigger_plugin_error("plugin function $plugin_func() not found in $plugin_file", $tpl_file, $tpl_line);
continue;
}
}
/*
* Plugin specific processing and error checking.
*/
if (!$found) {
if ($type == 'modifier') {
/*
* In case modifier falls back on using PHP functions
* directly, we only allow those specified in the security
* context.
*/
if ($this->security && !in_array($name, $this->security_settings['MODIFIER_FUNCS'])) {
$message = "(secure mode) modifier '$name' is not allowed";
} else {
if (!function_exists($name)) {
$message = "modifier '$name' is not implemented";
} else {
$plugin_func = $name;
$found = true;
}
}
} else if ($type == 'function') {
/*
* This is a catch-all situation.
*/
$message = "unknown tag - '$name'";
}
}
if ($found) {
$this->_plugins[$type][$name] = array($plugin_func, $tpl_file, $tpl_line, true);
} else {
// output error
$this->_trigger_plugin_error($message, $tpl_file, $tpl_line);
}
}
}
/*======================================================================*\
Function: _load_resource_plugin
Purpose:
\*======================================================================*/
function _load_resource_plugin($type)
{
/*
* Resource plugins are not quite like the other ones, so they are
* handled differently. The first element of plugin info is the array of
* functions provided by the plugin, the second one indicates whether
* all of them exist or not.
*/
$plugin = &$this->_plugins['resource'][$type];
if (isset($plugin)) {
if (!$plugin[1] && count($plugin[0])) {
$plugin[1] = true;
foreach ($plugin[0] as $plugin_func) {
if (!function_exists($plugin_func)) {
$plugin[1] = false;
break;
}
}
}
if (!$plugin[1]) {
$this->_trigger_plugin_error("resource '$type' is not implemented");
}
return;
}
$plugin_file = $this->plugins_dir .
'/resource.' .
$type .
'.php';
$found = true;
if (!file_exists($plugin_file) || !is_readable($plugin_file)) {
$this->_trigger_plugin_error("could not load plugin file $plugin_file");
$found = false;
} else {
/*
* If the plugin file is found, it -must- provide the properly named
* plugin functions.
*/
include_once $plugin_file;
/*
* Locate functions that we require the plugin to provide.
*/
$resource_ops = array('source', 'timestamp', 'secure', 'trusted');
$resource_funcs = array();
foreach ($resource_ops as $op) {
$plugin_func = 'smarty_resource_' . $type . '_' . $op;
if (!function_exists($plugin_func)) {
$this->_trigger_plugin_error("plugin function $plugin_func() not found in $plugin_file");
return;
} else {
$resource_funcs[] = $plugin_func;
}
}
$this->_plugins['resource'][$type] = array($resource_funcs, true);
}
}
/*======================================================================*\ /*======================================================================*\
Function: quote_replace Function: quote_replace
Purpose: Quote subpattern references Purpose: Quote subpattern references
@@ -1532,6 +1706,20 @@ function _run_insert_handler($args)
trigger_error("Smarty error: $error_msg", $error_type); trigger_error("Smarty error: $error_msg", $error_type);
} }
/*======================================================================*\
Function: _trigger_plugin_error
Purpose: trigger Smarty plugin error
\*======================================================================*/
function _trigger_plugin_error($error_msg, $tpl_file = null, $tpl_line = null, $error_type = E_USER_WARNING)
{
if (isset($tpl_line) && isset($tpl_file)) {
trigger_error("Smarty plugin error: [in " . $tpl_file . " line " .
$tpl_line . "]: $error_msg", $error_type);
} else {
trigger_error("Smarty plugin error: $error_msg", $error_type);
}
}
/*======================================================================*\ /*======================================================================*\
Function: _get_microtime Function: _get_microtime
Purpose: Get seconds and microseconds Purpose: Get seconds and microseconds

View File

@@ -7,7 +7,7 @@
* Andrei Zmievski <andrei@php.net> * Andrei Zmievski <andrei@php.net>
* *
* Version: 1.5.2 * Version: 1.5.2
* Copyright: 2001 ispi of Lincoln, Inc. * Copyright: 2001,2002 ispi of Lincoln, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -48,6 +48,8 @@ class Smarty_Compiler extends Smarty {
var $_current_file = null; // the current template being compiled var $_current_file = null; // the current template being compiled
var $_current_line_no = 1; // line number for error messages var $_current_line_no = 1; // line number for error messages
var $_capture_stack = array(); // keeps track of nested capture buffers var $_capture_stack = array(); // keeps track of nested capture buffers
var $_plugin_info = array(); // keeps track of plugins to load
var $_filters_loaded = false;
/*======================================================================*\ /*======================================================================*\
@@ -64,13 +66,19 @@ class Smarty_Compiler extends Smarty {
} }
} }
if (!$this->_filters_loaded) {
$this->_load_filters();
$this->_filters_loaded = true;
}
// run template source through prefilter functions // run template source through prefilter functions
if (is_array($this->prefilter_funcs) && count($this->prefilter_funcs) > 0) { if (count($this->_plugins['prefilter']) > 0) {
foreach ($this->prefilter_funcs as $prefilter) { foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
if (function_exists($prefilter)) { if ($prefilter[3] || function_exists($prefilter[0])) {
$template_source = $prefilter($template_source, $this); $template_source = $prefilter[0]($template_source, $this);
$this->_plugins['prefilter'][$filter_name][3] = true;
} else { } else {
$this->_trigger_error_msg("prefilter function $prefilter does not exist."); $this->_trigger_plugin_error("Smarty plugin error: prefilter '$filter_name' is not implemented");
} }
} }
} }
@@ -170,16 +178,30 @@ class Smarty_Compiler extends Smarty {
} }
// run compiled template through postfilter functions // run compiled template through postfilter functions
if (is_array($this->postfilter_funcs) && count($this->postfilter_funcs) > 0) { if (count($this->_plugins['postfilter']) > 0) {
foreach ($this->postfilter_funcs as $postfilter) { foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
if (function_exists($postfilter)) { if ($postfilter[3] || function_exists($postfilter[0])) {
$template_compiled = $postfilter($template_compiled, $this); $template_compiled = $postfilter[0]($template_compiled, $this);
$this->_plugins['postfilter'][$filter_name][3] = true;
} else { } else {
$this->_trigger_error_msg("postfilter function $postfilter does not exist."); $this->_trigger_plugin_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
} }
} }
} }
/* Emit code to load needed plugins. */
if (count($this->_plugin_info)) {
$plugins_code = '<?php $this->_load_plugins(array(';
foreach ($this->_plugin_info as $plugin_type => $plugins) {
foreach ($plugins as $plugin_name => $plugin_info) {
$plugins_code .= "\narray('$plugin_type', '$plugin_name', '$plugin_info[0]', $plugin_info[1]),";
}
}
$plugins_code .= ")); ?>";
$template_compiled = $plugins_code . $template_compiled;
$this->_plugin_info = array();
}
return true; return true;
} }
@@ -300,13 +322,10 @@ class Smarty_Compiler extends Smarty {
return $this->_compile_insert_tag($tag_args); return $this->_compile_insert_tag($tag_args);
default: default:
if (isset($this->compiler_funcs[$tag_command])) { if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
return $this->_compile_compiler_tag($tag_command, $tag_args); return $output;
} else if (isset($this->custom_funcs[$tag_command])) {
return $this->_compile_custom_tag($tag_command, $tag_args);
} else { } else {
$this->_syntax_error("unknown tag - '$tag_command'", E_USER_WARNING); return $this->_compile_custom_tag($tag_command, $tag_args);
return;
} }
} }
} }
@@ -316,16 +335,62 @@ class Smarty_Compiler extends Smarty {
Function: _compile_compiler_tag Function: _compile_compiler_tag
Purpose: compile the custom compiler tag Purpose: compile the custom compiler tag
\*======================================================================*/ \*======================================================================*/
function _compile_compiler_tag($tag_command, $tag_args) function _compile_compiler_tag($tag_command, $tag_args, &$output)
{ {
$function = $this->compiler_funcs[$tag_command]; $found = false;
$have_function = true;
if (!function_exists($function)) { $plugin_file = $this->plugins_dir .
$this->_syntax_error("compiler function '$tag_command' is not implemented", E_USER_WARNING); '/compiler.' .
return; $tag_command .
'.php';
/*
* First we check if the compiler function has already been registered
* or loaded from a plugin file.
*/
if (isset($this->_plugins['compiler'][$tag_command])) {
$found = true;
$plugin_func = $this->_plugins['compiler'][$tag_command][0];
if (!function_exists($plugin_func)) {
$message = "compiler function '$tag_command' is not implemented";
$have_function = false;
}
}
/*
* Otherwise we need to load plugin file and look for the function
* inside it.
*/
else if (file_exists($plugin_file) && is_readable($plugin_file)) {
$found = true;
include_once $plugin_file;
$plugin_func = 'smarty_compiler_' . $tag_command;
if (!function_exists($plugin_func)) {
$message = "plugin function $plugin_func() not found in $plugin_file\n";
$have_function = false;
} else {
$this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null);
}
} }
return '<?php ' . $function($tag_args, $this) . ' ?>'; /*
* True return value means that we either found a plugin or a
* dynamically registered function. False means that we didn't and the
* compiler should now emit code to load custom function plugin for this
* tag.
*/
if ($found) {
if ($have_function) {
$output = '<?php ' . $plugin_func($tag_args, $this) . ' ?>';
} else {
$this->_syntax_error($message, E_USER_WARNING);
}
return true;
} else {
return false;
}
} }
@@ -335,12 +400,10 @@ class Smarty_Compiler extends Smarty {
\*======================================================================*/ \*======================================================================*/
function _compile_custom_tag($tag_command, $tag_args) function _compile_custom_tag($tag_command, $tag_args)
{ {
$function = $this->custom_funcs[$tag_command]; $this->_add_plugin('function',
$tag_command,
if (!function_exists($function)) { $this->_current_file,
$this->_syntax_error("custom function '$tag_command' is not implemented", E_USER_WARNING); $this->_current_line_no);
return;
}
$arg_list = array(); $arg_list = array();
$attrs = $this->_parse_attrs($tag_args); $attrs = $this->_parse_attrs($tag_args);
@@ -350,7 +413,7 @@ class Smarty_Compiler extends Smarty {
$arg_list[] = "'$arg_name' => $arg_value"; $arg_list[] = "'$arg_name' => $arg_value";
} }
return "<?php $function(array(".implode(',', (array)$arg_list)."), \$this); if(\$this->_extract) { extract(\$this->_tpl_vars); \$this->_extract=false; } ?>"; return "<?php \$this->_plugins['function']['$tag_command'][0](array(".implode(',', (array)$arg_list)."), \$this); if(\$this->_extract) { extract(\$this->_tpl_vars); \$this->_extract=false; } ?>";
} }
@@ -361,7 +424,7 @@ class Smarty_Compiler extends Smarty {
function _compile_insert_tag($tag_args) function _compile_insert_tag($tag_args)
{ {
$attrs = $this->_parse_attrs($tag_args); $attrs = $this->_parse_attrs($tag_args);
$name = substr($attrs['name'], 1, -1); $name = $this->_dequote($attrs['name']);
if (empty($name)) { if (empty($name)) {
$this->_syntax_error("missing insert name"); $this->_syntax_error("missing insert name");
@@ -373,6 +436,8 @@ class Smarty_Compiler extends Smarty {
$arg_list[] = "'$arg_name' => $arg_value"; $arg_list[] = "'$arg_name' => $arg_value";
} }
$this->_add_plugin('insert', $name);
return "<?php echo \$this->_run_insert_handler(array(".implode(', ', (array)$arg_list).")); ?>\n"; return "<?php echo \$this->_run_insert_handler(array(".implode(', ', (array)$arg_list).")); ?>\n";
} }
@@ -471,28 +536,25 @@ class Smarty_Compiler extends Smarty {
if (empty($attrs['file'])) { if (empty($attrs['file'])) {
$this->_syntax_error("missing 'file' attribute in include_php tag"); $this->_syntax_error("missing 'file' attribute in include_php tag");
return false;
} }
$this->_parse_file_path($this->trusted_dir, $this->_dequote($attrs['file']), $resource_type, $resource_name); $this->_get_php_resource($this->_dequote($attrs['file']),
$resource_type, $php_resource);
if ($this->security) {
if( $resource_type != 'file' || !@is_file($resource_name)) {
$this->_syntax_error("include_php: $resource_type: $resource_name is not readable");
return false;
}
if (!$this->_is_trusted($resource_type, $resource_name)) {
$this->_syntax_error("include_php: $resource_type: $resource_name is not trusted");
return false;
}
}
if (!empty($attrs['assign'])) { if (!empty($attrs['assign'])) {
$output = "<?php ob_start();\n"; $output = "<?php ob_start();\n";
$output .= 'include("' . $resource_name . '");'."\n"; if ($resource_type == 'file') {
$output .= "\$this->assign(" . $this->_dequote($attrs['assign']).", ob_get_contents()); ob_end_clean();\n?>"; $output .= 'include("' . $php_resource . '");'."\n";
} else { } else {
$output = '<?php include("' . $resource_name . '"); ?>'; $output .= $php_resource;
}
$output .= "\$this->assign(" . $attrs['assign'] . ", ob_get_contents()); ob_end_clean();\n?>";
} else {
if ($resource_type == 'file') {
$output = '<?php include("' . $php_resource . '"); ?>';
} else {
$output = '<?php ' . $php_resource . ' ?>';
}
} }
return $output; return $output;
@@ -1083,32 +1145,11 @@ class Smarty_Compiler extends Smarty {
if ($modifier_name{0} == '@') { if ($modifier_name{0} == '@') {
$map_array = 'false'; $map_array = 'false';
$modifier_name = substr($modifier_name, 1); $modifier_name = substr($modifier_name, 1);
} else
$map_array = 'true';
/*
* First we lookup the modifier function name in the registered
* modifiers table.
*/
@$mod_func_name = $this->custom_mods[$modifier_name];
/*
* If we don't find that modifier there, we assume it's just a PHP
* function name.
*/
if (!isset($mod_func_name)) {
if ($this->security && !in_array($modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
$this->_syntax_error("(secure mode) modifier '$modifier_name' is not allowed", E_USER_WARNING);
continue;
} else { } else {
$mod_func_name = $modifier_name; $map_array = 'true';
}
} }
if (!function_exists($mod_func_name)) { $this->_add_plugin('modifier', $modifier_name);
$this->_syntax_error("modifier '$modifier_name' is not implemented", E_USER_WARNING);
continue;
}
$this->_parse_vars_props($modifier_args); $this->_parse_vars_props($modifier_args);
@@ -1117,7 +1158,23 @@ class Smarty_Compiler extends Smarty {
else else
$modifier_args = ''; $modifier_args = '';
$output = "\$this->_run_mod_handler('$mod_func_name', $map_array, $output$modifier_args)"; $output = "\$this->_run_mod_handler('$modifier_name', $map_array, $output$modifier_args)";
}
}
/*======================================================================*\
Function: _add_plugin
Purpose:
\*======================================================================*/
function _add_plugin($type, $name)
{
if (!isset($this->_plugin_info[$type])) {
$this->_plugin_info[$type] = array();
}
if (!isset($this->_plugin_info[$type][$name])) {
$this->_plugin_info[$type][$name] = array($this->_current_file,
$this->_current_line_no);
} }
} }
@@ -1172,6 +1229,38 @@ class Smarty_Compiler extends Smarty {
return $compiled_ref; return $compiled_ref;
} }
/*======================================================================*\
Function: _load_filters
Purpose: load pre- and post-filters
\*======================================================================*/
function _load_filters()
{
$plugins_dir = $this->plugins_dir;
$handle = opendir($plugins_dir);
while ($entry = readdir($handle)) {
$parts = explode('.', $entry, 3);
if ($entry == '.' ||
$entry == '..' ||
count($parts) < 3 ||
$parts[2] != 'php' ||
($parts[0] != 'prefilter' &&
$parts[0] != 'postfilter') ||
isset($this->_plugins[$parts[0]][$parts[1]]))
continue;
$plugin_file = $plugins_dir . '/' . $entry;
include_once $plugin_file;
$plugin_func = 'smarty_' . $parts[0] . '_' . $parts[1];
if (!function_exists($plugin_func)) {
$this->_trigger_plugin_error("Smarty plugin error: plugin function $plugin_func() not found in $plugin_file");
} else {
$this->_plugins[$parts[0]][$parts[1]] = array($plugin_func, null, null, true);
}
}
closedir($handle);
}
/*======================================================================*\ /*======================================================================*\
Function: _syntax_error Function: _syntax_error
Purpose: display Smarty syntax error Purpose: display Smarty syntax error

6
TODO
View File

@@ -1,6 +1,4 @@
* Ability to load multiple sections in one {config_load ...} * Ability to load multiple sections in one {config_load ...}
* do away with Smarty.addons.php and make drop-in plugin directory for
functions and modifiers
* handle asp style tags in $php_handler * handle asp style tags in $php_handler
* correctly capture nested php tag syntax in templates: * correctly capture nested php tag syntax in templates:
<?php echo "<?php exit(); ?>"; ?> <?php echo "<?php exit(); ?>"; ?>
@@ -8,8 +6,10 @@
default=$foo}, then using $bar in included template, instead of $foo.bar default=$foo}, then using $bar in included template, instead of $foo.bar
* support implementations of prefiltes, mods, and others as class methods. * support implementations of prefiltes, mods, and others as class methods.
* possibly implement default modifiers that apply to variables upon display * possibly implement default modifiers that apply to variables upon display
* possibly implement undefined template tags custom handling
* think about possibility of supporting something like {$data[foo].$key[bar]} * think about possibility of supporting something like {$data[foo].$key[bar]}
* allow {custom} .. {/custom} style of custom functions * allow {custom} .. {/custom} style of custom functions
* ability to concatenate values/strings together * ability to concatenate values/strings together
* fix all E_NOTICE warnings * fix all E_NOTICE warnings
* make simple math easier
* 'eval' modifier
* caching all but parts of the template

View File

@@ -1,5 +1,5 @@
{config_load file=test.conf section="setup"} {config_load file=test.conf section="setup"}
{include file=header.tpl title=foo} {include file="header.tpl" title=foo}
<PRE> <PRE>

View File

@@ -9,7 +9,7 @@ require_once "PEAR.php";
* @author Andrei Zmievski <andrei@php.net> * @author Andrei Zmievski <andrei@php.net>
* @access public * @access public
* *
* Copyright: 2001 ispi of Lincoln, Inc. * Copyright: 2001,2002 ispi of Lincoln, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View File

@@ -1,5 +1,4 @@
<?php <?php
/* /*
* Project: Smarty: the PHP compiling template engine * Project: Smarty: the PHP compiling template engine
* File: Smarty.class.php * File: Smarty.class.php
@@ -7,7 +6,7 @@
* Andrei Zmievski <andrei@php.net> * Andrei Zmievski <andrei@php.net>
* *
* Version: 1.5.2 * Version: 1.5.2
* Copyright: 2001 ispi of Lincoln, Inc. * Copyright: 2001,2002 ispi of Lincoln, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -48,7 +47,7 @@ if (!defined('SMARTY_DIR')) {
define('SMARTY_DIR', ''); define('SMARTY_DIR', '');
} }
require_once SMARTY_DIR.'Smarty.addons.php'; //require_once SMARTY_DIR.'Smarty.addons.php';
define('SMARTY_PHP_PASSTHRU', 0); define('SMARTY_PHP_PASSTHRU', 0);
define('SMARTY_PHP_QUOTE', 1); define('SMARTY_PHP_QUOTE', 1);
@@ -67,6 +66,7 @@ class Smarty
var $template_dir = './templates'; // name of directory for templates var $template_dir = './templates'; // name of directory for templates
var $compile_dir = './templates_c'; // name of directory for compiled templates var $compile_dir = './templates_c'; // name of directory for compiled templates
var $config_dir = './configs'; // directory where config files are located var $config_dir = './configs'; // directory where config files are located
var $plugins_dir = './plugins'; // directory where plugins are kept
var $debugging = false; // enable debugging console true/false var $debugging = false; // enable debugging console true/false
var $debug_tpl = 'file:debug.tpl'; // path to debug console template var $debug_tpl = 'file:debug.tpl'; // path to debug console template
@@ -133,53 +133,12 @@ class Smarty
var $left_delimiter = '{'; // template tag delimiters. var $left_delimiter = '{'; // template tag delimiters.
var $right_delimiter = '}'; var $right_delimiter = '}';
var $compiler_funcs = array(
);
var $custom_funcs = array( 'html_options' => 'smarty_func_html_options',
'html_select_date' => 'smarty_func_html_select_date',
'html_select_time' => 'smarty_func_html_select_time',
'math' => 'smarty_func_math',
'fetch' => 'smarty_func_fetch',
'counter' => 'smarty_func_counter',
'assign' => 'smarty_func_assign',
'popup_init' => 'smarty_func_overlib_init',
'popup' => 'smarty_func_overlib',
'assign_debug_info' => 'smarty_func_assign_debug_info'
);
var $custom_mods = array( 'lower' => 'strtolower',
'upper' => 'strtoupper',
'capitalize' => 'ucwords',
'escape' => 'smarty_mod_escape',
'truncate' => 'smarty_mod_truncate',
'spacify' => 'smarty_mod_spacify',
'date_format' => 'smarty_mod_date_format',
'string_format' => 'smarty_mod_string_format',
'replace' => 'smarty_mod_replace',
'regex_replace' => 'smarty_mod_regex_replace',
'strip_tags' => 'smarty_mod_strip_tags',
'default' => 'smarty_mod_default',
'count_characters' => 'smarty_mod_count_characters',
'count_words' => 'smarty_mod_count_words',
'count_sentences' => 'smarty_mod_count_sentences',
'count_paragraphs' => 'smarty_mod_count_paragraphs',
'wordwrap' => 'smarty_mod_wordwrap',
'indent' => 'smarty_mod_indent',
'debug_print_var' => 'smarty_mod_debug_print_var'
);
var $show_info_header = false; // display HTML info header at top of page output var $show_info_header = false; // display HTML info header at top of page output
var $show_info_include = false; // display HTML comments at top & bottom of var $show_info_include = false; // display HTML comments at top & bottom of
// each included template // each included template
var $compiler_class = 'Smarty_Compiler'; // the compiler class used by var $compiler_class = 'Smarty_Compiler'; // the compiler class used by
// Smarty to compile templates // Smarty to compile templates
var $resource_funcs = array(); // functions that resource handlers are mapped to
var $prefilter_funcs = array(); // functions that templates are filtered through
// before being compiled
var $postfilter_funcs = array(); // functions that compiled templates are filtered
// through after compilation
var $request_vars_order = "EGPCS"; // the order in which request variables are var $request_vars_order = "EGPCS"; // the order in which request variables are
// registered, similar to variables_order // registered, similar to variables_order
@@ -208,6 +167,14 @@ class Smarty
var $_smarty_debug_id = 'SMARTY_DEBUG'; // text in URL to enable debug mode var $_smarty_debug_id = 'SMARTY_DEBUG'; // text in URL to enable debug mode
var $_smarty_debug_info = array(); // debugging information for debug console var $_smarty_debug_info = array(); // debugging information for debug console
var $_cache_info = array(); // info that makes up a cache file var $_cache_info = array(); // info that makes up a cache file
var $_plugins = array( // table keeping track of plugins
'modifier' => array(),
'function' => array(),
'compiler' => array(),
'prefilter' => array(),
'postfilter'=> array(),
'resource' => array(),
'insert' => array());
/*======================================================================*\ /*======================================================================*\
@@ -301,7 +268,8 @@ class Smarty
\*======================================================================*/ \*======================================================================*/
function register_function($function, $function_impl) function register_function($function, $function_impl)
{ {
$this->custom_funcs[$function] = $function_impl; $this->_plugins['function'][$function] =
array($function_impl, null, null, false);
} }
/*======================================================================*\ /*======================================================================*\
@@ -310,7 +278,7 @@ class Smarty
\*======================================================================*/ \*======================================================================*/
function unregister_function($function) function unregister_function($function)
{ {
unset($this->custom_funcs[$function]); unset($this->_plugins['function'][$function]);
} }
/*======================================================================*\ /*======================================================================*\
@@ -319,7 +287,8 @@ class Smarty
\*======================================================================*/ \*======================================================================*/
function register_compiler_function($function, $function_impl) function register_compiler_function($function, $function_impl)
{ {
$this->compiler_funcs[$function] = $function_impl; $this->_plugins['compiler'][$function] =
array($function_impl, null, null, false);
} }
/*======================================================================*\ /*======================================================================*\
@@ -328,7 +297,7 @@ class Smarty
\*======================================================================*/ \*======================================================================*/
function unregister_compiler_function($function) function unregister_compiler_function($function)
{ {
unset($this->compiler_funcs[$function]); unset($this->_plugins['compiler'][$function]);
} }
/*======================================================================*\ /*======================================================================*\
@@ -337,7 +306,8 @@ class Smarty
\*======================================================================*/ \*======================================================================*/
function register_modifier($modifier, $modifier_impl) function register_modifier($modifier, $modifier_impl)
{ {
$this->custom_mods[$modifier] = $modifier_impl; $this->_plugins['modifier'][$modifier] =
array($modifier_impl, null, null, false);
} }
/*======================================================================*\ /*======================================================================*\
@@ -346,25 +316,26 @@ class Smarty
\*======================================================================*/ \*======================================================================*/
function unregister_modifier($modifier) function unregister_modifier($modifier)
{ {
unset($this->custom_mods[$modifier]); unset($this->_plugins['modifier'][$modifier]);
} }
/*======================================================================*\ /*======================================================================*\
Function: register_resource Function: register_resource
Purpose: Registers a resource to fetch a template Purpose: Registers a resource to fetch a template
\*======================================================================*/ \*======================================================================*/
function register_resource($name, $function_name) function register_resource($type, $functions)
{ {
$this->resource_funcs[$name] = $function_name; $this->_plugins['resource'][$type] =
array((array)$functions, false);
} }
/*======================================================================*\ /*======================================================================*\
Function: unregister_resource Function: unregister_resource
Purpose: Unregisters a resource Purpose: Unregisters a resource
\*======================================================================*/ \*======================================================================*/
function unregister_resource($name) function unregister_resource($type)
{ {
unset($this->resource_funcs[$name]); unset($this->_plugins['resource'][$type]);
} }
/*======================================================================*\ /*======================================================================*\
@@ -372,24 +343,19 @@ class Smarty
Purpose: Registers a prefilter function to apply Purpose: Registers a prefilter function to apply
to a template before compiling to a template before compiling
\*======================================================================*/ \*======================================================================*/
function register_prefilter($function_name) function register_prefilter($function)
{ {
$this->prefilter_funcs[] = $function_name; $this->_plugins['prefilter'][$function]
= array($function, null, null, false);
} }
/*======================================================================*\ /*======================================================================*\
Function: unregister_prefilter Function: unregister_prefilter
Purpose: Unregisters a prefilter function Purpose: Unregisters a prefilter function
\*======================================================================*/ \*======================================================================*/
function unregister_prefilter($function_name) function unregister_prefilter($function)
{ {
$tmp_array = array(); unset($this->_plugins['prefilter'][$function]);
foreach($this->prefilter_funcs as $curr_func) {
if ($curr_func != $function_name) {
$tmp_array[] = $curr_func;
}
}
$this->prefilter_funcs = $tmp_array;
} }
/*======================================================================*\ /*======================================================================*\
@@ -397,24 +363,19 @@ class Smarty
Purpose: Registers a postfilter function to apply Purpose: Registers a postfilter function to apply
to a compiled template after compilation to a compiled template after compilation
\*======================================================================*/ \*======================================================================*/
function register_postfilter($function_name) function register_postfilter($function)
{ {
$this->postfilter_funcs[] = $function_name; $this->_plugins['postfilter'][$function]
= array($function, null, null, false);
} }
/*======================================================================*\ /*======================================================================*\
Function: unregister_postfilter Function: unregister_postfilter
Purpose: Unregisters a postfilter function Purpose: Unregisters a postfilter function
\*======================================================================*/ \*======================================================================*/
function unregister_postfilter($function_name) function unregister_postfilter($function)
{ {
$tmp_array = array(); unset($this->_plugins['postfilter'][$function]);
foreach($this->postfilter_funcs as $curr_func) {
if ($curr_func != $function_name) {
$tmp_array[] = $curr_func;
}
}
$this->postfilter_funcs = $tmp_array;
} }
/*======================================================================*\ /*======================================================================*\
@@ -466,6 +427,7 @@ class Smarty
if (!isset($compile_id)) if (!isset($compile_id))
$compile_id = $this->compile_id; $compile_id = $this->compile_id;
return $this->_read_cache_file($tpl_file, $cache_id, $compile_id, $results); return $this->_read_cache_file($tpl_file, $cache_id, $compile_id, $results);
} }
@@ -541,11 +503,9 @@ class Smarty
$this->_inclusion_depth = 0; $this->_inclusion_depth = 0;
if ($this->caching) { if ($this->caching) {
$this->_cache_info[] = array('template', $_smarty_tpl_file);
if ($this->_read_cache_file($_smarty_tpl_file, $_smarty_cache_id, $_smarty_compile_id, $_smarty_results)) { if ($this->_read_cache_file($_smarty_tpl_file, $_smarty_cache_id, $_smarty_compile_id, $_smarty_results)) {
if ( $this->_cache_info['insert_tags'] ) { if (@count($this->_cache_info['insert_tags'])) {
$this->_load_plugins($this->_cache_info['insert_tags']);
$_smarty_results = $this->_process_cached_inserts($_smarty_results); $_smarty_results = $this->_process_cached_inserts($_smarty_results);
} }
if ($_smarty_display) { if ($_smarty_display) {
@@ -556,12 +516,12 @@ class Smarty
$_smarty_results .= $this->_generate_debug_output(); $_smarty_results .= $this->_generate_debug_output();
} }
if( $this->check_if_modified ) { if ($this->check_if_modified) {
global $HTTP_IF_MODIFIED_SINCE; global $HTTP_IF_MODIFIED_SINCE;
$last_modified_date = substr($HTTP_IF_MODIFIED_SINCE,0,strpos($HTTP_IF_MODIFIED_SINCE,'GMT')+3); $last_modified_date = substr($HTTP_IF_MODIFIED_SINCE,0,strpos($HTTP_IF_MODIFIED_SINCE,'GMT')+3);
$gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT'; $gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
if( !$this->_cache_info['insert_tags'] if (@count($this->_cache_info['insert_tags']) == 0
&& $gmt_mtime == $last_modified_date ) { && $gmt_mtime == $last_modified_date) {
header("HTTP/1.1 304 Not Modified"); header("HTTP/1.1 304 Not Modified");
} }
} }
@@ -572,6 +532,9 @@ class Smarty
} else { } else {
return $_smarty_results; return $_smarty_results;
} }
} else {
$this->_cache_info = array();
$this->_cache_info['template'][] = $_smarty_tpl_file;
} }
} }
@@ -600,15 +563,6 @@ class Smarty
$compile_path = $this->_get_compile_path($_smarty_tpl_file); $compile_path = $this->_get_compile_path($_smarty_tpl_file);
$_smarty_trusted = false;
if ($this->security) {
$this->_parse_file_path($this->template_dir, $_smarty_tpl_file, $resource_type, $resource_name);
if ($this->_is_trusted($resource_type, $resource_name)) {
$_smarty_trusted = true;
$this->security = false;
}
}
// if we just need to display the results, don't perform output // if we just need to display the results, don't perform output
// buffering - for speed // buffering - for speed
if ($_smarty_display && !$this->caching) { if ($_smarty_display && !$this->caching) {
@@ -618,7 +572,9 @@ class Smarty
if ($this->show_info_include) { if ($this->show_info_include) {
echo "\n<!-- SMARTY_BEGIN: ".$_smarty_tpl_file." -->\n"; echo "\n<!-- SMARTY_BEGIN: ".$_smarty_tpl_file." -->\n";
} }
include($compile_path); include($compile_path);
if ($this->show_info_include) { if ($this->show_info_include) {
echo "\n<!-- SMARTY_END: ".$_smarty_tpl_file." -->\n"; echo "\n<!-- SMARTY_END: ".$_smarty_tpl_file." -->\n";
} }
@@ -631,7 +587,9 @@ class Smarty
if ($this->show_info_include) { if ($this->show_info_include) {
echo "\n<!-- SMARTY_BEGIN: ".$_smarty_tpl_file." -->\n"; echo "\n<!-- SMARTY_BEGIN: ".$_smarty_tpl_file." -->\n";
} }
include($compile_path); include($compile_path);
if ($this->show_info_include) { if ($this->show_info_include) {
echo "\n<!-- SMARTY_END: ".$_smarty_tpl_file." -->\n"; echo "\n<!-- SMARTY_END: ".$_smarty_tpl_file." -->\n";
} }
@@ -639,9 +597,6 @@ class Smarty
$_smarty_results = ob_get_contents(); $_smarty_results = ob_get_contents();
ob_end_clean(); ob_end_clean();
} }
if ($_smarty_trusted) {
$this->security = true;
}
if ($this->caching) { if ($this->caching) {
$this->_write_cache_file($_smarty_tpl_file, $_smarty_cache_id, $_smarty_compile_id, $_smarty_results); $this->_write_cache_file($_smarty_tpl_file, $_smarty_cache_id, $_smarty_compile_id, $_smarty_results);
@@ -650,8 +605,7 @@ class Smarty
if ($_smarty_display) { if ($_smarty_display) {
if (isset($_smarty_results)) { echo $_smarty_results; } if (isset($_smarty_results)) { echo $_smarty_results; }
if ($this->debugging) if ($this->debugging) {
{
// capture time for debugging info // capture time for debugging info
$this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = ($this->_get_microtime() - $debug_start_time); $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = ($this->_get_microtime() - $debug_start_time);
@@ -729,19 +683,19 @@ function _generate_debug_output() {
/*======================================================================*\ /*======================================================================*\
Function: _is_trusted() Function: _is_trusted()
Purpose: determines if a template is within the trusted_dir or not. Purpose: determines if a resource is trusted or not
\*======================================================================*/ \*======================================================================*/
function _is_trusted($resource_type, $resource_name) function _is_trusted($resource_type, $resource_name)
{ {
$_smarty_trusted = false; $_smarty_trusted = false;
if ($resource_type == 'file') {
if (!empty($this->trusted_dir)) { if (!empty($this->trusted_dir)) {
// see if template file is within a trusted directory. If so, // see if template file is within a trusted directory. If so,
// disable security during the execution of the template. // disable security during the execution of the template.
if ($resource_type == 'file') {
if (!empty($this->trusted_dir)) { if (!empty($this->trusted_dir)) {
foreach ((array)$this->trusted_dir as $curr_dir) { foreach ((array)$this->trusted_dir as $curr_dir) {
if ( !empty($curr_dir) && is_readable ($curr_dir)) { if (!empty($curr_dir) && is_readable ($curr_dir)) {
if (substr(realpath($resource_name),0, strlen(realpath($curr_dir))) == realpath($curr_dir)) { if (substr(realpath($resource_name),0, strlen(realpath($curr_dir))) == realpath($curr_dir)) {
$_smarty_trusted = true; $_smarty_trusted = true;
break; break;
@@ -749,20 +703,22 @@ function _is_trusted($resource_type, $resource_name)
} }
} }
} }
}
} else { } else {
// resource is not on local file system // resource is not on local file system
$_smarty_trusted = false; $resource_func = $this->_plugins['resource'][$resource_type][0][3];
} $_smarty_trusted = $resource_func($resource_name, $this);
} }
return $_smarty_trusted; return $_smarty_trusted;
} }
/*======================================================================*\ /*======================================================================*\
Function: _is_secure() Function: _is_secure()
Purpose: determins if a template is secure or not. Purpose: determines if a resource is secure or not.
\*======================================================================*/ \*======================================================================*/
function _is_secure($resource_type, $resource_name) { function _is_secure($resource_type, $resource_name)
{
if (!$this->security || $this->security_settings['INCLUDE_ANY']) { if (!$this->security || $this->security_settings['INCLUDE_ANY']) {
return true; return true;
} }
@@ -781,11 +737,62 @@ function _is_trusted($resource_type, $resource_name)
} }
} else { } else {
// resource is not on local file system // resource is not on local file system
$_smarty_secure = true; $resource_func = $this->_plugins['resource'][$resource_type][0][2];
$_smarty_secure = $resource_func($resource_name, $_smarty_secure, $this);
} }
return $_smarty_secure; return $_smarty_secure;
} }
/*======================================================================*\
Function: _get_php_resource
Purpose: Retrieves PHP script resource
\*======================================================================*/
function _get_php_resource($resource, &$resource_type, &$php_resource)
{
$this->_parse_file_path($this->trusted_dir, $resource, $resource_type, $resource_name);
/*
* Find out if the resource exists.
*/
$readable = true;
if ($resource_type == 'file' && !@is_file($resource_name)) {
$readable = false;
} else if ($resource_type != 'file') {
$resource_func = $this->_plugins['resource'][$resource_type][0][0];
$readable = $resource_func($resource_name, $template_source, $this);
}
/*
* Set the error function, depending on which class calls us.
*/
if (method_exists($this, '_syntax_error')) {
$error_func = '_syntax_error';
} else {
$error_func = '_trigger_error_msg';
}
if ($readable) {
if ($this->security) {
if (!$this->_is_trusted($resource_type, $resource_name)) {
$this->$error_func("(secure mode) '$resource_type:$resource_name' is not trusted");
return false;
}
}
} else {
$this->$error_func("'$resource_type: $resource_name' is not readable");
return false;
}
if ($resource_type == 'file') {
$php_resource = $resource_name;
} else {
$php_resource = $template_source;
}
return true;
}
/*======================================================================*\ /*======================================================================*\
@@ -873,8 +880,8 @@ function _is_trusted($resource_type, $resource_name)
Function: _parse_file_path Function: _parse_file_path
Purpose: parse out the type and name from the template resource Purpose: parse out the type and name from the template resource
\*======================================================================*/ \*======================================================================*/
function _parse_file_path($file_base_path, $file_path, &$resource_type, &$resource_name) { function _parse_file_path($file_base_path, $file_path, &$resource_type, &$resource_name)
{
// split tpl_path by the first colon // split tpl_path by the first colon
$file_path_parts = explode(':', $file_path, 2); $file_path_parts = explode(':', $file_path, 2);
@@ -885,14 +892,17 @@ function _is_trusted($resource_type, $resource_name)
} else { } else {
$resource_type = $file_path_parts[0]; $resource_type = $file_path_parts[0];
$resource_name = $file_path_parts[1]; $resource_name = $file_path_parts[1];
if ($resource_type != 'file') {
$this->_load_resource_plugin($resource_type);
}
} }
if ($resource_type == 'file') { if ($resource_type == 'file') {
if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $resource_name)) { if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $resource_name)) {
// relative pathname to $file_base_path // relative pathname to $file_base_path
// use the first directory where the file is found // use the first directory where the file is found
foreach((array)$file_base_path as $curr_path) { foreach ((array)$file_base_path as $curr_path) {
if(@is_file($curr_path.'/'.$resource_name)) { if (@is_file($curr_path.'/'.$resource_name)) {
$resource_name = $curr_path.'/'.$resource_name; $resource_name = $curr_path.'/'.$resource_name;
return true; return true;
} }
@@ -912,10 +922,10 @@ function _is_trusted($resource_type, $resource_name)
Purpose: fetch the template info. Gets timestamp, and source Purpose: fetch the template info. Gets timestamp, and source
if get_source is true if get_source is true
\*======================================================================*/ \*======================================================================*/
function _fetch_template_info($tpl_path, &$template_source, &$template_timestamp, $get_source=true) function _fetch_template_info($tpl_path, &$template_source, &$template_timestamp, $get_source = true)
{ {
$_return = false; $_return = false;
if($this->_parse_file_path($this->template_dir, $tpl_path, $resource_type, $resource_name)) { if ($this->_parse_file_path($this->template_dir, $tpl_path, $resource_type, $resource_name)) {
switch ($resource_type) { switch ($resource_type) {
case 'file': case 'file':
if (@is_file($resource_name)) { if (@is_file($resource_name)) {
@@ -926,22 +936,26 @@ function _is_trusted($resource_type, $resource_name)
$_return = true; $_return = true;
} }
break; break;
default: default:
if (isset($this->resource_funcs[$resource_type])) { // call resource functions to fetch the template source and timestamp
$funcname = $this->resource_funcs[$resource_type]; if ($get_source) {
if (function_exists($funcname)) { $resource_func = $this->_plugins['resource'][$resource_type][0][0];
// call the function to fetch the template $_source_return = $resource_func($resource_name, $template_source, $this);
$_return = $funcname($resource_name, $template_source, $template_timestamp, $get_source, $this); } else {
} $_source_return = true;
} }
$resource_func = $this->_plugins['resource'][$resource_type][0][1];
$_timestamp_return = $resource_func($resource_name, $template_timestamp, $this);
$_return = $_source_return && $_timestamp_return;
break; break;
} }
} }
if(!$_return) { if (!$_return) {
// see if we can get a template with the default template handler // see if we can get a template with the default template handler
if(!empty($this->default_template_handler_func)) { if (!empty($this->default_template_handler_func)) {
if(!function_exists($this->default_template_handler_func)) { if (!function_exists($this->default_template_handler_func)) {
$this->_trigger_error_msg("default template handler function \"$this->default_template_handler_func\" doesn't exist."); $this->_trigger_error_msg("default template handler function \"$this->default_template_handler_func\" doesn't exist.");
$_return = false; $_return = false;
} }
@@ -950,14 +964,15 @@ function _is_trusted($resource_type, $resource_name)
} }
} }
if(!$_return) { if (!$_return) {
$this->_trigger_error_msg("unable to read template resource: \"$tpl_path\""); $this->_trigger_error_msg("unable to read template resource: \"$tpl_path\"");
} elseif ($_return && $this->security && !$this->_is_secure($resource_type, $resource_name) && !$this->_is_trusted($resource_type, $resource_name)) { } else if ($_return && $this->security && !$this->_is_secure($resource_type, $resource_name)) {
$this->_trigger_error_msg("(secure mode) accessing \"$tpl_path\" is not allowed"); $this->_trigger_error_msg("(secure mode) accessing \"$tpl_path\" is not allowed");
$template_source = null; $template_source = null;
$template_timestamp = null; $template_timestamp = null;
return false; return false;
} }
return $_return; return $_return;
} }
@@ -974,22 +989,19 @@ function _is_trusted($resource_type, $resource_name)
$smarty_compiler->template_dir = $this->template_dir; $smarty_compiler->template_dir = $this->template_dir;
$smarty_compiler->compile_dir = $this->compile_dir; $smarty_compiler->compile_dir = $this->compile_dir;
$smarty_compiler->plugins_dir = $this->plugins_dir;
$smarty_compiler->config_dir = $this->config_dir; $smarty_compiler->config_dir = $this->config_dir;
$smarty_compiler->force_compile = $this->force_compile; $smarty_compiler->force_compile = $this->force_compile;
$smarty_compiler->caching = $this->caching; $smarty_compiler->caching = $this->caching;
$smarty_compiler->php_handling = $this->php_handling; $smarty_compiler->php_handling = $this->php_handling;
$smarty_compiler->left_delimiter = $this->left_delimiter; $smarty_compiler->left_delimiter = $this->left_delimiter;
$smarty_compiler->right_delimiter = $this->right_delimiter; $smarty_compiler->right_delimiter = $this->right_delimiter;
$smarty_compiler->custom_funcs = $this->custom_funcs;
$smarty_compiler->custom_mods = $this->custom_mods;
$smarty_compiler->_version = $this->_version; $smarty_compiler->_version = $this->_version;
$smarty_compiler->prefilter_funcs = $this->prefilter_funcs;
$smarty_compiler->postfilter_funcs = $this->postfilter_funcs;
$smarty_compiler->compiler_funcs = $this->compiler_funcs;
$smarty_compiler->security = $this->security; $smarty_compiler->security = $this->security;
$smarty_compiler->secure_dir = $this->secure_dir; $smarty_compiler->secure_dir = $this->secure_dir;
$smarty_compiler->security_settings = $this->security_settings; $smarty_compiler->security_settings = $this->security_settings;
$smarty_compiler->trusted_dir = $this->trusted_dir; $smarty_compiler->trusted_dir = $this->trusted_dir;
$smarty_compiler->_plugins = &$this->_plugins;
if ($smarty_compiler->_compile_file($tpl_file, $template_source, $template_compiled)) if ($smarty_compiler->_compile_file($tpl_file, $template_source, $template_compiled))
return true; return true;
@@ -1019,14 +1031,6 @@ function _is_trusted($resource_type, $resource_name)
array_unshift($this->_config, $this->_config[0]); array_unshift($this->_config, $this->_config[0]);
$compile_path = $this->_get_compile_path($_smarty_include_tpl_file); $compile_path = $this->_get_compile_path($_smarty_include_tpl_file);
$this->_parse_file_path($this->template_dir, $_smarty_include_tpl_file, $resource_type, $resource_name);
if ($this->security && $this->_is_trusted($resource_type, $resource_name)) {
$_smarty_trusted = true;
$this->security = false;
} else {
$_smarty_trusted = false;
}
if ($this->_process_template($_smarty_include_tpl_file, $compile_path)) { if ($this->_process_template($_smarty_include_tpl_file, $compile_path)) {
if ($this->show_info_include) { if ($this->show_info_include) {
echo "\n<!-- SMARTY_BEGIN: ".$_smarty_include_tpl_file." -->\n"; echo "\n<!-- SMARTY_BEGIN: ".$_smarty_include_tpl_file." -->\n";
@@ -1037,10 +1041,6 @@ function _is_trusted($resource_type, $resource_name)
} }
} }
if ($_smarty_trusted) {
$this->security = true;
}
array_shift($this->_config); array_shift($this->_config);
$this->_inclusion_depth--; $this->_inclusion_depth--;
@@ -1050,7 +1050,7 @@ function _is_trusted($resource_type, $resource_name)
} }
if ($this->caching) { if ($this->caching) {
$this->_cache_info[] = array('template', $_smarty_include_tpl_file); $this->_cache_info['template'][] = $_smarty_include_tpl_file;
} }
} }
@@ -1065,7 +1065,7 @@ function _is_trusted($resource_type, $resource_name)
} }
if ($this->caching) { if ($this->caching) {
$this->_cache_info[] = array('config', $file); $this->_cache_info['config'][] = $file;
} }
if (!isset($this->_config[0]['files'][$file])) { if (!isset($this->_config[0]['files'][$file])) {
@@ -1111,7 +1111,6 @@ function _is_trusted($resource_type, $resource_name)
\*======================================================================*/ \*======================================================================*/
function _process_cached_inserts($results) function _process_cached_inserts($results)
{ {
preg_match_all('!'.$this->_smarty_md5.'{insert_cache (.*)}'.$this->_smarty_md5.'!Uis', preg_match_all('!'.$this->_smarty_md5.'{insert_cache (.*)}'.$this->_smarty_md5.'!Uis',
$results, $match); $results, $match);
list($cached_inserts, $insert_args) = $match; list($cached_inserts, $insert_args) = $match;
@@ -1127,21 +1126,19 @@ function _is_trusted($resource_type, $resource_name)
unset($args['name']); unset($args['name']);
if (isset($args['script'])) { if (isset($args['script'])) {
$this->_parse_file_path($this->trusted_dir, $this->_dequote($args['script']), $resource_type, $resource_name); if (!$this->_get_php_resource($this->_dequote($args['script']), $resource_type, $php_resource)) {
if ($this->security) {
if( $resource_type != 'file' || !@is_file($resource_name)) {
$this->_syntax_error("insert: $resource_type: $resource_name is not readable"); return false;
}
if (!$this->_is_trusted($resource_type, $resource_name)) {
$this->_syntax_error("insert: $resource_type: $resource_name is not trusted");
return false; return false;
} }
if ($resource_type == 'file') {
include_once($php_resource);
} else {
eval($php_resource);
} }
include_once($resource_name);
unset($args['script']); unset($args['script']);
} }
$function_name = 'insert_' . $name; $function_name = $this->_plugins['insert'][$name][0];
$replace = $function_name($args, $this); $replace = $function_name($args, $this);
$results = str_replace($cached_inserts[$i], $replace, $results); $results = str_replace($cached_inserts[$i], $replace, $results);
@@ -1169,24 +1166,30 @@ function _run_insert_handler($args)
if ($this->caching) { if ($this->caching) {
$arg_string = serialize($args); $arg_string = serialize($args);
$name = $args['name'];
if (!isset($this->_cache_info['insert_tags'][$name])) {
$this->_cache_info['insert_tags'][$name] = array('insert',
$name,
$this->_plugins['insert'][$name][1],
$this->_plugins['insert'][$name][2],
false);
}
return $this->_smarty_md5."{insert_cache $arg_string}".$this->_smarty_md5; return $this->_smarty_md5."{insert_cache $arg_string}".$this->_smarty_md5;
} else { } else {
$function_name = 'insert_'.$args['name'];
if (isset($args['script'])) { if (isset($args['script'])) {
$this->_parse_file_path($this->trusted_dir, $this->_dequote($args['script']), $resource_type, $resource_name); if (!$this->_get_php_resource($this->_dequote($args['script']), $resource_type, $php_resource)) {
if ($this->security) {
if ( $resource_type != 'file' || !@is_file($resource_name) ) {
$this->_syntax_error("insert: $resource_type: $resource_name is not readable");
return false; return false;
} }
if ( !$this->_is_trusted($resource_type, $resource_name) ) {
$this->_syntax_error("insert: $resource_type: $resource_name is not trusted");
return false;
}
}
include_once($resource_name);
}
if ($resource_type == 'file') {
include_once($php_resource);
} else {
eval($php_resource);
}
unset($args['script']);
}
$function_name = $this->_plugins['insert'][$args['name']][0];
$content = $function_name($args, $this); $content = $function_name($args, $this);
if ($this->debugging) { if ($this->debugging) {
$this->_smarty_debug_info[] = array('type' => 'insert', $this->_smarty_debug_info[] = array('type' => 'insert',
@@ -1194,8 +1197,9 @@ function _run_insert_handler($args)
'depth' => $this->_inclusion_depth, 'depth' => $this->_inclusion_depth,
'exec_time' => $this->_get_microtime() - $debug_start_time); 'exec_time' => $this->_get_microtime() - $debug_start_time);
} }
if (!empty($args["assign"])) { if (!empty($args["assign"])) {
$this->assign($args["assign"],$content); $this->assign($args["assign"], $content);
} else { } else {
return $content; return $content;
} }
@@ -1210,7 +1214,9 @@ function _run_insert_handler($args)
function _run_mod_handler() function _run_mod_handler()
{ {
$args = func_get_args(); $args = func_get_args();
list($func_name, $map_array) = array_splice($args, 0, 2); list($modifier_name, $map_array) = array_splice($args, 0, 2);
list($func_name, $tpl_file, $tpl_line) =
$this->_plugins['modifier'][$modifier_name];
$var = $args[0]; $var = $args[0];
if ($map_array && is_array($var)) { if ($map_array && is_array($var)) {
@@ -1409,11 +1415,6 @@ function _run_insert_handler($args)
\*======================================================================*/ \*======================================================================*/
function _write_cache_file($tpl_file, $cache_id, $compile_id, $results) function _write_cache_file($tpl_file, $cache_id, $compile_id, $results)
{ {
// determine if insert tags are present
if (strpos($results,$this->_smarty_md5)) {
$this->_cache_info['insert_tags'] = true;
}
// put timestamp in cache header // put timestamp in cache header
$this->_cache_info['timestamp'] = time(); $this->_cache_info['timestamp'] = time();
@@ -1450,7 +1451,6 @@ function _run_insert_handler($args)
} }
if (!empty($this->cache_handler_func)) { if (!empty($this->cache_handler_func)) {
// use cache_handler function // use cache_handler function
$funcname = $this->cache_handler_func; $funcname = $this->cache_handler_func;
$funcname('read', $this, $results, $tpl_file, $cache_id, $compile_id); $funcname('read', $this, $results, $tpl_file, $cache_id, $compile_id);
@@ -1485,25 +1485,24 @@ function _run_insert_handler($args)
} }
if ($this->compile_check) { if ($this->compile_check) {
foreach ($this->_cache_info as $curr_cache_info) { foreach ($this->_cache_info['template'] as $template_dep) {
switch ($curr_cache_info[0]) { $this->_fetch_template_info($template_dep, $template_source, $template_timestamp, false);
case 'template':
$this->_fetch_template_info($curr_cache_info[1], $template_source, $template_timestamp, false);
if ($cache_timestamp < $template_timestamp) { if ($cache_timestamp < $template_timestamp) {
// template file has changed, regenerate cache // template file has changed, regenerate cache
return false; return false;
} }
break; }
case 'config': if (isset($this->_cache_info['config'])) {
if ($cache_timestamp < filemtime($this->config_dir.'/'.$curr_cache_info[1])) { foreach ($this->_cache_info['config'] as $config_dep) {
if ($cache_timestamp < filemtime($this->config_dir.'/'.$config_dep)) {
// config file file has changed, regenerate cache // config file file has changed, regenerate cache
return false; return false;
} }
break;
} }
} }
} }
$results = $cache_split[1]; $results = $cache_split[1];
return true; return true;
} else { } else {
@@ -1513,6 +1512,181 @@ function _run_insert_handler($args)
} }
/*======================================================================*\
Function: _load_plugins
Purpose: Load requested plugins
\*======================================================================*/
function _load_plugins($plugins)
{
foreach ($plugins as $plugin_info) {
list($type, $name, $tpl_file, $tpl_line) = $plugin_info;
$plugin = &$this->_plugins[$type][$name];
/*
* We do not load plugin more than once for each instance of Smarty.
* The following code checks for that. The plugin can also be
* registered dynamically at runtime, in which case template file
* and line number will be unknown, so we fill them in.
*
* The final element of the info array is a flag that indicates
* whether the dynamically registered plugin function has been
* checked for existence yet or not.
*/
if (isset($plugin)) {
if (!$plugin[3]) {
if (!function_exists($plugin[0])) {
$this->_trigger_plugin_error("$type '$name' is not implemented", $tpl_file, $tpl_line);
} else {
$plugin[1] = $tpl_file;
$plugin[2] = $tpl_line;
$plugin[3] = true;
}
}
continue;
} else if ($type == 'insert') {
/*
* For backwards compatibility, we check for insert functions in
* the symbol table before trying to load them as a plugin.
*/
$plugin_func = 'insert_' . $name;
if (function_exists($plugin_func)) {
$plugin = array($plugin_func, $tpl_file, $tpl_line, true);
continue;
}
}
$plugin_file = $this->plugins_dir .
'/' .
$type .
'.' .
$name .
'.php';
$found = true;
if (!file_exists($plugin_file) || !is_readable($plugin_file)) {
$message = "could not load plugin file $plugin_file\n";
$found = false;
}
/*
* If plugin file is found, it -must- provide the properly named
* plugin function. In case it doesn't, simply output the error and
* do not fall back on any other method.
*/
if ($found) {
include_once $plugin_file;
$plugin_func = 'smarty_' . $type . '_' . $name;
if (!function_exists($plugin_func)) {
$this->_trigger_plugin_error("plugin function $plugin_func() not found in $plugin_file", $tpl_file, $tpl_line);
continue;
}
}
/*
* Plugin specific processing and error checking.
*/
if (!$found) {
if ($type == 'modifier') {
/*
* In case modifier falls back on using PHP functions
* directly, we only allow those specified in the security
* context.
*/
if ($this->security && !in_array($name, $this->security_settings['MODIFIER_FUNCS'])) {
$message = "(secure mode) modifier '$name' is not allowed";
} else {
if (!function_exists($name)) {
$message = "modifier '$name' is not implemented";
} else {
$plugin_func = $name;
$found = true;
}
}
} else if ($type == 'function') {
/*
* This is a catch-all situation.
*/
$message = "unknown tag - '$name'";
}
}
if ($found) {
$this->_plugins[$type][$name] = array($plugin_func, $tpl_file, $tpl_line, true);
} else {
// output error
$this->_trigger_plugin_error($message, $tpl_file, $tpl_line);
}
}
}
/*======================================================================*\
Function: _load_resource_plugin
Purpose:
\*======================================================================*/
function _load_resource_plugin($type)
{
/*
* Resource plugins are not quite like the other ones, so they are
* handled differently. The first element of plugin info is the array of
* functions provided by the plugin, the second one indicates whether
* all of them exist or not.
*/
$plugin = &$this->_plugins['resource'][$type];
if (isset($plugin)) {
if (!$plugin[1] && count($plugin[0])) {
$plugin[1] = true;
foreach ($plugin[0] as $plugin_func) {
if (!function_exists($plugin_func)) {
$plugin[1] = false;
break;
}
}
}
if (!$plugin[1]) {
$this->_trigger_plugin_error("resource '$type' is not implemented");
}
return;
}
$plugin_file = $this->plugins_dir .
'/resource.' .
$type .
'.php';
$found = true;
if (!file_exists($plugin_file) || !is_readable($plugin_file)) {
$this->_trigger_plugin_error("could not load plugin file $plugin_file");
$found = false;
} else {
/*
* If the plugin file is found, it -must- provide the properly named
* plugin functions.
*/
include_once $plugin_file;
/*
* Locate functions that we require the plugin to provide.
*/
$resource_ops = array('source', 'timestamp', 'secure', 'trusted');
$resource_funcs = array();
foreach ($resource_ops as $op) {
$plugin_func = 'smarty_resource_' . $type . '_' . $op;
if (!function_exists($plugin_func)) {
$this->_trigger_plugin_error("plugin function $plugin_func() not found in $plugin_file");
return;
} else {
$resource_funcs[] = $plugin_func;
}
}
$this->_plugins['resource'][$type] = array($resource_funcs, true);
}
}
/*======================================================================*\ /*======================================================================*\
Function: quote_replace Function: quote_replace
Purpose: Quote subpattern references Purpose: Quote subpattern references
@@ -1532,6 +1706,20 @@ function _run_insert_handler($args)
trigger_error("Smarty error: $error_msg", $error_type); trigger_error("Smarty error: $error_msg", $error_type);
} }
/*======================================================================*\
Function: _trigger_plugin_error
Purpose: trigger Smarty plugin error
\*======================================================================*/
function _trigger_plugin_error($error_msg, $tpl_file = null, $tpl_line = null, $error_type = E_USER_WARNING)
{
if (isset($tpl_line) && isset($tpl_file)) {
trigger_error("Smarty plugin error: [in " . $tpl_file . " line " .
$tpl_line . "]: $error_msg", $error_type);
} else {
trigger_error("Smarty plugin error: $error_msg", $error_type);
}
}
/*======================================================================*\ /*======================================================================*\
Function: _get_microtime Function: _get_microtime
Purpose: Get seconds and microseconds Purpose: Get seconds and microseconds

View File

@@ -7,7 +7,7 @@
* Andrei Zmievski <andrei@php.net> * Andrei Zmievski <andrei@php.net>
* *
* Version: 1.5.2 * Version: 1.5.2
* Copyright: 2001 ispi of Lincoln, Inc. * Copyright: 2001,2002 ispi of Lincoln, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -48,6 +48,8 @@ class Smarty_Compiler extends Smarty {
var $_current_file = null; // the current template being compiled var $_current_file = null; // the current template being compiled
var $_current_line_no = 1; // line number for error messages var $_current_line_no = 1; // line number for error messages
var $_capture_stack = array(); // keeps track of nested capture buffers var $_capture_stack = array(); // keeps track of nested capture buffers
var $_plugin_info = array(); // keeps track of plugins to load
var $_filters_loaded = false;
/*======================================================================*\ /*======================================================================*\
@@ -64,13 +66,19 @@ class Smarty_Compiler extends Smarty {
} }
} }
if (!$this->_filters_loaded) {
$this->_load_filters();
$this->_filters_loaded = true;
}
// run template source through prefilter functions // run template source through prefilter functions
if (is_array($this->prefilter_funcs) && count($this->prefilter_funcs) > 0) { if (count($this->_plugins['prefilter']) > 0) {
foreach ($this->prefilter_funcs as $prefilter) { foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
if (function_exists($prefilter)) { if ($prefilter[3] || function_exists($prefilter[0])) {
$template_source = $prefilter($template_source, $this); $template_source = $prefilter[0]($template_source, $this);
$this->_plugins['prefilter'][$filter_name][3] = true;
} else { } else {
$this->_trigger_error_msg("prefilter function $prefilter does not exist."); $this->_trigger_plugin_error("Smarty plugin error: prefilter '$filter_name' is not implemented");
} }
} }
} }
@@ -170,16 +178,30 @@ class Smarty_Compiler extends Smarty {
} }
// run compiled template through postfilter functions // run compiled template through postfilter functions
if (is_array($this->postfilter_funcs) && count($this->postfilter_funcs) > 0) { if (count($this->_plugins['postfilter']) > 0) {
foreach ($this->postfilter_funcs as $postfilter) { foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
if (function_exists($postfilter)) { if ($postfilter[3] || function_exists($postfilter[0])) {
$template_compiled = $postfilter($template_compiled, $this); $template_compiled = $postfilter[0]($template_compiled, $this);
$this->_plugins['postfilter'][$filter_name][3] = true;
} else { } else {
$this->_trigger_error_msg("postfilter function $postfilter does not exist."); $this->_trigger_plugin_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
} }
} }
} }
/* Emit code to load needed plugins. */
if (count($this->_plugin_info)) {
$plugins_code = '<?php $this->_load_plugins(array(';
foreach ($this->_plugin_info as $plugin_type => $plugins) {
foreach ($plugins as $plugin_name => $plugin_info) {
$plugins_code .= "\narray('$plugin_type', '$plugin_name', '$plugin_info[0]', $plugin_info[1]),";
}
}
$plugins_code .= ")); ?>";
$template_compiled = $plugins_code . $template_compiled;
$this->_plugin_info = array();
}
return true; return true;
} }
@@ -300,13 +322,10 @@ class Smarty_Compiler extends Smarty {
return $this->_compile_insert_tag($tag_args); return $this->_compile_insert_tag($tag_args);
default: default:
if (isset($this->compiler_funcs[$tag_command])) { if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
return $this->_compile_compiler_tag($tag_command, $tag_args); return $output;
} else if (isset($this->custom_funcs[$tag_command])) {
return $this->_compile_custom_tag($tag_command, $tag_args);
} else { } else {
$this->_syntax_error("unknown tag - '$tag_command'", E_USER_WARNING); return $this->_compile_custom_tag($tag_command, $tag_args);
return;
} }
} }
} }
@@ -316,16 +335,62 @@ class Smarty_Compiler extends Smarty {
Function: _compile_compiler_tag Function: _compile_compiler_tag
Purpose: compile the custom compiler tag Purpose: compile the custom compiler tag
\*======================================================================*/ \*======================================================================*/
function _compile_compiler_tag($tag_command, $tag_args) function _compile_compiler_tag($tag_command, $tag_args, &$output)
{ {
$function = $this->compiler_funcs[$tag_command]; $found = false;
$have_function = true;
if (!function_exists($function)) { $plugin_file = $this->plugins_dir .
$this->_syntax_error("compiler function '$tag_command' is not implemented", E_USER_WARNING); '/compiler.' .
return; $tag_command .
'.php';
/*
* First we check if the compiler function has already been registered
* or loaded from a plugin file.
*/
if (isset($this->_plugins['compiler'][$tag_command])) {
$found = true;
$plugin_func = $this->_plugins['compiler'][$tag_command][0];
if (!function_exists($plugin_func)) {
$message = "compiler function '$tag_command' is not implemented";
$have_function = false;
}
}
/*
* Otherwise we need to load plugin file and look for the function
* inside it.
*/
else if (file_exists($plugin_file) && is_readable($plugin_file)) {
$found = true;
include_once $plugin_file;
$plugin_func = 'smarty_compiler_' . $tag_command;
if (!function_exists($plugin_func)) {
$message = "plugin function $plugin_func() not found in $plugin_file\n";
$have_function = false;
} else {
$this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null);
}
} }
return '<?php ' . $function($tag_args, $this) . ' ?>'; /*
* True return value means that we either found a plugin or a
* dynamically registered function. False means that we didn't and the
* compiler should now emit code to load custom function plugin for this
* tag.
*/
if ($found) {
if ($have_function) {
$output = '<?php ' . $plugin_func($tag_args, $this) . ' ?>';
} else {
$this->_syntax_error($message, E_USER_WARNING);
}
return true;
} else {
return false;
}
} }
@@ -335,12 +400,10 @@ class Smarty_Compiler extends Smarty {
\*======================================================================*/ \*======================================================================*/
function _compile_custom_tag($tag_command, $tag_args) function _compile_custom_tag($tag_command, $tag_args)
{ {
$function = $this->custom_funcs[$tag_command]; $this->_add_plugin('function',
$tag_command,
if (!function_exists($function)) { $this->_current_file,
$this->_syntax_error("custom function '$tag_command' is not implemented", E_USER_WARNING); $this->_current_line_no);
return;
}
$arg_list = array(); $arg_list = array();
$attrs = $this->_parse_attrs($tag_args); $attrs = $this->_parse_attrs($tag_args);
@@ -350,7 +413,7 @@ class Smarty_Compiler extends Smarty {
$arg_list[] = "'$arg_name' => $arg_value"; $arg_list[] = "'$arg_name' => $arg_value";
} }
return "<?php $function(array(".implode(',', (array)$arg_list)."), \$this); if(\$this->_extract) { extract(\$this->_tpl_vars); \$this->_extract=false; } ?>"; return "<?php \$this->_plugins['function']['$tag_command'][0](array(".implode(',', (array)$arg_list)."), \$this); if(\$this->_extract) { extract(\$this->_tpl_vars); \$this->_extract=false; } ?>";
} }
@@ -361,7 +424,7 @@ class Smarty_Compiler extends Smarty {
function _compile_insert_tag($tag_args) function _compile_insert_tag($tag_args)
{ {
$attrs = $this->_parse_attrs($tag_args); $attrs = $this->_parse_attrs($tag_args);
$name = substr($attrs['name'], 1, -1); $name = $this->_dequote($attrs['name']);
if (empty($name)) { if (empty($name)) {
$this->_syntax_error("missing insert name"); $this->_syntax_error("missing insert name");
@@ -373,6 +436,8 @@ class Smarty_Compiler extends Smarty {
$arg_list[] = "'$arg_name' => $arg_value"; $arg_list[] = "'$arg_name' => $arg_value";
} }
$this->_add_plugin('insert', $name);
return "<?php echo \$this->_run_insert_handler(array(".implode(', ', (array)$arg_list).")); ?>\n"; return "<?php echo \$this->_run_insert_handler(array(".implode(', ', (array)$arg_list).")); ?>\n";
} }
@@ -471,28 +536,25 @@ class Smarty_Compiler extends Smarty {
if (empty($attrs['file'])) { if (empty($attrs['file'])) {
$this->_syntax_error("missing 'file' attribute in include_php tag"); $this->_syntax_error("missing 'file' attribute in include_php tag");
return false;
} }
$this->_parse_file_path($this->trusted_dir, $this->_dequote($attrs['file']), $resource_type, $resource_name); $this->_get_php_resource($this->_dequote($attrs['file']),
$resource_type, $php_resource);
if ($this->security) {
if( $resource_type != 'file' || !@is_file($resource_name)) {
$this->_syntax_error("include_php: $resource_type: $resource_name is not readable");
return false;
}
if (!$this->_is_trusted($resource_type, $resource_name)) {
$this->_syntax_error("include_php: $resource_type: $resource_name is not trusted");
return false;
}
}
if (!empty($attrs['assign'])) { if (!empty($attrs['assign'])) {
$output = "<?php ob_start();\n"; $output = "<?php ob_start();\n";
$output .= 'include("' . $resource_name . '");'."\n"; if ($resource_type == 'file') {
$output .= "\$this->assign(" . $this->_dequote($attrs['assign']).", ob_get_contents()); ob_end_clean();\n?>"; $output .= 'include("' . $php_resource . '");'."\n";
} else { } else {
$output = '<?php include("' . $resource_name . '"); ?>'; $output .= $php_resource;
}
$output .= "\$this->assign(" . $attrs['assign'] . ", ob_get_contents()); ob_end_clean();\n?>";
} else {
if ($resource_type == 'file') {
$output = '<?php include("' . $php_resource . '"); ?>';
} else {
$output = '<?php ' . $php_resource . ' ?>';
}
} }
return $output; return $output;
@@ -1083,32 +1145,11 @@ class Smarty_Compiler extends Smarty {
if ($modifier_name{0} == '@') { if ($modifier_name{0} == '@') {
$map_array = 'false'; $map_array = 'false';
$modifier_name = substr($modifier_name, 1); $modifier_name = substr($modifier_name, 1);
} else
$map_array = 'true';
/*
* First we lookup the modifier function name in the registered
* modifiers table.
*/
@$mod_func_name = $this->custom_mods[$modifier_name];
/*
* If we don't find that modifier there, we assume it's just a PHP
* function name.
*/
if (!isset($mod_func_name)) {
if ($this->security && !in_array($modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
$this->_syntax_error("(secure mode) modifier '$modifier_name' is not allowed", E_USER_WARNING);
continue;
} else { } else {
$mod_func_name = $modifier_name; $map_array = 'true';
}
} }
if (!function_exists($mod_func_name)) { $this->_add_plugin('modifier', $modifier_name);
$this->_syntax_error("modifier '$modifier_name' is not implemented", E_USER_WARNING);
continue;
}
$this->_parse_vars_props($modifier_args); $this->_parse_vars_props($modifier_args);
@@ -1117,7 +1158,23 @@ class Smarty_Compiler extends Smarty {
else else
$modifier_args = ''; $modifier_args = '';
$output = "\$this->_run_mod_handler('$mod_func_name', $map_array, $output$modifier_args)"; $output = "\$this->_run_mod_handler('$modifier_name', $map_array, $output$modifier_args)";
}
}
/*======================================================================*\
Function: _add_plugin
Purpose:
\*======================================================================*/
function _add_plugin($type, $name)
{
if (!isset($this->_plugin_info[$type])) {
$this->_plugin_info[$type] = array();
}
if (!isset($this->_plugin_info[$type][$name])) {
$this->_plugin_info[$type][$name] = array($this->_current_file,
$this->_current_line_no);
} }
} }
@@ -1172,6 +1229,38 @@ class Smarty_Compiler extends Smarty {
return $compiled_ref; return $compiled_ref;
} }
/*======================================================================*\
Function: _load_filters
Purpose: load pre- and post-filters
\*======================================================================*/
function _load_filters()
{
$plugins_dir = $this->plugins_dir;
$handle = opendir($plugins_dir);
while ($entry = readdir($handle)) {
$parts = explode('.', $entry, 3);
if ($entry == '.' ||
$entry == '..' ||
count($parts) < 3 ||
$parts[2] != 'php' ||
($parts[0] != 'prefilter' &&
$parts[0] != 'postfilter') ||
isset($this->_plugins[$parts[0]][$parts[1]]))
continue;
$plugin_file = $plugins_dir . '/' . $entry;
include_once $plugin_file;
$plugin_func = 'smarty_' . $parts[0] . '_' . $parts[1];
if (!function_exists($plugin_func)) {
$this->_trigger_plugin_error("Smarty plugin error: plugin function $plugin_func() not found in $plugin_file");
} else {
$this->_plugins[$parts[0]][$parts[1]] = array($plugin_func, null, null, true);
}
}
closedir($handle);
}
/*======================================================================*\ /*======================================================================*\
Function: _syntax_error Function: _syntax_error
Purpose: display Smarty syntax error Purpose: display Smarty syntax error

View File

@@ -0,0 +1,31 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: assign
* Purpose: assign a value to a template variable
* -------------------------------------------------------------
*/
function smarty_function_assign($args, &$smarty_obj)
{
extract($args);
if (empty($var)) {
$smarty_obj->_trigger_error_msg("assign: missing 'var' parameter");
return;
}
if (!in_array('value', array_keys($args))) {
$smarty_obj->_trigger_error_msg("assign: missing 'value' parameter");
return;
}
$smarty_obj->assign($var, $value);
return true;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,32 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: assign_debug_info
* Purpose: assign debug info to the template
* -------------------------------------------------------------
*/
function smarty_function_assign_debug_info($args, &$smarty_obj)
{
$assigned_vars = $smarty_obj->_tpl_vars;
ksort($assigned_vars);
if (is_array($smarty_obj->_config[0])) {
$config_vars = $smarty_obj->_config[0];
ksort($config_vars);
$smarty_obj->assign("_debug_config_keys", array_keys($config_vars));
$smarty_obj->assign("_debug_config_vals", array_values($config_vars));
}
$included_templates = $smarty_obj->_smarty_debug_info;
$smarty_obj->assign("_debug_keys", array_keys($assigned_vars));
$smarty_obj->assign("_debug_vals", array_values($assigned_vars));
$smarty_obj->assign("_debug_tpls", $included_templates);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,63 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: counter
* Purpose: print out a counter value
* -------------------------------------------------------------
*/
function smarty_function_counter($args, &$smarty_obj)
{
static $count = array();
static $skipval = array();
static $dir = array();
static $id = "default";
static $printval = array();
static $assign = "";
extract($args);
if (!isset($id))
$id = "default";
if (isset($start))
$count[$id] = $start;
else if (!isset($count[$id]))
$count[$id]=1;
if (!isset($print))
$printval[$id]=true;
else
$printval[$id]=$print;
if (!empty($assign)) {
$printval[$id] = false;
$smarty_obj->assign($assign, $count[$id]);
}
if ($printval[$id])
echo $count[$id];
if (isset($skip))
$skipval[$id] = $skip;
else if (empty($skipval[$id]))
$skipval[$id] = 1;
if (isset($direction))
$dir[$id] = $direction;
else if (!isset($dir[$id]))
$dir[$id] = "up";
if ($dir[$id] == "down")
$count[$id] -= $skipval[$id];
else
$count[$id] += $skipval[$id];
return true;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,51 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: fetch
* Purpose: fetch file, web or ftp data and display results
* -------------------------------------------------------------
*/
function smarty_function_fetch($args, &$smarty_obj)
{
extract($args);
if (empty($file)) {
$smarty_obj->_trigger_error_msg("parameter 'file' cannot be empty");
return;
}
if ($smarty_obj->security && !preg_match('!^(http|ftp)://!', $file)) {
// make sure fetched file comes from secure directory
foreach ($smarty_obj->secure_dir as $curr_dir) {
if (substr(realpath($file), 0, strlen(realpath($curr_dir))) == realpath($curr_dir)) {
$resource_is_secure = true;
break;
}
}
if (!$resource_is_secure) {
$smarty_obj->_trigger_error_msg("(secure mode) fetch '$file' is not allowed");
return;
}
if (!@is_readable($file)) {
$smarty_obj->_trigger_error_msg("fetch cannot read file '$file'");
return;
}
}
if (!empty($assign)) {
ob_start();
readfile($file);
$smarty_obj->assign($assign,ob_get_contents());
ob_end_clean();
} else {
readfile($file);
}
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,55 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: html_options
* Purpose: Prints the list of <option> tags generated from
* the passed parameters
* -------------------------------------------------------------
*/
function smarty_function_html_options($params, &$smarty)
{
$print_result = true;
extract($params);
$html_result = '';
settype($selected, 'array');
if (isset($options)) {
settype($options, 'array');
foreach ($options as $key => $value) {
$html_result .= "<option value=\"$key\"";
if (in_array($key, $selected))
$html_result .= " selected=\"selected\"";
$html_result .= ">$value</option>\n";
}
} else {
settype($output, 'array');
settype($values, 'array');
for ($i = 0; $i < count($output); $i++) {
/* By default, check value against $selected */
$sel_check = $values[$i];
$html_result .= "<option";
if ($i < count($values))
$html_result .= " value=\"".$values[$i]."\"";
else
$sel_check = $output[$i]; /* if more outputs than values, then
check output against $selected */
if (in_array($sel_check, $selected))
$html_result .= " selected";
$html_result .= ">".$output[$i]."</option>\n";
}
}
if ($print_result)
print $html_result;
else
return $html_result;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,182 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: html_select_date
* Purpose: Prints the dropdowns for date selection.
* -------------------------------------------------------------
*/
include_once dirname(__FILE__) . '/.make_timestamp.php';
include_once dirname(__FILE__) . '/function.html_options.php';
function smarty_function_html_select_date($params, &$smarty)
{
/* Default values. */
$prefix = "Date_";
$time = time();
$start_year = strftime("%Y");
$end_year = $start_year;
$display_days = true;
$display_months = true;
$display_years = true;
$month_format = "%B";
$day_format = "%02d";
$year_as_text = false;
/* Display years in reverse order? Ie. 2000,1999,.... */
$reverse_years = false;
/* Should the select boxes be part of an array when returned from PHP?
e.g. setting it to "birthday", would create "birthday[Day]",
"birthday[Month]" & "birthday[Year]". Can be combined with prefix */
$field_array = null;
/* <select size>'s of the different <select> tags.
If not set, uses default dropdown. */
$day_size = null;
$month_size = null;
$year_size = null;
/* Unparsed attributes common to *ALL* the <select>/<input> tags.
An example might be in the template: all_extra ='class ="foo"'. */
$all_extra = null;
/* Separate attributes for the tags. */
$day_extra = null;
$month_extra = null;
$year_extra = null;
/* Order in which to display the fields.
"D" -> day, "M" -> month, "Y" -> year. */
$field_order = 'MDY';
/* String printed between the different fields. */
$field_separator = "\n";
extract($params);
$time = smarty_make_timestamp($time);
$field_order = strtoupper($field_order);
$html_result = $month_result = $day_result = $year_result = "";
if ($display_months) {
$month_names = array();
for ($i = 1; $i <= 12; $i++)
$month_names[] = strftime($month_format, mktime(0, 0, 0, $i, 1, 2000));
$month_result .= '<select name=';
if (null !== $field_array){
$month_result .= '"' . $field_array . '[' . $prefix . 'Month]"';
} else {
$month_result .= '"' . $prefix . 'Month"';
}
if (null !== $month_size){
$month_result .= ' size="' . $month_size . '"';
}
if (null !== $month_extra){
$month_result .= ' ' . $month_extra;
}
if (null !== $all_extra){
$month_result .= ' ' . $all_extra;
}
$month_result .= '>'."\n";
$month_result .= smarty_function_html_options(array('output' => $month_names,
'values' => range(1, 12),
'selected' => strftime("%m", $time),
'print_result' => false),
$smarty);
$month_result .= '</select>';
}
if ($display_days) {
$days = range(1, 31);
for ($i = 0; $i < count($days); $i++)
$days[$i] = sprintf($day_format, $days[$i]);
$day_result .= '<select name=';
if (null !== $field_array){
$day_result .= '"' . $field_array . '[' . $prefix . 'Day]"';
} else {
$day_result .= '"' . $prefix . 'Day"';
}
if (null !== $day_size){
$day_result .= ' size="' . $day_size . '"';
}
if (null !== $all_extra){
$day_result .= ' ' . $all_extra;
}
if (null !== $day_extra){
$day_result .= ' ' . $day_extra;
}
$day_result .= '>'."\n";
$day_result .= smarty_function_html_options(array('output' => $days,
'values' => range(1, 31),
'selected' => strftime("%d", $time),
'print_result' => false),
$smarty);
$day_result .= '</select>';
}
if ($display_years) {
if (null !== $field_array){
$year_name = $field_array . '[' . $prefix . 'Year]';
} else {
$year_name = $prefix . 'Year';
}
if ($year_as_text) {
$year_result .= '<input type="text" name="' . $year_name . '" value="'.strftime('%Y', $time).'" size="4" maxlength="4"';
if (null !== $all_extra){
$year_result .= ' ' . $all_extra;
}
if (null !== $year_extra){
$year_result .= ' ' . $year_extra;
}
$year_result .= '>';
} else {
$years = range((int)$start_year, (int)$end_year);
if ($reverse_years) {
rsort($years, SORT_NUMERIC);
}
$year_result .= '<select name="' . $year_name . '"';
if (null !== $year_size){
$year_result .= ' size="' . $year_size . '"';
}
if (null !== $all_extra){
$year_result .= ' ' . $all_extra;
}
if (null !== $year_extra){
$year_result .= ' ' . $year_extra;
}
$year_result .= '>'."\n";
$year_result .= smarty_function_html_options(array('output' => $years,
'values' => $years,
'selected' => strftime("%Y", $time),
'print_result' => false),
$smarty);
$year_result .= '</select>';
}
}
// Loop thru the field_order field
for ($i = 0; $i <= 2; $i++){
$c = substr($field_order, $i, 1);
switch ($c){
case 'D':
$html_result .= $day_result;
break;
case 'M':
$html_result .= $month_result;
break;
case 'Y':
$html_result .= $year_result;
break;
}
// Add the field seperator
$html_result .= $field_separator;
}
print $html_result;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,114 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: html_select_time
* Purpose: Prints the dropdowns for time selection
* -------------------------------------------------------------
*/
include_once dirname(__FILE__) . '/.make_timestamp.php';
include_once dirname(__FILE__) . '/function.html_options.php';
function smarty_function_html_select_time($params, &$smarty)
{
/* Default values. */
$prefix = "Time_";
$time = time();
$display_hours = true;
$display_minutes = true;
$display_seconds = true;
$display_meridian = true;
$use_24_hours = true;
$minute_interval = 1;
$second_interval = 1;
/* Should the select boxes be part of an array when returned from PHP?
e.g. setting it to "birthday", would create "birthday[Hour]",
"birthday[Minute]", "birthday[Seconds]" & "birthday[Meridian]".
Can be combined with prefix. */
$field_array = null;
extract($params);
$time = smarty_make_timestamp($time);
$html_result = '';
if ($display_hours) {
$hours = $use_24_hours ? range(0, 23) : range(1, 12);
$hour_fmt = $use_24_hours ? '%H' : '%I';
for ($i = 0; $i < count($hours); $i++)
$hours[$i] = sprintf('%02d', $hours[$i]);
$html_result .= '<select name=';
if (null !== $field_array) {
$html_result .= '"' . $field_array . '[' . $prefix . 'Hour]">'."\n";
} else {
$html_result .= '"' . $prefix . 'Hour">'."\n";
}
$html_result .= smarty_function_html_options(array('output' => $hours,
'values' => $hours,
'selected' => strftime($hour_fmt, $time),
'print_result' => false),
$smarty);
$html_result .= "</select>\n";
}
if ($display_minutes) {
$all_minutes = range(0, 59);
for ($i = 0; $i < count($all_minutes); $i+= $minute_interval)
$minutes[] = sprintf('%02d', $all_minutes[$i]);
$selected = intval(floor(strftime('%M', $time) / $minute_interval) * $minute_interval);
$html_result .= '<select name=';
if (null !== $field_array) {
$html_result .= '"' . $field_array . '[' . $prefix . 'Minute]">'."\n";
} else {
$html_result .= '"' . $prefix . 'Minute">'."\n";
}
$html_result .= smarty_function_html_options(array('output' => $minutes,
'values' => $minutes,
'selected' => $selected,
'print_result' => false),
$smarty);
$html_result .= "</select>\n";
}
if ($display_seconds) {
$all_seconds = range(0, 59);
for ($i = 0; $i < count($all_seconds); $i+= $second_interval)
$seconds[] = sprintf('%02d', $all_seconds[$i]);
$selected = intval(floor(strftime('%S', $time) / $second_interval) * $second_interval);
$html_result .= '<select name=';
if (null !== $field_array) {
$html_result .= '"' . $field_array . '[' . $prefix . 'Second]">'."\n";
} else {
$html_result .= '"' . $prefix . 'Second">'."\n";
}
$html_result .= smarty_function_html_options(array('output' => $seconds,
'values' => $seconds,
'selected' => $selected,
'print_result' => false),
$smarty);
$html_result .= "</select>\n";
}
if ($display_meridian && !$use_24_hours) {
$html_result .= '<select name=';
if (null !== $field_array) {
$html_result .= '"' . $field_array . '[' . $prefix . 'Meridian]">'."\n";
} else {
$html_result .= '"' . $prefix . 'Meridian">'."\n";
}
$html_result .= smarty_function_html_options(array('output' => array('AM', 'PM'),
'values' => array('am', 'pm'),
'selected' => strtolower(strftime('%p', $time)),
'print_result' => false),
$smarty);
$html_result .= "</select>\n";
}
print $html_result;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,73 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: math
* Purpose: handle math computations in template
* -------------------------------------------------------------
*/
function smarty_function_math($args, &$smarty_obj)
{
// be sure equation parameter is present
if (empty($args["equation"])) {
$smarty_obj->_trigger_error_msg("math: missing equation parameter");
return;
}
$equation = $args["equation"];
// make sure parenthesis are balanced
if (substr_count($equation,"(") != substr_count($equation,")")) {
$smarty_obj->_trigger_error_msg("math: unbalanced parenthesis");
return;
}
// match all vars in equation, make sure all are passed
preg_match_all("![a-zA-Z][a-zA-Z0-9]*!",$equation, $match);
$allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10',
'max','min','pi','pow','rand','round','sin','sqrt','srand','tan');
foreach($match[0] as $curr_var) {
if (!in_array($curr_var,array_keys($args)) && !in_array($curr_var, $allowed_funcs)) {
$smarty_obj->_trigger_error_msg("math: parameter $curr_var not passed as argument");
return;
}
}
foreach($args as $key => $val) {
if ($key != "equation" && $key != "format" && $key != "assign") {
// make sure value is not empty
if (strlen($val)==0) {
$smarty_obj->_trigger_error_msg("math: parameter $key is empty");
return;
}
if (!is_numeric($val)) {
$smarty_obj->_trigger_error_msg("math: parameter $key: is not numeric");
return;
}
$equation = preg_replace("/\b$key\b/",$val, $equation);
}
}
eval("\$smarty_math_result = ".$equation.";");
if (empty($args["format"])) {
if (empty($args["assign"])) {
echo $smarty_math_result;
} else {
$smarty_obj->assign($args["assign"],$smarty_math_result);
}
} else {
if (empty($args["assign"])){
printf($args["format"],$smarty_math_result);
} else {
$smarty_obj->assign($assign,sprintf($args["format"],$smarty_math_result));
}
}
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,76 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: popup
* Purpose: make text pop up in windows via overlib
* -------------------------------------------------------------
*/
function smarty_function_popup($args, &$smarty_obj)
{
extract($args);
if (empty($text) && !isset($inarray) && empty($function)) {
$smarty_obj->_trigger_error_msg("overlib: attribute 'text' or 'inarray' or 'function' required");
return false;
}
if (empty($trigger)) { $trigger = "onMouseOver"; }
echo $trigger.'="return overlib(\''.str_replace("'","\'",$text).'\'';
if ($sticky) { echo ",STICKY"; }
if (!empty($caption)) { echo ",CAPTION,'".str_replace("'","\'",$caption)."'"; }
if (!empty($fgcolor)) { echo ",FGCOLOR,'$fgcolor'"; }
if (!empty($bgcolor)) { echo ",BGCOLOR,'$bgcolor'"; }
if (!empty($textcolor)) { echo ",TEXTCOLOR,'$textcolor'"; }
if (!empty($capcolor)) { echo ",CAPCOLOR,'$capcolor'"; }
if (!empty($closecolor)) { echo ",CLOSECOLOR,'$closecolor'"; }
if (!empty($textfont)) { echo ",TEXTFONT,'$textfont'"; }
if (!empty($captionfont)) { echo ",CAPTIONFONT,'$captionfont'"; }
if (!empty($closefont)) { echo ",CLOSEFONT,'$closefont'"; }
if (!empty($textsize)) { echo ",TEXTSIZE,$textsize"; }
if (!empty($captionsize)) { echo ",CAPTIONSIZE,$captionsize"; }
if (!empty($closesize)) { echo ",CLOSESIZE,$closesize"; }
if (!empty($width)) { echo ",WIDTH,$width"; }
if (!empty($height)) { echo ",HEIGHT,$height"; }
if (!empty($left)) { echo ",LEFT"; }
if (!empty($right)) { echo ",RIGHT"; }
if (!empty($center)) { echo ",CENTER"; }
if (!empty($above)) { echo ",ABOVE"; }
if (!empty($below)) { echo ",BELOW"; }
if (isset($border)) { echo ",BORDER,$border"; }
if (isset($offsetx)) { echo ",OFFSETX,$offsetx"; }
if (isset($offsety)) { echo ",OFFSETY,$offsety"; }
if (!empty($fgbackground)) { echo ",FGBACKGROUND,'$fgbackground'"; }
if (!empty($bgbackground)) { echo ",BGBACKGROUND,'$bgbackground'"; }
if (!empty($closetext)) { echo ",CLOSETEXT,'".str_replace("'","\'",$closetext)."'"; }
if (!empty($noclose)) { echo ",NOCLOSE"; }
if (!empty($status)) { echo ",STATUS,'".str_replace("'","\'",$status)."'"; }
if (!empty($autostatus)) { echo ",AUTOSTATUS"; }
if (!empty($autostatuscap)) { echo ",AUTOSTATUSCAP"; }
if (isset($inarray)) { echo ",INARRAY,'$inarray'"; }
if (isset($caparray)) { echo ",CAPARRAY,'$caparray'"; }
if (!empty($capicon)) { echo ",CAPICON,'$capicon'"; }
if (!empty($snapx)) { echo ",SNAPX,$snapx"; }
if (!empty($snapy)) { echo ",SNAPY,$snapy"; }
if (isset($fixx)) { echo ",FIXX,$fixx"; }
if (isset($fixy)) { echo ",FIXY,$fixy"; }
if (!empty($background)) { echo ",BACKGROUND,'$background'"; }
if (!empty($padx)) { echo ",PADX,$padx"; }
if (!empty($pady)) { echo ",PADY,$pady"; }
if (!empty($fullhtml)) { echo ",FULLHTML"; }
if (!empty($frame)) { echo ",FRAME,'$frame'"; }
if (isset($timeout)) { echo ",TIMEOUT,$timeout"; }
if (!empty($function)) { echo ",FUNCTION,'$function'"; }
if (isset($delay)) { echo ",DELAY,$delay"; }
if (!empty($hauto)) { echo ",HAUTO"; }
if (!empty($vauto)) { echo ",VAUTO"; }
echo ');" onMouseOut="nd();"';
return;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,23 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: popup_init
* Purpose: initialize overlib
* -------------------------------------------------------------
*/
function smarty_function_popup_init($args, &$smarty_obj)
{
// be sure to place overlib.js where Smarty can locate it.
// overlib.js came with the distribution of Smarty.
echo '<DIV ID="overDiv" STYLE="position:absolute; visibility:hidden; z-index:1000;"></DIV>'."\n".'<SCRIPT LANGUAGE=javascript>'."\n".'<!--'."\n";
readfile(SMARTY_DIR."overlib.js",1);
echo '// -->'."\n".'</SCRIPT>'."\n";
return;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,16 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: capitalize
* Purpose: capitalize words in the string
* -------------------------------------------------------------
*/
function smarty_modifier_capitalize($string)
{
return ucwords($string);
}
?>

View File

@@ -0,0 +1,21 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: count_characteres
* Purpose: count the number of characters in a text
* -------------------------------------------------------------
*/
function smarty_modifier_count_characters($string, $include_spaces = false)
{
if ($include_spaces)
return(strlen($string));
return preg_match_all("/[^\s]/",$string, $match);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,19 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: count_paragraphs
* Purpose: count the number of paragraphs in a text
* -------------------------------------------------------------
*/
function smarty_modifier_count_paragraphs($string)
{
// count \r or \n characters
return count(preg_split('/[\r\n]+/', $string));
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,19 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: count_sentences
* Purpose: count the number of sentences in a text
* -------------------------------------------------------------
*/
function smarty_modifier_count_sentences($string)
{
// find periods with a word before but not after.
return preg_match_all('/[^\s]\.(?!\w)/', $string, $match);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,23 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: count_words
* Purpose: count the number of words in a text
* -------------------------------------------------------------
*/
function smarty_modifier_count_words($string)
{
// split text by ' ',\r,\n,\f,\t
$split_array = preg_split('/\s+/',$string);
// count matches that contain alphanumerics
$word_count = preg_grep('/[a-zA-Z0-9]/', $split_array);
return count($word_count);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,18 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: date_format
* Purpose: format datestamps via strftime
* -------------------------------------------------------------
*/
function smarty_modifier_date_format($string, $format="%b %e, %Y")
{
return strftime($format, smarty_make_timestamp($string));
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,37 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: debug_print_var
* Purpose: formats variable contents for display in the console
* -------------------------------------------------------------
*/
function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
{
if (is_array($var)) {
$results = "<b>Array (".count($var).")</b>";
foreach ($var as $curr_key => $curr_val) {
$return = smarty_modifier_debug_print_var($curr_val, $depth+1);
$results .= '<br>\r'.str_repeat('&nbsp;', $depth*2)."<b>$curr_key</b> =&gt; $return";
}
return $results;
} else {
if (empty($var)) {
return '<i>empty</i>';
}
if (strlen($var) > $length ) {
$results = substr($var, 0, $length-3).'...';
} else {
$results = $var;
}
$results = preg_replace("![\r\t\n]!", " ", $results);
$results = htmlspecialchars(htmlspecialchars($results));
return $results;
}
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,21 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: default
* Purpose: designate default value for empty variables
* -------------------------------------------------------------
*/
function smarty_modifier_default($string, $default = '')
{
if (empty($string))
return $default;
else
return $string;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,31 @@
<?php
/*
* Smarty plugin
* ------------------------------------------------------------
* Type: modifier
* Name: escape
* Purpose: Escape the string according to escapement type
* ------------------------------------------------------------
*/
function smarty_modifier_escape($string, $esc_type = 'html')
{
switch ($esc_type) {
case 'html':
return htmlspecialchars($string, ENT_QUOTES);
case 'url':
return urlencode($string);
case 'quotes':
// escape unescaped single quotes
return preg_replace("%(?<!\\\\)'%", "\\'", $string);
default:
return $string;
}
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,16 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: lower
* Purpose: convert string to lowercase
* -------------------------------------------------------------
*/
function smarty_modifier_lower($string)
{
return strtolower($string);
}
?>

View File

@@ -0,0 +1,18 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: regex_replace
* Purpose: regular epxression search/replace
* -------------------------------------------------------------
*/
function smarty_modifier_regex_replace($string, $search, $replace)
{
return preg_replace($search, $replace, $string);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,18 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: replace
* Purpose: simple search/replace
* -------------------------------------------------------------
*/
function smarty_modifier_replace($string, $search, $replace)
{
return str_replace($search, $replace, $string);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,19 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: spacify
* Purpose: add spaces between characters in a string
* -------------------------------------------------------------
*/
function smarty_modifier_spacify($string, $spacify_char = ' ')
{
return implode($spacify_char,
preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY));
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,18 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: string_format
* Purpose: format strings via sprintf
* -------------------------------------------------------------
*/
function smarty_modifier_string_format($string, $format)
{
return sprintf($format, $string);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,21 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: strip_tags
* Purpose: strip html tags from text
* -------------------------------------------------------------
*/
function smarty_modifier_strip_tags($string, $replace_with_space = true)
{
if ($replace_with_space)
return preg_replace('!<[^>]*?>!', ' ', $string);
else
return strip_tags($string);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,33 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: truncate
* Purpose: Truncate a string to a certain length if necessary,
* optionally splitting in the middle of a word, and
* appending the $etc string.
* -------------------------------------------------------------
*/
function smarty_modifier_truncate($string, $length = 80, $etc = '...',
$break_words = false)
{
if ($length == 0)
return '';
if (strlen($string) > $length) {
$length -= strlen($etc);
$fragment = substr($string, 0, $length+1);
if ($break_words)
$fragment = substr($fragment, 0, -1);
else
$fragment = preg_replace('/\s+(\S+)?$/', '', $fragment);
return $fragment.$etc;
} else
return $string;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,16 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: upper
* Purpose: convert string to uppercase
* -------------------------------------------------------------
*/
function smarty_modifier_upper($string)
{
return strtoupper($string);
}
?>

View File

@@ -0,0 +1,31 @@
<?php
/*======================================================================*\
Function: smarty_make_timestamp
Purpose: used by other smarty functions to make a timestamp
from a string.
\*======================================================================*/
function smarty_make_timestamp($string)
{
if(empty($string)) {
$string = "now";
}
$time = strtotime($string);
if (is_numeric($time) && $time != -1)
return $time;
// is mysql timestamp format of YYYYMMDDHHMMSS?
if (is_numeric($string) && strlen($string) == 14) {
$time = mktime(substr($string,8,2),substr($string,10,2),substr($string,12,2),
substr($string,4,2),substr($string,6,2),substr($string,0,4));
return $time;
}
// can't decipher, just return it
return $string;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,31 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: assign
* Purpose: assign a value to a template variable
* -------------------------------------------------------------
*/
function smarty_function_assign($args, &$smarty_obj)
{
extract($args);
if (empty($var)) {
$smarty_obj->_trigger_error_msg("assign: missing 'var' parameter");
return;
}
if (!in_array('value', array_keys($args))) {
$smarty_obj->_trigger_error_msg("assign: missing 'value' parameter");
return;
}
$smarty_obj->assign($var, $value);
return true;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,32 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: assign_debug_info
* Purpose: assign debug info to the template
* -------------------------------------------------------------
*/
function smarty_function_assign_debug_info($args, &$smarty_obj)
{
$assigned_vars = $smarty_obj->_tpl_vars;
ksort($assigned_vars);
if (is_array($smarty_obj->_config[0])) {
$config_vars = $smarty_obj->_config[0];
ksort($config_vars);
$smarty_obj->assign("_debug_config_keys", array_keys($config_vars));
$smarty_obj->assign("_debug_config_vals", array_values($config_vars));
}
$included_templates = $smarty_obj->_smarty_debug_info;
$smarty_obj->assign("_debug_keys", array_keys($assigned_vars));
$smarty_obj->assign("_debug_vals", array_values($assigned_vars));
$smarty_obj->assign("_debug_tpls", $included_templates);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,63 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: counter
* Purpose: print out a counter value
* -------------------------------------------------------------
*/
function smarty_function_counter($args, &$smarty_obj)
{
static $count = array();
static $skipval = array();
static $dir = array();
static $id = "default";
static $printval = array();
static $assign = "";
extract($args);
if (!isset($id))
$id = "default";
if (isset($start))
$count[$id] = $start;
else if (!isset($count[$id]))
$count[$id]=1;
if (!isset($print))
$printval[$id]=true;
else
$printval[$id]=$print;
if (!empty($assign)) {
$printval[$id] = false;
$smarty_obj->assign($assign, $count[$id]);
}
if ($printval[$id])
echo $count[$id];
if (isset($skip))
$skipval[$id] = $skip;
else if (empty($skipval[$id]))
$skipval[$id] = 1;
if (isset($direction))
$dir[$id] = $direction;
else if (!isset($dir[$id]))
$dir[$id] = "up";
if ($dir[$id] == "down")
$count[$id] -= $skipval[$id];
else
$count[$id] += $skipval[$id];
return true;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,51 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: fetch
* Purpose: fetch file, web or ftp data and display results
* -------------------------------------------------------------
*/
function smarty_function_fetch($args, &$smarty_obj)
{
extract($args);
if (empty($file)) {
$smarty_obj->_trigger_error_msg("parameter 'file' cannot be empty");
return;
}
if ($smarty_obj->security && !preg_match('!^(http|ftp)://!', $file)) {
// make sure fetched file comes from secure directory
foreach ($smarty_obj->secure_dir as $curr_dir) {
if (substr(realpath($file), 0, strlen(realpath($curr_dir))) == realpath($curr_dir)) {
$resource_is_secure = true;
break;
}
}
if (!$resource_is_secure) {
$smarty_obj->_trigger_error_msg("(secure mode) fetch '$file' is not allowed");
return;
}
if (!@is_readable($file)) {
$smarty_obj->_trigger_error_msg("fetch cannot read file '$file'");
return;
}
}
if (!empty($assign)) {
ob_start();
readfile($file);
$smarty_obj->assign($assign,ob_get_contents());
ob_end_clean();
} else {
readfile($file);
}
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,55 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: html_options
* Purpose: Prints the list of <option> tags generated from
* the passed parameters
* -------------------------------------------------------------
*/
function smarty_function_html_options($params, &$smarty)
{
$print_result = true;
extract($params);
$html_result = '';
settype($selected, 'array');
if (isset($options)) {
settype($options, 'array');
foreach ($options as $key => $value) {
$html_result .= "<option value=\"$key\"";
if (in_array($key, $selected))
$html_result .= " selected=\"selected\"";
$html_result .= ">$value</option>\n";
}
} else {
settype($output, 'array');
settype($values, 'array');
for ($i = 0; $i < count($output); $i++) {
/* By default, check value against $selected */
$sel_check = $values[$i];
$html_result .= "<option";
if ($i < count($values))
$html_result .= " value=\"".$values[$i]."\"";
else
$sel_check = $output[$i]; /* if more outputs than values, then
check output against $selected */
if (in_array($sel_check, $selected))
$html_result .= " selected";
$html_result .= ">".$output[$i]."</option>\n";
}
}
if ($print_result)
print $html_result;
else
return $html_result;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,182 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: html_select_date
* Purpose: Prints the dropdowns for date selection.
* -------------------------------------------------------------
*/
include_once dirname(__FILE__) . '/.make_timestamp.php';
include_once dirname(__FILE__) . '/function.html_options.php';
function smarty_function_html_select_date($params, &$smarty)
{
/* Default values. */
$prefix = "Date_";
$time = time();
$start_year = strftime("%Y");
$end_year = $start_year;
$display_days = true;
$display_months = true;
$display_years = true;
$month_format = "%B";
$day_format = "%02d";
$year_as_text = false;
/* Display years in reverse order? Ie. 2000,1999,.... */
$reverse_years = false;
/* Should the select boxes be part of an array when returned from PHP?
e.g. setting it to "birthday", would create "birthday[Day]",
"birthday[Month]" & "birthday[Year]". Can be combined with prefix */
$field_array = null;
/* <select size>'s of the different <select> tags.
If not set, uses default dropdown. */
$day_size = null;
$month_size = null;
$year_size = null;
/* Unparsed attributes common to *ALL* the <select>/<input> tags.
An example might be in the template: all_extra ='class ="foo"'. */
$all_extra = null;
/* Separate attributes for the tags. */
$day_extra = null;
$month_extra = null;
$year_extra = null;
/* Order in which to display the fields.
"D" -> day, "M" -> month, "Y" -> year. */
$field_order = 'MDY';
/* String printed between the different fields. */
$field_separator = "\n";
extract($params);
$time = smarty_make_timestamp($time);
$field_order = strtoupper($field_order);
$html_result = $month_result = $day_result = $year_result = "";
if ($display_months) {
$month_names = array();
for ($i = 1; $i <= 12; $i++)
$month_names[] = strftime($month_format, mktime(0, 0, 0, $i, 1, 2000));
$month_result .= '<select name=';
if (null !== $field_array){
$month_result .= '"' . $field_array . '[' . $prefix . 'Month]"';
} else {
$month_result .= '"' . $prefix . 'Month"';
}
if (null !== $month_size){
$month_result .= ' size="' . $month_size . '"';
}
if (null !== $month_extra){
$month_result .= ' ' . $month_extra;
}
if (null !== $all_extra){
$month_result .= ' ' . $all_extra;
}
$month_result .= '>'."\n";
$month_result .= smarty_function_html_options(array('output' => $month_names,
'values' => range(1, 12),
'selected' => strftime("%m", $time),
'print_result' => false),
$smarty);
$month_result .= '</select>';
}
if ($display_days) {
$days = range(1, 31);
for ($i = 0; $i < count($days); $i++)
$days[$i] = sprintf($day_format, $days[$i]);
$day_result .= '<select name=';
if (null !== $field_array){
$day_result .= '"' . $field_array . '[' . $prefix . 'Day]"';
} else {
$day_result .= '"' . $prefix . 'Day"';
}
if (null !== $day_size){
$day_result .= ' size="' . $day_size . '"';
}
if (null !== $all_extra){
$day_result .= ' ' . $all_extra;
}
if (null !== $day_extra){
$day_result .= ' ' . $day_extra;
}
$day_result .= '>'."\n";
$day_result .= smarty_function_html_options(array('output' => $days,
'values' => range(1, 31),
'selected' => strftime("%d", $time),
'print_result' => false),
$smarty);
$day_result .= '</select>';
}
if ($display_years) {
if (null !== $field_array){
$year_name = $field_array . '[' . $prefix . 'Year]';
} else {
$year_name = $prefix . 'Year';
}
if ($year_as_text) {
$year_result .= '<input type="text" name="' . $year_name . '" value="'.strftime('%Y', $time).'" size="4" maxlength="4"';
if (null !== $all_extra){
$year_result .= ' ' . $all_extra;
}
if (null !== $year_extra){
$year_result .= ' ' . $year_extra;
}
$year_result .= '>';
} else {
$years = range((int)$start_year, (int)$end_year);
if ($reverse_years) {
rsort($years, SORT_NUMERIC);
}
$year_result .= '<select name="' . $year_name . '"';
if (null !== $year_size){
$year_result .= ' size="' . $year_size . '"';
}
if (null !== $all_extra){
$year_result .= ' ' . $all_extra;
}
if (null !== $year_extra){
$year_result .= ' ' . $year_extra;
}
$year_result .= '>'."\n";
$year_result .= smarty_function_html_options(array('output' => $years,
'values' => $years,
'selected' => strftime("%Y", $time),
'print_result' => false),
$smarty);
$year_result .= '</select>';
}
}
// Loop thru the field_order field
for ($i = 0; $i <= 2; $i++){
$c = substr($field_order, $i, 1);
switch ($c){
case 'D':
$html_result .= $day_result;
break;
case 'M':
$html_result .= $month_result;
break;
case 'Y':
$html_result .= $year_result;
break;
}
// Add the field seperator
$html_result .= $field_separator;
}
print $html_result;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,114 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: html_select_time
* Purpose: Prints the dropdowns for time selection
* -------------------------------------------------------------
*/
include_once dirname(__FILE__) . '/.make_timestamp.php';
include_once dirname(__FILE__) . '/function.html_options.php';
function smarty_function_html_select_time($params, &$smarty)
{
/* Default values. */
$prefix = "Time_";
$time = time();
$display_hours = true;
$display_minutes = true;
$display_seconds = true;
$display_meridian = true;
$use_24_hours = true;
$minute_interval = 1;
$second_interval = 1;
/* Should the select boxes be part of an array when returned from PHP?
e.g. setting it to "birthday", would create "birthday[Hour]",
"birthday[Minute]", "birthday[Seconds]" & "birthday[Meridian]".
Can be combined with prefix. */
$field_array = null;
extract($params);
$time = smarty_make_timestamp($time);
$html_result = '';
if ($display_hours) {
$hours = $use_24_hours ? range(0, 23) : range(1, 12);
$hour_fmt = $use_24_hours ? '%H' : '%I';
for ($i = 0; $i < count($hours); $i++)
$hours[$i] = sprintf('%02d', $hours[$i]);
$html_result .= '<select name=';
if (null !== $field_array) {
$html_result .= '"' . $field_array . '[' . $prefix . 'Hour]">'."\n";
} else {
$html_result .= '"' . $prefix . 'Hour">'."\n";
}
$html_result .= smarty_function_html_options(array('output' => $hours,
'values' => $hours,
'selected' => strftime($hour_fmt, $time),
'print_result' => false),
$smarty);
$html_result .= "</select>\n";
}
if ($display_minutes) {
$all_minutes = range(0, 59);
for ($i = 0; $i < count($all_minutes); $i+= $minute_interval)
$minutes[] = sprintf('%02d', $all_minutes[$i]);
$selected = intval(floor(strftime('%M', $time) / $minute_interval) * $minute_interval);
$html_result .= '<select name=';
if (null !== $field_array) {
$html_result .= '"' . $field_array . '[' . $prefix . 'Minute]">'."\n";
} else {
$html_result .= '"' . $prefix . 'Minute">'."\n";
}
$html_result .= smarty_function_html_options(array('output' => $minutes,
'values' => $minutes,
'selected' => $selected,
'print_result' => false),
$smarty);
$html_result .= "</select>\n";
}
if ($display_seconds) {
$all_seconds = range(0, 59);
for ($i = 0; $i < count($all_seconds); $i+= $second_interval)
$seconds[] = sprintf('%02d', $all_seconds[$i]);
$selected = intval(floor(strftime('%S', $time) / $second_interval) * $second_interval);
$html_result .= '<select name=';
if (null !== $field_array) {
$html_result .= '"' . $field_array . '[' . $prefix . 'Second]">'."\n";
} else {
$html_result .= '"' . $prefix . 'Second">'."\n";
}
$html_result .= smarty_function_html_options(array('output' => $seconds,
'values' => $seconds,
'selected' => $selected,
'print_result' => false),
$smarty);
$html_result .= "</select>\n";
}
if ($display_meridian && !$use_24_hours) {
$html_result .= '<select name=';
if (null !== $field_array) {
$html_result .= '"' . $field_array . '[' . $prefix . 'Meridian]">'."\n";
} else {
$html_result .= '"' . $prefix . 'Meridian">'."\n";
}
$html_result .= smarty_function_html_options(array('output' => array('AM', 'PM'),
'values' => array('am', 'pm'),
'selected' => strtolower(strftime('%p', $time)),
'print_result' => false),
$smarty);
$html_result .= "</select>\n";
}
print $html_result;
}
/* vim: set expandtab: */
?>

73
plugins/function.math.php Normal file
View File

@@ -0,0 +1,73 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: math
* Purpose: handle math computations in template
* -------------------------------------------------------------
*/
function smarty_function_math($args, &$smarty_obj)
{
// be sure equation parameter is present
if (empty($args["equation"])) {
$smarty_obj->_trigger_error_msg("math: missing equation parameter");
return;
}
$equation = $args["equation"];
// make sure parenthesis are balanced
if (substr_count($equation,"(") != substr_count($equation,")")) {
$smarty_obj->_trigger_error_msg("math: unbalanced parenthesis");
return;
}
// match all vars in equation, make sure all are passed
preg_match_all("![a-zA-Z][a-zA-Z0-9]*!",$equation, $match);
$allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10',
'max','min','pi','pow','rand','round','sin','sqrt','srand','tan');
foreach($match[0] as $curr_var) {
if (!in_array($curr_var,array_keys($args)) && !in_array($curr_var, $allowed_funcs)) {
$smarty_obj->_trigger_error_msg("math: parameter $curr_var not passed as argument");
return;
}
}
foreach($args as $key => $val) {
if ($key != "equation" && $key != "format" && $key != "assign") {
// make sure value is not empty
if (strlen($val)==0) {
$smarty_obj->_trigger_error_msg("math: parameter $key is empty");
return;
}
if (!is_numeric($val)) {
$smarty_obj->_trigger_error_msg("math: parameter $key: is not numeric");
return;
}
$equation = preg_replace("/\b$key\b/",$val, $equation);
}
}
eval("\$smarty_math_result = ".$equation.";");
if (empty($args["format"])) {
if (empty($args["assign"])) {
echo $smarty_math_result;
} else {
$smarty_obj->assign($args["assign"],$smarty_math_result);
}
} else {
if (empty($args["assign"])){
printf($args["format"],$smarty_math_result);
} else {
$smarty_obj->assign($assign,sprintf($args["format"],$smarty_math_result));
}
}
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,76 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: popup
* Purpose: make text pop up in windows via overlib
* -------------------------------------------------------------
*/
function smarty_function_popup($args, &$smarty_obj)
{
extract($args);
if (empty($text) && !isset($inarray) && empty($function)) {
$smarty_obj->_trigger_error_msg("overlib: attribute 'text' or 'inarray' or 'function' required");
return false;
}
if (empty($trigger)) { $trigger = "onMouseOver"; }
echo $trigger.'="return overlib(\''.str_replace("'","\'",$text).'\'';
if ($sticky) { echo ",STICKY"; }
if (!empty($caption)) { echo ",CAPTION,'".str_replace("'","\'",$caption)."'"; }
if (!empty($fgcolor)) { echo ",FGCOLOR,'$fgcolor'"; }
if (!empty($bgcolor)) { echo ",BGCOLOR,'$bgcolor'"; }
if (!empty($textcolor)) { echo ",TEXTCOLOR,'$textcolor'"; }
if (!empty($capcolor)) { echo ",CAPCOLOR,'$capcolor'"; }
if (!empty($closecolor)) { echo ",CLOSECOLOR,'$closecolor'"; }
if (!empty($textfont)) { echo ",TEXTFONT,'$textfont'"; }
if (!empty($captionfont)) { echo ",CAPTIONFONT,'$captionfont'"; }
if (!empty($closefont)) { echo ",CLOSEFONT,'$closefont'"; }
if (!empty($textsize)) { echo ",TEXTSIZE,$textsize"; }
if (!empty($captionsize)) { echo ",CAPTIONSIZE,$captionsize"; }
if (!empty($closesize)) { echo ",CLOSESIZE,$closesize"; }
if (!empty($width)) { echo ",WIDTH,$width"; }
if (!empty($height)) { echo ",HEIGHT,$height"; }
if (!empty($left)) { echo ",LEFT"; }
if (!empty($right)) { echo ",RIGHT"; }
if (!empty($center)) { echo ",CENTER"; }
if (!empty($above)) { echo ",ABOVE"; }
if (!empty($below)) { echo ",BELOW"; }
if (isset($border)) { echo ",BORDER,$border"; }
if (isset($offsetx)) { echo ",OFFSETX,$offsetx"; }
if (isset($offsety)) { echo ",OFFSETY,$offsety"; }
if (!empty($fgbackground)) { echo ",FGBACKGROUND,'$fgbackground'"; }
if (!empty($bgbackground)) { echo ",BGBACKGROUND,'$bgbackground'"; }
if (!empty($closetext)) { echo ",CLOSETEXT,'".str_replace("'","\'",$closetext)."'"; }
if (!empty($noclose)) { echo ",NOCLOSE"; }
if (!empty($status)) { echo ",STATUS,'".str_replace("'","\'",$status)."'"; }
if (!empty($autostatus)) { echo ",AUTOSTATUS"; }
if (!empty($autostatuscap)) { echo ",AUTOSTATUSCAP"; }
if (isset($inarray)) { echo ",INARRAY,'$inarray'"; }
if (isset($caparray)) { echo ",CAPARRAY,'$caparray'"; }
if (!empty($capicon)) { echo ",CAPICON,'$capicon'"; }
if (!empty($snapx)) { echo ",SNAPX,$snapx"; }
if (!empty($snapy)) { echo ",SNAPY,$snapy"; }
if (isset($fixx)) { echo ",FIXX,$fixx"; }
if (isset($fixy)) { echo ",FIXY,$fixy"; }
if (!empty($background)) { echo ",BACKGROUND,'$background'"; }
if (!empty($padx)) { echo ",PADX,$padx"; }
if (!empty($pady)) { echo ",PADY,$pady"; }
if (!empty($fullhtml)) { echo ",FULLHTML"; }
if (!empty($frame)) { echo ",FRAME,'$frame'"; }
if (isset($timeout)) { echo ",TIMEOUT,$timeout"; }
if (!empty($function)) { echo ",FUNCTION,'$function'"; }
if (isset($delay)) { echo ",DELAY,$delay"; }
if (!empty($hauto)) { echo ",HAUTO"; }
if (!empty($vauto)) { echo ",VAUTO"; }
echo ');" onMouseOut="nd();"';
return;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,23 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: popup_init
* Purpose: initialize overlib
* -------------------------------------------------------------
*/
function smarty_function_popup_init($args, &$smarty_obj)
{
// be sure to place overlib.js where Smarty can locate it.
// overlib.js came with the distribution of Smarty.
echo '<DIV ID="overDiv" STYLE="position:absolute; visibility:hidden; z-index:1000;"></DIV>'."\n".'<SCRIPT LANGUAGE=javascript>'."\n".'<!--'."\n";
readfile(SMARTY_DIR."overlib.js",1);
echo '// -->'."\n".'</SCRIPT>'."\n";
return;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,16 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: capitalize
* Purpose: capitalize words in the string
* -------------------------------------------------------------
*/
function smarty_modifier_capitalize($string)
{
return ucwords($string);
}
?>

View File

@@ -0,0 +1,21 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: count_characteres
* Purpose: count the number of characters in a text
* -------------------------------------------------------------
*/
function smarty_modifier_count_characters($string, $include_spaces = false)
{
if ($include_spaces)
return(strlen($string));
return preg_match_all("/[^\s]/",$string, $match);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,19 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: count_paragraphs
* Purpose: count the number of paragraphs in a text
* -------------------------------------------------------------
*/
function smarty_modifier_count_paragraphs($string)
{
// count \r or \n characters
return count(preg_split('/[\r\n]+/', $string));
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,19 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: count_sentences
* Purpose: count the number of sentences in a text
* -------------------------------------------------------------
*/
function smarty_modifier_count_sentences($string)
{
// find periods with a word before but not after.
return preg_match_all('/[^\s]\.(?!\w)/', $string, $match);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,23 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: count_words
* Purpose: count the number of words in a text
* -------------------------------------------------------------
*/
function smarty_modifier_count_words($string)
{
// split text by ' ',\r,\n,\f,\t
$split_array = preg_split('/\s+/',$string);
// count matches that contain alphanumerics
$word_count = preg_grep('/[a-zA-Z0-9]/', $split_array);
return count($word_count);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,18 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: date_format
* Purpose: format datestamps via strftime
* -------------------------------------------------------------
*/
function smarty_modifier_date_format($string, $format="%b %e, %Y")
{
return strftime($format, smarty_make_timestamp($string));
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,37 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: debug_print_var
* Purpose: formats variable contents for display in the console
* -------------------------------------------------------------
*/
function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
{
if (is_array($var)) {
$results = "<b>Array (".count($var).")</b>";
foreach ($var as $curr_key => $curr_val) {
$return = smarty_modifier_debug_print_var($curr_val, $depth+1);
$results .= '<br>\r'.str_repeat('&nbsp;', $depth*2)."<b>$curr_key</b> =&gt; $return";
}
return $results;
} else {
if (empty($var)) {
return '<i>empty</i>';
}
if (strlen($var) > $length ) {
$results = substr($var, 0, $length-3).'...';
} else {
$results = $var;
}
$results = preg_replace("![\r\t\n]!", " ", $results);
$results = htmlspecialchars(htmlspecialchars($results));
return $results;
}
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,21 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: default
* Purpose: designate default value for empty variables
* -------------------------------------------------------------
*/
function smarty_modifier_default($string, $default = '')
{
if (empty($string))
return $default;
else
return $string;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,31 @@
<?php
/*
* Smarty plugin
* ------------------------------------------------------------
* Type: modifier
* Name: escape
* Purpose: Escape the string according to escapement type
* ------------------------------------------------------------
*/
function smarty_modifier_escape($string, $esc_type = 'html')
{
switch ($esc_type) {
case 'html':
return htmlspecialchars($string, ENT_QUOTES);
case 'url':
return urlencode($string);
case 'quotes':
// escape unescaped single quotes
return preg_replace("%(?<!\\\\)'%", "\\'", $string);
default:
return $string;
}
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,16 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: lower
* Purpose: convert string to lowercase
* -------------------------------------------------------------
*/
function smarty_modifier_lower($string)
{
return strtolower($string);
}
?>

View File

@@ -0,0 +1,18 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: regex_replace
* Purpose: regular epxression search/replace
* -------------------------------------------------------------
*/
function smarty_modifier_regex_replace($string, $search, $replace)
{
return preg_replace($search, $replace, $string);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,18 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: replace
* Purpose: simple search/replace
* -------------------------------------------------------------
*/
function smarty_modifier_replace($string, $search, $replace)
{
return str_replace($search, $replace, $string);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,19 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: spacify
* Purpose: add spaces between characters in a string
* -------------------------------------------------------------
*/
function smarty_modifier_spacify($string, $spacify_char = ' ')
{
return implode($spacify_char,
preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY));
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,18 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: string_format
* Purpose: format strings via sprintf
* -------------------------------------------------------------
*/
function smarty_modifier_string_format($string, $format)
{
return sprintf($format, $string);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,21 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: strip_tags
* Purpose: strip html tags from text
* -------------------------------------------------------------
*/
function smarty_modifier_strip_tags($string, $replace_with_space = true)
{
if ($replace_with_space)
return preg_replace('!<[^>]*?>!', ' ', $string);
else
return strip_tags($string);
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,33 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: truncate
* Purpose: Truncate a string to a certain length if necessary,
* optionally splitting in the middle of a word, and
* appending the $etc string.
* -------------------------------------------------------------
*/
function smarty_modifier_truncate($string, $length = 80, $etc = '...',
$break_words = false)
{
if ($length == 0)
return '';
if (strlen($string) > $length) {
$length -= strlen($etc);
$fragment = substr($string, 0, $length+1);
if ($break_words)
$fragment = substr($fragment, 0, -1);
else
$fragment = preg_replace('/\s+(\S+)?$/', '', $fragment);
return $fragment.$etc;
} else
return $string;
}
/* vim: set expandtab: */
?>

View File

@@ -0,0 +1,16 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: upper
* Purpose: convert string to uppercase
* -------------------------------------------------------------
*/
function smarty_modifier_upper($string)
{
return strtoupper($string);
}
?>

View File

@@ -0,0 +1,31 @@
<?php
/*======================================================================*\
Function: smarty_make_timestamp
Purpose: used by other smarty functions to make a timestamp
from a string.
\*======================================================================*/
function smarty_make_timestamp($string)
{
if(empty($string)) {
$string = "now";
}
$time = strtotime($string);
if (is_numeric($time) && $time != -1)
return $time;
// is mysql timestamp format of YYYYMMDDHHMMSS?
if (is_numeric($string) && strlen($string) == 14) {
$time = mktime(substr($string,8,2),substr($string,10,2),substr($string,12,2),
substr($string,4,2),substr($string,6,2),substr($string,0,4));
return $time;
}
// can't decipher, just return it
return $string;
}
/* vim: set expandtab: */
?>

View File

@@ -1,5 +1,5 @@
{config_load file=test.conf section="setup"} {config_load file=test.conf section="setup"}
{include file=header.tpl title=foo} {include file="header.tpl" title=foo}
<PRE> <PRE>