Replacing Legacy Smarty Tags with Hooks

In previous WHMCS versions, Smarty 3's SmartyBC provided backwards compatibility for Smarty's {php}, {include_php}, and {insert} tags. To promote better security, we plan to move to Smarty 4, which is not compatible with SmartyBC, in the near future.

In most cases, the best way to remove legacy Smarty tags from your customizations is to replace them with hooks.

We will remove support for legacy Smarty tags in WHMCS 9.0. If your customizations include legacy Smarty tags, you must eliminate them.

Replacing Tags in Email Templates

For email templates, you can replace PHP logic that uses  {php}, {include_php}, or {insert} tags with a hook using the add_hook function:

add_hook('EmailPreSend', 1, function($vars) {
    // Perform PHP logic here and store the output in an associative array.
    // The array key and value will be the merge field key and value.
    $mergeFieldsArray = [
        'customMergeField' => true,
    ];
    // Return the associative array.
    return $mergeFieldsArray;
});
Click to copy

When you do this, email templates can access items in the returned associative array as though they were standard merge fields. You can use them as part of conditional statements via {if}{else}{/if} and iterate through them via {foreach}{/foreach}.

For more information, see Email Templates and our Developer Hook Reference.

Creating a Hook that Only Executes for a Specific Template

When you can replace PHP logic that uses  {php}, {include_php}, or {insert} tags with a hook, you can choose to only execute it when the system sends a specific email template.

To do this, you will need to add a conditional statement that specifies the name of the desired email template:

add_hook('EmailPreSend', 1, function($vars) {
    $mergeFieldsArray = [];
    // Use the messagename array item from the $vars array to find the template being sent.
    // Perform PHP logic here and store the output in an associative array.
    // The array key and value will be the merge field key and value.
    if ($vars['messagename'] == 'Order Confirmation') {
        $mergeFieldsArray = [
            'customMergeField' => true,
        ];
    }
    // Return the associative array.
    return $mergeFieldsArray;
});
Click to copy

The example above executes when the system sends the Order Confirmation email template. You can specify any template using the name that displays at Configuration > System Settings > Email Templates.

Replacing {php} Tags in Template .tpl Files

For .tpl template files, you can replace PHP logic that uses  {php}, {include_php}, or {insert} tags with a hook using the add_hook function:

add_hook('ClientAreaPage', 1, function($vars) {
    // Perform PHP logic here and store the output in an associative array.
    // The array key and value will be the Smarty variable key and value.
    $smartyVariablesArray = [
        'customSmartyVariable' => true,
    ];
    // Return the associative array.
    return $smartyVariablesArray;
});
Click to copy

When you do this, template files can access items in the returned associative array as though they were standard Smarty variables. You can use them as part of conditional statements via {if}{else}{/if} and iterate through them via {foreach}{/foreach}.

For more information, see PHP Logic Using Hooks and Smarty Themes.

Creating a Hook that Only Executes on a Specific Page

When you can replace PHP logic that uses  {php}, {include_php}, or {insert} tags with a hook, you can choose to only execute it for a specific page. You can do this using two different methods: using a specific ClientAreaPage hook point or using variables in the $vars array.

Only Executing on a Specific Page Using ClientAreaPage Hooks

For this method, specify the ClientAreaPage hook point for the desired area within WHMCS:

add_hook('ClientAreaPageEmails', 1, function($vars) {
    // Perform PHP logic here and store the output in an associative array.
    // The array key and value will be the Smarty variable key and value.
    $smartyVariablesArray = [
        'customSmartyVariable' => true,
    ];
    // Return the associative array.
    return $smartyVariablesArray;
});
Click to copy

The example above executes using the ClientAreaPageEmails hook point. For a list of ClientAreaPage hook points, see our Client Area Page Hooks Reference.

Only Executing on a Specific Page Using $vars Variables

For this method, use one or more of the variables in the $vars array to determine the page that the system is rendering:

add_hook('ClientAreaPage', 1, function($vars) {
    // Use a variable to find the .tpl file being loaded.
    $smartyVariablesArray = [];
    if ($vars['templatefile'] == 'viewcart') {
        $smartyVariablesArray = [
            'customSmartyVariable' => true,
        ];
    }
    // Use combinations of variables for more granular control.
    // Perform PHP logic here and store the output in an associative array.
    // The array key and value will be the Smarty variable key and value.
    $scriptName = str_replace("{$vars['webroot']}/", '', $vars['SCRIPT_NAME']);
    if ($scriptName && $vars['action'] == 'view') {
        $smartyVariablesArray = [
            'customSmartyVariable' => false,
        ];
    }
    // Return the associative array.
    return $smartyVariablesArray;
});

// Items within the returned associative array can be accessed from the template file as if they were
// standard Smarty variables. They can be used with Smarty's built-in functions like {if}{else}{/if} and
// {foreach}{/foreach}.
// More information can be found at the following resources:
// 
// https://developers.whmcs.com/themes/php/
// https://developers.whmcs.com/themes/smarty/
Click to copy
  • The example above uses the templatefile, webroot, SCRIPT_NAME, and view variables in the $vars array to find the template that the system is loading. In many cases, the templatefile variable can suffice to find this.
  • The example above only executes when the system is loading the viewcart.tpl template file.