XF 2.2 Callback question


Well-known member
I have created a page on my second forum with the callback option.
To test I used this script as an example: w3schools.com | Form (try it yourself)
<xf:callback class="\masterforum\test\index" method="getHtml"></xf:callback>
Server folder forum/src/addons/masterforum/test/index.php:
// define variables and set to empty values
$nameErr = $emailErr = $genderErr = $websiteErr = "";
$name = $email = $gender = $comment = $website = "";

  if (empty($_POST["name"])) {
    $nameErr = "Name is required";
  } else {
    $name = test_input($_POST["name"]);
    // check if name only contains letters and whitespace
    if (!preg_match("/^[a-zA-Z-' ]*$/",$name)) {
      $nameErr = "Only letters and white space allowed";
  if (empty($_POST["email"])) {
    $emailErr = "Email is required";
  } else {
    $email = test_input($_POST["email"]);
    // check if e-mail address is well-formed
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
      $emailErr = "Invalid email format";
  if (empty($_POST["website"])) {
    $website = "";
  } else {
    $website = test_input($_POST["website"]);
    // check if URL address syntax is valid (this regular expression also allows dashes in the URL)
    if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$website)) {
      $websiteErr = "Invalid URL";

  if (empty($_POST["comment"])) {
    $comment = "";
  } else {
    $comment = test_input($_POST["comment"]);

  if (empty($_POST["gender"])) {
    $genderErr = "Gender is required";
  } else {
    $gender = test_input($_POST["gender"]);

function test_input($data) {
  $data = trim($data);
  $data = stripslashes($data);
  $data = htmlspecialchars($data);
  return $data;

<h2>PHP Form Validation Example</h2>
<p><span class="error">* required field</span></p>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>"> 
  Name: <input type="text" name="name" value="<?php echo $name;?>">
  <span class="error">* <?php echo $nameErr;?></span>
  E-mail: <input type="text" name="email" value="<?php echo $email;?>">
  <span class="error">* <?php echo $emailErr;?></span>
  Website: <input type="text" name="website" value="<?php echo $website;?>">
  <span class="error"><?php echo $websiteErr;?></span>
  Comment: <textarea name="comment" rows="5" cols="40"><?php echo $comment;?></textarea>
  <input type="radio" name="gender" <?php if (isset($gender) && $gender=="female") echo "checked";?> value="female">Female
  <input type="radio" name="gender" <?php if (isset($gender) && $gender=="male") echo "checked";?> value="male">Male
  <input type="radio" name="gender" <?php if (isset($gender) && $gender=="other") echo "checked";?> value="other">Other 
  <span class="error">* <?php echo $genderErr;?></span>
  <input type="submit" name="submit" value="Submit"> 

echo "<h2>Your Input:</h2>";
echo $name;
echo "<br>";
echo $email;
echo "<br>";
echo $website;
echo "<br>";
echo $comment;
echo "<br>";
echo $gender;

The result: masterforum | Test
The form is displayed, but with the following error message: Callback \masterforum\test\index::getHtml is invalid (error_invalid_class).
After filling in the form and pressing send, I get another error message:
Oops! We ran into some problems.
Security error occurred. Please press back, refresh the page, and try again.
How can I get the form working?


XenForo developer
Staff member
Your PHP file (src/addons/masterforum/test/index.php) needs to be a class with the name you've specified and defining a static method getHtml.


namespace masterforum\test;

class index
    public static function getHtml()
    // ...

This method then needs to return the HTML output you want to display.

Handling the form is a different beast as if you're wanting to do it within XF, you're going to need the full XF framework, which essentially means a full add-on.


Well-known member
Thanks @Mike (y)
The form is displayed, but with the following error message: Callback \masterforum\test\index::getHtml is invalid (error_invalid_class).
This problem is solved now :)

The other problem is that after submitting the form it will be redirected to another page.
To fix that I changed $_SERVER["PHP_SELF"]"> to $_SERVER['REQUEST_URI'].
The script itself doesn't work yet, but I'm going to see what I can adjust.


Well-known member
touching $_SERVER could expose lots of security issues.
Since you are using XenForo, you need to do it in the XenForo way to display the form as opposed to copying and pasting pure And messy PHP codes.

I suggest you look into contact_form template (Admin->Appearence->Templates->Public->
and search for contact_form (using filter)

then learn how the XenForo template syntax being used, and how it renders contact form (https://www.masterforum.nl/forum/index.php?misc/contact)
It has <xf:form> which translates to the POST action
<xf:form action="{{ link('misc/contact') }}" class="block" ajax="true" data-force-flash-message="true">

and xf:textboxrow which is translating to HTML text box for email input,
<xf:textboxrow name="email" maxlength="{{ max_length($xf.visitor, 'email') }}" type="email"
                    label="{{ phrase('your_email_address') }}" required="required" hint="{{ phrase('required') }}" />
etc.. and submit buttons etc.

check that action="{{ link('misc/contact') }}" part in <xf:form tag

it means that form submit process handles in the Contact action in Misc public controller class which is located in src/XF/Pub/Controller/Misc.php
(you can find which controller is being used, and template names at the bottom of the contact us page if you have enabled the debugging mode in config.php

Then again you navigate to line: 44 and you see the action actionContact method, under this line 66 if ($this->isPost())
you see this setupContactService

   $contactService = $this->setupContactService();
so you navigate back to the top of the file, so you will find that protected function setupContactService(), and you will have this part there:
        $input = $this->filter([
            'username' => 'str',
            'email' => 'str',
            'subject' => 'str',
            'message' => 'str'
THAT! is how you collect the form data. form data get collected into that $input variable.

Try these links too:

Goodluck :)