2001-03-02 21:38:42 +00:00
< ? php
2003-01-29 22:51:20 +00:00
/**
2001-03-07 04:52:27 +00:00
* Project : Smarty : the PHP compiling template engine
* File : Smarty_Compiler . class . php
*
* 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
*
2003-04-14 08:51:25 +00:00
* @ link http :// smarty . php . net /
2003-02-16 05:09:19 +00:00
* @ author Monte Ohrt < monte @ ispi . net >
* @ author Andrei Zmievski < andrei @ php . net >
2004-02-23 23:14:40 +00:00
* @ version 2.6 . 3 - dev
2004-02-17 15:52:02 +00:00
* @ copyright 2001 - 2004 ispi of Lincoln , Inc .
2003-02-16 05:09:19 +00:00
* @ package Smarty
2001-03-07 04:52:27 +00:00
*/
2003-04-01 15:23:16 +00:00
/* $Id$ */
2003-07-02 10:56:27 +00:00
2003-04-20 21:12:13 +00:00
/**
* Template compiling class
* @ package Smarty
*/
2001-03-02 21:38:42 +00:00
class Smarty_Compiler extends Smarty {
// internal vars
2003-02-16 05:09:19 +00:00
/** #@+
* @ access private
*/
2004-01-08 12:46:27 +00:00
var $_folded_blocks = array (); // keeps folded template blocks
2001-03-02 21:38:42 +00:00
var $_current_file = null ; // the current template being compiled
var $_current_line_no = 1 ; // line number for error messages
2001-07-24 18:39:03 +00:00
var $_capture_stack = array (); // keeps track of nested capture buffers
2002-01-31 20:49:40 +00:00
var $_plugin_info = array (); // keeps track of plugins to load
2002-02-15 20:50:44 +00:00
var $_init_smarty_vars = false ;
2003-10-25 19:43:14 +00:00
var $_permitted_tokens = array ( 'true' , 'false' , 'yes' , 'no' , 'on' , 'off' , 'null' );
var $_db_qstr_regexp = null ; // regexps are setup in the constructor
var $_si_qstr_regexp = null ;
var $_qstr_regexp = null ;
var $_func_regexp = null ;
var $_var_bracket_regexp = null ;
var $_dvar_guts_regexp = null ;
var $_dvar_regexp = null ;
var $_cvar_regexp = null ;
var $_svar_regexp = null ;
var $_avar_regexp = null ;
var $_mod_regexp = null ;
var $_var_regexp = null ;
var $_parenth_param_regexp = null ;
var $_func_call_regexp = null ;
var $_obj_ext_regexp = null ;
var $_obj_start_regexp = null ;
var $_obj_params_regexp = null ;
var $_obj_call_regexp = null ;
2003-06-30 00:07:27 +00:00
var $_cacheable_state = 0 ;
2003-08-06 11:35:59 +00:00
var $_cache_attrs_count = 0 ;
2003-06-18 23:01:42 +00:00
var $_nocache_count = 0 ;
var $_cache_serial = null ;
var $_cache_include = null ;
2003-09-01 15:54:05 +00:00
var $_strip_depth = 0 ;
2003-10-25 19:43:14 +00:00
var $_additional_newline = " \n " ;
2003-09-01 15:54:05 +00:00
2003-02-16 05:09:19 +00:00
/**#@-*/
2003-10-11 08:55:53 +00:00
/**
* The class constructor .
*/
2002-12-18 16:51:48 +00:00
function Smarty_Compiler ()
{
2003-10-11 08:55:53 +00:00
// matches double quoted strings:
// "foobar"
// "foo\"bar"
$this -> _db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"' ;
// matches single quoted strings:
// 'foobar'
// 'foo\'bar'
$this -> _si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'' ;
// matches single or double quoted strings
$this -> _qstr_regexp = '(?:' . $this -> _db_qstr_regexp . '|' . $this -> _si_qstr_regexp . ')' ;
// matches bracket portion of vars
// [0]
// [foo]
// [$bar]
$this -> _var_bracket_regexp = '\[\$?[\w\.]+\]' ;
2004-04-16 08:50:27 +00:00
// matches numerical constants
// 30
// -12
// 13.22
$this -> _num_const_regexp = '\-?\d+(?:\.\d+)?' ;
2003-10-11 08:55:53 +00:00
// matches $ vars (not objects):
// $foo
// $foo.bar
// $foo.bar.foobar
// $foo[0]
// $foo[$bar]
// $foo[5][blah]
// $foo[5].bar[$foobar][4]
$this -> _dvar_math_regexp = '[\+\-\*\/\%]' ;
2003-10-11 09:32:24 +00:00
$this -> _dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]' ;
2003-10-11 08:55:53 +00:00
$this -> _dvar_guts_regexp = '\w+(?:' . $this -> _var_bracket_regexp
2004-04-16 08:50:27 +00:00
. ')*(?:\.\$?\w+(?:' . $this -> _var_bracket_regexp . ')*)*(?:' . $this -> _dvar_math_regexp . '(?:' . $this -> _num_const_regexp . '|' . $this -> _dvar_math_var_regexp . ')*)?' ;
2003-10-11 08:55:53 +00:00
$this -> _dvar_regexp = '\$' . $this -> _dvar_guts_regexp ;
// matches config vars:
// #foo#
// #foobar123_foo#
$this -> _cvar_regexp = '\#\w+\#' ;
// matches section vars:
// %foo.bar%
$this -> _svar_regexp = '\%\w+\.\w+\%' ;
// matches all valid variables (no quotes, no modifiers)
$this -> _avar_regexp = '(?:' . $this -> _dvar_regexp . '|'
. $this -> _cvar_regexp . '|' . $this -> _svar_regexp . ')' ;
// matches valid variable syntax:
// $foo
// $foo
// #foo#
// #foo#
// "text"
// "text"
2004-04-16 08:34:39 +00:00
$this -> _var_regexp = '(?:' . $this -> _avar_regexp . '|' . $this -> _num_const_regexp . '|' . $this -> _qstr_regexp . ')' ;
2003-10-11 08:55:53 +00:00
// matches valid object call (no objects allowed in parameters):
// $foo->bar
// $foo->bar()
// $foo->bar("text")
// $foo->bar($foo, $bar, "text")
// $foo->bar($foo, "foo")
// $foo->bar->foo()
// $foo->bar->foo->bar()
$this -> _obj_ext_regexp = '\->(?:\$?' . $this -> _dvar_guts_regexp . ')' ;
$this -> _obj_params_regexp = '\((?:\w+|'
. $this -> _var_regexp . '(?:\s*,\s*(?:(?:\w+|'
. $this -> _var_regexp . ')))*)?\)' ;
$this -> _obj_start_regexp = '(?:' . $this -> _dvar_regexp . '(?:' . $this -> _obj_ext_regexp . ')+)' ;
$this -> _obj_call_regexp = '(?:' . $this -> _obj_start_regexp . '(?:' . $this -> _obj_params_regexp . ')?)' ;
// matches valid modifier syntax:
// |foo
// |@foo
// |foo:"bar"
// |foo:$bar
// |foo:"bar":$foobar
// |foo|bar
// |foo:$foo->bar
$this -> _mod_regexp = '(?:\|@?\w+(?::(?>-?\w+|'
. $this -> _obj_call_regexp . '|' . $this -> _avar_regexp . '|' . $this -> _qstr_regexp . '))*)' ;
// matches valid function name:
// foo123
// _foo_bar
$this -> _func_regexp = '[a-zA-Z_]\w*' ;
// matches valid registered object:
// foo->bar
$this -> _reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*' ;
// matches valid parameter values:
// true
// $foo
// $foo|bar
// #foo#
// #foo#|bar
// "text"
// "text"|bar
// $foo->bar
$this -> _param_regexp = '(?:\s*(?:' . $this -> _obj_call_regexp . '|'
. $this -> _var_regexp . '|\w+)(?>' . $this -> _mod_regexp . '*)\s*)' ;
// matches valid parenthesised function parameters:
//
// "text"
// $foo, $bar, "text"
// $foo|bar, "foo"|bar, $foo->bar($foo)|bar
$this -> _parenth_param_regexp = '(?:\((?:\w+|'
. $this -> _param_regexp . '(?:\s*,\s*(?:(?:\w+|'
. $this -> _param_regexp . ')))*)?\))' ;
// matches valid function call:
// foo()
// foo_bar($foo)
// _foo_bar($foo,"bar")
// foo123($foo,$foo->bar(),"foo")
$this -> _func_call_regexp = '(?:' . $this -> _func_regexp . '\s*(?:'
. $this -> _parenth_param_regexp . '))' ;
}
/**
* compile a resource
*
2003-06-20 20:13:42 +00:00
* sets $compiled_content to the compiled source
2003-10-11 08:55:53 +00:00
* @ param string $resource_name
* @ param string $source_content
* @ param string $compiled_content
2003-04-20 21:12:13 +00:00
* @ return true
2003-10-11 08:55:53 +00:00
*/
2003-06-20 20:13:42 +00:00
function _compile_file ( $resource_name , $source_content , & $compiled_content )
2001-03-02 23:13:01 +00:00
{
2003-10-11 08:55:53 +00:00
2001-06-19 15:30:29 +00:00
if ( $this -> security ) {
2001-06-15 14:52:48 +00:00
// do not allow php syntax to be executed unless specified
if ( $this -> php_handling == SMARTY_PHP_ALLOW &&
! $this -> security_settings [ 'PHP_HANDLING' ]) {
$this -> php_handling = SMARTY_PHP_PASSTHRU ;
}
}
2001-10-26 14:15:30 +00:00
2002-04-16 20:04:06 +00:00
$this -> _load_filters ();
2002-01-31 20:49:40 +00:00
2003-06-20 20:13:42 +00:00
$this -> _current_file = $resource_name ;
2002-03-21 16:24:43 +00:00
$this -> _current_line_no = 1 ;
$ldq = preg_quote ( $this -> left_delimiter , '!' );
$rdq = preg_quote ( $this -> right_delimiter , '!' );
2001-09-28 21:39:57 +00:00
// run template source through prefilter functions
2002-01-31 20:49:40 +00:00
if ( count ( $this -> _plugins [ 'prefilter' ]) > 0 ) {
foreach ( $this -> _plugins [ 'prefilter' ] as $filter_name => $prefilter ) {
2002-04-05 17:16:52 +00:00
if ( $prefilter === false ) continue ;
2003-09-12 13:40:53 +00:00
if ( $prefilter [ 3 ] || is_callable ( $prefilter [ 0 ])) {
2003-06-20 20:13:42 +00:00
$source_content = call_user_func_array ( $prefilter [ 0 ],
array ( $source_content , & $this ));
2002-01-31 20:49:40 +00:00
$this -> _plugins [ 'prefilter' ][ $filter_name ][ 3 ] = true ;
2001-04-19 21:08:17 +00:00
} else {
2003-01-25 20:31:45 +00:00
$this -> _trigger_fatal_error ( " [plugin] prefilter ' $filter_name ' is not implemented " );
2001-04-19 21:08:17 +00:00
}
2001-04-24 16:43:05 +00:00
}
2001-04-19 21:08:17 +00:00
}
2003-10-11 08:55:53 +00:00
2004-01-08 12:46:27 +00:00
/* fetch all special blocks */
$search = " ! { $ldq } \ *(.*?) \ * { $rdq } | { $ldq } \ s*literal \ s* { $rdq } (.*?) { $ldq } \ s*/literal \ s* { $rdq } | { $ldq } \ s*php \ s* { $rdq } (.*?) { $ldq } \ s*/php \ s* { $rdq } !s " ;
2001-10-26 14:15:30 +00:00
2004-01-08 12:46:27 +00:00
preg_match_all ( $search , $source_content , $match , PREG_SET_ORDER );
$this -> _folded_blocks = $match ;
reset ( $this -> _folded_blocks );
2001-04-26 17:27:40 +00:00
2004-01-08 12:46:27 +00:00
/* replace special blocks by "{php}" */
$source_content = preg_replace ( $search . 'e' , " ' "
. $this -> _quote_replace ( $this -> left_delimiter ) . 'php'
. " ' . str_repeat( \" \n \" , substr_count(' \\ 0', \" \n \" )) .' "
. $this -> _quote_replace ( $this -> right_delimiter )
. " ' "
, $source_content );
2003-10-11 08:55:53 +00:00
2001-03-02 23:13:01 +00:00
/* Gather all template tags. */
2003-06-20 20:13:42 +00:00
preg_match_all ( " ! { $ldq } \ s*(.*?) \ s* { $rdq } !s " , $source_content , $_match );
2003-04-17 15:20:19 +00:00
$template_tags = $_match [ 1 ];
2001-03-02 23:13:01 +00:00
/* Split content by template tags to obtain non-template content. */
2003-06-20 20:13:42 +00:00
$text_blocks = preg_split ( " ! { $ldq } .*? { $rdq } !s " , $source_content );
2003-10-11 08:55:53 +00:00
2001-03-02 23:13:01 +00:00
/* loop through text blocks */
2002-06-03 16:05:33 +00:00
for ( $curr_tb = 0 , $for_max = count ( $text_blocks ); $curr_tb < $for_max ; $curr_tb ++ ) {
2003-01-30 16:09:53 +00:00
/* match anything resembling php tags */
if ( preg_match_all ( '!(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?php[\"\']?)!is' , $text_blocks [ $curr_tb ], $sp_match )) {
2003-10-11 08:55:53 +00:00
/* replace tags with placeholders to prevent recursive replacements */
$sp_match [ 1 ] = array_unique ( $sp_match [ 1 ]);
usort ( $sp_match [ 1 ], '_smarty_sort_length' );
2003-01-30 16:09:53 +00:00
for ( $curr_sp = 0 , $for_max2 = count ( $sp_match [ 1 ]); $curr_sp < $for_max2 ; $curr_sp ++ ) {
2003-10-11 08:55:53 +00:00
$text_blocks [ $curr_tb ] = str_replace ( $sp_match [ 1 ][ $curr_sp ], '%%%SMARTYSP' . $curr_sp . '%%%' , $text_blocks [ $curr_tb ]);
}
2003-01-30 16:09:53 +00:00
/* process each one */
2003-10-23 21:04:12 +00:00
for ( $curr_sp = 0 , $for_max2 = count ( $sp_match [ 1 ]); $curr_sp < $for_max2 ; $curr_sp ++ ) {
2003-01-30 16:09:53 +00:00
if ( $this -> php_handling == SMARTY_PHP_PASSTHRU ) {
/* echo php contents */
$text_blocks [ $curr_tb ] = str_replace ( '%%%SMARTYSP' . $curr_sp . '%%%' , '<?php echo \'' . str_replace ( " ' " , " \ ' " , $sp_match [ 1 ][ $curr_sp ]) . '\'; ?>' . " \n " , $text_blocks [ $curr_tb ]);
} else if ( $this -> php_handling == SMARTY_PHP_QUOTE ) {
/* quote php tags */
$text_blocks [ $curr_tb ] = str_replace ( '%%%SMARTYSP' . $curr_sp . '%%%' , htmlspecialchars ( $sp_match [ 1 ][ $curr_sp ]), $text_blocks [ $curr_tb ]);
} else if ( $this -> php_handling == SMARTY_PHP_REMOVE ) {
/* remove php tags */
$text_blocks [ $curr_tb ] = str_replace ( '%%%SMARTYSP' . $curr_sp . '%%%' , '' , $text_blocks [ $curr_tb ]);
} else {
2003-10-11 08:55:53 +00:00
/* SMARTY_PHP_ALLOW, but echo non php starting tags */
$sp_match [ 1 ][ $curr_sp ] = preg_replace ( '%(<\?(?!php|=|$))%i' , '<?php echo \'\\1\'?>' . " \n " , $sp_match [ 1 ][ $curr_sp ]);
$text_blocks [ $curr_tb ] = str_replace ( '%%%SMARTYSP' . $curr_sp . '%%%' , $sp_match [ 1 ][ $curr_sp ], $text_blocks [ $curr_tb ]);
}
2001-03-02 23:13:01 +00:00
}
2001-03-02 21:38:42 +00:00
}
}
2001-03-02 23:13:01 +00:00
/* Compile the template tags into PHP code. */
$compiled_tags = array ();
2002-06-03 16:05:33 +00:00
for ( $i = 0 , $for_max = count ( $template_tags ); $i < $for_max ; $i ++ ) {
2001-03-02 23:13:01 +00:00
$this -> _current_line_no += substr_count ( $text_blocks [ $i ], " \n " );
$compiled_tags [] = $this -> _compile_tag ( $template_tags [ $i ]);
$this -> _current_line_no += substr_count ( $template_tags [ $i ], " \n " );
}
2003-12-08 10:44:21 +00:00
if ( count ( $this -> _tag_stack ) > 0 ) {
list ( $_open_tag , $_line_no ) = end ( $this -> _tag_stack );
$this -> _syntax_error ( " unclosed tag \ { $_open_tag } (opened line $_line_no ). " , E_USER_ERROR , __FILE__ , __LINE__ );
return ;
}
2001-03-02 21:38:42 +00:00
2003-10-11 08:55:53 +00:00
$compiled_content = '' ;
2001-03-02 23:13:01 +00:00
/* Interleave the compiled contents and text blocks to get the final result. */
2002-06-03 16:05:33 +00:00
for ( $i = 0 , $for_max = count ( $compiled_tags ); $i < $for_max ; $i ++ ) {
2003-10-11 08:55:53 +00:00
if ( $compiled_tags [ $i ] == '' ) {
// tag result empty, remove first newline from following text block
$text_blocks [ $i + 1 ] = preg_replace ( '!^(\r\n|\r|\n)!' , '' , $text_blocks [ $i + 1 ]);
}
2003-06-20 20:13:42 +00:00
$compiled_content .= $text_blocks [ $i ] . $compiled_tags [ $i ];
2001-03-02 23:13:01 +00:00
}
2003-06-20 20:13:42 +00:00
$compiled_content .= $text_blocks [ $i ];
2001-03-02 23:13:01 +00:00
2003-08-20 14:48:36 +00:00
/* Reformat data between 'strip' and '/strip' tags, removing spaces, tabs and newlines. */
if ( preg_match_all ( " ! { $ldq } strip { $rdq } .*? { $ldq } /strip { $rdq } !s " , $compiled_content , $_match )) {
$strip_tags = $_match [ 0 ];
2003-09-01 18:17:58 +00:00
$strip_tags_modified = preg_replace ( " ! { $ldq } /?strip { $rdq } |[ \t ]+ $ |^[ \t ]+!m " , '' , $strip_tags );
$strip_tags_modified = preg_replace ( '![\r\n]+!m' , '' , $strip_tags_modified );
2003-08-20 14:48:36 +00:00
for ( $i = 0 , $for_max = count ( $strip_tags ); $i < $for_max ; $i ++ )
$compiled_content = preg_replace ( " ! { $ldq } strip { $rdq } .*? { $ldq } /strip { $rdq } !s " ,
2003-11-18 23:35:05 +00:00
$this -> _quote_replace ( $strip_tags_modified [ $i ]),
2003-08-20 14:48:36 +00:00
$compiled_content , 1 );
}
2001-10-26 14:15:30 +00:00
// remove \n from the end of the file, if any
2003-06-23 17:01:45 +00:00
if (( $_len = strlen ( $compiled_content )) && ( $compiled_content { $_len - 1 } == " \n " )) {
2003-06-20 20:13:42 +00:00
$compiled_content = substr ( $compiled_content , 0 , - 1 );
2001-10-26 14:15:30 +00:00
}
2001-09-28 21:39:57 +00:00
2003-06-18 23:01:42 +00:00
if ( ! empty ( $this -> _cache_serial )) {
2003-06-20 20:13:42 +00:00
$compiled_content = " <?php \$ this->_cache_serials[' " . $this -> _cache_include . " '] = ' " . $this -> _cache_serial . " '; ?> " . $compiled_content ;
2003-06-18 23:01:42 +00:00
}
2003-04-26 15:56:18 +00:00
// remove unnecessary close/open tags
2003-06-20 20:13:42 +00:00
$compiled_content = preg_replace ( '!\?>\n?<\?php!' , '' , $compiled_content );
2003-04-26 15:56:18 +00:00
2001-09-28 21:39:57 +00:00
// run compiled template through postfilter functions
2002-01-31 20:49:40 +00:00
if ( count ( $this -> _plugins [ 'postfilter' ]) > 0 ) {
foreach ( $this -> _plugins [ 'postfilter' ] as $filter_name => $postfilter ) {
2002-04-05 17:16:52 +00:00
if ( $postfilter === false ) continue ;
2003-09-12 13:40:53 +00:00
if ( $postfilter [ 3 ] || is_callable ( $postfilter [ 0 ])) {
2003-06-20 20:13:42 +00:00
$compiled_content = call_user_func_array ( $postfilter [ 0 ],
array ( $compiled_content , & $this ));
2002-01-31 20:49:40 +00:00
$this -> _plugins [ 'postfilter' ][ $filter_name ][ 3 ] = true ;
2001-09-28 21:39:57 +00:00
} else {
2003-03-31 21:57:41 +00:00
$this -> _trigger_fatal_error ( " Smarty plugin error: postfilter ' $filter_name ' is not implemented " );
2002-01-31 20:49:40 +00:00
}
}
}
2002-02-05 19:05:39 +00:00
// put header at the top of the compiled template
$template_header = " <?php /* Smarty version " . $this -> _version . " , created on " . strftime ( " %Y-%m-%d %H:%M:%S " ) . " \n " ;
2003-07-28 20:36:55 +00:00
$template_header .= " compiled from " . strtr ( urlencode ( $resource_name ), array ( '%2F' => '/' , '%3A' => ':' )) . " */ ?> \n " ;
2002-02-05 19:05:39 +00:00
2002-01-31 20:49:40 +00:00
/* Emit code to load needed plugins. */
2003-06-18 23:01:42 +00:00
$this -> _plugins_code = '' ;
2002-01-31 20:49:40 +00:00
if ( count ( $this -> _plugin_info )) {
2003-05-19 22:38:28 +00:00
$_plugins_params = " array('plugins' => array( " ;
2002-01-31 20:49:40 +00:00
foreach ( $this -> _plugin_info as $plugin_type => $plugins ) {
foreach ( $plugins as $plugin_name => $plugin_info ) {
2003-05-19 22:38:28 +00:00
$_plugins_params .= " array(' $plugin_type ', ' $plugin_name ', ' $plugin_info[0] ', $plugin_info[1] , " ;
$_plugins_params .= $plugin_info [ 2 ] ? 'true),' : 'false),' ;
2001-09-28 21:39:57 +00:00
}
}
2003-05-19 22:38:28 +00:00
$_plugins_params .= '))' ;
2003-10-11 08:55:53 +00:00
$plugins_code = " <?php require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php'); \n smarty_core_load_plugins( $_plugins_params , \$ this); ?> \n " ;
2002-02-05 19:05:39 +00:00
$template_header .= $plugins_code ;
2002-01-31 20:49:40 +00:00
$this -> _plugin_info = array ();
2003-06-18 23:01:42 +00:00
$this -> _plugins_code = $plugins_code ;
2001-09-28 21:39:57 +00:00
}
2001-10-26 14:15:30 +00:00
2002-02-15 20:50:44 +00:00
if ( $this -> _init_smarty_vars ) {
2003-06-23 21:31:32 +00:00
$template_header .= " <?php require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.assign_smarty_interface.php'); \n smarty_core_assign_smarty_interface(null, \$ this); ?> \n " ;
2002-02-15 20:50:44 +00:00
$this -> _init_smarty_vars = false ;
}
2003-06-20 20:13:42 +00:00
$compiled_content = $template_header . $compiled_content ;
2001-03-02 23:13:01 +00:00
return true ;
}
2001-03-02 21:38:42 +00:00
2003-10-11 08:55:53 +00:00
/**
* Compile a template tag
*
* @ param string $template_tag
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2001-03-02 23:13:01 +00:00
function _compile_tag ( $template_tag )
2003-06-11 21:52:09 +00:00
{
2003-04-17 18:30:41 +00:00
/* Matched comment. */
if ( $template_tag { 0 } == '*' && $template_tag { strlen ( $template_tag ) - 1 } == '*' )
return '' ;
2003-10-11 08:55:53 +00:00
2002-12-19 17:02:11 +00:00
/* Split tag into two three parts: command, command modifiers and the arguments. */
2003-01-23 23:33:29 +00:00
if ( ! preg_match ( '/^(?:(' . $this -> _obj_call_regexp . '|' . $this -> _var_regexp
2003-10-11 08:55:53 +00:00
. '|\/?' . $this -> _reg_obj_regexp . '|\/?' . $this -> _func_regexp . ')(' . $this -> _mod_regexp . ' * ))
2002-12-18 16:51:48 +00:00
( ? : \s + ( .* )) ? $
/ xs ' , $template_tag , $match )) {
2003-10-11 08:55:53 +00:00
$this -> _syntax_error ( " unrecognized tag: $template_tag " , E_USER_ERROR , __FILE__ , __LINE__ );
}
2002-12-24 14:56:43 +00:00
2001-06-15 14:52:48 +00:00
$tag_command = $match [ 1 ];
2003-01-17 23:54:29 +00:00
$tag_modifier = isset ( $match [ 2 ]) ? $match [ 2 ] : null ;
$tag_args = isset ( $match [ 3 ]) ? $match [ 3 ] : null ;
2003-06-11 21:52:09 +00:00
2003-01-23 23:33:29 +00:00
if ( preg_match ( '!^' . $this -> _obj_call_regexp . '|' . $this -> _var_regexp . '$!' , $tag_command )) {
2003-10-11 08:55:53 +00:00
/* tag name is a variable or object */
2003-03-15 20:03:46 +00:00
$_return = $this -> _parse_var_props ( $tag_command . $tag_modifier , $this -> _parse_attrs ( $tag_args ));
2003-10-11 08:55:53 +00:00
if ( isset ( $_tag_attrs [ 'assign' ])) {
return " <?php \$ this->assign(' " . $this -> _dequote ( $_tag_attrs [ 'assign' ]) . " ', $_return ); ?> \n " ;
} else {
2003-10-25 19:43:14 +00:00
return " <?php echo $_return ; ?> " . $this -> _additional_newline ;
2003-10-11 08:55:53 +00:00
}
}
/* If the tag name is a registered object, we process it. */
2003-06-08 01:07:39 +00:00
if ( preg_match ( '!^\/?' . $this -> _reg_obj_regexp . '$!' , $tag_command )) {
2003-10-11 08:55:53 +00:00
return $this -> _compile_registered_object_tag ( $tag_command , $this -> _parse_attrs ( $tag_args ), $tag_modifier );
}
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
switch ( $tag_command ) {
case 'include' :
return $this -> _compile_include_tag ( $tag_args );
2001-03-02 21:38:42 +00:00
2001-12-04 22:31:47 +00:00
case 'include_php' :
return $this -> _compile_include_php_tag ( $tag_args );
2001-03-02 23:13:01 +00:00
case 'if' :
2003-12-08 10:44:21 +00:00
$this -> _push_tag ( 'if' );
2001-03-02 23:13:01 +00:00
return $this -> _compile_if_tag ( $tag_args );
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
case 'else' :
2003-12-08 10:44:21 +00:00
list ( $_open_tag ) = end ( $this -> _tag_stack );
if ( $_open_tag != 'if' && $_open_tag != 'elseif' )
2004-05-21 14:11:41 +00:00
$this -> _syntax_error ( 'unexpected {else}' , E_USER_ERROR , __FILE__ , __LINE__ );
2003-12-08 10:44:21 +00:00
else
$this -> _push_tag ( 'else' );
2001-03-02 23:13:01 +00:00
return '<?php else: ?>' ;
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
case 'elseif' :
2003-12-08 10:44:21 +00:00
list ( $_open_tag ) = end ( $this -> _tag_stack );
if ( $_open_tag != 'if' && $_open_tag != 'elseif' )
2004-05-21 14:11:41 +00:00
$this -> _syntax_error ( 'unexpected {elseif}' , E_USER_ERROR , __FILE__ , __LINE__ );
2003-12-08 10:44:21 +00:00
if ( $_open_tag == 'if' )
$this -> _push_tag ( 'elseif' );
2001-03-02 23:13:01 +00:00
return $this -> _compile_if_tag ( $tag_args , true );
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
case '/if' :
2003-12-08 10:44:21 +00:00
$this -> _pop_tag ( 'if' );
2001-03-02 23:13:01 +00:00
return '<?php endif; ?>' ;
2001-03-02 21:38:42 +00:00
2001-06-15 14:52:48 +00:00
case 'capture' :
2001-07-24 18:39:03 +00:00
return $this -> _compile_capture_tag ( true , $tag_args );
2001-10-26 14:15:30 +00:00
2001-06-15 14:52:48 +00:00
case '/capture' :
2001-07-24 18:39:03 +00:00
return $this -> _compile_capture_tag ( false );
2001-10-26 14:15:30 +00:00
2001-03-02 23:13:01 +00:00
case 'ldelim' :
return $this -> left_delimiter ;
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
case 'rdelim' :
return $this -> right_delimiter ;
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
case 'section' :
2003-12-08 10:44:21 +00:00
$this -> _push_tag ( 'section' );
2001-03-02 23:13:01 +00:00
return $this -> _compile_section_start ( $tag_args );
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
case 'sectionelse' :
2003-12-08 10:44:21 +00:00
$this -> _push_tag ( 'sectionelse' );
2001-03-02 23:13:01 +00:00
return " <?php endfor; else: ?> " ;
2003-12-08 10:44:21 +00:00
break ;
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
case '/section' :
2003-12-08 10:44:21 +00:00
$_open_tag = $this -> _pop_tag ( 'section' );
if ( $_open_tag == 'sectionelse' )
2001-03-02 23:13:01 +00:00
return " <?php endif; ?> " ;
else
return " <?php endfor; endif; ?> " ;
2001-03-02 21:38:42 +00:00
2001-11-27 15:27:22 +00:00
case 'foreach' :
2003-12-08 10:44:21 +00:00
$this -> _push_tag ( 'foreach' );
2001-11-27 15:27:22 +00:00
return $this -> _compile_foreach_start ( $tag_args );
break ;
case 'foreachelse' :
2003-12-08 10:44:21 +00:00
$this -> _push_tag ( 'foreachelse' );
2003-09-16 08:15:58 +00:00
return " <?php endforeach; unset( \$ _from); else: ?> " ;
2001-11-27 15:27:22 +00:00
case '/foreach' :
2003-12-08 10:44:21 +00:00
$_open_tag = $this -> _pop_tag ( 'foreach' );
if ( $_open_tag == 'foreachelse' )
2001-11-27 15:27:22 +00:00
return " <?php endif; ?> " ;
else
2003-09-16 08:15:58 +00:00
return " <?php endforeach; unset( \$ _from); endif; ?> " ;
2003-12-08 10:44:21 +00:00
break ;
2001-11-27 15:27:22 +00:00
2003-08-20 14:48:36 +00:00
case 'strip' :
case '/strip' :
2003-09-02 10:29:50 +00:00
if ( $tag_command { 0 } == '/' ) {
2003-12-08 10:44:21 +00:00
$this -> _pop_tag ( 'strip' );
2003-09-02 10:29:50 +00:00
if ( -- $this -> _strip_depth == 0 ) { /* outermost closing {/strip} */
$this -> _additional_newline = " \n " ;
return $this -> left_delimiter . $tag_command . $this -> right_delimiter ;
}
} else {
2003-12-08 10:44:21 +00:00
$this -> _push_tag ( 'strip' );
2003-09-02 10:29:50 +00:00
if ( $this -> _strip_depth ++== 0 ) { /* outermost opening {strip} */
$this -> _additional_newline = " " ;
return $this -> left_delimiter . $tag_command . $this -> right_delimiter ;
}
}
return '' ;
2003-09-01 15:54:05 +00:00
2001-04-26 17:27:40 +00:00
case 'php' :
2004-01-08 12:46:27 +00:00
/* handle folded tags replaced by {php} */
list (, $block ) = each ( $this -> _folded_blocks );
$this -> _current_line_no += substr_count ( $block [ 0 ], " \n " );
/* the number of matched elements in the regexp in _compile_file ()
determins the type of folded tag that was found */
switch ( count ( $block )) {
case 2 : /* comment */
return '' ;
case 3 : /* literal */
return " <?php echo ' " . strtr ( $block [ 2 ], array ( " ' " => " \ ' " , " \\ " => " \\ \\ " )) . " '; ?> " . $this -> _additional_newline ;
case 4 : /* php */
if ( $this -> security && ! $this -> security_settings [ 'PHP_TAGS' ]) {
$this -> _syntax_error ( " (secure mode) php tags not permitted " , E_USER_WARNING , __FILE__ , __LINE__ );
return ;
}
2004-01-10 23:43:07 +00:00
return '<?php ' . $block [ 3 ] . ' ?>' ;
2001-06-15 14:52:48 +00:00
}
2004-01-08 12:46:27 +00:00
break ;
2001-10-26 14:15:30 +00:00
2001-03-02 23:13:01 +00:00
case 'insert' :
return $this -> _compile_insert_tag ( $tag_args );
2001-03-02 21:38:42 +00:00
2003-01-23 23:33:29 +00:00
default :
2002-01-31 20:49:40 +00:00
if ( $this -> _compile_compiler_tag ( $tag_command , $tag_args , $output )) {
return $output ;
2002-12-19 17:02:11 +00:00
} else if ( $this -> _compile_block_tag ( $tag_command , $tag_args , $tag_modifier , $output )) {
2002-03-25 22:32:05 +00:00
return $output ;
2004-01-25 15:29:19 +00:00
} else if ( $this -> _compile_custom_tag ( $tag_command , $tag_args , $tag_modifier , $output )) {
return $output ;
2001-06-15 14:52:48 +00:00
} else {
2004-01-25 15:39:10 +00:00
$this -> _syntax_error ( " unrecognized tag ' $tag_command ' " , E_USER_ERROR , __FILE__ , __LINE__ );
2001-03-02 23:13:01 +00:00
}
2004-01-25 15:29:19 +00:00
2001-03-02 23:13:01 +00:00
}
2001-03-02 21:38:42 +00:00
}
2001-05-22 15:31:28 +00:00
2003-10-11 08:55:53 +00:00
/**
* compile the custom compiler tag
*
2003-02-16 05:09:19 +00:00
* sets $output to the compiled custom compiler tag
2003-10-11 08:55:53 +00:00
* @ param string $tag_command
* @ param string $tag_args
* @ param string $output
2003-04-20 21:12:13 +00:00
* @ return boolean
2003-10-11 08:55:53 +00:00
*/
2002-01-31 20:49:40 +00:00
function _compile_compiler_tag ( $tag_command , $tag_args , & $output )
2001-06-15 14:52:48 +00:00
{
2002-01-31 20:49:40 +00:00
$found = false ;
$have_function = true ;
/*
* 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 ];
2003-09-12 13:40:53 +00:00
if ( ! is_callable ( $plugin_func )) {
2002-01-31 20:49:40 +00:00
$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 .
*/
2002-06-26 14:51:12 +00:00
else if ( $plugin_file = $this -> _get_plugin_filepath ( 'compiler' , $tag_command )) {
2002-01-31 20:49:40 +00:00
$found = true ;
include_once $plugin_file ;
$plugin_func = 'smarty_compiler_' . $tag_command ;
2003-09-12 13:40:53 +00:00
if ( ! is_callable ( $plugin_func )) {
2002-01-31 20:49:40 +00:00
$message = " plugin function $plugin_func () not found in $plugin_file\n " ;
$have_function = false ;
} else {
2003-06-18 23:01:42 +00:00
$this -> _plugins [ 'compiler' ][ $tag_command ] = array ( $plugin_func , null , null , null , true );
2002-01-31 20:49:40 +00:00
}
2001-06-15 14:52:48 +00:00
}
2001-04-24 16:43:05 +00:00
2002-01-31 20:49:40 +00:00
/*
* 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 ) {
2003-06-16 14:38:57 +00:00
$output = call_user_func_array ( $plugin_func , array ( $tag_args , & $this ));
2003-10-11 08:55:53 +00:00
if ( $output != '' ) {
$output = '<?php ' . $this -> _push_cacheable_state ( 'compiler' , $tag_command )
2003-06-18 23:01:42 +00:00
. $output
. $this -> _pop_cacheable_state ( 'compiler' , $tag_command ) . ' ?>' ;
2003-10-11 08:55:53 +00:00
}
2002-01-31 20:49:40 +00:00
} else {
2002-12-24 17:07:43 +00:00
$this -> _syntax_error ( $message , E_USER_WARNING , __FILE__ , __LINE__ );
2002-01-31 20:49:40 +00:00
}
return true ;
} else {
return false ;
}
2001-06-15 14:52:48 +00:00
}
2001-04-24 16:43:05 +00:00
2001-05-22 15:31:28 +00:00
2003-10-11 08:55:53 +00:00
/**
* compile block function tag
*
2003-02-16 05:09:19 +00:00
* sets $output to compiled block function tag
2003-10-11 08:55:53 +00:00
* @ param string $tag_command
* @ param string $tag_args
* @ param string $tag_modifier
* @ param string $output
2003-04-20 21:12:13 +00:00
* @ return boolean
2003-10-11 08:55:53 +00:00
*/
2002-12-19 17:02:11 +00:00
function _compile_block_tag ( $tag_command , $tag_args , $tag_modifier , & $output )
2002-03-25 22:32:05 +00:00
{
if ( $tag_command { 0 } == '/' ) {
$start_tag = false ;
$tag_command = substr ( $tag_command , 1 );
} else
$start_tag = true ;
$found = false ;
$have_function = true ;
/*
* First we check if the block function has already been registered
* or loaded from a plugin file .
*/
if ( isset ( $this -> _plugins [ 'block' ][ $tag_command ])) {
$found = true ;
$plugin_func = $this -> _plugins [ 'block' ][ $tag_command ][ 0 ];
2003-09-12 13:40:53 +00:00
if ( ! is_callable ( $plugin_func )) {
2002-03-25 22:32:05 +00:00
$message = " block function ' $tag_command ' is not implemented " ;
$have_function = false ;
}
}
/*
* Otherwise we need to load plugin file and look for the function
* inside it .
*/
2002-06-26 14:51:12 +00:00
else if ( $plugin_file = $this -> _get_plugin_filepath ( 'block' , $tag_command )) {
2002-03-25 22:32:05 +00:00
$found = true ;
include_once $plugin_file ;
$plugin_func = 'smarty_block_' . $tag_command ;
if ( ! function_exists ( $plugin_func )) {
$message = " plugin function $plugin_func () not found in $plugin_file\n " ;
$have_function = false ;
} else {
2003-07-03 14:12:01 +00:00
$this -> _plugins [ 'block' ][ $tag_command ] = array ( $plugin_func , null , null , null , true );
2003-07-03 15:45:29 +00:00
2002-03-25 22:32:05 +00:00
}
}
if ( ! $found ) {
return false ;
} else if ( ! $have_function ) {
2002-12-24 17:07:43 +00:00
$this -> _syntax_error ( $message , E_USER_WARNING , __FILE__ , __LINE__ );
2002-03-25 22:32:05 +00:00
return true ;
}
/*
* Even though we ' ve located the plugin function , compilation
* happens only once , so the plugin will still need to be loaded
* at runtime for future requests .
*/
$this -> _add_plugin ( 'block' , $tag_command );
2003-12-08 10:44:21 +00:00
if ( $start_tag )
$this -> _push_tag ( $tag_command );
else
$this -> _pop_tag ( $tag_command );
2002-03-25 22:32:05 +00:00
if ( $start_tag ) {
2003-06-18 23:01:42 +00:00
$output = '<?php ' . $this -> _push_cacheable_state ( 'block' , $tag_command );
2003-08-06 11:35:59 +00:00
$attrs = $this -> _parse_attrs ( $tag_args );
$arg_list = $this -> _compile_arg_list ( 'block' , $tag_command , $attrs , $_cache_attrs = '' );
2004-01-27 23:00:26 +00:00
$output .= " $_cache_attrs\ $this->_tag_stack [] = array(' $tag_command ', array( " . implode ( ',' , $arg_list ) . ')); ' ;
$output .= $this -> _compile_plugin_call ( 'block' , $tag_command ) . '($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat=true);' ;
2003-04-20 13:04:42 +00:00
$output .= 'while ($_block_repeat) { ob_start(); ?>' ;
2002-03-25 22:32:05 +00:00
} else {
2003-04-20 13:04:42 +00:00
$output = '<?php $this->_block_content = ob_get_contents(); ob_end_clean(); ' ;
$_out_tag_text = $this -> _compile_plugin_call ( 'block' , $tag_command ) . '($this->_tag_stack[count($this->_tag_stack)-1][1], $this->_block_content, $this, $_block_repeat=false)' ;
if ( $tag_modifier != '' ) {
$this -> _parse_modifiers ( $_out_tag_text , $tag_modifier );
}
$output .= 'echo ' . $_out_tag_text . '; } ' ;
2003-10-11 08:55:53 +00:00
$output .= " array_pop( \$ this->_tag_stack); " . $this -> _pop_cacheable_state ( 'block' , $tag_command ) . '?>' ;
2002-03-25 22:32:05 +00:00
}
return true ;
}
2003-10-11 08:55:53 +00:00
/**
* compile custom function tag
*
* @ param string $tag_command
* @ param string $tag_args
* @ param string $tag_modifier
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2004-01-25 15:29:19 +00:00
function _compile_custom_tag ( $tag_command , $tag_args , $tag_modifier , & $output )
2003-10-11 08:55:53 +00:00
{
2004-01-25 15:29:19 +00:00
$found = false ;
$have_function = true ;
/*
* First we check if the custom function has already been registered
* or loaded from a plugin file .
*/
if ( isset ( $this -> _plugins [ 'function' ][ $tag_command ])) {
$found = true ;
$plugin_func = $this -> _plugins [ 'function' ][ $tag_command ][ 0 ];
if ( ! is_callable ( $plugin_func )) {
$message = " custom 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 ( $plugin_file = $this -> _get_plugin_filepath ( 'function' , $tag_command )) {
$found = true ;
include_once $plugin_file ;
$plugin_func = 'smarty_function_' . $tag_command ;
if ( ! function_exists ( $plugin_func )) {
$message = " plugin function $plugin_func () not found in $plugin_file\n " ;
$have_function = false ;
} else {
$this -> _plugins [ 'function' ][ $tag_command ] = array ( $plugin_func , null , null , null , true );
}
}
if ( ! $found ) {
return false ;
} else if ( ! $have_function ) {
$this -> _syntax_error ( $message , E_USER_WARNING , __FILE__ , __LINE__ );
return true ;
}
/* declare plugin to be loaded on display of the template that
we compile right now */
2002-03-19 22:21:22 +00:00
$this -> _add_plugin ( 'function' , $tag_command );
2001-03-02 21:38:42 +00:00
2003-08-06 11:35:59 +00:00
$_cacheable_state = $this -> _push_cacheable_state ( 'function' , $tag_command );
2001-03-02 23:13:01 +00:00
$attrs = $this -> _parse_attrs ( $tag_args );
2003-08-06 11:35:59 +00:00
$arg_list = $this -> _compile_arg_list ( 'function' , $tag_command , $attrs , $_cache_attrs = '' );
2003-02-19 15:58:03 +00:00
2004-01-25 15:29:19 +00:00
$output = $this -> _compile_plugin_call ( 'function' , $tag_command ) . '(array(' . implode ( ',' , $arg_list ) . " ), \$ this) " ;
2003-10-11 08:55:53 +00:00
if ( $tag_modifier != '' ) {
2004-01-25 15:29:19 +00:00
$this -> _parse_modifiers ( $output , $tag_modifier );
2003-10-11 08:55:53 +00:00
}
2004-01-25 15:29:19 +00:00
if ( $output != '' ) {
$output = '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';'
2003-09-01 18:17:58 +00:00
. $this -> _pop_cacheable_state ( 'function' , $tag_command ) . " ?> " . $this -> _additional_newline ;
2003-10-11 08:55:53 +00:00
}
2004-01-25 15:29:19 +00:00
return true ;
2001-03-02 23:13:01 +00:00
}
2001-03-02 21:38:42 +00:00
2003-10-11 08:55:53 +00:00
/**
* compile a registered object tag
*
* @ param string $tag_command
* @ param array $attrs
* @ param string $tag_modifier
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2003-01-23 23:33:29 +00:00
function _compile_registered_object_tag ( $tag_command , $attrs , $tag_modifier )
{
2003-06-08 01:07:39 +00:00
if ( $tag_command { 0 } == '/' ) {
$start_tag = false ;
$tag_command = substr ( $tag_command , 1 );
} else {
$start_tag = true ;
}
2003-10-11 08:55:53 +00:00
list ( $object , $obj_comp ) = explode ( '->' , $tag_command );
2003-01-23 23:33:29 +00:00
$arg_list = array ();
2003-10-11 08:55:53 +00:00
if ( count ( $attrs )) {
$_assign_var = false ;
foreach ( $attrs as $arg_name => $arg_value ) {
if ( $arg_name == 'assign' ) {
$_assign_var = $arg_value ;
unset ( $attrs [ 'assign' ]);
continue ;
}
if ( is_bool ( $arg_value ))
$arg_value = $arg_value ? 'true' : 'false' ;
$arg_list [] = " ' $arg_name ' => $arg_value " ;
}
}
2003-06-08 01:07:39 +00:00
if ( $this -> _reg_objects [ $object ][ 2 ]) {
// smarty object argument format
$args = " array( " . implode ( ',' , ( array ) $arg_list ) . " ), \$ this " ;
} else {
// traditional argument format
$args = implode ( ',' , array_values ( $attrs ));
if ( empty ( $args )) {
$args = 'null' ;
}
}
$prefix = '' ;
$postfix = '' ;
2003-09-01 15:54:05 +00:00
$newline = '' ;
2003-10-11 08:55:53 +00:00
if ( ! is_object ( $this -> _reg_objects [ $object ][ 0 ])) {
2004-01-29 10:38:12 +00:00
$this -> _trigger_fatal_error ( " registered ' $object ' is not an object " , $this -> _current_file , $this -> _current_line_no , __FILE__ , __LINE__ );
2003-10-11 08:55:53 +00:00
} elseif ( ! empty ( $this -> _reg_objects [ $object ][ 1 ]) && ! in_array ( $obj_comp , $this -> _reg_objects [ $object ][ 1 ])) {
2004-01-29 10:38:12 +00:00
$this -> _trigger_fatal_error ( " ' $obj_comp ' is not a registered component of object ' $object ' " , $this -> _current_file , $this -> _current_line_no , __FILE__ , __LINE__ );
2003-10-11 08:55:53 +00:00
} elseif ( method_exists ( $this -> _reg_objects [ $object ][ 0 ], $obj_comp )) {
// method
2003-06-08 01:07:39 +00:00
if ( in_array ( $obj_comp , $this -> _reg_objects [ $object ][ 3 ])) {
2003-10-11 08:55:53 +00:00
// block method
2003-06-08 01:07:39 +00:00
if ( $start_tag ) {
$prefix = " \$ this->_tag_stack[] = array(' $obj_comp ', $args ); " ;
$prefix .= " \$ this->_reg_objects[' $object '][0]-> $obj_comp ( \$ this->_tag_stack[count( \$ this->_tag_stack)-1][1], null, \$ this, \$ _block_repeat=true); " ;
$prefix .= " while ( \$ _block_repeat) { ob_start(); " ;
$return = null ;
$postfix = '' ;
2003-10-11 08:55:53 +00:00
} else {
2003-06-08 01:07:39 +00:00
$prefix = " \$ this->_obj_block_content = ob_get_contents(); ob_end_clean(); " ;
$return = " \$ this->_reg_objects[' $object '][0]-> $obj_comp ( \$ this->_tag_stack[count( \$ this->_tag_stack)-1][1], \$ this->_obj_block_content, \$ this, \$ _block_repeat=false) " ;
$postfix = " } array_pop( \$ this->_tag_stack); " ;
}
} else {
// non-block method
$return = " \$ this->_reg_objects[' $object '][0]-> $obj_comp ( $args ) " ;
2003-10-11 08:55:53 +00:00
}
} else {
// property
$return = " \$ this->_reg_objects[' $object '][0]-> $obj_comp " ;
}
2003-06-08 01:07:39 +00:00
if ( $return != null ) {
if ( $tag_modifier != '' ) {
$this -> _parse_modifiers ( $return , $tag_modifier );
}
if ( ! empty ( $_assign_var )) {
$output = " \$ this->assign(' " . $this -> _dequote ( $_assign_var ) . " ', $return ); " ;
} else {
$output = 'echo ' . $return . ';' ;
2003-09-01 18:17:58 +00:00
$newline = $this -> _additional_newline ;
2003-06-08 01:07:39 +00:00
}
} else {
$output = '' ;
}
2003-09-01 15:54:05 +00:00
return '<?php ' . $prefix . $output . $postfix . " ?> " . $newline ;
2003-01-23 23:33:29 +00:00
}
2001-05-22 15:31:28 +00:00
2003-10-11 08:55:53 +00:00
/**
* Compile { insert ... } tag
*
* @ param string $tag_args
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2001-03-02 23:13:01 +00:00
function _compile_insert_tag ( $tag_args )
{
$attrs = $this -> _parse_attrs ( $tag_args );
2002-01-31 20:49:40 +00:00
$name = $this -> _dequote ( $attrs [ 'name' ]);
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
if ( empty ( $name )) {
2002-12-24 17:07:43 +00:00
$this -> _syntax_error ( " missing insert name " , E_USER_ERROR , __FILE__ , __LINE__ );
2001-03-02 23:13:01 +00:00
}
2001-03-02 21:38:42 +00:00
2002-03-19 22:21:22 +00:00
if ( ! empty ( $attrs [ 'script' ])) {
$delayed_loading = true ;
2002-11-22 14:33:03 +00:00
} else {
2003-10-11 08:55:53 +00:00
$delayed_loading = false ;
}
2002-03-19 22:21:22 +00:00
2001-03-02 23:13:01 +00:00
foreach ( $attrs as $arg_name => $arg_value ) {
if ( is_bool ( $arg_value ))
$arg_value = $arg_value ? 'true' : 'false' ;
$arg_list [] = " ' $arg_name ' => $arg_value " ;
}
2001-03-02 21:38:42 +00:00
2002-03-19 22:21:22 +00:00
$this -> _add_plugin ( 'insert' , $name , $delayed_loading );
2002-01-31 20:49:40 +00:00
2003-10-11 08:55:53 +00:00
$_params = " array('args' => array( " . implode ( ', ' , ( array ) $arg_list ) . " )) " ;
2003-09-01 18:17:58 +00:00
return " <?php require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.run_insert_handler.php'); \n echo smarty_core_run_insert_handler( $_params , \$ this); ?> " . $this -> _additional_newline ;
2001-10-26 14:15:30 +00:00
}
2003-10-11 08:55:53 +00:00
/**
* Compile { include ... } tag
*
* @ param string $tag_args
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2001-03-02 23:13:01 +00:00
function _compile_include_tag ( $tag_args )
{
$attrs = $this -> _parse_attrs ( $tag_args );
2001-11-20 22:36:56 +00:00
$arg_list = array ();
2001-10-26 14:15:30 +00:00
2001-03-02 23:13:01 +00:00
if ( empty ( $attrs [ 'file' ])) {
2002-12-24 17:07:43 +00:00
$this -> _syntax_error ( " missing 'file' attribute in include tag " , E_USER_ERROR , __FILE__ , __LINE__ );
2001-04-27 19:39:31 +00:00
}
2001-03-02 21:38:42 +00:00
2001-06-15 14:52:48 +00:00
foreach ( $attrs as $arg_name => $arg_value ) {
if ( $arg_name == 'file' ) {
$include_file = $arg_value ;
2001-04-11 18:35:17 +00:00
continue ;
2001-12-05 20:08:12 +00:00
} else if ( $arg_name == 'assign' ) {
2001-12-05 16:36:58 +00:00
$assign_var = $arg_value ;
continue ;
}
2001-06-15 14:52:48 +00:00
if ( is_bool ( $arg_value ))
$arg_value = $arg_value ? 'true' : 'false' ;
$arg_list [] = " ' $arg_name ' => $arg_value " ;
}
2001-12-05 20:08:12 +00:00
$output = '<?php ' ;
2001-12-05 16:36:58 +00:00
if ( isset ( $assign_var )) {
2003-10-11 08:55:53 +00:00
$output .= " ob_start(); \n " ;
2001-12-05 20:08:12 +00:00
}
2003-10-11 08:55:53 +00:00
$output .=
2003-05-19 22:38:28 +00:00
" \$ _smarty_tpl_vars = \$ this->_tpl_vars; \n " ;
2003-10-11 08:55:53 +00:00
$_params = " array('smarty_include_tpl_file' => " . $include_file . " , 'smarty_include_vars' => array( " . implode ( ',' , ( array ) $arg_list ) . " )) " ;
$output .= " \$ this->_smarty_include( $_params ); \n " .
2003-05-23 19:26:57 +00:00
" \$ this->_tpl_vars = \$ _smarty_tpl_vars; \n " .
" unset( \$ _smarty_tpl_vars); \n " ;
2001-12-05 20:08:12 +00:00
if ( isset ( $assign_var )) {
2003-10-11 08:55:53 +00:00
$output .= " \$ this->assign( " . $assign_var . " , ob_get_contents()); ob_end_clean(); \n " ;
2001-12-05 20:08:12 +00:00
}
$output .= ' ?>' ;
2003-10-11 08:55:53 +00:00
return $output ;
2001-06-15 14:52:48 +00:00
2001-03-02 23:13:01 +00:00
}
2001-03-02 21:38:42 +00:00
2003-10-11 08:55:53 +00:00
/**
* Compile { include ... } tag
*
* @ param string $tag_args
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2001-12-04 22:31:47 +00:00
function _compile_include_php_tag ( $tag_args )
{
$attrs = $this -> _parse_attrs ( $tag_args );
if ( empty ( $attrs [ 'file' ])) {
2002-12-24 17:07:43 +00:00
$this -> _syntax_error ( " missing 'file' attribute in include_php tag " , E_USER_ERROR , __FILE__ , __LINE__ );
2001-12-04 22:31:47 +00:00
}
2002-01-31 20:49:40 +00:00
2003-10-23 12:42:52 +00:00
$assign_var = ( empty ( $attrs [ 'assign' ])) ? '' : $this -> _dequote ( $attrs [ 'assign' ]);
$once_var = ( empty ( $attrs [ 'once' ]) || $attrs [ 'once' ] == 'false' ) ? 'false' : 'true' ;
2003-10-11 08:55:53 +00:00
2003-11-21 12:39:50 +00:00
$arg_list = array ();
2003-10-11 08:55:53 +00:00
foreach ( $attrs as $arg_name => $arg_value ) {
if ( $arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign' ) {
if ( is_bool ( $arg_value ))
$arg_value = $arg_value ? 'true' : 'false' ;
$arg_list [] = " ' $arg_name ' => $arg_value " ;
}
}
2003-11-21 12:39:50 +00:00
$_params = " array('smarty_file' => " . $attrs [ 'file' ] . " , 'smarty_assign' => ' $assign_var ', 'smarty_once' => $once_var , 'smarty_include_vars' => array( " . implode ( ',' , $arg_list ) . " )) " ;
2003-10-11 08:55:53 +00:00
return " <?php require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.smarty_include_php.php'); \n smarty_core_smarty_include_php( $_params , \$ this); ?> " . $this -> _additional_newline ;
2001-12-04 22:31:47 +00:00
}
2001-05-22 15:31:28 +00:00
2003-10-11 08:55:53 +00:00
/**
* Compile { section ... } tag
*
* @ param string $tag_args
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2001-03-02 23:13:01 +00:00
function _compile_section_start ( $tag_args )
{
$attrs = $this -> _parse_attrs ( $tag_args );
2001-08-01 16:22:55 +00:00
$arg_list = array ();
2001-03-02 23:13:01 +00:00
2002-12-19 17:02:11 +00:00
$output = '<?php ' ;
2001-03-02 23:13:01 +00:00
$section_name = $attrs [ 'name' ];
if ( empty ( $section_name )) {
2002-12-24 17:07:43 +00:00
$this -> _syntax_error ( " missing section name " , E_USER_ERROR , __FILE__ , __LINE__ );
2001-03-02 23:13:01 +00:00
}
2001-03-02 21:38:42 +00:00
2004-04-16 07:53:37 +00:00
$output .= " unset( \$ this->_sections[ $section_name ]); \n " ;
2001-11-27 15:27:22 +00:00
$section_props = " \$ this->_sections[ $section_name ] " ;
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
foreach ( $attrs as $attr_name => $attr_value ) {
switch ( $attr_name ) {
case 'loop' :
2003-09-16 08:15:58 +00:00
$output .= " { $section_props } ['loop'] = is_array( \$ _loop= $attr_value ) ? count( \$ _loop) : max(0, (int) \$ _loop); unset( \$ _loop); \n " ;
2001-03-02 23:13:01 +00:00
break ;
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
case 'show' :
if ( is_bool ( $attr_value ))
2001-06-26 21:12:54 +00:00
$show_attr_value = $attr_value ? 'true' : 'false' ;
else
2001-06-27 19:21:53 +00:00
$show_attr_value = " (bool) $attr_value " ;
$output .= " { $section_props } ['show'] = $show_attr_value ; \n " ;
2001-06-26 21:12:54 +00:00
break ;
case 'name' :
2001-03-02 23:13:01 +00:00
$output .= " { $section_props } [' $attr_name '] = $attr_value ; \n " ;
break ;
2001-03-02 21:38:42 +00:00
2001-06-26 21:12:54 +00:00
case 'max' :
case 'start' :
$output .= " { $section_props } [' $attr_name '] = (int) $attr_value ; \n " ;
break ;
2001-06-27 19:21:53 +00:00
case 'step' :
$output .= " { $section_props } [' $attr_name '] = ((int) $attr_value ) == 0 ? 1 : (int) $attr_value ; \n " ;
break ;
2001-03-02 23:13:01 +00:00
default :
2002-12-24 17:07:43 +00:00
$this -> _syntax_error ( " unknown section attribute - ' $attr_name ' " , E_USER_ERROR , __FILE__ , __LINE__ );
2001-03-02 23:13:01 +00:00
break ;
}
2001-03-02 21:38:42 +00:00
}
2001-06-27 19:21:53 +00:00
if ( ! isset ( $attrs [ 'show' ]))
$output .= " { $section_props } ['show'] = true; \n " ;
2001-06-26 21:12:54 +00:00
if ( ! isset ( $attrs [ 'loop' ]))
2001-03-02 23:13:01 +00:00
$output .= " { $section_props } ['loop'] = 1; \n " ;
2001-03-02 21:38:42 +00:00
2001-06-26 21:12:54 +00:00
if ( ! isset ( $attrs [ 'max' ]))
$output .= " { $section_props } ['max'] = { $section_props } ['loop']; \n " ;
2001-06-27 16:44:26 +00:00
else
$output .= " if ( { $section_props } ['max'] < 0) \n " .
2001-10-26 14:15:30 +00:00
" { $section_props } ['max'] = { $section_props } ['loop']; \n " ;
2001-06-26 21:12:54 +00:00
2001-06-27 19:21:53 +00:00
if ( ! isset ( $attrs [ 'step' ]))
$output .= " { $section_props } ['step'] = 1; \n " ;
2001-06-26 21:12:54 +00:00
if ( ! isset ( $attrs [ 'start' ]))
2001-06-27 19:21:53 +00:00
$output .= " { $section_props } ['start'] = { $section_props } ['step'] > 0 ? 0 : { $section_props } ['loop']-1; \n " ;
else {
2001-06-26 21:12:54 +00:00
$output .= " if ( { $section_props } ['start'] < 0) \n " .
2001-06-27 19:21:53 +00:00
" { $section_props } ['start'] = max( { $section_props } ['step'] > 0 ? 0 : -1, { $section_props } ['loop'] + { $section_props } ['start']); \n " .
" else \n " .
" { $section_props } ['start'] = min( { $section_props } ['start'], { $section_props } ['step'] > 0 ? { $section_props } ['loop'] : { $section_props } ['loop']-1); \n " ;
}
2001-03-02 21:38:42 +00:00
2002-06-13 20:14:46 +00:00
$output .= " if ( { $section_props } ['show']) { \n " ;
if ( ! isset ( $attrs [ 'start' ]) && ! isset ( $attrs [ 'step' ]) && ! isset ( $attrs [ 'max' ])) {
$output .= " { $section_props } ['total'] = { $section_props } ['loop']; \n " ;
} else {
$output .= " { $section_props } ['total'] = min(ceil(( { $section_props } ['step'] > 0 ? { $section_props } ['loop'] - { $section_props } ['start'] : { $section_props } ['start']+1)/abs( { $section_props } ['step'])), { $section_props } ['max']); \n " ;
}
$output .= " if ( { $section_props } ['total'] == 0) \n " .
2001-06-27 19:21:53 +00:00
" { $section_props } ['show'] = false; \n " .
" } else \n " .
2001-06-26 21:12:54 +00:00
" { $section_props } ['total'] = 0; \n " ;
2001-03-02 21:38:42 +00:00
2001-06-26 21:12:54 +00:00
$output .= " if ( { $section_props } ['show']): \n " ;
2001-03-02 23:13:01 +00:00
$output .= "
2001-06-26 21:12:54 +00:00
for ({ $section_props }[ 'index' ] = { $section_props }[ 'start' ], { $section_props }[ 'iteration' ] = 1 ;
2001-06-27 19:21:53 +00:00
{ $section_props }[ 'iteration' ] <= { $section_props }[ 'total' ];
{ $section_props }[ 'index' ] += { $section_props }[ 'step' ], { $section_props }[ 'iteration' ] ++ ) : \n " ;
2001-06-27 19:27:29 +00:00
$output .= " { $section_props } ['rownum'] = { $section_props } ['iteration']; \n " ;
2001-06-27 19:21:53 +00:00
$output .= " { $section_props } ['index_prev'] = { $section_props } ['index'] - { $section_props } ['step']; \n " ;
$output .= " { $section_props } ['index_next'] = { $section_props } ['index'] + { $section_props } ['step']; \n " ;
$output .= " { $section_props } ['first'] = ( { $section_props } ['iteration'] == 1); \n " ;
$output .= " { $section_props } ['last'] = ( { $section_props } ['iteration'] == { $section_props } ['total']); \n " ;
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
$output .= " ?> " ;
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
return $output ;
}
2001-03-02 21:38:42 +00:00
2003-10-11 08:55:53 +00:00
/**
* Compile { foreach ... } tag .
*
* @ param string $tag_args
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2001-11-27 15:27:22 +00:00
function _compile_foreach_start ( $tag_args )
{
$attrs = $this -> _parse_attrs ( $tag_args );
$arg_list = array ();
if ( empty ( $attrs [ 'from' ])) {
2002-12-24 17:07:43 +00:00
$this -> _syntax_error ( " missing 'from' attribute " , E_USER_ERROR , __FILE__ , __LINE__ );
2001-11-27 15:27:22 +00:00
}
if ( empty ( $attrs [ 'item' ])) {
2002-12-24 17:07:43 +00:00
$this -> _syntax_error ( " missing 'item' attribute " , E_USER_ERROR , __FILE__ , __LINE__ );
2001-11-27 15:27:22 +00:00
}
$from = $attrs [ 'from' ];
$item = $this -> _dequote ( $attrs [ 'item' ]);
2001-11-29 17:05:39 +00:00
if ( isset ( $attrs [ 'name' ]))
$name = $attrs [ 'name' ];
2001-11-27 15:27:22 +00:00
$output = '<?php ' ;
2001-11-29 17:05:39 +00:00
if ( isset ( $name )) {
$output .= " if (isset( \$ this->_foreach[ $name ])) unset( \$ this->_foreach[ $name ]); \n " ;
$foreach_props = " \$ this->_foreach[ $name ] " ;
}
2001-11-27 15:27:22 +00:00
$key_part = '' ;
foreach ( $attrs as $attr_name => $attr_value ) {
switch ( $attr_name ) {
case 'key' :
$key = $this -> _dequote ( $attrs [ 'key' ]);
$key_part = " \$ this->_tpl_vars[' $key '] => " ;
break ;
case 'name' :
$output .= " { $foreach_props } [' $attr_name '] = $attr_value ; \n " ;
break ;
}
}
2001-11-29 17:05:39 +00:00
if ( isset ( $name )) {
2003-09-16 08:15:58 +00:00
$output .= " { $foreach_props } ['total'] = count( \$ _from = (array) $from ); \n " ;
2001-11-29 17:05:39 +00:00
$output .= " { $foreach_props } ['show'] = { $foreach_props } ['total'] > 0; \n " ;
$output .= " if ( { $foreach_props } ['show']): \n " ;
$output .= " { $foreach_props } ['iteration'] = 0; \n " ;
2003-09-16 08:15:58 +00:00
$output .= " foreach ( \$ _from as $key_part\ $this->_tpl_vars [' $item ']): \n " ;
2001-11-29 17:05:39 +00:00
$output .= " { $foreach_props } ['iteration']++; \n " ;
$output .= " { $foreach_props } ['first'] = ( { $foreach_props } ['iteration'] == 1); \n " ;
$output .= " { $foreach_props } ['last'] = ( { $foreach_props } ['iteration'] == { $foreach_props } ['total']); \n " ;
} else {
2003-09-16 08:15:58 +00:00
$output .= " if (count( \$ _from = (array) $from )): \n " ;
$output .= " foreach ( \$ _from as $key_part\ $this->_tpl_vars [' $item ']): \n " ;
2001-11-29 17:05:39 +00:00
}
2001-11-27 15:27:22 +00:00
$output .= '?>' ;
return $output ;
}
2001-05-22 15:31:28 +00:00
2003-10-11 08:55:53 +00:00
/**
* Compile { capture } .. { / capture } tags
*
* @ param boolean $start true if this is the { capture } tag
* @ param string $tag_args
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2003-06-18 23:01:42 +00:00
2001-07-24 18:39:03 +00:00
function _compile_capture_tag ( $start , $tag_args = '' )
{
$attrs = $this -> _parse_attrs ( $tag_args );
if ( $start ) {
if ( isset ( $attrs [ 'name' ]))
$buffer = $attrs [ 'name' ];
else
$buffer = " 'default' " ;
2003-06-19 10:42:59 +00:00
if ( isset ( $attrs [ 'assign' ]))
$assign = $attrs [ 'assign' ];
else
$assign = null ;
2001-07-24 18:39:03 +00:00
$output = " <?php ob_start(); ?> " ;
2003-06-19 10:42:59 +00:00
$this -> _capture_stack [] = array ( $buffer , $assign );
2001-07-24 18:39:03 +00:00
} else {
2003-06-19 10:42:59 +00:00
list ( $buffer , $assign ) = array_pop ( $this -> _capture_stack );
$output = " <?php \$ this->_smarty_vars['capture'][ $buffer ] = ob_get_contents(); " ;
if ( isset ( $assign )) {
$output .= " \$ this->assign( $assign , ob_get_contents()); " ;
}
$output .= " ob_end_clean(); ?> " ;
2001-07-24 18:39:03 +00:00
}
return $output ;
}
2003-10-11 08:55:53 +00:00
/**
* Compile { if ... } tag
*
* @ param string $tag_args
* @ param boolean $elseif if true , uses elseif instead of if
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2001-03-02 23:13:01 +00:00
function _compile_if_tag ( $tag_args , $elseif = false )
{
2002-12-23 22:52:42 +00:00
2001-03-02 23:13:01 +00:00
/* Tokenize args for 'if' tag. */
2002-12-19 23:55:17 +00:00
preg_match_all ( ' / ( ?>
2003-10-11 08:55:53 +00:00
' . $this->_obj_call_regexp . ' ( ? : ' . $this->_mod_regexp . ' * ) ? | # valid object call
' . $this->_var_regexp . ' ( ? : ' . $this->_mod_regexp . ' * ) ? | # var or quoted string
\ - ? 0 [ xX ][ 0 - 9 a - fA - F ] +| \ - ? \d + ( ? : \ . \d + ) ? | \ . \d +|!==|===|==|!=|<>|<<|>>|<=|>=| \ & \ &| \ | \ || \ ( | \ ) | , | \ !| \ ^|=| \ &| \ ~|<|>| \ || \ %| \ +| \ -| \ /| \ *| \ @ | # valid non-word token
\b\w + \b | # valid word token
\S + # anything else
) / x ' , $tag_args , $match );
2001-03-02 23:13:01 +00:00
$tokens = $match [ 0 ];
2003-10-11 08:55:53 +00:00
// make sure we have balanced parenthesis
$token_count = array_count_values ( $tokens );
if ( isset ( $token_count [ '(' ]) && $token_count [ '(' ] != $token_count [ ')' ]) {
$this -> _syntax_error ( " unbalanced parenthesis in if statement " , E_USER_ERROR , __FILE__ , __LINE__ );
}
2001-03-02 23:13:01 +00:00
$is_arg_stack = array ();
2002-12-19 23:55:17 +00:00
for ( $i = 0 ; $i < count ( $tokens ); $i ++ ) {
2001-10-26 14:15:30 +00:00
2001-03-02 23:13:01 +00:00
$token = & $tokens [ $i ];
2003-10-11 08:55:53 +00:00
2003-02-06 14:37:49 +00:00
switch ( strtolower ( $token )) {
2003-01-15 15:23:13 +00:00
case '!' :
case '%' :
case '!==' :
2002-12-19 23:55:17 +00:00
case '==' :
2003-02-17 14:47:21 +00:00
case '===' :
2003-01-15 15:23:13 +00:00
case '>' :
case '<' :
case '!=' :
2003-02-24 16:24:29 +00:00
case '<>' :
case '<<' :
case '>>' :
2003-01-15 15:23:13 +00:00
case '<=' :
case '>=' :
case '&&' :
case '||' :
2003-10-11 08:55:53 +00:00
case '|' :
case '^' :
case '&' :
case '~' :
case ')' :
case ',' :
case '+' :
case '-' :
case '*' :
case '/' :
case '@' :
break ;
2003-01-15 15:23:13 +00:00
case 'eq' :
2001-03-02 23:13:01 +00:00
$token = '==' ;
break ;
case 'ne' :
case 'neq' :
$token = '!=' ;
break ;
case 'lt' :
$token = '<' ;
break ;
case 'le' :
case 'lte' :
$token = '<=' ;
break ;
case 'gt' :
$token = '>' ;
break ;
case 'ge' :
case 'gte' :
$token = '>=' ;
break ;
case 'and' :
$token = '&&' ;
break ;
case 'or' :
$token = '||' ;
break ;
case 'not' :
$token = '!' ;
break ;
case 'mod' :
$token = '%' ;
break ;
case '(' :
array_push ( $is_arg_stack , $i );
break ;
2003-10-11 08:55:53 +00:00
2001-03-02 23:13:01 +00:00
case 'is' :
/* If last token was a ')' , we operate on the parenthesized
expression . The start of the expression is on the stack .
Otherwise , we operate on the last encountered token . */
if ( $tokens [ $i - 1 ] == ')' )
$is_arg_start = array_pop ( $is_arg_stack );
else
$is_arg_start = $i - 1 ;
/* Construct the argument for 'is' expression , so it knows
what to operate on . */
$is_arg = implode ( ' ' , array_slice ( $tokens , $is_arg_start , $i - $is_arg_start ));
2003-10-11 08:55:53 +00:00
2001-03-02 23:13:01 +00:00
/* Pass all tokens from next one until the end to the
'is' expression parsing function . The function will
return modified tokens , where the first one is the result
of the 'is' expression and the rest are the tokens it
2003-10-11 08:55:53 +00:00
didn ' t touch . */
2001-03-02 23:13:01 +00:00
$new_tokens = $this -> _parse_is_expr ( $is_arg , array_slice ( $tokens , $i + 1 ));
2003-10-11 08:55:53 +00:00
2001-03-02 23:13:01 +00:00
/* Replace the old tokens with the new ones. */
array_splice ( $tokens , $is_arg_start , count ( $tokens ), $new_tokens );
/* Adjust argument start so that it won ' t change from the
current position for the next iteration . */
$i = $is_arg_start ;
break ;
2003-10-11 08:55:53 +00:00
2001-06-15 14:52:48 +00:00
default :
2003-10-11 08:55:53 +00:00
if ( preg_match ( '!^' . $this -> _func_regexp . '$!' , $token ) ) {
// function call
if ( $this -> security &&
! in_array ( $token , $this -> security_settings [ 'IF_FUNCS' ])) {
$this -> _syntax_error ( " (secure mode) ' $token ' not allowed in if statement " , E_USER_ERROR , __FILE__ , __LINE__ );
}
} elseif ( preg_match ( '!^' . $this -> _obj_call_regexp . '|' . $this -> _var_regexp . '(?:' . $this -> _mod_regexp . '*)$!' , $token )) {
// object or variable
$token = $this -> _parse_var_props ( $token );
} elseif ( is_numeric ( $token )) {
// number, skip it
} else {
$this -> _syntax_error ( " unidentified token ' $token ' " , E_USER_ERROR , __FILE__ , __LINE__ );
}
2001-06-15 14:52:48 +00:00
break ;
2001-03-02 23:13:01 +00:00
}
}
2003-10-11 08:55:53 +00:00
2001-03-02 23:13:01 +00:00
if ( $elseif )
return '<?php elseif (' . implode ( ' ' , $tokens ) . '): ?>' ;
else
return '<?php if (' . implode ( ' ' , $tokens ) . '): ?>' ;
}
2001-03-02 21:38:42 +00:00
2001-05-22 15:31:28 +00:00
2003-08-06 11:35:59 +00:00
function _compile_arg_list ( $type , $name , $attrs , & $cache_code ) {
$arg_list = array ();
2003-10-11 08:55:53 +00:00
2003-08-06 11:35:59 +00:00
if ( isset ( $type ) && isset ( $name )
&& isset ( $this -> _plugins [ $type ])
&& isset ( $this -> _plugins [ $type ][ $name ])
&& empty ( $this -> _plugins [ $type ][ $name ][ 4 ])
&& is_array ( $this -> _plugins [ $type ][ $name ][ 5 ])
) {
/* we have a list of parameters that should be cached */
$_cache_attrs = $this -> _plugins [ $type ][ $name ][ 5 ];
$_count = $this -> _cache_attrs_count ++ ;
2003-08-07 11:35:46 +00:00
$cache_code = " \$ _cache_attrs =& \$ this->_smarty_cache_attrs(' $this->_cache_serial ',' $_count '); " ;
2003-08-06 11:35:59 +00:00
} else {
/* no parameters are cached */
$_cache_attrs = null ;
}
foreach ( $attrs as $arg_name => $arg_value ) {
if ( is_bool ( $arg_value ))
$arg_value = $arg_value ? 'true' : 'false' ;
if ( is_null ( $arg_value ))
$arg_value = 'null' ;
if ( $_cache_attrs && in_array ( $arg_name , $_cache_attrs )) {
$arg_list [] = " ' $arg_name ' => ( \$ this->_cache_including) ? \$ _cache_attrs[' $arg_name '] : ( \$ _cache_attrs[' $arg_name ']= $arg_value ) " ;
} else {
$arg_list [] = " ' $arg_name ' => $arg_value " ;
}
}
return $arg_list ;
}
2003-10-11 08:55:53 +00:00
/**
* Parse is expression
*
* @ param string $is_arg
* @ param array $tokens
2003-04-20 21:12:13 +00:00
* @ return array
2003-10-11 08:55:53 +00:00
*/
2001-03-02 23:13:01 +00:00
function _parse_is_expr ( $is_arg , $tokens )
{
$expr_end = 0 ;
2001-08-01 16:22:55 +00:00
$negate_expr = false ;
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
if (( $first_token = array_shift ( $tokens )) == 'not' ) {
$negate_expr = true ;
$expr_type = array_shift ( $tokens );
} else
$expr_type = $first_token ;
switch ( $expr_type ) {
case 'even' :
2004-02-07 20:55:27 +00:00
if ( isset ( $tokens [ $expr_end ]) && $tokens [ $expr_end ] == 'by' ) {
2001-03-02 23:13:01 +00:00
$expr_end ++ ;
$expr_arg = $tokens [ $expr_end ++ ];
2003-12-11 19:39:02 +00:00
$expr = " !(1 & ( $is_arg / " . $this -> _parse_var_props ( $expr_arg ) . " )) " ;
2002-02-04 17:20:36 +00:00
} else
2003-12-11 19:52:38 +00:00
$expr = " !(1 & $is_arg ) " ;
2001-03-02 21:38:42 +00:00
break ;
2001-03-02 23:13:01 +00:00
case 'odd' :
2004-02-07 20:55:27 +00:00
if ( isset ( $tokens [ $expr_end ]) && $tokens [ $expr_end ] == 'by' ) {
2001-03-02 23:13:01 +00:00
$expr_end ++ ;
$expr_arg = $tokens [ $expr_end ++ ];
2003-12-11 19:39:02 +00:00
$expr = " (1 & ( $is_arg / " . $this -> _parse_var_props ( $expr_arg ) . " )) " ;
2002-02-04 17:20:36 +00:00
} else
2003-12-11 19:52:38 +00:00
$expr = " (1 & $is_arg ) " ;
2001-03-02 21:38:42 +00:00
break ;
2001-03-02 23:13:01 +00:00
case 'div' :
2001-08-01 16:22:55 +00:00
if ( @ $tokens [ $expr_end ] == 'by' ) {
2001-03-02 23:13:01 +00:00
$expr_end ++ ;
$expr_arg = $tokens [ $expr_end ++ ];
2002-12-20 01:12:43 +00:00
$expr = " !( $is_arg % " . $this -> _parse_var_props ( $expr_arg ) . " ) " ;
2001-03-02 23:13:01 +00:00
} else {
2002-12-24 17:07:43 +00:00
$this -> _syntax_error ( " expecting 'by' after 'div' " , E_USER_ERROR , __FILE__ , __LINE__ );
2001-03-02 23:13:01 +00:00
}
2001-03-02 21:38:42 +00:00
break ;
2001-03-02 23:13:01 +00:00
default :
2002-12-24 17:07:43 +00:00
$this -> _syntax_error ( " unknown 'is' expression - ' $expr_type ' " , E_USER_ERROR , __FILE__ , __LINE__ );
2001-03-02 21:38:42 +00:00
break ;
}
2001-03-02 23:13:01 +00:00
if ( $negate_expr ) {
$expr = " !( $expr ) " ;
}
2003-10-11 08:55:53 +00:00
array_splice ( $tokens , 0 , $expr_end , $expr );
2001-03-02 23:13:01 +00:00
return $tokens ;
2001-03-02 21:38:42 +00:00
}
2001-05-22 15:31:28 +00:00
2003-10-11 08:55:53 +00:00
/**
* Parse attribute string
*
* @ param string $tag_args
2003-04-20 21:12:13 +00:00
* @ return array
2003-10-11 08:55:53 +00:00
*/
2003-05-04 22:08:44 +00:00
function _parse_attrs ( $tag_args )
2002-12-19 17:02:11 +00:00
{
2003-10-11 08:55:53 +00:00
2001-03-02 23:13:01 +00:00
/* Tokenize tag attributes. */
2003-01-21 20:39:09 +00:00
preg_match_all ( '/(?:' . $this -> _obj_call_regexp . '|' . $this -> _qstr_regexp . ' | ( ?> [^"\'=\s]+)
2001-03-02 23:13:01 +00:00
) + |
[ = ]
/ x ' , $tag_args , $match );
2003-10-11 08:55:53 +00:00
$tokens = $match [ 0 ];
2001-03-02 23:13:01 +00:00
$attrs = array ();
/* Parse state :
0 - expecting attribute name
1 - expecting '='
2 - expecting attribute value ( not '=' ) */
$state = 0 ;
2003-10-11 08:55:53 +00:00
2001-03-02 23:13:01 +00:00
foreach ( $tokens as $token ) {
switch ( $state ) {
case 0 :
/* If the token is a valid identifier , we set attribute name
and go to state 1. */
if ( preg_match ( '!^\w+$!' , $token )) {
$attr_name = $token ;
$state = 1 ;
} else
2003-02-13 15:28:14 +00:00
$this -> _syntax_error ( " invalid attribute name: ' $token ' " , E_USER_ERROR , __FILE__ , __LINE__ );
2001-03-02 23:13:01 +00:00
break ;
case 1 :
/* If the token is '=', then we go to state 2. */
if ( $token == '=' ) {
$state = 2 ;
} else
2003-01-17 23:54:29 +00:00
$this -> _syntax_error ( " expecting '=' after attribute name ' $last_token ' " , E_USER_ERROR , __FILE__ , __LINE__ );
2001-03-02 23:13:01 +00:00
break ;
case 2 :
/* If token is not '=' , we set the attribute value and go to
state 0. */
if ( $token != '=' ) {
/* We booleanize the token if it ' s a non - quoted possible
boolean value . */
2003-02-13 15:28:14 +00:00
if ( preg_match ( '!^(on|yes|true)$!' , $token )) {
2003-02-19 15:58:03 +00:00
$token = 'true' ;
2003-10-11 08:55:53 +00:00
} else if ( preg_match ( '!^(off|no|false)$!' , $token )) {
2003-02-19 15:58:03 +00:00
$token = 'false' ;
2003-10-11 08:55:53 +00:00
} else if ( $token == 'null' ) {
2003-02-19 15:58:03 +00:00
$token = 'null' ;
2003-10-11 08:55:53 +00:00
} else if ( preg_match ( '!^-?([0-9]+|0[xX][0-9a-fA-F]+)$!' , $token )) {
2003-04-03 17:00:17 +00:00
/* treat integer literally */
2003-10-11 08:55:53 +00:00
} else if ( ! preg_match ( '!^' . $this -> _obj_call_regexp . '|' . $this -> _var_regexp . '(?:' . $this -> _mod_regexp . ')*$!' , $token )) {
/* treat as a string, double-quote it escaping quotes */
2003-02-17 17:11:42 +00:00
$token = '"' . addslashes ( $token ) . '"' ;
2003-10-11 08:55:53 +00:00
}
2001-03-02 23:13:01 +00:00
$attrs [ $attr_name ] = $token ;
$state = 0 ;
} else
2002-12-24 17:07:43 +00:00
$this -> _syntax_error ( " '=' cannot be an attribute value " , E_USER_ERROR , __FILE__ , __LINE__ );
2001-03-02 23:13:01 +00:00
break ;
}
2003-10-11 08:55:53 +00:00
$last_token = $token ;
}
if ( $state != 0 ) {
if ( $state == 1 ) {
$this -> _syntax_error ( " expecting '=' after attribute name ' $last_token ' " , E_USER_ERROR , __FILE__ , __LINE__ );
} else {
$this -> _syntax_error ( " missing attribute value " , E_USER_ERROR , __FILE__ , __LINE__ );
}
2001-03-02 21:38:42 +00:00
}
2001-03-02 23:13:01 +00:00
$this -> _parse_vars_props ( $attrs );
2003-10-11 08:55:53 +00:00
2001-03-02 23:13:01 +00:00
return $attrs ;
}
2001-03-02 21:38:42 +00:00
2003-10-11 08:55:53 +00:00
/**
* compile multiple variables and section properties tokens into
* PHP code
*
* @ param array $tokens
*/
2001-03-02 23:13:01 +00:00
function _parse_vars_props ( & $tokens )
2002-12-20 01:12:43 +00:00
{
2003-10-11 08:55:53 +00:00
foreach ( $tokens as $key => $val ) {
$tokens [ $key ] = $this -> _parse_var_props ( $val );
}
}
/**
* compile single variable and section properties token into
* PHP code
*
* @ param string $val
* @ param string $tag_attrs
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2003-10-25 19:43:14 +00:00
function _parse_var_props ( $val )
2003-10-11 08:55:53 +00:00
{
$val = trim ( $val );
2002-12-23 22:52:42 +00:00
2003-10-27 15:27:55 +00:00
if ( preg_match ( '!^(' . $this -> _obj_call_regexp . '|' . $this -> _dvar_regexp . ')(' . $this -> _mod_regexp . '*)$!' , $val , $match )) {
2003-12-27 09:25:25 +00:00
// $ variable or object
$return = $this -> _parse_var ( $match [ 1 ]);
$modifiers = $match [ 2 ];
if ( ! empty ( $this -> default_modifiers ) && ! preg_match ( '!(^|\|)smarty:nodefaults($|\|)!' , $modifiers )) {
$_default_mod_string = implode ( '|' ,( array ) $this -> default_modifiers );
$modifiers = empty ( $modifiers ) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers ;
2003-10-11 08:55:53 +00:00
}
2003-12-27 09:25:25 +00:00
$this -> _parse_modifiers ( $return , $modifiers );
return $return ;
} elseif ( preg_match ( '!^' . $this -> _db_qstr_regexp . '(?:' . $this -> _mod_regexp . '*)$!' , $val )) {
2003-10-11 08:55:53 +00:00
// double quoted text
preg_match ( '!^(' . $this -> _db_qstr_regexp . ')(' . $this -> _mod_regexp . '*)$!' , $val , $match );
2002-12-20 01:12:43 +00:00
$return = $this -> _expand_quoted_text ( $match [ 1 ]);
2003-10-11 08:55:53 +00:00
if ( $match [ 2 ] != '' ) {
$this -> _parse_modifiers ( $return , $match [ 2 ]);
}
return $return ;
}
2004-04-16 08:34:39 +00:00
elseif ( preg_match ( '!^' . $this -> _num_const_regexp . '(?:' . $this -> _mod_regexp . '*)$!' , $val )) {
// numerical constant
preg_match ( '!^(' . $this -> _num_const_regexp . ')(' . $this -> _mod_regexp . '*)$!' , $val , $match );
if ( $match [ 2 ] != '' ) {
$this -> _parse_modifiers ( $match [ 1 ], $match [ 2 ]);
return $match [ 1 ];
}
}
2002-12-24 14:56:43 +00:00
elseif ( preg_match ( '!^' . $this -> _si_qstr_regexp . '(?:' . $this -> _mod_regexp . '*)$!' , $val )) {
2003-10-11 08:55:53 +00:00
// single quoted text
preg_match ( '!^(' . $this -> _si_qstr_regexp . ')(' . $this -> _mod_regexp . '*)$!' , $val , $match );
if ( $match [ 2 ] != '' ) {
$this -> _parse_modifiers ( $match [ 1 ], $match [ 2 ]);
return $match [ 1 ];
}
}
2002-12-24 14:56:43 +00:00
elseif ( preg_match ( '!^' . $this -> _cvar_regexp . '(?:' . $this -> _mod_regexp . '*)$!' , $val )) {
2003-10-11 08:55:53 +00:00
// config var
2002-12-20 01:12:43 +00:00
return $this -> _parse_conf_var ( $val );
2003-10-11 08:55:53 +00:00
}
2002-12-24 14:56:43 +00:00
elseif ( preg_match ( '!^' . $this -> _svar_regexp . '(?:' . $this -> _mod_regexp . '*)$!' , $val )) {
2003-10-11 08:55:53 +00:00
// section var
2002-12-20 01:12:43 +00:00
return $this -> _parse_section_prop ( $val );
2003-10-11 08:55:53 +00:00
}
elseif ( ! in_array ( $val , $this -> _permitted_tokens ) && ! is_numeric ( $val )) {
// literal string
return $this -> _expand_quoted_text ( '"' . $val . '"' );
}
return $val ;
2001-03-02 21:38:42 +00:00
}
2003-10-11 08:55:53 +00:00
/**
* expand quoted text with embedded variables
*
* @ param string $var_expr
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2002-12-18 16:51:48 +00:00
function _expand_quoted_text ( $var_expr )
{
2003-10-11 08:55:53 +00:00
// if contains unescaped $, expand it
if ( preg_match_all ( '%(?:\`(?<!\\\\)\$' . $this -> _dvar_guts_regexp . '\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)%' , $var_expr , $_match )) {
$_match = $_match [ 0 ];
rsort ( $_match );
reset ( $_match );
foreach ( $_match as $_var ) {
2003-10-20 14:02:03 +00:00
$var_expr = str_replace ( $_var , '".(' . $this -> _parse_var ( str_replace ( '`' , '' , $_var )) . ')."' , $var_expr );
2003-10-11 08:55:53 +00:00
}
2003-03-17 14:56:39 +00:00
$_return = preg_replace ( '%\.""|(?<!\\\\)""\.%' , '' , $var_expr );
2003-10-11 08:55:53 +00:00
} else {
$_return = $var_expr ;
}
// replace double quoted literal string with single quotes
$_return = preg_replace ( '!^"([\s\w]+)"$!' , " ' \\ 1' " , $_return );
return $_return ;
}
/**
2003-10-27 15:27:55 +00:00
* parse variable expression into PHP code
2003-10-11 08:55:53 +00:00
*
* @ param string $var_expr
2003-10-11 09:32:24 +00:00
* @ param string $output
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2003-10-27 15:27:55 +00:00
function _parse_var ( $var_expr )
2003-01-21 20:39:09 +00:00
{
2003-10-11 09:32:24 +00:00
$_has_math = false ;
2003-10-11 08:55:53 +00:00
$_math_vars = preg_split ( '!(' . $this -> _dvar_math_regexp . '|' . $this -> _qstr_regexp . ')!' , $var_expr , - 1 , PREG_SPLIT_DELIM_CAPTURE );
2003-10-11 09:32:24 +00:00
2003-10-27 15:27:55 +00:00
if ( count ( $_math_vars ) > 1 ) {
2003-10-11 09:32:24 +00:00
$_first_var = " " ;
2003-10-11 08:55:53 +00:00
$_complete_var = " " ;
2003-11-21 12:39:50 +00:00
$_output = " " ;
2003-10-11 08:55:53 +00:00
// simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter)
2003-10-27 15:27:55 +00:00
foreach ( $_math_vars as $_k => $_math_var ) {
2003-10-11 08:55:53 +00:00
$_math_var = $_math_vars [ $_k ];
2003-10-11 09:32:24 +00:00
2003-10-27 15:27:55 +00:00
if ( ! empty ( $_math_var ) || is_numeric ( $_math_var )) {
2003-10-11 08:55:53 +00:00
// hit a math operator, so process the stuff which came before it
2003-10-27 15:27:55 +00:00
if ( preg_match ( '!^' . $this -> _dvar_math_regexp . '$!' , $_math_var )) {
2003-10-11 08:55:53 +00:00
$_has_math = true ;
2003-10-27 15:27:55 +00:00
if ( ! empty ( $_complete_var ) || is_numeric ( $_complete_var )) {
$_output .= $this -> _parse_var ( $_complete_var );
2003-10-11 08:55:53 +00:00
}
// just output the math operator to php
$_output .= $_math_var ;
2003-10-11 09:32:24 +00:00
if ( empty ( $_first_var ))
$_first_var = $_complete_var ;
2003-10-11 08:55:53 +00:00
$_complete_var = " " ;
2003-10-27 15:27:55 +00:00
} else {
2003-10-11 08:55:53 +00:00
// fetch multiple -> (like $foo->bar->baz ) which wouldn't get fetched else, because it would only get $foo->bar and treat the ->baz as "-" ">baz" then
2003-10-27 15:27:55 +00:00
for ( $_i = $_k + 1 ; $_i <= count ( $_math_vars ); $_i += 2 ) {
2003-10-11 08:55:53 +00:00
// fetch -> because it gets splitted at - and move it back together
2003-10-27 15:27:55 +00:00
if ( /* prevent notice */ ( isset ( $_math_vars [ $_i ]) && isset ( $_math_vars [ $_i + 1 ])) && ( $_math_vars [ $_i ] === '-' && $_math_vars [ $_i + 1 ]{ 0 } === '>' )) {
2003-10-11 08:55:53 +00:00
$_math_var .= $_math_vars [ $_i ] . $_math_vars [ $_i + 1 ];
$_math_vars [ $_i ] = $_math_vars [ $_i + 1 ] = '' ;
2003-10-27 15:27:55 +00:00
} else {
2003-10-11 08:55:53 +00:00
break ;
2003-10-27 15:27:55 +00:00
}
2003-10-11 08:55:53 +00:00
}
$_complete_var .= $_math_var ;
}
}
}
2003-10-27 15:27:55 +00:00
if ( $_has_math ) {
2003-10-11 09:32:24 +00:00
if ( ! empty ( $_complete_var ) || is_numeric ( $_complete_var ))
2004-04-16 10:31:43 +00:00
$_output .= $this -> _parse_var ( $_complete_var );
2003-10-11 08:55:53 +00:00
2003-10-11 09:32:24 +00:00
// get the modifiers working (only the last var from math + modifier is left)
$var_expr = $_complete_var ;
2003-10-11 08:55:53 +00:00
}
}
// prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit)
2003-10-27 15:27:55 +00:00
if ( is_numeric ( $var_expr { 0 }))
$_var_ref = $var_expr ;
2003-10-11 08:55:53 +00:00
else
2003-10-27 15:27:55 +00:00
$_var_ref = substr ( $var_expr , 1 );
2003-10-11 08:55:53 +00:00
2003-10-27 15:27:55 +00:00
if ( ! $_has_math ) {
2003-10-11 09:32:24 +00:00
// get [foo] and .foo and ->foo and (...) pieces
preg_match_all ( '!(?:^\w+)|' . $this -> _obj_params_regexp . '|(?:' . $this -> _var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+!' , $_var_ref , $match );
$_indexes = $match [ 0 ];
$_var_name = array_shift ( $_indexes );
/* Handle $smarty.* variable references as a special case. */
if ( $_var_name == 'smarty' ) {
/*
* If the reference could be compiled , use the compiled output ;
* otherwise , fall back on the $smarty variable generated at
* run - time .
*/
if (( $smarty_ref = $this -> _compile_smarty_ref ( $_indexes )) !== null ) {
$_output = $smarty_ref ;
} else {
$_var_name = substr ( array_shift ( $_indexes ), 1 );
$_output = " \$ this->_smarty_vars[' $_var_name '] " ;
}
} elseif ( is_numeric ( $_var_name ) && is_numeric ( $var_expr { 0 })) {
// because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers
if ( count ( $_indexes ) > 0 )
{
$_var_name .= implode ( " " , $_indexes );
$_indexes = array ();
}
$_output = $_var_name ;
2001-11-27 15:27:22 +00:00
} else {
2003-10-11 09:32:24 +00:00
$_output = " \$ this->_tpl_vars[' $_var_name '] " ;
2001-11-27 15:27:22 +00:00
}
2003-07-03 15:45:29 +00:00
2003-10-11 09:32:24 +00:00
foreach ( $_indexes as $_index ) {
if ( $_index { 0 } == '[' ) {
$_index = substr ( $_index , 1 , - 1 );
if ( is_numeric ( $_index )) {
$_output .= " [ $_index ] " ;
} elseif ( $_index { 0 } == '$' ) {
2003-11-13 16:51:47 +00:00
if ( strpos ( $_index , '.' ) !== false ) {
$_output .= '[' . $this -> _parse_var ( $_index ) . ']' ;
} else {
$_output .= " [ \$ this->_tpl_vars[' " . substr ( $_index , 1 ) . " ']] " ;
}
2003-10-11 09:32:24 +00:00
} else {
$_var_parts = explode ( '.' , $_index );
$_var_section = $_var_parts [ 0 ];
$_var_section_prop = isset ( $_var_parts [ 1 ]) ? $_var_parts [ 1 ] : 'index' ;
$_output .= " [ \$ this->_sections[' $_var_section '][' $_var_section_prop ']] " ;
}
} else if ( $_index { 0 } == '.' ) {
if ( $_index { 1 } == '$' )
$_output .= " [ \$ this->_tpl_vars[' " . substr ( $_index , 2 ) . " ']] " ;
else
$_output .= " [' " . substr ( $_index , 1 ) . " '] " ;
} else if ( substr ( $_index , 0 , 2 ) == '->' ) {
if ( substr ( $_index , 2 , 2 ) == '__' ) {
$this -> _syntax_error ( 'call to internal object members is not allowed' , E_USER_ERROR , __FILE__ , __LINE__ );
} elseif ( $this -> security && substr ( $_index , 2 , 1 ) == '_' ) {
$this -> _syntax_error ( '(secure) call to private object member is not allowed' , E_USER_ERROR , __FILE__ , __LINE__ );
} elseif ( $_index { 2 } == '$' ) {
if ( $this -> security ) {
$this -> _syntax_error ( '(secure) call to dynamic object member is not allowed' , E_USER_ERROR , __FILE__ , __LINE__ );
} else {
$_output .= '->{(($_var=$this->_tpl_vars[\'' . substr ( $_index , 3 ) . '\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}' ;
}
2003-07-03 15:45:29 +00:00
} else {
2003-10-11 09:32:24 +00:00
$_output .= $_index ;
2003-07-03 15:45:29 +00:00
}
2003-10-11 09:32:24 +00:00
} elseif ( $_index { 0 } == '(' ) {
$_index = $this -> _parse_parenth_args ( $_index );
$_output .= $_index ;
2003-07-03 15:45:29 +00:00
} else {
$_output .= $_index ;
}
2001-06-15 14:52:48 +00:00
}
}
2003-10-11 08:55:53 +00:00
2003-06-11 21:52:09 +00:00
return $_output ;
2003-01-21 20:39:09 +00:00
}
2003-10-11 08:55:53 +00:00
/**
* parse arguments in function call parenthesis
*
* @ param string $parenth_args
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2003-01-21 20:39:09 +00:00
function _parse_parenth_args ( $parenth_args )
{
2003-10-11 08:55:53 +00:00
preg_match_all ( '!' . $this -> _param_regexp . '!' , $parenth_args , $match );
$match = $match [ 0 ];
rsort ( $match );
reset ( $match );
$orig_vals = $match ;
$this -> _parse_vars_props ( $match );
return str_replace ( $orig_vals , $match , $parenth_args );
}
/**
* parse configuration variable expression into PHP code
*
* @ param string $conf_var_expr
*/
2001-03-02 23:13:01 +00:00
function _parse_conf_var ( $conf_var_expr )
2003-06-16 19:45:11 +00:00
{
2001-05-15 14:24:06 +00:00
$parts = explode ( '|' , $conf_var_expr , 2 );
2001-06-15 14:52:48 +00:00
$var_ref = $parts [ 0 ];
$modifiers = isset ( $parts [ 1 ]) ? $parts [ 1 ] : '' ;
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
$var_name = substr ( $var_ref , 1 , - 1 );
2001-03-02 21:38:42 +00:00
2003-06-16 19:45:11 +00:00
$output = " \$ this->_config[0]['vars'][' $var_name '] " ;
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
$this -> _parse_modifiers ( $output , $modifiers );
2003-06-16 19:45:11 +00:00
2001-03-02 23:13:01 +00:00
return $output ;
}
2001-03-02 21:38:42 +00:00
2003-10-11 08:55:53 +00:00
/**
* parse section property expression into PHP code
*
* @ param string $section_prop_expr
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2001-03-02 23:13:01 +00:00
function _parse_section_prop ( $section_prop_expr )
{
2001-05-15 14:24:06 +00:00
$parts = explode ( '|' , $section_prop_expr , 2 );
2001-06-15 14:52:48 +00:00
$var_ref = $parts [ 0 ];
$modifiers = isset ( $parts [ 1 ]) ? $parts [ 1 ] : '' ;
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
preg_match ( '!%(\w+)\.(\w+)%!' , $var_ref , $match );
$section_name = $match [ 1 ];
$prop_name = $match [ 2 ];
2001-03-02 21:38:42 +00:00
2001-11-27 15:27:22 +00:00
$output = " \$ this->_sections[' $section_name '][' $prop_name '] " ;
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
$this -> _parse_modifiers ( $output , $modifiers );
2001-03-02 21:38:42 +00:00
2001-03-02 23:13:01 +00:00
return $output ;
}
2001-03-02 21:38:42 +00:00
2001-05-22 15:31:28 +00:00
2003-10-11 08:55:53 +00:00
/**
* parse modifier chain into PHP code
*
2003-02-16 05:09:19 +00:00
* sets $output to parsed modified chain
2003-10-11 08:55:53 +00:00
* @ param string $output
* @ param string $modifier_string
*/
2001-03-02 23:13:01 +00:00
function _parse_modifiers ( & $output , $modifier_string )
{
2003-03-15 20:47:29 +00:00
preg_match_all ( '!\|(@?\w+)((?>:(?:' . $this -> _qstr_regexp . '|[^|]+))*)!' , '|' . $modifier_string , $_match );
2003-06-16 19:45:11 +00:00
list (, $_modifiers , $modifier_arg_strings ) = $_match ;
2003-03-15 20:47:29 +00:00
for ( $_i = 0 , $_for_max = count ( $_modifiers ); $_i < $_for_max ; $_i ++ ) {
2003-04-29 17:00:30 +00:00
$_modifier_name = $_modifiers [ $_i ];
2003-10-11 08:55:53 +00:00
if ( $_modifier_name == 'smarty' ) {
// skip smarty modifier
continue ;
}
2003-06-16 19:45:11 +00:00
preg_match_all ( '!:(' . $this -> _qstr_regexp . '|[^:]+)!' , $modifier_arg_strings [ $_i ], $_match );
2003-03-15 20:47:29 +00:00
$_modifier_args = $_match [ 1 ];
2003-06-16 19:45:11 +00:00
2003-03-15 20:47:29 +00:00
if ( $_modifier_name { 0 } == '@' ) {
2003-07-29 10:29:36 +00:00
$_map_array = false ;
2003-03-15 20:47:29 +00:00
$_modifier_name = substr ( $_modifier_name , 1 );
2002-01-31 20:49:40 +00:00
} else {
2003-07-29 10:29:36 +00:00
$_map_array = true ;
2001-06-15 14:52:48 +00:00
}
2003-07-29 10:29:36 +00:00
2003-08-06 08:16:29 +00:00
if ( empty ( $this -> _plugins [ 'modifier' ][ $_modifier_name ])
2003-10-11 08:55:53 +00:00
&& ! $this -> _get_plugin_filepath ( 'modifier' , $_modifier_name )
2003-08-06 08:16:29 +00:00
&& function_exists ( $_modifier_name )) {
2003-07-29 10:29:36 +00:00
if ( $this -> security && ! in_array ( $_modifier_name , $this -> security_settings [ 'MODIFIER_FUNCS' ])) {
2004-01-29 10:38:12 +00:00
$this -> _trigger_fatal_error ( " [plugin] (secure mode) modifier ' $_modifier_name ' is not allowed " , $this -> _current_file , $this -> _current_line_no , __FILE__ , __LINE__ );
2003-07-29 10:29:36 +00:00
} else {
$this -> _plugins [ 'modifier' ][ $_modifier_name ] = array ( $_modifier_name , null , null , false );
}
}
2004-01-27 23:00:26 +00:00
$this -> _add_plugin ( 'modifier' , $_modifier_name );
2003-07-29 10:29:36 +00:00
2003-03-15 20:47:29 +00:00
$this -> _parse_vars_props ( $_modifier_args );
2001-03-02 21:38:42 +00:00
2003-10-11 08:55:53 +00:00
if ( $_modifier_name == 'default' ) {
// supress notifications of default modifier vars and args
if ( $output { 0 } == '$' ) {
$output = '@' . $output ;
}
if ( isset ( $_modifier_args [ 0 ]) && $_modifier_args [ 0 ]{ 0 } == '$' ) {
$_modifier_args [ 0 ] = '@' . $_modifier_args [ 0 ];
}
}
2003-06-16 19:45:11 +00:00
if ( count ( $_modifier_args ) > 0 )
$_modifier_args = ', ' . implode ( ', ' , $_modifier_args );
else
$_modifier_args = '' ;
2001-03-02 21:38:42 +00:00
2003-07-29 10:29:36 +00:00
if ( $_map_array ) {
$output = " ((is_array( \$ _tmp= $output )) ? \$ this->_run_mod_handler(' $_modifier_name ', true, \$ _tmp $_modifier_args ) : " . $this -> _compile_plugin_call ( 'modifier' , $_modifier_name ) . " ( \$ _tmp $_modifier_args )) " ;
} else {
$output = $this -> _compile_plugin_call ( 'modifier' , $_modifier_name ) . " ( $output $_modifier_args ) " ;
}
2003-06-16 19:45:11 +00:00
}
2001-03-02 21:38:42 +00:00
}
2003-06-17 21:54:55 +00:00
2003-10-11 08:55:53 +00:00
/**
* add plugin
*
* @ param string $type
* @ param string $name
* @ param boolean ? $delayed_loading
*/
2002-03-19 22:21:22 +00:00
function _add_plugin ( $type , $name , $delayed_loading = null )
2002-01-31 20:49:40 +00:00
{
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 ,
2002-03-19 22:21:22 +00:00
$this -> _current_line_no ,
$delayed_loading );
2002-01-31 20:49:40 +00:00
}
}
2003-10-11 08:55:53 +00:00
/**
* Compiles references of type $smarty . foo
*
* @ param string $indexes
2003-04-20 21:12:13 +00:00
* @ return string
2003-10-11 08:55:53 +00:00
*/
2001-11-27 15:27:22 +00:00
function _compile_smarty_ref ( & $indexes )
{
/* Extract the reference name. */
2003-02-27 17:32:08 +00:00
$_ref = substr ( $indexes [ 0 ], 1 );
2003-08-18 09:28:02 +00:00
foreach ( $indexes as $_index_no => $_index ) {
if ( $_index { 0 } != '.' && $_index_no < 2 || ! preg_match ( '!^(\.|\[|->)!' , $_index )) {
2003-10-11 08:55:53 +00:00
$this -> _syntax_error ( '$smarty' . implode ( '' , array_slice ( $indexes , 0 , 2 )) . ' is an invalid reference' , E_USER_ERROR , __FILE__ , __LINE__ );
}
}
2003-02-27 17:32:08 +00:00
switch ( $_ref ) {
2001-11-27 15:27:22 +00:00
case 'now' :
$compiled_ref = 'time()' ;
2003-10-11 08:55:53 +00:00
$_max_index = 1 ;
2001-11-27 15:27:22 +00:00
break ;
case 'foreach' :
2001-11-29 21:19:39 +00:00
case 'section' :
2001-11-27 15:27:22 +00:00
array_shift ( $indexes );
2003-02-27 17:32:08 +00:00
$_var = $this -> _parse_var_props ( substr ( $indexes [ 0 ], 1 ));
if ( $_ref == 'foreach' )
$compiled_ref = " \$ this->_foreach[ $_var ] " ;
2001-11-29 21:19:39 +00:00
else
2003-02-27 17:32:08 +00:00
$compiled_ref = " \$ this->_sections[ $_var ] " ;
2001-11-27 15:27:22 +00:00
break ;
case 'get' :
2003-06-11 22:17:52 +00:00
$compiled_ref = ( $this -> request_use_auto_globals ) ? '$_GET' : " \$ GLOBALS['HTTP_GET_VARS'] " ;
2003-06-24 09:39:37 +00:00
break ;
2002-02-15 20:50:44 +00:00
2001-11-27 15:27:22 +00:00
case 'post' :
2003-06-11 22:17:52 +00:00
$compiled_ref = ( $this -> request_use_auto_globals ) ? '$_POST' : " \$ GLOBALS['HTTP_POST_VARS'] " ;
2002-02-15 20:50:44 +00:00
break ;
2001-11-27 15:27:22 +00:00
case 'cookies' :
2003-06-11 22:17:52 +00:00
$compiled_ref = ( $this -> request_use_auto_globals ) ? '$_COOKIE' : " \$ GLOBALS['HTTP_COOKIE_VARS'] " ;
2002-02-15 20:50:44 +00:00
break ;
case 'env' :
2003-06-11 22:17:52 +00:00
$compiled_ref = ( $this -> request_use_auto_globals ) ? '$_ENV' : " \$ GLOBALS['HTTP_ENV_VARS'] " ;
2002-02-15 20:50:44 +00:00
break ;
2001-11-27 15:27:22 +00:00
case 'server' :
2003-06-11 22:17:52 +00:00
$compiled_ref = ( $this -> request_use_auto_globals ) ? '$_SERVER' : " \$ GLOBALS['HTTP_SERVER_VARS'] " ;
2002-02-15 20:50:44 +00:00
break ;
2001-11-27 15:27:22 +00:00
case 'session' :
2003-06-11 22:17:52 +00:00
$compiled_ref = ( $this -> request_use_auto_globals ) ? '$_SESSION' : " \$ GLOBALS['HTTP_SESSION_VARS'] " ;
2002-02-15 20:50:44 +00:00
break ;
/*
* These cases are handled either at run - time or elsewhere in the
* compiler .
*/
2001-11-27 15:27:22 +00:00
case 'request' :
2003-06-11 22:17:52 +00:00
if ( $this -> request_use_auto_globals ) {
$compiled_ref = '$_REQUEST' ;
break ;
} else {
$this -> _init_smarty_vars = true ;
}
2002-02-15 20:50:44 +00:00
return null ;
2001-11-27 20:04:47 +00:00
case 'capture' :
2001-11-27 15:27:22 +00:00
return null ;
2002-04-03 16:31:59 +00:00
case 'template' :
$compiled_ref = " ' $this->_current_file ' " ;
2003-10-11 08:55:53 +00:00
$_max_index = 1 ;
break ;
case 'version' :
$compiled_ref = " ' $this->_version ' " ;
$_max_index = 1 ;
2002-04-03 16:31:59 +00:00
break ;
2003-10-11 08:55:53 +00:00
case 'const' :
2002-12-19 17:02:11 +00:00
array_shift ( $indexes );
2003-10-11 08:55:53 +00:00
$_val = $this -> _parse_var_props ( substr ( $indexes [ 0 ], 1 ));
$compiled_ref = '@constant(' . $_val . ')' ;
$_max_index = 1 ;
2002-12-19 17:02:11 +00:00
break ;
2003-02-24 14:51:47 +00:00
case 'config' :
2003-06-16 19:45:11 +00:00
$compiled_ref = " \$ this->_config[0]['vars'] " ;
2003-11-26 14:02:05 +00:00
$_max_index = 3 ;
2003-02-24 14:51:47 +00:00
break ;
2001-11-27 15:27:22 +00:00
default :
2003-03-19 12:51:34 +00:00
$this -> _syntax_error ( '$smarty.' . $_ref . ' is an unknown reference' , E_USER_ERROR , __FILE__ , __LINE__ );
2001-11-27 15:27:22 +00:00
break ;
}
2003-02-27 17:32:08 +00:00
if ( isset ( $_max_index ) && count ( $indexes ) > $_max_index ) {
$this -> _syntax_error ( '$smarty' . implode ( '' , $indexes ) . ' is an invalid reference' , E_USER_ERROR , __FILE__ , __LINE__ );
}
2001-11-27 15:27:22 +00:00
array_shift ( $indexes );
return $compiled_ref ;
}
2001-05-22 15:31:28 +00:00
2003-04-15 10:41:13 +00:00
/**
* compiles call to plugin of type $type with name $name
* returns a string containing the function - name or method call
* without the paramter - list that would have follow to make the
* call valid php - syntax
*
* @ param string $type
* @ param string $name
2003-04-20 21:12:13 +00:00
* @ return string
2003-04-15 10:41:13 +00:00
*/
function _compile_plugin_call ( $type , $name ) {
if ( isset ( $this -> _plugins [ $type ][ $name ])) {
/* plugin loaded */
if ( is_array ( $this -> _plugins [ $type ][ $name ][ 0 ])) {
2003-10-11 08:55:53 +00:00
return (( is_object ( $this -> _plugins [ $type ][ $name ][ 0 ][ 0 ])) ?
2003-07-31 13:51:28 +00:00
" \$ this->_plugins[' $type '][' $name '][0][0]-> " /* method callback */
: ( string )( $this -> _plugins [ $type ][ $name ][ 0 ][ 0 ]) . '::' /* class callback */
) . $this -> _plugins [ $type ][ $name ][ 0 ][ 1 ];
2003-04-15 10:41:13 +00:00
} else {
/* function callback */
return $this -> _plugins [ $type ][ $name ][ 0 ];
2003-10-11 08:55:53 +00:00
2003-04-15 10:41:13 +00:00
}
} else {
/* plugin not loaded -> auto-loadable-plugin */
return 'smarty_' . $type . '_' . $name ;
2003-10-11 08:55:53 +00:00
2003-04-15 10:41:13 +00:00
}
}
2003-10-11 08:55:53 +00:00
/**
* load pre - and post - filters
*/
2002-01-31 20:49:40 +00:00
function _load_filters ()
{
2002-04-16 20:04:06 +00:00
if ( count ( $this -> _plugins [ 'prefilter' ]) > 0 ) {
foreach ( $this -> _plugins [ 'prefilter' ] as $filter_name => $prefilter ) {
if ( $prefilter === false ) {
unset ( $this -> _plugins [ 'prefilter' ][ $filter_name ]);
2003-10-11 08:55:53 +00:00
$_params = array ( 'plugins' => array ( array ( 'prefilter' , $filter_name , null , null , false )));
require_once ( SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php' );
2003-06-16 15:18:38 +00:00
smarty_core_load_plugins ( $_params , $this );
2002-04-16 20:04:06 +00:00
}
}
}
if ( count ( $this -> _plugins [ 'postfilter' ]) > 0 ) {
foreach ( $this -> _plugins [ 'postfilter' ] as $filter_name => $postfilter ) {
if ( $postfilter === false ) {
unset ( $this -> _plugins [ 'postfilter' ][ $filter_name ]);
2003-10-11 08:55:53 +00:00
$_params = array ( 'plugins' => array ( array ( 'postfilter' , $filter_name , null , null , false )));
require_once ( SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php' );
2003-06-16 15:18:38 +00:00
smarty_core_load_plugins ( $_params , $this );
2002-04-16 20:04:06 +00:00
}
2002-01-31 20:49:40 +00:00
}
}
}
2002-04-16 20:04:06 +00:00
2002-01-31 20:49:40 +00:00
2003-11-18 23:35:05 +00:00
/**
* Quote subpattern references
*
* @ param string $string
* @ return string
*/
function _quote_replace ( $string )
{
return preg_replace ( '![\\$]\d!' , '\\\\\\0' , $string );
}
2003-10-11 08:55:53 +00:00
/**
* display Smarty syntax error
*
* @ param string $error_msg
* @ param integer $error_type
* @ param string $file
* @ param integer $line
*/
2002-12-24 17:07:43 +00:00
function _syntax_error ( $error_msg , $error_type = E_USER_ERROR , $file = null , $line = null )
2001-03-08 20:24:38 +00:00
{
2004-01-25 15:39:10 +00:00
$this -> _trigger_fatal_error ( " syntax error: $error_msg " , $this -> _current_file , $this -> _current_line_no , $file , $line , $error_type );
2001-03-08 20:24:38 +00:00
}
2003-06-18 23:01:42 +00:00
/**
* check if the compilation changes from cacheable to
* non - cacheable state with the beginning of the current
* plugin . return php - code to reflect the transition .
* @ return string
*/
function _push_cacheable_state ( $type , $name ) {
$_cacheable = ! isset ( $this -> _plugins [ $type ][ $name ]) || $this -> _plugins [ $type ][ $name ][ 4 ];
if ( $_cacheable
2003-07-03 15:43:00 +00:00
|| 0 < $this -> _cacheable_state ++ ) return '' ;
2003-06-18 23:01:42 +00:00
if ( ! isset ( $this -> _cache_serial )) $this -> _cache_serial = md5 ( uniqid ( 'Smarty' ));
$_ret = 'if ($this->caching) { echo \'{nocache:'
. $this -> _cache_serial . '#' . $this -> _nocache_count
. '}\';}' ;
return $_ret ;
}
2003-10-11 08:55:53 +00:00
2003-06-18 23:01:42 +00:00
/**
* check if the compilation changes from non - cacheable to
* cacheable state with the end of the current plugin return
* php - code to reflect the transition .
* @ return string
*/
function _pop_cacheable_state ( $type , $name ) {
$_cacheable = ! isset ( $this -> _plugins [ $type ][ $name ]) || $this -> _plugins [ $type ][ $name ][ 4 ];
if ( $_cacheable
2003-07-03 15:43:00 +00:00
|| -- $this -> _cacheable_state > 0 ) return '' ;
2003-06-18 23:01:42 +00:00
return 'if ($this->caching) { echo \'{/nocache:'
. $this -> _cache_serial . '#' . ( $this -> _nocache_count ++ )
. '}\';}' ;
}
2003-12-08 10:44:21 +00:00
/**
* push opening tag - name , file - name and line - number on the tag - stack
* @ param : string the opening tag ' s name
*/
function _push_tag ( $open_tag )
{
array_push ( $this -> _tag_stack , array ( $open_tag , $this -> _current_line_no ));
}
/**
* pop closing tag - name
* raise an error if this stack - top doesn ' t match with the closing tag
* @ param : string the closing tag ' s name
* @ return : string the opening tag ' s name
*/
function _pop_tag ( $close_tag )
{
$message = '' ;
if ( count ( $this -> _tag_stack ) > 0 ) {
list ( $_open_tag , $_line_no ) = array_pop ( $this -> _tag_stack );
if ( $close_tag == $_open_tag ) {
return $_open_tag ;
}
if ( $close_tag == 'if' && ( $_open_tag == 'else' || $_open_tag == 'elseif' )) {
return $this -> _pop_tag ( $close_tag );
}
if ( $close_tag == 'section' && $_open_tag == 'sectionelse' ) {
$this -> _pop_tag ( $close_tag );
return $_open_tag ;
}
if ( $close_tag == 'foreach' && $_open_tag == 'foreachelse' ) {
$this -> _pop_tag ( $close_tag );
return $_open_tag ;
}
$message = " expected { / $_open_tag } (opened line $_line_no ). " ;
}
$this -> _syntax_error ( " mismatched tag { / $close_tag }. $message " ,
E_USER_ERROR , __FILE__ , __LINE__ );
}
2001-03-02 21:38:42 +00:00
}
2003-01-30 16:48:55 +00:00
/**
* compare to values by their string length
*
* @ access private
2003-02-16 05:09:19 +00:00
* @ param string $a
* @ param string $b
2003-04-20 21:12:13 +00:00
* @ return 0 |- 1 | 1
2003-01-30 16:48:55 +00:00
*/
function _smarty_sort_length ( $a , $b )
{
2003-10-11 08:55:53 +00:00
if ( $a == $b )
return 0 ;
2003-01-30 16:48:55 +00:00
2003-10-11 08:55:53 +00:00
if ( strlen ( $a ) == strlen ( $b ))
return ( $a > $b ) ? - 1 : 1 ;
2003-01-30 16:48:55 +00:00
2003-10-11 08:55:53 +00:00
return ( strlen ( $a ) > strlen ( $b )) ? - 1 : 1 ;
2003-01-30 16:48:55 +00:00
}
2001-06-15 18:55:28 +00:00
/* vim: set et: */
2001-03-02 21:38:42 +00:00
?>