Jump to content

No more smarty variables in PHP for WHMCS 7?


yggdrasil

Recommended Posts

I have noticed that my templates that had PHP code are now broken and give a PHP error after upgrading to v7.

 

Example, something like this does not work anymore and gives a PHP error:

 

{php}
header("Location: {$WEB_ROOT}/clientarea.php;
{/php}

 

If I take away the smarty web root tag it works again. Is there any reason for this? I could not find anything in the change logs about this. Yes, I know, I should not use PHP in smarty but I'm not that far yet to move them out, first I need to make them work again before trying to move them to hooks as they they are all broke in v7.

 

MySQL and PHP where not changed in the server, so I assume this is something new in the provided Smarty version with WHMC 7.

Edited by yggdrasil
Link to comment
Share on other sites

You'll have to go back to the Migration Guide for v6...

 

{php}
$WEB_ROOT = $template->getVariable('WEB_ROOT')->value;
header("Location: $WEB_ROOT/clientarea.php");
{/php}

 

Migration guide? I was not even aware that existed, its news to me. I will take a look because I just upgraded and was not aware I had to do code changes. Now I discovered plenty of things stopped working.

 

What you posted seems longer and more complicated than before :(

 

So you need to get the variables and put them in PHP now? They where available directly before.

 

Thank you Brian!

Edited by yggdrasil
Link to comment
Share on other sites

You'll have to go back to the Migration Guide for v6...

 

{php}
$WEB_ROOT = $template->getVariable('WEB_ROOT')->value;
header("Location: $WEB_ROOT/clientarea.php");
{/php}

 

I tested this and it doesn't work for everything, in particular smarty variables in arrays. This seems like a downgrade if you ask me in Smarty, but at least we can use JavaScript fine again if I read correctly vs enclosing them in tags :)

 

The reason I say this is because something like this does not work at all anymore.:

 

Before worked directly:

{$loggedinuser.userid}

 

Prints ID of user logged in. Quick and clean.

 

Result is blank array. Also you can see the above was much cleaner and simple.

$loggeduserid = $template->getVariable('loggedinuser.userid')->value;

 

Link to comment
Share on other sites

{php}
$smartyvars = $template->getTemplateVars();
echo $smartyvars['loggedinuser']['userid'];
{/php}

if it were me, i'd be realising that i'm in a Smarty template and rewriting the code as Smarty (with perhaps hook assistance)... rather than adding PHP to the template and then having to pass Smarty variables to/from the {php} tags.

 

short-term you're fine, but long-term you'll seriously have to get out of doing this. :idea:

Link to comment
Share on other sites

{php}
$smartyvars = $template->getTemplateVars();
echo $smartyvars['loggedinuser']['userid'];
{/php}

if it were me, i'd be realising that i'm in a Smarty template and rewriting the code as Smarty (with perhaps hook assistance)... rather than adding PHP to the template and then having to pass Smarty variables to/from the {php} tags.

 

short-term you're fine, but long-term you'll seriously have to get out of doing this. :idea:

 

This is why with Smarty3 now it makes less sense to me.

 

Before:

 

The same smarty vars used in your templates could be used in your PHP code directly.

 

Now:

 

You need to convert the smarty vars to PHP vars first.

 

Add to this that in order to use PHP vars in the template you need to convert them to Smarty but this was also true before. Now, it’s just one more extra layer…

I understand what you mean but Smarty can’t do most of the PHP logic, therefore I need to do it PHP, not to mention that I need to tap into the database and then make some calculation with the data. Now, I could get away and not use Smarty at all. There is no need for that if you can just access everything in the database but that is just way to much extra work to code. If the template has customer data and product data available as Smarty vars, it’s much easier to me and quicker just to use that instead of re-inventing the wheel. WHMCS is doing the heavy lifting and getting most data already. I just need to access it.

 

If you mean why not just stick to Smarty then? Well, I don’t think you can do regex or exploit data and analyze it with Smarty so its PHP in most cases. I’m sure you can do many things in Smarty but it’s still a templating system, not a developing language. Smarty is still a presentation language in the end. I just use the smarty vars as placeholder to get the data instead of tapping the database directly. If I can avoid the database because WHMCS has the information parsed already in that template, then I try to use that.

Link to comment
Share on other sites

This is why with Smarty3 now it makes less sense to me.

strangely, I find it much more intuitive than v2.

 

Before: / Now:

You need to convert the smarty vars to PHP vars first. Add to this that in order to use PHP vars in the template you need to convert them to Smarty but this was also true before. Now, it’s just one more extra layer…

but that's because you're not supposed to be using PHP directly in the template... in fact, in S3 you can't use {php} at all - it's only by WHMCS "temporarily" adding the feature back in that you can do this nonsense.

 

I understand what you mean but Smarty can’t do most of the PHP logic,

nonsense.

 

there's an argument that you shouldn't try to do that - normally by the code police, but they all go rabid with anyone using {php} tags in Smarty anyway... but better to do using Smarty than using {php} tags.

 

therefore I need to do it PHP, not to mention that I need to tap into the database and then make some calculation with the data. Now, I could get away and not use Smarty at all. There is no need for that if you can just access everything in the database but that is just way to much extra work to code. If the template has customer data and product data available as Smarty vars, it’s much easier to me and quicker just to use that instead of re-inventing the wheel. WHMCS is doing the heavy lifting and getting most data already. I just need to access it.

but you are reinventing the wheel - you're taking something that already exists, copying it to php, doing something with it in there and then copying back to Smarty (or perhaps outputting in the PHP).. :twisted:

 

If you mean why not just stick to Smarty then? Well, I don’t think you can do regex or exploit data and analyze it with Smarty so its PHP in most cases.

for the third time, i'll use the word nonsense (as I can't think of another polite word).

 

I’m sure you can do many things in Smarty but it’s still a templating system, not a developing language.

yet you're quite happy to throw PHP code into the middle of it. :roll:

 

Smarty is still a presentation language in the end. I just use the smarty vars as placeholder to get the data instead of tapping the database directly. If I can avoid the database because WHMCS has the information parsed already in that template, then I try to use that.

if WHMCS has given you data to output in a Smarty template, then manipulate it in Smarty - don't be throwing it into {php} tags as some sort of lazy method of doing something with it.

 

yes, in an ideal world you keep them separate - PHP logic outside of the template, and Smarty inside it - but this isn't an ideal world and it's WHMCS we're talking about where, for the most part, there isn't direct access to the PHP... therefore, you can mix & match.

 

if it were me, i'd likely use Smarty to do what you're doing where possible - fine, if the variable you need isn't there, query the db (or use the class documentation) in a hook and pass the result back to the template... or if you really need some serious manipulation of the data using PHP, then do it the hook - but the point is, you need to get to the stage where your first thought isn't to slap {php} tags into the template... in fact, ultimately it shouldn't be your 1st, 2nd, 3rd, 4th or even 5th thought to do that - perhaps not today, but down the road.

 

if you already have the Smarty variable, unless you were trying to do something extraordinary kinky to it, i'd be surprised if you couldn't do it in Smarty alone - about the only exception to that is if you're calling external php files, but if you're doing that, you should be doing it in a hook anyway.

Link to comment
Share on other sites

How do you find this approach more intuitive?

 

I just had to rewrite something and I had to add the smarty tag you posted before at the beginning of my PHP code for every single custom LANG word I have in my language file plus other vars I was using. Like 30 lines. Before this, I didn’t had too, because I could print or use the smarty var directly in the PHP code. Now you need to convert them first to PHP. That is not more intuitive if you ask me. The code is longer if you need to write more lines.

 

I do agree with you. This is nonsense, reading Smarty in PHP, then converting it back but I don’t understand what you are saying exactly. You are saying I should stick with Smarty for whatever I’m doing?

 

Ok, first assuming I should learn a new language which I don’t know, like Smarty, what you are saying is that you can do everything in Smarty just fine?

 

I thought Smarty is just a templating system to print data and separate the logic. You are really comparing it to PHP? Can I do regex or complex things with smarty?

 

Assuming your answer is yes, you can do everything, it would mean Smarty is on par with PHP (or maybe it’s just using PHP for those functions…) there are 3 things that would not make sense in that case:

 

1. First, if it’s using PHP, it’s just another software layer on top of it. That should not be more efficient than using PHP directly because its means its Apache > PHP > Smarty > Database

 

How is another layer of software running on top of another better? The lowest you go the better.

 

2. If I know how to code at least something in PHP but not in smarty it now means I need to learn a completely new syntax just for WHMCS. This without assuming WHMCS goes away with Smarty in the future and then you have to rewrite everything back to PHP in the first place.

 

3. If you are doing all the logic in Smarty, then you are mixing the presentation and the code. Even Smarty on its site puts as goal “To separate application code from the presentation.”

 

Why would you be doing some code logic in Smarty if it was not designed for that?

 

I’m not trying to argue here but I had the impression you said you can do everything in Smarty and you don’t need PHP which means you are not using Smarty just for presentation but for code logic. My idea is to take the PHP code away eventually and move them to hooks, so Smarty only lives in .tpl files and PHP in the .php hooks files.

 

This is just a temporary approach for very basic things I did. Most of the PHP code I use is not even in WHMCS in the first place. If Smarty is as powerful as you mean, then I will buy a book on it and start learning but I don't want to invest energy in a language if WHMCS may remove it in the future.

Link to comment
Share on other sites

How do you find this approach more intuitive?

because I first came to Smarty when I got my WHMCS license many years ago - had never used it before, but understood it straight away (though i've used PHP for many years).

with v3, you can take some quick shortcuts when coding that you couldn't imagine doing with v2 - when I show you the code to do certain things in v5 compared to v7 (as I will later), you'll see the difference.

 

I just had to rewrite something and I had to add the smarty tag you posted before at the beginning of my PHP code for every single custom LANG word I have in my language file plus other vars I was using. Like 30 lines. Before this, I didn’t had too, because I could print or use the smarty var directly in the PHP code. Now you need to convert them first to PHP. That is not more intuitive if you ask me. The code is longer if you need to write more lines.

bangs head against wall... repeats...

 

it's intuitive because I don't NEED to be using {php} tags in the code - it never even occurs to me these days - yes I admit I used to do it occasionally when starting with WHMCS, but i'm a reformed sinner now. :evil:

 

i'm tempted to ask what exactly the original PHP code was, and what you changed it to... I can't believe that, re-written using Smarty, it would be anywhere near 30 lines.

 

I do agree with you. This is nonsense, reading Smarty in PHP, then converting it back but I don’t understand what you are saying exactly. You are saying I should stick with Smarty for whatever I’m doing?

well i'm handicapped by not knowing exactly what you're trying to do, but it's an option yes - if you're trying to do this in the template, do it in Smarty; if it can't be done in Smarty (and i'm not suggesting everything can be), then use a hook (or a combination of the two) - there should never really be a valid reason to use {php} tags.

 

Ok, first assuming I should learn a new language which I don’t know, like Smarty, what you are saying is that you can do everything in Smarty just fine?

well perhaps not everything, but most... things that might take me 10+ lines in a hook, I might be able to do in 1 with Smarty - that doesn't make one method better than the other, just occasionally quicker.

 

I thought Smarty is just a templating system to print data and separate the logic. You are really comparing it to PHP? Can I do regex or complex things with smarty?

it can use PHP functions. :)

 

as I said before, logic and output should be separate, but you've already broken that rule by slapping {php} tags into the template.

 

This without assuming WHMCS goes away with Smarty in the future and then you have to rewrite everything back to PHP in the first place.

never worry about what WHMCS might do in the future, we'll never know until it happens... you might as well worry whether the sun exploded 8 minutes ago.. it's pointless. :)

one day, WHMCS will be using Smarty v4, but that's probably not until WHMCS v10 or v11 - and who knows where any of us will be by then!

 

If you are doing all the logic in Smarty, then you are mixing the presentation and the code. Even Smarty on its site puts as goal “To separate application code from the presentation.”

then i'm prepared to be arrested by the code police - though i'll be sharing a cell with you as you'd get a life sentence for using {php} tags in the template. :lol:

 

btw - I didn't suggest to do all the logic in Smarty... you should certainly never use {php} tags, but it's not a crime to use some logic in Smarty... but perhaps we're possibly just arguing over the definition/usage of the word 'logic'.

 

Why would you be doing some code logic in Smarty if it was not designed for that?

let me answer that with some example code that I posted yesterday...

 

in summary, the user wanted the order period to be shown in the order summary template and he was using prorata pricing - now, the code to do that in Smarty is (for his specific case)...

 

{if $producttotals.productinfo.gid eq "7"}<br />Initial Invoice Pro-rated: {$smarty.now|date_format:"%m/%d/%Y"} - {$producttotals.proratadate}{/if}

nothing wrong with that - the code police wouldn't even bring me in for questioning...

unfortunately for the OP, the second date was wrong (not my fault as it's generated by WHMCS!) - I needed to reduce it by 1 day... so what to do? there are 3 options...

 

1. fix it in Smarty.

2. create a new Smarty variable using a hook

or your favourite option and what I suspect you would instinctively want to do...

3. take the Smarty variable, copy it into {php} tags, subtract 1 day from it, return it to Smarty and output it.

 

if we assume 3 is just plain BAD; 2 is perfectly valid but would take more lines of code and you'd still need a template edit - so why don't we just do 1 as the template has been edited anyway ?

 

if we were to do it using Smarty v2 (would still work in WHMCS v7)...

{if $producttotals.productinfo.gid eq "7"}<br />{math equation="x - y" x=$producttotals.proratadate|strtotime y=86000 assign="prorata_date"}Initial Invoice Pro-rated: {$smarty.now|date_format:"%m/%d/%Y"} - {$prorata_date|date_format:"%m/%d/%Y"}{/if}

or if you want to use some Smarty v3 shortcuts, I could have simply said this...

{if $producttotals.productinfo.gid eq "7"}<br />Initial Invoice Pro-rated: {$smarty.now|date_format:"%m/%d/%Y"} - {(($producttotals.proratadate|strtotime)-86000)|date_format:"%m/%d/%Y"}{/if}  

so in v2, all I need to do is create a new variable in Smarty, using the existing $producttotals.proratadate variable, take a day off it, then output the new variable using a specific date format...

in v3, I don't even need to make a new variable - I can manipulate the existing one.

 

in either case, not a {php} tag in sight.

 

I don't particularly see anything wrong with doing that - if someone wants to change the content of a template and the variables already exist, then do it in Smarty... the biggest reason not to is that your changes may get overwritten during an update, but if you ignore that, then I don't see the harm.

 

it's as equally wrong to say to do it using Smarty 100% of the time as it is to say to use hooks 100% of the time - it's horses for courses.... some situations just require hooks, some can be done using Smarty and others might need both (or even an alternate method).

 

I’m not trying to argue here but I had the impression you said you can do everything in Smarty and you don’t need PHP which means you are not using Smarty just for presentation but for code logic. My idea is to take the PHP code away eventually and move them to hooks, so Smarty only lives in .tpl files and PHP in the .php hooks files.

and that's not a bad ideal - i'm merely suggesting that, depending on what your PHP code is doing, it may be possible to keep it in the template as pure Smarty... not that you should ALWAYS do that, just that it's an option if you want to, and if suitable..

 

at the end of the day if, as with the OP above, a problem can be fixed with 1 line of Smarty code, compared with multiple lines for a hook (with additional template tweaks still needed), then i'll post the Smarty solution.

Link to comment
Share on other sites

When I mentioned my code is longer now I was referring to the PHP code, not smarty, as before I was just using the {smarty.tag} directly in the code and now I have to convert them first at the top to PHP vars and then use them. This is why I said its longer in PHP.

 

Everything you said after that I probably agree. You know better WHMCS than I do so I would not dare to say otherwise. I already was aware that PHP in Smarty is evil. Even in other coding sites when other people asked for PHP in Smarty most users reply with do not use PHP in Smarty. I don’t disagree here, it’s just the easier solution for me right as a non-programmer but just a small business owner that is forced to do most of things himself (accounting, developing, design, support, sales, etc.)

 

The smart thing to do is to move them to hooks, and then even probably disable PHP in Smarty completely and in the future maybe have some ACL list that only allows PHP to be inserted from the hooks folder path directly into templates but not from other sources so make it even more secure. It seems Smarty did had its fair share of security issues that affected WHMCS in the past, so anything to make WHMCS more secure, I'm the first one to support this, even if its going to make things more complicated. Security should always be top priority.

 

I’m going to be honest here. I don’t know smarty enough yet. I do find it easier than PHP in the syntax with the if and else statements and I did wrote some very basic smarty lines before and it was extremely easy, but I was not aware you could more than that because I never saw it doing that. Now that you posted that data code example I’m a bit surprised on how powerful it is. I was not aware you could do math calculations with Smarty. So I did a bit of research and it seems its quite powerful. I had the impression Smarty was used only to do some basic stuff and its main task in WHMCS was to insert the language tags in files, at least from the templates there is no complicated code in there.

 

This changes things completely and like you said chances are that you can probably do most of what I’m doing in Smarty without PHP. In my case, some things are so basic that I’m sure I can, I will just need to learn a bit of Smarty and assuming some specific result or var can’t be done, like you said, then you can put that in a hook, then pass the result to the template and keep it on Smarty. Your point is to stick with Smarty as much as you can and go away from PHP in the templates. And if you need PHP, then put them on a hook and pass them to the templates and again stick to Smarty there.

 

Now for a future discussion it would be nice how to pass data from the template back to the hook. That seems to be my only road block so far to move the code away from the templates or convert them to Smarty. I guess I will buy that book and start to learn a bit of Smarty now, if it’s going to stick with WHMCS I may better know the ins and out of it. It will surely make my live easier while I develop my site.

Link to comment
Share on other sites

When I mentioned my code is longer now I was referring to the PHP code, not smarty, as before I was just using the {smarty.tag} directly in the code and now I have to convert them first at the top to PHP vars and then use them. This is why I said its longer in PHP.

that's probably due to how WHMCS added the feature back... I can't say i've done much {php} testing with v6 or 7 to see if there is a way to do it quicker.

 

Everything you said after that I probably agree. You know better WHMCS than I do so I would not dare to say otherwise. I already was aware that PHP in Smarty is evil. Even in other coding sites when other people asked for PHP in Smarty most users reply with do not use PHP in Smarty. I don’t disagree here, it’s just the easier solution for me right as a non-programmer but just a small business owner that is forced to do most of things himself (accounting, developing, design, support, sales, etc.)

no I absolutely understand your position, and I don't really object to anyone using {php} as a short-term fix, just as long as they understand that the option won't be around forever.

 

I’m going to be honest here. I don’t know smarty enough yet. I do find it easier than PHP in the syntax with the if and else statements and I did wrote some very basic smarty lines before and it was extremely easy, but I was not aware you could more than that because I never saw it doing that. Now that you posted that data code example I’m a bit surprised on how powerful it is. I was not aware you could do math calculations with Smarty. So I did a bit of research and it seems its quite powerful. I had the impression Smarty was used only to do some basic stuff and its main task in WHMCS was to insert the language tags in files, at least from the templates there is no complicated code in there.

that's cos WHMCS have access to the PHP code and they can do what needs to be done on that side... us mere mortals don't have that privilege... you could fix your kbcats issues in seconds with access to the original source.

 

This changes things completely and like you said chances are that you can probably do most of what I’m doing in Smarty without PHP. In my case, some things are so basic that I’m sure I can, I will just need to learn a bit of Smarty and assuming some specific result or var can’t be done, like you said, then you can put that in a hook, then pass the result to the template and keep it on Smarty. Your point is to stick with Smarty as much as you can and go away from PHP in the templates. And if you need PHP, then put them on a hook and pass them to the templates and again stick to Smarty there.

by jove, he's got it! :idea:

 

Now for a future discussion it would be nice how to pass data from the template back to the hook. That seems to be my only road block so far to move the code away from the templates or convert them to Smarty. I guess I will buy that book and start to learn a bit of Smarty now, if it’s going to stick with WHMCS I may better know the ins and out of it. It will surely make my live easier while I develop my site.

there's a book? I might need to have a read of it after you! :)

 

with regards to accessing existing Smarty variables in a hook, here's a rather silly example...

 

<?php

function hook_use_smarty_variables_from_template($vars) {

   $loggedinuser = $vars['loggedinuser'];

   if ($loggedinuser['firstname'] == 'Brian') {
       $message = 'run for your lives, '.$loggedinuser['firstname'].' is logged in!';
   }
   return array("message" => $message);        
}
add_hook("ClientAreaPage", 1, "hook_use_smarty_variables_from_template");
?>

so this hook tries to access the $loggedinuser array you were referring to earlier (you obviously need to be logged in for this to work)... and generates a message variable based on the user's name and returns that variable back to Smarty.

 

as I said, it's a silly example because there are better ways to get a user's name in hooks (using Class docs would be one) - also, i've put no validation in the hook to prevent the variable being created if it's not me logged in.... but it at least shows you how to get a Smarty vasriable from the template, do something to it and return it back to Smarty... in this case as a new variable, but you could modify an existing one by just returning it with the same name.

Link to comment
Share on other sites

The KB cat issue, ahh my week of troubles...

 

I finally did solved that, and yes it was PHP but you should be proud because its completely in a hook, nothing on templates :)

 

I just did a check that verifies the URI, compares it with a regex to be sure it's the correct one (categories) and also for security reasons and based on this replaces the path and then redirects the user to the correct url, if not (user coming from another place) it does nothing. Now, in WHMCS the links are still the originals for each category, but if you click on them, you are redirect so fast that its invisible to the user and the benefit is no messing with the sidebar at all, everything stays as the original template system. Ah I forgot, I did this for multi languages, so it redirects on a different url based on the language just like I did before with articles. It works together with some custom .htaccess rules. Its amazing how you can solve the same problem with dozens of different approaches. I guess this is true in coding in general, you can do the same with tons of different ways and none is better or worse depending on how you look at it, some are just more efficient, or cleaner or well, different. Security of course should always be taken into consideration.

 

Sure, there is a book about Smarty. Sadly it's a bit old:

https://www.amazon.com/Smarty-PHP-Template-Programming-Applications/dp/190481140X

 

But the basics probably are still true today. No O'Reilly book either :(

 

Or Lynda:

https://www.lynda.com/MySQL-tutorials/Using-Smarty-PHP-templating-engine/653/47450-4.html

 

Again, not exactly updated. I guess not many people are covering Smarty 3 yet either. Now there is a business idea, you should write a book on WHMCS (Kindle), you are going to make tons of money for sure :)

 

I would certainly be willing to help.

Link to comment
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