diff --git a/NEWS b/NEWS index 62ca2790..28923b3a 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ + - added plugin functionality and made existing modifiers + and custom functions into plugins. (Andrei) - fixed issue with php executing in literal blocks (Monte) Version 1.3.0 diff --git a/Smarty.class.php b/Smarty.class.php index 1daa5b3a..0cee8fe7 100644 --- a/Smarty.class.php +++ b/Smarty.class.php @@ -37,12 +37,14 @@ * */ -require('Smarty.addons.php'); +define('SMARTY_PHP_PASSTHRU', 0); +define('SMARTY_PHP_QUOTE', 1); +define('SMARTY_PHP_REMOVE', 2); +define('SMARTY_PHP_ALLOW', 3); + +define('SMARTY_PLUGIN_MODIFIER', 0); +define('SMARTY_PLUGIN_FUNCTION', 1); -define("SMARTY_PHP_PASSTHRU",0); -define("SMARTY_PHP_QUOTE",1); -define("SMARTY_PHP_REMOVE",2); -define("SMARTY_PHP_ALLOW",3); class Smarty { @@ -51,6 +53,7 @@ class Smarty var $template_dir = './templates'; // name of directory for templates var $compile_dir = './templates_c'; // name of directory for compiled templates var $config_dir = './configs'; // directory where config files are located + var $plugin_dir = './plugins'; // directory where plugins are located var $global_assign = array('SCRIPT_NAME'); // variables from the GLOBALS array // that are implicitly assigned @@ -84,22 +87,8 @@ class Smarty var $right_delimiter = '}'; - var $custom_funcs = array( 'html_options' => 'smarty_func_html_options', - 'html_select_date' => 'smarty_func_html_select_date' - ); - - 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', - 'strip_tags' => 'smarty_mod_strip_tags', - 'default' => 'smarty_mod_default' - ); + var $custom_funcs = array(); // a table of custom functions + var $custom_mods = array(); // a table of custom modifiers // internal vars var $_error_msg = false; // error messages. true/false @@ -109,6 +98,7 @@ class Smarty var $_current_file = null; // the current template being compiled var $_current_line_no = 1; // line number for error messages var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; // md5 checksum of the string 'Smarty' + var $_plugins_loaded = false; // keeps track of whether plugins are loaded /*======================================================================*\ @@ -333,6 +323,9 @@ class Smarty } } + /* Load Smarty plugins. */ + $this->_load_plugins(); + // compile files $this->_compile($this->template_dir); //assemble compile directory path to file @@ -1251,6 +1244,64 @@ class Smarty } +/*======================================================================*\ + Function: _load_plugins + Purpose: Load Smarty plugins +\*======================================================================*/ + function _load_plugins() + { + if ($this->_plugins_loaded) + return true; + + if (!is_dir($this->plugin_dir)) + return false; + + $dir_handle = opendir($this->plugin_dir); + while ($entry = readdir($dir_handle)) { + $plugin_file = $this->plugin_dir.'/'.$entry; + + if ($entry == '.' || $entry == '..' || + !is_file($plugin_file) || + substr($plugin_file, -11) != '.plugin.php') + continue; + + unset($smarty_plugin_info); + include_once $plugin_file; + + if (!isset($smarty_plugin_info) || !is_array($smarty_plugin_info)) { + trigger_error("Could not load plugin '$plugin_file': missing or incorrect plugin info descriptor", E_USER_WARNING); + continue; + } + + $plugin_table = (array)$smarty_plugin_info['table']; + foreach ($plugin_table as $plugin) { + extract($plugin); + if (empty($name) || empty($impl)) + continue; + + switch ($type) { + case SMARTY_PLUGIN_MODIFIER: + $this->register_modifier($name, $impl); + break; + + case SMARTY_PLUGIN_FUNCTION: + $this->register_function($name, $impl); + break; + + default: + trigger_error("Unknown plugin type $type in $plugin_file", E_USER_WARNING); + break; + } + } + } + closedir($dir_handle); + + $this->_plugins_loaded = true; + + return true; + } + + /*======================================================================*\ Function: _dequote Purpose: Remove starting and ending quotes from the string @@ -1368,6 +1419,45 @@ class Smarty } } + +/*======================================================================*\ + Function: _smarty_insert_handler + Purpose: Handles insert tag calls +\*======================================================================*/ +function _smarty_insert_handler($args, $caching, $delimiter) +{ + if ($caching) { + $arg_string = serialize($args); + return "$delimiter{insert_cache $arg_string}$delimiter"; + } else { + $function_name = 'insert_'.$args['name']; + return $function_name($args); + } +} + + +/*======================================================================*\ + Function: _smarty_mod_handler + Purpose: Handles modifier calls +\*======================================================================*/ +function _smarty_mod_handler() +{ + $args = func_get_args(); + list($func_name, $map_array) = array_splice($args, 0, 2); + $var = $args[0]; + + if ($map_array && is_array($var)) { + foreach ($var as $key => $val) { + $args[0] = $val; + $var[$key] = call_user_func_array($func_name, $args); + } + return $var; + } else { + return call_user_func_array($func_name, $args); + } +} + + /* vim: set expandtab: */ ?> diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 1daa5b3a..0cee8fe7 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -37,12 +37,14 @@ * */ -require('Smarty.addons.php'); +define('SMARTY_PHP_PASSTHRU', 0); +define('SMARTY_PHP_QUOTE', 1); +define('SMARTY_PHP_REMOVE', 2); +define('SMARTY_PHP_ALLOW', 3); + +define('SMARTY_PLUGIN_MODIFIER', 0); +define('SMARTY_PLUGIN_FUNCTION', 1); -define("SMARTY_PHP_PASSTHRU",0); -define("SMARTY_PHP_QUOTE",1); -define("SMARTY_PHP_REMOVE",2); -define("SMARTY_PHP_ALLOW",3); class Smarty { @@ -51,6 +53,7 @@ class Smarty var $template_dir = './templates'; // name of directory for templates var $compile_dir = './templates_c'; // name of directory for compiled templates var $config_dir = './configs'; // directory where config files are located + var $plugin_dir = './plugins'; // directory where plugins are located var $global_assign = array('SCRIPT_NAME'); // variables from the GLOBALS array // that are implicitly assigned @@ -84,22 +87,8 @@ class Smarty var $right_delimiter = '}'; - var $custom_funcs = array( 'html_options' => 'smarty_func_html_options', - 'html_select_date' => 'smarty_func_html_select_date' - ); - - 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', - 'strip_tags' => 'smarty_mod_strip_tags', - 'default' => 'smarty_mod_default' - ); + var $custom_funcs = array(); // a table of custom functions + var $custom_mods = array(); // a table of custom modifiers // internal vars var $_error_msg = false; // error messages. true/false @@ -109,6 +98,7 @@ class Smarty var $_current_file = null; // the current template being compiled var $_current_line_no = 1; // line number for error messages var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; // md5 checksum of the string 'Smarty' + var $_plugins_loaded = false; // keeps track of whether plugins are loaded /*======================================================================*\ @@ -333,6 +323,9 @@ class Smarty } } + /* Load Smarty plugins. */ + $this->_load_plugins(); + // compile files $this->_compile($this->template_dir); //assemble compile directory path to file @@ -1251,6 +1244,64 @@ class Smarty } +/*======================================================================*\ + Function: _load_plugins + Purpose: Load Smarty plugins +\*======================================================================*/ + function _load_plugins() + { + if ($this->_plugins_loaded) + return true; + + if (!is_dir($this->plugin_dir)) + return false; + + $dir_handle = opendir($this->plugin_dir); + while ($entry = readdir($dir_handle)) { + $plugin_file = $this->plugin_dir.'/'.$entry; + + if ($entry == '.' || $entry == '..' || + !is_file($plugin_file) || + substr($plugin_file, -11) != '.plugin.php') + continue; + + unset($smarty_plugin_info); + include_once $plugin_file; + + if (!isset($smarty_plugin_info) || !is_array($smarty_plugin_info)) { + trigger_error("Could not load plugin '$plugin_file': missing or incorrect plugin info descriptor", E_USER_WARNING); + continue; + } + + $plugin_table = (array)$smarty_plugin_info['table']; + foreach ($plugin_table as $plugin) { + extract($plugin); + if (empty($name) || empty($impl)) + continue; + + switch ($type) { + case SMARTY_PLUGIN_MODIFIER: + $this->register_modifier($name, $impl); + break; + + case SMARTY_PLUGIN_FUNCTION: + $this->register_function($name, $impl); + break; + + default: + trigger_error("Unknown plugin type $type in $plugin_file", E_USER_WARNING); + break; + } + } + } + closedir($dir_handle); + + $this->_plugins_loaded = true; + + return true; + } + + /*======================================================================*\ Function: _dequote Purpose: Remove starting and ending quotes from the string @@ -1368,6 +1419,45 @@ class Smarty } } + +/*======================================================================*\ + Function: _smarty_insert_handler + Purpose: Handles insert tag calls +\*======================================================================*/ +function _smarty_insert_handler($args, $caching, $delimiter) +{ + if ($caching) { + $arg_string = serialize($args); + return "$delimiter{insert_cache $arg_string}$delimiter"; + } else { + $function_name = 'insert_'.$args['name']; + return $function_name($args); + } +} + + +/*======================================================================*\ + Function: _smarty_mod_handler + Purpose: Handles modifier calls +\*======================================================================*/ +function _smarty_mod_handler() +{ + $args = func_get_args(); + list($func_name, $map_array) = array_splice($args, 0, 2); + $var = $args[0]; + + if ($map_array && is_array($var)) { + foreach ($var as $key => $val) { + $args[0] = $val; + $var[$key] = call_user_func_array($func_name, $args); + } + return $var; + } else { + return call_user_func_array($func_name, $args); + } +} + + /* vim: set expandtab: */ ?> diff --git a/Smarty.addons.php b/libs/plugins/standard.plugin.php similarity index 60% rename from Smarty.addons.php rename to libs/plugins/standard.plugin.php index e5ef6ecd..650d0532 100644 --- a/Smarty.addons.php +++ b/libs/plugins/standard.plugin.php @@ -1,78 +1,49 @@ - * Andrei Zmievski - * Version: 1.3.0 - * 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@ispi.net - * - * Or, write to: - * Monte Ohrt - * CTO, ispi - * 237 S. 70th suite 220 - * Lincoln, NE 68510 - * - * The latest version of Smarty can be obtained from: - * http://www.phpinsider.com - * - */ + +$smarty_plugin_info['name'] = 'standard'; -/*============================================*\ - Inserts handler -\*============================================*/ - -function _smarty_insert_handler($args, $caching, $delimiter) -{ - if ($caching) { - $arg_string = serialize($args); - return "$delimiter{insert_cache $arg_string}$delimiter"; - } else { - $function_name = 'insert_'.$args['name']; - return $function_name($args); - } -} +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'lower', + 'impl' => 'strtolower'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'upper', + 'impl' => 'strtoupper'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'capitalize', + 'impl' => 'ucwords'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'escape', + 'impl' => 'smarty_mod_escape'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'truncate', + 'impl' => 'smarty_mod_truncate'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'spacify', + 'impl' => 'smarty_mod_spacify'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'date_format', + 'impl' => 'smarty_mod_date_format'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'string_format', + 'impl' => 'smarty_mod_string_format'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'replace', + 'impl' => 'smarty_mod_replace'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'strip_tags', + 'impl' => 'smarty_mod_strip_tags'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'default', + 'impl' => 'smarty_mod_default'); -/*============================================*\ - Modifiers -\*============================================*/ - -function _smarty_mod_handler() -{ - $args = func_get_args(); - list($func_name, $map_array) = array_splice($args, 0, 2); - $var = $args[0]; - - if ($map_array && is_array($var)) { - foreach ($var as $key => $val) { - $args[0] = $val; - $var[$key] = call_user_func_array($func_name, $args); - } - return $var; - } else { - return call_user_func_array($func_name, $args); - } -} +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_FUNCTION, + 'name' => 'html_options', + 'impl' => 'smarty_func_html_options'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_FUNCTION, + 'name' => 'html_select_date', + 'impl' => 'smarty_func_html_select_date'); /*======================================================================*\ @@ -118,28 +89,51 @@ function smarty_mod_truncate($string, $length = 80, $etc = '...', $break_words = } +/*======================================================================*\ + Function: smarty_mod_spacify + Purpose: Insert a character (space by default) between every + character in the 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: Output formatted date +\*======================================================================*/ function smarty_mod_date_format($string, $format="%b %e, %Y") { return strftime($format, $string); } +/*======================================================================*\ + Function: smarty_mod_string_format + Purpose: Output formatted string +\*======================================================================*/ function smarty_mod_string_format($string, $format) { return sprintf($format, $string); } + +/*======================================================================*\ + Function: smarty_mod_replace + Purpose: Perform simple search and replace +\*======================================================================*/ function smarty_mod_replace($string, $search, $replace) { return str_replace($search, $replace, $string); } + +/*======================================================================*\ + Function: smarty_mod_strip_tags + Purpose: Strip HTML tags +\*======================================================================*/ function smarty_mod_strip_tags($string, $replace_with_space = true) { if ($replace_with_space) @@ -148,7 +142,12 @@ function smarty_mod_strip_tags($string, $replace_with_space = true) return strip_tags($string); } -function smarty_mod_default($string, $default="") + +/*======================================================================*\ + Function: smarty_mod_default + Purpose: Output default value if string is empty +\*======================================================================*/ +function smarty_mod_default($string, $default='') { if(empty($string)) return $default; @@ -156,9 +155,6 @@ function smarty_mod_default($string, $default="") return $string; } -/*============================================*\ - Custom tag functions -\*============================================*/ /*======================================================================*\ Function: smarty_func_html_options diff --git a/plugins/standard.plugin.php b/plugins/standard.plugin.php new file mode 100644 index 00000000..650d0532 --- /dev/null +++ b/plugins/standard.plugin.php @@ -0,0 +1,274 @@ + SMARTY_PLUGIN_MODIFIER, + 'name' => 'lower', + 'impl' => 'strtolower'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'upper', + 'impl' => 'strtoupper'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'capitalize', + 'impl' => 'ucwords'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'escape', + 'impl' => 'smarty_mod_escape'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'truncate', + 'impl' => 'smarty_mod_truncate'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'spacify', + 'impl' => 'smarty_mod_spacify'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'date_format', + 'impl' => 'smarty_mod_date_format'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'string_format', + 'impl' => 'smarty_mod_string_format'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'replace', + 'impl' => 'smarty_mod_replace'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'strip_tags', + 'impl' => 'smarty_mod_strip_tags'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_MODIFIER, + 'name' => 'default', + 'impl' => 'smarty_mod_default'); + + +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_FUNCTION, + 'name' => 'html_options', + 'impl' => 'smarty_func_html_options'); +$smarty_plugin_info['table'][] = array('type' => SMARTY_PLUGIN_FUNCTION, + 'name' => 'html_select_date', + 'impl' => 'smarty_func_html_select_date'); + + +/*======================================================================*\ + 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); + + case 'url': + return urlencode($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: Insert a character (space by default) between every + character in the 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: Output formatted date +\*======================================================================*/ +function smarty_mod_date_format($string, $format="%b %e, %Y") +{ + return strftime($format, $string); +} + + +/*======================================================================*\ + Function: smarty_mod_string_format + Purpose: Output formatted string +\*======================================================================*/ +function smarty_mod_string_format($string, $format) +{ + return sprintf($format, $string); +} + + +/*======================================================================*\ + Function: smarty_mod_replace + Purpose: Perform simple search and replace +\*======================================================================*/ +function smarty_mod_replace($string, $search, $replace) +{ + return str_replace($search, $replace, $string); +} + + +/*======================================================================*\ + Function: smarty_mod_strip_tags + Purpose: Strip HTML tags +\*======================================================================*/ +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: Output default value if string is empty +\*======================================================================*/ +function smarty_mod_default($string, $default='') +{ + if(empty($string)) + return $default; + else + return $string; +} + + +/*======================================================================*\ + Function: smarty_func_html_options + Purpose: Prints the list of