Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using closures as registered plugins #273

Closed
bertptrs opened this issue Aug 16, 2016 · 3 comments
Closed

Using closures as registered plugins #273

bertptrs opened this issue Aug 16, 2016 · 3 comments

Comments

@bertptrs
Copy link

Currently, Smarty::registerPlguin allows you to supply a Closure (since it is a callable) but when using it in a template it does not compile, resulting in the error Object of class Closure could not be converted to string.

This is because (for functions, other types of plugins behave similarly), it hits the following code segment:

if (!is_array($function)) {
    $output = "{$function}({$_params},\$_smarty_tpl)";
} elseif (is_object($function[ 0 ])) {
    $output =
        "\$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION]['{$tag}'][0][0]->{$function[1]}({$_params},\$_smarty_tpl)";
} else {
    $output = "{$function[0]}::{$function[1]}({$_params},\$_smarty_tpl)";
}

The first case gets executed, since a Closure is not an array. This could be solved by adding the following case:

if ($function instanceof Closure) {
    $output = "\$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION]['{$tag}'][0]({$_params},\$_smarty_tpl)";
} elseif (!is_array($function)) {
// And so forth

Could this be supported? I could probably write a patch works for it. This is backwards compatible to at least PHP 5.2, as the class does not have to be loaded (or even exist) for the operator to work.

@bertptrs
Copy link
Author

Additionally, the calling syntax for closures is valid for the other types as well, so the branching structure might be removed altogether.

@fox34
Copy link

fox34 commented Aug 18, 2016

You can use this patch as temporary workaround. Not perfect, but doing the job. Note: Works unmodified only with 3.1.30, since some code has been changed around.
Derived from this patch for older smarty versions: https://gist.github.com/za-creature/1761969

Smarty-v3.1.30.registerPlugin.closure.txt

--- smarty-3.1.30/libs/sysplugins/smarty_internal_compile_private_registered_function_original.php  2016-08-18 14:01:17.312290405 +0200
+++ smarty-3.1.30/libs/sysplugins/smarty_internal_compile_private_registered_function.php   2016-08-18 13:59:29.460844435 +0200
@@ -61,7 +61,10 @@
         $_params = 'array(' . implode(",", $_paramsArray) . ')';
         $function = $tag_info[ 0 ];
         // compile code
-        if (!is_array($function)) {
+        if(is_object($function) && $function instanceof Closure) {
+            $output =
+                "\$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION]['{$tag}'][0]({$_params}, null, \$_smarty_tpl, \$_block_repeat)";
+        } elseif (!is_array($function)) {
             $output = "{$function}({$_params},\$_smarty_tpl)";
         } elseif (is_object($function[ 0 ])) {
             $output =

Edit: Did not see your own solution in your first post. Sorry, seems to be equal.

@uwetews
Copy link
Contributor

uwetews commented May 27, 2017

The fix is now in the master branch and will later be included in 3.1.32

@uwetews uwetews closed this as completed May 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants