Jump to content
Tapeix

Access $smarty->getTemplateVars() in mail template

Recommended Posts

The following PHP code will display a message when latefee overide is enabled.

GLOBAL $smarty;
if ($smarty->getTemplateVars()['client']['latefeeoveride'] == 0) {
    print("show message");
}

 However, this code cannot be included within the mail templates. Instead, I have to rewrite the following syntax within the boundries of smarty. 

$smarty->getTemplateVars()['client']['latefeeoveride']

Can anyone help me with that? I'm looking forward to your suggestions.

Edited by Tapeix

Share this post


Link to post
Share on other sites
31 minutes ago, Tapeix said:

However, within WHMCS its emails I cannot write PHP. Instead, the latefeeoveride variable has to be access within the limits of Smarty. Does anyone know how to rewrite the $smarty->getTemplateVars()['client']['latefeeoveride'] syntax to something that's compatible within the mail templates? 

the Smarty Security Policy would have a fatal heart attack if you tried anything like that. 🚑

in reality, what you would do is use an EmailPreSend hook to query the database (capsule, class whatever) and make that value available to the template as a merge field... then if your email template, you can do the usual Smarty conditional statement using that merge field... {if $latefeeoverride}blah blah blah{/if}

Share this post


Link to post
Share on other sites

Having me working with capsule for the first time is being a hard time. 😉 

While this query works:

SELECT latefeeoverides
FROM tblinvoices
WHERE tblinvoices.id = 8231611
JOIN tblclients ON tblclients.id=tblinvoices.userid

This obvously doesn't because WHMCS didn't implement Laravel 1 on 1:

Capsule::table('SELECT latefeeoverides FROM tblinvoices WHERE tblinvoices.id = ? JOIN tblclients ON tblclients.id=tblinvoices.userid', $vars['relid']);

But unfortunately my attempt to rewrite the query to WHMCS standards doesn't work either: 

use WHMCS\Database\Capsule;

add_hook('EmailPreSend', 1, function($vars) {
    $merge_fields = [];
    if (!array_key_exists('latefeeoverides', $vars['mergefields'])) {
        $merge_fields['latefeeoverides'] = Capsule::table('tblinvoices')
            ->select("latefeeoverides")
            ->join("tblclients ON tblclients.id=tblinvoices.userid")
            ->where("tblinvoices.id = ?", $vars['relid']
            );
    }

    return $merge_fields;

});

# ADD MERGE FIELDS TO MAIL TEMPLATE
add_hook('EmailTplMergeFields', 1, function($vars) {
    $merge_fields = [];
    $merge_fields['latefeeoverides'] = "Latefeeoverides status";
    return $merge_fields;
});

Even my attempt to use the deprecated select_query function didn't work:

        $table = "tblinvoices";
        $fields = "latefeeoveride";
        $where = array(
            "tblinvoices.id" => $vars['relid'],
        );
        $sort = "id";
        $sortorder = "ASC";
        $limits = "1";
        $join = "tblclients ON tblinvoices.userid=tblclients.id";
        $result = select_query($table, $fields, $where,$sort,$sortorder,$limits, $join);

        while ($data = mysql_fetch_array($result)) {
            $merge_fields['latefeeoverides'] = $data['latefeeoveride'];
        }

For now I'll take a break. 🙂 

Share this post


Link to post
Share on other sites
1 hour ago, Tapeix said:

Having me working with capsule for the first time is being a hard time. 😉 

like most things, the first time can be painful. 😖

1 hour ago, Tapeix said:

This obviously doesn't because WHMCS didn't implement Laravel 1 on 1:

you can use RAW select queries in Laravel (and WHMCS) - I rarely bother, but Kian often posts code here doing it that way.

1 hour ago, Tapeix said:

But unfortunately my attempt to rewrite the query to WHMCS standards doesn't work either: 

unless i'm missing something, I think you may have overcomplicated this, so let me post two example hooks - one using the class model, and then again using capsule, to see if that helps you on your way...

for the sake of argument, i'm assuming (from the above code) that you're trying to do this in an Invoice email template - so in the examples, i'm going to limit the hook to work only the Invoice Payment Reminder template in the capsule version, but specify multiple valid invoice email templates in the model class version by using in_array (the method would work in the capsule hook too)...

first the capsule method...

<?php

# Email MergeFields Hook
# Written by brian!

use WHMCS\Database\Capsule;

add_hook('EmailPreSend', 1, function($vars) {
 
	if ($vars['messagename'] == 'Invoice Payment Reminder') {
		$mergefields = $vars['mergefields'];
		$clientid = $mergefields['client_id'];
		$overridelatefees = Capsule::table('tblclients')->where('id',$clientid)->value('latefeeoveride');
		$merge_fields['latefeesoverride'] = $overridelatefees;
		return $merge_fields;
	}
});

let's ignore for now that WHMCS have misspelled the column heading and override should have 2 x r (unless that's one of those weird US English quirks!) 🙄

second, the class method...

<?php

# Email MergeFields Hook
# Written by brian!

use WHMCS\User\Client;

add_hook('EmailPreSend', 1, function($vars) {

	$validtemplates = array("Invoice Payment Reminder","Invoice Payment Confirmation");
	if (in_array($vars["messagename"], $validtemplates)) {
		$mergefields = $vars['mergefields'];
		$clientid = $mergefields['client_id'];
		$thisclient = Client::find($clientid);
		$overridelatefees = $thisclient->overrideLateFee;
		$merge_fields['latefeesoverride'] = $overridelatefees;
		return $merge_fields;
	}
});

tbh in both cases, I could have trimmed some of those lines of code, but I wanted you to see the steps I was taking clearly.

both hooks would return different values - so the class method will return true / false, whereas using capsule will just return what's in the database, e.g 1 or 0.

in either case, you should be able to use a conditional statement in the email template to see if the client has late fees overridden, and if so, to display your text...

{if $latefeesoverride}override enabled{/if}

Share this post


Link to post
Share on other sites

Wow, Brian. That is very kind of you. 

Meanwhile, I've almost got it to work, but could figure it out how to process the following output. 

[{"latefeeoveride":0}]

You have made the code much more clearer. I mean, look at my chunky code. 😄 

Code:

<?php 
use WHMCS\Database\Capsule;

add_hook('EmailTplMergeFields', 1, function($vars) {
    $merge_fields = [];
    $merge_fields['latefeeoverides'] = "Latefeeoverides status";
    return $merge_fields;
});

add_hook('EmailPreSend', 1, function($vars) {
    $merge_fields = [];
        if (!array_key_exists('latefeeoverides', $vars['mergefields'])) {
            $result =
                Capsule::table('tblinvoices')
                ->select('latefeeoveride')
                ->join('tblclients', 'tblinvoices.userid', '=', 'tblclients.id')
                ->where("tblinvoices.id", $vars['relid'])
                ->get();

            $merge_fields['latefeeoverides'] = $result;

        } else {
            $merge_fields['latefeeoverides'] = "abc";
        }

    return $merge_fields;
});

Moreover, I didn't know that $vars contained the client_id; I couldn't debug the mailoutput, so I decided to use a join instead.  #doyourhomework

I think I'll keep experimenting to better understand how things work, like this:

$validtemplates = array("Invoice Payment Reminder","Invoice Payment Confirmation","First Invoice Overdue Notice","Second Invoice Overdue Notice","Third Invoice Overdue Notice");

But once again, thanks! I'll install your code within the next few minutes.

Edited by Tapeix

Share this post


Link to post
Share on other sites

The final code looks like this.

<?php

/** Check latefee status
 *  1 = no latefees to be applied, 0 = latefees to be applied
 *  You can use the following message to display a custom message to clients with latefees enabled:
 *  {if $latefeesoverride = 1}You are charged $10.00 administration costs{/if}
 *  Made by brain! (ref. https://whmcs.community/topic/305334-access-smarty-gettemplatevars-in-mail-template/)
 */

use WHMCS\Database\Capsule;

add_hook('EmailTplMergeFields', 1, function($vars) {
    $merge_fields = [];
    $merge_fields['latefeesoverride'] = "Latefeesoverride status";
    return $merge_fields;
});

add_hook('EmailPreSend', 1, function($vars) {
    $validtemplates = array("Invoice Payment Reminder","Invoice Payment Confirmation","First Invoice Overdue Notice","Second Invoice Overdue Notice","Third Invoice Overdue Notice");
    if (in_array($vars["messagename"], $validtemplates)) {
        $merge_fields = $vars['mergefields'];
        $clientid = $merge_fields['client_id'];
        $overridelatefees = Capsule::table('tblclients')->where('id', $clientid)->value('latefeeoveride');
        $merge_fields['latefeesoverride'] = $overridelatefees;
        return $merge_fields;
    }
});

 

Share this post


Link to post
Share on other sites
27 minutes ago, Tapeix said:

Moreover, I didn't know that $vars contained the client_id;

the hook point can access the email templates mergefields - i'm not guaranteeing that client_id will be available on all templates though! 🙂

31 minutes ago, Tapeix said:

I couldn't debug the mailoutput, so I decided to use a join instead.  #doyourhomework

with it being a Smarty template, you can add {debug} to any email template, send a test email using it (ideally you have a dev install or test client account for this), view the email from the admin area client summary emails tab and it should open the normal Smarty debug window.... remember to remove the {debug} from the template when you're finished.

34 minutes ago, Tapeix said:

I think I'll keep experimenting to better understand how things work, like this:

you could achieve the same using an IF statement with multiple OR - but in_array looks cleaner.

with regards to EmailTplMergeFields, it's probably worth mentioning that you don't need to include that to make the content from the other hook work... it's only to add it as an option in the available merge fields table in email templates.

also, you can use the same in_array solution in that hook so that it is only shown on those valid invoice templates where the other hook is using it.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated