2009-12-29 20:12:51 +00:00
< ? php
2012-06-09 14:00:57 +00:00
2009-12-29 20:12:51 +00:00
/**
2010-02-27 23:28:14 +00:00
* Smarty Internal Plugin Smarty Template Compiler Base
2011-03-28 22:18:39 +00:00
*
2010-02-27 23:28:14 +00:00
* This file contains the basic classes and methodes for compiling Smarty templates with lexer / parser
2011-03-28 22:18:39 +00:00
*
2010-02-27 23:28:14 +00:00
* @ package Smarty
* @ subpackage Compiler
2011-03-28 22:18:39 +00:00
* @ author Uwe Tews
2010-02-27 23:28:14 +00:00
*/
2010-08-17 15:39:51 +00:00
2009-12-29 20:12:51 +00:00
/**
2011-09-16 14:19:56 +00:00
* Main abstract compiler class
*
* @ package Smarty
* @ subpackage Compiler
2010-02-27 23:28:14 +00:00
*/
2011-09-16 14:19:56 +00:00
abstract class Smarty_Internal_TemplateCompilerBase {
/**
* hash for nocache sections
*
* @ var mixed
*/
2011-03-28 22:18:39 +00:00
private $nocache_hash = null ;
2012-06-09 14:00:57 +00:00
2011-09-16 14:19:56 +00:00
/**
* suppress generation of nocache code
*
* @ var bool
*/
2011-03-28 22:18:39 +00:00
public $suppressNocacheProcessing = false ;
2012-06-09 14:00:57 +00:00
2011-09-16 14:19:56 +00:00
/**
* suppress generation of merged template code
*
* @ var bool
*/
public $suppressMergedTemplates = false ;
2012-06-09 14:00:57 +00:00
2011-09-16 14:19:56 +00:00
/**
* compile tag objects
*
* @ var array
*/
public static $_tag_objects = array ();
2012-06-09 14:00:57 +00:00
2011-09-16 14:19:56 +00:00
/**
* tag stack
*
* @ var array
*/
2011-03-28 22:18:39 +00:00
public $_tag_stack = array ();
2012-06-09 14:00:57 +00:00
2011-09-16 14:19:56 +00:00
/**
* current template
*
* @ var Smarty_Internal_Template
*/
2010-02-09 21:20:17 +00:00
public $template = null ;
2012-06-09 14:00:57 +00:00
2011-09-16 14:19:56 +00:00
/**
* merged templates
*
* @ var array
*/
public $merged_templates = array ();
2012-06-09 14:00:57 +00:00
2011-09-16 14:19:56 +00:00
/**
* flag when compiling { block }
*
* @ var bool
*/
public $inheritance = false ;
2012-06-09 14:00:57 +00:00
2011-09-16 14:19:56 +00:00
/**
* plugins loaded by default plugin handler
*
* @ var array
*/
public $default_handler_plugins = array ();
2012-06-09 14:00:57 +00:00
2011-09-16 14:19:56 +00:00
/**
* saved preprocessed modifier list
*
* @ var mixed
*/
public $default_modifier_list = null ;
2012-06-09 14:00:57 +00:00
2011-09-16 14:19:56 +00:00
/**
* force compilation of complete template as nocache
* @ var boolean
*/
public $forceNocache = false ;
2012-06-09 14:00:57 +00:00
2011-09-16 14:19:56 +00:00
/**
* suppress Smarty header code in compiled template
* @ var bool
*/
public $suppressHeader = false ;
2012-06-09 14:00:57 +00:00
2011-09-16 14:19:56 +00:00
/**
* suppress template property header code in compiled template
* @ var bool
*/
public $suppressTemplatePropertyHeader = false ;
2012-06-09 14:00:57 +00:00
2011-09-16 14:19:56 +00:00
/**
* flag if compiled template file shall we written
* @ var bool
*/
public $write_compiled_code = true ;
2012-06-09 14:00:57 +00:00
2011-09-28 15:56:01 +00:00
/**
* flag if currently a template function is compiled
* @ var bool
*/
public $compiles_template_function = false ;
2012-06-09 14:00:57 +00:00
2011-09-28 15:56:01 +00:00
/**
* called subfuntions from template function
* @ var array
*/
public $called_functions = array ();
2012-06-09 14:00:57 +00:00
2011-09-16 14:19:56 +00:00
/**
* flags for used modifier plugins
* @ var array
*/
public $modifier_plugins = array ();
2012-06-09 14:00:57 +00:00
2012-03-03 14:10:39 +00:00
/**
* type of already compiled modifier
* @ var array
*/
public $known_modifier_type = array ();
2009-12-29 20:12:51 +00:00
/**
2010-02-27 23:28:14 +00:00
* Initialize compiler
*/
2012-06-09 14:00:57 +00:00
public function __construct () {
2009-12-29 20:12:51 +00:00
$this -> nocache_hash = str_replace ( '.' , '-' , uniqid ( rand (), true ));
2011-03-28 22:18:39 +00:00
}
2011-01-14 18:39:16 +00:00
2009-12-30 14:26:42 +00:00
/**
2011-09-16 14:19:56 +00:00
* Method to compile a Smarty template
2011-03-28 22:18:39 +00:00
*
2011-09-16 14:19:56 +00:00
* @ param Smarty_Internal_Template $template template object to compile
2010-02-27 23:28:14 +00:00
* @ return bool true if compiling succeeded , false if it failed
*/
2012-06-09 14:00:57 +00:00
public function compileTemplate ( Smarty_Internal_Template $template ) {
2010-01-07 19:33:18 +00:00
if ( empty ( $template -> properties [ 'nocache_hash' ])) {
$template -> properties [ 'nocache_hash' ] = $this -> nocache_hash ;
} else {
$this -> nocache_hash = $template -> properties [ 'nocache_hash' ];
2011-03-28 22:18:39 +00:00
}
2009-12-30 14:26:42 +00:00
// flag for nochache sections
$this -> nocache = false ;
2011-03-28 22:18:39 +00:00
$this -> tag_nocache = false ;
2009-12-30 14:26:42 +00:00
// save template object in compiler class
$this -> template = $template ;
2011-10-04 18:58:17 +00:00
// reset has noche code flag
2011-11-21 00:37:33 +00:00
$this -> template -> has_nocache_code = false ;
2011-09-16 14:19:56 +00:00
$this -> smarty -> _current_file = $saved_filepath = $this -> template -> source -> filepath ;
2009-12-30 14:26:42 +00:00
// template header code
$template_header = '' ;
2011-09-16 14:19:56 +00:00
if ( ! $this -> suppressHeader ) {
2009-12-30 14:26:42 +00:00
$template_header .= " <?php /* Smarty version " . Smarty :: SMARTY_VERSION . " , created on " . strftime ( " %Y-%m-%d %H:%M:%S " ) . " \n " ;
2011-09-16 14:19:56 +00:00
$template_header .= " compiled from \" " . $this -> template -> source -> filepath . " \" */ ?> \n " ;
2011-03-28 22:18:39 +00:00
}
2009-12-29 20:12:51 +00:00
2009-12-30 14:26:42 +00:00
do {
// flag for aborting current and start recompile
2011-03-28 22:18:39 +00:00
$this -> abort_and_recompile = false ;
2009-12-30 14:26:42 +00:00
// get template source
2011-09-16 14:19:56 +00:00
$_content = $template -> source -> content ;
2009-12-30 14:26:42 +00:00
// run prefilter if required
if ( isset ( $this -> smarty -> autoload_filters [ 'pre' ]) || isset ( $this -> smarty -> registered_filters [ 'pre' ])) {
2012-03-27 14:44:46 +00:00
$_content = Smarty_Internal_Filter_Handler :: runFilter ( 'pre' , $_content , $template );
2011-03-28 22:18:39 +00:00
}
2009-12-30 14:26:42 +00:00
// on empty template just return header
if ( $_content == '' ) {
2011-09-16 14:19:56 +00:00
if ( $this -> suppressTemplatePropertyHeader ) {
$code = '' ;
2009-12-29 20:12:51 +00:00
} else {
2011-09-16 14:19:56 +00:00
$code = $template_header . $template -> createTemplateCodeFrame ();
2011-03-28 22:18:39 +00:00
}
2011-09-16 14:19:56 +00:00
return $code ;
2011-03-28 22:18:39 +00:00
}
2009-12-30 14:26:42 +00:00
// call compiler
$_compiled_code = $this -> doCompile ( $_content );
2011-03-01 19:47:44 +00:00
} while ( $this -> abort_and_recompile );
2011-09-16 14:19:56 +00:00
$this -> template -> source -> filepath = $saved_filepath ;
// free memory
unset ( $this -> parser -> root_buffer , $this -> parser -> current_buffer , $this -> parser , $this -> lex , $this -> template );
self :: $_tag_objects = array ();
2010-03-31 16:23:01 +00:00
// return compiled code to template object
2011-09-16 14:19:56 +00:00
$merged_code = '' ;
2011-12-28 18:51:20 +00:00
if ( ! $this -> suppressMergedTemplates && ! empty ( $this -> merged_templates )) {
2011-09-16 14:19:56 +00:00
foreach ( $this -> merged_templates as $code ) {
$merged_code .= $code ;
}
2011-12-28 18:51:20 +00:00
// run postfilter if required on merged code
if ( isset ( $this -> smarty -> autoload_filters [ 'post' ]) || isset ( $this -> smarty -> registered_filters [ 'post' ])) {
$merged_code = Smarty_Internal_Filter_Handler :: runFilter ( 'post' , $merged_code , $template );
}
}
// run postfilter if required on compiled template code
if ( isset ( $this -> smarty -> autoload_filters [ 'post' ]) || isset ( $this -> smarty -> registered_filters [ 'post' ])) {
$_compiled_code = Smarty_Internal_Filter_Handler :: runFilter ( 'post' , $_compiled_code , $template );
2011-09-16 14:19:56 +00:00
}
if ( $this -> suppressTemplatePropertyHeader ) {
$code = $_compiled_code . $merged_code ;
2009-12-30 14:26:42 +00:00
} else {
2011-09-16 14:19:56 +00:00
$code = $template_header . $template -> createTemplateCodeFrame ( $_compiled_code ) . $merged_code ;
2011-03-28 22:18:39 +00:00
}
2011-09-16 14:19:56 +00:00
return $code ;
2011-03-28 22:18:39 +00:00
}
2009-12-29 20:12:51 +00:00
2009-12-30 14:26:42 +00:00
/**
2010-02-27 23:28:14 +00:00
* Compile Tag
2011-03-28 22:18:39 +00:00
*
2010-02-27 23:28:14 +00:00
* This is a call back from the lexer / parser
* It executes the required compile plugin for the Smarty tag
2011-03-28 22:18:39 +00:00
*
2011-09-16 14:19:56 +00:00
* @ param string $tag tag name
* @ param array $args array with tag attributes
* @ param array $parameter array with compilation parameter
2010-02-27 23:28:14 +00:00
* @ return string compiled code
*/
2012-06-09 14:00:57 +00:00
public function compileTag ( $tag , $args , $parameter = array ()) {
2009-12-30 14:26:42 +00:00
// $args contains the attributes parsed and compiled by the lexer/parser
// assume that tag does compile into code, but creates no HTML output
$this -> has_code = true ;
2010-11-11 21:34:36 +00:00
$this -> has_output = false ;
// log tag/attributes
if ( isset ( $this -> smarty -> get_used_tags ) && $this -> smarty -> get_used_tags ) {
2011-09-16 14:19:56 +00:00
$this -> template -> used_tags [] = array ( $tag , $args );
2011-03-28 22:18:39 +00:00
}
2011-09-16 14:19:56 +00:00
// check nocache option flag
2012-06-09 14:00:57 +00:00
if ( in_array ( " 'nocache' " , $args ) || in_array ( array ( 'nocache' => 'true' ), $args )
|| in_array ( array ( 'nocache' => '"true"' ), $args ) || in_array ( array ( 'nocache' => " 'true' " ), $args )) {
2011-09-16 14:19:56 +00:00
$this -> tag_nocache = true ;
2010-11-11 21:34:36 +00:00
}
2009-12-30 14:26:42 +00:00
// compile the smarty tag (required compile classes to compile the tag are autoloaded)
2010-11-11 21:34:36 +00:00
if (( $_output = $this -> callTagCompiler ( $tag , $args , $parameter )) === false ) {
2010-05-11 17:01:08 +00:00
if ( isset ( $this -> smarty -> template_functions [ $tag ])) {
// template defined by {template} tag
2010-11-11 21:34:36 +00:00
$args [ '_attr' ][ 'name' ] = " ' " . $tag . " ' " ;
$_output = $this -> callTagCompiler ( 'call' , $args , $parameter );
2011-03-28 22:18:39 +00:00
}
}
2010-05-11 17:01:08 +00:00
if ( $_output !== false ) {
2009-12-30 14:26:42 +00:00
if ( $_output !== true ) {
// did we get compiled code
if ( $this -> has_code ) {
// Does it create output?
if ( $this -> has_output ) {
$_output .= " \n " ;
2011-03-28 22:18:39 +00:00
}
2009-12-30 14:26:42 +00:00
// return compiled code
return $_output ;
2011-03-28 22:18:39 +00:00
}
}
2009-12-30 14:26:42 +00:00
// tag did not produce compiled code
return '' ;
} else {
2010-11-11 21:34:36 +00:00
// map_named attributes
if ( isset ( $args [ '_attr' ])) {
foreach ( $args [ '_attr' ] as $key => $attribute ) {
if ( is_array ( $attribute )) {
$args = array_merge ( $args , $attribute );
2011-03-28 22:18:39 +00:00
}
}
}
2009-12-30 14:26:42 +00:00
// not an internal compiler tag
2010-04-30 14:00:26 +00:00
if ( strlen ( $tag ) < 6 || substr ( $tag , - 5 ) != 'close' ) {
2009-12-30 14:26:42 +00:00
// check if tag is a registered object
2010-11-11 21:34:36 +00:00
if ( isset ( $this -> smarty -> registered_objects [ $tag ]) && isset ( $parameter [ 'object_methode' ])) {
$methode = $parameter [ 'object_methode' ];
2009-12-30 14:26:42 +00:00
if ( ! in_array ( $methode , $this -> smarty -> registered_objects [ $tag ][ 3 ]) &&
2012-06-09 14:00:57 +00:00
( empty ( $this -> smarty -> registered_objects [ $tag ][ 1 ]) || in_array ( $methode , $this -> smarty -> registered_objects [ $tag ][ 1 ]))) {
2010-11-11 21:34:36 +00:00
return $this -> callTagCompiler ( 'private_object_function' , $args , $parameter , $tag , $methode );
2009-12-30 14:26:42 +00:00
} elseif ( in_array ( $methode , $this -> smarty -> registered_objects [ $tag ][ 3 ])) {
2010-11-11 21:34:36 +00:00
return $this -> callTagCompiler ( 'private_object_block_function' , $args , $parameter , $tag , $methode );
2009-12-30 14:26:42 +00:00
} else {
2012-06-09 14:00:57 +00:00
return $this -> trigger_template_error ( 'unallowed methode "' . $methode . '" in registered object "' . $tag . '"' , $this -> lex -> taglineno );
2011-03-28 22:18:39 +00:00
}
}
2009-12-30 14:26:42 +00:00
// check if tag is registered
2011-09-16 14:19:56 +00:00
foreach ( array ( Smarty :: PLUGIN_COMPILER , Smarty :: PLUGIN_FUNCTION , Smarty :: PLUGIN_BLOCK ) as $plugin_type ) {
if ( isset ( $this -> smarty -> registered_plugins [ $plugin_type ][ $tag ])) {
2009-12-30 14:26:42 +00:00
// if compiler function plugin call it now
2011-09-16 14:19:56 +00:00
if ( $plugin_type == Smarty :: PLUGIN_COMPILER ) {
2010-11-11 21:34:36 +00:00
$new_args = array ();
2011-09-18 18:36:26 +00:00
foreach ( $args as $key => $mixed ) {
2012-06-09 14:00:57 +00:00
if ( is_array ( $mixed )) {
$new_args = array_merge ( $new_args , $mixed );
2011-09-18 18:36:26 +00:00
} else {
2012-06-09 14:00:57 +00:00
$new_args [ $key ] = $mixed ;
2011-09-18 18:36:26 +00:00
}
2011-03-28 22:18:39 +00:00
}
2011-09-16 14:19:56 +00:00
if ( ! $this -> smarty -> registered_plugins [ $plugin_type ][ $tag ][ 1 ]) {
2009-12-30 14:26:42 +00:00
$this -> tag_nocache = true ;
2011-03-28 22:18:39 +00:00
}
2011-09-16 14:19:56 +00:00
$function = $this -> smarty -> registered_plugins [ $plugin_type ][ $tag ][ 0 ];
2010-07-01 19:57:56 +00:00
if ( ! is_array ( $function )) {
2010-11-11 21:34:36 +00:00
return $function ( $new_args , $this );
2010-07-01 19:57:56 +00:00
} else if ( is_object ( $function [ 0 ])) {
2011-09-16 14:19:56 +00:00
return $this -> smarty -> registered_plugins [ $plugin_type ][ $tag ][ 0 ][ 0 ] -> $function [ 1 ]( $new_args , $this );
2010-07-01 19:57:56 +00:00
} else {
2011-09-16 14:19:56 +00:00
return call_user_func_array ( $function , array ( $new_args , $this ));
2011-03-28 22:18:39 +00:00
}
}
2009-12-30 14:26:42 +00:00
// compile registered function or block function
2011-09-16 14:19:56 +00:00
if ( $plugin_type == Smarty :: PLUGIN_FUNCTION || $plugin_type == Smarty :: PLUGIN_BLOCK ) {
return $this -> callTagCompiler ( 'private_registered_' . $plugin_type , $args , $parameter , $tag );
2011-03-28 22:18:39 +00:00
}
}
}
2009-12-30 14:26:42 +00:00
// check plugins from plugins folder
foreach ( $this -> smarty -> plugin_search_order as $plugin_type ) {
2011-09-16 14:19:56 +00:00
if ( $plugin_type == Smarty :: PLUGIN_BLOCK && $this -> smarty -> loadPlugin ( 'smarty_compiler_' . $tag ) && ( ! isset ( $this -> smarty -> security_policy ) || $this -> smarty -> security_policy -> isTrustedTag ( $tag , $this ))) {
2009-12-29 20:12:51 +00:00
$plugin = 'smarty_compiler_' . $tag ;
2010-02-09 21:20:17 +00:00
if ( is_callable ( $plugin )) {
2011-09-16 14:19:56 +00:00
// convert arguments format for old compiler plugins
2010-12-31 13:47:12 +00:00
$new_args = array ();
2011-09-18 18:36:26 +00:00
foreach ( $args as $key => $mixed ) {
2012-06-09 14:00:57 +00:00
if ( is_array ( $mixed )) {
$new_args = array_merge ( $new_args , $mixed );
2011-09-18 18:36:26 +00:00
} else {
2012-06-09 14:00:57 +00:00
$new_args [ $key ] = $mixed ;
2011-09-18 18:36:26 +00:00
}
2011-03-28 22:18:39 +00:00
}
2010-12-31 13:47:12 +00:00
return $plugin ( $new_args , $this -> smarty );
2011-03-28 22:18:39 +00:00
}
2009-12-29 20:12:51 +00:00
if ( class_exists ( $plugin , false )) {
2010-02-27 23:28:14 +00:00
$plugin_object = new $plugin ;
if ( method_exists ( $plugin_object , 'compile' )) {
return $plugin_object -> compile ( $args , $this );
2011-03-28 22:18:39 +00:00
}
}
2010-08-13 10:39:51 +00:00
throw new SmartyException ( " Plugin \" { $tag } \" not callable " );
2009-12-30 14:26:42 +00:00
} else {
2010-01-01 12:07:36 +00:00
if ( $function = $this -> getPlugin ( $tag , $plugin_type )) {
2012-06-09 14:00:57 +00:00
if ( ! isset ( $this -> smarty -> security_policy ) || $this -> smarty -> security_policy -> isTrustedTag ( $tag , $this )) {
2011-09-16 14:19:56 +00:00
return $this -> callTagCompiler ( 'private_' . $plugin_type . '_plugin' , $args , $parameter , $tag , $function );
}
}
}
}
if ( is_callable ( $this -> smarty -> default_plugin_handler_func )) {
$found = false ;
// look for already resolved tags
foreach ( $this -> smarty -> plugin_search_order as $plugin_type ) {
if ( isset ( $this -> default_handler_plugins [ $plugin_type ][ $tag ])) {
$found = true ;
break ;
}
}
if ( ! $found ) {
// call default handler
foreach ( $this -> smarty -> plugin_search_order as $plugin_type ) {
if ( $this -> getPluginFromDefaultHandler ( $tag , $plugin_type )) {
$found = true ;
break ;
}
}
}
if ( $found ) {
// if compiler function plugin call it now
if ( $plugin_type == Smarty :: PLUGIN_COMPILER ) {
$new_args = array ();
foreach ( $args as $mixed ) {
$new_args = array_merge ( $new_args , $mixed );
}
$function = $this -> default_handler_plugins [ $plugin_type ][ $tag ][ 0 ];
if ( ! is_array ( $function )) {
return $function ( $new_args , $this );
} else if ( is_object ( $function [ 0 ])) {
return $this -> default_handler_plugins [ $plugin_type ][ $tag ][ 0 ][ 0 ] -> $function [ 1 ]( $new_args , $this );
} else {
return call_user_func_array ( $function , array ( $new_args , $this ));
}
} else {
return $this -> callTagCompiler ( 'private_registered_' . $plugin_type , $args , $parameter , $tag );
2011-03-28 22:18:39 +00:00
}
}
}
2009-12-30 14:26:42 +00:00
} else {
// compile closing tag of block function
2011-03-28 22:18:39 +00:00
$base_tag = substr ( $tag , 0 , - 5 );
2009-12-30 14:26:42 +00:00
// check if closing tag is a registered object
2010-11-11 21:34:36 +00:00
if ( isset ( $this -> smarty -> registered_objects [ $base_tag ]) && isset ( $parameter [ 'object_methode' ])) {
$methode = $parameter [ 'object_methode' ];
2009-12-30 14:26:42 +00:00
if ( in_array ( $methode , $this -> smarty -> registered_objects [ $base_tag ][ 3 ])) {
2010-11-11 21:34:36 +00:00
return $this -> callTagCompiler ( 'private_object_block_function' , $args , $parameter , $tag , $methode );
2009-12-30 14:26:42 +00:00
} else {
2012-06-09 14:00:57 +00:00
return $this -> trigger_template_error ( 'unallowed closing tag methode "' . $methode . '" in registered object "' . $base_tag . '"' , $this -> lex -> taglineno );
2011-03-28 22:18:39 +00:00
}
}
2009-12-30 14:26:42 +00:00
// registered block tag ?
2011-09-16 14:19:56 +00:00
if ( isset ( $this -> smarty -> registered_plugins [ Smarty :: PLUGIN_BLOCK ][ $base_tag ]) || isset ( $this -> default_handler_plugins [ Smarty :: PLUGIN_BLOCK ][ $base_tag ])) {
2010-11-11 21:34:36 +00:00
return $this -> callTagCompiler ( 'private_registered_block' , $args , $parameter , $tag );
2011-03-28 22:18:39 +00:00
}
2009-12-30 14:26:42 +00:00
// block plugin?
2010-11-11 21:34:36 +00:00
if ( $function = $this -> getPlugin ( $base_tag , Smarty :: PLUGIN_BLOCK )) {
return $this -> callTagCompiler ( 'private_block_plugin' , $args , $parameter , $tag , $function );
2011-03-28 22:18:39 +00:00
}
2012-06-09 14:00:57 +00:00
// registered compiler plugin ?
if ( isset ( $this -> smarty -> registered_plugins [ Smarty :: PLUGIN_COMPILER ][ $tag ])) {
// if compiler function plugin call it now
$args = array ();
if ( ! $this -> smarty -> registered_plugins [ Smarty :: PLUGIN_COMPILER ][ $tag ][ 1 ]) {
$this -> tag_nocache = true ;
}
$function = $this -> smarty -> registered_plugins [ Smarty :: PLUGIN_COMPILER ][ $tag ][ 0 ];
if ( ! is_array ( $function )) {
return $function ( $args , $this );
} else if ( is_object ( $function [ 0 ])) {
return $this -> smarty -> registered_plugins [ Smarty :: PLUGIN_COMPILER ][ $tag ][ 0 ][ 0 ] -> $function [ 1 ]( $args , $this );
} else {
return call_user_func_array ( $function , array ( $args , $this ));
}
}
2010-11-13 04:10:52 +00:00
if ( $this -> smarty -> loadPlugin ( 'smarty_compiler_' . $tag )) {
2009-12-30 14:26:42 +00:00
$plugin = 'smarty_compiler_' . $tag ;
2010-02-09 21:20:17 +00:00
if ( is_callable ( $plugin )) {
2010-02-27 23:28:14 +00:00
return $plugin ( $args , $this -> smarty );
2011-03-28 22:18:39 +00:00
}
2009-12-30 14:26:42 +00:00
if ( class_exists ( $plugin , false )) {
2010-02-27 23:28:14 +00:00
$plugin_object = new $plugin ;
if ( method_exists ( $plugin_object , 'compile' )) {
return $plugin_object -> compile ( $args , $this );
2011-03-28 22:18:39 +00:00
}
}
2010-08-13 10:39:51 +00:00
throw new SmartyException ( " Plugin \" { $tag } \" not callable " );
2011-03-28 22:18:39 +00:00
}
}
2012-06-09 14:00:57 +00:00
$this -> trigger_template_error ( " unknown tag \" " . $tag . " \" " , $this -> lex -> taglineno );
2011-03-28 22:18:39 +00:00
}
}
2009-12-30 14:26:42 +00:00
/**
2010-02-27 23:28:14 +00:00
* lazy loads internal compile plugin for tag and calls the compile methode
2011-03-28 22:18:39 +00:00
*
2010-02-27 23:28:14 +00:00
* compile objects cached for reuse .
* class name format : Smarty_Internal_Compile_TagName
* plugin filename format : Smarty_Internal_Tagname . php
2011-03-28 22:18:39 +00:00
*
2011-09-16 14:19:56 +00:00
* @ param string $tag tag name
* @ param array $args list of tag attributes
* @ param mixed $param1 optional parameter
* @ param mixed $param2 optional parameter
* @ param mixed $param3 optional parameter
2010-02-27 23:28:14 +00:00
* @ return string compiled code
*/
2012-06-09 14:00:57 +00:00
public function callTagCompiler ( $tag , $args , $param1 = null , $param2 = null , $param3 = null ) {
2009-12-30 14:26:42 +00:00
// re-use object if already exists
if ( isset ( self :: $_tag_objects [ $tag ])) {
// compile this tag
2010-02-27 23:28:14 +00:00
return self :: $_tag_objects [ $tag ] -> compile ( $args , $this , $param1 , $param2 , $param3 );
2011-03-28 22:18:39 +00:00
}
2009-12-30 14:26:42 +00:00
// lazy load internal compiler plugin
$class_name = 'Smarty_Internal_Compile_' . $tag ;
2010-11-13 04:10:52 +00:00
if ( $this -> smarty -> loadPlugin ( $class_name )) {
2011-09-16 14:19:56 +00:00
// check if tag allowed by security
if ( ! isset ( $this -> smarty -> security_policy ) || $this -> smarty -> security_policy -> isTrustedTag ( $tag , $this )) {
2012-06-09 14:00:57 +00:00
// use plugin if found
self :: $_tag_objects [ $tag ] = new $class_name ;
// compile this tag
return self :: $_tag_objects [ $tag ] -> compile ( $args , $this , $param1 , $param2 , $param3 );
2011-09-16 14:19:56 +00:00
}
2011-03-28 22:18:39 +00:00
}
2009-12-30 14:26:42 +00:00
// no internal compile plugin for this tag
return false ;
2011-03-28 22:18:39 +00:00
}
2009-12-29 20:12:51 +00:00
2009-12-30 14:26:42 +00:00
/**
2010-02-27 23:28:14 +00:00
* Check for plugins and return function name
2011-03-28 22:18:39 +00:00
*
2011-09-16 14:19:56 +00:00
* @ param string $pugin_name name of plugin or function
* @ param string $plugin_type type of plugin
2010-02-27 23:28:14 +00:00
* @ return string call name of function
*/
2012-06-09 14:00:57 +00:00
public function getPlugin ( $plugin_name , $plugin_type ) {
2010-02-05 17:03:22 +00:00
$function = null ;
if ( $this -> template -> caching && ( $this -> nocache || $this -> tag_nocache )) {
2011-09-16 14:19:56 +00:00
if ( isset ( $this -> template -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ])) {
$function = $this -> template -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ];
} else if ( isset ( $this -> template -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ])) {
$this -> template -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ] = $this -> template -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ];
$function = $this -> template -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ];
2011-03-28 22:18:39 +00:00
}
2010-02-05 17:03:22 +00:00
} else {
2011-09-16 14:19:56 +00:00
if ( isset ( $this -> template -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ])) {
$function = $this -> template -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ];
} else if ( isset ( $this -> template -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ])) {
$this -> template -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ] = $this -> template -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ];
$function = $this -> template -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ];
2011-03-28 22:18:39 +00:00
}
}
2010-02-05 17:03:22 +00:00
if ( isset ( $function )) {
2011-09-16 14:19:56 +00:00
if ( $plugin_type == 'modifier' ) {
$this -> modifier_plugins [ $plugin_name ] = true ;
2011-03-28 22:18:39 +00:00
}
2010-02-05 17:03:22 +00:00
return $function ;
2011-03-28 22:18:39 +00:00
}
2009-12-30 14:26:42 +00:00
// loop through plugin dirs and find the plugin
2011-09-16 14:19:56 +00:00
$function = 'smarty_' . $plugin_type . '_' . $plugin_name ;
$file = $this -> smarty -> loadPlugin ( $function , false );
if ( is_string ( $file )) {
2009-12-31 16:38:12 +00:00
if ( $this -> template -> caching && ( $this -> nocache || $this -> tag_nocache )) {
2011-09-16 14:19:56 +00:00
$this -> template -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'file' ] = $file ;
$this -> template -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ] = $function ;
2009-12-30 14:26:42 +00:00
} else {
2011-09-16 14:19:56 +00:00
$this -> template -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'file' ] = $file ;
$this -> template -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ] = $function ;
2011-03-28 22:18:39 +00:00
}
2011-09-16 14:19:56 +00:00
if ( $plugin_type == 'modifier' ) {
$this -> modifier_plugins [ $plugin_name ] = true ;
2011-03-28 22:18:39 +00:00
}
2010-02-05 17:03:22 +00:00
return $function ;
2011-03-28 22:18:39 +00:00
}
2010-02-05 17:03:22 +00:00
if ( is_callable ( $function )) {
2010-01-01 12:07:36 +00:00
// plugin function is defined in the script
2010-02-05 17:03:22 +00:00
return $function ;
2011-03-28 22:18:39 +00:00
}
2009-12-30 14:26:42 +00:00
return false ;
2011-03-28 22:18:39 +00:00
}
2011-09-16 14:19:56 +00:00
/**
* Check for plugins by default plugin handler
*
* @ param string $tag name of tag
* @ param string $plugin_type type of plugin
* @ return boolean true if found
*/
2012-06-09 14:00:57 +00:00
public function getPluginFromDefaultHandler ( $tag , $plugin_type ) {
2011-09-16 14:19:56 +00:00
$callback = null ;
$script = null ;
2012-02-07 21:55:37 +00:00
$cacheable = true ;
2011-09-16 14:19:56 +00:00
$result = call_user_func_array (
2012-06-09 14:00:57 +00:00
$this -> smarty -> default_plugin_handler_func , array ( $tag , $plugin_type , $this -> template , & $callback , & $script , & $cacheable )
2011-09-16 14:19:56 +00:00
);
if ( $result ) {
2012-02-07 21:55:37 +00:00
$this -> tag_nocache = $this -> tag_nocache || ! $cacheable ;
2011-09-16 14:19:56 +00:00
if ( $script !== null ) {
if ( is_file ( $script )) {
if ( $this -> template -> caching && ( $this -> nocache || $this -> tag_nocache )) {
$this -> template -> required_plugins [ 'nocache' ][ $tag ][ $plugin_type ][ 'file' ] = $script ;
$this -> template -> required_plugins [ 'nocache' ][ $tag ][ $plugin_type ][ 'function' ] = $callback ;
} else {
$this -> template -> required_plugins [ 'compiled' ][ $tag ][ $plugin_type ][ 'file' ] = $script ;
$this -> template -> required_plugins [ 'compiled' ][ $tag ][ $plugin_type ][ 'function' ] = $callback ;
}
include_once $script ;
2012-06-09 14:00:57 +00:00
} else {
2011-11-29 17:47:37 +00:00
$this -> trigger_template_error ( " Default plugin handler: Returned script file \" { $script } \" for \" { $tag } \" not found " );
2011-09-16 14:19:56 +00:00
}
}
2011-11-29 17:47:37 +00:00
if ( ! is_string ( $callback ) && ! ( is_array ( $callback ) && is_string ( $callback [ 0 ]) && is_string ( $callback [ 1 ]))) {
$this -> trigger_template_error ( " Default plugin handler: Returned callback for \" { $tag } \" must be a static function name or array of class and function name " );
}
2011-09-16 14:19:56 +00:00
if ( is_callable ( $callback )) {
$this -> default_handler_plugins [ $plugin_type ][ $tag ] = array ( $callback , true , array ());
return true ;
} else {
2011-11-29 17:47:37 +00:00
$this -> trigger_template_error ( " Default plugin handler: Returned callback for \" { $tag } \" not callable " );
2011-09-16 14:19:56 +00:00
}
}
return false ;
}
2009-12-30 14:26:42 +00:00
/**
2010-02-27 23:28:14 +00:00
* Inject inline code for nocache template sections
2011-03-28 22:18:39 +00:00
*
2010-02-27 23:28:14 +00:00
* This method gets the content of each template element from the parser .
* If the content is compiled code and it should be not cached the code is injected
* into the rendered output .
2011-03-28 22:18:39 +00:00
*
2011-09-16 14:19:56 +00:00
* @ param string $content content of template element
2010-02-27 23:28:14 +00:00
* @ param boolean $is_code true if content is compiled code
* @ return string content
*/
2012-06-09 14:00:57 +00:00
public function processNocacheCode ( $content , $is_code ) {
2009-12-30 14:26:42 +00:00
// If the template is not evaluated and we have a nocache section and or a nocache tag
2010-01-09 19:23:35 +00:00
if ( $is_code && ! empty ( $content )) {
2009-12-30 14:26:42 +00:00
// generate replacement code
2011-09-16 14:19:56 +00:00
if (( ! ( $this -> template -> source -> recompiled ) || $this -> forceNocache ) && $this -> template -> caching && ! $this -> suppressNocacheProcessing &&
2012-06-09 14:00:57 +00:00
( $this -> nocache || $this -> tag_nocache || $this -> forceNocache == 2 )) {
2009-12-30 14:26:42 +00:00
$this -> template -> has_nocache_code = true ;
$_output = str_replace ( " ' " , " \ ' " , $content );
2012-04-08 12:08:48 +00:00
$_output = str_replace ( '\\\\' , '\\\\\\\\' , $_output );
2010-12-17 21:05:29 +00:00
$_output = str_replace ( " ^#^ " , " ' " , $_output );
2011-07-12 17:20:45 +00:00
$_output = " <?php echo '/*%%SmartyNocache: { $this -> nocache_hash } %%*/ " . $_output . " /*/%%SmartyNocache: { $this -> nocache_hash } %%*/';?> \n " ;
2009-12-30 14:26:42 +00:00
// make sure we include modifer plugins for nocache code
2011-09-16 14:19:56 +00:00
foreach ( $this -> modifier_plugins as $plugin_name => $dummy ) {
if ( isset ( $this -> template -> required_plugins [ 'compiled' ][ $plugin_name ][ 'modifier' ])) {
$this -> template -> required_plugins [ 'nocache' ][ $plugin_name ][ 'modifier' ] = $this -> template -> required_plugins [ 'compiled' ][ $plugin_name ][ 'modifier' ];
2011-03-28 22:18:39 +00:00
}
}
2009-12-29 20:12:51 +00:00
} else {
$_output = $content ;
2011-03-28 22:18:39 +00:00
}
2009-12-30 14:26:42 +00:00
} else {
$_output = $content ;
2011-03-28 22:18:39 +00:00
}
2011-11-21 00:37:33 +00:00
$this -> modifier_plugins = array ();
2010-01-09 19:23:35 +00:00
$this -> suppressNocacheProcessing = false ;
2010-05-07 13:08:46 +00:00
$this -> tag_nocache = false ;
2009-12-30 14:26:42 +00:00
return $_output ;
2011-03-28 22:18:39 +00:00
}
2011-09-16 14:19:56 +00:00
2009-12-30 14:26:42 +00:00
/**
2010-02-27 23:28:14 +00:00
* display compiler error messages without dying
2011-03-28 22:18:39 +00:00
*
2010-02-27 23:28:14 +00:00
* If parameter $args is empty it is a parser detected syntax error .
* In this case the parser is called to obtain information about expected tokens .
2011-03-28 22:18:39 +00:00
*
2010-02-27 23:28:14 +00:00
* If parameter $args contains a string this is used as error message
2011-03-28 22:18:39 +00:00
*
2011-09-16 14:19:56 +00:00
* @ param string $args individual error message or null
* @ param string $line line - number
* @ throws SmartyCompilerException when an unexpected token is found
2010-02-27 23:28:14 +00:00
*/
2012-06-09 14:00:57 +00:00
public function trigger_template_error ( $args = null , $line = null ) {
2009-12-30 14:26:42 +00:00
// get template source line which has error
if ( ! isset ( $line )) {
$line = $this -> lex -> line ;
2011-03-28 22:18:39 +00:00
}
2009-12-30 14:26:42 +00:00
$match = preg_split ( " / \n / " , $this -> lex -> data );
2012-06-09 14:00:57 +00:00
$error_text = 'Syntax Error in template "' . $this -> template -> source -> filepath . '" on line ' . $line . ' "' . htmlspecialchars ( trim ( preg_replace ( '![\t\r\n]+!' , ' ' , $match [ $line - 1 ]))) . '" ' ;
2009-12-30 14:26:42 +00:00
if ( isset ( $args )) {
// individual error message
$error_text .= $args ;
} else {
// expected token from parser
2012-06-09 14:00:57 +00:00
$error_text .= ' - Unexpected "' . $this -> lex -> value . '"' ;
if ( count ( $this -> parser -> yy_get_expected_tokens ( $this -> parser -> yymajor )) <= 4 ) {
2011-09-16 14:19:56 +00:00
foreach ( $this -> parser -> yy_get_expected_tokens ( $this -> parser -> yymajor ) as $token ) {
$exp_token = $this -> parser -> yyTokenName [ $token ];
if ( isset ( $this -> lex -> smarty_token_names [ $exp_token ])) {
// token type from lexer
$expect [] = '"' . $this -> lex -> smarty_token_names [ $exp_token ] . '"' ;
} else {
// otherwise internal token name
$expect [] = $this -> parser -> yyTokenName [ $token ];
}
}
$error_text .= ', expected one of: ' . implode ( ' , ' , $expect );
}
2011-03-28 22:18:39 +00:00
}
2010-08-13 10:39:51 +00:00
throw new SmartyCompilerException ( $error_text );
2011-03-28 22:18:39 +00:00
}
2011-09-16 14:19:56 +00:00
2011-03-28 22:18:39 +00:00
}
2010-11-11 21:34:36 +00:00
2010-02-27 23:28:14 +00:00
?>