1
votes

I am attempting to convert some PHP code so that it uses Twig for its template engine.

The code I developed previously worked in such a manner that generating a HTML dropdown list involved calling a static method (formTools::generateSchoolList()) which queried a database and then echo the results into the HTML (spaghetti code).

I've been having some issues creating and then displaying the result of functions and I'm hoping someone can help me troubleshoot the errors I am receiving. In formTools.class.php, I am referring to a single static method for this example and although the Twig Docs suggested using an anonymous method (I called the static function above within the anonymous function), I wasn't able to get that to work, so I made the Twig_SimpleFunction callable parameter the static method directly.

If I do that I get (using return within the static method):

Parse error: syntax error, unexpected '<' in /Path_To_Vendor/vendor/twig/twig/lib/Twig/Environment.php(332) : eval()'d code on line 46

Fatal error: Class '__TwigTemplate_96fa0bd50202e1016defd78dc63d0ee7f8c3432728ffb0946f67a6a1e5c89437' not found in /Path_To_Vendor/vendor/twig/twig/lib/Twig/Environment.php on line 346

If I echo within static function, I get:

Fatal error: Call to undefined method Twig_SimpleFunction::compile() in /path_to_vendor/vendor/twig/twig/lib/Twig/Node/Expression/Call.php on line 27

formTools.class.php

/**
 * Generates a list of all available schools in a dropdown box
 *
 * @throws Exception
 */
static function generateSchoolList() {
    $db = new database(databaseHost, databaseUser, databasePass, databaseName);
    $query = "SELECT * FROM `schoolCodes`";
    $codes = $db->query($query);

    if (isset($codes)) {
        $result = "<select name='schoolCode'>";
        $result .= "<option class='dropdown' value=''>&nbsp;&nbsp;&nbsp;&nbsp;</option>";
        $result .= "<option class='dropdown' disabled>----</option>";
        foreach ($codes as $code) {
            $result .= "<option class='dropdown' value='{$code['codeID']}'>{$code['schoolName']} ({$code['code']})</option>";
        }
        $result .= "</select>";
        **echo/return** $result;
    } else {
        throw new Exception("The schoolCodes table is empty.");
    }
}

formviewer.php

require_once('../vendor/autoload.php');
$ft = new formTools();
$it = new ingestTasks();

Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem('../templates');
$twig = new Twig_Environment($loader);

$function = new Twig_SimpleFunction('generateSchoolList',
    formTools::generateSchoolList()
);
$twig->addFunction($function);

$template = $twig->loadTemplate('viewPlayersByRoster.twig');
echo $twig->render($template);

viewPlayersByRoster.twig

{% extends "base.twig" %}

{% block title %}View Players by Roster{% endblock %}

{% block content %}
<p class="formDesc">This form is for viewing all players on a given roster.</p>
<form action="formviewer.php?action=viewPlayersByRoster" target="_self" method="post">
    <input hidden="hidden" value="viewPlayersByRoster" name="action"  title="action"/>
    <table>
        <tr>
            <td class="rightAlignText"><label for="schoolCode">School:</label></td>
            <td>{{ generateSchoolList() }}</td>
        </tr>
    </table>
</form>
{% endblock %}

EDIT: Using PHP 5.5.24 (cannot update past this), Twig 1.18.2 and using Composer.

composer.json

"require": {
    "twig/twig": "v1.18.2"
  },
      "autoload": {
    "classmap": ["libs/"]
}

EDIT 2:

Changed to what tacone said and got this:

Catchable fatal error: Object of class __TwigTemplate_96fa0bd50202e1016defd78dc63d0ee7f8c3432728ffb0946f67a6a1e5c89437 could not be converted to string in /path_to_vendor/vendor/twig/twig/lib/Twig/Loader/Filesystem.php on line 216

/Filesystem.php

protected function normalizeName($name)
{
    return preg_replace('#/{2,}#', '/', strtr((string) $name, '\\', '/'));
}

formTools.class.php

public function __toString() {
    return $this->formTools;
}
1
Solved. Had to pare everything down to the bare essentials and I figured out I was improperly calling the render() method. - Caleb Williams

1 Answers

2
votes

You are executing the static method instead of passing its coordinates.

Try using PHP classical callback syntax:

$function = new Twig_SimpleFunction('generateSchoolList', ['formTools', 'generateSchoolList']);
$twig->addFunction($function);

See also https://stackoverflow.com/a/29629460/358813