Эх сурвалжийг харах

Update version of smarty to 4.3.1

markjcrane 2 жил өмнө
parent
commit
ea359d6a60
100 өөрчлөгдсөн 713 нэмэгдсэн , 2119 устгасан
  1. 10 9
      resources/templates/engine/smarty/Autoloader.php
  2. 0 179
      resources/templates/engine/smarty/LICENSE
  3. 0 575
      resources/templates/engine/smarty/README
  4. 44 64
      resources/templates/engine/smarty/Smarty.class.php
  5. 0 477
      resources/templates/engine/smarty/SmartyBC.class.php
  6. 1 1
      resources/templates/engine/smarty/bootstrap.php
  7. 34 19
      resources/templates/engine/smarty/debug.tpl
  8. 51 0
      resources/templates/engine/smarty/functions.php
  9. 1 1
      resources/templates/engine/smarty/plugins/block.textformat.php
  10. 1 1
      resources/templates/engine/smarty/plugins/function.counter.php
  11. 1 1
      resources/templates/engine/smarty/plugins/function.cycle.php
  12. 1 1
      resources/templates/engine/smarty/plugins/function.fetch.php
  13. 1 1
      resources/templates/engine/smarty/plugins/function.html_checkboxes.php
  14. 1 1
      resources/templates/engine/smarty/plugins/function.html_image.php
  15. 1 1
      resources/templates/engine/smarty/plugins/function.html_options.php
  16. 1 1
      resources/templates/engine/smarty/plugins/function.html_radios.php
  17. 41 34
      resources/templates/engine/smarty/plugins/function.html_select_date.php
  18. 1 1
      resources/templates/engine/smarty/plugins/function.html_select_time.php
  19. 1 1
      resources/templates/engine/smarty/plugins/function.html_table.php
  20. 21 16
      resources/templates/engine/smarty/plugins/function.mailto.php
  21. 32 2
      resources/templates/engine/smarty/plugins/function.math.php
  22. 2 0
      resources/templates/engine/smarty/plugins/modifier.capitalize.php
  23. 36 0
      resources/templates/engine/smarty/plugins/modifier.count.php
  24. 5 4
      resources/templates/engine/smarty/plugins/modifier.date_format.php
  25. 16 82
      resources/templates/engine/smarty/plugins/modifier.escape.php
  26. 25 0
      resources/templates/engine/smarty/plugins/modifier.explode.php
  27. 1 1
      resources/templates/engine/smarty/plugins/modifier.mb_wordwrap.php
  28. 26 0
      resources/templates/engine/smarty/plugins/modifier.number_format.php
  29. 1 1
      resources/templates/engine/smarty/plugins/modifier.regex_replace.php
  30. 1 1
      resources/templates/engine/smarty/plugins/modifier.replace.php
  31. 1 1
      resources/templates/engine/smarty/plugins/modifier.spacify.php
  32. 5 5
      resources/templates/engine/smarty/plugins/modifier.truncate.php
  33. 1 1
      resources/templates/engine/smarty/plugins/modifiercompiler.cat.php
  34. 3 3
      resources/templates/engine/smarty/plugins/modifiercompiler.count_characters.php
  35. 1 1
      resources/templates/engine/smarty/plugins/modifiercompiler.count_paragraphs.php
  36. 1 1
      resources/templates/engine/smarty/plugins/modifiercompiler.count_sentences.php
  37. 2 2
      resources/templates/engine/smarty/plugins/modifiercompiler.count_words.php
  38. 2 2
      resources/templates/engine/smarty/plugins/modifiercompiler.default.php
  39. 17 42
      resources/templates/engine/smarty/plugins/modifiercompiler.escape.php
  40. 1 1
      resources/templates/engine/smarty/plugins/modifiercompiler.indent.php
  41. 3 3
      resources/templates/engine/smarty/plugins/modifiercompiler.lower.php
  42. 23 0
      resources/templates/engine/smarty/plugins/modifiercompiler.nl2br.php
  43. 23 0
      resources/templates/engine/smarty/plugins/modifiercompiler.round.php
  44. 23 0
      resources/templates/engine/smarty/plugins/modifiercompiler.str_repeat.php
  45. 1 1
      resources/templates/engine/smarty/plugins/modifiercompiler.string_format.php
  46. 1 1
      resources/templates/engine/smarty/plugins/modifiercompiler.strip.php
  47. 3 3
      resources/templates/engine/smarty/plugins/modifiercompiler.strip_tags.php
  48. 23 0
      resources/templates/engine/smarty/plugins/modifiercompiler.strlen.php
  49. 17 9
      resources/templates/engine/smarty/plugins/modifiercompiler.unescape.php
  50. 3 3
      resources/templates/engine/smarty/plugins/modifiercompiler.upper.php
  51. 1 1
      resources/templates/engine/smarty/plugins/modifiercompiler.wordwrap.php
  52. 2 2
      resources/templates/engine/smarty/plugins/outputfilter.trimwhitespace.php
  53. 1 7
      resources/templates/engine/smarty/plugins/shared.escape_special_chars.php
  54. 35 1
      resources/templates/engine/smarty/plugins/shared.mb_str_replace.php
  55. 1 1
      resources/templates/engine/smarty/plugins/variablefilter.htmlspecialchars.php
  56. 2 2
      resources/templates/engine/smarty/sysplugins/smarty_cacheresource.php
  57. 2 2
      resources/templates/engine/smarty/sysplugins/smarty_cacheresource_keyvaluestore.php
  58. 2 6
      resources/templates/engine/smarty/sysplugins/smarty_internal_cacheresource_file.php
  59. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_compile_assign.php
  60. 2 2
      resources/templates/engine/smarty/sysplugins/smarty_internal_compile_block.php
  61. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_compile_for.php
  62. 4 6
      resources/templates/engine/smarty/sysplugins/smarty_internal_compile_foreach.php
  63. 10 5
      resources/templates/engine/smarty/sysplugins/smarty_internal_compile_function.php
  64. 2 2
      resources/templates/engine/smarty/sysplugins/smarty_internal_compile_include.php
  65. 0 110
      resources/templates/engine/smarty/sysplugins/smarty_internal_compile_include_php.php
  66. 3 2
      resources/templates/engine/smarty/sysplugins/smarty_internal_compile_insert.php
  67. 3 3
      resources/templates/engine/smarty/sysplugins/smarty_internal_compile_private_foreachsection.php
  68. 3 0
      resources/templates/engine/smarty/sysplugins/smarty_internal_compile_private_modifier.php
  69. 0 253
      resources/templates/engine/smarty/sysplugins/smarty_internal_compile_private_php.php
  70. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_compile_private_print_expression.php
  71. 9 5
      resources/templates/engine/smarty/sysplugins/smarty_internal_compile_private_special_variable.php
  72. 8 6
      resources/templates/engine/smarty/sysplugins/smarty_internal_config_file_compiler.php
  73. 2 22
      resources/templates/engine/smarty/sysplugins/smarty_internal_data.php
  74. 2 2
      resources/templates/engine/smarty/sysplugins/smarty_internal_debug.php
  75. 60 72
      resources/templates/engine/smarty/sysplugins/smarty_internal_errorhandler.php
  76. 14 14
      resources/templates/engine/smarty/sysplugins/smarty_internal_extension_handler.php
  77. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_append.php
  78. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_appendbyref.php
  79. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_clearallassign.php
  80. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_clearallcache.php
  81. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_clearassign.php
  82. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_clearcache.php
  83. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_clearcompiledtemplate.php
  84. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_clearconfig.php
  85. 2 2
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_configload.php
  86. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_createdata.php
  87. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_getconfigvars.php
  88. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_getregisteredobject.php
  89. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_gettags.php
  90. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_gettemplatevars.php
  91. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_loadfilter.php
  92. 2 2
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_loadplugin.php
  93. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_mustcompile.php
  94. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_registercacheresource.php
  95. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_registerclass.php
  96. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_registerdefaultpluginhandler.php
  97. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_registerfilter.php
  98. 1 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_registerobject.php
  99. 3 1
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_registerplugin.php
  100. 4 11
      resources/templates/engine/smarty/sysplugins/smarty_internal_method_registerresource.php

+ 10 - 9
resources/templates/engine/smarty/Autoloader.php

@@ -5,6 +5,11 @@
  * @package Smarty
  */
 
+
+if (!defined('SMARTY_HELPER_FUNCTIONS_LOADED')) {
+	include __DIR__ . '/functions.php';
+}
+
 /**
  * Smarty Autoloader
  *
@@ -39,7 +44,7 @@ class Smarty_Autoloader
      *
      * @var array
      */
-    public static $rootClasses = array('smarty' => 'Smarty.class.php', 'smartybc' => 'SmartyBC.class.php',);
+    public static $rootClasses = array('smarty' => 'Smarty.class.php');
 
     /**
      * Registers Smarty_Autoloader backward compatible to older installations.
@@ -73,14 +78,10 @@ class Smarty_Autoloader
      */
     public static function register($prepend = false)
     {
-        self::$SMARTY_DIR = defined('SMARTY_DIR') ? SMARTY_DIR : dirname(__FILE__) . DIRECTORY_SEPARATOR;
+        self::$SMARTY_DIR = defined('SMARTY_DIR') ? SMARTY_DIR : __DIR__ . DIRECTORY_SEPARATOR;
         self::$SMARTY_SYSPLUGINS_DIR = defined('SMARTY_SYSPLUGINS_DIR') ? SMARTY_SYSPLUGINS_DIR :
             self::$SMARTY_DIR . 'sysplugins' . DIRECTORY_SEPARATOR;
-        if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
-            spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend);
-        } else {
-            spl_autoload_register(array(__CLASS__, 'autoload'));
-        }
+        spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend);
     }
 
     /**
@@ -90,10 +91,10 @@ class Smarty_Autoloader
      */
     public static function autoload($class)
     {
-        if ($class[ 0 ] !== 'S' && strpos($class, 'Smarty') !== 0) {
+        if ($class[ 0 ] !== 'S' || strpos($class, 'Smarty') !== 0) {
             return;
         }
-        $_class = strtolower($class);
+        $_class = smarty_strtolower_ascii($class);
         if (isset(self::$rootClasses[ $_class ])) {
             $file = self::$SMARTY_DIR . self::$rootClasses[ $_class ];
             if (is_file($file)) {

+ 0 - 179
resources/templates/engine/smarty/LICENSE

@@ -1,179 +0,0 @@
-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. <http://fsf.org/>
- 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.

+ 0 - 575
resources/templates/engine/smarty/README

@@ -1,575 +0,0 @@
-Smarty 3.x
-
-Author: Monte Ohrt <monte at ohrt dot com >
-Author: Uwe Tews
-
-AN INTRODUCTION TO SMARTY 3
-
-NOTICE FOR 3.1 release:
-
-Please see the SMARTY_3.1_NOTES.txt file that comes with the distribution.
-
-NOTICE for 3.0.5 release:
-
-Smarty now follows the PHP error_reporting level by default. If PHP does not mask E_NOTICE and you try to access an unset template variable, you will now get an E_NOTICE warning. To revert to the old behavior:
-
-$smarty->error_reporting = E_ALL & ~E_NOTICE;
-
-NOTICE for 3.0 release:
-
-IMPORTANT: Some API adjustments have been made between the RC4 and 3.0 release.
-We felt it is better to make these now instead of after a 3.0 release, then have to
-immediately deprecate APIs in 3.1. Online documentation has been updated
-to reflect these changes. Specifically:
-
----- API CHANGES RC4 -> 3.0 ----
-
-$smarty->register->*
-$smarty->unregister->*
-$smarty->utility->*
-$samrty->cache->*
-
-Have all been changed to local method calls such as:
-
-$smarty->clearAllCache()
-$smarty->registerFoo()
-$smarty->unregisterFoo()
-$smarty->testInstall()
-etc.
-
-Registration of function, block, compiler, and modifier plugins have been
-consolidated under two API calls:
-
-$smarty->registerPlugin(...)
-$smarty->unregisterPlugin(...)
-
-Registration of pre, post, output and variable filters have been
-consolidated under two API calls:
-
-$smarty->registerFilter(...)
-$smarty->unregisterFilter(...)
-
-Please refer to the online documentation for all specific changes:
-
-http://www.smarty.net/documentation
-
-----
-
-The Smarty 3 API has been refactored to a syntax geared
-for consistency and modularity. The Smarty 2 API syntax is still supported, but
-will throw a deprecation notice. You can disable the notices, but it is highly
-recommended to adjust your syntax to Smarty 3, as the Smarty 2 syntax must run
-through an extra rerouting wrapper.
-
-Basically, all Smarty methods now follow the "fooBarBaz" camel case syntax. Also,
-all Smarty properties now have getters and setters. So for example, the property
-$smarty->cache_dir can be set with $smarty->setCacheDir('foo/') and can be
-retrieved with $smarty->getCacheDir().
-
-Some of the Smarty 3 APIs have been revoked such as the "is*" methods that were
-just duplicate functions of the now available "get*" methods.
-
-Here is a rundown of the Smarty 3 API:
-
-$smarty->fetch($template, $cache_id = null, $compile_id = null, $parent = null)
-$smarty->display($template, $cache_id = null, $compile_id = null, $parent = null)
-$smarty->isCached($template, $cache_id = null, $compile_id = null)
-$smarty->createData($parent = null)
-$smarty->createTemplate($template, $cache_id = null, $compile_id = null, $parent = null)
-$smarty->enableSecurity()
-$smarty->disableSecurity()
-$smarty->setTemplateDir($template_dir)
-$smarty->addTemplateDir($template_dir)
-$smarty->templateExists($resource_name)
-$smarty->loadPlugin($plugin_name, $check = true)
-$smarty->loadFilter($type, $name)
-$smarty->setExceptionHandler($handler)
-$smarty->addPluginsDir($plugins_dir)
-$smarty->getGlobal($varname = null)
-$smarty->getRegisteredObject($name)
-$smarty->getDebugTemplate()
-$smarty->setDebugTemplate($tpl_name)
-$smarty->assign($tpl_var, $value = null, $nocache = false)
-$smarty->assignGlobal($varname, $value = null, $nocache = false)
-$smarty->assignByRef($tpl_var, &$value, $nocache = false)
-$smarty->append($tpl_var, $value = null, $merge = false, $nocache = false)
-$smarty->appendByRef($tpl_var, &$value, $merge = false)
-$smarty->clearAssign($tpl_var)
-$smarty->clearAllAssign()
-$smarty->configLoad($config_file, $sections = null)
-$smarty->getVariable($variable, $_ptr = null, $search_parents = true, $error_enable = true)
-$smarty->getConfigVariable($variable)
-$smarty->getStreamVariable($variable)
-$smarty->getConfigVars($varname = null)
-$smarty->clearConfig($varname = null)
-$smarty->getTemplateVars($varname = null, $_ptr = null, $search_parents = true)
-$smarty->clearAllCache($exp_time = null, $type = null)
-$smarty->clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
-
-$smarty->registerPlugin($type, $tag, $callback, $cacheable = true, $cache_attr = array())
-
-$smarty->registerObject($object_name, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
-
-$smarty->registerFilter($type, $function_name)
-$smarty->registerResource($resource_type, $function_names)
-$smarty->registerDefaultPluginHandler($function_name)
-$smarty->registerDefaultTemplateHandler($function_name)
-
-$smarty->unregisterPlugin($type, $tag)
-$smarty->unregisterObject($object_name)
-$smarty->unregisterFilter($type, $function_name)
-$smarty->unregisterResource($resource_type)
-
-$smarty->compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
-$smarty->clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
-$smarty->testInstall()
-
-// then all the getters/setters, available for all properties. Here are a few:
-
-$caching = $smarty->getCaching();      // get $smarty->caching
-$smarty->setCaching(true);             // set $smarty->caching
-$smarty->setDeprecationNotices(false); // set $smarty->deprecation_notices
-$smarty->setCacheId($id);              // set $smarty->cache_id
-$debugging = $smarty->getDebugging();  // get $smarty->debugging
-
-
-FILE STRUCTURE
-
-The Smarty 3 file structure is similar to Smarty 2:
-
-/libs/
-  Smarty.class.php
-/libs/sysplugins/
-  internal.*
-/libs/plugins/
-  function.mailto.php
-  modifier.escape.php
-  ...
-
-A lot of Smarty 3 core functionality lies in the sysplugins directory; you do
-not need to change any files here. The /libs/plugins/ folder is where Smarty
-plugins are located. You can add your own here, or create a separate plugin
-directory, just the same as Smarty 2. You will still need to create your own
-/cache/, /templates/, /templates_c/, /configs/ folders. Be sure /cache/ and
-/templates_c/ are writable.
-
-The typical way to use Smarty 3 should also look familiar:
-
-require('Smarty.class.php');
-$smarty = new Smarty;
-$smarty->assign('foo','bar');
-$smarty->display('index.tpl');
-
-
-However, Smarty 3 works completely different on the inside. Smarty 3 is mostly
-backward compatible with Smarty 2, except for the following items:
-
-*) Smarty 3 is PHP 5 only. It will not work with PHP 4.
-*) The {php} tag is disabled by default. Enable with $smarty->allow_php_tag=true.
-*) Delimiters surrounded by whitespace are no longer treated as Smarty tags.
-   Therefore, { foo } will not compile as a tag, you must use {foo}. This change
-   Makes Javascript/CSS easier to work with, eliminating the need for {literal}.
-   This can be disabled by setting $smarty->auto_literal = false;
-*) The Smarty 3 API is a bit different. Many Smarty 2 API calls are deprecated
-   but still work. You will want to update your calls to Smarty 3 for maximum
-   efficiency.
-
-
-There are many things that are new to Smarty 3. Here are the notable items:
-
-LEXER/PARSER
-============
-
-Smarty 3 now uses a lexing tokenizer for its parser/compiler. Basically, this
-means Smarty has some syntax additions that make life easier such as in-template
-math, shorter/intuitive function parameter options, infinite function recursion,
-more accurate error handling, etc.
-
-
-WHAT IS NEW IN SMARTY TEMPLATE SYNTAX
-=====================================
-
-Smarty 3 allows expressions almost anywhere. Expressions can include PHP
-functions as long as they are not disabled by the security policy, object
-methods and properties, etc. The {math} plugin is no longer necessary but
-is still supported for BC.
-
-Examples:
-{$x+$y}                           will output the sum of x and y.
-{$foo = strlen($bar)}             function in assignment
-{assign var=foo value= $x+$y}     in attributes
-{$foo = myfunct( ($x+$y)*3 )}     as function parameter
-{$foo[$x+3]}                      as array index
-
-Smarty tags can be used as values within other tags.
-Example:  {$foo={counter}+3}
-
-Smarty tags can also be used inside double quoted strings.
-Example:  {$foo="this is message {counter}"}
-
-You can define arrays within templates.
-Examples:
-{assign var=foo value=[1,2,3]}
-{assign var=foo value=['y'=>'yellow','b'=>'blue']}
-Arrays can be nested.
-{assign var=foo value=[1,[9,8],3]}
-
-There is a new short syntax supported for assigning variables.
-Example: {$foo=$bar+2}
-
-You can assign a value to a specific array element. If the variable exists but
-is not an array, it is converted to an array before the new values are assigned.
-Examples:
-{$foo['bar']=1}
-{$foo['bar']['blar']=1}
-
-You can append values to an array. If the variable exists but is not an array,
-it is converted to an array before the new values are assigned.
-Example: {$foo[]=1}
-
-You can use a PHP-like syntax for accessing array elements, as well as the
-original "dot" notation.
-Examples:
-{$foo[1]}             normal access
-{$foo['bar']}
-{$foo['bar'][1]}
-{$foo[$x+$x]}         index may contain any expression
-{$foo[$bar[1]]}       nested index
-{$foo[section_name]}  smarty section access, not array access!
-
-The original "dot" notation stays, and with improvements.
-Examples:
-{$foo.a.b.c}        =>  $foo['a']['b']['c']
-{$foo.a.$b.c}       =>  $foo['a'][$b]['c']        with variable index
-{$foo.a.{$b+4}.c}   =>  $foo['a'][$b+4]['c']       with expression as index
-{$foo.a.{$b.c}}     =>  $foo['a'][$b['c']]         with nested index
-
-note that { and } are used to address ambiguties when nesting the dot syntax.
-
-Variable names themselves can be variable and contain expressions.
-Examples:
-$foo         normal variable
-$foo_{$bar}  variable name containing other variable
-$foo_{$x+$y} variable name containing expressions
-$foo_{$bar}_buh_{$blar}  variable name with multiple segments
-{$foo_{$x}}  will output the variable $foo_1 if $x has a value of 1.
-
-Object method chaining is implemented.
-Example: {$object->method1($x)->method2($y)}
-
-{for} tag added for looping (replacement for {section} tag):
-{for $x=0, $y=count($foo); $x<$y; $x++}  ....  {/for}
-Any number of statements can be used separated by comma as the first
-initial expression at {for}.
-
-{for $x = $start to $end step $step} ... {/for}is in the SVN now .
-You can use also
-{for $x = $start to $end} ... {/for}
-In this case the step value will be automatically 1 or -1 depending on the start and end values.
-Instead of $start and $end you can use any valid expression.
-Inside the loop the following special vars can be accessed:
-$x@iteration = number of iteration
-$x@total = total number of iterations
-$x@first = true on first iteration
-$x@last = true on last iteration
-
-
-The Smarty 2 {section} syntax is still supported.
-
-New shorter {foreach} syntax to loop over an array.
-Example: {foreach $myarray as $var}...{/foreach}
-
-Within the foreach loop, properties are access via:
-
-$var@key            foreach $var array key
-$var@iteration      foreach current iteration count (1,2,3...)
-$var@index          foreach current index count (0,1,2...)
-$var@total          foreach $var array total
-$var@first          true on first iteration
-$var@last           true on last iteration
-
-The Smarty 2 {foreach} tag syntax is still supported.
-
-NOTE: {$bar[foo]} still indicates a variable inside of a {section} named foo.
-If you want to access an array element with index foo, you must use quotes
-such as {$bar['foo']}, or use the dot syntax {$bar.foo}.
-
-while block tag is now implemented:
-{while $foo}...{/while}
-{while $x lt 10}...{/while}
-
-Direct access to PHP functions:
-Just as you can use PHP functions as modifiers directly, you can now access
-PHP functions directly, provided they are permitted by security settings:
-{time()}
-
-There is a new {function}...{/function} block tag to implement a template function.
-This enables reuse of code sequences like a plugin function. It can call itself recursively.
-Template function must be called with the new {call name=foo...} tag.
-
-Example:
-
-Template file:
-{function name=menu level=0}
-  <ul class="level{$level}">
-  {foreach $data as $entry}
-    {if is_array($entry)}
-      <li>{$entry@key}</li>
-       {call name=menu data=$entry level=$level+1}
-    {else}
-      <li>{$entry}</li>
-    {/if}
-  {/foreach}
-  </ul>
-{/function}
-
-{$menu = ['item1','item2','item3' => ['item3-1','item3-2','item3-3' =>
-  ['item3-3-1','item3-3-2']],'item4']}
-
-{call name=menu data=$menu}
-
-
-Generated output:
-    * item1
-    * item2
-    * item3
-          o item3-1
-          o item3-2
-          o item3-3
-                + item3-3-1
-                + item3-3-2
-    * item4
-
-The function tag itself must have the "name" attribute. This name is the tag
-name when calling the function. The function tag may have any number of
-additional attributes. These will be default settings for local variables.
-
-New {nocache} block function:
-{nocache}...{/nocache} will declare a section of the template to be non-cached
-when template caching is enabled.
-
-New nocache attribute:
-You can declare variable/function output as non-cached with the nocache attribute.
-Examples:
-
-{$foo nocache=true}
-{$foo nocache} /* same */
-
-{foo bar="baz" nocache=true}
-{foo bar="baz" nocache} /* same */
-
-{time() nocache=true}
-{time() nocache} /* same */
-
-Or you can also assign the variable in your script as nocache:
-$smarty->assign('foo',$something,true); // third param is nocache setting
-{$foo} /* non-cached */
-
-$smarty.current_dir returns the directory name of the current template.
-
-You can use strings directly as templates with the "string" resource type.
-Examples:
-$smarty->display('string:This is my template, {$foo}!'); // php
-{include file="string:This is my template, {$foo}!"} // template
-
-
-
-VARIABLE SCOPE / VARIABLE STORAGE
-=================================
-
-In Smarty 2, all assigned variables were stored within the Smarty object.
-Therefore, all variables assigned in PHP were accessible by all subsequent
-fetch and display template calls.
-
-In Smarty 3, we have the choice to assign variables to the main Smarty object,
-to user-created data objects, and to user-created template objects.
-These objects can be chained. The object at the end of a chain can access all
-variables belonging to that template and all variables within the parent objects.
-The Smarty object can only be the root of a chain, but a chain can be isolated
-from the Smarty object.
-
-All known Smarty assignment interfaces will work on the data and template objects.
-
-Besides the above mentioned objects, there is also a special storage area for
-global variables.
-
-A Smarty data object can be created as follows:
-$data = $smarty->createData();    // create root data object
-$data->assign('foo','bar');       // assign variables as usual
-$data->config_load('my.conf');									 // load config file
-
-$data= $smarty->createData($smarty);  // create data object having a parent link to
-the Smarty object
-
-$data2= $smarty->createData($data);   // create data object having a parent link to
-the $data data object
-
-A template object can be created by using the createTemplate method. It has the
-same parameter assignments as the fetch() or display() method.
-Function definition:
-function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null)
-
-The first parameter can be a template name, a smarty object or a data object.
-
-Examples:
-$tpl = $smarty->createTemplate('mytpl.tpl'); // create template object not linked to any parent
-$tpl->assign('foo','bar');                   // directly assign variables
-$tpl->config_load('my.conf');									 // load config file
-
-$tpl = $smarty->createTemplate('mytpl.tpl',$smarty);  // create template having a parent link to the Smarty object
-$tpl = $smarty->createTemplate('mytpl.tpl',$data);    // create template having a parent link to the $data object
-
-The standard fetch() and display() methods will implicitly create a template object.
-If the $parent parameter is not specified in these method calls, the template object
-is will link back to the Smarty object as it's parent.
-
-If a template is called by an {include...} tag from another template, the
-subtemplate links back to the calling template as it's parent.
-
-All variables assigned locally or from a parent template are accessible. If the
-template creates or modifies a variable by using the {assign var=foo...} or
-{$foo=...} tags, these new values are only known locally (local scope). When the
-template exits, none of the new variables or modifications can be seen in the
-parent template(s). This is same behavior as in Smarty 2.
-
-With Smarty 3, we can assign variables with a scope attribute which allows the
-availablility of these new variables or modifications globally (ie in the parent
-templates.)
-
-Possible scopes are local, parent, root and global.
-Examples:
-{assign var=foo value='bar'}       // no scope is specified, the default 'local'
-{$foo='bar'}                       // same, local scope
-{assign var=foo value='bar' scope='local'} // same, local scope
-
-{assign var=foo value='bar' scope='parent'} // Values will be available to the parent object
-{$foo='bar' scope='parent'}                 // (normally the calling template)
-
-{assign var=foo value='bar' scope='root'}   // Values will be exported up to the root object, so they can
-{$foo='bar' scope='root'}                   // be seen from all templates using the same root.
-
-{assign var=foo value='bar' scope='global'} // Values will be exported to global variable storage,
-{$foo='bar' scope='global'}                 // they are available to any and all templates.
-
-
-The scope attribute can also be attached to the {include...} tag. In this case,
-the specified scope will be the default scope for all assignments within the
-included template.
-
-
-PLUGINS
-=======
-
-Smarty 3 plugins follow the same coding rules as in Smarty 2.
-The main difference is that the template object is now passed in place of the smarty object.
-The smarty object can be still be accessed through $template->smarty.
-
-smarty_plugintype_name (array $params, Smarty_Internal_Template $template)
-
-The Smarty 2 plugins are still compatible as long as they do not make use of specific Smarty 2 internals.
-
-
-TEMPLATE INHERITANCE:
-=====================
-
-With template inheritance you can define blocks, which are areas that can be
-overridden by child templates, so your templates could look like this:
-
-parent.tpl:
-<html>
-  <head>
-    <title>{block name='title'}My site name{/block}</title>
-  </head>
-  <body>
-    <h1>{block name='page-title'}Default page title{/block}</h1>
-    <div id="content">
-      {block name='content'}
-        Default content
-      {/block}
-    </div>
-  </body>
-</html>
-
-child.tpl:
-{extends file='parent.tpl'}
-{block name='title'}
-Child title
-{/block}
-
-grandchild.tpl:
-{extends file='child.tpl'}
-{block name='title'}Home - {$smarty.block.parent}{/block}
-{block name='page-title'}My home{/block}
-{block name='content'}
-  {foreach $images as $img}
-    <img src="{$img.url}" alt="{$img.description}" />
-  {/foreach}
-{/block}
-
-We redefined all the blocks here, however in the title block we used {$smarty.block.parent},
-which tells Smarty to insert the default content from the parent template in its place.
-The content block was overridden to display the image files, and page-title has also be
-overridden to display a completely different title.
-
-If we render grandchild.tpl we will get this:
-<html>
-  <head>
-    <title>Home - Child title</title>
-  </head>
-  <body>
-    <h1>My home</h1>
-    <div id="content">
-      <img src="/example.jpg" alt="image" />
-      <img src="/example2.jpg" alt="image" />
-      <img src="/example3.jpg" alt="image" />
-    </div>
-  </body>
-</html>
-
-NOTE: In the child templates everything outside the {extends} or {block} tag sections
-is ignored.
-
-The inheritance tree can be as big as you want (meaning you can extend a file that
-extends another one that extends another one and so on..), but be aware that all files
-have to be checked for modifications at runtime so the more inheritance the more overhead you add.
-
-Instead of defining the parent/child relationships with the {extends} tag in the child template you
-can use the resource as follow:
-
-$smarty->display('extends:parent.tpl|child.tpl|grandchild.tpl');
-
-Child {block} tags may optionally have a append or prepend attribute. In this case the parent block content
-is appended or prepended to the child block content.
-
-{block name='title' append} My title {/block}
-
-
-PHP STREAMS:
-============
-
-(see online documentation)
-
-VARIBLE FILTERS:
-================
-
-(see online documentation)
-
-
-STATIC CLASS ACCESS AND NAMESPACE SUPPORT
-=========================================
-
-You can register a class with optional namespace for the use in the template like:
-
-$smarty->register->templateClass('foo','name\name2\myclass');
-
-In the template you can use it like this:
-{foo::method()}  etc.
-
-
-=======================
-
-Please look through it and send any questions/suggestions/etc to the forums.
-
-http://www.phpinsider.com/smarty-forum/viewtopic.php?t=14168
-
-Monte and Uwe

+ 44 - 64
resources/templates/engine/smarty/Smarty.class.php

@@ -6,7 +6,7 @@
  * 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.
+ * version 3.0 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
@@ -20,14 +20,13 @@
  * Smarty mailing list. Send a blank e-mail to
  * [email protected]
  *
- * @link      http://www.smarty.net/
+ * @link      https://www.smarty.net/
  * @copyright 2018 New Digital Group, Inc.
  * @copyright 2018 Uwe Tews
  * @author    Monte Ohrt <monte at ohrt dot com>
  * @author    Uwe Tews   <uwe dot tews at gmail dot com>
  * @author    Rodney Rehm
  * @package   Smarty
- * @version   3.1.33
  */
 /**
  * set SMARTY_DIR to absolute path to Smarty library files.
@@ -37,7 +36,7 @@ if (!defined('SMARTY_DIR')) {
     /**
      *
      */
-    define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+    define('SMARTY_DIR', __DIR__ . DIRECTORY_SEPARATOR);
 }
 /**
  * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins.
@@ -61,25 +60,21 @@ if (!defined('SMARTY_MBSTRING')) {
      */
     define('SMARTY_MBSTRING', function_exists('mb_get_info'));
 }
-if (!defined('SMARTY_RESOURCE_CHAR_SET')) {
-    // UTF-8 can only be done properly when mbstring is available!
-    /**
-     * @deprecated in favor of Smarty::$_CHARSET
-     */
-    define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1');
-}
-if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) {
-    /**
-     * @deprecated in favor of Smarty::$_DATE_FORMAT
-     */
-    define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y');
+
+/**
+ * Load helper functions
+ */
+if (!defined('SMARTY_HELPER_FUNCTIONS_LOADED')) {
+    include __DIR__ . '/functions.php';
 }
+
 /**
  * Load Smarty_Autoloader
  */
 if (!class_exists('Smarty_Autoloader')) {
-    include dirname(__FILE__) . '/bootstrap.php';
+    include __DIR__ . '/bootstrap.php';
 }
+
 /**
  * Load always needed external class files
  */
@@ -112,7 +107,7 @@ class Smarty extends Smarty_Internal_TemplateBase
     /**
      * smarty version
      */
-    const SMARTY_VERSION = '3.1.33';
+    const SMARTY_VERSION = '4.3.1';
     /**
      * define variable scopes
      */
@@ -144,13 +139,7 @@ class Smarty extends Smarty_Internal_TemplateBase
     const DEBUG_OFF        = 0;
     const DEBUG_ON         = 1;
     const DEBUG_INDIVIDUAL = 2;
-    /**
-     * modes for handling of "<?php ... ?>" tags in templates.
-     */
-    const PHP_PASSTHRU = 0; //-> print tags as plain text
-    const PHP_QUOTE    = 1; //-> escape tags as entities
-    const PHP_REMOVE   = 2; //-> escape tags as entities
-    const PHP_ALLOW    = 3; //-> escape tags as entities
+
     /**
      * filter types
      */
@@ -180,13 +169,13 @@ class Smarty extends Smarty_Internal_TemplateBase
     /**
      * The character set to adhere to (e.g. "UTF-8")
      */
-    public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET;
+    public static $_CHARSET = SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1';
 
     /**
      * The date format to be used internally
      * (accepts date() and strftime())
      */
-    public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT;
+    public static $_DATE_FORMAT = '%b %e, %Y';
 
     /**
      * Flag denoting if PCRE should run in UTF-8 mode
@@ -370,13 +359,6 @@ class Smarty extends Smarty_Internal_TemplateBase
      */
     public $security_policy = null;
 
-    /**
-     * controls handling of PHP-blocks
-     *
-     * @var integer
-     */
-    public $php_handling = self::PHP_PASSTHRU;
-
     /**
      * controls if the php template file resource is allowed
      *
@@ -667,6 +649,12 @@ class Smarty extends Smarty_Internal_TemplateBase
         'cache_dir'    => 'CacheDir',
     );
 
+    /**
+     * PHP7 Compatibility mode
+     * @var bool
+     */
+    private $isMutingUndefinedOrNullWarnings = false;
+
     /**
      * Initialize new Smarty object
      */
@@ -689,27 +677,6 @@ class Smarty extends Smarty_Internal_TemplateBase
         }
     }
 
-    /**
-     * Enable error handler to mute expected messages
-     *
-     * @return     boolean
-     * @deprecated
-     */
-    public static function muteExpectedErrors()
-    {
-        return Smarty_Internal_ErrorHandler::muteExpectedErrors();
-    }
-
-    /**
-     * Disable error handler muting expected messages
-     *
-     * @deprecated
-     */
-    public static function unmuteExpectedErrors()
-    {
-        restore_error_handler();
-    }
-
     /**
      * Check if a template resource exists
      *
@@ -800,7 +767,7 @@ class Smarty extends Smarty_Internal_TemplateBase
      * @param mixed $index    index of directory to get, null to get all
      * @param bool  $isConfig true for config_dir
      *
-     * @return array list of template directories, or directory of $index
+     * @return array|string list of template directories, or directory of $index
      */
     public function getTemplateDir($index = null, $isConfig = false)
     {
@@ -909,7 +876,7 @@ class Smarty extends Smarty_Internal_TemplateBase
                 $this->plugins_dir = (array)$this->plugins_dir;
             }
             foreach ($this->plugins_dir as $k => $v) {
-                $this->plugins_dir[ $k ] = $this->_realpath(rtrim($v, '/\\') . DIRECTORY_SEPARATOR, true);
+                $this->plugins_dir[ $k ] = $this->_realpath(rtrim($v ?? '', '/\\') . DIRECTORY_SEPARATOR, true);
             }
             $this->_cache[ 'plugin_files' ] = array();
             $this->_pluginsDirNormalized = true;
@@ -1387,12 +1354,7 @@ class Smarty extends Smarty_Internal_TemplateBase
      */
     private function _normalizeDir($dirName, $dir)
     {
-        $this->{$dirName} = $this->_realpath(rtrim($dir, "/\\") . DIRECTORY_SEPARATOR, true);
-        if (class_exists('Smarty_Internal_ErrorHandler', false)) {
-            if (!isset(Smarty_Internal_ErrorHandler::$mutedDirectories[ $this->{$dirName} ])) {
-                Smarty_Internal_ErrorHandler::$mutedDirectories[ $this->{$dirName} ] = null;
-            }
-        }
+        $this->{$dirName} = $this->_realpath(rtrim($dir ?? '', "/\\") . DIRECTORY_SEPARATOR, true);
     }
 
     /**
@@ -1414,7 +1376,7 @@ class Smarty extends Smarty_Internal_TemplateBase
         }
         foreach ($dir as $k => $v) {
             if (!isset($processed[ $k ])) {
-                $dir[ $k ] = $v = $this->_realpath(rtrim($v, "/\\") . DIRECTORY_SEPARATOR, true);
+                $dir[ $k ] = $v = $this->_realpath(rtrim($v ?? '', "/\\") . DIRECTORY_SEPARATOR, true);
                 $processed[ $k ] = true;
             }
         }
@@ -1422,4 +1384,22 @@ class Smarty extends Smarty_Internal_TemplateBase
         $isConfig ? $this->_joined_config_dir = join('#', $this->config_dir) :
             $this->_joined_template_dir = join('#', $this->template_dir);
     }
+
+    /**
+     * Mutes errors for "undefined index", "undefined array key" and "trying to read property of null".
+     *
+     * @void
+     */
+    public function muteUndefinedOrNullWarnings(): void {
+        $this->isMutingUndefinedOrNullWarnings = true;
+    }
+
+    /**
+     * Indicates if Smarty will mute errors for "undefined index", "undefined array key" and "trying to read property of null".
+     * @bool
+     */
+    public function isMutingUndefinedOrNullWarnings(): bool {
+        return $this->isMutingUndefinedOrNullWarnings;
+    }
+
 }

+ 0 - 477
resources/templates/engine/smarty/SmartyBC.class.php

@@ -1,477 +0,0 @@
-<?php
-/**
- * Project:     Smarty: the PHP compiling template engine
- * File:        SmartyBC.class.php
- * SVN:         $Id: $
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * For questions, help, comments, discussion, etc., please join the
- * Smarty mailing list. Send a blank e-mail to
- * [email protected]
- *
- * @link      http://www.smarty.net/
- * @copyright 2008 New Digital Group, Inc.
- * @author    Monte Ohrt <monte at ohrt dot com>
- * @author    Uwe Tews
- * @author    Rodney Rehm
- * @package   Smarty
- */
-/**
- * @ignore
- */
-require_once dirname(__FILE__) . '/Smarty.class.php';
-
-/**
- * Smarty Backward Compatibility Wrapper Class
- *
- * @package Smarty
- */
-class SmartyBC extends Smarty
-{
-    /**
-     * Smarty 2 BC
-     *
-     * @var string
-     */
-    public $_version = self::SMARTY_VERSION;
-
-    /**
-     * This is an array of directories where trusted php scripts reside.
-     *
-     * @var array
-     */
-    public $trusted_dir = array();
-
-    /**
-     * Initialize new SmartyBC object
-     */
-    public function __construct()
-    {
-        parent::__construct();
-    }
-
-    /**
-     * wrapper for assign_by_ref
-     *
-     * @param string $tpl_var the template variable name
-     * @param mixed  &$value  the referenced value to assign
-     */
-    public function assign_by_ref($tpl_var, &$value)
-    {
-        $this->assignByRef($tpl_var, $value);
-    }
-
-    /**
-     * wrapper for append_by_ref
-     *
-     * @param string  $tpl_var the template variable name
-     * @param mixed   &$value  the referenced value to append
-     * @param boolean $merge   flag if array elements shall be merged
-     */
-    public function append_by_ref($tpl_var, &$value, $merge = false)
-    {
-        $this->appendByRef($tpl_var, $value, $merge);
-    }
-
-    /**
-     * clear the given assigned template variable.
-     *
-     * @param string $tpl_var the template variable to clear
-     */
-    public function clear_assign($tpl_var)
-    {
-        $this->clearAssign($tpl_var);
-    }
-
-    /**
-     * Registers custom function to be used in templates
-     *
-     * @param string $function      the name of the template function
-     * @param string $function_impl the name of the PHP function to register
-     * @param bool   $cacheable
-     * @param mixed  $cache_attrs
-     *
-     * @throws \SmartyException
-     */
-    public function register_function($function, $function_impl, $cacheable = true, $cache_attrs = null)
-    {
-        $this->registerPlugin('function', $function, $function_impl, $cacheable, $cache_attrs);
-    }
-
-    /**
-     * Unregister custom function
-     *
-     * @param string $function name of template function
-     */
-    public function unregister_function($function)
-    {
-        $this->unregisterPlugin('function', $function);
-    }
-
-    /**
-     * Registers object to be used in templates
-     *
-     * @param string  $object        name of template object
-     * @param object  $object_impl   the referenced PHP object to register
-     * @param array   $allowed       list of allowed methods (empty = all)
-     * @param boolean $smarty_args   smarty argument format, else traditional
-     * @param array   $block_methods list of methods that are block format
-     *
-     * @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()
-    ) {
-        settype($allowed, 'array');
-        settype($smarty_args, 'boolean');
-        $this->registerObject($object, $object_impl, $allowed, $smarty_args, $block_methods);
-    }
-
-    /**
-     * Unregister object
-     *
-     * @param string $object name of template object
-     */
-    public function unregister_object($object)
-    {
-        $this->unregisterObject($object);
-    }
-
-    /**
-     * Registers block function to be used in templates
-     *
-     * @param string $block      name of template block
-     * @param string $block_impl PHP function to register
-     * @param bool   $cacheable
-     * @param mixed  $cache_attrs
-     *
-     * @throws \SmartyException
-     */
-    public function register_block($block, $block_impl, $cacheable = true, $cache_attrs = null)
-    {
-        $this->registerPlugin('block', $block, $block_impl, $cacheable, $cache_attrs);
-    }
-
-    /**
-     * Unregister block function
-     *
-     * @param string $block name of template function
-     */
-    public function unregister_block($block)
-    {
-        $this->unregisterPlugin('block', $block);
-    }
-
-    /**
-     * Registers compiler function
-     *
-     * @param string $function      name of template function
-     * @param string $function_impl name of PHP function to register
-     * @param bool   $cacheable
-     *
-     * @throws \SmartyException
-     */
-    public function register_compiler_function($function, $function_impl, $cacheable = true)
-    {
-        $this->registerPlugin('compiler', $function, $function_impl, $cacheable);
-    }
-
-    /**
-     * Unregister compiler function
-     *
-     * @param string $function name of template function
-     */
-    public function unregister_compiler_function($function)
-    {
-        $this->unregisterPlugin('compiler', $function);
-    }
-
-    /**
-     * Registers modifier to be used in templates
-     *
-     * @param string $modifier      name of template modifier
-     * @param string $modifier_impl name of PHP function to register
-     *
-     * @throws \SmartyException
-     */
-    public function register_modifier($modifier, $modifier_impl)
-    {
-        $this->registerPlugin('modifier', $modifier, $modifier_impl);
-    }
-
-    /**
-     * Unregister modifier
-     *
-     * @param string $modifier name of template modifier
-     */
-    public function unregister_modifier($modifier)
-    {
-        $this->unregisterPlugin('modifier', $modifier);
-    }
-
-    /**
-     * Registers a resource to fetch a template
-     *
-     * @param string $type      name of resource
-     * @param array  $functions array of functions to handle resource
-     */
-    public function register_resource($type, $functions)
-    {
-        $this->registerResource($type, $functions);
-    }
-
-    /**
-     * Unregister a resource
-     *
-     * @param string $type name of resource
-     */
-    public function unregister_resource($type)
-    {
-        $this->unregisterResource($type);
-    }
-
-    /**
-     * Registers a prefilter function to apply
-     * to a template before compiling
-     *
-     * @param callable $function
-     *
-     * @throws \SmartyException
-     */
-    public function register_prefilter($function)
-    {
-        $this->registerFilter('pre', $function);
-    }
-
-    /**
-     * Unregister a prefilter function
-     *
-     * @param callable $function
-     */
-    public function unregister_prefilter($function)
-    {
-        $this->unregisterFilter('pre', $function);
-    }
-
-    /**
-     * Registers a postfilter function to apply
-     * to a compiled template after compilation
-     *
-     * @param callable $function
-     *
-     * @throws \SmartyException
-     */
-    public function register_postfilter($function)
-    {
-        $this->registerFilter('post', $function);
-    }
-
-    /**
-     * Unregister a postfilter function
-     *
-     * @param callable $function
-     */
-    public function unregister_postfilter($function)
-    {
-        $this->unregisterFilter('post', $function);
-    }
-
-    /**
-     * Registers an output filter function to apply
-     * to a template output
-     *
-     * @param callable $function
-     *
-     * @throws \SmartyException
-     */
-    public function register_outputfilter($function)
-    {
-        $this->registerFilter('output', $function);
-    }
-
-    /**
-     * Unregister an outputfilter function
-     *
-     * @param callable $function
-     */
-    public function unregister_outputfilter($function)
-    {
-        $this->unregisterFilter('output', $function);
-    }
-
-    /**
-     * load a filter of specified type and name
-     *
-     * @param string $type filter type
-     * @param string $name filter name
-     *
-     * @throws \SmartyException
-     */
-    public function load_filter($type, $name)
-    {
-        $this->loadFilter($type, $name);
-    }
-
-    /**
-     * clear cached content for the given template and cache id
-     *
-     * @param string $tpl_file   name of template file
-     * @param string $cache_id   name of cache_id
-     * @param string $compile_id name of compile_id
-     * @param string $exp_time   expiration time
-     *
-     * @return boolean
-     */
-    public function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
-    {
-        return $this->clearCache($tpl_file, $cache_id, $compile_id, $exp_time);
-    }
-
-    /**
-     * clear the entire contents of cache (all templates)
-     *
-     * @param string $exp_time expire time
-     *
-     * @return boolean
-     */
-    public function clear_all_cache($exp_time = null)
-    {
-        return $this->clearCache(null, null, null, $exp_time);
-    }
-
-    /**
-     * test to see if valid cache exists for this template
-     *
-     * @param string $tpl_file name of template file
-     * @param string $cache_id
-     * @param string $compile_id
-     *
-     * @return bool
-     * @throws \Exception
-     * @throws \SmartyException
-     */
-    public function is_cached($tpl_file, $cache_id = null, $compile_id = null)
-    {
-        return $this->isCached($tpl_file, $cache_id, $compile_id);
-    }
-
-    /**
-     * clear all the assigned template variables.
-     */
-    public function clear_all_assign()
-    {
-        $this->clearAllAssign();
-    }
-
-    /**
-     * clears compiled version of specified template resource,
-     * or all compiled template files if one is not specified.
-     * This function is for advanced use only, not normally needed.
-     *
-     * @param string $tpl_file
-     * @param string $compile_id
-     * @param string $exp_time
-     *
-     * @return boolean results of {@link smarty_core_rm_auto()}
-     */
-    public function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
-    {
-        return $this->clearCompiledTemplate($tpl_file, $compile_id, $exp_time);
-    }
-
-    /**
-     * Checks whether requested template exists.
-     *
-     * @param string $tpl_file
-     *
-     * @return bool
-     * @throws \SmartyException
-     */
-    public function template_exists($tpl_file)
-    {
-        return $this->templateExists($tpl_file);
-    }
-
-    /**
-     * Returns an array containing template variables
-     *
-     * @param string $name
-     *
-     * @return array
-     */
-    public function get_template_vars($name = null)
-    {
-        return $this->getTemplateVars($name);
-    }
-
-    /**
-     * Returns an array containing config variables
-     *
-     * @param string $name
-     *
-     * @return array
-     */
-    public function get_config_vars($name = null)
-    {
-        return $this->getConfigVars($name);
-    }
-
-    /**
-     * load configuration values
-     *
-     * @param string $file
-     * @param string $section
-     * @param string $scope
-     */
-    public function config_load($file, $section = null, $scope = 'global')
-    {
-        $this->ConfigLoad($file, $section, $scope);
-    }
-
-    /**
-     * return a reference to a registered object
-     *
-     * @param string $name
-     *
-     * @return object
-     */
-    public function get_registered_object($name)
-    {
-        return $this->getRegisteredObject($name);
-    }
-
-    /**
-     * clear configuration values
-     *
-     * @param string $var
-     */
-    public function clear_config($var = null)
-    {
-        $this->clearConfig($var);
-    }
-
-    /**
-     * trigger Smarty error
-     *
-     * @param string  $error_msg
-     * @param integer $error_type
-     */
-    public function trigger_error($error_msg, $error_type = E_USER_WARNING)
-    {
-        trigger_error("Smarty error: $error_msg", $error_type);
-    }
-}

+ 1 - 1
resources/templates/engine/smarty/bootstrap.php

@@ -11,6 +11,6 @@
  * Load and register Smarty Autoloader
  */
 if (!class_exists('Smarty_Autoloader')) {
-    include dirname(__FILE__) . '/Autoloader.php';
+    include __DIR__ . '/Autoloader.php';
 }
 Smarty_Autoloader::register(true);

+ 34 - 19
resources/templates/engine/smarty/debug.tpl

@@ -1,9 +1,9 @@
 {capture name='_smarty_debug' assign=debug_output}
-    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+    <!DOCTYPE html>
+    <html lang="en">
     <head>
         <title>Smarty Debug Console</title>
-        <style type="text/css">
+        <style>
             {literal}
             body, h1, h2, h3, td, th, p {
                 font-family: sans-serif;
@@ -31,6 +31,7 @@
                 padding: 2px;
                 border-top: 1px solid black;
             }
+
             h3 {
                 text-align: left;
                 font-weight: bold;
@@ -67,11 +68,11 @@
                 color: green;
             }
 
-            .odd {
+            tr:nth-child(odd) {
                 background-color: #eeeeee;
             }
 
-            .even {
+            tr:nth-child(even) {
                 background-color: #fafafa;
             }
 
@@ -84,13 +85,16 @@
                 color: black;
                 font-weight: bold;
             }
+
             #blue h3 {
                 color: blue;
             }
+
             #normal div {
                 color: black;
                 font-weight: normal;
             }
+
             #table_assigned_vars th {
                 color: blue;
                 font-weight: bold;
@@ -99,7 +103,6 @@
             #table_config_vars th {
                 color: maroon;
             }
-
             {/literal}
         </style>
     </head>
@@ -112,11 +115,11 @@
         <h2>included templates &amp; config files (load time in seconds)</h2>
         <div>
             {foreach $template_data as $template}
-                <font color=brown>{$template.name}</font>
-                <br />&nbsp;&nbsp;<span class="exectime">
+                <span style="color: brown;">{$template.name}</span>
+                <br>&nbsp;&nbsp;<span class="exectime">
                 (compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"})
                  </span>
-                <br />
+                <br>
             {/foreach}
         </div>
     {/if}
@@ -125,13 +128,22 @@
 
     <table id="table_assigned_vars">
         {foreach $assigned_vars as $vars}
-            <tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
-                <td><h3><font color=blue>${$vars@key}</font></h3>
-                    {if isset($vars['nocache'])}<b>Nocache</b><br />{/if}
-                    {if isset($vars['scope'])}<b>Origin:</b> {$vars['scope']|debug_print_var nofilter}{/if}
+            <tr>
+                <td>
+                    <h3 style="color: blue;">${$vars@key}</h3>
+                    {if isset($vars['nocache'])}<strong>Nocache</strong><br>{/if}
+                    {if isset($vars['scope'])}<strong>Origin:</strong> {$vars['scope']|debug_print_var nofilter}{/if}
+                </td>
+                <td>
+                    <h3>Value</h3>
+                    {$vars['value']|debug_print_var:10:80 nofilter}
+                </td>
+                <td>
+                    {if isset($vars['attributes'])}
+                        <h3>Attributes</h3>
+                        {$vars['attributes']|debug_print_var nofilter}
+                    {/if}
                 </td>
-                <td><h3>Value</h3>{$vars['value']|debug_print_var:10:80 nofilter}</td>
-                <td>{if isset($vars['attributes'])}<h3>Attributes</h3>{$vars['attributes']|debug_print_var nofilter} {/if}</td>
          {/foreach}
     </table>
 
@@ -139,11 +151,14 @@
 
     <table id="table_config_vars">
         {foreach $config_vars as $vars}
-            <tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
-                <td><h3><font color=blue>#{$vars@key}#</font></h3>
-                    {if isset($vars['scope'])}<b>Origin:</b> {$vars['scope']|debug_print_var nofilter}{/if}
+            <tr>
+                <td>
+                    <h3 style="color: blue;">#{$vars@key}#</h3>
+                    {if isset($vars['scope'])}<strong>Origin:</strong> {$vars['scope']|debug_print_var nofilter}{/if}
+                </td>
+                <td>
+                    {$vars['value']|debug_print_var:10:80 nofilter}
                 </td>
-                <td>{$vars['value']|debug_print_var:10:80 nofilter}</td>
             </tr>
         {/foreach}
 

+ 51 - 0
resources/templates/engine/smarty/functions.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * This file is part of the Smarty package.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+/**
+ * Registers some helper/polyfill functions.
+ */
+
+const SMARTY_HELPER_FUNCTIONS_LOADED = true;
+
+/**
+ * Converts the first characters in $string to uppercase (A-Z) if it is an ASCII lowercase character (a-z).
+ *
+ * May not be required when running PHP8.2+: https://wiki.php.net/rfc/strtolower-ascii
+ *
+ * @param $string
+ *
+ * @return string
+ */
+function smarty_ucfirst_ascii($string): string {
+    return smarty_strtoupper_ascii(substr($string, 0, 1)) . substr($string, 1);
+}
+
+/**
+ * Converts all uppercase ASCII characters (A-Z) in $string to lowercase (a-z).
+ *
+ * May not be required when running PHP8.2+: https://wiki.php.net/rfc/strtolower-ascii
+ *
+ * @param $string
+ *
+ * @return string
+ */
+function smarty_strtolower_ascii($string): string {
+    return strtr($string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
+}
+
+/**
+ * Converts all lowercase ASCII characters (a-z) in $string to uppercase (A-Z).
+ *
+ * May not be required when running PHP8.2+: https://wiki.php.net/rfc/strtolower-ascii
+ *
+ * @param $string
+ *
+ * @return string
+ */
+function smarty_strtoupper_ascii($string): string {
+    return strtr($string, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
+}

+ 1 - 1
resources/templates/engine/smarty/plugins/block.textformat.php

@@ -20,7 +20,7 @@
  * - indent_char   - string (" ")
  * - wrap_boundary - boolean (true)
  *
- * @link   http://www.smarty.net/manual/en/language.function.textformat.php {textformat}
+ * @link   https://www.smarty.net/manual/en/language.function.textformat.php {textformat}
  *         (Smarty online manual)
  *
  * @param array                    $params   parameters

+ 1 - 1
resources/templates/engine/smarty/plugins/function.counter.php

@@ -12,7 +12,7 @@
  * Purpose:  print out a counter value
  *
  * @author Monte Ohrt <monte at ohrt dot com>
- * @link   http://www.smarty.net/manual/en/language.function.counter.php {counter}
+ * @link   https://www.smarty.net/manual/en/language.function.counter.php {counter}
  *         (Smarty online manual)
  *
  * @param array                    $params   parameters

+ 1 - 1
resources/templates/engine/smarty/plugins/function.cycle.php

@@ -28,7 +28,7 @@
  * {cycle name=row values="one,two,three" reset=true}
  * {cycle name=row}
  *
- * @link    http://www.smarty.net/manual/en/language.function.cycle.php {cycle}
+ * @link    https://www.smarty.net/manual/en/language.function.cycle.php {cycle}
  *           (Smarty online manual)
  * @author  Monte Ohrt <monte at ohrt dot com>
  * @author  credit to Mark Priatel <[email protected]>

+ 1 - 1
resources/templates/engine/smarty/plugins/function.fetch.php

@@ -11,7 +11,7 @@
  * Name:     fetch
  * Purpose:  fetch file, web or ftp data and display results
  *
- * @link   http://www.smarty.net/manual/en/language.function.fetch.php {fetch}
+ * @link   https://www.smarty.net/manual/en/language.function.fetch.php {fetch}
  *         (Smarty online manual)
  * @author Monte Ohrt <monte at ohrt dot com>
  *

+ 1 - 1
resources/templates/engine/smarty/plugins/function.html_checkboxes.php

@@ -29,7 +29,7 @@
  * - assign     (optional) - assign the output as an array to this variable
  * - escape     (optional) - escape the content (not value), defaults to true
  *
- * @link    http://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
+ * @link    https://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
  *             (Smarty online manual)
  * @author  Christopher Kvarme <[email protected]>
  * @author  credits to Monte Ohrt <monte at ohrt dot com>

+ 1 - 1
resources/templates/engine/smarty/plugins/function.html_image.php

@@ -21,7 +21,7 @@
  * - basedir     - (optional) - base directory for absolute paths, default is environment variable DOCUMENT_ROOT
  * - path_prefix - prefix for path output (optional, default empty)
  *
- * @link    http://www.smarty.net/manual/en/language.function.html.image.php {html_image}
+ * @link    https://www.smarty.net/manual/en/language.function.html.image.php {html_image}
  *          (Smarty online manual)
  * @author  Monte Ohrt <monte at ohrt dot com>
  * @author  credits to Duda <[email protected]>

+ 1 - 1
resources/templates/engine/smarty/plugins/function.html_options.php

@@ -21,7 +21,7 @@
  * - id         (optional) - string default not set
  * - class      (optional) - string default not set
  *
- * @link   http://www.smarty.net/manual/en/language.function.html.options.php {html_image}
+ * @link   https://www.smarty.net/manual/en/language.function.html.options.php {html_image}
  *           (Smarty online manual)
  * @author Monte Ohrt <monte at ohrt dot com>
  * @author Ralf Strehle (minor optimization) <ralf dot strehle at yahoo dot de>

+ 1 - 1
resources/templates/engine/smarty/plugins/function.html_radios.php

@@ -29,7 +29,7 @@
  * {html_radios values=$ids name='box' separator='<br>' output=$names}
  * {html_radios values=$ids checked=$checked separator='<br>' output=$names}
  *
- * @link    http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
+ * @link    https://www.smarty.net/manual/en/language.function.html.radios.php {html_radios}
  *          (Smarty online manual)
  * @author  Christopher Kvarme <[email protected]>
  * @author  credits to Monte Ohrt <monte at ohrt dot com>

+ 41 - 34
resources/templates/engine/smarty/plugins/function.html_select_date.php

@@ -28,7 +28,7 @@
  *            - 2.0 complete rewrite for performance,
  *              added attributes month_names, *_id
  *
- * @link    http://www.smarty.net/manual/en/language.function.html.select.date.php {html_select_date}
+ * @link    https://www.smarty.net/manual/en/language.function.html.select.date.php {html_select_date}
  *           (Smarty online manual)
  * @version 2.0
  * @author  Andrei Zmievski
@@ -101,6 +101,7 @@ function smarty_function_html_select_date($params, Smarty_Internal_Template $tem
     $field_separator = "\n";
     $option_separator = "\n";
     $time = null;
+
     // $all_empty = null;
     // $day_empty = null;
     // $month_empty = null;
@@ -113,17 +114,7 @@ function smarty_function_html_select_date($params, Smarty_Internal_Template $tem
     foreach ($params as $_key => $_value) {
         switch ($_key) {
             case 'time':
-                if (!is_array($_value) && $_value !== null) {
-                    $template->_checkPlugins(
-                        array(
-                            array(
-                                'function' => 'smarty_make_timestamp',
-                                'file'     => SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'
-                            )
-                        )
-                    );
-                    $time = smarty_make_timestamp($_value);
-                }
+                $$_key = $_value; // we'll handle conversion below
                 break;
             case 'month_names':
                 if (is_array($_value) && count($_value) === 12) {
@@ -178,43 +169,59 @@ function smarty_function_html_select_date($params, Smarty_Internal_Template $tem
     }
     // Note: date() is faster than strftime()
     // Note: explode(date()) is faster than date() date() date()
-    if (isset($params[ 'time' ]) && is_array($params[ 'time' ])) {
-        if (isset($params[ 'time' ][ $prefix . 'Year' ])) {
+
+    if (isset($time) && is_array($time)) {
+        if (isset($time[$prefix . 'Year'])) {
             // $_REQUEST[$field_array] given
-            foreach (array(
-                'Y' => 'Year',
-                'm' => 'Month',
-                'd' => 'Day'
-            ) as $_elementKey => $_elementName) {
+            foreach ([
+                         'Y' => 'Year',
+                         'm' => 'Month',
+                         'd' => 'Day'
+                     ] as $_elementKey => $_elementName) {
                 $_variableName = '_' . strtolower($_elementName);
                 $$_variableName =
-                    isset($params[ 'time' ][ $prefix . $_elementName ]) ? $params[ 'time' ][ $prefix . $_elementName ] :
+                    isset($time[$prefix . $_elementName]) ? $time[$prefix . $_elementName] :
                         date($_elementKey);
             }
-        } elseif (isset($params[ 'time' ][ $field_array ][ $prefix . 'Year' ])) {
+        } elseif (isset($time[$field_array][$prefix . 'Year'])) {
             // $_REQUEST given
-            foreach (array(
-                'Y' => 'Year',
-                'm' => 'Month',
-                'd' => 'Day'
-            ) as $_elementKey => $_elementName) {
+            foreach ([
+                         'Y' => 'Year',
+                         'm' => 'Month',
+                         'd' => 'Day'
+                     ] as $_elementKey => $_elementName) {
                 $_variableName = '_' . strtolower($_elementName);
-                $$_variableName = isset($params[ 'time' ][ $field_array ][ $prefix . $_elementName ]) ?
-                    $params[ 'time' ][ $field_array ][ $prefix . $_elementName ] : date($_elementKey);
+                $$_variableName = isset($time[$field_array][$prefix . $_elementName]) ?
+                    $time[$field_array][$prefix . $_elementName] : date($_elementKey);
             }
         } else {
             // no date found, use NOW
-            list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
+            [$_year, $_month, $_day] = explode('-', date('Y-m-d'));
         }
+    } elseif (isset($time) && preg_match("/(\d*)-(\d*)-(\d*)/", $time, $matches)) {
+        $_year = $_month = $_day = null;
+        if ($matches[1] > '') $_year = (int) $matches[1];
+        if ($matches[2] > '') $_month = (int) $matches[2];
+        if ($matches[3] > '') $_day = (int) $matches[3];
     } elseif ($time === null) {
         if (array_key_exists('time', $params)) {
-            $_year = $_month = $_day = $time = null;
+            $_year = $_month = $_day = null;
         } else {
-            list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
+            [$_year, $_month, $_day] = explode('-', date('Y-m-d'));
         }
     } else {
-        list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d', $time));
+        $template->_checkPlugins(
+            array(
+                array(
+                    'function' => 'smarty_make_timestamp',
+                    'file'     => SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'
+                )
+            )
+        );
+        $time = smarty_make_timestamp($time);
+        [$_year, $_month, $_day] = explode('-', date('Y-m-d', $time));
     }
+
     // make syntax "+N" or "-N" work with $start_year and $end_year
     // Note preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match) is slower than trim+substr
     foreach (array(
@@ -309,8 +316,8 @@ function smarty_function_html_select_date($params, Smarty_Internal_Template $tem
         for ($i = 1; $i <= 12; $i++) {
             $_val = sprintf('%02d', $i);
             $_text = isset($month_names) ? smarty_function_escape_special_chars($month_names[ $i ]) :
-                ($month_format === '%m' ? $_val : strftime($month_format, $_month_timestamps[ $i ]));
-            $_value = $month_value_format === '%m' ? $_val : strftime($month_value_format, $_month_timestamps[ $i ]);
+                ($month_format === '%m' ? $_val : @strftime($month_format, $_month_timestamps[ $i ]));
+            $_value = $month_value_format === '%m' ? $_val : @strftime($month_value_format, $_month_timestamps[ $i ]);
             $_html_months .= '<option value="' . $_value . '"' . ($_val == $_month ? ' selected="selected"' : '') .
                              '>' . $_text . '</option>' . $option_separator;
         }

+ 1 - 1
resources/templates/engine/smarty/plugins/function.html_select_time.php

@@ -11,7 +11,7 @@
  * Name:     html_select_time
  * Purpose:  Prints the dropdowns for time selection
  *
- * @link   http://www.smarty.net/manual/en/language.function.html.select.time.php {html_select_time}
+ * @link   https://www.smarty.net/manual/en/language.function.html.select.time.php {html_select_time}
  *           (Smarty online manual)
  * @author Roberto Berto <[email protected]>
  * @author Monte Ohrt <monte AT ohrt DOT com>

+ 1 - 1
resources/templates/engine/smarty/plugins/function.html_table.php

@@ -38,7 +38,7 @@
  * @author  credit to Messju Mohr <messju at lammfellpuschen dot de>
  * @author  credit to boots <boots dot smarty at yahoo dot com>
  * @version 1.1
- * @link    http://www.smarty.net/manual/en/language.function.html.table.php {html_table}
+ * @link    https://www.smarty.net/manual/en/language.function.html.table.php {html_table}
  *           (Smarty online manual)
  *
  * @param array $params parameters

+ 21 - 16
resources/templates/engine/smarty/plugins/function.mailto.php

@@ -36,7 +36,7 @@
  * {mailto address="[email protected]" cc="[email protected],[email protected]"}
  * {mailto address="[email protected]" extra='class="mailto"'}
  *
- * @link    http://www.smarty.net/manual/en/language.function.mailto.php {mailto}
+ * @link    https://www.smarty.net/manual/en/language.function.mailto.php {mailto}
  *           (Smarty online manual)
  * @version 1.2
  * @author  Monte Ohrt <monte at ohrt dot com>
@@ -48,8 +48,13 @@
  */
 function smarty_function_mailto($params)
 {
-    static $_allowed_encoding =
-        array('javascript' => true, 'javascript_charcode' => true, 'hex' => true, 'none' => true);
+    static $_allowed_encoding = [
+        'javascript' => true,
+        'javascript_charcode' => true,
+        'hex' => true,
+        'none' => true
+    ];
+
     $extra = '';
     if (empty($params[ 'address' ])) {
         trigger_error("mailto: missing 'address' parameter", E_USER_WARNING);
@@ -57,19 +62,19 @@ function smarty_function_mailto($params)
     } else {
         $address = $params[ 'address' ];
     }
+
     $text = $address;
+
     // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
     // so, don't encode it.
-    $search = array('%40', '%2C');
-    $replace = array('@', ',');
-    $mail_parms = array();
+    $mail_parms = [];
     foreach ($params as $var => $value) {
         switch ($var) {
             case 'cc':
             case 'bcc':
             case 'followupto':
                 if (!empty($value)) {
-                    $mail_parms[] = $var . '=' . str_replace($search, $replace, rawurlencode($value));
+                    $mail_parms[] = $var . '=' . str_replace(['%40', '%2C'], ['@', ','], rawurlencode($value));
                 }
                 break;
             case 'subject':
@@ -83,6 +88,7 @@ function smarty_function_mailto($params)
             default:
         }
     }
+
     if ($mail_parms) {
         $address .= '?' . join('&', $mail_parms);
     }
@@ -94,22 +100,21 @@ function smarty_function_mailto($params)
         );
         return;
     }
-    // FIXME: (rodneyrehm) document.write() excues me what? 1998 has passed!
+
+    $string = '<a href="mailto:' . htmlspecialchars($address, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, Smarty::$_CHARSET) .
+        '" ' . $extra . '>' . htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, Smarty::$_CHARSET) . '</a>';
+
     if ($encode === 'javascript') {
-        $string = 'document.write(\'<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>\');';
         $js_encode = '';
         for ($x = 0, $_length = strlen($string); $x < $_length; $x++) {
             $js_encode .= '%' . bin2hex($string[ $x ]);
         }
-        return '<script type="text/javascript">eval(unescape(\'' . $js_encode . '\'))</script>';
+        return '<script type="text/javascript">document.write(unescape(\'' . $js_encode . '\'))</script>';
     } elseif ($encode === 'javascript_charcode') {
-        $string = '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
-        for ($x = 0, $y = strlen($string); $x < $y; $x++) {
+        for ($x = 0, $_length = strlen($string); $x < $_length; $x++) {
             $ord[] = ord($string[ $x ]);
         }
-        $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n" . "{document.write(String.fromCharCode(" .
-                implode(',', $ord) . "))" . "}\n" . "</script>\n";
-        return $_ret;
+        return '<script type="text/javascript">document.write(String.fromCharCode(' . implode(',', $ord) . '))</script>';
     } elseif ($encode === 'hex') {
         preg_match('!^(.*)(\?.*)$!', $address, $match);
         if (!empty($match[ 2 ])) {
@@ -132,6 +137,6 @@ function smarty_function_mailto($params)
         return '<a href="' . $mailto . $address_encode . '" ' . $extra . '>' . $text_encode . '</a>';
     } else {
         // no encoding
-        return '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
+        return $string;
     }
 }

+ 32 - 2
resources/templates/engine/smarty/plugins/function.math.php

@@ -12,7 +12,7 @@
  * Name:     math
  * Purpose:  handle math computations in template
  *
- * @link   http://www.smarty.net/manual/en/language.function.math.php {math}
+ * @link   https://www.smarty.net/manual/en/language.function.math.php {math}
  *           (Smarty online manual)
  * @author Monte Ohrt <monte at ohrt dot com>
  *
@@ -28,7 +28,12 @@ function smarty_function_math($params, $template)
             'int'   => true,
             'abs'   => true,
             'ceil'  => true,
+            'acos'   => true,
+            'acosh'   => true,
             'cos'   => true,
+            'cosh'   => true,
+            'deg2rad'   => true,
+            'rad2deg'   => true,
             'exp'   => true,
             'floor' => true,
             'log'   => true,
@@ -39,27 +44,51 @@ function smarty_function_math($params, $template)
             'pow'   => true,
             'rand'  => true,
             'round' => true,
+            'asin'   => true,
+            'asinh'   => true,
             'sin'   => true,
+            'sinh'   => true,
             'sqrt'  => true,
             'srand' => true,
-            'tan'   => true
+            'atan'   => true,
+            'atanh'   => true,
+            'tan'   => true,
+            'tanh'   => true
         );
+
     // be sure equation parameter is present
     if (empty($params[ 'equation' ])) {
         trigger_error("math: missing equation parameter", E_USER_WARNING);
         return;
     }
     $equation = $params[ 'equation' ];
+
+    // Remove whitespaces
+    $equation = preg_replace('/\s+/', '', $equation);
+
+    // Adapted from https://www.php.net/manual/en/function.eval.php#107377
+    $number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number
+    $functionsOrVars = '((?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))';
+    $operators = '[,+\/*\^%-]'; // Allowed math operators
+    $regexp = '/^(('.$number.'|'.$functionsOrVars.'|('.$functionsOrVars.'\s*\((?1)*\)|\((?1)*\)))(?:'.$operators.'(?1))?)+$/';
+
+    if (!preg_match($regexp, $equation)) {
+        trigger_error("math: illegal characters", E_USER_WARNING);
+        return;
+    }
+
     // make sure parenthesis are balanced
     if (substr_count($equation, '(') !== substr_count($equation, ')')) {
         trigger_error("math: unbalanced parenthesis", E_USER_WARNING);
         return;
     }
+
     // disallow backticks
     if (strpos($equation, '`') !== false) {
         trigger_error("math: backtick character not allowed in equation", E_USER_WARNING);
         return;
     }
+
     // also disallow dollar signs
     if (strpos($equation, '$') !== false) {
         trigger_error("math: dollar signs not allowed in equation", E_USER_WARNING);
@@ -96,6 +125,7 @@ function smarty_function_math($params, $template)
     }
     $smarty_math_result = null;
     eval("\$smarty_math_result = " . $equation . ";");
+
     if (empty($params[ 'format' ])) {
         if (empty($params[ 'assign' ])) {
             return $smarty_math_result;

+ 2 - 0
resources/templates/engine/smarty/plugins/modifier.capitalize.php

@@ -22,6 +22,8 @@
  */
 function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = false)
 {
+    $string = (string) $string;
+
     if (Smarty::$_MBSTRING) {
         if ($lc_rest) {
             // uppercase (including hyphenated words)

+ 36 - 0
resources/templates/engine/smarty/plugins/modifier.count.php

@@ -0,0 +1,36 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package    Smarty
+ * @subpackage PluginsModifier
+ */
+/**
+ * Smarty count modifier plugin
+ * Type:     modifier
+ * Name:     count
+ * Purpose:  counts all elements in an array or in a Countable object
+ * Input:
+ *          - Countable|array: array or object to count
+ *          - mode: int defaults to 0 for normal count mode, if set to 1 counts recursive
+  *
+ * @param mixed $arrayOrObject  input array/object
+ * @param int $mode       count mode
+ *
+ * @return int
+ */
+function smarty_modifier_count($arrayOrObject, $mode = 0)
+{
+    /*
+     * @see https://www.php.net/count
+     * > Prior to PHP 8.0.0, if the parameter was neither an array nor an object that implements the Countable interface,
+     * > 1 would be returned, unless value was null, in which case 0 would be returned.
+     */
+
+    if ($arrayOrObject instanceof Countable || is_array($arrayOrObject)) {
+        return count($arrayOrObject, (int) $mode);
+    } elseif ($arrayOrObject === null) {
+        return 0;
+    }
+    return 1;
+}

+ 5 - 4
resources/templates/engine/smarty/plugins/modifier.date_format.php

@@ -15,7 +15,7 @@
  *          - format: strftime format for output
  *          - default_date: default date if $string is empty
  *
- * @link   http://www.smarty.net/manual/en/language.modifier.date.format.php date_format (Smarty online manual)
+ * @link   https://www.smarty.net/manual/en/language.modifier.date.format.php date_format (Smarty online manual)
  * @author Monte Ohrt <monte at ohrt dot com>
  *
  * @param string $string       input date string
@@ -41,9 +41,9 @@ function smarty_modifier_date_format($string, $format = null, $default_date = ''
         }
         $is_loaded = true;
     }
-    if ($string !== '' && $string !== '0000-00-00' && $string !== '0000-00-00 00:00:00') {
+    if (!empty($string) && $string !== '0000-00-00' && $string !== '0000-00-00 00:00:00') {
         $timestamp = smarty_make_timestamp($string);
-    } elseif ($default_date !== '') {
+    } elseif (!empty($default_date)) {
         $timestamp = smarty_make_timestamp($default_date);
     } else {
         return;
@@ -78,7 +78,8 @@ function smarty_modifier_date_format($string, $format = null, $default_date = ''
             }
             $format = str_replace($_win_from, $_win_to, $format);
         }
-        return strftime($format, $timestamp);
+        // @ to suppress deprecation errors when running in PHP8.1 or higher.
+        return @strftime($format, $timestamp);
     } else {
         return date($format, $timestamp);
     }

+ 16 - 82
resources/templates/engine/smarty/plugins/modifier.escape.php

@@ -11,7 +11,7 @@
  * Name:     escape
  * Purpose:  escape string for output
  *
- * @link   http://www.smarty.net/docs/en/language.modifier.escape
+ * @link   https://www.smarty.net/docs/en/language.modifier.escape
  * @author Monte Ohrt <monte at ohrt dot com>
  *
  * @param string  $string        input string
@@ -23,98 +23,25 @@
  */
 function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true)
 {
-    static $_double_encode = null;
     static $is_loaded_1 = false;
     static $is_loaded_2 = false;
-    if ($_double_encode === null) {
-        $_double_encode = version_compare(PHP_VERSION, '5.2.3', '>=');
-    }
     if (!$char_set) {
         $char_set = Smarty::$_CHARSET;
     }
+
+    $string = (string)$string;
+
     switch ($esc_type) {
         case 'html':
-            if ($_double_encode) {
-                // php >=5.3.2 - go native
-                return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
-            } else {
-                if ($double_encode) {
-                    // php <5.2.3 - only handle double encoding
-                    return htmlspecialchars($string, ENT_QUOTES, $char_set);
-                } else {
-                    // php <5.2.3 - prevent double encoding
-                    $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
-                    $string = htmlspecialchars($string, ENT_QUOTES, $char_set);
-                    $string = str_replace(
-                        array(
-                            '%%%SMARTY_START%%%',
-                            '%%%SMARTY_END%%%'
-                        ),
-                        array(
-                            '&',
-                            ';'
-                        ),
-                        $string
-                    );
-                    return $string;
-                }
-            }
+            return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
         // no break
         case 'htmlall':
             if (Smarty::$_MBSTRING) {
-                // mb_convert_encoding ignores htmlspecialchars()
-                if ($_double_encode) {
-                    // php >=5.3.2 - go native
-                    $string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
-                } else {
-                    if ($double_encode) {
-                        // php <5.2.3 - only handle double encoding
-                        $string = htmlspecialchars($string, ENT_QUOTES, $char_set);
-                    } else {
-                        // php <5.2.3 - prevent double encoding
-                        $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
-                        $string = htmlspecialchars($string, ENT_QUOTES, $char_set);
-                        $string =
-                            str_replace(
-                                array(
-                                    '%%%SMARTY_START%%%',
-                                    '%%%SMARTY_END%%%'
-                                ),
-                                array(
-                                    '&',
-                                    ';'
-                                ),
-                                $string
-                            );
-                        return $string;
-                    }
-                }
-                // htmlentities() won't convert everything, so use mb_convert_encoding
-                return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set);
+                $string = mb_convert_encoding($string, 'UTF-8', $char_set);
+                return htmlentities($string, ENT_QUOTES, 'UTF-8', $double_encode);
             }
             // no MBString fallback
-            if ($_double_encode) {
-                return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
-            } else {
-                if ($double_encode) {
-                    return htmlentities($string, ENT_QUOTES, $char_set);
-                } else {
-                    $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
-                    $string = htmlentities($string, ENT_QUOTES, $char_set);
-                    $string = str_replace(
-                        array(
-                            '%%%SMARTY_START%%%',
-                            '%%%SMARTY_END%%%'
-                        ),
-                        array(
-                            '&',
-                            ';'
-                        ),
-                        $string
-                    );
-                    return $string;
-                }
-            }
+            return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
         // no break
         case 'url':
             return rawurlencode($string);
@@ -184,7 +111,13 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
                     '"'  => '\\"',
                     "\r" => '\\r',
                     "\n" => '\\n',
-                    '</' => '<\/'
+                    '</' => '<\/',
+                    // see https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements
+                    '<!--' => '<\!--',
+                    '<s'   => '<\s',
+                    '<S'   => '<\S',
+	                "`" => "\\\\`",
+	                "\${" => "\\\\\\$\\{"
                 )
             );
         case 'mail':
@@ -250,6 +183,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
             }
             return $return;
         default:
+            trigger_error("escape: unsupported type: $esc_type - returning unmodified string", E_USER_NOTICE);
             return $string;
     }
 }

+ 25 - 0
resources/templates/engine/smarty/plugins/modifier.explode.php

@@ -0,0 +1,25 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package    Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty explode modifier plugin
+ * Type:     modifier
+ * Name:     explode
+ * Purpose:  split a string by a string
+ *
+ * @param string   $separator
+ * @param string   $string
+ * @param int|null $limit
+ *
+ * @return array
+ */
+function smarty_modifier_explode($separator, $string, ?int $limit = null)
+{
+    // provide $string default to prevent deprecation errors in PHP >=8.1
+    return explode($separator, $string ?? '', $limit ?? PHP_INT_MAX);
+}

+ 1 - 1
resources/templates/engine/smarty/plugins/modifier.mb_wordwrap.php

@@ -11,7 +11,7 @@
  * Name:     mb_wordwrap
  * Purpose:  Wrap a string to a given number of characters
  *
- * @link   http://php.net/manual/en/function.wordwrap.php for similarity
+ * @link   https://php.net/manual/en/function.wordwrap.php for similarity
  *
  * @param string  $str   the string to wrap
  * @param int     $width the width of the output

+ 26 - 0
resources/templates/engine/smarty/plugins/modifier.number_format.php

@@ -0,0 +1,26 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package    Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty number_format modifier plugin
+ * Type:     modifier
+ * Name:     number_format
+ * Purpose:  Format a number with grouped thousands
+ *
+ * @param float|null  $num
+ * @param int         $decimals
+ * @param string|null $decimal_separator
+ * @param string|null $thousands_separator
+ *
+ * @return string
+ */
+function smarty_modifier_number_format(?float $num, int $decimals = 0, ?string $decimal_separator = ".", ?string $thousands_separator = ",")
+{
+    // provide $num default to prevent deprecation errors in PHP >=8.1
+    return number_format($num ?? 0.0, $decimals, $decimal_separator, $thousands_separator);
+}

+ 1 - 1
resources/templates/engine/smarty/plugins/modifier.regex_replace.php

@@ -11,7 +11,7 @@
  * Name:     regex_replace
  * Purpose:  regular expression search/replace
  *
- * @link   http://smarty.php.net/manual/en/language.modifier.regex.replace.php
+ * @link   https://www.smarty.net/manual/en/language.modifier.regex.replace.php
  *          regex_replace (Smarty online manual)
  * @author Monte Ohrt <monte at ohrt dot com>
  *

+ 1 - 1
resources/templates/engine/smarty/plugins/modifier.replace.php

@@ -11,7 +11,7 @@
  * Name:     replace
  * Purpose:  simple search/replace
  *
- * @link   http://smarty.php.net/manual/en/language.modifier.replace.php replace (Smarty online manual)
+ * @link   https://www.smarty.net/manual/en/language.modifier.replace.php replace (Smarty online manual)
  * @author Monte Ohrt <monte at ohrt dot com>
  * @author Uwe Tews
  *

+ 1 - 1
resources/templates/engine/smarty/plugins/modifier.spacify.php

@@ -11,7 +11,7 @@
  * Name:     spacify
  * Purpose:  add spaces between characters in a string
  *
- * @link   http://smarty.php.net/manual/en/language.modifier.spacify.php spacify (Smarty online manual)
+ * @link   https://www.smarty.net/manual/en/language.modifier.spacify.php spacify (Smarty online manual)
  * @author Monte Ohrt <monte at ohrt dot com>
  *
  * @param string $string       input string

+ 5 - 5
resources/templates/engine/smarty/plugins/modifier.truncate.php

@@ -13,7 +13,7 @@
  *               optionally splitting in the middle of a word, and
  *               appending the $etc string or inserting $etc into the middle.
  *
- * @link   http://smarty.php.net/manual/en/language.modifier.truncate.php truncate (Smarty online manual)
+ * @link   https://www.smarty.net/manual/en/language.modifier.truncate.php truncate (Smarty online manual)
  * @author Monte Ohrt <monte at ohrt dot com>
  *
  * @param string  $string      input string
@@ -26,7 +26,7 @@
  */
 function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_words = false, $middle = false)
 {
-    if ($length === 0) {
+    if ($length === 0 || $string === null) {
         return '';
     }
     if (Smarty::$_MBSTRING) {
@@ -42,8 +42,8 @@ function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_wo
             if (!$middle) {
                 return mb_substr($string, 0, $length, Smarty::$_CHARSET) . $etc;
             }
-            return mb_substr($string, 0, $length / 2, Smarty::$_CHARSET) . $etc .
-                   mb_substr($string, -$length / 2, $length, Smarty::$_CHARSET);
+            return mb_substr($string, 0, intval($length / 2), Smarty::$_CHARSET) . $etc .
+                   mb_substr($string, -intval($length / 2), $length, Smarty::$_CHARSET);
         }
         return $string;
     }
@@ -56,7 +56,7 @@ function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_wo
         if (!$middle) {
             return substr($string, 0, $length) . $etc;
         }
-        return substr($string, 0, $length / 2) . $etc . substr($string, -$length / 2);
+        return substr($string, 0, intval($length / 2)) . $etc . substr($string, -intval($length / 2));
     }
     return $string;
 }

+ 1 - 1
resources/templates/engine/smarty/plugins/modifiercompiler.cat.php

@@ -14,7 +14,7 @@
  * Input:    string to catenate
  * Example:  {$var|cat:"foo"}
  *
- * @link   http://smarty.php.net/manual/en/language.modifier.cat.php cat
+ * @link   https://www.smarty.net/manual/en/language.modifier.cat.php cat
  *           (Smarty online manual)
  * @author Uwe Tews
  *

+ 3 - 3
resources/templates/engine/smarty/plugins/modifiercompiler.count_characters.php

@@ -11,7 +11,7 @@
  * Name:     count_characters
  * Purpose:  count the number of characters in a text
  *
- * @link   http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online
+ * @link   https://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online
  *         manual)
  * @author Uwe Tews
  *
@@ -25,8 +25,8 @@ function smarty_modifiercompiler_count_characters($params)
         return 'preg_match_all(\'/[^\s]/' . Smarty::$_UTF8_MODIFIER . '\',' . $params[ 0 ] . ', $tmp)';
     }
     if (Smarty::$_MBSTRING) {
-        return 'mb_strlen(' . $params[ 0 ] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')';
+        return 'mb_strlen((string) ' . $params[ 0 ] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')';
     }
     // no MBString fallback
-    return 'strlen(' . $params[ 0 ] . ')';
+    return 'strlen((string) ' . $params[ 0 ] . ')';
 }

+ 1 - 1
resources/templates/engine/smarty/plugins/modifiercompiler.count_paragraphs.php

@@ -11,7 +11,7 @@
  * Name:     count_paragraphs
  * Purpose:  count the number of paragraphs in a text
  *
- * @link   http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
+ * @link   https://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
  *          count_paragraphs (Smarty online manual)
  * @author Uwe Tews
  *

+ 1 - 1
resources/templates/engine/smarty/plugins/modifiercompiler.count_sentences.php

@@ -11,7 +11,7 @@
  * Name:     count_sentences
  * Purpose:  count the number of sentences in a text
  *
- * @link   http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
+ * @link   https://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
  *          count_sentences (Smarty online manual)
  * @author Uwe Tews
  *

+ 2 - 2
resources/templates/engine/smarty/plugins/modifiercompiler.count_words.php

@@ -11,7 +11,7 @@
  * Name:     count_words
  * Purpose:  count the number of words in a text
  *
- * @link   http://www.smarty.net/manual/en/language.modifier.count.words.php count_words (Smarty online manual)
+ * @link   https://www.smarty.net/manual/en/language.modifier.count.words.php count_words (Smarty online manual)
  * @author Uwe Tews
  *
  * @param array $params parameters
@@ -27,5 +27,5 @@ function smarty_modifiercompiler_count_words($params)
                $params[ 0 ] . ', $tmp)';
     }
     // no MBString fallback
-    return 'str_word_count(' . $params[ 0 ] . ')';
+    return 'str_word_count((string) ' . $params[ 0 ] . ')';
 }

+ 2 - 2
resources/templates/engine/smarty/plugins/modifiercompiler.default.php

@@ -11,7 +11,7 @@
  * Name:     default
  * Purpose:  designate default value for empty variables
  *
- * @link   http://www.smarty.net/manual/en/language.modifier.default.php default (Smarty online manual)
+ * @link   https://www.smarty.net/manual/en/language.modifier.default.php default (Smarty online manual)
  * @author Uwe Tews
  *
  * @param array $params parameters
@@ -26,7 +26,7 @@ function smarty_modifiercompiler_default($params)
     }
     array_shift($params);
     foreach ($params as $param) {
-        $output = '(($tmp = @' . $output . ')===null||$tmp===\'\' ? ' . $param . ' : $tmp)';
+        $output = '(($tmp = ' . $output . ' ?? null)===null||$tmp===\'\' ? ' . $param . ' ?? null : $tmp)';
     }
     return $output;
 }

+ 17 - 42
resources/templates/engine/smarty/plugins/modifiercompiler.escape.php

@@ -11,19 +11,17 @@
  * Name:     escape
  * Purpose:  escape string for output
  *
- * @link   http://www.smarty.net/docsv2/en/language.modifier.escape count_characters (Smarty online manual)
+ * @link   https://www.smarty.net/docsv2/en/language.modifier.escape count_characters (Smarty online manual)
  * @author Rodney Rehm
  *
  * @param array                                $params parameters
  * @param Smarty_Internal_TemplateCompilerBase $compiler
  *
  * @return string with compiled code
- * @throws \SmartyException
+ * @throws SmartyException
  */
 function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompilerBase $compiler)
 {
-    static $_double_encode = null;
-    static $is_loaded = false;
     $compiler->template->_checkPlugins(
         array(
             array(
@@ -32,9 +30,6 @@ function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompile
             )
         )
     );
-    if ($_double_encode === null) {
-        $_double_encode = version_compare(PHP_VERSION, '5.2.3', '>=');
-    }
     try {
         $esc_type = smarty_literal_compiler_param($params, 1, 'html');
         $char_set = smarty_literal_compiler_param($params, 2, Smarty::$_CHARSET);
@@ -44,54 +39,34 @@ function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompile
         }
         switch ($esc_type) {
             case 'html':
-                if ($_double_encode) {
-                    return 'htmlspecialchars(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' .
-                           var_export($double_encode, true) . ')';
-                } elseif ($double_encode) {
-                    return 'htmlspecialchars(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ')';
-                } else {
-                    // fall back to modifier.escape.php
-                }
+                return 'htmlspecialchars((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' .
+                    var_export($double_encode, true) . ')';
             // no break
             case 'htmlall':
                 if (Smarty::$_MBSTRING) {
-                    if ($_double_encode) {
-                        // php >=5.2.3 - go native
-                        return 'mb_convert_encoding(htmlspecialchars(' . $params[ 0 ] . ', ENT_QUOTES, ' .
-                               var_export($char_set, true) . ', ' . var_export($double_encode, true) .
-                               '), "HTML-ENTITIES", ' . var_export($char_set, true) . ')';
-                    } elseif ($double_encode) {
-                        // php <5.2.3 - only handle double encoding
-                        return 'mb_convert_encoding(htmlspecialchars(' . $params[ 0 ] . ', ENT_QUOTES, ' .
-                               var_export($char_set, true) . '), "HTML-ENTITIES", ' . var_export($char_set, true) . ')';
-                    } else {
-                        // fall back to modifier.escape.php
-                    }
+                    return 'htmlentities(mb_convert_encoding((string)' . $params[ 0 ] . ', \'UTF-8\', ' .
+                        var_export($char_set, true) . '), ENT_QUOTES, \'UTF-8\', ' .
+                        var_export($double_encode, true) . ')';
                 }
                 // no MBString fallback
-                if ($_double_encode) {
-                    // php >=5.2.3 - go native
-                    return 'htmlentities(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' .
-                           var_export($double_encode, true) . ')';
-                } elseif ($double_encode) {
-                    // php <5.2.3 - only handle double encoding
-                    return 'htmlentities(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ')';
-                } else {
-                    // fall back to modifier.escape.php
-                }
+                return 'htmlentities((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' .
+                    var_export($double_encode, true) . ')';
             // no break
             case 'url':
-                return 'rawurlencode(' . $params[ 0 ] . ')';
+                return 'rawurlencode((string)' . $params[ 0 ] . ')';
             case 'urlpathinfo':
-                return 'str_replace("%2F", "/", rawurlencode(' . $params[ 0 ] . '))';
+                return 'str_replace("%2F", "/", rawurlencode((string)' . $params[ 0 ] . '))';
             case 'quotes':
                 // escape unescaped single quotes
-                return 'preg_replace("%(?<!\\\\\\\\)\'%", "\\\'",' . $params[ 0 ] . ')';
+                return 'preg_replace("%(?<!\\\\\\\\)\'%", "\\\'", (string)' . $params[ 0 ] . ')';
             case 'javascript':
                 // escape quotes and backslashes, newlines, etc.
-                return 'strtr(' .
+                // see https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements
+                return 'strtr((string)' .
                        $params[ 0 ] .
-                       ', array("\\\\" => "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", "</" => "<\/" ))';
+                       ', array("\\\\" => "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", 
+                       "\\n" => "\\\n", "</" => "<\/", "<!--" => "<\!--", "<s" => "<\s", "<S" => "<\S",
+                       "`" => "\\\\`", "\${" => "\\\\\\$\\{"))';
         }
     } catch (SmartyException $e) {
         // pass through to regular plugin fallback

+ 1 - 1
resources/templates/engine/smarty/plugins/modifiercompiler.indent.php

@@ -11,7 +11,7 @@
  * Name:     indent
  * Purpose:  indent lines of text
  *
- * @link   http://www.smarty.net/manual/en/language.modifier.indent.php indent (Smarty online manual)
+ * @link   https://www.smarty.net/manual/en/language.modifier.indent.php indent (Smarty online manual)
  * @author Uwe Tews
  *
  * @param array $params parameters

+ 3 - 3
resources/templates/engine/smarty/plugins/modifiercompiler.lower.php

@@ -11,7 +11,7 @@
  * Name:     lower
  * Purpose:  convert string to lowercase
  *
- * @link   http://www.smarty.net/manual/en/language.modifier.lower.php lower (Smarty online manual)
+ * @link   https://www.smarty.net/manual/en/language.modifier.lower.php lower (Smarty online manual)
  * @author Monte Ohrt <monte at ohrt dot com>
  * @author Uwe Tews
  *
@@ -22,8 +22,8 @@
 function smarty_modifiercompiler_lower($params)
 {
     if (Smarty::$_MBSTRING) {
-        return 'mb_strtolower(' . $params[ 0 ] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')';
+        return 'mb_strtolower((string) ' . $params[ 0 ] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')';
     }
     // no MBString fallback
-    return 'strtolower(' . $params[ 0 ] . ')';
+    return 'strtolower((string) ' . $params[ 0 ] . ')';
 }

+ 23 - 0
resources/templates/engine/smarty/plugins/modifiercompiler.nl2br.php

@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * Smarty plugin
+ *
+ * @package    Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+/**
+ * Smarty nl2br modifier plugin
+ * Type:     modifier
+ * Name:     nl2br
+ * Purpose:  insert HTML line breaks before all newlines in a string
+ *
+ * @link   https://www.smarty.net/docs/en/language.modifier.nl2br.tpl nl2br (Smarty online manual)
+  *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_nl2br($params) {
+    return 'nl2br((string) ' . $params[0] . ', (bool) ' . ($params[1] ?? true) . ')';
+}

+ 23 - 0
resources/templates/engine/smarty/plugins/modifiercompiler.round.php

@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * Smarty plugin
+ *
+ * @package    Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+/**
+ * Smarty round modifier plugin
+ * Type:     modifier
+ * Name:     round
+ * Purpose:  Returns the rounded value of num to specified precision (number of digits after the decimal point)
+ *
+ * @link   https://www.smarty.net/docs/en/language.modifier.round.tpl round (Smarty online manual)
+  *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_round($params) {
+    return 'round((float) ' . $params[0] . ', (int) ' . ($params[1] ?? 0) . ', (int) ' . ($params[2] ?? PHP_ROUND_HALF_UP) . ')';
+}

+ 23 - 0
resources/templates/engine/smarty/plugins/modifiercompiler.str_repeat.php

@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * Smarty plugin
+ *
+ * @package    Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+/**
+ * Smarty str_repeat modifier plugin
+ * Type:     modifier
+ * Name:     str_repeat
+ * Purpose:  returns string repeated times times
+ *
+ * @link   https://www.smarty.net/docs/en/language.modifier.str_repeat.tpl str_repeat (Smarty online manual)
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_str_repeat($params) {
+    return 'str_repeat((string) ' . $params[0] . ', (int) ' . $params[1] . ')';
+}

+ 1 - 1
resources/templates/engine/smarty/plugins/modifiercompiler.string_format.php

@@ -11,7 +11,7 @@
  * Name:     string_format
  * Purpose:  format strings via sprintf
  *
- * @link   http://www.smarty.net/manual/en/language.modifier.string.format.php string_format (Smarty online manual)
+ * @link   https://www.smarty.net/manual/en/language.modifier.string.format.php string_format (Smarty online manual)
  * @author Uwe Tews
  *
  * @param array $params parameters

+ 1 - 1
resources/templates/engine/smarty/plugins/modifiercompiler.strip.php

@@ -14,7 +14,7 @@
  * Example:  {$var|strip} {$var|strip:"&nbsp;"}
  * Date:     September 25th, 2002
  *
- * @link   http://www.smarty.net/manual/en/language.modifier.strip.php strip (Smarty online manual)
+ * @link   https://www.smarty.net/manual/en/language.modifier.strip.php strip (Smarty online manual)
  * @author Uwe Tews
  *
  * @param array $params parameters

+ 3 - 3
resources/templates/engine/smarty/plugins/modifiercompiler.strip_tags.php

@@ -11,7 +11,7 @@
  * Name:     strip_tags
  * Purpose:  strip html tags from text
  *
- * @link   http://www.smarty.net/docs/en/language.modifier.strip.tags.tpl strip_tags (Smarty online manual)
+ * @link   https://www.smarty.net/docs/en/language.modifier.strip.tags.tpl strip_tags (Smarty online manual)
  * @author Uwe Tews
  *
  * @param array $params parameters
@@ -21,8 +21,8 @@
 function smarty_modifiercompiler_strip_tags($params)
 {
     if (!isset($params[ 1 ]) || $params[ 1 ] === true || trim($params[ 1 ], '"') === 'true') {
-        return "preg_replace('!<[^>]*?>!', ' ', {$params[0]})";
+        return "preg_replace('!<[^>]*?>!', ' ', {$params[0]} ?: '')";
     } else {
-        return 'strip_tags(' . $params[ 0 ] . ')';
+        return 'strip_tags((string) ' . $params[ 0 ] . ')';
     }
 }

+ 23 - 0
resources/templates/engine/smarty/plugins/modifiercompiler.strlen.php

@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * Smarty plugin
+ *
+ * @package    Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+/**
+ * Smarty strlen modifier plugin
+ * Type:     modifier
+ * Name:     strlen
+ * Purpose:  return the length of the given string
+ *
+ * @link   https://www.smarty.net/docs/en/language.modifier.strlen.tpl strlen (Smarty online manual)
+  *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_strlen($params) {
+    return 'strlen((string) ' . $params[0] . ')';
+}

+ 17 - 9
resources/templates/engine/smarty/plugins/modifiercompiler.unescape.php

@@ -14,26 +14,34 @@
  * @author Rodney Rehm
  *
  * @param array $params parameters
+ * @param Smarty_Internal_TemplateCompilerBase $compiler
  *
  * @return string with compiled code
  */
-function smarty_modifiercompiler_unescape($params)
+function smarty_modifiercompiler_unescape($params, Smarty_Internal_TemplateCompilerBase $compiler)
 {
-    if (!isset($params[ 1 ])) {
-        $params[ 1 ] = 'html';
-    }
+    $compiler->template->_checkPlugins(
+        array(
+            array(
+                'function' => 'smarty_literal_compiler_param',
+                'file'     => SMARTY_PLUGINS_DIR . 'shared.literal_compiler_param.php'
+            )
+        )
+    );
+
+    $esc_type = smarty_literal_compiler_param($params, 1, 'html');
+
     if (!isset($params[ 2 ])) {
         $params[ 2 ] = '\'' . addslashes(Smarty::$_CHARSET) . '\'';
-    } else {
-        $params[ 2 ] = "'{$params[ 2 ]}'";
     }
-    switch (trim($params[ 1 ], '"\'')) {
+
+    switch ($esc_type) {
         case 'entity':
         case 'htmlall':
             if (Smarty::$_MBSTRING) {
-                return 'mb_convert_encoding(' . $params[ 0 ] . ', ' . $params[ 2 ] . ', \'HTML-ENTITIES\')';
+                return 'html_entity_decode(mb_convert_encoding(' . $params[ 0 ] . ', ' . $params[ 2 ] . ', \'UTF-8\'), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, ' . $params[ 2 ] . ')';
             }
-            return 'html_entity_decode(' . $params[ 0 ] . ', ENT_NOQUOTES, ' . $params[ 2 ] . ')';
+            return 'html_entity_decode(' . $params[ 0 ] . ', ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, ' . $params[ 2 ] . ')';
         case 'html':
             return 'htmlspecialchars_decode(' . $params[ 0 ] . ', ENT_QUOTES)';
         case 'url':

+ 3 - 3
resources/templates/engine/smarty/plugins/modifiercompiler.upper.php

@@ -11,7 +11,7 @@
  * Name:     lower
  * Purpose:  convert string to uppercase
  *
- * @link   http://smarty.php.net/manual/en/language.modifier.upper.php lower (Smarty online manual)
+ * @link   https://www.smarty.net/manual/en/language.modifier.upper.php lower (Smarty online manual)
  * @author Uwe Tews
  *
  * @param array $params parameters
@@ -21,8 +21,8 @@
 function smarty_modifiercompiler_upper($params)
 {
     if (Smarty::$_MBSTRING) {
-        return 'mb_strtoupper(' . $params[ 0 ] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')';
+        return 'mb_strtoupper((string) ' . $params[ 0 ] . ' ?? \'\', \'' . addslashes(Smarty::$_CHARSET) . '\')';
     }
     // no MBString fallback
-    return 'strtoupper(' . $params[ 0 ] . ')';
+    return 'strtoupper((string) ' . $params[ 0 ] . ' ?? \'\')';
 }

+ 1 - 1
resources/templates/engine/smarty/plugins/modifiercompiler.wordwrap.php

@@ -11,7 +11,7 @@
  * Name:     wordwrap
  * Purpose:  wrap a string of text at a given length
  *
- * @link   http://smarty.php.net/manual/en/language.modifier.wordwrap.php wordwrap (Smarty online manual)
+ * @link   https://www.smarty.net/manual/en/language.modifier.wordwrap.php wordwrap (Smarty online manual)
  * @author Uwe Tews
  *
  * @param array                                 $params parameters

+ 2 - 2
resources/templates/engine/smarty/plugins/outputfilter.trimwhitespace.php

@@ -41,7 +41,7 @@ function smarty_outputfilter_trimwhitespace($source)
         }
     }
     // Strip all HTML-Comments
-    // yes, even the ones in <script> - see http://stackoverflow.com/a/808850/515124
+    // yes, even the ones in <script> - see https://stackoverflow.com/a/808850/515124
     $source = preg_replace('#<!--.*?-->#ms', '', $source);
     // capture html elements not to be messed with
     $_offset = 0;
@@ -62,7 +62,7 @@ function smarty_outputfilter_trimwhitespace($source)
         }
     }
     $expressions = array(// replace multiple spaces between tags by a single space
-                         // can't remove them entirely, becaue that might break poorly implemented CSS display:inline-block elements
+                         // can't remove them entirely, because that might break poorly implemented CSS display:inline-block elements
                          '#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s'                                    => '\1 \2',
                          // remove spaces between attributes (but not in attribute values!)
                          '#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5',

+ 1 - 7
resources/templates/engine/smarty/plugins/shared.escape_special_chars.php

@@ -20,13 +20,7 @@
 function smarty_function_escape_special_chars($string)
 {
     if (!is_array($string)) {
-        if (version_compare(PHP_VERSION, '5.2.3', '>=')) {
-            $string = htmlspecialchars($string, ENT_COMPAT, Smarty::$_CHARSET, false);
-        } else {
-            $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
-            $string = htmlspecialchars($string);
-            $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
-        }
+        $string = htmlspecialchars((string) $string, ENT_COMPAT, Smarty::$_CHARSET, false);
     }
     return $string;
 }

+ 35 - 1
resources/templates/engine/smarty/plugins/shared.mb_str_replace.php

@@ -44,9 +44,43 @@ if (!function_exists('smarty_mb_str_replace')) {
                 }
             }
         } else {
-            $parts = mb_split(preg_quote($search), $subject);
+            $mb_reg_charset = mb_regex_encoding();
+            // Check if mbstring regex is using UTF-8
+            $reg_is_unicode = !strcasecmp($mb_reg_charset, "UTF-8");
+            if(!$reg_is_unicode) {
+                // ...and set to UTF-8 if not
+                mb_regex_encoding("UTF-8");
+            }
+
+            // See if charset used by Smarty is matching one used by regex...
+            $current_charset = mb_regex_encoding();
+            $convert_result = (bool)strcasecmp(Smarty::$_CHARSET, $current_charset);
+            if($convert_result) {
+                // ...convert to it if not.
+                $subject = mb_convert_encoding($subject, $current_charset, Smarty::$_CHARSET);
+                $search = mb_convert_encoding($search, $current_charset, Smarty::$_CHARSET);
+                $replace = mb_convert_encoding($replace, $current_charset, Smarty::$_CHARSET);
+            }
+
+            $parts = mb_split(preg_quote($search), $subject ?? "") ?: array();
+            // If original regex encoding was not unicode...
+            if(!$reg_is_unicode) {
+                // ...restore original regex encoding to avoid breaking the system.
+                mb_regex_encoding($mb_reg_charset);
+            }
+            if($parts === false) {
+                // This exception is thrown if call to mb_split failed.
+                // Usually it happens, when $search or $replace are not valid for given mb_regex_encoding().
+                // There may be other cases for it to fail, please file an issue if you find a reproducible one.
+                throw new SmartyException("Source string is not a valid $current_charset sequence (probably)");
+            }
+
             $count = count($parts) - 1;
             $subject = implode($replace, $parts);
+            // Convert results back to charset used by Smarty, if needed.
+            if($convert_result) {
+                $subject = mb_convert_encoding($subject, Smarty::$_CHARSET, $current_charset);
+            }
         }
         return $subject;
     }

+ 1 - 1
resources/templates/engine/smarty/plugins/variablefilter.htmlspecialchars.php

@@ -15,5 +15,5 @@
  */
 function smarty_variablefilter_htmlspecialchars($source, Smarty_Internal_Template $template)
 {
-    return htmlspecialchars($source, ENT_QUOTES, Smarty::$_CHARSET);
+    return htmlspecialchars((string) $source, ENT_QUOTES, Smarty::$_CHARSET);
 }

+ 2 - 2
resources/templates/engine/smarty/sysplugins/smarty_cacheresource.php

@@ -205,11 +205,11 @@ abstract class Smarty_CacheResource
         }
         // try sysplugins dir
         if (isset(self::$sysplugins[ $type ])) {
-            $cache_resource_class = 'Smarty_Internal_CacheResource_' . ucfirst($type);
+            $cache_resource_class = 'Smarty_Internal_CacheResource_' . smarty_ucfirst_ascii($type);
             return $smarty->_cache[ 'cacheresource_handlers' ][ $type ] = new $cache_resource_class();
         }
         // try plugins dir
-        $cache_resource_class = 'Smarty_CacheResource_' . ucfirst($type);
+        $cache_resource_class = 'Smarty_CacheResource_' . smarty_ucfirst_ascii($type);
         if ($smarty->loadPlugin($cache_resource_class)) {
             return $smarty->_cache[ 'cacheresource_handlers' ][ $type ] = new $cache_resource_class();
         }

+ 2 - 2
resources/templates/engine/smarty/sysplugins/smarty_cacheresource_keyvaluestore.php

@@ -244,7 +244,7 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource
      */
     protected function sanitize($string)
     {
-        $string = trim($string, '|');
+        $string = trim((string)$string, '|');
         if (!$string) {
             return '';
         }
@@ -428,7 +428,7 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource
             $t[] = 'IVK#COMPILE' . $_compile;
         }
         $_name .= '#';
-        $cid = trim($cache_id, '|');
+        $cid = trim((string)$cache_id, '|');
         if (!$cid) {
             return $t;
         }

+ 2 - 6
resources/templates/engine/smarty/sysplugins/smarty_internal_cacheresource_file.php

@@ -196,12 +196,8 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource
      */
     public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
     {
-        if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
-            clearstatcache(true, $cached->lock_id);
-        } else {
-            clearstatcache();
-        }
-        if (is_file($cached->lock_id)) {
+        clearstatcache(true, $cached->lock_id ?? '');
+        if (null !== $cached->lock_id && is_file($cached->lock_id)) {
             $t = filemtime($cached->lock_id);
             return $t && (time() - $t < $smarty->locking_timeout);
         } else {

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_compile_assign.php

@@ -83,7 +83,7 @@ class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase
         if (isset($parameter[ 'smarty_internal_index' ])) {
             $output =
                 "<?php \$_tmp_array = isset(\$_smarty_tpl->tpl_vars[{$_var}]) ? \$_smarty_tpl->tpl_vars[{$_var}]->value : array();\n";
-            $output .= "if (!is_array(\$_tmp_array) || \$_tmp_array instanceof ArrayAccess) {\n";
+            $output .= "if (!(is_array(\$_tmp_array) || \$_tmp_array instanceof ArrayAccess)) {\n";
             $output .= "settype(\$_tmp_array, 'array');\n";
             $output .= "}\n";
             $output .= "\$_tmp_array{$parameter['smarty_internal_index']} = {$_attr['value']};\n";

+ 2 - 2
resources/templates/engine/smarty/sysplugins/smarty_internal_compile_block.php

@@ -125,7 +125,7 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_
         // setup buffer for template function code
         $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
         $output = "<?php\n";
-        $output .= "/* {block {$_name}} */\n";
+        $output .= $compiler->cStyleComment(" {block {$_name}} ") . "\n";
         $output .= "class {$_className} extends Smarty_Internal_Block\n";
         $output .= "{\n";
         foreach ($_block as $property => $value) {
@@ -155,7 +155,7 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_
         }
         $output .= "}\n";
         $output .= "}\n";
-        $output .= "/* {/block {$_name}} */\n\n";
+        $output .= $compiler->cStyleComment(" {/block {$_name}} ") . "\n\n";
         $output .= "?>\n";
         $compiler->parser->current_buffer->append_subtree(
             $compiler->parser,

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_compile_for.php

@@ -18,7 +18,7 @@ class Smarty_Internal_Compile_For extends Smarty_Internal_CompileBase
 {
     /**
      * Compiles code for the {for} tag
-     * Smarty 3 does implement two different syntax's:
+     * Smarty supports two different syntax's:
      * - {for $var in $array}
      * For looping over arrays or iterators
      * - {for $x=0; $x<$y; $x++}

+ 4 - 6
resources/templates/engine/smarty/sysplugins/smarty_internal_compile_foreach.php

@@ -219,8 +219,9 @@ class Smarty_Internal_Compile_Foreach extends Smarty_Internal_Compile_Private_Fo
         if (isset($itemAttr[ 'index' ])) {
             $output .= "{$itemVar}->index = -1;\n";
         }
-        $output .= "if (\$_from !== null) {\n";
-        $output .= "foreach (\$_from as {$keyTerm}{$itemVar}->value) {\n";
+        $output .= "{$itemVar}->do_else = true;\n";
+        $output .= "if (\$_from !== null) foreach (\$_from as {$keyTerm}{$itemVar}->value) {\n";
+        $output .= "{$itemVar}->do_else = false;\n";
         if (isset($attributes[ 'key' ]) && isset($itemAttr[ 'key' ])) {
             $output .= "\$_smarty_tpl->tpl_vars['{$key}']->value = {$itemVar}->key;\n";
         }
@@ -296,7 +297,7 @@ class Smarty_Internal_Compile_Foreachelse extends Smarty_Internal_CompileBase
         if ($restore === 2) {
             $output .= "{$itemVar} = {$local}saved;\n";
         }
-        $output .= "}\n} else {\n?>";
+        $output .= "}\nif ({$itemVar}->do_else) {\n?>";
         return $output;
     }
 }
@@ -332,9 +333,6 @@ class Smarty_Internal_Compile_Foreachclose extends Smarty_Internal_CompileBase
         if ($restore === 2) {
             $output .= "{$itemVar} = {$local}saved;\n";
         }
-        if ($restore > 0) {
-            $output .= "}\n";
-        }
         $output .= "}\n";
         /* @var Smarty_Internal_Compile_Foreach $foreachCompiler */
         $foreachCompiler = $compiler->getTagCompiler('foreach');

+ 10 - 5
resources/templates/engine/smarty/sysplugins/smarty_internal_compile_function.php

@@ -58,6 +58,11 @@ class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase
         }
         unset($_attr[ 'nocache' ]);
         $_name = trim($_attr[ 'name' ], '\'"');
+
+        if (!preg_match('/^[a-zA-Z0-9_\x80-\xff]+$/', $_name)) {
+	        $compiler->trigger_template_error("Function name contains invalid characters: {$_name}", null, true);
+        }
+
         $compiler->parent_compiler->tpl_function[ $_name ] = array();
         $save = array(
             $_attr, $compiler->parser->current_buffer, $compiler->template->compiled->has_nocache_code,
@@ -129,7 +134,7 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
         if ($compiler->template->compiled->has_nocache_code) {
             $compiler->parent_compiler->tpl_function[ $_name ][ 'call_name_caching' ] = $_funcNameCaching;
             $output = "<?php\n";
-            $output .= "/* {$_funcNameCaching} */\n";
+            $output .= $compiler->cStyleComment(" {$_funcNameCaching} ") . "\n";
             $output .= "if (!function_exists('{$_funcNameCaching}')) {\n";
             $output .= "function {$_funcNameCaching} (Smarty_Internal_Template \$_smarty_tpl,\$params) {\n";
             $output .= "ob_start();\n";
@@ -152,9 +157,9 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
             $output = "<?php echo \"/*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/<?php ";
             $output .= "\\\$_smarty_tpl->smarty->ext->_tplFunction->restoreTemplateVariables(\\\$_smarty_tpl, '{$_name}');?>\n";
             $output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\";\n?>";
-            $output .= "<?php echo str_replace('{$compiler->template->compiled->nocache_hash}', \$_smarty_tpl->compiled->nocache_hash, ob_get_clean());\n";
+            $output .= "<?php echo str_replace('{$compiler->template->compiled->nocache_hash}', \$_smarty_tpl->compiled->nocache_hash ?? '', ob_get_clean());\n";
             $output .= "}\n}\n";
-            $output .= "/*/ {$_funcName}_nocache */\n\n";
+            $output .= $compiler->cStyleComment("/ {$_funcName}_nocache ") . "\n\n";
             $output .= "?>\n";
             $compiler->parser->current_buffer->append_subtree(
                 $compiler->parser,
@@ -174,7 +179,7 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
         }
         $compiler->parent_compiler->tpl_function[ $_name ][ 'call_name' ] = $_funcName;
         $output = "<?php\n";
-        $output .= "/* {$_funcName} */\n";
+        $output .= $compiler->cStyleComment(" {$_funcName} ") . "\n";
         $output .= "if (!function_exists('{$_funcName}')) {\n";
         $output .= "function {$_funcName}(Smarty_Internal_Template \$_smarty_tpl,\$params) {\n";
         $output .= $_paramsCode;
@@ -191,7 +196,7 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
         );
         $compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
         $output = "<?php\n}}\n";
-        $output .= "/*/ {$_funcName} */\n\n";
+        $output .= $compiler->cStyleComment("/ {$_funcName} ") . "\n\n";
         $output .= "?>\n";
         $compiler->parser->current_buffer->append_subtree(
             $compiler->parser,

+ 2 - 2
resources/templates/engine/smarty/sysplugins/smarty_internal_compile_include.php

@@ -318,14 +318,14 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
             }
             // get compiled code
             $compiled_code = "<?php\n\n";
-            $compiled_code .= "/* Start inline template \"{$sourceInfo}\" =============================*/\n";
+            $compiled_code .= $compiler->cStyleComment(" Start inline template \"{$sourceInfo}\" =============================") . "\n";
             $compiled_code .= "function {$tpl->compiled->unifunc} (Smarty_Internal_Template \$_smarty_tpl) {\n";
             $compiled_code .= "?>\n" . $tpl->compiler->compileTemplateSource($tpl, null, $compiler->parent_compiler);
             $compiled_code .= "<?php\n";
             $compiled_code .= "}\n?>\n";
             $compiled_code .= $tpl->compiler->postFilter($tpl->compiler->blockOrFunctionCode);
             $compiled_code .= "<?php\n\n";
-            $compiled_code .= "/* End inline template \"{$sourceInfo}\" =============================*/\n";
+            $compiled_code .= $compiler->cStyleComment(" End inline template \"{$sourceInfo}\" =============================") . "\n";
             $compiled_code .= '?>';
             unset($tpl->compiler);
             if ($tpl->compiled->has_nocache_code) {

+ 0 - 110
resources/templates/engine/smarty/sysplugins/smarty_internal_compile_include_php.php

@@ -1,110 +0,0 @@
-<?php
-/**
- * Smarty Internal Plugin Compile Include PHP
- * Compiles the {include_php} tag
- *
- * @package    Smarty
- * @subpackage Compiler
- * @author     Uwe Tews
- */
-
-/**
- * Smarty Internal Plugin Compile Insert Class
- *
- * @package    Smarty
- * @subpackage Compiler
- */
-class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase
-{
-    /**
-     * Attribute definition: Overwrites base class.
-     *
-     * @var array
-     * @see Smarty_Internal_CompileBase
-     */
-    public $required_attributes = array('file');
-
-    /**
-     * Attribute definition: Overwrites base class.
-     *
-     * @var array
-     * @see Smarty_Internal_CompileBase
-     */
-    public $shorttag_order = array('file');
-
-    /**
-     * Attribute definition: Overwrites base class.
-     *
-     * @var array
-     * @see Smarty_Internal_CompileBase
-     */
-    public $optional_attributes = array('once', 'assign');
-
-    /**
-     * Compiles code for the {include_php} tag
-     *
-     * @param array                                 $args     array with attributes from parser
-     * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
-     *
-     * @return string
-     * @throws \SmartyCompilerException
-     * @throws \SmartyException
-     */
-    public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
-    {
-        if (!($compiler->smarty instanceof SmartyBC)) {
-            throw new SmartyException("{include_php} is deprecated, use SmartyBC class to enable");
-        }
-        // check and get attributes
-        $_attr = $this->getAttributes($compiler, $args);
-        /**
-         *
-         *
-         * @var Smarty_Internal_Template $_smarty_tpl
-         * used in evaluated code
-         */
-        $_smarty_tpl = $compiler->template;
-        $_filepath = false;
-        $_file = null;
-        eval('$_file = @' . $_attr[ 'file' ] . ';');
-        if (!isset($compiler->smarty->security_policy) && file_exists($_file)) {
-            $_filepath = $compiler->smarty->_realpath($_file, true);
-        } else {
-            if (isset($compiler->smarty->security_policy)) {
-                $_dir = $compiler->smarty->security_policy->trusted_dir;
-            } else {
-                $_dir = $compiler->smarty->trusted_dir;
-            }
-            if (!empty($_dir)) {
-                foreach ((array)$_dir as $_script_dir) {
-                    $_path = $compiler->smarty->_realpath($_script_dir . DIRECTORY_SEPARATOR . $_file, true);
-                    if (file_exists($_path)) {
-                        $_filepath = $_path;
-                        break;
-                    }
-                }
-            }
-        }
-        if ($_filepath === false) {
-            $compiler->trigger_template_error("{include_php} file '{$_file}' is not readable", null, true);
-        }
-        if (isset($compiler->smarty->security_policy)) {
-            $compiler->smarty->security_policy->isTrustedPHPDir($_filepath);
-        }
-        if (isset($_attr[ 'assign' ])) {
-            // output will be stored in a smarty variable instead of being displayed
-            $_assign = $_attr[ 'assign' ];
-        }
-        $_once = '_once';
-        if (isset($_attr[ 'once' ])) {
-            if ($_attr[ 'once' ] === 'false') {
-                $_once = '';
-            }
-        }
-        if (isset($_assign)) {
-            return "<?php ob_start();\ninclude{$_once} ('{$_filepath}');\n\$_smarty_tpl->assign({$_assign},ob_get_clean());\n?>";
-        } else {
-            return "<?php include{$_once} ('{$_filepath}');?>\n";
-        }
-    }
-}

+ 3 - 2
resources/templates/engine/smarty/sysplugins/smarty_internal_compile_insert.php

@@ -89,11 +89,11 @@ class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase
                 if (isset($compiler->smarty->security_policy)) {
                     $_dir = $compiler->smarty->security_policy->trusted_dir;
                 } else {
-                    $_dir = $compiler->smarty instanceof SmartyBC ? $compiler->smarty->trusted_dir : null;
+                    $_dir = null;
                 }
                 if (!empty($_dir)) {
                     foreach ((array)$_dir as $_script_dir) {
-                        $_script_dir = rtrim($_script_dir, '/\\') . DIRECTORY_SEPARATOR;
+                        $_script_dir = rtrim($_script_dir ?? '', '/\\') . DIRECTORY_SEPARATOR;
                         if (file_exists($_script_dir . $_script)) {
                             $_filepath = $_script_dir . $_script;
                             break;
@@ -151,6 +151,7 @@ class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase
                 $_output .= "echo {$_function}({$_params},\$_smarty_tpl);?>";
             }
         }
+        $compiler->template->compiled->has_nocache_code = true;
         return $_output;
     }
 }

+ 3 - 3
resources/templates/engine/smarty/sysplugins/smarty_internal_compile_private_foreachsection.php

@@ -143,7 +143,7 @@ class Smarty_Internal_Compile_Private_ForeachSection extends Smarty_Internal_Com
         foreach ($this->resultOffsets as $key => $offset) {
             foreach ($match[ $offset ] as $m) {
                 if (!empty($m)) {
-                    $this->matchResults[ $key ][ strtolower($m) ] = true;
+                    $this->matchResults[ $key ][ smarty_strtolower_ascii($m) ] = true;
                 }
             }
         }
@@ -213,12 +213,12 @@ class Smarty_Internal_Compile_Private_ForeachSection extends Smarty_Internal_Com
      */
     public function compileSpecialVariable($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
     {
-        $tag = strtolower(trim($parameter[ 0 ], '"\''));
+        $tag = smarty_strtolower_ascii(trim($parameter[ 0 ], '"\''));
         $name = isset($parameter[ 1 ]) ? $compiler->getId($parameter[ 1 ]) : false;
         if (!$name) {
             $compiler->trigger_template_error("missing or illegal \$smarty.{$tag} name attribute", null, true);
         }
-        $property = isset($parameter[ 2 ]) ? strtolower($compiler->getId($parameter[ 2 ])) : false;
+        $property = isset($parameter[ 2 ]) ? smarty_strtolower_ascii($compiler->getId($parameter[ 2 ])) : false;
         if (!$property || !in_array($property, $this->nameProperties)) {
             $compiler->trigger_template_error("missing or illegal \$smarty.{$tag} property attribute", null, true);
         }

+ 3 - 0
resources/templates/engine/smarty/sysplugins/smarty_internal_compile_private_modifier.php

@@ -109,6 +109,9 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa
                             if (!is_object($compiler->smarty->security_policy)
                                 || $compiler->smarty->security_policy->isTrustedPhpModifier($modifier, $compiler)
                             ) {
+                                trigger_error('Using php-function "' . $modifier . '" as a modifier is deprecated and will be ' .
+                                    'removed in a future release. Use Smarty::registerPlugin to explicitly register ' .
+                                    'a custom modifier.', E_USER_DEPRECATED);
                                 $output = "{$modifier}({$params})";
                             }
                             $compiler->known_modifier_type[ $modifier ] = $type;

+ 0 - 253
resources/templates/engine/smarty/sysplugins/smarty_internal_compile_private_php.php

@@ -1,253 +0,0 @@
-<?php
-/**
- * Smarty Internal Plugin Compile PHP Expression
- * Compiles any tag which will output an expression or variable
- *
- * @package    Smarty
- * @subpackage Compiler
- * @author     Uwe Tews
- */
-
-/**
- * Smarty Internal Plugin Compile PHP Expression Class
- *
- * @package    Smarty
- * @subpackage Compiler
- */
-class Smarty_Internal_Compile_Private_Php extends Smarty_Internal_CompileBase
-{
-    /**
-     * Attribute definition: Overwrites base class.
-     *
-     * @var array
-     * @see Smarty_Internal_CompileBase
-     */
-    public $required_attributes = array('code', 'type');
-
-    /**
-     * Compiles code for generating output from any expression
-     *
-     * @param array                                 $args      array with attributes from parser
-     * @param \Smarty_Internal_TemplateCompilerBase $compiler  compiler object
-     * @param array                                 $parameter array with compilation parameter
-     *
-     * @return string
-     * @throws \SmartyException
-     */
-    public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
-    {
-        // check and get attributes
-        $_attr = $this->getAttributes($compiler, $args);
-        $compiler->has_code = false;
-        if ($_attr[ 'type' ] === 'xml') {
-            $compiler->tag_nocache = true;
-            $output = addcslashes($_attr[ 'code' ], "'\\");
-            $compiler->parser->current_buffer->append_subtree(
-                $compiler->parser,
-                new Smarty_Internal_ParseTree_Tag(
-                    $compiler->parser,
-                    $compiler->processNocacheCode(
-                        "<?php echo '{$output}';?>",
-                        true
-                    )
-                )
-            );
-            return '';
-        }
-        if ($_attr[ 'type' ] !== 'tag') {
-            if ($compiler->php_handling === Smarty::PHP_REMOVE) {
-                return '';
-            } elseif ($compiler->php_handling === Smarty::PHP_QUOTE) {
-                $output =
-                    preg_replace_callback(
-                        '#(<\?(?:php|=)?)|(<%)|(<script\s+language\s*=\s*["\']?\s*php\s*["\']?\s*>)|(\?>)|(%>)|(<\/script>)#i',
-                        array($this, 'quote'),
-                        $_attr[ 'code' ]
-                    );
-                $compiler->parser->current_buffer->append_subtree(
-                    $compiler->parser,
-                    new Smarty_Internal_ParseTree_Text($output)
-                );
-                return '';
-            } elseif ($compiler->php_handling === Smarty::PHP_PASSTHRU || $_attr[ 'type' ] === 'unmatched') {
-                $compiler->tag_nocache = true;
-                $output = addcslashes($_attr[ 'code' ], "'\\");
-                $compiler->parser->current_buffer->append_subtree(
-                    $compiler->parser,
-                    new Smarty_Internal_ParseTree_Tag(
-                        $compiler->parser,
-                        $compiler->processNocacheCode(
-                            "<?php echo '{$output}';?>",
-                            true
-                        )
-                    )
-                );
-                return '';
-            } elseif ($compiler->php_handling === Smarty::PHP_ALLOW) {
-                if (!($compiler->smarty instanceof SmartyBC)) {
-                    $compiler->trigger_template_error(
-                        '$smarty->php_handling PHP_ALLOW not allowed. Use SmartyBC to enable it',
-                        null,
-                        true
-                    );
-                }
-                $compiler->has_code = true;
-                return $_attr[ 'code' ];
-            } else {
-                $compiler->trigger_template_error('Illegal $smarty->php_handling value', null, true);
-            }
-        } else {
-            $compiler->has_code = true;
-            if (!($compiler->smarty instanceof SmartyBC)) {
-                $compiler->trigger_template_error(
-                    '{php}{/php} tags not allowed. Use SmartyBC to enable them',
-                    null,
-                    true
-                );
-            }
-            $ldel = preg_quote($compiler->smarty->left_delimiter, '#');
-            $rdel = preg_quote($compiler->smarty->right_delimiter, '#');
-            preg_match("#^({$ldel}php\\s*)((.)*?)({$rdel})#", $_attr[ 'code' ], $match);
-            if (!empty($match[ 2 ])) {
-                if ('nocache' === trim($match[ 2 ])) {
-                    $compiler->tag_nocache = true;
-                } else {
-                    $compiler->trigger_template_error("illegal value of option flag '{$match[2]}'", null, true);
-                }
-            }
-            return preg_replace(
-                array("#^{$ldel}\\s*php\\s*(.)*?{$rdel}#", "#{$ldel}\\s*/\\s*php\\s*{$rdel}$#"),
-                array('<?php ', '?>'),
-                $_attr[ 'code' ]
-            );
-        }
-    }
-
-    /**
-     * Lexer code for PHP tags
-     *
-     * This code has been moved from lexer here fo easier debugging and maintenance
-     *
-     * @param Smarty_Internal_Templatelexer $lex
-     *
-     * @throws \SmartyCompilerException
-     */
-    public function parsePhp(Smarty_Internal_Templatelexer $lex)
-    {
-        $lex->token = Smarty_Internal_Templateparser::TP_PHP;
-        $close = 0;
-        $lex->taglineno = $lex->line;
-        $closeTag = '?>';
-        if (strpos($lex->value, '<?xml') === 0) {
-            $lex->is_xml = true;
-            $lex->phpType = 'xml';
-            return;
-        } elseif (strpos($lex->value, '<?') === 0) {
-            $lex->phpType = 'php';
-        } elseif (strpos($lex->value, '<%') === 0) {
-            $lex->phpType = 'asp';
-            $closeTag = '%>';
-        } elseif (strpos($lex->value, '%>') === 0) {
-            $lex->phpType = 'unmatched';
-        } elseif (strpos($lex->value, '?>') === 0) {
-            if ($lex->is_xml) {
-                $lex->is_xml = false;
-                $lex->phpType = 'xml';
-                return;
-            }
-            $lex->phpType = 'unmatched';
-        } elseif (strpos($lex->value, '<s') === 0) {
-            $lex->phpType = 'script';
-            $closeTag = '</script>';
-        } elseif (strpos($lex->value, $lex->smarty->left_delimiter) === 0) {
-            if ($lex->isAutoLiteral()) {
-                $lex->token = Smarty_Internal_Templateparser::TP_TEXT;
-                return;
-            }
-            $closeTag = "{$lex->smarty->left_delimiter}/php{$lex->smarty->right_delimiter}";
-            if ($lex->value === $closeTag) {
-                $lex->compiler->trigger_template_error("unexpected closing tag '{$closeTag}'");
-            }
-            $lex->phpType = 'tag';
-        }
-        if ($lex->phpType === 'unmatched') {
-            return;
-        }
-        if (($lex->phpType === 'php' || $lex->phpType === 'asp')
-            &&
-            ($lex->compiler->php_handling === Smarty::PHP_PASSTHRU ||
-             $lex->compiler->php_handling === Smarty::PHP_QUOTE)
-        ) {
-            return;
-        }
-        $start = $lex->counter + strlen($lex->value);
-        $body = true;
-        if (preg_match('~' . preg_quote($closeTag, '~') . '~i', $lex->data, $match, PREG_OFFSET_CAPTURE, $start)) {
-            $close = $match[ 0 ][ 1 ];
-        } else {
-            $lex->compiler->trigger_template_error("missing closing tag '{$closeTag}'");
-        }
-        while ($body) {
-            if (preg_match(
-                '~([/][*])|([/][/][^\n]*)|(\'[^\'\\\\]*(?:\\.[^\'\\\\]*)*\')|("[^"\\\\]*(?:\\.[^"\\\\]*)*")~',
-                $lex->data,
-                $match,
-                PREG_OFFSET_CAPTURE,
-                $start
-            )
-            ) {
-                $value = $match[ 0 ][ 0 ];
-                $from = $pos = $match[ 0 ][ 1 ];
-                if ($pos > $close) {
-                    $body = false;
-                } else {
-                    $start = $pos + strlen($value);
-                    $phpCommentStart = $value === '/*';
-                    if ($phpCommentStart) {
-                        $phpCommentEnd = preg_match('~([*][/])~', $lex->data, $match, PREG_OFFSET_CAPTURE, $start);
-                        if ($phpCommentEnd) {
-                            $pos2 = $match[ 0 ][ 1 ];
-                            $start = $pos2 + strlen($match[ 0 ][ 0 ]);
-                        }
-                    }
-                    while ($close > $pos && $close < $start) {
-                        if (preg_match(
-                            '~' . preg_quote($closeTag, '~') . '~i',
-                            $lex->data,
-                            $match,
-                            PREG_OFFSET_CAPTURE,
-                            $from
-                        )
-                        ) {
-                            $close = $match[ 0 ][ 1 ];
-                            $from = $close + strlen($match[ 0 ][ 0 ]);
-                        } else {
-                            $lex->compiler->trigger_template_error("missing closing tag '{$closeTag}'");
-                        }
-                    }
-                    if ($phpCommentStart && (!$phpCommentEnd || $pos2 > $close)) {
-                        $lex->taglineno = $lex->line + substr_count(substr($lex->data, $lex->counter, $start), "\n");
-                        $lex->compiler->trigger_template_error("missing PHP comment closing tag '*/'");
-                    }
-                }
-            } else {
-                $body = false;
-            }
-        }
-        $lex->value = substr($lex->data, $lex->counter, $close + strlen($closeTag) - $lex->counter);
-    }
-
-    /*
-     * Call back function for $php_handling = PHP_QUOTE
-     *
-     */
-    /**
-     * @param $match
-     *
-     * @return string
-     */
-    private function quote($match)
-    {
-        return htmlspecialchars($match[ 0 ], ENT_QUOTES);
-    }
-}

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_compile_private_print_expression.php

@@ -93,7 +93,7 @@ class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_C
                 }
                 // autoescape html
                 if ($compiler->template->smarty->escape_html) {
-                    $output = "htmlspecialchars({$output}, ENT_QUOTES, '" . addslashes(Smarty::$_CHARSET) . "')";
+                    $output = "htmlspecialchars((string) {$output}, ENT_QUOTES, '" . addslashes(Smarty::$_CHARSET) . "')";
                 }
                 // loop over registered filters
                 if (!empty($compiler->template->smarty->registered_filters[ Smarty::FILTER_VARIABLE ])) {

+ 9 - 5
resources/templates/engine/smarty/sysplugins/smarty_internal_compile_private_special_variable.php

@@ -29,7 +29,7 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
     public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
     {
         $_index = preg_split("/\]\[/", substr($parameter, 1, strlen($parameter) - 2));
-        $variable = strtolower($compiler->getId($_index[ 0 ]));
+        $variable = smarty_strtolower_ascii($compiler->getId($_index[ 0 ]));
         if ($variable === false) {
             $compiler->trigger_template_error("special \$Smarty variable name index can not be variable", null, true);
         }
@@ -40,7 +40,7 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
                 case 'foreach':
                 case 'section':
                     if (!isset(Smarty_Internal_TemplateCompilerBase::$_tag_objects[ $variable ])) {
-                        $class = 'Smarty_Internal_Compile_' . ucfirst($variable);
+                        $class = 'Smarty_Internal_Compile_' . smarty_ucfirst_ascii($variable);
                         Smarty_Internal_TemplateCompilerBase::$_tag_objects[ $variable ] = new $class;
                     }
                     return Smarty_Internal_TemplateCompilerBase::$_tag_objects[ $variable ]->compileSpecialVariable(
@@ -76,11 +76,15 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
                         $compiler->trigger_template_error("(secure mode) super globals not permitted");
                         break;
                     }
-                    $compiled_ref = '$_' . strtoupper($variable);
+                    $compiled_ref = '$_' . smarty_strtoupper_ascii($variable);
                     break;
                 case 'template':
                     return 'basename($_smarty_tpl->source->filepath)';
                 case 'template_object':
+                    if (isset($compiler->smarty->security_policy)) {
+                        $compiler->trigger_template_error("(secure mode) template_object not permitted");
+                        break;
+                    }
                     return '$_smarty_tpl';
                 case 'current_dir':
                     return 'dirname($_smarty_tpl->source->filepath)';
@@ -94,9 +98,9 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
                         break;
                     }
                     if (strpos($_index[ 1 ], '$') === false && strpos($_index[ 1 ], '\'') === false) {
-                        return "@constant('{$_index[1]}')";
+                        return "(defined('{$_index[1]}') ? constant('{$_index[1]}') : null)";
                     } else {
-                        return "@constant({$_index[1]})";
+                        return "(defined({$_index[1]}) ? constant({$_index[1]}) : null)";
                     }
                 // no break
                 case 'config':

+ 8 - 6
resources/templates/engine/smarty/sysplugins/smarty_internal_config_file_compiler.php

@@ -115,7 +115,7 @@ class Smarty_Internal_Config_File_Compiler
             $this->smarty->_debug->start_compile($this->template);
         }
         // init the lexer/parser to compile the config file
-        /* @var Smarty_Internal_ConfigFileLexer $this ->lex */
+        /* @var Smarty_Internal_ConfigFileLexer $this->lex */
         $this->lex = new $this->lexer_class(
             str_replace(
                 array(
@@ -127,7 +127,7 @@ class Smarty_Internal_Config_File_Compiler
             ) . "\n",
             $this
         );
-        /* @var Smarty_Internal_ConfigFileParser $this ->parser */
+        /* @var Smarty_Internal_ConfigFileParser $this->parser */
         $this->parser = new $this->parser_class($this->lex, $this);
         if (function_exists('mb_internal_encoding')
             && function_exists('ini_get')
@@ -157,10 +157,12 @@ class Smarty_Internal_Config_File_Compiler
             $this->smarty->_debug->end_compile($this->template);
         }
         // template header code
-        $template_header =
-            "<?php /* Smarty version " . Smarty::SMARTY_VERSION . ", created on " . strftime("%Y-%m-%d %H:%M:%S") .
-            "\n";
-        $template_header .= "         compiled from '{$this->template->source->filepath}' */ ?>\n";
+        $template_header = sprintf(
+            "<?php /* Smarty version %s, created on %s\n         compiled from '%s' */ ?>\n",
+            Smarty::SMARTY_VERSION,
+            date("Y-m-d H:i:s"),
+            str_replace('*/', '* /' , $this->template->source->filepath)
+        );
         $code = '<?php $_smarty_tpl->smarty->ext->configLoad->_loadConfigVars($_smarty_tpl, ' .
                 var_export($this->config_data, true) . '); ?>';
         return $template_header . $this->template->smarty->ext->_codeFrame->create($this->template, $code);

+ 2 - 22
resources/templates/engine/smarty/sysplugins/smarty_internal_data.php

@@ -121,7 +121,7 @@ abstract class Smarty_Internal_Data
      * appends values to template variables
      *
      * @api  Smarty::append()
-     * @link http://www.smarty.net/docs/en/api.append.tpl
+     * @link https://www.smarty.net/docs/en/api.append.tpl
      *
      * @param array|string $tpl_var the template variable name(s)
      * @param mixed        $value   the value to append
@@ -182,7 +182,7 @@ abstract class Smarty_Internal_Data
      * Returns a single or all template variables
      *
      * @api  Smarty::getTemplateVars()
-     * @link http://www.smarty.net/docs/en/api.get.template.vars.tpl
+     * @link https://www.smarty.net/docs/en/api.get.template.vars.tpl
      *
      * @param string                                                  $varName       variable name or null
      * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $_ptr          optional pointer to data object
@@ -195,26 +195,6 @@ abstract class Smarty_Internal_Data
         return $this->ext->getTemplateVars->getTemplateVars($this, $varName, $_ptr, $searchParents);
     }
 
-    /**
-     * gets the object of a Smarty variable
-     *
-     * @param string               $variable      the name of the Smarty variable
-     * @param Smarty_Internal_Data $_ptr          optional pointer to data object
-     * @param boolean              $searchParents search also in parent data
-     * @param bool                 $error_enable
-     *
-     * @return     Smarty_Variable|Smarty_Undefined_Variable the object of the variable
-     * @deprecated since 3.1.28 please use Smarty_Internal_Data::getTemplateVars() instead.
-     */
-    public function getVariable(
-        $variable = null,
-        Smarty_Internal_Data $_ptr = null,
-        $searchParents = true,
-        $error_enable = true
-    ) {
-        return $this->ext->getTemplateVars->_getVariable($this, $variable, $_ptr, $searchParents, $error_enable);
-    }
-
     /**
      * Follow the parent chain an merge template and config variables
      *

+ 2 - 2
resources/templates/engine/smarty/sysplugins/smarty_internal_debug.php

@@ -210,7 +210,7 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
         // copy the working dirs from application
         $debObj->setCompileDir($smarty->getCompileDir());
         // init properties by hand as user may have edited the original Smarty class
-        $debObj->setPluginsDir(is_dir(dirname(__FILE__) . '/../plugins') ? dirname(__FILE__) .
+        $debObj->setPluginsDir(is_dir(__DIR__ . '/../plugins') ? __DIR__ .
                                                                            '/../plugins' : $smarty->getPluginsDir());
         $debObj->force_compile = false;
         $debObj->compile_check = Smarty::COMPILECHECK_ON;
@@ -221,7 +221,7 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
         $debObj->debugging_ctrl = 'NONE';
         $debObj->error_reporting = E_ALL & ~E_NOTICE;
         $debObj->debug_tpl =
-            isset($smarty->debug_tpl) ? $smarty->debug_tpl : 'file:' . dirname(__FILE__) . '/../debug.tpl';
+            isset($smarty->debug_tpl) ? $smarty->debug_tpl : 'file:' . __DIR__ . '/../debug.tpl';
         $debObj->registered_plugins = array();
         $debObj->registered_resources = array();
         $debObj->registered_filters = array();

+ 60 - 72
resources/templates/engine/smarty/sysplugins/smarty_internal_errorhandler.php

@@ -1,61 +1,66 @@
 <?php
 
 /**
- * Smarty error handler
+ * Smarty error handler to fix new error levels in PHP8 for backwards compatibility
  *
  * @package    Smarty
  * @subpackage PluginsInternal
- * @author     Uwe Tews
+ * @author     Simon Wisselink
  *
- * @deprecated
-Smarty does no longer use @filemtime()
  */
 class Smarty_Internal_ErrorHandler
 {
+
     /**
-     * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors()
+     * Allows {$foo} where foo is unset.
+     * @var bool
      */
-    public static $mutedDirectories = array();
+    public $allowUndefinedVars = true;
 
     /**
-     * error handler returned by set_error_handler() in self::muteExpectedErrors()
+     * Allows {$foo.bar} where bar is unset and {$foo.bar1.bar2} where either bar1 or bar2 is unset.
+     * @var bool
      */
-    private static $previousErrorHandler = null;
+    public $allowUndefinedArrayKeys = true;
 
     /**
-     * Enable error handler to mute expected messages
-     *
+     * Allows {$foo->bar} where bar is not an object (e.g. null or false).
+     * @var bool
      */
-    public static function muteExpectedErrors()
-    {
-        /*
-            error muting is done because some people implemented custom error_handlers using
-            http://php.net/set_error_handler and for some reason did not understand the following paragraph:
+    public $allowDereferencingNonObjects = true;
 
-                It is important to remember that the standard PHP error handler is completely bypassed for the
-                error types specified by error_types unless the callback function returns FALSE.
-                error_reporting() settings will have no effect and your error handler will be called regardless -
-                however you are still able to read the current value of error_reporting and act appropriately.
-                Of particular note is that this value will be 0 if the statement that caused the error was
-                prepended by the @ error-control operator.
+    private $previousErrorHandler = null;
 
-            Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include
-                - @filemtime() is almost twice as fast as using an additional file_exists()
-                - between file_exists() and filemtime() a possible race condition is opened,
-                  which does not exist using the simple @filemtime() approach.
+    /**
+     * Enable error handler to intercept errors
+     */
+    public function activate() {
+        /*
+            Error muting is done because some people implemented custom error_handlers using
+            https://php.net/set_error_handler and for some reason did not understand the following paragraph:
+
+            It is important to remember that the standard PHP error handler is completely bypassed for the
+            error types specified by error_types unless the callback function returns FALSE.
+            error_reporting() settings will have no effect and your error handler will be called regardless -
+            however you are still able to read the current value of error_reporting and act appropriately.
+            Of particular note is that this value will be 0 if the statement that caused the error was
+            prepended by the @ error-control operator.
         */
-        $error_handler = array('Smarty_Internal_ErrorHandler', 'mutingErrorHandler');
-        $previous = set_error_handler($error_handler);
-        // avoid dead loops
-        if ($previous !== $error_handler) {
-            self::$previousErrorHandler = $previous;
-        }
+        $this->previousErrorHandler = set_error_handler([$this, 'handleError']);
+    }
+
+    /**
+     * Disable error handler
+     */
+    public function deactivate() {
+        restore_error_handler();
+        $this->previousErrorHandler = null;
     }
 
     /**
      * Error Handler to mute expected messages
      *
-     * @link http://php.net/set_error_handler
+     * @link https://php.net/set_error_handler
      *
      * @param integer $errno Error level
      * @param         $errstr
@@ -65,49 +70,32 @@ class Smarty_Internal_ErrorHandler
      *
      * @return bool
      */
-    public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext)
+    public function handleError($errno, $errstr, $errfile, $errline, $errcontext = [])
     {
-        $_is_muted_directory = false;
-        // add the SMARTY_DIR to the list of muted directories
-        if (!isset(self::$mutedDirectories[ SMARTY_DIR ])) {
-            $smarty_dir = realpath(SMARTY_DIR);
-            if ($smarty_dir !== false) {
-                self::$mutedDirectories[ SMARTY_DIR ] =
-                    array('file' => $smarty_dir, 'length' => strlen($smarty_dir),);
-            }
+
+        if ($this->allowUndefinedVars && preg_match(
+                '/^(Attempt to read property "value" on null|Trying to get property (\'value\' )?of non-object)/',
+                $errstr
+            )) {
+            return; // suppresses this error
         }
-        // walk the muted directories and test against $errfile
-        foreach (self::$mutedDirectories as $key => &$dir) {
-            if (!$dir) {
-                // resolve directory and length for speedy comparisons
-                $file = realpath($key);
-                if ($file === false) {
-                    // this directory does not exist, remove and skip it
-                    unset(self::$mutedDirectories[ $key ]);
-                    continue;
-                }
-                $dir = array('file' => $file, 'length' => strlen($file),);
-            }
-            if (!strncmp($errfile, $dir[ 'file' ], $dir[ 'length' ])) {
-                $_is_muted_directory = true;
-                break;
-            }
+
+        if ($this->allowUndefinedArrayKeys && preg_match(
+            '/^(Undefined index|Undefined array key|Trying to access array offset on value of type)/',
+            $errstr
+        )) {
+            return; // suppresses this error
         }
-        // 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())) {
-            if (self::$previousErrorHandler) {
-                return call_user_func(
-                    self::$previousErrorHandler,
-                    $errno,
-                    $errstr,
-                    $errfile,
-                    $errline,
-                    $errcontext
-                );
-            } else {
-                return false;
-            }
+
+        if ($this->allowDereferencingNonObjects && preg_match(
+                '/^Attempt to read property ".+?" on/',
+                $errstr
+            )) {
+            return; // suppresses this error
         }
+
+        // pass all other errors through to the previous error handler or to the default PHP error handler
+        return $this->previousErrorHandler ?
+            call_user_func($this->previousErrorHandler, $errno, $errstr, $errfile, $errline, $errcontext) : false;
     }
 }

+ 14 - 14
resources/templates/engine/smarty/sysplugins/smarty_internal_extension_handler.php

@@ -36,6 +36,7 @@
  * @property   Smarty_Internal_Method_RegisterPlugin     $registerPlugin
  * @property   mixed|\Smarty_Template_Cached             configLoad
  */
+#[\AllowDynamicProperties]
 class Smarty_Internal_Extension_Handler
 {
     public $objType = null;
@@ -88,20 +89,19 @@ class Smarty_Internal_Extension_Handler
                         $objType = $data->_objType;
                         $propertyType = false;
                         if (!isset($this->resolvedProperties[ $match[ 0 ] ][ $objType ])) {
-                            $property = isset($this->resolvedProperties[ 'property' ][ $basename ]) ?
-                                $this->resolvedProperties[ 'property' ][ $basename ] :
-                                $property = $this->resolvedProperties[ 'property' ][ $basename ] = strtolower(
-                                    join(
-                                        '_',
-                                        preg_split(
-                                            '/([A-Z][^A-Z]*)/',
-                                            $basename,
-                                            -1,
-                                            PREG_SPLIT_NO_EMPTY |
-                                            PREG_SPLIT_DELIM_CAPTURE
-                                        )
+                            $property = $this->resolvedProperties['property'][$basename] ??
+                                $this->resolvedProperties['property'][$basename] = smarty_strtolower_ascii(
+                                join(
+                                    '_',
+                                    preg_split(
+                                        '/([A-Z][^A-Z]*)/',
+                                        $basename,
+                                        -1,
+                                        PREG_SPLIT_NO_EMPTY |
+                                        PREG_SPLIT_DELIM_CAPTURE
                                     )
-                                );
+                                )
+                            );
                             if ($property !== false) {
                                 if (property_exists($data, $property)) {
                                     $propertyType = $this->resolvedProperties[ $match[ 0 ] ][ $objType ] = 1;
@@ -145,7 +145,7 @@ class Smarty_Internal_Extension_Handler
     public function upperCase($name)
     {
         $_name = explode('_', $name);
-        $_name = array_map('ucfirst', $_name);
+        $_name = array_map('smarty_ucfirst_ascii', $_name);
         return implode('_', $_name);
     }
 

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_append.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_Append
      * appends values to template variables
      *
      * @api  Smarty::append()
-     * @link http://www.smarty.net/docs/en/api.append.tpl
+     * @link https://www.smarty.net/docs/en/api.append.tpl
      *
      * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
      * @param array|string                                            $tpl_var the template variable name(s)

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_appendbyref.php

@@ -15,7 +15,7 @@ class Smarty_Internal_Method_AppendByRef
      * appends values to template variables by reference
      *
      * @api  Smarty::appendByRef()
-     * @link http://www.smarty.net/docs/en/api.append.by.ref.tpl
+     * @link https://www.smarty.net/docs/en/api.append.by.ref.tpl
      *
      * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
      * @param string                                                  $tpl_var the template variable name

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_clearallassign.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_ClearAllAssign
      * clear all the assigned template variables.
      *
      * @api  Smarty::clearAllAssign()
-     * @link http://www.smarty.net/docs/en/api.clear.all.assign.tpl
+     * @link https://www.smarty.net/docs/en/api.clear.all.assign.tpl
      *
      * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
      *

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_clearallcache.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_ClearAllCache
      * Empty cache folder
      *
      * @api  Smarty::clearAllCache()
-     * @link http://www.smarty.net/docs/en/api.clear.all.cache.tpl
+     * @link https://www.smarty.net/docs/en/api.clear.all.cache.tpl
      *
      * @param \Smarty $smarty
      * @param integer $exp_time expiration time

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_clearassign.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_ClearAssign
      * clear the given assigned template variable(s).
      *
      * @api  Smarty::clearAssign()
-     * @link http://www.smarty.net/docs/en/api.clear.assign.tpl
+     * @link https://www.smarty.net/docs/en/api.clear.assign.tpl
      *
      * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
      * @param string|array                                            $tpl_var the template variable(s) to clear

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_clearcache.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_ClearCache
      * Empty cache for a specific template
      *
      * @api  Smarty::clearCache()
-     * @link http://www.smarty.net/docs/en/api.clear.cache.tpl
+     * @link https://www.smarty.net/docs/en/api.clear.cache.tpl
      *
      * @param \Smarty $smarty
      * @param string  $template_name template name

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_clearcompiledtemplate.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_ClearCompiledTemplate
      * Delete compiled template file
      *
      * @api  Smarty::clearCompiledTemplate()
-     * @link http://www.smarty.net/docs/en/api.clear.compiled.template.tpl
+     * @link https://www.smarty.net/docs/en/api.clear.compiled.template.tpl
      *
      * @param \Smarty $smarty
      * @param string  $resource_name template name

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_clearconfig.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_ClearConfig
      * clear a single or all config variables
      *
      * @api  Smarty::clearConfig()
-     * @link http://www.smarty.net/docs/en/api.clear.config.tpl
+     * @link https://www.smarty.net/docs/en/api.clear.config.tpl
      *
      * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
      * @param string|null                                             $name variable name or null

+ 2 - 2
resources/templates/engine/smarty/sysplugins/smarty_internal_method_configload.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_ConfigLoad
      * load a config file, optionally load just selected sections
      *
      * @api  Smarty::configLoad()
-     * @link http://www.smarty.net/docs/en/api.config.load.tpl
+     * @link https://www.smarty.net/docs/en/api.config.load.tpl
      *
      * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
      * @param string                                                  $config_file filename
@@ -42,7 +42,7 @@ class Smarty_Internal_Method_ConfigLoad
      * load a config file, optionally load just selected sections
      *
      * @api  Smarty::configLoad()
-     * @link http://www.smarty.net/docs/en/api.config.load.tpl
+     * @link https://www.smarty.net/docs/en/api.config.load.tpl
      *
      * @param \Smarty|\Smarty_Internal_Data|\Smarty_Internal_Template $data
      * @param string                                                  $config_file filename

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_createdata.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_CreateData
      * creates a data object
      *
      * @api  Smarty::createData()
-     * @link http://www.smarty.net/docs/en/api.create.data.tpl
+     * @link https://www.smarty.net/docs/en/api.create.data.tpl
      *
      * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty      $obj
      * @param \Smarty_Internal_Template|\Smarty_Internal_Data|\Smarty_Data|\Smarty $parent next higher level of Smarty

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_getconfigvars.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_GetConfigVars
      * Returns a single or all config variables
      *
      * @api  Smarty::getConfigVars()
-     * @link http://www.smarty.net/docs/en/api.get.config.vars.tpl
+     * @link https://www.smarty.net/docs/en/api.get.config.vars.tpl
      *
      * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
      * @param string                                                  $varname        variable name or null

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_getregisteredobject.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_GetRegisteredObject
      * return a reference to a registered object
      *
      * @api  Smarty::getRegisteredObject()
-     * @link http://www.smarty.net/docs/en/api.get.registered.object.tpl
+     * @link https://www.smarty.net/docs/en/api.get.registered.object.tpl
      *
      * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
      * @param string                                                          $object_name object name

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_gettags.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_GetTags
      * Return array of tag/attributes of all tags used by an template
      *
      * @api  Smarty::getTags()
-     * @link http://www.smarty.net/docs/en/api.get.tags.tpl
+     * @link https://www.smarty.net/docs/en/api.get.tags.tpl
      *
      * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
      * @param null|string|Smarty_Internal_Template                            $template

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_gettemplatevars.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_GetTemplateVars
      * Returns a single or all template variables
      *
      * @api  Smarty::getTemplateVars()
-     * @link http://www.smarty.net/docs/en/api.get.template.vars.tpl
+     * @link https://www.smarty.net/docs/en/api.get.template.vars.tpl
      *
      * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
      * @param string                                                  $varName       variable name or null

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_loadfilter.php

@@ -30,7 +30,7 @@ class Smarty_Internal_Method_LoadFilter
      *
      * @api  Smarty::loadFilter()
      *
-     * @link http://www.smarty.net/docs/en/api.load.filter.tpl
+     * @link https://www.smarty.net/docs/en/api.load.filter.tpl
      *
      * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
      * @param string                                                          $type filter type

+ 2 - 2
resources/templates/engine/smarty/sysplugins/smarty_internal_method_loadplugin.php

@@ -40,7 +40,7 @@ class Smarty_Internal_Method_LoadPlugin
             throw new SmartyException("plugin {$plugin_name} is not a valid name format");
         }
         if (!empty($match[ 2 ])) {
-            $file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php';
+            $file = SMARTY_SYSPLUGINS_DIR . smarty_strtolower_ascii($plugin_name) . '.php';
             if (isset($this->plugin_files[ $file ])) {
                 if ($this->plugin_files[ $file ] !== false) {
                     return $this->plugin_files[ $file ];
@@ -60,7 +60,7 @@ class Smarty_Internal_Method_LoadPlugin
         }
         // plugin filename is expected to be: [type].[name].php
         $_plugin_filename = "{$match[1]}.{$match[4]}.php";
-        $_lower_filename = strtolower($_plugin_filename);
+        $_lower_filename = smarty_strtolower_ascii($_plugin_filename);
         if (isset($this->plugin_files)) {
             if (isset($this->plugin_files[ 'plugins_dir' ][ $_lower_filename ])) {
                 if (!$smarty->use_include_path || $this->plugin_files[ 'plugins_dir' ][ $_lower_filename ] !== false) {

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_mustcompile.php

@@ -32,7 +32,7 @@ class Smarty_Internal_Method_MustCompile
     {
         if (!$_template->source->exists) {
             if ($_template->_isSubTpl()) {
-                $parent_resource = " in '$_template->parent->template_resource}'";
+                $parent_resource = " in '{$_template->parent->template_resource}'";
             } else {
                 $parent_resource = '';
             }

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_registercacheresource.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_RegisterCacheResource
      * Registers a resource to fetch a template
      *
      * @api  Smarty::registerCacheResource()
-     * @link http://www.smarty.net/docs/en/api.register.cacheresource.tpl
+     * @link https://www.smarty.net/docs/en/api.register.cacheresource.tpl
      *
      * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
      * @param string                                                          $name name of resource type

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_registerclass.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_RegisterClass
      * Registers static classes to be used in templates
      *
      * @api  Smarty::registerClass()
-     * @link http://www.smarty.net/docs/en/api.register.class.tpl
+     * @link https://www.smarty.net/docs/en/api.register.class.tpl
      *
      * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
      * @param string                                                          $class_name

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_registerdefaultpluginhandler.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_RegisterDefaultPluginHandler
      * Registers a default plugin handler
      *
      * @api  Smarty::registerDefaultPluginHandler()
-     * @link http://www.smarty.net/docs/en/api.register.default.plugin.handler.tpl
+     * @link https://www.smarty.net/docs/en/api.register.default.plugin.handler.tpl
      *
      * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
      * @param callable                                                        $callback class/method name

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_registerfilter.php

@@ -30,7 +30,7 @@ class Smarty_Internal_Method_RegisterFilter
      *
      * @api  Smarty::registerFilter()
      *
-     * @link http://www.smarty.net/docs/en/api.register.filter.tpl
+     * @link https://www.smarty.net/docs/en/api.register.filter.tpl
      *
      * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
      * @param string                                                          $type filter type

+ 1 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_registerobject.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_RegisterObject
      * Registers object to be used in templates
      *
      * @api  Smarty::registerObject()
-     * @link http://www.smarty.net/docs/en/api.register.object.tpl
+     * @link https://www.smarty.net/docs/en/api.register.object.tpl
      *
      * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
      * @param string                                                          $object_name

+ 3 - 1
resources/templates/engine/smarty/sysplugins/smarty_internal_method_registerplugin.php

@@ -22,7 +22,7 @@ class Smarty_Internal_Method_RegisterPlugin
      * Registers plugin to be used in templates
      *
      * @api  Smarty::registerPlugin()
-     * @link http://www.smarty.net/docs/en/api.register.plugin.tpl
+     * @link https://www.smarty.net/docs/en/api.register.plugin.tpl
      *
      * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
      * @param string                                                          $type       plugin type
@@ -48,6 +48,8 @@ class Smarty_Internal_Method_RegisterPlugin
             throw new SmartyException("Plugin tag '{$name}' already registered");
         } elseif (!is_callable($callback)) {
             throw new SmartyException("Plugin '{$name}' not callable");
+        } elseif ($cacheable && $cache_attr) {
+            throw new SmartyException("Cannot set caching attributes for plugin '{$name}' when it is cacheable.");
         } else {
             $smarty->registered_plugins[ $type ][ $name ] = array($callback, (bool)$cacheable, (array)$cache_attr);
         }

+ 4 - 11
resources/templates/engine/smarty/sysplugins/smarty_internal_method_registerresource.php

@@ -22,25 +22,18 @@ class Smarty_Internal_Method_RegisterResource
      * Registers a resource to fetch a template
      *
      * @api  Smarty::registerResource()
-     * @link http://www.smarty.net/docs/en/api.register.resource.tpl
+     * @link https://www.smarty.net/docs/en/api.register.resource.tpl
      *
      * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
      * @param string                                                          $name             name of resource type
-     * @param Smarty_Resource|array                                           $resource_handler or instance of
-     *                                                                                          Smarty_Resource,
-     *                                                                                          or array of
-     *                                                                                          callbacks to
-     *                                                                                          handle
-     *                                                                                          resource
-     *                                                                                          (deprecated)
+     * @param Smarty_Resource                                           $resource_handler instance of Smarty_Resource
      *
      * @return \Smarty|\Smarty_Internal_Template
      */
-    public function registerResource(Smarty_Internal_TemplateBase $obj, $name, $resource_handler)
+    public function registerResource(Smarty_Internal_TemplateBase $obj, $name, Smarty_Resource $resource_handler)
     {
         $smarty = $obj->_getSmartyObj();
-        $smarty->registered_resources[ $name ] =
-            $resource_handler instanceof Smarty_Resource ? $resource_handler : array($resource_handler, false);
+        $smarty->registered_resources[ $name ] = $resource_handler;
         return $obj;
     }
 }

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно