|
Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon. |
|
View previous topic :: View next topic |
Author |
Message |
infect Smarty Rookie
Joined: 04 Jun 2004 Posts: 9
|
Posted: Mon Jun 07, 2004 11:05 pm Post subject: SmartyValidate custom criteria functions |
|
|
I was just wondering what values an "isCustom" custom function should return. The documentation shows an example function signature, but not an actual function.
From the documentation:
Quote: |
isCustom
--------
example:
{validate field="password" criteria="isCustom" function="passValid" message="..."}
"isCustom": checks a field against a php function. "function" is
required, and must be an existing PHP function. Class method
calls must be wrapped in a PHP function. The function must be
registered with the register_criteria() method.
custom functions are called like so:
passValid($value, $empty, &$params, &$formvars) { }
Where $value is the form value being tested and $empty is the boolean value
of the "empty" attribute. The third value holds the array of ALL the
attributes for this validator. $params is passed by reference so you can
manipulate the session data within your function if necessary. The fourth
parameter is ALL the submitted form vars, passed by reference so you can
manipulate them if necessary.
|
most importantly, the line that reads:
Quote: |
passValid($value, $empty, &$params, &$formvars) { }
|
if for example, i wanted to make a function to make sure all characters in a field are alphanumeric, this is what i came up with:
Code: |
// NOTE: IT IS ASSUMED THAT THESE CRITERIA HAVE ALREADY BEEN RUN: notEmpty, isLength
function username_alphanumeric($value, $empty, &$params, &$formvars)
{
// extract the field data into $username
if(ereg('[^A-Za-z0-9]', $username))
{
echo "Usernames must contain only letters and numbers.";
}
else
{
echo "$username is a valid username.";
}
}
|
it is obviously incomplete, but instead of echoing the messages, should i be returning true and false, or printing out their error message directly from $params only if it fails? just a bit confused, any help would be greatly appreciated. |
|
Back to top |
|
infect Smarty Rookie
Joined: 04 Jun 2004 Posts: 9
|
Posted: Tue Jun 08, 2004 12:00 am Post subject: |
|
|
this seems to have worked:
Code: |
// NOTE: IT IS ASSUMED THAT THESE CRITERIA HAVE ALREADY BEEN RUN: notEmpty, isLength
function username_alphanumeric($value, $empty, &$params, &$formvars)
{
if(ereg('[^A-Za-z0-9]', $value))
{
return false;
}
else
{
return true;
}
}
|
or, for brevity:
Code: |
// NOTE: IT IS ASSUMED THAT THESE CRITERIA HAVE ALREADY BEEN RUN: notEmpty, isLength
function username_alphanumeric($value, $empty, &$params, &$formvars)
{
return !ereg('[^A-Za-z0-9]', $value);
}
|
|
|
Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Tue Jun 08, 2004 12:29 am Post subject: |
|
|
That is correct, your function should return true/false. The error message is stated in the template tag. If you'd rather have the function determine the error message, you can reset it from within the function:
$params['message'] = 'That is incorrect.';
Or, you can assign one or more variables in the $formvars array. If you assign that array to Smarty after the validation they will be available from within the template.
$formvars['errors'][] = 'username is incorrect';
$formvars['errors'][] = 'password is incorrect'; |
|
Back to top |
|
infect Smarty Rookie
Joined: 04 Jun 2004 Posts: 9
|
Posted: Tue Jun 08, 2004 5:11 am Post subject: smarty validator bug? |
|
|
monte, is there a limitation to the number of criteria you can register to a function? for some reason it will not run both of my custom criteria together, but if i disable one, then the other works perfectly...
I've checked my code over and over and can't seem to find what i might be doing wrong. I was wondering if maybe the smartyvalidator class doesn't keep more than one "isCustom" function stored at a time, what do you think?
this may be the relevant code, i'm not sure:
Code: |
function register_criteria($func_name, $form = 'default') {
if(!SmartyValidate::is_init($form)) {
trigger_error("SmartyValidate: [register_criteria] form '$form' is not initialized.");
return false;
}
if(!function_exists($func_name)) {
trigger_error("SmartyValidate: [register_criteria] function '$function' does not exist.");
return false;
}
if(!in_array($func_name, $_SESSION['SmartyValidate'][$form]['registered_criteria']))
$_SESSION['SmartyValidate'][$form]['registered_criteria'][] = $func_name;
return true;
}
|
when $_SESSION['SmartyValidate'][$form]['registered_criteria'][] = $func_name; is set, it does not look like any index is being changed in order to accommodate additional functions, it seems as though it is simply being reset. I could be totally off, but i think i'm doing it right.
here's my code for reference:
function.validate_form.php
Code: |
<?php
require_once(SMARTY_DIR . 'SmartyValidate.class.php');
// WARNING: I'M CURRENTLY NOT ESCAPING ALL DATA FROM THE FORM! THIS IS BAD! FIX!
function smarty_function_validate_form($params, &$smarty)
{
$isValidFormData = valid_form(&$smarty);
$smarty->assign($params['isValidFormData'], $isValidFormData);
}
function valid_form(&$smarty)
{
// required initialization
SmartyValidate::connect($smarty);
SmartyValidate::register_criteria('username_availible');
SmartyValidate::register_criteria('username_alphanumeric');
// initialize the form validater
if(empty($_POST))
{
// register custom criteria for checking if username is availible
return false;
}
else
{
// validate after a POST
if(SmartyValidate::is_valid($_POST))
{
// no errors
// TODO: submit values into database
$query = "INSERT INTO user (username, username_crc, password, first_name, last_name, date_created, email_address, phone_number) VALUES ('%s',%u,'%s','%s', '%s', NOW(),'%s','%s')";
$query = sprintf($query, mysql_escape_string($_POST['username']), crc32($_POST['username']), md5($_POST['password']), mysql_escape_string($_POST['first_name']), mysql_escape_string($_POST['last_name']), $_POST['email_address'], $_POST['phone_number']);
// TODO: send them a verification email
// TODO: clear data and send them to the "succeeded" page
// clear session data and continue
SmartyValidate::disconnect();
return true;
}
else
{
// error, redraw the form
$smarty->assign($_POST);
return false;
}
}
}
// custom criteria functions
// NOTE: IT IS ASSUMED THAT THESE CRITERIA HAVE ALREADY BEEN RUN: isLength
function username_availible($value, $empty, &$params, &$formvars)
{
echo "GOT HERE: username_availible (start) <br>";
if(!get_magic_quotes_gpc())
{
$value = addslashes($value);
}
$query = "SELECT * FROM user WHERE username_crc=%u AND username='%s'";
$query = sprintf($query, crc32($value), $value);
echo "QUERY: $query<br>";
$result = mysql_query($query);
$num_rows = @mysql_num_rows($result);
if ($num_rows)
{
return false;
}
else
{
return true;
}
}
function username_alphanumeric($value, $empty, &$params, &$formvars)
{
echo " GOT HERE: username_alphanumeric (start) <br>";
return !ereg('[^A-Za-z0-9]', $value); // if it does contain those characters, then the test should fail...
}
?>
|
and registration_form.tpl:
Code: |
<form method="post" action="?action=register" name="register">
<fieldset>
<legend>Registration Information</legend>
<p class="inputRequirement">* Required information</p>
<div class="formRow"><label>First Name:</label> <input name="first_name" type="text" class="textbox" {if $smarty.post.first_name != ""} value="{$smarty.post.first_name}" {/if} />
<span class="inputRequirement">* {validate field="first_name" criteria="notEmpty" transform="trim" message="First Name is required."}</span></div>
<div class="formRow"><label>Last Name:</label> <input name="last_name" type="text" class="textbox" {if $smarty.post.last_name != ""} value="{$smarty.post.last_name}" {/if} />
<span class="inputRequirement">* {validate field="last_name" criteria="notEmpty" transform="trim" message="Last Name is required."}</span></div>
<div class="formRow"><label>Phone Number:</label> <input name="phone_number" type="text" class="textbox" {if $smarty.post.phone_number != ""} value="{$smarty.post.phone_number}" {/if} />
<span class="inputRequirement">{validate field="phone_number" criteria="isNumber" empty="yes" transform="trim" message="Phone Number must be a number."}</span></div>
<div class="formRow"><label>Email Address:</label> <input name="email_address" type="text" class="textbox" {if $smarty.post.email_address != ""} value="{$smarty.post.email_address}" {/if} />
<span class="inputRequirement">* {validate field="email_address" criteria="isEmail" transform="trim" message="Email Address not valid."}</span></div>
<div class="formRow"><label>Re-Type Email Address:</label> <input name="email_address_verify" type="text" class="textbox" {if $smarty.post.email_address_verify != ""} value="{$smarty.post.email_address_verify}" {/if} />
<span class="inputRequirement">* {validate field="email_address_verify" criteria="isEqual" field2="email_address" transform="trim" message="Email Addresses do not match."}</span></div>
</fieldset>
<div class="fieldSetSpacer"><!-- spacer --></div>
<fieldset>
<legend>Account Information</legend>
<p class="inputRequirement">* Required information</p>
<div class="formRow"><label>Preferred Username:</label> <input name="username" type="text" class="textbox" {if $smarty.post.username != ""} value="{$smarty.post.username}" {/if} />
<span class="inputRequirement">* {validate field="username" criteria="isCustom" function="username_alphanumeric" message="Username may only include alphanumeric characters (a-z, 0-9)."}{validate field="username" criteria="isLength" transform="trim" min="6" max="20" message="Username must be between 6 and 20 characters long."}{validate field="username" criteria="isCustom" function="username_availible" message="Username is not availible, please try a different name."}</span></div>
<div class="formRow"><label>Password:</label> <input name="password" type="password" class="textbox" {if $smarty.post.password != ""} value="{$smarty.post.password}" {/if} />
<span class="inputRequirement">* {validate field="password" criteria="isLength" transform="trim" min="6" max="50" message="Password must be at least 6 characters long."}</span></div>
<div class="formRow"><label>Re-Type Password:</label> <input name="password_verify" type="password" class="textbox" {if $smarty.post.password_verify != ""} value="{$smarty.post.password_verify}" {/if} />
<span class="inputRequirement">* {validate field="password" criteria="isEqual" field2="password_verify" message="Passwords do not match."}</span></div>
</fieldset>
<br />
<input type="submit" value="Register!" />
</form>
|
|
|
Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Tue Jun 08, 2004 1:44 pm Post subject: |
|
|
There is no limit to the number of criteria on a single form element, however as soon as one criteria fails, the rest are ignored. |
|
Back to top |
|
jaey Smarty Regular
Joined: 25 May 2004 Posts: 36 Location: Louisville, Kentucky, USA
|
Posted: Mon Jun 14, 2004 4:24 am Post subject: |
|
|
The relevent lines from infect's template are:
Code: | {validate field="username" criteria="isCustom" function="username_alphanumeric" ...}
{validate field="username" criteria="isCustom" function="username_availible" ...}
|
The relevent lines of code from "plugins/function.validate.php" in SmartyValidate (version 2.1-b1) appear to be:
Code: | 1 $_sess =& $_SESSION['SmartyValidate'][$_form]['validators'];
2
3 $_found = false;
4 if(isset($_sess) && is_array($_sess)) {
5 foreach($_sess as $_key => $_field) {
6 if($_field['field'] == $params['field']
7 && $_field['criteria'] == $params['criteria']) {
8 // field exists
9 $_found = true;
10 if(isset($_sess[$_key]['valid'])
11 && !$_sess[$_key]['valid']) {
12 // not valid, show error and reset
13 $_halt[$_form] = $params['halt'];
14 $_echo = true;
15 if(isset($params['assign'])) {
16 $smarty->assign($params['assign'], $params['message']);
17 $_echo = false;
18 }
19 if(isset($params['append'])) {
20 $smarty->append($params['append'], $params['message']);
21 $_echo = false;
22 }
23 if($_echo) {
24 // no assign or append, so echo message
25 echo $params['message'];
26 }
27 $_sess[$_key]['valid'] = null;
28 break;
29 }
30 }
31 }
32 }
33 if(!$_found) {
34 // create
35 $_sess[] = $params;
36 }
|
The way I read this code, a validator only gets added to the session if lines 6 and 7 evaluate to false. Looking at the two lines from infect's template, the first validator will be processed. However, lines 6 and 7 will evaluate to true for the second validator since the field name and criteria are the same for both validators. This means that the second validator will be ignored. |
|
Back to top |
|
infect Smarty Rookie
Joined: 04 Jun 2004 Posts: 9
|
Posted: Mon Jun 14, 2004 6:28 am Post subject: |
|
|
Right you are... I'll try that and see if it fixes the problem. I really appreciate your time!
... one question though... on the initial load... wouldn't everything be loaded completely? |
|
Back to top |
|
|
|
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
|
|