From 7cfa3a8d2efddc8b6f21614ba77c23eff98ba12c Mon Sep 17 00:00:00 2001 From: SlowFox71 <37612339+SlowFox71@users.noreply.github.com> Date: Sat, 12 Feb 2022 23:48:41 +0100 Subject: [PATCH 1/2] Adding namespace support for searching plugins (using the autoloader) --- libs/Smarty.class.php | 34 +++++++++++- libs/sysplugins/smarty_cacheresource.php | 4 +- ...arty_internal_compile_private_modifier.php | 2 +- .../smarty_internal_method_loadfilter.php | 2 +- .../smarty_internal_method_loadplugin.php | 20 ++++++- .../smarty_internal_runtime_filterhandler.php | 12 +++-- libs/sysplugins/smarty_internal_template.php | 54 ++++++++++++------- .../smarty_internal_templatecompilerbase.php | 26 +++++++-- libs/sysplugins/smarty_resource.php | 4 +- libs/sysplugins/smarty_template_config.php | 2 +- libs/sysplugins/smarty_template_source.php | 2 +- 11 files changed, 124 insertions(+), 38 deletions(-) diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 0abbe6a7d..44e7ac326 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -262,6 +262,13 @@ class Smarty extends Smarty_Internal_TemplateBase */ public $_pluginsDirNormalized = false; + /** + * plugins namespace + * + * @var array + */ + public $plugins_namespace = array(); + /** * flag if template_dir is normalized * @@ -889,6 +896,29 @@ public function setPluginsDir($plugins_dir) return $this; } + /** + * Get plugin namespace(s) + * + * @return array list of plugin namespace(s) + */ + public function getPluginsNamespace() : Array + { + return $this->plugins_namespace; + } + + /** + * Set plugin namepaces + * + * @param string|array $plugins_namespace namespace(s) of plugins + * + * @return Smarty current Smarty instance for chaining + */ + public function setPluginsNamespace($plugins_namespace) + { + $this->plugins_namespace = (array)$plugins_namespace; + return $this; + } + /** * Get compiled directory * @@ -1019,9 +1049,9 @@ public function createTemplate($template, $cache_id = null, $compile_id = null, * @return string |boolean filepath of loaded file or false * @throws \SmartyException */ - public function loadPlugin($plugin_name, $check = true) + public function loadPlugin($plugin_prefix, $plugin_type, $plugin_name, $check = true) { - return $this->ext->loadPlugin->loadPlugin($this, $plugin_name, $check); + return $this->ext->loadPlugin->loadPlugin($this, $plugin_prefix, $plugin_type, $plugin_name, $check); } /** diff --git a/libs/sysplugins/smarty_cacheresource.php b/libs/sysplugins/smarty_cacheresource.php index 91e9f3924..7f574af45 100644 --- a/libs/sysplugins/smarty_cacheresource.php +++ b/libs/sysplugins/smarty_cacheresource.php @@ -209,8 +209,8 @@ public static function load(Smarty $smarty, $type = null) return $smarty->_cache[ 'cacheresource_handlers' ][ $type ] = new $cache_resource_class(); } // try plugins dir - $cache_resource_class = 'Smarty_CacheResource_' . ucfirst($type); - if ($smarty->loadPlugin($cache_resource_class)) { + if ($smarty->loadPlugin('Smarty', 'CacheResource', ucfirst($type))) { + $cache_resource_class = 'Smarty_CacheResource_' . ucfirst($type); return $smarty->_cache[ 'cacheresource_handlers' ][ $type ] = new $cache_resource_class(); } // give up diff --git a/libs/sysplugins/smarty_internal_compile_private_modifier.php b/libs/sysplugins/smarty_internal_compile_private_modifier.php index 72773fff8..580548940 100644 --- a/libs/sysplugins/smarty_internal_compile_private_modifier.php +++ b/libs/sysplugins/smarty_internal_compile_private_modifier.php @@ -77,7 +77,7 @@ public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $ break; case 3: // modifiercompiler plugin - if ($compiler->smarty->loadPlugin('smarty_modifiercompiler_' . $modifier)) { + if ($compiler->smarty->loadPlugin('smarty', 'modifiercompiler', $modifier)) { // check if modifier allowed if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler) diff --git a/libs/sysplugins/smarty_internal_method_loadfilter.php b/libs/sysplugins/smarty_internal_method_loadfilter.php index af788a24e..512dd5b8a 100644 --- a/libs/sysplugins/smarty_internal_method_loadfilter.php +++ b/libs/sysplugins/smarty_internal_method_loadfilter.php @@ -49,7 +49,7 @@ public function loadFilter(Smarty_Internal_TemplateBase $obj, $type, $name) $smarty->registered_filters[ $type ][ $_filter_name ] = $_plugin; return true; } - if ($smarty->loadPlugin($_plugin)) { + if ($smarty->loadPlugin('smarty', "{$type}filter", $name)) { if (class_exists($_plugin, false)) { $_plugin = array($_plugin, 'execute'); } diff --git a/libs/sysplugins/smarty_internal_method_loadplugin.php b/libs/sysplugins/smarty_internal_method_loadplugin.php index 3bd659cb8..381e05956 100644 --- a/libs/sysplugins/smarty_internal_method_loadplugin.php +++ b/libs/sysplugins/smarty_internal_method_loadplugin.php @@ -23,19 +23,35 @@ class Smarty_Internal_Method_LoadPlugin * class name format: Smarty_PluginType_PluginName * plugin filename format: plugintype.pluginname.php * + * plugin classes may also be autoloaded and will be + * used, if they implement the appropriate method + * * @param \Smarty $smarty * @param string $plugin_name class plugin name to load * @param bool $check check if already loaded * - * @return bool|string + * @return bool|string|array * @throws \SmartyException */ - public function loadPlugin(Smarty $smarty, $plugin_name, $check) + public function loadPlugin(Smarty $smarty, $plugin_prefix, $plugin_type, $name, $check) { // if function or class exists, exit silently (already loaded) + $plugin_name = "{$plugin_prefix}_{$plugin_type}_{$name}"; if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) { return true; } + + // check for auto-loader plugin + foreach ($smarty->getPluginsNamespace() as $namespace) { + $class = $namespace . '\\' . $name; + if (class_exists($class, true) && is_callable(array($class, $plugin_type))) { + // the requested class exists and implements the required interface. + // as we are using the autoloader, we do not know the file name + if ($check) return true; + else return array($class, $plugin_type); + } + } + if (!preg_match('#^smarty_((internal)|([^_]+))_(.+)$#i', $plugin_name, $match)) { throw new SmartyException("plugin {$plugin_name} is not a valid name format"); } diff --git a/libs/sysplugins/smarty_internal_runtime_filterhandler.php b/libs/sysplugins/smarty_internal_runtime_filterhandler.php index 9f868e1a4..0fdbd5f93 100644 --- a/libs/sysplugins/smarty_internal_runtime_filterhandler.php +++ b/libs/sysplugins/smarty_internal_runtime_filterhandler.php @@ -35,13 +35,19 @@ public function runFilter($type, $content, Smarty_Internal_Template $template) // loop over autoload filters of specified type if (!empty($template->smarty->autoload_filters[ $type ])) { foreach ((array)$template->smarty->autoload_filters[ $type ] as $name) { - $plugin_name = "Smarty_{$type}filter_{$name}"; + $plugin_prefix = 'Smarty'; + $plugin_type = "{$type}filter"; + $plugin_name = "{$plugin_prefix}_{$plugin_type}_{$name}"; if (function_exists($plugin_name)) { $callback = $plugin_name; } elseif (class_exists($plugin_name, false) && is_callable(array($plugin_name, 'execute'))) { $callback = array($plugin_name, 'execute'); - } elseif ($template->smarty->loadPlugin($plugin_name, false)) { - if (function_exists($plugin_name)) { + } elseif ($template->smarty->loadPlugin($plugin_prefix, $plugin_type, $name, false)) { + if (class_exists($name, true) && is_callable(array($name, $plugin_type))) { + // use autoloader style plugin + $callback = array($name, $plugin_type); + } + elseif (function_exists($plugin_name)) { // use loaded Smarty2 style plugin $callback = $plugin_name; } elseif (class_exists($plugin_name, false) && is_callable(array($plugin_name, 'execute'))) { diff --git a/libs/sysplugins/smarty_internal_template.php b/libs/sysplugins/smarty_internal_template.php index bae22a7d5..d561d98a6 100644 --- a/libs/sysplugins/smarty_internal_template.php +++ b/libs/sysplugins/smarty_internal_template.php @@ -448,24 +448,37 @@ public function _checkPlugins($plugins) { static $checked = array(); foreach ($plugins as $plugin) { - $name = join('::', (array)$plugin[ 'function' ]); - if (!isset($checked[ $name ])) { - if (!is_callable($plugin[ 'function' ])) { - if (is_file($plugin[ 'file' ])) { - include_once $plugin[ 'file' ]; - if (is_callable($plugin[ 'function' ])) { - $checked[ $name ] = true; - } - } - } else { + if (array_key_exists('method', $plugin)) { + // autoloader plugins + $name = join('::', $plugin[ 'method' ]); + if (is_callable($name)) { $checked[ $name ] = true; } + else { + throw new SmartyException("Plugin '{$name}' not callable"); + } } - if (!isset($checked[ $name ])) { - if (false !== $this->smarty->loadPlugin($name)) { - $checked[ $name ] = true; - } else { - throw new SmartyException("Plugin '{$name}' not callable"); + elseif (array_key_exists('function', $plugin)) { + // legacy plugins + $name = join('::', (array)$plugin[ 'function' ]); + if (!isset($checked[ $name ])) { + if (!is_callable($plugin[ 'function' ])) { + if (is_file($plugin[ 'file' ])) { + include_once $plugin[ 'file' ]; + if (is_callable($plugin[ 'function' ])) { + $checked[ $name ] = true; + } + } + } else { + $checked[ $name ] = true; + } + } + if (!isset($checked[ $name ])) { + if (false !== $this->smarty->loadPlugin($name)) { + $checked[ $name ] = true; + } else { + throw new SmartyException("Plugin '{$name}' not callable"); + } } } } @@ -644,11 +657,16 @@ public function _cleanUp() */ public function loadCompiler() { - if (!class_exists($this->source->compiler_class)) { - $this->smarty->loadPlugin($this->source->compiler_class); + $prefix = $this->source->compiler_class['prefix']; + $type = $this->source->compiler_class['type']; + $name = $this->source->compiler_class['name']; + $class = "{$prefix}_{$type}_{$name}"; + + if (!class_exists($class)) { + $this->smarty->loadPlugin($prefix, $type, $name); } $this->compiler = - new $this->source->compiler_class( + new $class( $this->source->template_lexer_class, $this->source->template_parser_class, $this->smarty diff --git a/libs/sysplugins/smarty_internal_templatecompilerbase.php b/libs/sysplugins/smarty_internal_templatecompilerbase.php index 272616148..31761f840 100644 --- a/libs/sysplugins/smarty_internal_templatecompilerbase.php +++ b/libs/sysplugins/smarty_internal_templatecompilerbase.php @@ -821,10 +821,26 @@ public function getPlugin($plugin_name, $plugin_type) return $function; } // loop through plugin dirs and find the plugin - $function = 'smarty_' . $plugin_type . '_' . $plugin_name; - $file = $this->smarty->loadPlugin($function, false); - if (is_string($file)) { + $function = "smarty_{$plugin_type}_{$plugin_name}"; + $file = $this->smarty->loadPlugin('smarty', $plugin_type, $plugin_name, false); + if (is_array($file)) { + // plugin is a static method of a class if ($this->caching && ($this->nocache || $this->tag_nocache)) { + $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'method' ] = + $file; + } else { + $this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'method' ] = + $file; + } + if ($plugin_type === 'modifier') { + $this->modifier_plugins[ $plugin_name ] = true; + } + return join('::', $file); + } + elseif (is_string($file)) { + // plugin is a function within a file + if ($this->caching && ($this->nocache || $this->tag_nocache)) { + $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'file' ] = $file; $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ] = @@ -1577,7 +1593,7 @@ private function compileTag2($tag, $args, $parameter) // check plugins from plugins folder foreach ($this->plugin_search_order as $plugin_type) { if ($plugin_type === Smarty::PLUGIN_COMPILER - && $this->smarty->loadPlugin('smarty_compiler_' . $tag) + && $this->smarty->loadPlugin('smarty', 'compiler', $tag) && (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) ) { @@ -1724,7 +1740,7 @@ private function compileTag2($tag, $args, $parameter) ) ); } - if ($this->smarty->loadPlugin('smarty_compiler_' . $tag)) { + if ($this->smarty->loadPlugin('smarty', 'compiler', $tag)) { $plugin = 'smarty_compiler_' . $tag; if (is_callable($plugin)) { return $plugin($args, $this->smarty); diff --git a/libs/sysplugins/smarty_resource.php b/libs/sysplugins/smarty_resource.php index 7fe84536f..f88a378f8 100644 --- a/libs/sysplugins/smarty_resource.php +++ b/libs/sysplugins/smarty_resource.php @@ -80,8 +80,8 @@ public static function load(Smarty $smarty, $type) return $smarty->_cache[ 'resource_handlers' ][ $type ] = new $_resource_class(); } // try plugins dir - $_resource_class = 'Smarty_Resource_' . ucfirst($type); - if ($smarty->loadPlugin($_resource_class)) { + if ($smarty->loadPlugin('Smarty', 'Resource', ucfirst($type))) { + $_resource_class = 'Smarty_Resource_' . ucfirst($type); if (class_exists($_resource_class, false)) { return $smarty->_cache[ 'resource_handlers' ][ $type ] = new $_resource_class(); } else { diff --git a/libs/sysplugins/smarty_template_config.php b/libs/sysplugins/smarty_template_config.php index 850ae32e7..59e9041d6 100644 --- a/libs/sysplugins/smarty_template_config.php +++ b/libs/sysplugins/smarty_template_config.php @@ -43,7 +43,7 @@ class Smarty_Template_Config extends Smarty_Template_Source * * @var string */ - public $compiler_class = 'Smarty_Internal_Config_File_Compiler'; + public $compiler_class = array('prefix' => 'Smarty', 'type' => 'Internal', 'name' => 'Config_File_Compiler'); /** * Name of the Class to tokenize this resource's contents with diff --git a/libs/sysplugins/smarty_template_source.php b/libs/sysplugins/smarty_template_source.php index 16b47f23c..73e97610f 100644 --- a/libs/sysplugins/smarty_template_source.php +++ b/libs/sysplugins/smarty_template_source.php @@ -106,7 +106,7 @@ class Smarty_Template_Source * * @var string */ - public $compiler_class = 'Smarty_Internal_SmartyTemplateCompiler'; + public $compiler_class = array('prefix' => 'Smarty', 'type' => 'Internal', 'name' => 'SmartyTemplateCompiler'); /** * Name of the Class to tokenize this resource's contents with From 40730bb54387e6ef5d9dc84416ad0af0d3babe43 Mon Sep 17 00:00:00 2001 From: SlowFox71 <37612339+SlowFox71@users.noreply.github.com> Date: Tue, 15 Feb 2022 23:16:04 +0100 Subject: [PATCH 2/2] Reverting to the loadPlugin() API Implementing autoLoadPlugin() for namespaced plugins Minor naming changes --- libs/Smarty.class.php | 46 ++++++++++----- libs/sysplugins/smarty_cacheresource.php | 4 +- ...arty_internal_compile_private_modifier.php | 2 +- .../smarty_internal_extension_handler.php | 1 + .../smarty_internal_method_autoloadplugin.php | 56 +++++++++++++++++++ .../smarty_internal_method_loadfilter.php | 2 +- .../smarty_internal_method_loadplugin.php | 20 +------ .../smarty_internal_runtime_filterhandler.php | 13 ++--- libs/sysplugins/smarty_internal_template.php | 29 +++++----- .../smarty_internal_templatecompilerbase.php | 15 ++--- libs/sysplugins/smarty_resource.php | 4 +- libs/sysplugins/smarty_template_config.php | 2 +- libs/sysplugins/smarty_template_source.php | 2 +- 13 files changed, 124 insertions(+), 72 deletions(-) create mode 100644 libs/sysplugins/smarty_internal_method_autoloadplugin.php diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 44e7ac326..aab4372c0 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -262,13 +262,6 @@ class Smarty extends Smarty_Internal_TemplateBase */ public $_pluginsDirNormalized = false; - /** - * plugins namespace - * - * @var array - */ - public $plugins_namespace = array(); - /** * flag if template_dir is normalized * @@ -618,6 +611,13 @@ class Smarty extends Smarty_Internal_TemplateBase */ protected $plugins_dir = array(); + /** + * plugins namespace + * + * @var array + */ + protected $plugins_namespaces = array(); + /** * cache directory * @@ -896,27 +896,40 @@ public function setPluginsDir($plugins_dir) return $this; } + /** + * Adds namespace for plugin files + * + * @param null|array|string $plugins_namespaces + * + * @return Smarty current Smarty instance for chaining + */ + public function addPluginsNamespace($plugins_namespaces) + { + $this->plugins_namespaces = array_merge($this->plugins_namespaces, (array)$plugins_namespaces); + return $this; + } + /** * Get plugin namespace(s) * * @return array list of plugin namespace(s) */ - public function getPluginsNamespace() : Array + public function getPluginsNamespaces() : Array { - return $this->plugins_namespace; + return $this->plugins_namespaces; } /** * Set plugin namepaces * - * @param string|array $plugins_namespace namespace(s) of plugins + * @param string|array $plugins_namespaces namespace(s) of plugins * * @return Smarty current Smarty instance for chaining */ - public function setPluginsNamespace($plugins_namespace) + public function setPluginsNamespaces($plugins_namespaces) { - $this->plugins_namespace = (array)$plugins_namespace; - return $this; + $this->plugins_namespaces = (array)$plugins_namespaces; + return $this; } /** @@ -1049,9 +1062,12 @@ public function createTemplate($template, $cache_id = null, $compile_id = null, * @return string |boolean filepath of loaded file or false * @throws \SmartyException */ - public function loadPlugin($plugin_prefix, $plugin_type, $plugin_name, $check = true) + public function loadPlugin($plugin_name, $check = true) { - return $this->ext->loadPlugin->loadPlugin($this, $plugin_prefix, $plugin_type, $plugin_name, $check); + $result = $this->ext->autoLoadPlugin->autoLoadPlugin($this, $plugin_name, $check); + if ($result === false) $result = $this->ext->loadPlugin->loadPlugin($this, $plugin_name, $check); + + return $result; } /** diff --git a/libs/sysplugins/smarty_cacheresource.php b/libs/sysplugins/smarty_cacheresource.php index 7f574af45..91e9f3924 100644 --- a/libs/sysplugins/smarty_cacheresource.php +++ b/libs/sysplugins/smarty_cacheresource.php @@ -209,8 +209,8 @@ public static function load(Smarty $smarty, $type = null) return $smarty->_cache[ 'cacheresource_handlers' ][ $type ] = new $cache_resource_class(); } // try plugins dir - if ($smarty->loadPlugin('Smarty', 'CacheResource', ucfirst($type))) { - $cache_resource_class = 'Smarty_CacheResource_' . ucfirst($type); + $cache_resource_class = 'Smarty_CacheResource_' . ucfirst($type); + if ($smarty->loadPlugin($cache_resource_class)) { return $smarty->_cache[ 'cacheresource_handlers' ][ $type ] = new $cache_resource_class(); } // give up diff --git a/libs/sysplugins/smarty_internal_compile_private_modifier.php b/libs/sysplugins/smarty_internal_compile_private_modifier.php index 580548940..72773fff8 100644 --- a/libs/sysplugins/smarty_internal_compile_private_modifier.php +++ b/libs/sysplugins/smarty_internal_compile_private_modifier.php @@ -77,7 +77,7 @@ public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $ break; case 3: // modifiercompiler plugin - if ($compiler->smarty->loadPlugin('smarty', 'modifiercompiler', $modifier)) { + if ($compiler->smarty->loadPlugin('smarty_modifiercompiler_' . $modifier)) { // check if modifier allowed if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler) diff --git a/libs/sysplugins/smarty_internal_extension_handler.php b/libs/sysplugins/smarty_internal_extension_handler.php index b07615526..b40f76e46 100644 --- a/libs/sysplugins/smarty_internal_extension_handler.php +++ b/libs/sysplugins/smarty_internal_extension_handler.php @@ -31,6 +31,7 @@ * @property Smarty_Internal_Method_AssignByRef $assignByRef * @property Smarty_Internal_Method_LoadFilter $loadFilter * @property Smarty_Internal_Method_LoadPlugin $loadPlugin + * @property Smarty_Internal_Method_AutoLoadPlugin $autoLoadPlugin * @property Smarty_Internal_Method_RegisterFilter $registerFilter * @property Smarty_Internal_Method_RegisterObject $registerObject * @property Smarty_Internal_Method_RegisterPlugin $registerPlugin diff --git a/libs/sysplugins/smarty_internal_method_autoloadplugin.php b/libs/sysplugins/smarty_internal_method_autoloadplugin.php new file mode 100644 index 000000000..2055c2a24 --- /dev/null +++ b/libs/sysplugins/smarty_internal_method_autoloadplugin.php @@ -0,0 +1,56 @@ +autoLoadPlugin() method + * + * @package Smarty + * @subpackage PluginsInternal + * @author Stefan Froehlich + */ +class Smarty_Internal_Method_AutoLoadPlugin +{ + /** + * Takes unknown classes and tries to load the + * appropriate plugin file via autoloader. + * The namespace must be registered with Smarty, + * the class name must match the plugin name and + * there needs to be a method named like the plugin + * type. + * + * @param \Smarty $smarty + * @param string $plugin_name class plugin name to load + * @param bool $check check if already loaded + * + * @return bool|string|array + * @throws \SmartyException + */ + public function autoLoadPlugin(Smarty $smarty, String $plugin_name, Bool $check) + { + // Naming convention of plugins is "Smarty_type_name" (corresponds + // to the file name of procedural plugins). We need to extract type + // and name + if (!preg_match('#^smarty_((internal)|([^_]+))_(.+)$#i', $plugin_name, $matches)) { + throw new SmartyException("plugin {$plugin_name} is not a valid name format"); + } + + // if function or class exists, exit silently (procedural plugin already loaded) + if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) { + return true; + } + + // check for auto-loader plugin + foreach ($smarty->getPluginsNamespaces() as $namespace) { + $class = $namespace . '\\' . $matches[4]; + if (class_exists($class, true) && is_callable(array($class, $matches[1]))) { + // the requested class exists and the required method exists + if ($check) return true; + else return array($class, $matches[1]); + } + } + + // no plugin loaded + return false; + } +} diff --git a/libs/sysplugins/smarty_internal_method_loadfilter.php b/libs/sysplugins/smarty_internal_method_loadfilter.php index 512dd5b8a..af788a24e 100644 --- a/libs/sysplugins/smarty_internal_method_loadfilter.php +++ b/libs/sysplugins/smarty_internal_method_loadfilter.php @@ -49,7 +49,7 @@ public function loadFilter(Smarty_Internal_TemplateBase $obj, $type, $name) $smarty->registered_filters[ $type ][ $_filter_name ] = $_plugin; return true; } - if ($smarty->loadPlugin('smarty', "{$type}filter", $name)) { + if ($smarty->loadPlugin($_plugin)) { if (class_exists($_plugin, false)) { $_plugin = array($_plugin, 'execute'); } diff --git a/libs/sysplugins/smarty_internal_method_loadplugin.php b/libs/sysplugins/smarty_internal_method_loadplugin.php index 381e05956..3bd659cb8 100644 --- a/libs/sysplugins/smarty_internal_method_loadplugin.php +++ b/libs/sysplugins/smarty_internal_method_loadplugin.php @@ -23,35 +23,19 @@ class Smarty_Internal_Method_LoadPlugin * class name format: Smarty_PluginType_PluginName * plugin filename format: plugintype.pluginname.php * - * plugin classes may also be autoloaded and will be - * used, if they implement the appropriate method - * * @param \Smarty $smarty * @param string $plugin_name class plugin name to load * @param bool $check check if already loaded * - * @return bool|string|array + * @return bool|string * @throws \SmartyException */ - public function loadPlugin(Smarty $smarty, $plugin_prefix, $plugin_type, $name, $check) + public function loadPlugin(Smarty $smarty, $plugin_name, $check) { // if function or class exists, exit silently (already loaded) - $plugin_name = "{$plugin_prefix}_{$plugin_type}_{$name}"; if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) { return true; } - - // check for auto-loader plugin - foreach ($smarty->getPluginsNamespace() as $namespace) { - $class = $namespace . '\\' . $name; - if (class_exists($class, true) && is_callable(array($class, $plugin_type))) { - // the requested class exists and implements the required interface. - // as we are using the autoloader, we do not know the file name - if ($check) return true; - else return array($class, $plugin_type); - } - } - if (!preg_match('#^smarty_((internal)|([^_]+))_(.+)$#i', $plugin_name, $match)) { throw new SmartyException("plugin {$plugin_name} is not a valid name format"); } diff --git a/libs/sysplugins/smarty_internal_runtime_filterhandler.php b/libs/sysplugins/smarty_internal_runtime_filterhandler.php index 0fdbd5f93..2824ba33a 100644 --- a/libs/sysplugins/smarty_internal_runtime_filterhandler.php +++ b/libs/sysplugins/smarty_internal_runtime_filterhandler.php @@ -35,19 +35,16 @@ public function runFilter($type, $content, Smarty_Internal_Template $template) // loop over autoload filters of specified type if (!empty($template->smarty->autoload_filters[ $type ])) { foreach ((array)$template->smarty->autoload_filters[ $type ] as $name) { - $plugin_prefix = 'Smarty'; - $plugin_type = "{$type}filter"; - $plugin_name = "{$plugin_prefix}_{$plugin_type}_{$name}"; + $plugin_name = "Smarty_{$type}filter_{$name}"; if (function_exists($plugin_name)) { $callback = $plugin_name; } elseif (class_exists($plugin_name, false) && is_callable(array($plugin_name, 'execute'))) { $callback = array($plugin_name, 'execute'); - } elseif ($template->smarty->loadPlugin($plugin_prefix, $plugin_type, $name, false)) { - if (class_exists($name, true) && is_callable(array($name, $plugin_type))) { + } elseif ($template->smarty->loadPlugin($plugin_name, false)) { + if (class_exists($name, true) && is_callable(array($name, "{$type}filter"))) { // use autoloader style plugin - $callback = array($name, $plugin_type); - } - elseif (function_exists($plugin_name)) { + $callback = array($name, "{$type}filter"); + } elseif (function_exists($plugin_name)) { // use loaded Smarty2 style plugin $callback = $plugin_name; } elseif (class_exists($plugin_name, false) && is_callable(array($plugin_name, 'execute'))) { diff --git a/libs/sysplugins/smarty_internal_template.php b/libs/sysplugins/smarty_internal_template.php index d561d98a6..1ee0a0df4 100644 --- a/libs/sysplugins/smarty_internal_template.php +++ b/libs/sysplugins/smarty_internal_template.php @@ -473,12 +473,18 @@ public function _checkPlugins($plugins) $checked[ $name ] = true; } } - if (!isset($checked[ $name ])) { - if (false !== $this->smarty->loadPlugin($name)) { - $checked[ $name ] = true; - } else { - throw new SmartyException("Plugin '{$name}' not callable"); - } + } + else { + // plugin must either set "method" (auto-load plugins) + // or "function" (procedural plugins) + throw new SmartyException("Plugin '{$name}' not defined"); + } + + if (!isset($checked[ $name ])) { + if (false !== $this->smarty->loadPlugin($name)) { + $checked[ $name ] = true; + } else { + throw new SmartyException("Plugin '{$name}' not callable"); } } } @@ -657,16 +663,11 @@ public function _cleanUp() */ public function loadCompiler() { - $prefix = $this->source->compiler_class['prefix']; - $type = $this->source->compiler_class['type']; - $name = $this->source->compiler_class['name']; - $class = "{$prefix}_{$type}_{$name}"; - - if (!class_exists($class)) { - $this->smarty->loadPlugin($prefix, $type, $name); + if (!class_exists($this->source->compiler_class)) { + $this->smarty->loadPlugin($this->source->compiler_class); } $this->compiler = - new $class( + new $this->source->compiler_class( $this->source->template_lexer_class, $this->source->template_parser_class, $this->smarty diff --git a/libs/sysplugins/smarty_internal_templatecompilerbase.php b/libs/sysplugins/smarty_internal_templatecompilerbase.php index 31761f840..c3ac80eba 100644 --- a/libs/sysplugins/smarty_internal_templatecompilerbase.php +++ b/libs/sysplugins/smarty_internal_templatecompilerbase.php @@ -821,10 +821,10 @@ public function getPlugin($plugin_name, $plugin_type) return $function; } // loop through plugin dirs and find the plugin - $function = "smarty_{$plugin_type}_{$plugin_name}"; - $file = $this->smarty->loadPlugin('smarty', $plugin_type, $plugin_name, false); + $function = 'smarty_' . $plugin_type . '_' . $plugin_name; + $file = $this->smarty->loadPlugin($function, false); if (is_array($file)) { - // plugin is a static method of a class + // plugin is implemented by a static method of an auto-loaded class if ($this->caching && ($this->nocache || $this->tag_nocache)) { $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'method' ] = $file; @@ -836,11 +836,8 @@ public function getPlugin($plugin_name, $plugin_type) $this->modifier_plugins[ $plugin_name ] = true; } return join('::', $file); - } - elseif (is_string($file)) { - // plugin is a function within a file + } elseif (is_string($file)) { if ($this->caching && ($this->nocache || $this->tag_nocache)) { - $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'file' ] = $file; $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ] = @@ -1593,7 +1590,7 @@ private function compileTag2($tag, $args, $parameter) // check plugins from plugins folder foreach ($this->plugin_search_order as $plugin_type) { if ($plugin_type === Smarty::PLUGIN_COMPILER - && $this->smarty->loadPlugin('smarty', 'compiler', $tag) + && $this->smarty->loadPlugin('smarty_compiler_' . $tag) && (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) ) { @@ -1740,7 +1737,7 @@ private function compileTag2($tag, $args, $parameter) ) ); } - if ($this->smarty->loadPlugin('smarty', 'compiler', $tag)) { + if ($this->smarty->loadPlugin('smarty_compiler_' . $tag)) { $plugin = 'smarty_compiler_' . $tag; if (is_callable($plugin)) { return $plugin($args, $this->smarty); diff --git a/libs/sysplugins/smarty_resource.php b/libs/sysplugins/smarty_resource.php index f88a378f8..7fe84536f 100644 --- a/libs/sysplugins/smarty_resource.php +++ b/libs/sysplugins/smarty_resource.php @@ -80,8 +80,8 @@ public static function load(Smarty $smarty, $type) return $smarty->_cache[ 'resource_handlers' ][ $type ] = new $_resource_class(); } // try plugins dir - if ($smarty->loadPlugin('Smarty', 'Resource', ucfirst($type))) { - $_resource_class = 'Smarty_Resource_' . ucfirst($type); + $_resource_class = 'Smarty_Resource_' . ucfirst($type); + if ($smarty->loadPlugin($_resource_class)) { if (class_exists($_resource_class, false)) { return $smarty->_cache[ 'resource_handlers' ][ $type ] = new $_resource_class(); } else { diff --git a/libs/sysplugins/smarty_template_config.php b/libs/sysplugins/smarty_template_config.php index 59e9041d6..850ae32e7 100644 --- a/libs/sysplugins/smarty_template_config.php +++ b/libs/sysplugins/smarty_template_config.php @@ -43,7 +43,7 @@ class Smarty_Template_Config extends Smarty_Template_Source * * @var string */ - public $compiler_class = array('prefix' => 'Smarty', 'type' => 'Internal', 'name' => 'Config_File_Compiler'); + public $compiler_class = 'Smarty_Internal_Config_File_Compiler'; /** * Name of the Class to tokenize this resource's contents with diff --git a/libs/sysplugins/smarty_template_source.php b/libs/sysplugins/smarty_template_source.php index 73e97610f..16b47f23c 100644 --- a/libs/sysplugins/smarty_template_source.php +++ b/libs/sysplugins/smarty_template_source.php @@ -106,7 +106,7 @@ class Smarty_Template_Source * * @var string */ - public $compiler_class = array('prefix' => 'Smarty', 'type' => 'Internal', 'name' => 'SmartyTemplateCompiler'); + public $compiler_class = 'Smarty_Internal_SmartyTemplateCompiler'; /** * Name of the Class to tokenize this resource's contents with