Smarty Forum Index Smarty
The discussions here are for Smarty, a template engine for the PHP programming language.

Should SmartyValidate exist as a template function?

 
Post new topic   Reply to topic    Smarty Forum Index -> Add-ons
View previous topic :: View next topic  
Author Message
B00zy
Smarty Rookie


Joined: 19 Jul 2004
Posts: 12

PostPosted: Tue Jul 27, 2004 8:34 am    Post subject: Should SmartyValidate exist as a template function? Reply with quote

...or should it exist as a PHP function?

What I've determined over the past week of using SmartyValidate on a rather large project is that the recommended use of this extension is not the proper use. Here is the example usage given in the README file included with SmartyValidate-2.2:

[php:1:3becb27fe7]
session_start();

// you will need to setup Smarty if
// the defaults are not correct.

require('Smarty.class.php');
require('SmartyValidate.class.php');

$smarty =& new Smarty;

if(empty($_POST)) {
$smarty->display('form.tpl');
} else {
// validate after a POST
if(SmartyValidate::is_valid($_POST)) {
// no errors, done with SmartyValidate
SmartyValidate::disconnect();
$smarty->display('success.tpl');
} else {
// error, redraw the form
$smarty->assign($_POST);
$smarty->display('form.tpl');
}
}
[/php:1:3becb27fe7]

If you look closely, this method is completely insecure (ATTN Monte: this should be changed in the documentation as it is encouraging the user to open a security hole):

Let's pretend success.tpl is actually myPasswordList.tpl.

    1. We don't even need to know what the form looks like. Hell, let's just skip right to posting variables. In fact, if we view the form we're screwed because that is how SmartyValidate is going to load the validation criteria.
    2. Write a script that will post to this form. Only one $_POST variable is required: $_POST['0wn3d'].
    3. Since $_POST is no longer empty, we're inside the first bracket. SmartyValidate::is_valid() will execute and will pass since there is no criteria to validate against.
    4. Jackpot! We can now see all the passwords on myPasswordList.tpl


Here are two possible ways to initialize the validation criteria:

    1. Check to see that $_SESSION['SmartyValidate'] has been registered. If not, display form.tpl, validation variables are loaded, everyone's happy!
    2. Create a file with only {validate} tags. Display validations.tpl when !empty($_POST). It's also good to enclose everything within a {capture} block so that no output is displayed which won't allow you to later send out headers, cookies, etc.


Personally, I think the 2nd solution is best because you can group all your validation criteria into one file -- much cleaner.


Aside from rectifying a possible hazardous misuse of SmartyValidate, this does raise an interesting question: Should SmartyValidate exist as a template function? Instead, should SmartyValidate exist as a PHP function? Why?

Redundancy!

Consider the 2nd solution of adding all the validate tags to a file. If we need to preload these variables every time, why not just do this:

[php:1:3becb27fe7]
session_start();

// you will need to setup Smarty if
// the defaults are not correct.

require('Smarty.class.php');
require('SmartyValidate.class.php');

$smarty =& new Smarty;

// Or these could even be in validation.inc.php
$params = array(
'field'=>'name',
'criteria'=>'isRegExp',
'append'=>'errors'
'empty'=>'no');

/* disconnect() should be called on every page load to ensure
* that any changes to the validation is reflected.
* Then we should reload the validation criteria.
*/
SmartyValidate::disconnect();
smarty_function_validate($params,$smarty);

if(empty($_POST)) {
$smarty->display('form.tpl');
} elseif(SmartyValidate::is_valid($_POST)) {
// no errors, done with SmartyValidate
SmartyValidate::disconnect();
$smarty->display('success.tpl');
} else {
// error, redraw the form
$smarty->assign($_POST);
$smarty->display('form.tpl');
}
[/php:1:3becb27fe7]

This would, in effect, be the same thing, and would clear the depency on Smarty (after a few modifications). Perhaps even open up the doors to some new features that might not be possible when/if SmartyValidate exists in the PHP realm.

However... the alternative advantage is in the question itself:

It's cleaner

The easy-to-understand and easy-to-manipulate syntax of Smarty is what allows this application to exist (and thrive!) in the template realm. If ever needed, designers can be educated in SmartyValidate before learning the basics of PHP. It's much cleaner than having a script full of arrays.

IMO, it should exist in both realms. These comparisons prove that it's possible to satisfy everyone here. All that is required to carry this over into the PHP realm is the use of smarty_function_validate() in your script.
Back to top
View user's profile Send private message
mohrt
Administrator


Joined: 16 Apr 2003
Posts: 7366
Location: Lincoln Nebraska, USA

PostPosted: Tue Jul 27, 2004 1:31 pm    Post subject: Re: Should SmartyValidate exist as a template function? Reply with quote

B00zy wrote:

3. Since $_POST is no longer empty, we're inside the first bracket. SmartyValidate::is_valid() will execute and will pass since there is no criteria to validate against.


That is incorrect, is_valid() will fail when SmartyValidate has not been initialized first. If it has been initialized, then the form will pass only if the validation criteria passes. It is your responsibility to ensure the validation is strict enough to fail on an empty form.

B00zy wrote:

Aside from rectifying a possible hazardous misuse of SmartyValidate, this does raise an interesting question: Should SmartyValidate exist as a template function? Instead, should SmartyValidate exist as a PHP function? Why?


This is already being discussed on another thread. The general consensus is to put the validation criteria in a config file (probably XML format), then the PHP code is kept to simple is_valid() testing and form posting, and the template is kept to testing for and displaying error messages.

Your welcome to join the discussion.
http://www.phpinsider.com/smarty-forum/viewtopic.php?t=2469&start=150
Back to top
View user's profile Send private message Visit poster's website
B00zy
Smarty Rookie


Joined: 19 Jul 2004
Posts: 12

PostPosted: Tue Jul 27, 2004 2:36 pm    Post subject: Re: Should SmartyValidate exist as a template function? Reply with quote

mohrt wrote:
B00zy wrote:

3. Since $_POST is no longer empty, we're inside the first bracket. SmartyValidate::is_valid() will execute and will pass since there is no criteria to validate against.


That is incorrect, is_valid() will fail when SmartyValidate has not been initialized first. If it has been initialized, then the form will pass only if the validation criteria passes. It is your responsibility to ensure the validation is strict enough to fail on an empty form.



WRONG, it is correct. Again...


    1. SmartyValidate::connect() loads the session.

    2. For arguments' sake, let's assume that I accidentally loaded form.tpl and all the validators are loaded before I begin my attack. $_SESSION['SmartyValidate'][$form]['validators'] is now filled with all the validators.

    3. I delete the cookie, the session now starts anew. Now, instead of loading the page again, I am going to send a POST request contaning one variable named "0wn3d" with a value of 1.

    4. SmartyValidate::connect() now loads a fresh session.

    5. $_SESSION['SmartyValidate'][$form]['validators'] is empty because the {validate} tags in form.tpl will not be displayed.

    6. $_POST is not empty because I poisoned it with my dummy variable "0wn3d".

    7. SmartyValidate::is_valid() == true and $_POST is not empty, apparently we're allowed to view success.tpl now.


Capiche?
Back to top
View user's profile Send private message
mohrt
Administrator


Joined: 16 Apr 2003
Posts: 7366
Location: Lincoln Nebraska, USA

PostPosted: Tue Jul 27, 2004 3:00 pm    Post subject: Reply with quote

I see now. This is inherent to the fact that form validation criteria is defined in the template, With the criteria abstration ideas going on in the other thread, this problem would be extinquished... the validation criteria would be established when the form was registered instead of when the form template was displayed.
Back to top
View user's profile Send private message Visit poster's website
B00zy
Smarty Rookie


Joined: 19 Jul 2004
Posts: 12

PostPosted: Tue Jul 27, 2004 3:28 pm    Post subject: Reply with quote

My current solution is as follows:

[php:1:3b3dca0358]
session_start();
/* When developing and changing around variables a lot,
* I want to make sure the variables in the session are being
* reset every time.
*/

if (!empty($_POST)) {
$smarty->display('validate.tpl'); /* Display this the first time to load all the validators */
if (SmartyValidate::is_valid($_POST)) {
/* Passed */
$smarty->display('authorized.tpl');
} else {
// Error occured
$smarty->display('validate.tpl'); /* It is necessary to display this twice so that the errors are assigned. */
$smarty->display('invalid.tpl');
}
} else {
// Default page
$smarty->display('form.tpl');
}
SmartyValidate::disconnect();

[/php:1:3b3dca0358]
Back to top
View user's profile Send private message
mohrt
Administrator


Joined: 16 Apr 2003
Posts: 7366
Location: Lincoln Nebraska, USA

PostPosted: Thu Jul 29, 2004 9:44 pm    Post subject: Reply with quote

There is now a fix committed to CVS, is_valid will silently fail when a form's criteria has not been defined.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Smarty Forum Index -> Add-ons All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP