2014-03-17 21:57:15 +00:00
< ? php
/**
* Smarty Internal Plugin Smarty Template Compiler Base
2014-06-06 02:40:04 +00:00
* This file contains the basic classes and methods for compiling Smarty templates with lexer / parser
2014-03-17 21:57:15 +00:00
*
2014-06-06 02:40:04 +00:00
* @ package Smarty
2014-03-17 21:57:15 +00:00
* @ subpackage Compiler
2014-06-06 02:40:04 +00:00
* @ author Uwe Tews
2014-03-17 21:57:15 +00:00
*/
/**
* Main abstract compiler class
*
2014-06-06 02:40:04 +00:00
* @ package Smarty
2014-03-17 21:57:15 +00:00
* @ subpackage Compiler
2015-10-18 04:46:05 +02:00
*
* @ property Smarty_Internal_SmartyTemplateCompiler $prefixCompiledCode = ''
* @ property Smarty_Internal_SmartyTemplateCompiler $postfixCompiledCode = ''
2015-12-27 08:12:46 +01:00
* @ method registerPostCompileCallback ( $callback , $parameter = array (), $key = null , $replace = false )
* @ method unregisterPostCompileCallback ( $key )
2014-03-17 21:57:15 +00:00
*/
abstract class Smarty_Internal_TemplateCompilerBase
{
2015-05-14 15:11:38 +02:00
2015-05-05 03:27:16 +02:00
/**
* Smarty object
2015-05-06 00:03:26 +02:00
*
2015-05-05 03:27:16 +02:00
* @ var Smarty
*/
public $smarty = null ;
2015-05-06 00:03:26 +02:00
2015-07-01 03:23:40 +02:00
/**
* Parser object
*
2015-09-14 23:16:13 +02:00
* @ var Smarty_Internal_Templateparser
2015-07-01 03:23:40 +02:00
*/
2015-08-06 19:42:40 +02:00
public $parser = null ;
2015-07-12 07:02:25 +02:00
2014-03-17 21:57:15 +00:00
/**
* hash for nocache sections
*
* @ var mixed
*/
2014-11-01 22:42:34 +01:00
public $nocache_hash = null ;
2014-03-17 21:57:15 +00:00
/**
* suppress generation of nocache code
*
* @ var bool
*/
public $suppressNocacheProcessing = false ;
/**
2015-07-01 03:23:40 +02:00
* compile tag objects cache
2014-03-17 21:57:15 +00:00
*
* @ var array
*/
2015-07-01 03:23:40 +02:00
public $_tag_objects = array ();
2014-03-17 21:57:15 +00:00
/**
* tag stack
*
* @ var array
*/
public $_tag_stack = array ();
/**
* current template
*
* @ var Smarty_Internal_Template
*/
public $template = null ;
/**
2014-11-01 22:42:34 +01:00
* merged included sub template data
*
* @ var array
*/
public $mergedSubTemplatesData = array ();
/**
* merged sub template code
*
* @ var array
*/
public $mergedSubTemplatesCode = array ();
/**
* collected template properties during compilation
2014-03-17 21:57:15 +00:00
*
* @ var array
*/
2014-11-01 22:42:34 +01:00
public $templateProperties = array ();
2014-03-17 21:57:15 +00:00
/**
* source line offset for error messages
*
* @ var int
*/
public $trace_line_offset = 0 ;
/**
* trace uid
*
* @ var string
*/
public $trace_uid = '' ;
/**
* trace file path
*
* @ var string
*/
public $trace_filepath = '' ;
2015-05-14 15:11:38 +02:00
2014-03-17 21:57:15 +00:00
/**
* stack for tracing file and line of nested { block } tags
*
* @ var array
*/
public $trace_stack = array ();
/**
* plugins loaded by default plugin handler
*
* @ var array
*/
public $default_handler_plugins = array ();
/**
* saved preprocessed modifier list
*
* @ var mixed
*/
public $default_modifier_list = null ;
/**
* force compilation of complete template as nocache
2014-06-06 02:40:04 +00:00
*
2014-03-17 21:57:15 +00:00
* @ var boolean
*/
public $forceNocache = false ;
/**
* flag if compiled template file shall we written
2014-06-06 02:40:04 +00:00
*
2014-03-17 21:57:15 +00:00
* @ var bool
*/
public $write_compiled_code = true ;
2015-12-08 23:41:42 +01:00
/**
* Template functions
*
* @ var array
*/
public $tpl_function = array ();
2014-03-17 21:57:15 +00:00
/**
2014-11-01 22:42:34 +01:00
* called sub functions from template function
2014-06-06 02:40:04 +00:00
*
2014-03-17 21:57:15 +00:00
* @ var array
*/
public $called_functions = array ();
2014-11-01 22:42:34 +01:00
/**
2015-09-16 16:23:38 +02:00
* compiled template or block function code
2014-11-01 22:42:34 +01:00
*
* @ var string
*/
2015-09-16 16:23:38 +02:00
public $blockOrFunctionCode = '' ;
2015-05-05 03:27:16 +02:00
2015-05-23 19:03:13 +02:00
/**
* php_handling setting either from Smarty or security
*
* @ var int
*/
public $php_handling = 0 ;
2014-03-17 21:57:15 +00:00
/**
* flags for used modifier plugins
2014-06-06 02:40:04 +00:00
*
2014-03-17 21:57:15 +00:00
* @ var array
*/
public $modifier_plugins = array ();
/**
* type of already compiled modifier
2014-06-06 02:40:04 +00:00
*
2014-03-17 21:57:15 +00:00
* @ var array
*/
public $known_modifier_type = array ();
2014-11-01 22:42:34 +01:00
/**
* parent compiler object for merged subtemplates and template functions
*
* @ var Smarty_Internal_TemplateCompilerBase
*/
public $parent_compiler = null ;
2015-05-05 03:27:16 +02:00
/**
* Flag true when compiling nocache section
*
* @ var bool
*/
public $nocache = false ;
/**
* Flag true when tag is compiled as nocache
2015-05-06 00:03:26 +02:00
*
2015-05-05 03:27:16 +02:00
* @ var bool
*/
public $tag_nocache = false ;
/**
* Compiled tag prefix code
*
* @ var array
*/
public $prefix_code = array ();
/**
* Prefix code stack
2015-05-06 00:03:26 +02:00
*
2015-05-05 03:27:16 +02:00
* @ var array
*/
public $prefixCodeStack = array ();
/**
* Tag has compiled code
2015-05-06 00:03:26 +02:00
*
2015-05-05 03:27:16 +02:00
* @ var bool
*/
public $has_code = false ;
2015-05-06 00:03:26 +02:00
/**
* A variable string was compiled
*
* @ var bool
*/
public $has_variable_string = false ;
2015-05-05 03:27:16 +02:00
/**
* Tag creates output
2015-05-06 00:03:26 +02:00
*
2015-05-05 03:27:16 +02:00
* @ var bool
*/
public $has_output = false ;
2015-08-06 19:42:40 +02:00
/**
* Stack for { setfilter } { / setfilter }
*
* @ var array
*/
public $variable_filter_stack = array ();
2015-08-10 21:57:06 +02:00
/**
2015-08-23 13:24:24 +02:00
* variable filters for { setfilter } { / setfilter }
*
* @ var array
*/
public $variable_filters = array ();
2015-09-01 01:54:28 +02:00
/**
* Nesting count of looping tags like { foreach }, { for }, { section }, { while }
2015-08-10 21:57:06 +02:00
*
* @ var int
*/
public $loopNesting = 0 ;
2015-04-02 01:42:53 +02:00
/**
* Strip preg pattern
*
* @ var string
*/
public $stripRegEx = '![\t ]*[\r\n]+[\t ]*!' ;
2015-08-19 02:19:25 +02:00
/**
* plugin search order
*
* @ var array
*/
public $plugin_search_order = array ( 'function' , 'block' , 'compiler' , 'class' );
2015-10-18 04:46:05 +02:00
/**
* General storage area for tag compiler plugins
*
* @ var array
*/
public $_cache = array ();
2016-02-09 01:15:12 +01:00
/**
* counter for prefix variable number
*
* @ var int
*/
public static $prefixVariableNumber = 0 ;
2014-03-17 21:57:15 +00:00
/**
2014-06-06 02:40:04 +00:00
* method to compile a Smarty template
2014-03-17 21:57:15 +00:00
*
2015-07-01 03:23:40 +02:00
* @ param mixed $_content template source
* @ param bool $isTemplateSource
2014-06-06 02:40:04 +00:00
*
2015-07-01 03:23:40 +02:00
* @ return bool true if compiling succeeded , false if it failed
2014-03-17 21:57:15 +00:00
*/
2015-07-01 03:23:40 +02:00
abstract protected function doCompile ( $_content , $isTemplateSource = false );
2014-03-17 21:57:15 +00:00
/**
* Initialize compiler
2015-10-18 04:46:05 +02:00
*
* @ param Smarty $smarty global instance
2014-03-17 21:57:15 +00:00
*/
2015-10-18 04:46:05 +02:00
public function __construct ( Smarty $smarty )
2014-03-17 21:57:15 +00:00
{
2015-10-18 04:46:05 +02:00
$this -> smarty = $smarty ;
2014-11-01 22:42:34 +01:00
$this -> nocache_hash = str_replace ( array ( '.' , ',' ), '_' , uniqid ( rand (), true ));
2014-03-17 21:57:15 +00:00
}
/**
* Method to compile a Smarty template
*
2015-05-06 00:03:26 +02:00
* @ param Smarty_Internal_Template $template template object to compile
* @ param bool $nocache true is shall be compiled in nocache mode
* @ param null | Smarty_Internal_TemplateCompilerBase $parent_compiler
2014-06-06 02:40:04 +00:00
*
2015-05-05 03:27:16 +02:00
* @ return bool true if compiling succeeded , false if it failed
2015-08-06 01:19:11 +02:00
* @ throws \Exception
2014-03-17 21:57:15 +00:00
*/
2015-09-16 16:23:38 +02:00
public function compileTemplate ( Smarty_Internal_Template $template , $nocache = null ,
Smarty_Internal_TemplateCompilerBase $parent_compiler = null )
2014-03-17 21:57:15 +00:00
{
2015-09-16 16:23:38 +02:00
// get code frame of compiled template
2015-11-01 02:58:27 +01:00
$_compiled_code = $template -> smarty -> ext -> _codeFrame -> create ( $template ,
$this -> compileTemplateSource ( $template , $nocache ,
$parent_compiler ),
$this -> postFilter ( $this -> blockOrFunctionCode ) .
2015-12-17 21:51:19 +01:00
join ( '' , $this -> mergedSubTemplatesCode ), false ,
$this );
2015-09-16 16:23:38 +02:00
return $_compiled_code ;
}
2015-09-01 01:54:28 +02:00
2015-09-16 16:23:38 +02:00
/**
* Compile template source and run optional post filter
*
* @ param \Smarty_Internal_Template $template
* @ param null | bool $nocache flag if template must be compiled in nocache mode
* @ param \Smarty_Internal_TemplateCompilerBase $parent_compiler
*
* @ return string
* @ throws \Exception
*/
public function compileTemplateSource ( Smarty_Internal_Template $template , $nocache = null ,
Smarty_Internal_TemplateCompilerBase $parent_compiler = null )
{
2015-08-06 01:19:11 +02:00
try {
2015-09-16 16:23:38 +02:00
// save template object in compiler class
$this -> template = $template ;
if ( property_exists ( $this -> template -> smarty , 'plugin_search_order' )) {
$this -> plugin_search_order = $this -> template -> smarty -> plugin_search_order ;
}
if ( $this -> smarty -> debugging ) {
$this -> smarty -> _debug -> start_compile ( $this -> template );
}
2015-08-06 01:19:11 +02:00
if ( isset ( $this -> template -> smarty -> security_policy )) {
$this -> php_handling = $this -> template -> smarty -> security_policy -> php_handling ;
} else {
$this -> php_handling = $this -> template -> smarty -> php_handling ;
2014-03-17 21:57:15 +00:00
}
2015-08-06 01:19:11 +02:00
$this -> parent_compiler = $parent_compiler ? $parent_compiler : $this ;
$nocache = isset ( $nocache ) ? $nocache : false ;
2015-08-09 20:43:04 +02:00
if ( empty ( $template -> compiled -> nocache_hash )) {
$template -> compiled -> nocache_hash = $this -> nocache_hash ;
2014-03-17 21:57:15 +00:00
} else {
2015-08-09 20:43:04 +02:00
$this -> nocache_hash = $template -> compiled -> nocache_hash ;
2014-03-17 21:57:15 +00:00
}
2015-09-14 23:16:13 +02:00
// flag for nocache sections
2015-09-01 01:54:28 +02:00
$this -> nocache = $nocache ;
$this -> tag_nocache = false ;
// reset has nocache code flag
$this -> template -> compiled -> has_nocache_code = false ;
$this -> has_variable_string = false ;
$this -> prefix_code = array ();
2015-09-16 16:23:38 +02:00
// add file dependency
2015-12-17 21:51:19 +01:00
$this -> parent_compiler -> template -> compiled -> file_dependency [ $this -> template -> source -> uid ] =
2015-09-16 16:23:38 +02:00
array ( $this -> template -> source -> filepath , $this -> template -> source -> getTimeStamp (),
$this -> template -> source -> type );
$this -> smarty -> _current_file = $this -> template -> source -> filepath ;
2015-09-01 01:54:28 +02:00
// get template source
if ( ! empty ( $this -> template -> source -> components )) {
2015-08-06 01:19:11 +02:00
// we have array of inheritance templates by extends: resource
2015-10-18 04:46:05 +02:00
// generate corresponding source code sequence
$_content =
Smarty_Internal_Compile_Extends :: extendsSourceArrayCode ( $this -> template -> source -> components );
2015-09-01 01:54:28 +02:00
} else {
2015-08-06 01:19:11 +02:00
// get template source
$_content = $this -> template -> source -> getContent ();
2015-09-01 01:54:28 +02:00
}
2015-09-16 16:23:38 +02:00
$_compiled_code = $this -> postFilter ( $this -> doCompile ( $this -> preFilter ( $_content ), true ));
}
catch ( Exception $e ) {
2015-09-01 01:54:28 +02:00
if ( $this -> smarty -> debugging ) {
$this -> smarty -> _debug -> end_compile ( $this -> template );
}
2015-08-06 19:40:37 +02:00
$this -> _tag_stack = array ();
$this -> _tag_objects = array ();
2015-08-06 01:19:11 +02:00
// free memory
$this -> parent_compiler = null ;
$this -> template = null ;
$this -> parser = null ;
throw $e ;
}
2015-09-16 16:23:38 +02:00
if ( $this -> smarty -> debugging ) {
$this -> smarty -> _debug -> end_compile ( $this -> template );
}
2014-11-01 22:42:34 +01:00
$this -> parent_compiler = null ;
2015-09-16 16:23:38 +02:00
$this -> parser = null ;
2014-11-01 22:42:34 +01:00
return $_compiled_code ;
2014-03-17 21:57:15 +00:00
}
2015-09-16 16:23:38 +02:00
/**
* Optionally process compiled code by post filter
*
* @ param string $code compiled code
*
* @ return string
* @ throws \SmartyException
*/
public function postFilter ( $code )
{
// run post filter if on code
if ( ! empty ( $code ) &&
2015-12-17 21:51:19 +01:00
( isset ( $this -> smarty -> autoload_filters [ 'post' ]) || isset ( $this -> smarty -> registered_filters [ 'post' ]))
2015-09-16 16:23:38 +02:00
) {
2015-10-24 05:02:24 +02:00
return $this -> smarty -> ext -> _filterHandler -> runFilter ( 'post' , $code , $this -> template );
2015-09-16 16:23:38 +02:00
} else {
return $code ;
}
}
/**
* Run optional prefilter
*
* @ param string $_content template source
*
* @ return string
* @ throws \SmartyException
*/
public function preFilter ( $_content )
{
// run pre filter if required
if ( $_content != '' &&
2015-12-17 21:51:19 +01:00
(( isset ( $this -> smarty -> autoload_filters [ 'pre' ]) || isset ( $this -> smarty -> registered_filters [ 'pre' ])))
2015-09-16 16:23:38 +02:00
) {
2015-10-24 05:02:24 +02:00
return $this -> smarty -> ext -> _filterHandler -> runFilter ( 'pre' , $_content , $this -> template );
2015-09-16 16:23:38 +02:00
} else {
return $_content ;
}
}
2014-03-17 21:57:15 +00:00
/**
* Compile Tag
* This is a call back from the lexer / parser
2015-05-05 03:33:53 +02:00
*
* Save current prefix code
* Compile tag
* Merge tag prefix code with saved one
* ( required nested tags in attributes )
2014-03-17 21:57:15 +00:00
*
* @ param string $tag tag name
2014-06-06 02:40:04 +00:00
* @ param array $args array with tag attributes
* @ param array $parameter array with compilation parameter
*
* @ throws SmartyCompilerException
* @ throws SmartyException
2014-03-17 21:57:15 +00:00
* @ return string compiled code
*/
public function compileTag ( $tag , $args , $parameter = array ())
{
2015-05-05 03:33:53 +02:00
$this -> prefixCodeStack [] = $this -> prefix_code ;
$this -> prefix_code = array ();
$result = $this -> compileTag2 ( $tag , $args , $parameter );
$this -> prefix_code = array_merge ( $this -> prefix_code , array_pop ( $this -> prefixCodeStack ));
return $result ;
}
/**
* Compile Tag
*
* @ param string $tag tag name
* @ param array $args array with tag attributes
* @ param array $parameter array with compilation parameter
*
* @ throws SmartyCompilerException
* @ throws SmartyException
* @ return string compiled code
*/
private function compileTag2 ( $tag , $args , $parameter )
{
$plugin_type = '' ;
2014-03-17 21:57:15 +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 ;
$this -> has_output = false ;
// log tag/attributes
2015-12-17 21:51:19 +01:00
if ( isset ( $this -> smarty -> _cache [ 'get_used_tags' ])) {
$this -> template -> _cache [ 'used_tags' ][] = array ( $tag , $args );
2014-03-17 21:57:15 +00:00
}
// check nocache option flag
2015-07-12 07:02:25 +02:00
if ( in_array ( " 'nocache' " , $args ) || in_array ( array ( 'nocache' => 'true' ), $args ) ||
in_array ( array ( 'nocache' => '"true"' ), $args ) || in_array ( array ( 'nocache' => " 'true' " ), $args )
) {
2014-03-17 21:57:15 +00:00
$this -> tag_nocache = true ;
}
2015-07-01 03:23:40 +02:00
// compile the smarty tag (required compile classes to compile the tag are auto loaded)
2014-03-17 21:57:15 +00:00
if (( $_output = $this -> callTagCompiler ( $tag , $args , $parameter )) === false ) {
2015-12-17 21:51:19 +01:00
if ( isset ( $this -> parent_compiler -> template -> tpl_function [ $tag ])) {
2014-03-17 21:57:15 +00:00
// template defined by {template} tag
2015-12-17 21:51:19 +01:00
$args [ '_attr' ][ 'name' ] = " ' " . $tag . " ' " ;
2014-03-17 21:57:15 +00:00
$_output = $this -> callTagCompiler ( 'call' , $args , $parameter );
}
}
if ( $_output !== false ) {
if ( $_output !== true ) {
// did we get compiled code
if ( $this -> has_code ) {
// Does it create output?
if ( $this -> has_output ) {
$_output .= " \n " ;
}
// return compiled code
return $_output ;
}
}
// tag did not produce compiled code
return null ;
} else {
// map_named attributes
2015-12-17 21:51:19 +01:00
if ( isset ( $args [ '_attr' ])) {
foreach ( $args [ '_attr' ] as $key => $attribute ) {
2014-03-17 21:57:15 +00:00
if ( is_array ( $attribute )) {
$args = array_merge ( $args , $attribute );
}
}
}
// not an internal compiler tag
2014-06-06 02:40:04 +00:00
if ( strlen ( $tag ) < 6 || substr ( $tag , - 5 ) != 'close' ) {
2014-03-17 21:57:15 +00:00
// check if tag is a registered object
2015-12-17 21:51:19 +01:00
if ( isset ( $this -> smarty -> registered_objects [ $tag ]) && isset ( $parameter [ 'object_method' ])) {
$method = $parameter [ 'object_method' ];
if ( ! in_array ( $method , $this -> smarty -> registered_objects [ $tag ][ 3 ]) &&
( empty ( $this -> smarty -> registered_objects [ $tag ][ 1 ]) ||
2016-02-09 01:27:15 +01:00
in_array ( $method , $this -> smarty -> registered_objects [ $tag ][ 1 ]))
2015-07-12 07:02:25 +02:00
) {
2014-06-06 02:40:04 +00:00
return $this -> callTagCompiler ( 'private_object_function' , $args , $parameter , $tag , $method );
2015-12-17 21:51:19 +01:00
} elseif ( in_array ( $method , $this -> smarty -> registered_objects [ $tag ][ 3 ])) {
2015-09-01 01:54:28 +02:00
return $this -> callTagCompiler ( 'private_object_block_function' , $args , $parameter , $tag ,
$method );
2014-03-17 21:57:15 +00:00
} else {
2014-06-06 02:40:04 +00:00
// throw exception
2015-07-12 07:02:25 +02:00
$this -> trigger_template_error ( 'not allowed method "' . $method . '" in registered object "' .
2015-08-06 01:19:11 +02:00
$tag . '"' , null , true );
2014-03-17 21:57:15 +00:00
}
}
// check if tag is registered
2015-07-12 07:02:25 +02:00
foreach ( array ( Smarty :: PLUGIN_COMPILER , Smarty :: PLUGIN_FUNCTION , Smarty :: PLUGIN_BLOCK ) as $plugin_type )
{
2015-12-17 21:51:19 +01:00
if ( isset ( $this -> smarty -> registered_plugins [ $plugin_type ][ $tag ])) {
2014-03-17 21:57:15 +00:00
// if compiler function plugin call it now
if ( $plugin_type == Smarty :: PLUGIN_COMPILER ) {
$new_args = array ();
foreach ( $args as $key => $mixed ) {
if ( is_array ( $mixed )) {
$new_args = array_merge ( $new_args , $mixed );
} else {
2015-12-17 21:51:19 +01:00
$new_args [ $key ] = $mixed ;
2014-03-17 21:57:15 +00:00
}
}
2015-12-17 21:51:19 +01:00
if ( ! $this -> smarty -> registered_plugins [ $plugin_type ][ $tag ][ 1 ]) {
2014-03-17 21:57:15 +00:00
$this -> tag_nocache = true ;
}
2015-12-17 21:51:19 +01:00
$function = $this -> smarty -> registered_plugins [ $plugin_type ][ $tag ][ 0 ];
2014-03-17 21:57:15 +00:00
if ( ! is_array ( $function )) {
return $function ( $new_args , $this );
2015-12-17 21:51:19 +01:00
} elseif ( is_object ( $function [ 0 ])) {
return $this -> smarty -> registered_plugins [ $plugin_type ][ $tag ][ 0 ][ 0 ] -> { $function [ 1 ]}( $new_args ,
$this );
2014-03-17 21:57:15 +00:00
} else {
return call_user_func_array ( $function , array ( $new_args , $this ));
}
}
// compile registered function or block function
if ( $plugin_type == Smarty :: PLUGIN_FUNCTION || $plugin_type == Smarty :: PLUGIN_BLOCK ) {
2015-09-01 01:54:28 +02:00
return $this -> callTagCompiler ( 'private_registered_' . $plugin_type , $args , $parameter ,
$tag );
2014-03-17 21:57:15 +00:00
}
}
}
// check plugins from plugins folder
2015-08-19 02:19:25 +02:00
foreach ( $this -> plugin_search_order as $plugin_type ) {
2015-07-12 07:02:25 +02:00
if ( $plugin_type == Smarty :: PLUGIN_COMPILER &&
$this -> smarty -> loadPlugin ( 'smarty_compiler_' . $tag ) &&
( ! isset ( $this -> smarty -> security_policy ) ||
2016-02-09 01:27:15 +01:00
$this -> smarty -> security_policy -> isTrustedTag ( $tag , $this ))
2015-07-12 07:02:25 +02:00
) {
2014-03-17 21:57:15 +00:00
$plugin = 'smarty_compiler_' . $tag ;
if ( is_callable ( $plugin )) {
// convert arguments format for old compiler plugins
$new_args = array ();
foreach ( $args as $key => $mixed ) {
if ( is_array ( $mixed )) {
$new_args = array_merge ( $new_args , $mixed );
} else {
2015-12-17 21:51:19 +01:00
$new_args [ $key ] = $mixed ;
2014-03-17 21:57:15 +00:00
}
}
return $plugin ( $new_args , $this -> smarty );
}
if ( class_exists ( $plugin , false )) {
$plugin_object = new $plugin ;
if ( method_exists ( $plugin_object , 'compile' )) {
return $plugin_object -> compile ( $args , $this );
}
}
throw new SmartyException ( " Plugin \" { $tag } \" not callable " );
} else {
if ( $function = $this -> getPlugin ( $tag , $plugin_type )) {
2015-07-12 07:02:25 +02:00
if ( ! isset ( $this -> smarty -> security_policy ) ||
$this -> smarty -> security_policy -> isTrustedTag ( $tag , $this )
) {
2015-09-01 01:54:28 +02:00
return $this -> callTagCompiler ( 'private_' . $plugin_type . '_plugin' , $args , $parameter ,
$tag , $function );
2014-03-17 21:57:15 +00:00
}
}
}
}
if ( is_callable ( $this -> smarty -> default_plugin_handler_func )) {
$found = false ;
// look for already resolved tags
2015-08-19 02:19:25 +02:00
foreach ( $this -> plugin_search_order as $plugin_type ) {
2015-12-17 21:51:19 +01:00
if ( isset ( $this -> default_handler_plugins [ $plugin_type ][ $tag ])) {
2014-03-17 21:57:15 +00:00
$found = true ;
break ;
}
}
if ( ! $found ) {
// call default handler
2015-08-19 02:19:25 +02:00
foreach ( $this -> plugin_search_order as $plugin_type ) {
2014-03-17 21:57:15 +00:00
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 );
}
2015-12-17 21:51:19 +01:00
$function = $this -> default_handler_plugins [ $plugin_type ][ $tag ][ 0 ];
2014-03-17 21:57:15 +00:00
if ( ! is_array ( $function )) {
return $function ( $new_args , $this );
2015-12-17 21:51:19 +01:00
} elseif ( is_object ( $function [ 0 ])) {
return $this -> default_handler_plugins [ $plugin_type ][ $tag ][ 0 ][ 0 ] -> $function [ 1 ]( $new_args ,
$this );
2014-03-17 21:57:15 +00:00
} else {
return call_user_func_array ( $function , array ( $new_args , $this ));
}
} else {
2015-09-01 01:54:28 +02:00
return $this -> callTagCompiler ( 'private_registered_' . $plugin_type , $args , $parameter ,
$tag );
2014-03-17 21:57:15 +00:00
}
}
}
} else {
// compile closing tag of block function
2014-06-06 02:40:04 +00:00
$base_tag = substr ( $tag , 0 , - 5 );
2014-03-17 21:57:15 +00:00
// check if closing tag is a registered object
2015-12-17 21:51:19 +01:00
if ( isset ( $this -> smarty -> registered_objects [ $base_tag ]) && isset ( $parameter [ 'object_method' ])) {
$method = $parameter [ 'object_method' ];
if ( in_array ( $method , $this -> smarty -> registered_objects [ $base_tag ][ 3 ])) {
2015-09-01 01:54:28 +02:00
return $this -> callTagCompiler ( 'private_object_block_function' , $args , $parameter , $tag ,
$method );
2014-03-17 21:57:15 +00:00
} else {
2014-06-06 02:40:04 +00:00
// throw exception
2015-07-12 07:02:25 +02:00
$this -> trigger_template_error ( 'not allowed closing tag method "' . $method .
2015-08-06 01:19:11 +02:00
'" in registered object "' . $base_tag . '"' , null , true );
2014-03-17 21:57:15 +00:00
}
}
// registered block tag ?
2015-12-17 21:51:19 +01:00
if ( isset ( $this -> smarty -> registered_plugins [ Smarty :: PLUGIN_BLOCK ][ $base_tag ]) ||
isset ( $this -> default_handler_plugins [ Smarty :: PLUGIN_BLOCK ][ $base_tag ])
2015-07-12 07:02:25 +02:00
) {
2014-03-17 21:57:15 +00:00
return $this -> callTagCompiler ( 'private_registered_block' , $args , $parameter , $tag );
}
2015-06-27 22:18:08 +02:00
// registered function tag ?
2015-12-17 21:51:19 +01:00
if ( isset ( $this -> smarty -> registered_plugins [ Smarty :: PLUGIN_FUNCTION ][ $tag ])) {
2015-06-27 22:18:08 +02:00
return $this -> callTagCompiler ( 'private_registered_function' , $args , $parameter , $tag );
}
2014-03-17 21:57:15 +00:00
// block plugin?
if ( $function = $this -> getPlugin ( $base_tag , Smarty :: PLUGIN_BLOCK )) {
return $this -> callTagCompiler ( 'private_block_plugin' , $args , $parameter , $tag , $function );
}
2015-06-27 22:18:08 +02:00
// function plugin?
if ( $function = $this -> getPlugin ( $tag , Smarty :: PLUGIN_FUNCTION )) {
2015-07-12 07:02:25 +02:00
if ( ! isset ( $this -> smarty -> security_policy ) ||
$this -> smarty -> security_policy -> isTrustedTag ( $tag , $this )
) {
2015-06-27 22:18:08 +02:00
return $this -> callTagCompiler ( 'private_function_plugin' , $args , $parameter , $tag , $function );
}
}
2014-03-17 21:57:15 +00:00
// registered compiler plugin ?
2015-12-17 21:51:19 +01:00
if ( isset ( $this -> smarty -> registered_plugins [ Smarty :: PLUGIN_COMPILER ][ $tag ])) {
2014-03-17 21:57:15 +00:00
// if compiler function plugin call it now
$args = array ();
2015-12-17 21:51:19 +01:00
if ( ! $this -> smarty -> registered_plugins [ Smarty :: PLUGIN_COMPILER ][ $tag ][ 1 ]) {
2014-03-17 21:57:15 +00:00
$this -> tag_nocache = true ;
}
2015-12-17 21:51:19 +01:00
$function = $this -> smarty -> registered_plugins [ Smarty :: PLUGIN_COMPILER ][ $tag ][ 0 ];
2014-03-17 21:57:15 +00:00
if ( ! is_array ( $function )) {
return $function ( $args , $this );
2015-12-17 21:51:19 +01:00
} elseif ( is_object ( $function [ 0 ])) {
return $this -> smarty -> registered_plugins [ Smarty :: PLUGIN_COMPILER ][ $tag ][ 0 ][ 0 ] -> $function [ 1 ]( $args ,
$this );
2014-03-17 21:57:15 +00:00
} else {
return call_user_func_array ( $function , array ( $args , $this ));
}
}
if ( $this -> smarty -> loadPlugin ( 'smarty_compiler_' . $tag )) {
$plugin = 'smarty_compiler_' . $tag ;
if ( is_callable ( $plugin )) {
return $plugin ( $args , $this -> smarty );
}
if ( class_exists ( $plugin , false )) {
$plugin_object = new $plugin ;
if ( method_exists ( $plugin_object , 'compile' )) {
return $plugin_object -> compile ( $args , $this );
}
}
throw new SmartyException ( " Plugin \" { $tag } \" not callable " );
}
}
2015-08-06 01:19:11 +02:00
$this -> trigger_template_error ( " unknown tag \" " . $tag . " \" " , null , true );
2014-03-17 21:57:15 +00:00
}
}
2015-04-02 01:35:16 +02:00
/**
* compile variable
*
* @ param string $variable
*
* @ return string
*/
public function compileVariable ( $variable )
{
if ( strpos ( $variable , '(' ) == 0 ) {
// not a variable variable
$var = trim ( $variable , '\'' );
2015-11-01 02:58:27 +01:00
$this -> tag_nocache = $this -> tag_nocache |
2016-02-09 01:27:15 +01:00
$this -> template -> ext -> getTemplateVars -> _getVariable ( $this -> template , $var , null , true ,
false ) -> nocache ;
2015-08-09 20:43:04 +02:00
// todo $this->template->compiled->properties['variables'][$var] = $this->tag_nocache | $this->nocache;
2015-04-02 01:35:16 +02:00
}
return '$_smarty_tpl->tpl_vars[' . $variable . ']->value' ;
}
2015-11-01 02:58:27 +01:00
/**
* compile config variable
*
* @ param string $variable
*
* @ return string
*/
public function compileConfigVariable ( $variable )
{
// return '$_smarty_tpl->config_vars[' . $variable . ']';
return '$_smarty_tpl->smarty->ext->configLoad->_getConfigVariable($_smarty_tpl, ' . $variable . ')' ;
}
2015-04-02 01:42:53 +02:00
/**
* This method is called from parser to process a text content section
* - remove text from inheritance child templates as they may generate output
* - strip text if strip is enabled
*
* @ param string $text
*
* @ return null | \Smarty_Internal_ParseTree_Text
*/
2015-05-05 03:27:16 +02:00
public function processText ( $text )
{
2015-12-17 21:51:19 +01:00
if (( string ) $text != '' ) {
$store = array ();
$_store = 0 ;
$_offset = 0 ;
if ( $this -> parser -> strip ) {
if ( strpos ( $text , '<' ) !== false ) {
// capture html elements not to be messed with
$_offset = 0 ;
if ( preg_match_all ( '#(<script[^>]*>.*?</script[^>]*>)|(<textarea[^>]*>.*?</textarea[^>]*>)|(<pre[^>]*>.*?</pre[^>]*>)#is' ,
$text , $matches , PREG_OFFSET_CAPTURE | PREG_SET_ORDER )) {
foreach ( $matches as $match ) {
$store [] = $match [ 0 ][ 0 ];
$_length = strlen ( $match [ 0 ][ 0 ]);
$replace = '@!@SMARTY:' . $_store . ':SMARTY@!@' ;
$text = substr_replace ( $text , $replace , $match [ 0 ][ 1 ] - $_offset , $_length );
$_offset += $_length - strlen ( $replace );
$_store ++ ;
}
2015-12-09 01:35:17 +01:00
}
2015-12-17 21:51:19 +01:00
$expressions = array ( // replace multiple spaces between tags by a single space
// can't remove them entirely, becaue that might break poorly implemented CSS display:inline-block elements
2016-02-09 01:27:15 +01:00
'#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s' => '\1\2' ,
2015-12-17 21:51:19 +01:00
// remove spaces between attributes (but not in attribute values!)
'#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5' ,
2016-02-09 01:27:15 +01:00
'#^\s+<#Ss' => '<' , '#>\s+$#Ss' => '>' , $this -> stripRegEx => '' );
2015-12-17 21:51:19 +01:00
$text = preg_replace ( array_keys ( $expressions ), array_values ( $expressions ), $text );
$_offset = 0 ;
if ( preg_match_all ( '#@!@SMARTY:([0-9]+):SMARTY@!@#is' , $text , $matches ,
PREG_OFFSET_CAPTURE | PREG_SET_ORDER )) {
foreach ( $matches as $match ) {
$_length = strlen ( $match [ 0 ][ 0 ]);
$replace = $store [ $match [ 1 ][ 0 ] ];
$text = substr_replace ( $text , $replace , $match [ 0 ][ 1 ] + $_offset , $_length );
$_offset += strlen ( $replace ) - $_length ;
$_store ++ ;
}
2015-12-09 01:35:17 +01:00
}
2015-12-17 21:51:19 +01:00
} else {
$text = preg_replace ( $this -> stripRegEx , '' , $text );
2015-12-09 01:35:17 +01:00
}
}
2015-08-06 01:19:11 +02:00
return new Smarty_Internal_ParseTree_Text ( $text );
2015-04-02 01:42:53 +02:00
}
2015-12-09 01:35:17 +01:00
return null ;
2015-12-17 21:51:19 +01:00
}
2015-04-02 01:42:53 +02:00
2014-03-17 21:57:15 +00:00
/**
2014-06-06 02:40:04 +00:00
* lazy loads internal compile plugin for tag and calls the compile method
2014-03-17 21:57:15 +00:00
* compile objects cached for reuse .
* class name format : Smarty_Internal_Compile_TagName
2015-07-01 03:23:40 +02:00
* plugin filename format : Smarty_Internal_TagName . php
2014-03-17 21:57:15 +00:00
*
* @ param string $tag tag name
2014-06-06 02:40:04 +00:00
* @ param array $args list of tag attributes
* @ param mixed $param1 optional parameter
* @ param mixed $param2 optional parameter
* @ param mixed $param3 optional parameter
*
2014-03-17 21:57:15 +00:00
* @ return string compiled code
*/
public function callTagCompiler ( $tag , $args , $param1 = null , $param2 = null , $param3 = null )
{
2015-06-27 21:50:33 +02:00
// re-use object if already exists
2015-12-17 21:51:19 +01:00
if ( ! isset ( $this -> _tag_objects [ $tag ])) {
2015-06-27 21:50:33 +02:00
// lazy load internal compiler plugin
2015-07-12 07:02:25 +02:00
$_tag = explode ( '_' , $tag );
2015-08-06 01:19:11 +02:00
$_tag = array_map ( 'ucfirst' , $_tag );
2015-07-12 07:02:25 +02:00
$class_name = 'Smarty_Internal_Compile_' . implode ( '_' , $_tag );
if ( class_exists ( $class_name ) &&
( ! isset ( $this -> smarty -> security_policy ) || $this -> smarty -> security_policy -> isTrustedTag ( $tag , $this ))
) {
2015-12-17 21:51:19 +01:00
$this -> _tag_objects [ $tag ] = new $class_name ;
2015-06-27 21:50:33 +02:00
} else {
2015-12-17 21:51:19 +01:00
$this -> _tag_objects [ $tag ] = false ;
2015-06-27 21:50:33 +02:00
return false ;
2015-01-01 22:59:07 +01:00
}
2014-03-17 21:57:15 +00:00
}
2015-06-27 21:50:33 +02:00
// compile this tag
2015-12-17 21:51:19 +01:00
return $this -> _tag_objects [ $tag ] === false ? false :
$this -> _tag_objects [ $tag ] -> compile ( $args , $this , $param1 , $param2 , $param3 );
2014-03-17 21:57:15 +00:00
}
/**
* Check for plugins and return function name
*
2014-06-06 02:40:04 +00:00
* @ param $plugin_name
2014-03-17 21:57:15 +00:00
* @ param string $plugin_type type of plugin
2014-06-06 02:40:04 +00:00
*
2014-03-17 21:57:15 +00:00
* @ return string call name of function
*/
public function getPlugin ( $plugin_name , $plugin_type )
{
$function = null ;
if ( $this -> template -> caching && ( $this -> nocache || $this -> tag_nocache )) {
2015-12-17 21:51:19 +01:00
if ( isset ( $this -> parent_compiler -> template -> compiled -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ])) {
2015-09-01 01:54:28 +02:00
$function =
2015-12-17 21:51:19 +01:00
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ];
} elseif ( isset ( $this -> parent_compiler -> template -> compiled -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ])) {
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ] =
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ];
2015-09-01 01:54:28 +02:00
$function =
2015-12-17 21:51:19 +01:00
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ];
2014-03-17 21:57:15 +00:00
}
} else {
2015-12-17 21:51:19 +01:00
if ( isset ( $this -> parent_compiler -> template -> compiled -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ])) {
2015-09-01 01:54:28 +02:00
$function =
2015-12-17 21:51:19 +01:00
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ];
} elseif ( isset ( $this -> parent_compiler -> template -> compiled -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ])) {
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ] =
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ];
2015-09-01 01:54:28 +02:00
$function =
2015-12-17 21:51:19 +01:00
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ];
2014-03-17 21:57:15 +00:00
}
}
if ( isset ( $function )) {
if ( $plugin_type == 'modifier' ) {
2015-12-17 21:51:19 +01:00
$this -> modifier_plugins [ $plugin_name ] = true ;
2014-03-17 21:57:15 +00:00
}
return $function ;
}
// loop through plugin dirs and find the plugin
$function = 'smarty_' . $plugin_type . '_' . $plugin_name ;
$file = $this -> smarty -> loadPlugin ( $function , false );
if ( is_string ( $file )) {
if ( $this -> template -> caching && ( $this -> nocache || $this -> tag_nocache )) {
2015-12-17 21:51:19 +01:00
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'file' ] =
2015-09-01 01:54:28 +02:00
$file ;
2015-12-17 21:51:19 +01:00
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ] =
2015-09-01 01:54:28 +02:00
$function ;
2014-03-17 21:57:15 +00:00
} else {
2015-12-17 21:51:19 +01:00
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'file' ] =
2015-09-01 01:54:28 +02:00
$file ;
2015-12-17 21:51:19 +01:00
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ] =
2015-09-01 01:54:28 +02:00
$function ;
2014-03-17 21:57:15 +00:00
}
if ( $plugin_type == 'modifier' ) {
2015-12-17 21:51:19 +01:00
$this -> modifier_plugins [ $plugin_name ] = true ;
2014-03-17 21:57:15 +00:00
}
return $function ;
}
if ( is_callable ( $function )) {
// plugin function is defined in the script
return $function ;
}
return false ;
}
/**
* Check for plugins by default plugin handler
*
* @ param string $tag name of tag
* @ param string $plugin_type type of plugin
2014-06-06 02:40:04 +00:00
*
2014-03-17 21:57:15 +00:00
* @ return boolean true if found
*/
public function getPluginFromDefaultHandler ( $tag , $plugin_type )
{
$callback = null ;
$script = null ;
$cacheable = true ;
2015-09-01 01:54:28 +02:00
$result = call_user_func_array ( $this -> smarty -> default_plugin_handler_func ,
array ( $tag , $plugin_type , $this -> template , & $callback , & $script , & $cacheable ));
2014-03-17 21:57:15 +00:00
if ( $result ) {
$this -> tag_nocache = $this -> tag_nocache || ! $cacheable ;
if ( $script !== null ) {
if ( is_file ( $script )) {
if ( $this -> template -> caching && ( $this -> nocache || $this -> tag_nocache )) {
2015-12-17 21:51:19 +01:00
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'nocache' ][ $tag ][ $plugin_type ][ 'file' ] =
2015-09-01 01:54:28 +02:00
$script ;
2015-12-17 21:51:19 +01:00
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'nocache' ][ $tag ][ $plugin_type ][ 'function' ] =
2015-09-01 01:54:28 +02:00
$callback ;
2014-03-17 21:57:15 +00:00
} else {
2015-12-17 21:51:19 +01:00
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'compiled' ][ $tag ][ $plugin_type ][ 'file' ] =
2015-09-01 01:54:28 +02:00
$script ;
2015-12-17 21:51:19 +01:00
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'compiled' ][ $tag ][ $plugin_type ][ 'function' ] =
2015-09-01 01:54:28 +02:00
$callback ;
2014-03-17 21:57:15 +00:00
}
2015-01-07 16:45:33 +01:00
require_once $script ;
2014-03-17 21:57:15 +00:00
} else {
$this -> trigger_template_error ( " Default plugin handler: Returned script file \" { $script } \" for \" { $tag } \" not found " );
}
}
2015-12-17 21:51:19 +01:00
if ( ! is_string ( $callback ) &&
! ( is_array ( $callback ) && is_string ( $callback [ 0 ]) && is_string ( $callback [ 1 ]))
) {
2014-03-17 21:57:15 +00:00
$this -> trigger_template_error ( " Default plugin handler: Returned callback for \" { $tag } \" must be a static function name or array of class and function name " );
}
if ( is_callable ( $callback )) {
2015-12-17 21:51:19 +01:00
$this -> default_handler_plugins [ $plugin_type ][ $tag ] = array ( $callback , true , array ());
2014-03-17 21:57:15 +00:00
return true ;
} else {
$this -> trigger_template_error ( " Default plugin handler: Returned callback for \" { $tag } \" not callable " );
}
}
return false ;
}
2015-05-13 02:09:00 +02:00
/**
* Append code segments and remove unneeded ?> <?php transitions
*
* @ param string $left
* @ param string $right
*
* @ return string
*/
2015-05-14 15:11:38 +02:00
public function appendCode ( $left , $right )
{
if ( preg_match ( '/\s*\?>\s*$/' , $left ) && preg_match ( '/^\s*<\?php\s+/' , $right )) {
2015-05-13 02:09:00 +02:00
$left = preg_replace ( '/\s*\?>\s*$/' , " \n " , $left );
$left .= preg_replace ( '/^\s*<\?php\s+/' , '' , $right );
} else {
$left .= $right ;
}
return $left ;
}
2014-03-17 21:57:15 +00:00
/**
* Inject inline code for nocache template sections
* 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 .
*
2014-06-06 02:40:04 +00:00
* @ param string $content content of template element
2014-03-17 21:57:15 +00:00
* @ param boolean $is_code true if content is compiled code
2014-06-06 02:40:04 +00:00
*
2014-03-17 21:57:15 +00:00
* @ return string content
*/
public function processNocacheCode ( $content , $is_code )
{
// If the template is not evaluated and we have a nocache section and or a nocache tag
if ( $is_code && ! empty ( $content )) {
// generate replacement code
2015-08-23 01:25:57 +02:00
if (( ! ( $this -> template -> source -> handler -> recompiled ) || $this -> forceNocache ) && $this -> template -> caching &&
2015-07-12 07:02:25 +02:00
! $this -> suppressNocacheProcessing && ( $this -> nocache || $this -> tag_nocache )
) {
2015-08-09 20:43:04 +02:00
$this -> template -> compiled -> has_nocache_code = true ;
2014-03-17 21:57:15 +00:00
$_output = addcslashes ( $content , '\'\\' );
$_output = str_replace ( " ^#^ " , " ' " , $_output );
2015-07-12 07:02:25 +02:00
$_output = " <?php echo '/*%%SmartyNocache: { $this -> nocache_hash } %%*/ " . $_output .
2016-02-09 01:27:15 +01:00
" /*/%%SmartyNocache: { $this -> nocache_hash } %%*/';?> \n " ;
2014-03-17 21:57:15 +00:00
// make sure we include modifier plugins for nocache code
foreach ( $this -> modifier_plugins as $plugin_name => $dummy ) {
2015-12-17 21:51:19 +01:00
if ( isset ( $this -> parent_compiler -> template -> compiled -> required_plugins [ 'compiled' ][ $plugin_name ][ 'modifier' ])) {
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'nocache' ][ $plugin_name ][ 'modifier' ] =
$this -> parent_compiler -> template -> compiled -> required_plugins [ 'compiled' ][ $plugin_name ][ 'modifier' ];
2014-03-17 21:57:15 +00:00
}
}
} else {
$_output = $content ;
}
} else {
$_output = $content ;
}
$this -> modifier_plugins = array ();
$this -> suppressNocacheProcessing = false ;
$this -> tag_nocache = false ;
return $_output ;
}
2015-07-01 03:23:40 +02:00
/**
* Get Id
*
* @ param string $input
*
* @ return bool | string
*/
public function getId ( $input )
{
2016-02-05 17:41:11 +01:00
if ( preg_match ( '~^([\'"]*)([0-9]*[a-zA-Z_]\w*)\1$~' , $input , $match )) {
return $match [ 2 ];
2015-07-01 03:23:40 +02:00
}
return false ;
}
/**
* Get variable name from string
*
* @ param string $input
*
* @ return bool | string
*/
public function getVariableName ( $input )
{
2015-07-06 03:12:25 +02:00
if ( preg_match ( '~^[$]_smarty_tpl->tpl_vars\[[\'"]*([0-9]*[a-zA-Z_]\w*)[\'"]*\]->value$~' , $input , $match )) {
2015-12-17 21:51:19 +01:00
return $match [ 1 ];
2015-07-01 03:23:40 +02:00
}
return false ;
}
2016-02-05 17:41:11 +01:00
/**
* Set nocache flag in variable or create new variable
*
* @ param string $varName
*/
2016-02-09 01:27:15 +01:00
public function setNocacheInVariable ( $varName )
{
2016-02-05 17:41:11 +01:00
// create nocache var to make it know for further compiling
if ( $_var = $this -> getId ( $varName )) {
if ( isset ( $this -> template -> tpl_vars [ $_var ])) {
$this -> template -> tpl_vars [ $_var ] = clone $this -> template -> tpl_vars [ $_var ];
$this -> template -> tpl_vars [ $_var ] -> nocache = true ;
} else {
$this -> template -> tpl_vars [ $_var ] = new Smarty_Variable ( null , true );
}
}
}
/**
* @ param array $_attr tag attributes
* @ param array $validScopes
*
* @ return int | string
* @ throws \SmartyCompilerException
*/
2016-02-09 01:27:15 +01:00
public function convertScope ( $_attr , $validScopes )
{
2016-02-05 17:41:11 +01:00
$_scope = Smarty :: SCOPE_LOCAL ;
if ( isset ( $_attr [ 'scope' ])) {
$_scopeName = trim ( $_attr [ 'scope' ], " ' \" " );
if ( is_numeric ( $_scopeName ) && in_array ( $_scopeName , $validScopes )) {
$_scope = $_scopeName ;
} elseif ( is_string ( $_scopeName )) {
$_scopeName = trim ( $_scopeName , " ' \" " );
$_scope = isset ( $validScopes [ $_scopeName ]) ? $validScopes [ $_scopeName ] : false ;
} else {
$_scope = false ;
}
if ( $_scope === false ) {
$err = var_export ( $_scopeName , true );
$this -> trigger_template_error ( " illegal value ' { $err } ' for \" scope \" attribute " , null , true );
}
if ( isset ( $_attr [ 'bubble_up' ]) && $_attr [ 'bubble_up' ]) {
$_scope += Smarty :: SCOPE_BUBBLE_UP ;
}
}
return $_scope ;
}
2014-11-08 21:27:53 +01:00
/**
* Generate nocache code string
*
* @ param string $code PHP code
*
* @ return string
*/
public function makeNocacheCode ( $code )
{
2015-07-12 07:02:25 +02:00
return " echo '/*%%SmartyNocache: { $this -> nocache_hash } %%*/<?php " .
2016-02-09 01:27:15 +01:00
str_replace ( " ^#^ " , " ' " , addcslashes ( $code , '\'\\' )) .
" ?>/*/%%SmartyNocache: { $this -> nocache_hash } %%*/'; \n " ;
2014-11-08 21:27:53 +01:00
}
2014-03-17 21:57:15 +00:00
/**
* display compiler error messages without dying
* 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 .
* If parameter $args contains a string this is used as error message
*
2015-08-06 01:19:11 +02:00
* @ param string $args individual error message or null
* @ param string $line line - number
* @ param null | bool $tagline if true the line number of last tag
2014-06-06 02:40:04 +00:00
*
2015-08-06 01:19:11 +02:00
* @ throws \SmartyCompilerException when an unexpected token is found
2014-03-17 21:57:15 +00:00
*/
2015-08-06 01:19:11 +02:00
public function trigger_template_error ( $args = null , $line = null , $tagline = null )
2014-03-17 21:57:15 +00:00
{
2015-08-06 01:19:11 +02:00
$lex = $this -> parser -> lex ;
if ( $tagline === true ) {
// get line number of Tag
$line = $lex -> taglineno ;
} elseif ( ! isset ( $line )) {
// get template source line which has error
$line = $lex -> line ;
} else {
$line = ( int ) $line ;
2014-03-17 21:57:15 +00:00
}
2015-08-06 01:19:11 +02:00
2015-08-01 14:28:39 +02:00
if ( in_array ( $this -> template -> source -> type , array ( 'eval' , 'string' ))) {
2015-09-01 01:54:28 +02:00
$templateName = $this -> template -> source -> type . ':' . trim ( preg_replace ( '![\t\r\n]+!' , ' ' ,
strlen ( $lex -> data ) > 40 ?
substr ( $lex -> data , 0 , 40 ) .
'...' : $lex -> data ));
2015-08-01 14:28:39 +02:00
} else {
$templateName = $this -> template -> source -> type . ':' . $this -> template -> source -> filepath ;
}
2014-06-06 02:40:04 +00:00
// $line += $this->trace_line_offset;
2015-08-06 01:19:11 +02:00
$match = preg_split ( " / \n / " , $lex -> data );
2015-09-01 01:54:28 +02:00
$error_text =
'Syntax error in template "' . ( empty ( $this -> trace_filepath ) ? $templateName : $this -> trace_filepath ) .
'" on line ' . ( $line + $this -> trace_line_offset ) . ' "' .
2015-12-17 21:51:19 +01:00
trim ( preg_replace ( '![\t\r\n]+!' , ' ' , $match [ $line - 1 ])) . '" ' ;
2014-03-17 21:57:15 +00:00
if ( isset ( $args )) {
// individual error message
$error_text .= $args ;
} else {
2015-05-05 03:27:16 +02:00
$expect = array ();
2014-03-17 21:57:15 +00:00
// expected token from parser
2015-08-06 01:19:11 +02:00
$error_text .= ' - Unexpected "' . $lex -> value . '"' ;
2014-03-17 21:57:15 +00:00
if ( count ( $this -> parser -> yy_get_expected_tokens ( $this -> parser -> yymajor )) <= 4 ) {
foreach ( $this -> parser -> yy_get_expected_tokens ( $this -> parser -> yymajor ) as $token ) {
2015-12-17 21:51:19 +01:00
$exp_token = $this -> parser -> yyTokenName [ $token ];
if ( isset ( $lex -> smarty_token_names [ $exp_token ])) {
2014-03-17 21:57:15 +00:00
// token type from lexer
2015-12-17 21:51:19 +01:00
$expect [] = '"' . $lex -> smarty_token_names [ $exp_token ] . '"' ;
2014-03-17 21:57:15 +00:00
} else {
// otherwise internal token name
2015-12-17 21:51:19 +01:00
$expect [] = $this -> parser -> yyTokenName [ $token ];
2014-03-17 21:57:15 +00:00
}
}
$error_text .= ', expected one of: ' . implode ( ' , ' , $expect );
}
}
$e = new SmartyCompilerException ( $error_text );
$e -> line = $line ;
2015-12-17 21:51:19 +01:00
$e -> source = trim ( preg_replace ( '![\t\r\n]+!' , ' ' , $match [ $line - 1 ]));
2014-03-17 21:57:15 +00:00
$e -> desc = $args ;
$e -> template = $this -> template -> source -> filepath ;
throw $e ;
}
2016-02-05 17:41:11 +01:00
/**
* Return var_export () value with all white spaces removed
*
* @ param mixed $value
*
* @ return string
*/
2016-02-09 01:27:15 +01:00
public function getVarExport ( $value )
{
2016-02-05 17:41:11 +01:00
return preg_replace ( '/\s/' , '' , var_export ( $value , true ));
}
/**
* Check if $value contains variable elements
*
* @ param mixed $value
*
* @ return bool | int
*/
2016-02-09 01:27:15 +01:00
public function isVariable ( $value )
{
2016-02-05 17:41:11 +01:00
if ( is_string ( $value )) {
return preg_match ( '/[$(]/' , $value );
}
if ( is_bool ( $value ) || is_numeric ( $value )) {
return false ;
}
if ( is_array ( $value )) {
2016-02-09 01:27:15 +01:00
foreach ( $value as $k => $v ) {
2016-02-05 17:41:11 +01:00
if ( $this -> isVariable ( $k ) || $this -> isVariable ( $v )) {
return true ;
}
}
return false ;
}
return false ;
}
2016-02-09 01:15:12 +01:00
/**
* Get new prefix variable name
*
* @ return string
*/
public function getNewPrefixVariable ()
{
self :: $prefixVariableNumber ++ ;
return $this -> getPrefixVariable ();
}
/**
* Get current prefix variable name
*
* @ return string
*/
public function getPrefixVariable ()
{
return '$_prefixVariable' . self :: $prefixVariableNumber ;
}
/**
* append code to prefix buffer
*
* @ param string $code
*/
public function appendPrefixCode ( $code )
{
$this -> prefix_code [] = $code ;
}
2014-03-17 21:57:15 +00:00
}