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

SmartyValidate isUnique plugin

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


Joined: 30 Sep 2004
Posts: 16

PostPosted: Fri Jun 10, 2005 1:52 pm    Post subject: SmartyValidate isUnique plugin Reply with quote

I've been using SmartyValidate since version 1, and there's been a LOT of wonderful changes/bug fixes, specifically those for version 2.x.

Here goes a personal plugin: isUnique
very often during a website's signup/registration process, you need to check if an username or email is already taken by someone else in a database table, and most of the time you just have to write a function to query that table.
This, in my opinion, can very likely be classified as data validation. Assuming you are using SmartyValidate for data validation, it would be inconsistent to use SmartyValidate for most of your data validation and having to write another block of codes outside of SmartyValidate to validate if a username/email address already exists in a database. So here is the isUnique plugin, feed the form field name, the table name, and the name of the column you want to check on, and the validator will tell you if it's Unique or not.

Sample Usage:

Code:
   <?php
    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)) {
        // new form, we (re)set the session data
        SmartyValidate::connect($smarty, true);
        // register our validators
       SmartyValidate::register_validator('username_isunique', 'username:users_table:username_column', 'isUnique', true);
        // display form
        $smarty->display('form.tpl');
    } else {   
       // validate after a POST
       SmartyValidate::connect($smarty);
       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');
       }
    }

    ?>



Code:
<?
/**
 * validate_criteria.isUnique.php
 *
 * @author Yi Tang
 * @package SmartyValidate plugins
 * @copyright 2005
 * @version 1.0
 */
/**
 * test if a value is unique in for a column in specific table
 *
 * @param string $value the value being tested
 * @param boolean $empty if field can be empty
 * @param array params validate parameter values
 * @param array formvars form var values
 */
function smarty_validate_criteria_isUnique($value, $empty, &$params, &$formvars) {
    if( strlen($value) != 0 )
    {
       //clean up $params
       $value = addslashes( ereg_replace("[^a-zA-Z0-9*_.-\']", '', $value) );
       $params['field2'] = ereg_replace("[^a-zA-Z0-9*_.-\']", '', $params['field2']);
       $params['field3'] = ereg_replace("[^a-zA-Z0-9*_.-\']", '', $params['field3']);
       $params['field4'] = ereg_replace("[^a-zA-Z0-9*_.-\']", '', $params['field4']);
       $params['field5'] = ereg_replace("[^a-zA-Z0-9*_.-\']", '', $params['field5']);
       //addslashes if magic quotes is off
       if( !get_magic_quotes_gpc() )
       {
          $params['field2'] = addslashes( $params['field2'] );
          $params['field3'] = addslashes( $params['field3'] );
          $params['field4'] = addslashes( $params['field4'] );
          $params['field5'] = addslashes( $params['field5'] );
       }
       //check on required $params
       if( !empty( $params['field2'] ) && !empty( $params['field3'] ) )
       {
          $sql = 'SELECT '.$params['field3'].' FROM '.$params['field2']
                .' WHERE '.$params['field3'].' = \''.$value.'\'';
         //check if a primary key column and value are supplied for self-exclusive checking
         if( !empty( $params['field4'] ) && !empty( $params['field5'] ) )
         {
            $sql .= ' AND '.$params['field4'].' != \''.$params['field5'].'\'';
         }
         //run the query
          if( false != ( $result = mysql_query($sql) ) )
         {
         return !mysql_num_rows($result);
         }
         else
         {
         return false;
         }
       }
       else
       {
          trigger_error('Missing table and field');
       return false;
       }
    }
    else
    {
    return $empty;
    }
}
?>


Last edited by tangfucius on Fri Jun 10, 2005 5:44 pm; edited 1 time in total
Back to top
View user's profile Send private message
mohrt
Administrator


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

PostPosted: Fri Jun 10, 2005 2:51 pm    Post subject: Reply with quote

Nice addon tangfucius,

Of course you would write a SmartyValidate criteria to handle something like username uniqueness. SmartyValidate doesn't ship with one because of variety of requirements necessary. Your plugin handles the database/table/column name, but doesn't cover the situation where you want to test for a unique username other than the given users' username.

For instance, you edit a user profile and it tests if the username is taken. You don't want to include the username of that user in the validation test, so you need another column (like user id) to use for exclusion.

So basically, write yourself a criteria function that fits the bill Smile


Last edited by mohrt on Fri Jun 10, 2005 3:12 pm; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
tangfucius
Smarty Rookie


Joined: 30 Sep 2004
Posts: 16

PostPosted: Fri Jun 10, 2005 3:08 pm    Post subject: Reply with quote

very good point.
the plugin was written based on the situation where you do not allow change of usernames in a website, however as pointed out in the reply, this has some limitations. Nevertheless here goes the re-vision that does what mohrt suggested, just so that some users might make use of it.

sample usage:

Code:
<?php
    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)) {
        // new form, we (re)set the session data
        SmartyValidate::connect($smarty, true);
        // register our validators
       SmartyValidate::register_validator('username_isunique', 'username:users_table:username_column:optional_primary_key_column:optional_primary_key_value', 'isUnique', true);
        // display form
        $smarty->display('form.tpl');
    } else {   
       // validate after a POST
       SmartyValidate::connect($smarty);
       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');
       }
    }

    ?>



validate_criteria.isUnique.php:

Code:
<?
/**
 * validate_criteria.isUnique.php
 *
 * @author Yi Tang
 * @package SmartyValidate plugins
 * @copyright 2005
 * @version 1.0
 */
/**
 * test if a value is unique in for a column in specific table
 *
 * @param string $value the value being tested
 * @param boolean $empty if field can be empty
 * @param array params validate parameter values
 * @param array formvars form var values
 */
function smarty_validate_criteria_isUnique($value, $empty, &$params, &$formvars) {
    if( strlen($value) != 0 )
    {
       //check on required $params
       if( !empty( $params['field2'] ) && !empty( $params['field3'] ) )
       {
          $sql = 'SELECT * FROM '.$params['field2'].' WHERE '.$params['field3'].' = \''.$value.'\'';
         //check if a primary key column and value are supplied for self-exclusive checking
         if( !empty( $params['field4'] ) && !empty( $params['field5'] ) )
         {
            $sql .= ' AND '.$params['field4'].' != \''.$params['field5'].'\'';
         }
         //run the query
          if( false != ( $result = mysql_query($sql) ) )
         {
         return !mysql_num_rows($result);
         }
         else
         {
         return false;
         }
       }
       else
       {
          trigger_error('Missing table and field');
       return false;
       }
    }
    else
    {
    return $empty;
    }
}
?>

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


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

PostPosted: Fri Jun 10, 2005 3:16 pm    Post subject: Reply with quote

One more thing, you might want to think about SQL injection attacks, what if the username has a single quote?


[php:1:468fd03091]$sql = sprintf("SELECT * FROM %s where %s = '%s'",
preg_replace('!\W!','',$params['field2']),
preg_replace('!\W!','',$params['field3']),
mysql_escape_string($value));[/php:1:468fd03091]
Back to top
View user's profile Send private message Visit poster's website
tangfucius
Smarty Rookie


Joined: 30 Sep 2004
Posts: 16

PostPosted: Fri Jun 10, 2005 3:35 pm    Post subject: Reply with quote

good point again. However this plugin is used to validate uniqueness, not autheticate permissions, there is not much security involved. Single quotes,
good point, although usernames shouldn't allow single quotes to start with,
it's still a good point as I'm trying to make this plugin universal.

Three easy fixes for the two points mohrt pointed out,
changed "SELECT * FROM" to "SELECT ".$params['field3']." FROM"
--this way it only returns the column field being validated on no matter what,
even if there is sql injection, they get nothing but the column being validated against.
--strip out all possible injection attacks
--addslashes on all $params and $value

this goes the result, any suggestion welcome:

Code:
<?
/**
 * validate_criteria.isUnique.php
 *
 * @author Yi Tang
 * @package SmartyValidate plugins
 * @copyright 2005
 * @version 1.0
 */
/**
 * test if a value is unique in for a column in specific table
 *
 * @param string $value the value being tested
 * @param boolean $empty if field can be empty
 * @param array params validate parameter values
 * @param array formvars form var values
 */
function smarty_validate_criteria_isUnique($value, $empty, &$params, &$formvars) {
    if( strlen($value) != 0 )
    {
       //clean up $params
       $value = addslashes( ereg_replace("[^a-zA-Z0-9*_.-\']", '', $value) );
       $params['field2'] = addslashes( ereg_replace("[^a-zA-Z0-9*_.-\']", '', $params['field2']) );
       $params['field3'] = addslashes( ereg_replace("[^a-zA-Z0-9*_.-\']", '', $params['field3']) );
       $params['field4'] = addslashes( ereg_replace("[^a-zA-Z0-9*_.-\']", '', $params['field4']) );
       $params['field5'] = addslashes( ereg_replace("[^a-zA-Z0-9*_.-\']", '', $params['field5']) );
       //check on required $params
       if( !empty( $params['field2'] ) && !empty( $params['field3'] ) )
       {
          $sql = 'SELECT '.$params['field3'].' FROM '.$params['field2']
                .' WHERE '.$params['field3'].' = \''.$value.'\'';
         //check if a primary key column and value are supplied for self-exclusive checking
         if( !empty( $params['field4'] ) && !empty( $params['field5'] ) )
         {
            $sql .= ' AND '.$params['field4'].' != \''.$params['field5'].'\'';
         }
         //run the query
          if( false != ( $result = mysql_query($sql) ) )
         {
         return !mysql_num_rows($result);
         }
         else
         {
         return false;
         }
       }
       else
       {
          trigger_error('Missing table and field');
       return false;
       }
    }
    else
    {
    return $empty;
    }
}
?>
Back to top
View user's profile Send private message
Tanmaya
Smarty n00b


Joined: 26 Jun 2008
Posts: 1

PostPosted: Thu Jun 26, 2008 10:01 am    Post subject: isunique doubt Reply with quote

hiii
it was yet relif to see your code but i am getting some error
if you could plpz help me out in this :
SmartyValidate: [is_valid] criteria function 'isUnique' was not found. in W:\www\faceimage\libs\SmartyValidate.class.php on line 592

Code:

////testuuseexit.php/////////////
<form name="form1" method="post" action="testuuseexi.php">
  <table width="100%" border="0" cellspacing="0" cellpadding="0">
    <tr>
      <th scope="col">&nbsp;</th>
      <th scope="col">&nbsp;</th>
      <th scope="col">&nbsp;</th>
    </tr>
    <tr>
      <th scope="row">&nbsp;</th>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <th scope="row">username{validate id="username_isunique" message="<font color='#FF0000' size='-6'>Please enter your full name</font> "}</th>
      <td><input type="text" name="txtunm" id="txtunm"></td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <th scope="row">&nbsp;</th>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <th scope="row">&nbsp;</th>
      <td><input type="submit" name="btnsub" id="btnsub" value="Submit"></td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <th scope="row">&nbsp;</th>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <th scope="row">&nbsp;</th>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <th scope="row">&nbsp;</th>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
  </table>
</form>

////////testuuseexit.php/////
<?php
    session_start();

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

    require('libs/Smarty.class.php');
    require('libs/SmartyValidate.class.php');
   
    $smarty =& new Smarty;
   
    if(empty($_POST)) {
        // new form, we (re)set the session data
        SmartyValidate::connect($smarty, true);
        // register our validators
SmartyValidate::register_validator('username_isunique', 'txtunm:tbluser:username', 'isUnique', true);
        // display form
        $smarty->display('testuuseexit.tpl');
    } else {   
       // validate after a POST
       SmartyValidate::connect($smarty);
       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('testuuseexit.tpl');
       }
    }

    ?>





i think there may be some mistakes but i couldnot find it out

is there some thing to be changed in the SmartyValidate.php

As i am new to this smarty i could not figure it out
Thanks
Back to top
View user's profile Send private message
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