From db684f61516ae5471de18b22e7a30bf1c141efc4 Mon Sep 17 00:00:00 2001 From: Rob Lensen Date: Thu, 18 Jan 2018 00:23:24 +0100 Subject: [PATCH] Update Smarty to 3.1.3 --- include/smarty/INHERITANCE_RELEASE_NOTES.txt | 22 +- include/smarty/LICENSE | 179 ++ include/smarty/NEW_FEATURES.txt | 116 +- include/smarty/change_log.txt | 343 ++- include/smarty/libs/Autoloader.php | 54 +- include/smarty/libs/Smarty.class.php | 549 +++-- include/smarty/libs/SmartyBC.class.php | 28 +- include/smarty/libs/bootstrap.php | 17 + .../smarty/libs/plugins/block.textformat.php | 8 +- .../smarty/libs/plugins/function.counter.php | 47 +- .../smarty/libs/plugins/function.cycle.php | 50 +- .../smarty/libs/plugins/function.fetch.php | 50 +- .../libs/plugins/function.html_checkboxes.php | 48 +- .../libs/plugins/function.html_image.php | 37 +- .../libs/plugins/function.html_options.php | 32 +- .../libs/plugins/function.html_radios.php | 41 +- .../plugins/function.html_select_date.php | 97 +- .../plugins/function.html_select_time.php | 109 +- .../libs/plugins/function.html_table.php | 14 +- .../smarty/libs/plugins/function.mailto.php | 42 +- include/smarty/libs/plugins/function.math.php | 76 +- .../libs/plugins/modifier.capitalize.php | 39 +- .../libs/plugins/modifier.date_format.php | 6 +- .../libs/plugins/modifier.debug_print_var.php | 22 +- .../smarty/libs/plugins/modifier.escape.php | 29 +- .../libs/plugins/modifier.regex_replace.php | 8 +- .../smarty/libs/plugins/modifier.replace.php | 5 +- .../smarty/libs/plugins/modifier.truncate.php | 8 +- .../modifiercompiler.count_characters.php | 8 +- .../modifiercompiler.count_paragraphs.php | 2 +- .../modifiercompiler.count_sentences.php | 2 +- .../plugins/modifiercompiler.count_words.php | 5 +- .../libs/plugins/modifiercompiler.default.php | 6 +- .../libs/plugins/modifiercompiler.escape.php | 65 +- .../plugins/modifiercompiler.from_charset.php | 8 +- .../libs/plugins/modifiercompiler.indent.php | 10 +- .../libs/plugins/modifiercompiler.lower.php | 4 +- .../modifiercompiler.string_format.php | 2 +- .../libs/plugins/modifiercompiler.strip.php | 4 +- .../plugins/modifiercompiler.strip_tags.php | 4 +- .../plugins/modifiercompiler.to_charset.php | 8 +- .../plugins/modifiercompiler.unescape.php | 22 +- .../libs/plugins/modifiercompiler.upper.php | 4 +- .../plugins/modifiercompiler.wordwrap.php | 26 +- .../plugins/outputfilter.trimwhitespace.php | 45 +- .../plugins/shared.escape_special_chars.php | 57 +- .../plugins/shared.literal_compiler_param.php | 9 +- .../libs/plugins/shared.make_timestamp.php | 8 +- .../libs/plugins/shared.mb_str_replace.php | 2 +- .../libs/plugins/shared.mb_wordwrap.php | 8 +- .../libs/sysplugins/smarty_cacheresource.php | 43 +- .../smarty_cacheresource_custom.php | 50 +- .../smarty_cacheresource_keyvaluestore.php | 80 +- .../smarty/libs/sysplugins/smarty_data.php | 2 +- .../libs/sysplugins/smarty_internal_block.php | 90 + .../smarty_internal_cacheresource_file.php | 87 +- .../smarty_internal_compile_append.php | 13 +- .../smarty_internal_compile_assign.php | 90 +- .../smarty_internal_compile_block.php | 174 +- .../smarty_internal_compile_block_child.php | 54 + .../smarty_internal_compile_block_parent.php | 73 + .../smarty_internal_compile_break.php | 61 +- .../smarty_internal_compile_call.php | 8 +- .../smarty_internal_compile_capture.php | 81 +- .../smarty_internal_compile_config_load.php | 50 +- .../smarty_internal_compile_continue.php | 53 +- .../smarty_internal_compile_debug.php | 3 +- .../smarty_internal_compile_eval.php | 11 +- .../smarty_internal_compile_extends.php | 36 +- .../smarty_internal_compile_for.php | 43 +- .../smarty_internal_compile_foreach.php | 245 +- .../smarty_internal_compile_function.php | 88 +- .../sysplugins/smarty_internal_compile_if.php | 141 +- .../smarty_internal_compile_include.php | 206 +- .../smarty_internal_compile_include_php.php | 12 +- .../smarty_internal_compile_insert.php | 34 +- .../smarty_internal_compile_ldelim.php | 2 +- .../smarty_internal_compile_make_nocache.php | 64 + ..._internal_compile_private_block_plugin.php | 95 +- ...nternal_compile_private_foreachsection.php | 17 +- ...ternal_compile_private_function_plugin.php | 32 +- ...arty_internal_compile_private_modifier.php | 62 +- ..._compile_private_object_block_function.php | 81 +- ...ternal_compile_private_object_function.php | 46 +- .../smarty_internal_compile_private_php.php | 85 +- ...ernal_compile_private_print_expression.php | 74 +- ...ernal_compile_private_registered_block.php | 129 +- ...al_compile_private_registered_function.php | 43 +- ...ernal_compile_private_special_variable.php | 8 +- .../smarty_internal_compile_rdelim.php | 7 +- .../smarty_internal_compile_section.php | 283 +-- .../smarty_internal_compile_setfilter.php | 12 +- ...ty_internal_compile_shared_inheritance.php | 8 +- .../smarty_internal_compile_while.php | 60 +- .../smarty_internal_compilebase.php | 80 +- .../smarty_internal_config_file_compiler.php | 53 +- .../smarty_internal_configfilelexer.php | 189 +- .../smarty_internal_configfileparser.php | 354 +-- .../libs/sysplugins/smarty_internal_data.php | 77 +- .../libs/sysplugins/smarty_internal_debug.php | 124 +- .../smarty_internal_extension_handler.php | 114 +- ...rty_internal_method_addautoloadfilters.php | 15 +- ...ty_internal_method_adddefaultmodifiers.php | 4 +- .../smarty_internal_method_append.php | 20 +- .../smarty_internal_method_appendbyref.php | 16 +- .../smarty_internal_method_assignbyref.php | 8 +- .../smarty_internal_method_assignglobal.php | 14 +- .../smarty_internal_method_clearallcache.php | 2 +- .../smarty_internal_method_clearassign.php | 4 +- .../smarty_internal_method_clearcache.php | 5 +- ..._internal_method_clearcompiledtemplate.php | 46 +- .../smarty_internal_method_clearconfig.php | 2 +- ...marty_internal_method_compileallconfig.php | 7 +- ...ty_internal_method_compilealltemplates.php | 24 +- .../smarty_internal_method_configload.php | 161 +- .../smarty_internal_method_createdata.php | 2 +- ...rty_internal_method_getautoloadfilters.php | 4 +- ...arty_internal_method_getconfigvariable.php | 34 + .../smarty_internal_method_getconfigvars.php | 4 +- ...marty_internal_method_getdebugtemplate.php | 4 +- ...ty_internal_method_getdefaultmodifiers.php | 2 +- .../smarty_internal_method_getglobal.php | 47 + ...ty_internal_method_getregisteredobject.php | 8 +- .../smarty_internal_method_gettags.php | 12 +- ...smarty_internal_method_gettemplatevars.php | 28 +- .../smarty_internal_method_loadfilter.php | 8 +- .../smarty_internal_method_loadplugin.php | 32 +- .../smarty_internal_method_mustcompile.php | 10 +- ..._internal_method_registercacheresource.php | 7 +- .../smarty_internal_method_registerclass.php | 4 +- ...al_method_registerdefaultconfighandler.php | 2 +- ...al_method_registerdefaultpluginhandler.php | 2 +- ..._method_registerdefaulttemplatehandler.php | 24 +- .../smarty_internal_method_registerfilter.php | 10 +- .../smarty_internal_method_registerobject.php | 9 +- .../smarty_internal_method_registerplugin.php | 9 +- ...marty_internal_method_registerresource.php | 6 +- ...rty_internal_method_setautoloadfilters.php | 6 +- ...marty_internal_method_setdebugtemplate.php | 2 +- ...ty_internal_method_setdefaultmodifiers.php | 2 +- .../smarty_internal_method_unloadfilter.php | 12 +- ...nternal_method_unregistercacheresource.php | 14 +- ...marty_internal_method_unregisterfilter.php | 12 +- ...marty_internal_method_unregisterobject.php | 6 +- ...marty_internal_method_unregisterplugin.php | 12 +- ...rty_internal_method_unregisterresource.php | 10 +- .../smarty_internal_nocache_insert.php | 8 +- .../smarty_internal_parsetree_dq.php | 15 +- .../smarty_internal_parsetree_tag.php | 2 +- .../smarty_internal_parsetree_template.php | 26 +- .../smarty_internal_resource_eval.php | 3 +- .../smarty_internal_resource_extends.php | 7 +- .../smarty_internal_resource_file.php | 45 +- .../smarty_internal_resource_php.php | 20 +- .../smarty_internal_resource_registered.php | 14 +- .../smarty_internal_resource_stream.php | 3 +- .../smarty_internal_resource_string.php | 16 +- .../smarty_internal_runtime_cachemodify.php | 21 +- ...rty_internal_runtime_cacheresourcefile.php | 136 ++ .../smarty_internal_runtime_capture.php | 161 ++ .../smarty_internal_runtime_codeframe.php | 36 +- .../smarty_internal_runtime_filterhandler.php | 14 +- .../smarty_internal_runtime_foreach.php | 128 +- ...smarty_internal_runtime_getincludepath.php | 38 +- .../smarty_internal_runtime_inheritance.php | 254 +- .../smarty_internal_runtime_make_nocache.php | 56 + .../smarty_internal_runtime_tplfunction.php | 100 +- .../smarty_internal_runtime_updatecache.php | 29 +- .../smarty_internal_runtime_updatescope.php | 130 +- .../smarty_internal_runtime_writefile.php | 7 +- ...smarty_internal_smartytemplatecompiler.php | 13 +- .../sysplugins/smarty_internal_template.php | 438 +++- .../smarty_internal_templatebase.php | 107 +- .../smarty_internal_templatecompilerbase.php | 335 ++- .../smarty_internal_templatelexer.php | 242 +- .../smarty_internal_templateparser.php | 2104 ++++++++--------- .../smarty_internal_testinstall.php | 332 ++- .../sysplugins/smarty_internal_undefined.php | 42 +- .../libs/sysplugins/smarty_resource.php | 72 +- .../sysplugins/smarty_resource_recompiled.php | 45 + .../sysplugins/smarty_resource_uncompiled.php | 46 +- .../libs/sysplugins/smarty_security.php | 145 +- .../sysplugins/smarty_template_cached.php | 14 +- .../sysplugins/smarty_template_compiled.php | 208 +- .../sysplugins/smarty_template_config.php | 68 +- .../smarty_template_resource_base.php | 57 +- .../sysplugins/smarty_template_source.php | 119 +- .../libs/sysplugins/smarty_variable.php | 1 + .../sysplugins/smartycompilerexception.php | 3 + .../libs/sysplugins/smartyexception.php | 1 + 190 files changed, 7430 insertions(+), 5215 deletions(-) create mode 100644 include/smarty/LICENSE create mode 100644 include/smarty/libs/bootstrap.php create mode 100644 include/smarty/libs/sysplugins/smarty_internal_block.php create mode 100644 include/smarty/libs/sysplugins/smarty_internal_compile_block_child.php create mode 100644 include/smarty/libs/sysplugins/smarty_internal_compile_block_parent.php create mode 100644 include/smarty/libs/sysplugins/smarty_internal_compile_make_nocache.php create mode 100644 include/smarty/libs/sysplugins/smarty_internal_method_getconfigvariable.php create mode 100644 include/smarty/libs/sysplugins/smarty_internal_method_getglobal.php create mode 100644 include/smarty/libs/sysplugins/smarty_internal_runtime_cacheresourcefile.php create mode 100644 include/smarty/libs/sysplugins/smarty_internal_runtime_capture.php create mode 100644 include/smarty/libs/sysplugins/smarty_internal_runtime_make_nocache.php diff --git a/include/smarty/INHERITANCE_RELEASE_NOTES.txt b/include/smarty/INHERITANCE_RELEASE_NOTES.txt index 8b2c64a1b..c415c4ccd 100644 --- a/include/smarty/INHERITANCE_RELEASE_NOTES.txt +++ b/include/smarty/INHERITANCE_RELEASE_NOTES.txt @@ -1,3 +1,14 @@ +3.1.31-dev +New tags for inheritance parent and child +{block_parent} == {$smarty.block.parent} +{block_child} == {$smarty.block.child} + +Since 3.1.28 you can mix inheritance by extends resource with the {extends} tag. +A template called by extends resource can extend a subtemplate or chain buy the {extends} tag. +Since 3.1.31 this feature can be turned off by setting the new Smarty property Smarty::$extends_recursion to false. + + +3.1.28 Starting with version 3.1.28 template inheritance is no longer a compile time process. All {block} tag parent/child relations are resolved at run time. This does resolve all known existing restrictions (see below). @@ -5,7 +16,7 @@ This does resolve all known existing restrictions (see below). The $smarty::$inheritance_merge_compiled_includes property has been removed. Any access to it is ignored. -This does enable some new features: +New features: Any code outside root {block} tags in child templates is now executed but any output will be ignored. @@ -31,7 +42,16 @@ Any code outside root {block} tags in child templates is now executed but any ou {/if} {/block} +{block} tags can have variable names. + {block $foo} + .... + {/block} + +Starting with 3.1.28 you can mix inheritance by extends resource with the {extends} tag. +A template called by extends resource can extend a subtemplate or chain buy the {extends} tag. + +NOTE There is a BC break. If you used the extends resource {extends} tags have been ignored. THE FOLLOWING RESTRICTIONS ARE NO LONGER EXISTING: In Smarty 3.1 template inheritance is a compile time process. All the extending of {block} tags diff --git a/include/smarty/LICENSE b/include/smarty/LICENSE new file mode 100644 index 000000000..fb8ca6c6f --- /dev/null +++ b/include/smarty/LICENSE @@ -0,0 +1,179 @@ +Smarty: the PHP compiling template engine + + 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 below for more details. + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/include/smarty/NEW_FEATURES.txt b/include/smarty/NEW_FEATURES.txt index 1a51c71d9..adbc1099b 100644 --- a/include/smarty/NEW_FEATURES.txt +++ b/include/smarty/NEW_FEATURES.txt @@ -2,6 +2,114 @@ This file contains a brief description of new features which have been added to Smarty 3.1 +Smarty 3.1.31 + New tags for inheritance parent and child + ========================================= + {block_parent} == {$smarty.block.parent} + {block_child} == {$smarty.block.child} + +Smarty 3.1.30 + + Loop optimization {foreach} and {section} + ========================================= + Smarty does optimize the {foreach} and {section} loops by removing code for not needed loop + properties. + The compiler collects needed properties by scanning the current template for $item@property, + $smarty.foreach.name.property and $smarty.section.name.property. + The compiler does not know if additional properties will be needed outside the current template scope. + Additional properties can be generated by adding them with the property attribute. + + Example: + index.tpl + {foreach $from as $item properties=[iteration, index]} + {include 'sub.tpl'} + {$item.total} + {/foreach} + + sub.tpl + {$item.index} {$item.iteration} {$item.total} + + In above example code for the 'total' property is automatically generated as $item.total is used in + index.tpl. Code for 'iteration' and 'index' must be added with properties=[iteration, index]. + + New tag {make_nocache} + ====================== + Syntax: {make_nocache $foo} + + This tag makes a variable which does exists normally only while rendering the compiled template + available in the cached template for use in not cached expressions. + + Expample: + {foreach from=$list item=item} +
  • {$item.name} {make_nocache $item}{if $current==$item.id} ACTIVE{/if}
  • + {/foreach} + + The {foreach} loop is rendered while processing the compiled template, but $current is a nocache + variable. Normally the {if $current==$item.id} would fail as the $item variable is unkown in the + cached template. {make_nocache $item} does make the current $item value known in thee cached template. + + {make_nocache} is ignored when caching is disabled or the variable does exists as nocache variable. + + NOTE: if the variable value does contain objects these must have the __set_state method implemented. + + + Scope Attributes + ================ + The scope handling has been updated to cover all cases of variable assignments in templates. + + The tags {assign}, {append} direct assignments like {$foo = ...}, {$foo[...]= ...} support + the following optional scope attributes: + scope='parent' - the variable will be assigned in the current template and if the template + was included by {include} the calling template + scope='tpl_root' - the variable will be assigned in the outermost root template called by $smarty->display() + or $smarty->fetch() and is bubbled up all {include} sub-templates to the current template. + scope='smarty' - the variable will be assigned in the Smarty object and is bubbled up all {include} sub-templates + to the current template. + scope='global' - the variable will be assigned as Smarty object global variable and is bubbled up all {include} + sub-templates to the current template. + scope='root' - the variable will be assigned if a data object was used for variable definitions in the data + object or in the Smarty object otherwise and is bubbled up all {include} sub-templates to the + current template. + scope='local' - this scope has only a meaning if the tag is called within a template {function}. + The variable will be assigned in the local scope of the template function and the + template which did call the template function. + + + The {config_load} tag supports all of the above except the global scope. + + The scope attribute can be used also with the {include} tag. + Supported scope are parent, tpl_root, smarty, global and root. + A scope used together with the {include} tag will cause that with some exceptions any variable + assignment within that sub-template will update/assign the variable in other scopes according + to the above rules. It does include also variables assigned by plugins, tags supporting the assign=foo + attribute and direct assignments in {if} and {while} like {if $foo=$bar}. + Excluded are the key and value variables of {foreach}, {for} loop variables , variables passed by attributes + in {include} and direct increments/decrements like {$foo++}, {$foo--} + + Note: The scopes should be used only to the extend really need. If a variable value assigned in an included + sub-template should be returned to the calling sub-template just use {$foo='bar' scope='parent'}. + Use scopes only with variables for which it's realy needed. Avoid general scope settings with the + {include} tag as it can have a performance impact. + + The {assign}, {append}, {config_load} and {$foo...=...} tags have a new option flag 'noscope'.Thi + Example: {$foo='bar' noscope} This will assign $foo only in the current template and any scope settings + at {include} is ignored. + + + Caching + ======= + Caching does now observe the template_dir setting and will create separate cache files if required + + Compiled Templates + ================== + The template_dir setting is now encoded in the uid of the file name. + The content of the compiled template may depend on the template_dir search order + {include .... inline} is used or $smarty->merge_compiled_includes is enabled + + APC + === + If APC is enabled force an apc_compile_file() when compiled or cached template was updated + Smarty 3.1.28 OPCACHE @@ -32,7 +140,7 @@ Smarty 3.1.28 The template_dir array is searched in the order of the indices. (Could be used to change the default search order) Example: $smarty->display('[1],[0]foo.bar'); - + Filter support ============== Optional filter names @@ -47,7 +155,7 @@ Smarty 3.1.28 If you register multiple closures register each with a unique filter name. - $smarty->registerFilter('pre', function($source) {return $source;}, 'closure_1'); - $smarty->registerFilter('pre', function($source) {return $source;}, 'closure_2'); - + Smarty 3.1.22 @@ -120,7 +228,7 @@ Smarty 3.1.22 Debugging ========= The layout of the debug window has been changed for better readability - + New class constants Smarty::DEBUG_OFF Smarty::DEBUG_ON @@ -129,5 +237,3 @@ Smarty 3.1.22 Smarty::DEBUG_INDIVIDUAL will create for each display() and fetch() call an individual debug window. - . - diff --git a/include/smarty/change_log.txt b/include/smarty/change_log.txt index dadc5d17d..1d42b0a76 100644 --- a/include/smarty/change_log.txt +++ b/include/smarty/change_log.txt @@ -1,11 +1,348 @@ - ===== 3.1.29 ===== (21.12.2015) +===== 3.1.31 ===== (14.12.2016) + 23.11.2016 + - move template object cache into static variables + + 19.11.2016 + - bugfix inheritance root child templates containing nested {block}{/block} could call sub-bock content from parent + template https://github.com/smarty-php/smarty/issues/317 + - change version checking + + 11.11.2016 + - bugfix when Smarty is using a cached template object on Smarty::fetch() or Smarty::isCached() the inheritance data + must be removed https://github.com/smarty-php/smarty/issues/312 + - smaller speed optimization + + 08.11.2016 + - add bootstrap file to load and register Smarty_Autoloader. Change composer.json to make it known to composer + + 07.11.2016 + - optimization of lexer speed https://github.com/smarty-php/smarty/issues/311 + + 27.10.2016 + - bugfix template function definitions array has not been cached between Smarty::fetch() and Smarty::display() calls + https://github.com/smarty-php/smarty/issues/301 + + 23.10.2016 + - improvement/bugfix when Smarty::fetch() is called on a template object the inheritance and tplFunctions property + should be copied to the called template object + + 21.10.2016 + - bugfix for compile locking touched timestamp of old compiled file was not restored on compilation error https://github.com/smarty-php/smarty/issues/308 + + 20.10.2016 + - bugfix nocache code was not removed in cache file when subtemplate did contain PHP short tags in text but no other + nocache code https://github.com/smarty-php/smarty/issues/300 + + 19.10.2016 + - bugfix {make_nocache $var} did fail when variable value did contain '\' https://github.com/smarty-php/smarty/issues/305 + - bugfix {make_nocache $var} remove spaces from variable value https://github.com/smarty-php/smarty/issues/304 + + 12.10.2016 + - bugfix {include} with template names including variable or constants could fail after bugfix from + 28.09.2016 https://github.com/smarty-php/smarty/issues/302 + + 08.10.2016 + - optimization move runtime extension for template functions into Smarty objects + + 29.09.2016 + - improvement new Smarty::$extends_recursion property to disable execution of {extends} in templates called by extends resource + https://github.com/smarty-php/smarty/issues/296 + + 28.09.2016 + - bugfix the generated code for calling a subtemplate must pass the template resource name in single quotes https://github.com/smarty-php/smarty/issues/299 + - bugfix nocache hash was not removed for tags in subtemplates https://github.com/smarty-php/smarty/issues/300 + + 27.09.2016 + - bugfix when Smarty does use an internally cached template object on Smarty::fetch() calls + the template and config variables must be cleared https://github.com/smarty-php/smarty/issues/297 + + 20.09.2016 + - bugfix some $smarty special template variables are no longer accessed as real variable. + using them on calls like {if isset($smarty.foo)} or {if empty($smarty.foo)} will fail + http://www.smarty.net/forums/viewtopic.php?t=26222 + - temporary fix for https://github.com/smarty-php/smarty/issues/293 main reason still under investigation + - improvement new tags {block_parent} {block_child} in template inheritance + + 19.09.2016 + - optimization clear compiled and cached folder completely on detected version change + - cleanup convert cache resource file method clear into runtime extension + + 15.09.2016 + - bugfix assigning a variable in if condition by function like {if $value = array_shift($array)} the function got called twice https://github.com/smarty-php/smarty/issues/291 + - bugfix function plugins called with assign attribute like {foo assign='bar'} did not output returned content because + because assumption was made that it was assigned to a variable https://github.com/smarty-php/smarty/issues/292 + - bugfix calling $smarty->isCached() on a not existing cache file with $smarty->cache_locking = true; could cause a 10 second delay http://www.smarty.net/forums/viewtopic.php?t=26282 + - improvement make Smarty::clearCompiledTemplate() on custom resource independent from changes of templateId computation + + 11.09.2016 + - improvement {math} misleading E_USER_WARNING messages when parameter value = null https://github.com/smarty-php/smarty/issues/288 + - improvement move often used code snippets into methods + - performance Smarty::configLoad() did load unneeded template source object + + 09.09.2016 + - bugfix/optimization {foreach} did not execute the {foreachelse} when iterating empty objects https://github.com/smarty-php/smarty/pull/287 + - bugfix {foreach} must keep the @properties when restoring a saved $item variable as the properties might be used outside {foreach} https://github.com/smarty-php/smarty/issues/267 + - improvement {foreach} observe {break n} and {continue n} nesting levels when restoring saved $item and $key variables + + 08.09.2016 + - bugfix implement wrapper for removed method getConfigVariable() https://github.com/smarty-php/smarty/issues/286 + + 07.09.2016 + - bugfix using nocache like attribute with value true like {plugin nocache=true} did not work https://github.com/smarty-php/smarty/issues/285 + - bugfix uppercase TRUE, FALSE and NULL did not work when security was enabled https://github.com/smarty-php/smarty/issues/282 + - bugfix when {foreach} was looping over an object the total property like {$item@total} did always return 1 https://github.com/smarty-php/smarty/issues/281 + - bugfix {capture}{/capture} did add in 3.1.30 unintended additional blank lines https://github.com/smarty-php/smarty/issues/268 + + 01.09.2016 + - performance require_once should be called only once for shared plugins https://github.com/smarty-php/smarty/issues/280 + + 26.08.2016 + - bugfix change of 23.08.2016 failed on linux when use_include_path = true + + 23.08.2016 + - bugfix remove constant DS as shortcut for DIRECTORY_SEPARATOR as the user may have defined it to something else https://github.com/smarty-php/smarty/issues/277 + + 20.08-2016 + - bugfix {config_load ... scope="global"} shall not throw an arror but fallback to scope="smarty" https://github.com/smarty-php/smarty/issues/274 + - bugfix {make_nocache} failed when using composer autoloader https://github.com/smarty-php/smarty/issues/275 + + 14.08.2016 + - bugfix $smarty_>debugging = true; did E_NOTICE messages when {eval} tag was used https://github.com/smarty-php/smarty/issues/266 + - bugfix Class 'Smarty_Internal_Runtime_ValidateCompiled' not found when upgrading from some older Smarty versions with existing + compiled or cached template files https://github.com/smarty-php/smarty/issues/269 + - optimization remove unneeded call to update acopes when {assign} scope and template scope was local (default) + +===== 3.1.30 ===== (07.08.2016) + + 07.08.2016 + - bugfix update of 04.08.2016 was incomplete + + 05.08.2016 + - bugfix compiling of templates failed when the Smarty delimiter did contain '/' https://github.com/smarty-php/smarty/issues/264 + - updated error checking at template and config default handler + + 04.08.2016 + - improvement move template function source parameter into extension + + 26.07.2016 + - optimization unneeded loading of compiled resource + + 24.07.2016 + - regression this->addPluginsDir('/abs/path/to/dir') adding absolute path without trailing '/' did fail https://github.com/smarty-php/smarty/issues/260 + + 23.07.2016 + - bugfix setTemplateDir('/') and setTemplateDir('') did create wrong absolute filepath https://github.com/smarty-php/smarty/issues/245 + - optimization of filepath normalization + - improvement remove double function declaration in plugin shared.escape_special_cars.php https://github.com/smarty-php/smarty/issues/229 + + 19.07.2016 + - bugfix multiple {include} with relative filepath within {block}{/block} could fail https://github.com/smarty-php/smarty/issues/246 + - bugfix {math} shell injection vulnerability patch provided by Tim Weber + + 18.07.2016 + - bugfix {foreach} if key variable and item@key attribute have been used both the key variable was not updated https://github.com/smarty-php/smarty/issues/254 + - bugfix modifier on plugins like {plugin|modifier ... } did fail when the plugin does return an array https://github.com/smarty-php/smarty/issues/228 + - bugfix avoid opcache_invalidate to result in ErrorException when opcache.restrict_api is not empty https://github.com/smarty-php/smarty/pull/244 + - bugfix multiple {include} with relative filepath within {block}{/block} could fail https://github.com/smarty-php/smarty/issues/246 + + 14.07.2016 + - bugfix wrong parameter on compileAllTemplates() and compileAllConfig() https://github.com/smarty-php/smarty/issues/231 + + 13.07.2016 + - bugfix PHP 7 compatibility on registered compiler plugins https://github.com/smarty-php/smarty/issues/241 + - update testInstall() https://github.com/smarty-php/smarty/issues/248https://github.com/smarty-php/smarty/issues/248 + - bugfix enable debugging could fail when template objects did already exists https://github.com/smarty-php/smarty/issues/237 + - bugfix template function data should be merged when loading subtemplate https://github.com/smarty-php/smarty/issues/240 + - bugfix wrong parameter on compileAllTemplates() https://github.com/smarty-php/smarty/issues/231 + + 12.07.2016 + - bugfix {foreach} item variable must be created also on empty from array https://github.com/smarty-php/smarty/issues/238 and https://github.com/smarty-php/smarty/issues/239 + - bugfix enableSecurity() must init cache flags https://github.com/smarty-php/smarty/issues/247 + + 27.05.2016 + - bugfix/improvement of compileAlltemplates() follow symlinks in template folder (PHP >= 5.3.1) https://github.com/smarty-php/smarty/issues/224 + clear internal cache and expension handler for each template to avoid possible conflicts https://github.com/smarty-php/smarty/issues/231 + + 16.05.2016 + - optimization {foreach} compiler and processing + - broken PHP 5.3 and 5.4 compatibility + + 15.05.2016 + - optimization and cleanup of resource code + + 10.05.2016 + - optimization of inheritance processing + + 07.05.2016 + -bugfix Only variables should be assigned by reference https://github.com/smarty-php/smarty/issues/227 + + 02.05.2016 + - enhancement {block} tag names can now be variable https://github.com/smarty-php/smarty/issues/221 + + 01.05.2016 + - bugfix same relative filepath at {include} called from template in different folders could display wrong sub-template + + 29.04.2016 + - bugfix {strip} remove space on linebreak between html tags https://github.com/smarty-php/smarty/issues/213 + + 24.04.2016 + - bugfix nested {include} with relative file path could fail when called in {block} ... {/block} https://github.com/smarty-php/smarty/issues/218 + + 14.04.2016 + - bugfix special variable {$smarty.capture.name} was not case sensitive on name https://github.com/smarty-php/smarty/issues/210 + - bugfix the default template handler must calculate the source uid https://github.com/smarty-php/smarty/issues/205 + + 13.04.2016 + - bugfix template inheritance status must be saved when calling sub-templates https://github.com/smarty-php/smarty/issues/215 + + 27.03.2016 + - bugfix change of 11.03.2016 cause again {capture} data could not been seen in other templates with {$smarty.capture.name} https://github.com/smarty-php/smarty/issues/153 + + 11.03.2016 + - optimization of capture and security handling + - improvement $smarty->clearCompiledTemplate() should return on recompiled or uncompiled resources + + 10.03.2016 + - optimization of resource processing + + 09.03.2016 + - improvement rework of 'scope' attribute handling see see NEW_FEATURES.txt https://github.com/smarty-php/smarty/issues/194 + https://github.com/smarty-php/smarty/issues/186 https://github.com/smarty-php/smarty/issues/179 + - bugfix correct Autoloader update of 2.3.2014 https://github.com/smarty-php/smarty/issues/199 + + 04.03.2016 + - bugfix change from 01.03.2016 will cause $smarty->isCached(..) failure if called multiple time for same template + (forum topic 25935) + + 02.03.2016 + - revert autoloader optimizations because of unexplainable warning when using plugins https://github.com/smarty-php/smarty/issues/199 + + 01.03.2016 + - bugfix template objects must be cached on $smarty->fetch('foo.tpl) calls incase the template is fetched + multiple times (forum topic 25909) + + 25.02.2016 + - bugfix wrong _realpath with 4 or more parent-directories https://github.com/smarty-php/smarty/issues/190 + - optimization of _realpath + - bugfix instanceof expression in template code must be treated as value https://github.com/smarty-php/smarty/issues/191 + + 20.02.2016 + - bugfix {strip} must keep space between hmtl tags. Broken by changes of 10.2.2016 https://github.com/smarty-php/smarty/issues/184 + - new feature/bugfix {foreach}{section} add 'properties' attribute to force compilation of loop properties + see NEW_FEATURES.txt https://github.com/smarty-php/smarty/issues/189 + + 19.02.2016 + - revert output buffer flushing on display, echo content again because possible problems when PHP files had + characters (newline} after ?> at file end https://github.com/smarty-php/smarty/issues/187 + + 14.02.2016 + - new tag {make_nocache} read NEW_FEATURES.txt https://github.com/smarty-php/smarty/issues/110 + - optimization of sub-template processing + - bugfix using extendsall as default resource and {include} inside {block} tags could produce unexpected results https://github.com/smarty-php/smarty/issues/183 + - optimization of tag attribute compiling + - optimization make compiler tag object cache static for higher compilation speed + + 11.02.2016 + - improvement added KnockoutJS comments to trimwhitespace outputfilter https://github.com/smarty-php/smarty/issues/82 + https://github.com/smarty-php/smarty/pull/181 + + 10.02.2016 + - bugfix {strip} must keep space on output creating smarty tags within html tags https://github.com/smarty-php/smarty/issues/177 + - bugfix wrong precedence on special if conditions like '$foo is ... by $bar' could cause wrong code https://github.com/smarty-php/smarty/issues/178 + - improvement because of ambiguities the inline constant support has been removed from the $foo.bar syntax https://github.com/smarty-php/smarty/issues/149 + - bugfix other {strip} error with output tags between hmtl https://github.com/smarty-php/smarty/issues/180 + + 09.02.2016 + - move some code from parser into compiler + - reformat all code for unique style + - update/bugfix scope attribute handling reworked. Read the newfeatures.txt file + + 05.02.2016 + - improvement internal compiler changes + + 01.02.2016 + - bugfix {foreach} compilation failed when $smarty->merge_compiled_includes = true and pre-filters are used. + + 29.01.2016 + - bugfix implement replacement code for _tag_stack property https://github.com/smarty-php/smarty/issues/151 + + 28.01.2016 + - bugfix allow windows network filepath or wrapper (forum topic 25876) https://github.com/smarty-php/smarty/issues/170 + - bugfix if fetch('foo.tpl') is called on a template object the $parent parameter should default to the calling template object https://github.com/smarty-php/smarty/issues/152 + + 27.01.2016 + - revert bugfix compiling {section} did create warning + - bugfix {$smarty.section.customer.loop} did throw compiler error https://github.com/smarty-php/smarty/issues/161 + update of yesterdays fix + - bugfix string resource could inject code at {block} or inline subtemplates through PHP comments https://github.com/smarty-php/smarty/issues/157 + - bugfix output filters did not observe nocache code flhttps://github.com/smarty-php/smarty/issues/154g https://github.com/smarty-php/smarty/issues/160 + - bugfix {extends} with relative file path did not work https://github.com/smarty-php/smarty/issues/154 + https://github.com/smarty-php/smarty/issues/158 + - bugfix {capture} data could not been seen in other templates with {$smarty.capture.name} https://github.com/smarty-php/smarty/issues/153 + + 26.01.2016 + - improvement observe Smarty::$_CHARSET in debugging console https://github.com/smarty-php/smarty/issues/169 + - bugfix compiling {section} did create warning + - bugfix {$smarty.section.customer.loop} did throw compiler error https://github.com/smarty-php/smarty/issues/161 + + 02.01.2016 + - update scope handling + - optimize block plugin compiler + - improvement runtime checks if registered block plugins are callable + + 01.01.2016 + - remove Smarty::$resource_cache_mode property + + 31.12.2015 + - optimization of {assign}, {if} and {while} compiled code + + 30.12.2015 + - bugfix plugin names starting with "php" did not compile https://github.com/smarty-php/smarty/issues/147 + + 29.12.2015 + - bugfix Smarty::error_reporting was not observed when display() or fetch() was called on template objects https://github.com/smarty-php/smarty/issues/145 + + 28.12.2015 + - optimization of {foreach} code size and processing + + 27.12.2015 + - improve inheritance code + - update external methods + - code fixes + - PHPdoc updates + + 25.12.2015 + - compile {block} tag code and its processing into classes + - optimization replace hhvm extension by inline code + - new feature If ACP is enabled force an apc_compile_file() when compiled or cached template was updated + + 24.12.2015 + - new feature Compiler does now observe the template_dir setting and will create separate compiled files if required + - bugfix post filter did fail on template inheritance https://github.com/smarty-php/smarty/issues/144 + + 23.12.2015 + - optimization move internal method decodeProperties back into template object + - optimization move subtemplate processing back into template object + - new feature Caching does now observe the template_dir setting and will create separate cache files if required + + 22.12.2015 + - change $xxx_dir properties from private to protected in case Smarty class gets extended + - code optimizations + + 21.12.2015 + - bugfix a filepath starting with '/' or '\' on windows should normalize to the root dir + of current working drive https://github.com/smarty-php/smarty/issues/134 + - optimization of filepath normalization + - bugfix {strip} must remove all blanks between html tags https://github.com/smarty-php/smarty/issues/136 + + ===== 3.1.29 ===== (21.12.2015) 21.12.2015 - optimization improve speed of filetime checks on extends and extendsall resource 20.12.2015 - bugfix failure when the default resource type was set to 'extendsall' https://github.com/smarty-php/smarty/issues/123 - update compilation of Smarty special variables - - bugfix add addition check for OS type on normalizaition of file path https://github.com/smarty-php/smarty/issues/134 + - bugfix add addition check for OS type on normalization of file path https://github.com/smarty-php/smarty/issues/134 - bugfix the source uid of the extendsall resource must contain $template_dir settings https://github.com/smarty-php/smarty/issues/123 19.12.2015 @@ -15,7 +352,7 @@ - improvement make sure that compiled and cache templates never can contain a trailing '?>? 18.12.2015 - - bugfix regression when modifier parameter was follow by math https://github.com/smarty-php/smarty/issues/132 + - bugfix regression when modifier parameter was followed by math https://github.com/smarty-php/smarty/issues/132 17.12.2015 - bugfix {$smarty.capture.nameFail} did lowercase capture name https://github.com/smarty-php/smarty/issues/135 diff --git a/include/smarty/libs/Autoloader.php b/include/smarty/libs/Autoloader.php index 7d0c388a6..d3b039caa 100644 --- a/include/smarty/libs/Autoloader.php +++ b/include/smarty/libs/Autoloader.php @@ -11,11 +11,12 @@ * @package Smarty * @author Uwe Tews * Usage: - * require_once '...path/Autoloader.php'; - * Smarty_Autoloader::register(); - * $smarty = new Smarty(); - * Note: This autoloader is not needed if you use Composer. - * Composer will automatically add the classes of the Smarty package to it common autoloader. + * require_once '...path/Autoloader.php'; + * Smarty_Autoloader::register(); + * or + * include '...path/bootstarp.php'; + * + * $smarty = new Smarty(); */ class Smarty_Autoloader { @@ -24,14 +25,14 @@ class Smarty_Autoloader * * @var string */ - public static $SMARTY_DIR = ''; + public static $SMARTY_DIR = null; /** * Filepath to Smarty internal plugins * * @var string */ - public static $SMARTY_SYSPLUGINS_DIR = ''; + public static $SMARTY_SYSPLUGINS_DIR = null; /** * Array with Smarty core classes and their filename @@ -57,7 +58,7 @@ class Smarty_Autoloader set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false ) { $registeredAutoLoadFunctions = spl_autoload_functions(); - if (!isset($registeredAutoLoadFunctions['spl_autoload'])) { + if (!isset($registeredAutoLoadFunctions[ 'spl_autoload' ])) { spl_autoload_register(); } } else { @@ -89,36 +90,21 @@ class Smarty_Autoloader */ public static function autoload($class) { + if ($class[ 0 ] !== 'S' && strpos($class, 'Smarty') !== 0) { + return; + } $_class = strtolower($class); - $file = self::$SMARTY_SYSPLUGINS_DIR . $_class . '.php'; - if (strpos($_class, 'smarty_internal_') === 0) { - if (strpos($_class, 'smarty_internal_compile_') === 0) { - if (is_file($file)) { - require $file; - } - return; + if (isset(self::$rootClasses[ $_class ])) { + $file = self::$SMARTY_DIR . self::$rootClasses[ $_class ]; + if (is_file($file)) { + include $file; } - @include $file; - return; - } - if (preg_match('/^(smarty_(((template_(source|config|cache|compiled|resource_base))|((cached|compiled)?resource)|(variable|security)))|(smarty(bc)?)$)/', - $_class, $match)) { - if (!empty($match[3])) { - @include $file; - return; - } elseif (!empty($match[9]) && isset(self::$rootClasses[$_class])) { - $file = self::$rootClasses[$_class]; - require $file; - return; + } else { + $file = self::$SMARTY_SYSPLUGINS_DIR . $_class . '.php'; + if (is_file($file)) { + include $file; } } - if (0 !== strpos($_class, 'smarty')) { - return; - } - if (is_file($file)) { - require $file; - return; - } return; } } diff --git a/include/smarty/libs/Smarty.class.php b/include/smarty/libs/Smarty.class.php index a029f942e..57eedfb93 100644 --- a/include/smarty/libs/Smarty.class.php +++ b/include/smarty/libs/Smarty.class.php @@ -21,28 +21,21 @@ * smarty-discussion-subscribe@googlegroups.com * * @link http://www.smarty.net/ - * @copyright 2015 New Digital Group, Inc. - * @copyright 2015 Uwe Tews + * @copyright 2016 New Digital Group, Inc. + * @copyright 2016 Uwe Tews * @author Monte Ohrt * @author Uwe Tews * @author Rodney Rehm * @package Smarty - * @version 3.1.29 + * @version 3.1.31 */ -/** - * define shorthand directory separator constant - */ -if (!defined('DS')) { - define('DS', DIRECTORY_SEPARATOR); -} - /** * set SMARTY_DIR to absolute path to Smarty library files. * Sets SMARTY_DIR only if user application has not already defined it. */ if (!defined('SMARTY_DIR')) { - define('SMARTY_DIR', dirname(__FILE__) . DS); + define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR); } /** @@ -50,10 +43,10 @@ if (!defined('SMARTY_DIR')) { * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it. */ if (!defined('SMARTY_SYSPLUGINS_DIR')) { - define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DS); + define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DIRECTORY_SEPARATOR); } if (!defined('SMARTY_PLUGINS_DIR')) { - define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS); + define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DIRECTORY_SEPARATOR); } if (!defined('SMARTY_MBSTRING')) { define('SMARTY_MBSTRING', function_exists('mb_get_info')); @@ -73,23 +66,16 @@ if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) { } /** - * Try loading the Smarty_Internal_Data class - * If we fail we must load Smarty's autoloader. - * Otherwise we may have a global autoloader like Composer + * Load Smarty_Autoloader */ -if (!class_exists('Smarty_Autoloader', false)) { - if (!class_exists('Smarty_Internal_Data', true)) { - require_once dirname(__FILE__) . '/Autoloader.php'; - Smarty_Autoloader::registerBC(); - } +if (!class_exists('Smarty_Autoloader')) { + include __DIR__ . '/bootstrap.php'; } /** * Load always needed external class files */ -if (!class_exists('Smarty_Internal_Data', false)) { - require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php'; -} +require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php'; require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_extension_handler.php'; require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php'; require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php'; @@ -97,17 +83,21 @@ require_once SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php'; require_once SMARTY_SYSPLUGINS_DIR . 'smarty_variable.php'; require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_source.php'; require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_resource_base.php'; +require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_resource_file.php'; /** * This is the main Smarty class * * @package Smarty * + * The following methods will be dynamically loaded by the extension handler when they are called. + * They are located in a corresponding Smarty_Internal_Method_xxxx class + * * @method int clearAllCache(int $exp_time = null, string $type = null) * @method int clearCache(string $template_name, string $cache_id = null, string $compile_id = null, int $exp_time = null, string $type = null) - * @method int compileAllTemplates(Smarty $smarty, string $extension = '.tpl', bool $force_compile = false, int $time_limit = 0, int $max_errors = null) - * @method int compileAllConfig(Smarty $smarty, string $extension = '.conf', bool $force_compile = false, int $time_limit = 0, int $max_errors = null) - * + * @method int compileAllTemplates(string $extension = '.tpl', bool $force_compile = false, int $time_limit = 0, int $max_errors = null) + * @method int compileAllConfig(string $extension = '.conf', bool $force_compile = false, int $time_limit = 0, int $max_errors = null) + * @method int clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null) */ class Smarty extends Smarty_Internal_TemplateBase { @@ -118,12 +108,12 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = '3.1.29'; + const SMARTY_VERSION = '3.1.31'; /** * define variable scopes */ - const SCOPE_LOCAL = 0; + const SCOPE_LOCAL = 1; const SCOPE_PARENT = 2; @@ -135,8 +125,6 @@ class Smarty extends Smarty_Internal_TemplateBase const SCOPE_GLOBAL = 32; - const SCOPE_BUBBLE_UP = 64; - /** * define caching modes */ @@ -206,6 +194,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Resource caching modes + * (not used since 3.1.30) */ const RESOURCE_CACHE_OFF = 0; @@ -288,7 +277,21 @@ class Smarty extends Smarty_Internal_TemplateBase * * @var array */ - private $template_dir = array('./templates/'); + protected $template_dir = array('./templates/'); + + /** + * flags for normalized template directory entries + * + * @var array + */ + protected $_processedTemplateDir = array(); + + /** + * flag if template_dir is normalized + * + * @var bool + */ + public $_templateDirNormalized = false; /** * joined template directory string used in cache keys @@ -297,6 +300,27 @@ class Smarty extends Smarty_Internal_TemplateBase */ public $_joined_template_dir = null; + /** + * config directory + * + * @var array + */ + protected $config_dir = array('./configs/'); + + /** + * flags for normalized template directory entries + * + * @var array + */ + protected $_processedConfigDir = array(); + + /** + * flag if config_dir is normalized + * + * @var bool + */ + public $_configDirNormalized = false; + /** * joined config directory string used in cache keys * @@ -330,28 +354,42 @@ class Smarty extends Smarty_Internal_TemplateBase * * @var string */ - private $compile_dir = './templates_c/'; + protected $compile_dir = './templates_c/'; + + /** + * flag if template_dir is normalized + * + * @var bool + */ + public $_compileDirNormalized = false; /** * plugins directory * * @var array */ - private $plugins_dir = null; + protected $plugins_dir = array(); + + /** + * flag if plugins_dir is normalized + * + * @var bool + */ + public $_pluginsDirNormalized = false; /** * cache directory * * @var string */ - private $cache_dir = './cache/'; + protected $cache_dir = './cache/'; /** - * config directory + * flag if template_dir is normalized * - * @var array + * @var bool */ - private $config_dir = array('./configs/'); + public $_cacheDirNormalized = false; /** * force template compiling? @@ -388,6 +426,15 @@ class Smarty extends Smarty_Internal_TemplateBase */ public $merge_compiled_includes = false; + /* + * flag for behaviour when extends: resource and {extends} tag are used simultaneous + * if false disable execution of {extends} in templates called by extends resource. + * (behaviour as versions < 3.1.28) + * + * @var boolean + */ + public $extends_recursion = true; + /** * force cache file creation * @@ -562,13 +609,6 @@ class Smarty extends Smarty_Internal_TemplateBase */ public $default_config_type = 'file'; - /** - * enable resource caching - * - * @var bool - */ - public $resource_cache_mode = 1; - /** * check If-Modified-Since headers * @@ -674,23 +714,30 @@ class Smarty extends Smarty_Internal_TemplateBase */ public $_debug = null; + /** + * Directory separator + * + * @var string + */ + public $ds = DIRECTORY_SEPARATOR; + /** * removed properties * * @var string[] */ - private static $obsoleteProperties = array('resource_caching', 'template_resource_caching', - 'direct_access_security', '_dir_perms', '_file_perms', - 'plugin_search_order', 'inheritance_merge_compiled_includes'); + private $obsoleteProperties = array('resource_caching', 'template_resource_caching', 'direct_access_security', + '_dir_perms', '_file_perms', 'plugin_search_order', + 'inheritance_merge_compiled_includes', 'resource_cache_mode',); /** - * List of private properties which will call getter/setter ona direct access + * List of private properties which will call getter/setter on a direct access * - * @var array + * @var string[] */ - private static $accessMap = array('template_dir' => 'TemplateDir', 'config_dir' => 'ConfigDir', - 'plugins_dir' => 'PluginsDir', 'compile_dir' => 'CompileDir', - 'cache_dir' => 'CacheDir',); + private $accessMap = array('template_dir' => 'TemplateDir', 'config_dir' => 'ConfigDir', + 'plugins_dir' => 'PluginsDir', 'compile_dir' => 'CompileDir', + 'cache_dir' => 'CacheDir',); /**#@-*/ @@ -699,19 +746,19 @@ class Smarty extends Smarty_Internal_TemplateBase */ public function __construct() { + $this->_clearTemplateCache(); parent::__construct(); if (is_callable('mb_internal_encoding')) { mb_internal_encoding(Smarty::$_CHARSET); } $this->start_time = microtime(true); - if (isset($_SERVER['SCRIPT_NAME'])) { - Smarty::$global_tpl_vars['SCRIPT_NAME'] = new Smarty_Variable($_SERVER['SCRIPT_NAME']); + if (isset($_SERVER[ 'SCRIPT_NAME' ])) { + Smarty::$global_tpl_vars[ 'SCRIPT_NAME' ] = new Smarty_Variable($_SERVER[ 'SCRIPT_NAME' ]); } // Check if we're running on windows Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; - // let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8 if (Smarty::$_CHARSET !== 'UTF-8') { Smarty::$_UTF8_MODIFIER = ''; @@ -732,31 +779,6 @@ class Smarty extends Smarty_Internal_TemplateBase return $source->exists; } - /** - * Returns a single or all global variables - * - * @param string $varname variable name or null - * - * @return string variable value or or array of variables - */ - public function getGlobal($varname = null) - { - if (isset($varname)) { - if (isset(self::$global_tpl_vars[$varname])) { - return self::$global_tpl_vars[$varname]->value; - } else { - return ''; - } - } else { - $_result = array(); - foreach (self::$global_tpl_vars AS $key => $var) { - $_result[$key] = $var->value; - } - - return $_result; - } - } - /** * Loads security class and enables security * @@ -793,12 +815,14 @@ class Smarty extends Smarty_Internal_TemplateBase */ public function setTemplateDir($template_dir, $isConfig = false) { - $type = $isConfig ? 'config_dir' : 'template_dir'; - $joined = '_joined_' . $type; - $this->{$type} = (array) $template_dir; - $this->{$joined} = join(' # ', $this->{$type}); - $this->_cache[$type . '_new'] = true; - $this->_cache[$type] = false; + if ($isConfig) { + $this->config_dir = array(); + $this->_processedConfigDir = array(); + } else { + $this->template_dir = array(); + $this->_processedTemplateDir = array(); + } + $this->addTemplateDir($template_dir, null, $isConfig); return $this; } @@ -813,16 +837,36 @@ class Smarty extends Smarty_Internal_TemplateBase */ public function addTemplateDir($template_dir, $key = null, $isConfig = false) { - $type = $isConfig ? 'config_dir' : 'template_dir'; - $joined = '_joined_' . $type; - if (!isset($this->_cache[$type])) { - $this->{$type} = (array) $this->{$type}; - $this->{$joined} = join(' # ', $this->{$type}); - $this->_cache[$type . '_new'] = true; - $this->_cache[$type] = false; + if ($isConfig) { + $processed = &$this->_processedConfigDir; + $dir = &$this->config_dir; + $this->_configDirNormalized = false; + } else { + $processed = &$this->_processedTemplateDir; + $dir = &$this->template_dir; + $this->_templateDirNormalized = false; + } + if (is_array($template_dir)) { + foreach ($template_dir as $k => $v) { + if (is_int($k)) { + // indexes are not merged but appended + $dir[] = $v; + } else { + // string indexes are overridden + $dir[ $k ] = $v; + unset($processed[ $key ]); + } + } + } else { + if ($key !== null) { + // override directory at specified index + $dir[ $key ] = $template_dir; + unset($processed[ $key ]); + } else { + // append new directory + $dir[] = $template_dir; + } } - $this->{$joined} .= ' # ' . join(' # ', (array) $template_dir); - $this->_addDir($type, $template_dir, $key); return $this; } @@ -836,24 +880,18 @@ class Smarty extends Smarty_Internal_TemplateBase */ public function getTemplateDir($index = null, $isConfig = false) { - $type = $isConfig ? 'config_dir' : 'template_dir'; - if (!isset($this->_cache[$type])) { - $joined = '_joined_' . $type; - $this->{$type} = (array) $this->{$type}; - $this->{$joined} = join(' # ', $this->{$type}); - $this->_cache[$type] = false; + if ($isConfig) { + $dir = &$this->config_dir; + } else { + $dir = &$this->template_dir; } - if ($this->_cache[$type] == false) { - foreach ($this->{$type} as $k => $v) { - $this->{$type}[$k] = $this->_realpath($v . DS, true); - } - $this->_cache[$type . '_new'] = true; - $this->_cache[$type] = true; + if ($isConfig ? !$this->_configDirNormalized : !$this->_templateDirNormalized) { + $this->_nomalizeTemplateConfig($isConfig); } if ($index !== null) { - return isset($this->{$type}[$index]) ? $this->{$type}[$index] : null; + return isset($dir[ $index ]) ? $dir[ $index ] : null; } - return $this->{$type}; + return $dir; } /** @@ -903,28 +941,24 @@ class Smarty extends Smarty_Internal_TemplateBase public function setPluginsDir($plugins_dir) { $this->plugins_dir = (array) $plugins_dir; - if (isset($this->_cache['plugins_dir'])) { - unset($this->_cache['plugins_dir']); - } + $this->_pluginsDirNormalized = false; return $this; } /** * Adds directory of plugin files * - * @param $plugins_dir + * @param null|array $plugins_dir * * @return Smarty current Smarty instance for chaining */ public function addPluginsDir($plugins_dir) { - if (!isset($this->plugins_dir)) { - $this->plugins_dir = array(SMARTY_PLUGINS_DIR); - } - $this->plugins_dir = array_merge((array) $this->plugins_dir, (array) $plugins_dir); - if (isset($this->_cache['plugins_dir'])) { - unset($this->_cache['plugins_dir']); + if (empty($this->plugins_dir)) { + $this->plugins_dir[] = SMARTY_PLUGINS_DIR; } + $this->plugins_dir = array_merge($this->plugins_dir, (array) $plugins_dir); + $this->_pluginsDirNormalized = false; return $this; } @@ -935,25 +969,24 @@ class Smarty extends Smarty_Internal_TemplateBase */ public function getPluginsDir() { - if (!isset($this->_cache['plugins_dir'])) { - if (!isset($this->plugins_dir)) { - $this->plugins_dir = array(SMARTY_PLUGINS_DIR); - } else { - $plugins_dir = (array) $this->plugins_dir; - $this->plugins_dir = array(); - foreach ($plugins_dir as $v) { - $this->plugins_dir[] = $this->_realpath($v . DS, true); - } - $this->plugins_dir = array_unique($this->plugins_dir); + if (empty($this->plugins_dir)) { + $this->plugins_dir[] = SMARTY_PLUGINS_DIR; + $this->_pluginsDirNormalized = false; + } + if (!$this->_pluginsDirNormalized) { + if (!is_array($this->plugins_dir)) { + $this->plugins_dir = (array) $this->plugins_dir; } - $this->_cache['plugin_files'] = array(); - $this->_cache['plugins_dir'] = true; + foreach ($this->plugins_dir as $k => $v) { + $this->plugins_dir[ $k ] = $this->_realpath(rtrim($v, "/\\") . $this->ds, true); + } + $this->_cache[ 'plugin_files' ] = array(); + $this->_pluginsDirNormalized = true; } return $this->plugins_dir; } /** - * Set compile directory * * @param string $compile_dir directory to store compiled templates in * @@ -961,11 +994,8 @@ class Smarty extends Smarty_Internal_TemplateBase */ public function setCompileDir($compile_dir) { - $this->compile_dir = $this->_realpath($compile_dir . DS, true); - if (!isset(Smarty::$_muted_directories[$this->compile_dir])) { - Smarty::$_muted_directories[$this->compile_dir] = null; - } - $this->_cache['compile_dir'] = true; + $this->_normalizeDir('compile_dir', $compile_dir); + $this->_compileDirNormalized = true; return $this; } @@ -976,12 +1006,9 @@ class Smarty extends Smarty_Internal_TemplateBase */ public function getCompileDir() { - if (!isset($this->_cache['compile_dir'])) { - $this->compile_dir = $this->_realpath($this->compile_dir . DS, true); - if (!isset(Smarty::$_muted_directories[$this->compile_dir])) { - Smarty::$_muted_directories[$this->compile_dir] = null; - } - $this->_cache['compile_dir'] = true; + if (!$this->_compileDirNormalized) { + $this->_normalizeDir('compile_dir', $this->compile_dir); + $this->_compileDirNormalized = true; } return $this->compile_dir; } @@ -995,11 +1022,8 @@ class Smarty extends Smarty_Internal_TemplateBase */ public function setCacheDir($cache_dir) { - $this->cache_dir = $this->_realpath($cache_dir . DS, true); - if (!isset(Smarty::$_muted_directories[$this->cache_dir])) { - Smarty::$_muted_directories[$this->cache_dir] = null; - } - $this->_cache['cache_dir'] = true; + $this->_normalizeDir('cache_dir', $cache_dir); + $this->_cacheDirNormalized = true; return $this; } @@ -1010,47 +1034,54 @@ class Smarty extends Smarty_Internal_TemplateBase */ public function getCacheDir() { - if (!isset($this->_cache['cache_dir'])) { - $this->cache_dir = $this->_realpath($this->cache_dir . DS, true); - if (!isset(Smarty::$_muted_directories[$this->cache_dir])) { - Smarty::$_muted_directories[$this->cache_dir] = null; - } - $this->_cache['cache_dir'] = true; + if (!$this->_cacheDirNormalized) { + $this->_normalizeDir('cache_dir', $this->cache_dir); + $this->_cacheDirNormalized = true; } return $this->cache_dir; } /** - * add directories to given property name + * Normalize and set directory string * - * @param string $dirName directory property name - * @param string|array $dir directory string or array of strings - * @param mixed $key optional key + * @param string $dirName cache_dir or compile_dir + * @param string $dir filepath of folder */ - private function _addDir($dirName, $dir, $key = null) + private function _normalizeDir($dirName, $dir) { - $rp = $this->_cache[$dirName]; - if (is_array($dir)) { - foreach ($dir as $k => $v) { - $path = $rp ? $this->_realpath($v . DS, true) : $v; - if (is_int($k)) { - // indexes are not merged but appended - $this->{$dirName}[] = $path; - } else { - // string indexes are overridden - $this->{$dirName}[$k] = $path; - } - } + $this->{$dirName} = $this->_realpath(rtrim($dir, "/\\") . $this->ds, true); + if (!isset(Smarty::$_muted_directories[ $this->{$dirName} ])) { + Smarty::$_muted_directories[ $this->{$dirName} ] = null; + } + } + + /** + * Normalize template_dir or config_dir + * + * @param bool $isConfig true for config_dir + * + */ + private function _nomalizeTemplateConfig($isConfig) + { + if ($isConfig) { + $processed = &$this->_processedConfigDir; + $dir = &$this->config_dir; } else { - $path = $rp ? $this->_realpath($dir . DS, true) : $dir; - if ($key !== null) { - // override directory at specified index - $this->{$dirName}[$key] = $path; - } else { - // append new directory - $this->{$dirName}[] = $path; + $processed = &$this->_processedTemplateDir; + $dir = &$this->template_dir; + } + if (!is_array($dir)) { + $dir = (array) $dir; + } + foreach ($dir as $k => $v) { + if (!isset($processed[ $k ])) { + $dir[ $k ] = $v = $this->_realpath(rtrim($v, "/\\") . $this->ds, true); + $processed[ $k ] = true; } } + $isConfig ? $this->_configDirNormalized = true : $this->_templateDirNormalized = true; + $isConfig ? $this->_joined_config_dir = join('#', $this->config_dir) : + $this->_joined_template_dir = join('#', $this->template_dir); } /** @@ -1076,27 +1107,34 @@ class Smarty extends Smarty_Internal_TemplateBase } else { $data = null; } - if ($this->caching && - isset($this->_cache['isCached'][$_templateId = $this->_getTemplateId($template, $cache_id, $compile_id)]) - ) { - $tpl = $do_clone ? clone $this->_cache['isCached'][$_templateId] : $this->_cache['isCached'][$_templateId]; - $tpl->parent = $parent; - $tpl->tpl_vars = array(); - $tpl->config_vars = array(); + if (!$this->_templateDirNormalized) { + $this->_nomalizeTemplateConfig(false); + } + $_templateId = $this->_getTemplateId($template, $cache_id, $compile_id); + $tpl = null; + if ($this->caching && isset(Smarty_Internal_Template::$isCacheTplObj[ $_templateId ])) { + $tpl = $do_clone ? clone Smarty_Internal_Template::$isCacheTplObj[ $_templateId ] : + Smarty_Internal_Template::$isCacheTplObj[ $_templateId ]; + $tpl->inheritance = null; + $tpl->tpl_vars = $tpl->config_vars = array(); + } else if (!$do_clone && isset(Smarty_Internal_Template::$tplObjCache[ $_templateId ])) { + $tpl = clone Smarty_Internal_Template::$tplObjCache[ $_templateId ]; + $tpl->inheritance = null; + $tpl->tpl_vars = $tpl->config_vars = array(); } else { /* @var Smarty_Internal_Template $tpl */ - $tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id, null, null); + $tpl = new $this->template_class($template, $this, null, $cache_id, $compile_id, null, null); + $tpl->templateId = $_templateId; } if ($do_clone) { $tpl->smarty = clone $tpl->smarty; - } elseif ($parent === null) { - $tpl->parent = $this; } + $tpl->parent = $parent ? $parent : $this; // fill data if present if (!empty($data) && is_array($data)) { // set up variable values foreach ($data as $_key => $_val) { - $tpl->tpl_vars[$_key] = new Smarty_Variable($_val); + $tpl->tpl_vars[ $_key ] = new Smarty_Variable($_val); } } if ($this->debugging || $this->debugging_ctrl == 'URL') { @@ -1128,26 +1166,31 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Get unique template id * - * @param string $template_name - * @param null|mixed $cache_id - * @param null|mixed $compile_id - * @param null $caching + * @param string $template_name + * @param null|mixed $cache_id + * @param null|mixed $compile_id + * @param null $caching + * @param \Smarty_Internal_Template $template * * @return string */ - public function _getTemplateId($template_name, $cache_id = null, $compile_id = null, $caching = null) + public function _getTemplateId($template_name, $cache_id = null, $compile_id = null, $caching = null, + Smarty_Internal_Template $template = null) { + $template_name = (strpos($template_name, ':') === false) ? "{$this->default_resource_type}:{$template_name}" : + $template_name; $cache_id = $cache_id === null ? $this->cache_id : $cache_id; $compile_id = $compile_id === null ? $this->compile_id : $compile_id; $caching = (int) ($caching === null ? $this->caching : $caching); - if ($this->allow_ambiguous_resources) { + if ((isset($template) && strpos($template_name, ':.') !== false) || $this->allow_ambiguous_resources) { $_templateId = - Smarty_Resource::getUniqueTemplateName($this, $template_name) . "#{$cache_id}#{$compile_id}#{$caching}"; + Smarty_Resource::getUniqueTemplateName((isset($template) ? $template : $this), $template_name) . + "#{$cache_id}#{$compile_id}#{$caching}"; } else { $_templateId = $this->_joined_template_dir . "#{$template_name}#{$cache_id}#{$compile_id}#{$caching}"; } - if (isset($_templateId[150])) { + if (isset($_templateId[ 150 ])) { $_templateId = sha1($_templateId); } return $_templateId; @@ -1158,36 +1201,66 @@ class Smarty extends Smarty_Internal_TemplateBase * - remove /./ and /../ * - make it absolute if required * - * @param string $path file path - * @param bool $realpath leave $path relative + * @param string $path file path + * @param bool $realpath if true - convert to absolute + * false - convert to relative + * null - keep as it is but remove /./ /../ * * @return string */ public function _realpath($path, $realpath = null) { - static $pattern = null; - static $nds = null; - if ($pattern == null) { - $nds = DS == '/' ? '\\' : '/'; - $ds = '\\' . DS; - $pattern = - "#([{$ds}]+[^{$ds}]+[{$ds}]+[.]([{$ds}]+[.])*[.][{$ds}]+([.][{$ds}]+)*)|([{$ds}]+([.][{$ds}]+)+)|[{$ds}]{2,}#"; + $nds = $this->ds == '/' ? '\\' : '/'; + // normalize $this->ds + $path = str_replace($nds, $this->ds, $path); + preg_match('%^(?(?:[[:alpha:]]:[\\\\]|/|[\\\\]{2}[[:alpha:]]+|[[:print:]]{2,}:[/]{2}|[\\\\])?)(?(?:[[:print:]]*))$%', + $path, $parts); + $path = $parts[ 'path' ]; + if ($parts[ 'root' ] == '\\') { + $parts[ 'root' ] = substr(getcwd(), 0, 2) . $parts[ 'root' ]; + } else { + if ($realpath !== null && !$parts[ 'root' ]) { + $path = getcwd() . $this->ds . $path; + } } - // normalize DS - if (strpos($path, $nds) !== false) { - $path = str_replace($nds, DS, $path); + // remove noop 'DIRECTORY_SEPARATOR DIRECTORY_SEPARATOR' and 'DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR' patterns + $path = preg_replace('#([\\\\/]([.]?[\\\\/])+)#', $this->ds, $path); + // resolve '..DIRECTORY_SEPARATOR' pattern, smallest first + if (strpos($path, '..' . $this->ds) != false && + preg_match_all('#(([.]?[\\\\/])*([.][.])[\\\\/]([.]?[\\\\/])*)+#', $path, $match) + ) { + $counts = array(); + foreach ($match[ 0 ] as $m) { + $counts[] = (int) ((strlen($m) - 1) / 3); + } + sort($counts); + foreach ($counts as $count) { + $path = preg_replace('#(([\\\\/]([.]?[\\\\/])*[^\\\\/.]+){' . $count . + '}[\\\\/]([.]?[\\\\/])*([.][.][\\\\/]([.]?[\\\\/])*){' . $count . '})(?=[^.])#', + $this->ds, $path); + } } - if ($realpath === true && (($path[0] !== '/' && DS == '/') || ($path[1] !== ':' && DS != '/'))) { - $path = getcwd() . DS . $path; - } - while ((strpos($path, '.' . DS) !== false) || (strpos($path, DS . DS) !== false)) { - $path = preg_replace($pattern, DS, $path); - } - if ($realpath === false && ($path[0] == '/' || $path[1] == ':')) { - $path = str_ireplace(getcwd(), '.', $path); - } - return $path; + return $parts[ 'root' ] . $path; + } + + /** + * Empty template objects cache + */ + public function _clearTemplateCache() + { + Smarty_Internal_Template::$isCacheTplObj = array(); + Smarty_Internal_Template::$tplObjCache = array(); + } + + /** + * Get Smarty object + * + * @return Smarty + */ + public function _getSmartyObj() + { + return $this; } /** @@ -1328,14 +1401,6 @@ class Smarty extends Smarty_Internal_TemplateBase Smarty_Internal_TestInstall::testInstall($this, $errors); } - /** - * Class destructor - */ - public function __destruct() - { - $i = 0;// intentionally left blank - } - /** * <> Generic getter. * Calls the appropriate getter function. @@ -1347,15 +1412,17 @@ class Smarty extends Smarty_Internal_TemplateBase */ public function __get($name) { - - if (isset(self::$accessMap[$name])) { - $method = 'get' . self::$accessMap[$name]; + if (isset($this->accessMap[ $name ])) { + $method = 'get' . $this->accessMap[ $name ]; return $this->{$method}(); - } elseif (in_array($name, self::$obsoleteProperties)) { + } elseif (isset($this->_cache[ $name ])) { + return $this->_cache[ $name ]; + } elseif (in_array($name, $this->obsoleteProperties)) { return null; } else { trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE); } + return null; } /** @@ -1368,10 +1435,10 @@ class Smarty extends Smarty_Internal_TemplateBase */ public function __set($name, $value) { - if (isset(self::$accessMap[$name])) { - $method = 'set' . self::$accessMap[$name]; + if (isset($this->accessMap[ $name ])) { + $method = 'set' . $this->accessMap[ $name ]; $this->{$method}($value); - } elseif (in_array($name, self::$obsoleteProperties)) { + } elseif (in_array($name, $this->obsoleteProperties)) { return; } else { if (is_object($value) && method_exists($value, $name)) { @@ -1393,17 +1460,17 @@ class Smarty extends Smarty_Internal_TemplateBase * @param $errline * @param $errcontext * - * @return boolean + * @return bool|void */ public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) { $_is_muted_directory = false; // add the SMARTY_DIR to the list of muted directories - if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) { + if (!isset(Smarty::$_muted_directories[ SMARTY_DIR ])) { $smarty_dir = realpath(SMARTY_DIR); if ($smarty_dir !== false) { - Smarty::$_muted_directories[SMARTY_DIR] = + Smarty::$_muted_directories[ SMARTY_DIR ] = array('file' => $smarty_dir, 'length' => strlen($smarty_dir),); } } @@ -1415,17 +1482,16 @@ class Smarty extends Smarty_Internal_TemplateBase $file = realpath($key); if ($file === false) { // this directory does not exist, remove and skip it - unset(Smarty::$_muted_directories[$key]); + unset(Smarty::$_muted_directories[ $key ]); continue; } $dir = array('file' => $file, 'length' => strlen($file),); } - if (!strncmp($errfile, $dir['file'], $dir['length'])) { + if (!strncmp($errfile, $dir[ 'file' ], $dir[ 'length' ])) { $_is_muted_directory = true; break; } } - // pass to next error handler if this error did not occur inside SMARTY_DIR // or the error was within smarty but masked to be ignored if (!$_is_muted_directory || ($errno && $errno & error_reporting())) { @@ -1436,6 +1502,7 @@ class Smarty extends Smarty_Internal_TemplateBase return false; } } + return; } /** diff --git a/include/smarty/libs/SmartyBC.class.php b/include/smarty/libs/SmartyBC.class.php index 1dd529c9c..3955e4f24 100644 --- a/include/smarty/libs/SmartyBC.class.php +++ b/include/smarty/libs/SmartyBC.class.php @@ -31,7 +31,7 @@ require_once(dirname(__FILE__) . '/Smarty.class.php'); /** - * Smarty Backward Compatability Wrapper Class + * Smarty Backward Compatibility Wrapper Class * * @package Smarty */ @@ -54,11 +54,10 @@ class SmartyBC extends Smarty /** * Initialize new SmartyBC object * - * @param array $options options to set during initialization, e.g. array( 'forceCompile' => false ) */ - public function __construct(array $options = array()) + public function __construct() { - parent::__construct($options); + parent::__construct(); } /** @@ -108,7 +107,7 @@ class SmartyBC extends Smarty } /** - * Unregisters custom function + * Unregister custom function * * @param string $function name of template function */ @@ -129,7 +128,8 @@ class SmartyBC extends Smarty * @throws SmartyException * @internal param array $block_functs list of methods that are block format */ - public function register_object($object, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) + public function register_object($object, $object_impl, $allowed = array(), $smarty_args = true, + $block_methods = array()) { settype($allowed, 'array'); settype($smarty_args, 'boolean'); @@ -137,7 +137,7 @@ class SmartyBC extends Smarty } /** - * Unregisters object + * Unregister object * * @param string $object name of template object */ @@ -160,7 +160,7 @@ class SmartyBC extends Smarty } /** - * Unregisters block function + * Unregister block function * * @param string $block name of template function */ @@ -182,7 +182,7 @@ class SmartyBC extends Smarty } /** - * Unregisters compiler function + * Unregister compiler function * * @param string $function name of template function */ @@ -203,7 +203,7 @@ class SmartyBC extends Smarty } /** - * Unregisters modifier + * Unregister modifier * * @param string $modifier name of template modifier */ @@ -224,7 +224,7 @@ class SmartyBC extends Smarty } /** - * Unregisters a resource + * Unregister a resource * * @param string $type name of resource */ @@ -245,7 +245,7 @@ class SmartyBC extends Smarty } /** - * Unregisters a prefilter function + * Unregister a prefilter function * * @param callable $function */ @@ -266,7 +266,7 @@ class SmartyBC extends Smarty } /** - * Unregisters a postfilter function + * Unregister a postfilter function * * @param callable $function */ @@ -287,7 +287,7 @@ class SmartyBC extends Smarty } /** - * Unregisters an outputfilter function + * Unregister an outputfilter function * * @param callable $function */ diff --git a/include/smarty/libs/bootstrap.php b/include/smarty/libs/bootstrap.php new file mode 100644 index 000000000..32096087f --- /dev/null +++ b/include/smarty/libs/bootstrap.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/* + * Load and register Smarty Autoloader + */ +if (!class_exists('Smarty_Autoloader')) { + require __DIR__ . '/Autoloader.php'; +} +Smarty_Autoloader::register(); diff --git a/include/smarty/libs/plugins/block.textformat.php b/include/smarty/libs/plugins/block.textformat.php index abf544939..e2c5e3de4 100644 --- a/include/smarty/libs/plugins/block.textformat.php +++ b/include/smarty/libs/plugins/block.textformat.php @@ -38,6 +38,9 @@ function smarty_block_textformat($params, $content, $template, &$repeat) if (is_null($content)) { return; } + if (Smarty::$_MBSTRING && !is_callable('smarty_mb_wordwrap')) { + require_once(SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php'); + } $style = null; $indent = 0; @@ -83,14 +86,15 @@ function smarty_block_textformat($params, $content, $template, &$repeat) continue; } // convert mult. spaces & special chars to single space - $_paragraph = preg_replace(array('!\s+!' . Smarty::$_UTF8_MODIFIER, '!(^\s+)|(\s+$)!' . Smarty::$_UTF8_MODIFIER), array(' ', ''), $_paragraph); + $_paragraph = + preg_replace(array('!\s+!' . Smarty::$_UTF8_MODIFIER, '!(^\s+)|(\s+$)!' . Smarty::$_UTF8_MODIFIER), + array(' ', ''), $_paragraph); // indent first line if ($indent_first > 0) { $_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph; } // wordwrap sentences if (Smarty::$_MBSTRING) { - require_once(SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php'); $_paragraph = smarty_mb_wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut); } else { $_paragraph = wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut); diff --git a/include/smarty/libs/plugins/function.counter.php b/include/smarty/libs/plugins/function.counter.php index 4da85a14e..bcc8f498c 100644 --- a/include/smarty/libs/plugins/function.counter.php +++ b/include/smarty/libs/plugins/function.counter.php @@ -25,53 +25,48 @@ function smarty_function_counter($params, $template) { static $counters = array(); - $name = (isset($params['name'])) ? $params['name'] : 'default'; - if (!isset($counters[$name])) { - $counters[$name] = array( - 'start' => 1, - 'skip' => 1, - 'direction' => 'up', - 'count' => 1 - ); + $name = (isset($params[ 'name' ])) ? $params[ 'name' ] : 'default'; + if (!isset($counters[ $name ])) { + $counters[ $name ] = array('start' => 1, 'skip' => 1, 'direction' => 'up', 'count' => 1); } - $counter =& $counters[$name]; + $counter =& $counters[ $name ]; - if (isset($params['start'])) { - $counter['start'] = $counter['count'] = (int) $params['start']; + if (isset($params[ 'start' ])) { + $counter[ 'start' ] = $counter[ 'count' ] = (int) $params[ 'start' ]; } - if (!empty($params['assign'])) { - $counter['assign'] = $params['assign']; + if (!empty($params[ 'assign' ])) { + $counter[ 'assign' ] = $params[ 'assign' ]; } - if (isset($counter['assign'])) { - $template->assign($counter['assign'], $counter['count']); + if (isset($counter[ 'assign' ])) { + $template->assign($counter[ 'assign' ], $counter[ 'count' ]); } - if (isset($params['print'])) { - $print = (bool) $params['print']; + if (isset($params[ 'print' ])) { + $print = (bool) $params[ 'print' ]; } else { - $print = empty($counter['assign']); + $print = empty($counter[ 'assign' ]); } if ($print) { - $retval = $counter['count']; + $retval = $counter[ 'count' ]; } else { $retval = null; } - if (isset($params['skip'])) { - $counter['skip'] = $params['skip']; + if (isset($params[ 'skip' ])) { + $counter[ 'skip' ] = $params[ 'skip' ]; } - if (isset($params['direction'])) { - $counter['direction'] = $params['direction']; + if (isset($params[ 'direction' ])) { + $counter[ 'direction' ] = $params[ 'direction' ]; } - if ($counter['direction'] == "down") { - $counter['count'] -= $counter['skip']; + if ($counter[ 'direction' ] == "down") { + $counter[ 'count' ] -= $counter[ 'skip' ]; } else { - $counter['count'] += $counter['skip']; + $counter[ 'count' ] += $counter[ 'skip' ]; } return $retval; diff --git a/include/smarty/libs/plugins/function.cycle.php b/include/smarty/libs/plugins/function.cycle.php index 8dc5cd9d5..a76d49aed 100644 --- a/include/smarty/libs/plugins/function.cycle.php +++ b/include/smarty/libs/plugins/function.cycle.php @@ -48,58 +48,56 @@ function smarty_function_cycle($params, $template) { static $cycle_vars; - $name = (empty($params['name'])) ? 'default' : $params['name']; - $print = (isset($params['print'])) ? (bool) $params['print'] : true; - $advance = (isset($params['advance'])) ? (bool) $params['advance'] : true; - $reset = (isset($params['reset'])) ? (bool) $params['reset'] : false; + $name = (empty($params[ 'name' ])) ? 'default' : $params[ 'name' ]; + $print = (isset($params[ 'print' ])) ? (bool) $params[ 'print' ] : true; + $advance = (isset($params[ 'advance' ])) ? (bool) $params[ 'advance' ] : true; + $reset = (isset($params[ 'reset' ])) ? (bool) $params[ 'reset' ] : false; - if (!isset($params['values'])) { - if (!isset($cycle_vars[$name]['values'])) { + if (!isset($params[ 'values' ])) { + if (!isset($cycle_vars[ $name ][ 'values' ])) { trigger_error("cycle: missing 'values' parameter"); return; } } else { - if (isset($cycle_vars[$name]['values']) - && $cycle_vars[$name]['values'] != $params['values'] - ) { - $cycle_vars[$name]['index'] = 0; + if (isset($cycle_vars[ $name ][ 'values' ]) && $cycle_vars[ $name ][ 'values' ] != $params[ 'values' ]) { + $cycle_vars[ $name ][ 'index' ] = 0; } - $cycle_vars[$name]['values'] = $params['values']; + $cycle_vars[ $name ][ 'values' ] = $params[ 'values' ]; } - if (isset($params['delimiter'])) { - $cycle_vars[$name]['delimiter'] = $params['delimiter']; - } elseif (!isset($cycle_vars[$name]['delimiter'])) { - $cycle_vars[$name]['delimiter'] = ','; + if (isset($params[ 'delimiter' ])) { + $cycle_vars[ $name ][ 'delimiter' ] = $params[ 'delimiter' ]; + } elseif (!isset($cycle_vars[ $name ][ 'delimiter' ])) { + $cycle_vars[ $name ][ 'delimiter' ] = ','; } - if (is_array($cycle_vars[$name]['values'])) { - $cycle_array = $cycle_vars[$name]['values']; + if (is_array($cycle_vars[ $name ][ 'values' ])) { + $cycle_array = $cycle_vars[ $name ][ 'values' ]; } else { - $cycle_array = explode($cycle_vars[$name]['delimiter'], $cycle_vars[$name]['values']); + $cycle_array = explode($cycle_vars[ $name ][ 'delimiter' ], $cycle_vars[ $name ][ 'values' ]); } - if (!isset($cycle_vars[$name]['index']) || $reset) { - $cycle_vars[$name]['index'] = 0; + if (!isset($cycle_vars[ $name ][ 'index' ]) || $reset) { + $cycle_vars[ $name ][ 'index' ] = 0; } - if (isset($params['assign'])) { + if (isset($params[ 'assign' ])) { $print = false; - $template->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]); + $template->assign($params[ 'assign' ], $cycle_array[ $cycle_vars[ $name ][ 'index' ] ]); } if ($print) { - $retval = $cycle_array[$cycle_vars[$name]['index']]; + $retval = $cycle_array[ $cycle_vars[ $name ][ 'index' ] ]; } else { $retval = null; } if ($advance) { - if ($cycle_vars[$name]['index'] >= count($cycle_array) - 1) { - $cycle_vars[$name]['index'] = 0; + if ($cycle_vars[ $name ][ 'index' ] >= count($cycle_array) - 1) { + $cycle_vars[ $name ][ 'index' ] = 0; } else { - $cycle_vars[$name]['index'] ++; + $cycle_vars[ $name ][ 'index' ] ++; } } diff --git a/include/smarty/libs/plugins/function.fetch.php b/include/smarty/libs/plugins/function.fetch.php index 3506d4a8d..cb60dd918 100644 --- a/include/smarty/libs/plugins/function.fetch.php +++ b/include/smarty/libs/plugins/function.fetch.php @@ -24,31 +24,31 @@ */ function smarty_function_fetch($params, $template) { - if (empty($params['file'])) { + if (empty($params[ 'file' ])) { trigger_error("[plugin] fetch parameter 'file' cannot be empty", E_USER_NOTICE); return; } // strip file protocol - if (stripos($params['file'], 'file://') === 0) { - $params['file'] = substr($params['file'], 7); + if (stripos($params[ 'file' ], 'file://') === 0) { + $params[ 'file' ] = substr($params[ 'file' ], 7); } - $protocol = strpos($params['file'], '://'); + $protocol = strpos($params[ 'file' ], '://'); if ($protocol !== false) { - $protocol = strtolower(substr($params['file'], 0, $protocol)); + $protocol = strtolower(substr($params[ 'file' ], 0, $protocol)); } if (isset($template->smarty->security_policy)) { if ($protocol) { // remote resource (or php stream, …) - if (!$template->smarty->security_policy->isTrustedUri($params['file'])) { + if (!$template->smarty->security_policy->isTrustedUri($params[ 'file' ])) { return; } } else { // local file - if (!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) { + if (!$template->smarty->security_policy->isTrustedResourceDir($params[ 'file' ])) { return; } } @@ -57,26 +57,26 @@ function smarty_function_fetch($params, $template) $content = ''; if ($protocol == 'http') { // http fetch - if ($uri_parts = parse_url($params['file'])) { + if ($uri_parts = parse_url($params[ 'file' ])) { // set defaults - $host = $server_name = $uri_parts['host']; + $host = $server_name = $uri_parts[ 'host' ]; $timeout = 30; $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; $agent = "Smarty Template Engine " . Smarty::SMARTY_VERSION; $referer = ""; - $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/'; - $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : ''; + $uri = !empty($uri_parts[ 'path' ]) ? $uri_parts[ 'path' ] : '/'; + $uri .= !empty($uri_parts[ 'query' ]) ? '?' . $uri_parts[ 'query' ] : ''; $_is_proxy = false; - if (empty($uri_parts['port'])) { + if (empty($uri_parts[ 'port' ])) { $port = 80; } else { - $port = $uri_parts['port']; + $port = $uri_parts[ 'port' ]; } - if (!empty($uri_parts['user'])) { - $user = $uri_parts['user']; + if (!empty($uri_parts[ 'user' ])) { + $user = $uri_parts[ 'user' ]; } - if (!empty($uri_parts['pass'])) { - $pass = $uri_parts['pass']; + if (!empty($uri_parts[ 'pass' ])) { + $pass = $uri_parts[ 'pass' ]; } // loop through parameters, setup headers foreach ($params as $param_key => $param_value) { @@ -163,7 +163,7 @@ function smarty_function_fetch($params, $template) return; } else { if ($_is_proxy) { - fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n"); + fputs($fp, 'GET ' . $params[ 'file' ] . " HTTP/1.0\r\n"); } else { fputs($fp, "GET $uri HTTP/1.0\r\n"); } @@ -195,10 +195,10 @@ function smarty_function_fetch($params, $template) fclose($fp); $csplit = preg_split("!\r\n\r\n!", $content, 2); - $content = $csplit[1]; + $content = $csplit[ 1 ]; - if (!empty($params['assign_headers'])) { - $template->assign($params['assign_headers'], preg_split("!\r\n!", $csplit[0])); + if (!empty($params[ 'assign_headers' ])) { + $template->assign($params[ 'assign_headers' ], preg_split("!\r\n!", $csplit[ 0 ])); } } } else { @@ -207,14 +207,14 @@ function smarty_function_fetch($params, $template) return; } } else { - $content = @file_get_contents($params['file']); + $content = @file_get_contents($params[ 'file' ]); if ($content === false) { - throw new SmartyException("{fetch} cannot read resource '" . $params['file'] . "'"); + throw new SmartyException("{fetch} cannot read resource '" . $params[ 'file' ] . "'"); } } - if (!empty($params['assign'])) { - $template->assign($params['assign'], $content); + if (!empty($params[ 'assign' ])) { + $template->assign($params[ 'assign' ], $content); } else { return $content; } diff --git a/include/smarty/libs/plugins/function.html_checkboxes.php b/include/smarty/libs/plugins/function.html_checkboxes.php index d78680368..04ce45733 100644 --- a/include/smarty/libs/plugins/function.html_checkboxes.php +++ b/include/smarty/libs/plugins/function.html_checkboxes.php @@ -45,7 +45,9 @@ */ function smarty_function_html_checkboxes($params, $template) { - require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'); + if (!is_callable('smarty_function_escape_special_chars')) { + require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'); + } $name = 'checkbox'; $values = null; @@ -90,19 +92,21 @@ function smarty_function_html_checkboxes($params, $template) if (method_exists($_sel, "__toString")) { $_sel = smarty_function_escape_special_chars((string) $_sel->__toString()); } else { - trigger_error("html_checkboxes: selected attribute contains an object of class '" . get_class($_sel) . "' without __toString() method", E_USER_NOTICE); + trigger_error("html_checkboxes: selected attribute contains an object of class '" . + get_class($_sel) . "' without __toString() method", E_USER_NOTICE); continue; } } else { $_sel = smarty_function_escape_special_chars((string) $_sel); } - $selected[$_sel] = true; + $selected[ $_sel ] = true; } } elseif (is_object($_val)) { if (method_exists($_val, "__toString")) { $selected = smarty_function_escape_special_chars((string) $_val->__toString()); } else { - trigger_error("html_checkboxes: selected attribute is an object of class '" . get_class($_val) . "' without __toString() method", E_USER_NOTICE); + trigger_error("html_checkboxes: selected attribute is an object of class '" . get_class($_val) . + "' without __toString() method", E_USER_NOTICE); } } else { $selected = smarty_function_escape_special_chars((string) $_val); @@ -110,7 +114,8 @@ function smarty_function_html_checkboxes($params, $template) break; case 'checkboxes': - trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING); + trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', + E_USER_WARNING); $options = (array) $_val; break; @@ -122,9 +127,10 @@ function smarty_function_html_checkboxes($params, $template) case 'disabled': case 'readonly': - if (!empty($params['strict'])) { + if (!empty($params[ 'strict' ])) { if (!is_scalar($_val)) { - trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE); + trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", + E_USER_NOTICE); } if ($_val === true || $_val === $_key) { @@ -153,23 +159,28 @@ function smarty_function_html_checkboxes($params, $template) if (isset($options)) { foreach ($options as $_key => $_val) { - $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape); + $_html_result[] = + smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, + $label_ids, $escape); } } else { foreach ($values as $_i => $_key) { - $_val = isset($output[$_i]) ? $output[$_i] : ''; - $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape); + $_val = isset($output[ $_i ]) ? $output[ $_i ] : ''; + $_html_result[] = + smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, + $label_ids, $escape); } } - if (!empty($params['assign'])) { - $template->assign($params['assign'], $_html_result); + if (!empty($params[ 'assign' ])) { + $template->assign($params[ 'assign' ], $_html_result); } else { return implode("\n", $_html_result); } } -function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape = true) +function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels, + $label_ids, $escape = true) { $_output = ''; @@ -177,7 +188,8 @@ function smarty_function_html_checkboxes_output($name, $value, $output, $selecte if (method_exists($value, "__toString")) { $value = (string) $value->__toString(); } else { - trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE); + trigger_error("html_options: value is an object of class '" . get_class($value) . + "' without __toString() method", E_USER_NOTICE); return ''; } @@ -189,7 +201,8 @@ function smarty_function_html_checkboxes_output($name, $value, $output, $selecte if (method_exists($output, "__toString")) { $output = (string) $output->__toString(); } else { - trigger_error("html_options: output is an object of class '" . get_class($output) . "' without __toString() method", E_USER_NOTICE); + trigger_error("html_options: output is an object of class '" . get_class($output) . + "' without __toString() method", E_USER_NOTICE); return ''; } @@ -199,7 +212,8 @@ function smarty_function_html_checkboxes_output($name, $value, $output, $selecte if ($labels) { if ($label_ids) { - $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value)); + $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', + $name . '_' . $value)); $_output .= '