Implemented Provide the ability to call a php file directly from template

AndyB

Well-known member
It would be awesome to be able to call a php file directly from a template without the need for an Addon and hook. For example:

<xen: include "/path/script.php">
 
Upvote 0
This suggestion has been implemented. Votes are no longer accepted.
Hi Shawn,

Curious what sort of things could go wrong.
On several sites there is more than one person with access to the AdminCp, it is not uncommon to have an administrator and someone with access to the templates to "edit' the style of the site and make small changes.

Giving the ability to run a file from the template engine gives whoever has access to the admincp the ability to execute any random file on the server, even if their access is restricted or if they did not have ftp or ssh access anyway. For a hacker it creates a tunnel from which to inject code into the site that it is hard to detect on top of it (since if someone edits a random template it is unlikely to be noticed).

Plus, it is bad design. The templates are the "view". The view layer shouldn't go back into calling controller logic, it should not have access to anything else than the model, by the time we reach the view most of the processing is done and it is only displaying things.

It is totally worth it to take the additional time and extend the controller to even execute or include whatever file is needed. All controllers can be extended in XF, and custom ones can be created.
 
Hi Rigel,

Thank you for taking the time to explain some of the issues in allowing php in templates.

I would like to address your two points.

1) The issue regarding a rouge moderator injecting php into templates could be easily solved by disallowing any access to templates to moderators.

2) I understand that in a perfect world code is written in a manner that is most efficient. But in the real world, admins like myself simply want to create modifications. I find that it's far simpler to modify the xenforo php and .js files directly. I make careful notes showing exactly what I have done and duplicating the hacks is extremely easy come upgrade time. I do the same type of documentation for all template mods.

Currently I only have a few self created Addons which are simple template hooks calling php files. Being able to delete these addons and replace them with a php include in the template system would make life easier for me.
 
New <xen:callback> tag
While generally we don't recommend running PHP via templates, some times it's significantly simpler than writing a full add-on. Here's an example call:

Code:
<xen:callback class="Class_Name_Here" method="getHtml"><b>HTML that will be passed to the callback.</b></xen:callback>

For advanced usage, you can also pass params to the callback via the params attribute (like in template hooks).

To try to limit any untoward usage of this, we place a couple constraints:
  • Like all of our other callbacks, it must happen to a method within a class. You can't just read out /etc/passwd directly.
  • The method that you're calling must start with a limited set of prefixes: get, is, has, render, view, return, print, show, display
I should note that while we've deprecated template hooks, you can actually use this with the new template modification system to effectively create new hooks. That is, if you'd rather work on the final rendered output rather than the template itself.

I quoted Mike's explanation about xen:callback, but it's over my head.

Could someone explain how this callback would work. In my post #1 I was suggesting it would be great to be able to call a php file directly from a template. Brogan indicates this has been implemented by this xen:callback but to me it sounds like it's different than what I was asking for.

How would the template call a php file using this xen:callback?
 
I quoted Mike's explanation about xen:callback, but it's over my head.

Could someone explain how this callback would work. In my post #1 I was suggesting it would be great to be able to call a php file directly from a template. Brogan indicates this has been implemented by this xen:callback but to me it sounds like it's different than what I was asking for.

How would the template call a php file using this xen:callback?
not knowing but guessing here...


A file named AndyB.php in dir library/Andys/ that has the php that you want to use in a page node...

Code:
<xen:callback class="Andys_AndyB" method="getHtml"><b>HTML that will be passed to the callback.</b></xen:callback>
 
I created a file called test.php with the following contents and saved under library/Andy/

Code:
<?php
echo 'test';
?>

I added the following to the first line of my header template:

Code:
<xen:callback class="Andy_test" method="getHtml"></xen:callback>

When I display my forum, above the header is displayed "testtest". Why is test displayed twice? I also get an error message:

Could not execute callback Andy_test::getHtml() - Not callable.

What am I doing wrong?
 
Last edited:
Hi Jeremy,

I just updated post #10 to show exactly what I did. It is a file called test.php. I assume the contents need to be changed. Do you have any idea what the contents of test.php file should be if all I want to do is echo the word "test" ??

Thank you.
 
OK, after a real play with this:
if you want to use the full power, the callback method signature should look like

PHP:
public static function getHtml($content, $params, XenForo_Template_Abstract $template){



template code
Code:
<xen:callback class="XP_Test" method="getHtml" params="{xen:array 'foo=baz'}">content</xen:callback>

PHP:
<?php

class XP_Test{

    public static function getHtml($content, $params, \XenForo_Template_Abstract $template){
        $return = '';

        $return .= 'passed content :  ' . $content ."<br >";
        $return .= 'passed params : ' . var_dump($params);
// you can even attach a existing template to the output
 $templateParams = array();
        $t = $template->create('template', $templateParams);
        $return .= $t;
        return $return;
    }
}
 
Just did a quick test, which is working fine:)

My class:
PHP:
<?php

class XFP_Test{

    public static function getHtml(){
        return 'my returned text';
    }
}

template:
Code:
<xen:callback class="XFP_Test" method="getHtml"></xen:callback>

In this example, where is the file located? How do you set the path?
 
Class names indicate the directory and file it belongs to.

You convert the _ to / and put a .php on the end.

So:

library/XFP/Test.php
 
Top Bottom