mirror of
https://github.com/e107inc/e107.git
synced 2025-08-01 12:20:44 +02:00
Start of generic user data validation, kill references to user_realm field
This commit is contained in:
378
e107_handlers/validator_class.php
Normal file
378
e107_handlers/validator_class.php
Normal file
@@ -0,0 +1,378 @@
|
||||
<?php
|
||||
/*
|
||||
* e107 website system
|
||||
*
|
||||
* Copyright (C) 2001-2008 e107 Inc (e107.org)
|
||||
* Released under the terms and conditions of the
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
|
||||
*
|
||||
* Handler - general purpose validation functions
|
||||
*
|
||||
* $Source: /cvs_backup/e107_0.8/e107_handlers/validator_class.php,v $
|
||||
* $Revision: 1.1 $
|
||||
* $Date: 2008-12-21 11:07:58 $
|
||||
* $Author: e107steved $
|
||||
*
|
||||
*/
|
||||
|
||||
// List of error numbers which may be returned from validation
|
||||
define('ERR_MISSING_VALUE','01');
|
||||
define('ERR_UNEXPECTED_VALUE','02');
|
||||
define('ERR_INVALID_CHARS', '03');
|
||||
define('ERR_TOO_SHORT', '04');
|
||||
define('ERR_TOO_LONG', '05');
|
||||
define('ERR_DUPLICATE', '06');
|
||||
define('ERR_DISALLOWED_TEXT', '07');
|
||||
define('ERR_FIELD_DISABLED', '08');
|
||||
define('ERR_INVALID_WORD', '09');
|
||||
define('ERR_PASSWORDS_DIFFERENT', '10');
|
||||
define('ERR_BANNED_EMAIL', '11');
|
||||
define('ERR_INVALID_EMAIL', '12');
|
||||
define('ERR_ARRAY_EXPECTED', '13');
|
||||
define('ERR_BANNED_USER', '14');
|
||||
define('ERR_FIELDS_DIFFERENT', '15');
|
||||
define('ERR_CODE_ERROR', '16');
|
||||
define('ERR_TOO_LOW', '17');
|
||||
define('ERR_TOO_HIGH', '18');
|
||||
|
||||
|
||||
/*
|
||||
The validator functions use an array of parameters for each variable to be validated.
|
||||
|
||||
The index of the parameter array is the destination field name.
|
||||
|
||||
Possible processing options:
|
||||
'srcname' - specifies the array index of the source data, where its different to the destination index
|
||||
'dbClean' - method for preparing the value to write to the DB (done as final step before returning). Options are:
|
||||
- 'toDB' - passes final value through $tp->toDB()
|
||||
- 'intval' - makes an integer
|
||||
'stripTags' - strips HTML tags from the value (not an error if there are some)
|
||||
'minLength' - minimum length (in utf-8 characters) for the string
|
||||
'maxLength' - minimum length (in utf-8 characters) for the string
|
||||
'minVal' - lowest allowed value for numerics
|
||||
'maxVal' - highest allowed value for numerics
|
||||
'longTrim' - if set, and the string exceeds maxLength, its trimmed
|
||||
'enablePref' - value is processed only if the named $pref evaluates to true; otherwise any input is discarded without error
|
||||
'dataType' - selects special processing methods:
|
||||
1 - array of numerics (e.g. class membership)
|
||||
|
||||
In general, only define an option if its to be used
|
||||
*/
|
||||
|
||||
|
||||
class validatorClass
|
||||
{
|
||||
// Passed an array of 'source' fields and an array of definitions to validate. The definition may include the name of a validation function.
|
||||
// Returns three arrays - one of validated results, one of failed fields and one of errors corresponding to the failed fields
|
||||
// Normally processes only those source fields it finds (and for which it has a definition). If $addDefaults is true, sets defaults for those that have
|
||||
// ...one and aren't otherwise defined.
|
||||
function validateFields(&$sourceFields, &$definitions, $addDefaults = FALSE)
|
||||
{
|
||||
global $tp, $pref;
|
||||
$ret = array('validate' => array(), 'failed' => array(), 'errors' => array());
|
||||
foreach ($definitions as $dest => $defs)
|
||||
{
|
||||
$errNum = 0; // Start with no error
|
||||
$src = varset($defs['srcName'],$dest); // Set source field name
|
||||
if (!isset($sourceFields[$src]))
|
||||
{
|
||||
if ($addDefaults)
|
||||
{
|
||||
if (isset($defs['default']))
|
||||
{
|
||||
$ret['validate'] = $defs['default']; // Set default value if one is specified
|
||||
} //...otherwise don't add the value at all
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret['errors'][$dest] = ERR_MISSING_VALUE; // No source value
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Got a field we want, and some data to validate here
|
||||
$value = $sourceFields[$src];
|
||||
if (!$errNum && isset($defs['enablePref']))
|
||||
{ // Only process this field if a specified pref enables it
|
||||
if (!varsettrue($pref[$options['enablePref']]))
|
||||
{
|
||||
continue; // Just loop to the next field - ignore this one.
|
||||
}
|
||||
}
|
||||
if (!$errNum && isset($defs['stripTags']))
|
||||
{
|
||||
$newValue = trim(strip_tags($value));
|
||||
if ($newValue <> $value)
|
||||
{
|
||||
$errNum = ERR_INVALID_CHARS;
|
||||
}
|
||||
$value = $newValue;
|
||||
}
|
||||
if (!$errNum && isset($defs['stripChars']))
|
||||
{
|
||||
$newValue = trim(preg_replace($defs['stripChars'], "", $value));
|
||||
if ($newValue <> $value)
|
||||
{
|
||||
$errNum = ERR_INVALID_CHARS;
|
||||
}
|
||||
$value = $newValue;
|
||||
}
|
||||
if (!$errNum && isset($defs['minLength']) && $tp->uStrLen($value) < $defs['minLength'])
|
||||
{
|
||||
if ($value == '')
|
||||
{
|
||||
$errNum = ERR_MISSING_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
$errNum = ERR_TOO_SHORT;
|
||||
}
|
||||
}
|
||||
if (!$errNum && isset($defs['maxLength']) && $tp->uStrLen($value) > $defs['maxLength'])
|
||||
{
|
||||
if (varsettrue($defs['longtrim']))
|
||||
{
|
||||
$value = substr($value,0,$defs['maxLength']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$errNum = ERR_TOO_LONG;
|
||||
}
|
||||
}
|
||||
if (!$errnum && isset($defs['minVal']) && ($value < $defs['minVal']))
|
||||
{
|
||||
$errNum = ERR_TOO_LOW;
|
||||
}
|
||||
if (!$errnum && isset($defs['maxVal']) && ($value < $defs['maxVal']))
|
||||
{
|
||||
$errNum = ERR_TOO_HIGH;
|
||||
}
|
||||
if (!$errNum && isset($defs['fixedBlock']))
|
||||
{
|
||||
$newValue = $tp->uStrToLower($value);
|
||||
$temp = explode(',',$defs['fixedBlock']);
|
||||
foreach ($temp as $t)
|
||||
{
|
||||
if ($newValue == $tp->uStrToLower($t))
|
||||
{
|
||||
$errNum = ERR_INVALID_WORD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$errNum && isset($defs['dataType']))
|
||||
{
|
||||
switch ($defs['dataType'])
|
||||
{
|
||||
case 1 : // Assumes we're passed an array variable to be turned into a comma-separated list of integers
|
||||
if (is_array($value))
|
||||
{
|
||||
$temp = array();
|
||||
foreach ($value as $v)
|
||||
{
|
||||
$temp[] = intval($v);
|
||||
}
|
||||
$value = implode(',',array_unique($temp));
|
||||
}
|
||||
else
|
||||
{
|
||||
$errNum = ERR_ARRAY_EXPECTED;
|
||||
}
|
||||
default :
|
||||
$errNum = ERR_CODE_ERROR; // Pick up bad values
|
||||
}
|
||||
}
|
||||
if (!$errNum)
|
||||
{
|
||||
if (isset($defs['dbClean']))
|
||||
{
|
||||
switch ($defs['dbClean'])
|
||||
{
|
||||
case 'toDB' :
|
||||
$value = $tp->toDB($value);
|
||||
break;
|
||||
case 'intval' :
|
||||
$value = intval($value);
|
||||
break;
|
||||
default :
|
||||
echo "Invalid dbClean method: {$defs['dbClean']}<br />"; // Debug message
|
||||
}
|
||||
}
|
||||
$ret['validate'][$dest] = $value; // Success!!
|
||||
}
|
||||
}
|
||||
if ($errNum)
|
||||
{ // error to report
|
||||
$ret['errors'][$dest] = $errNum;
|
||||
$ret['failed'][$dest] = $sourceFields[$src]; // Save value with error
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Validate data against a DB table
|
||||
// Inspects the passed array of user data (not necessarily containing all possible fields) and validates against the DB where appropriate.
|
||||
// Just skips over fields for which we don't have a validation routine without an error
|
||||
// The target array is as returned from validateFields(), so has 'validate', 'failed' and 'errors' first-level sub-arrays
|
||||
// All the 'vetting methods' begin 'vet', and don't overlap with validateFields(), so the same definition array may be used for both
|
||||
// Similarly, error numbers don't overlap with validateFields()
|
||||
// Typically checks for unacceptable duplicates, banned users etc
|
||||
// Any errors are reflected by updating the passed array.
|
||||
// Returns TRUE if all data validates, FALSE if any field fails to validate. Checks all fields which are present, regardless
|
||||
// For some things we need to know the user_id of the data being validated, so may return an error if that isn't specified
|
||||
|
||||
Parameters:
|
||||
'vetMethod' - see list below. To use more than one method, specify comma-separated
|
||||
'vetParam' - possible parameter for some vet methods
|
||||
|
||||
Valid 'vetMethod' values (use comma separated list for multiple vetting):
|
||||
0 - Null method
|
||||
1 - Check for duplicates - field name in table must be the same as array index unless 'dbFieldName' specifies otherwise
|
||||
2 - Check against the comma-separated wordlist in the $pref named in vetParam['signup_disallow_text']
|
||||
|
||||
*/
|
||||
function dbValidateArray(&$targetData, &$definitions, $targetTable, $userID = 0)
|
||||
{
|
||||
global $pref;
|
||||
$u_sql = new db;
|
||||
$allOK = TRUE;
|
||||
$userID = intval($userID); // Precautionary
|
||||
if (!$targetTable) return FALSE;
|
||||
foreach ($targetData['validate'] as $f => $v)
|
||||
{
|
||||
$errMsg = '';
|
||||
if (isset($definitions[$f]))
|
||||
{
|
||||
$options = $definitions[$f]; // Validation options to use
|
||||
if (isset($options['vetMethod']))
|
||||
{
|
||||
$toDo = explode(',',$options['vetMethod']);
|
||||
foreach ($toDo as $vm)
|
||||
{
|
||||
switch ($vm)
|
||||
{
|
||||
case 0 : // Shouldn't get this - just do nothing if we do
|
||||
break;
|
||||
case 1 : // Check for duplicates.
|
||||
if ($v == '')
|
||||
{
|
||||
$errMsg = ERR_MISSING_VALUE;
|
||||
break;
|
||||
}
|
||||
$field = varset($options['dbFieldName'],$f);
|
||||
if ($temp = $u_sql->db_Count($targetTable, "(*)", "WHERE `{$f}`='".$v."' AND `user_id` != ".$userID))
|
||||
{
|
||||
$errMsg = ERR_DUPLICATE;
|
||||
}
|
||||
// echo "Duplicate check: {$f} = {$v} Result: {$temp}<br />";
|
||||
break;
|
||||
case 2 : // Check against $pref
|
||||
if (isset($options['vetParam']) && isset($pref[$options['vetParam']]))
|
||||
{
|
||||
$tmp = explode(",", $pref[$options['vetParam']]);
|
||||
foreach($tmp as $disallow)
|
||||
{
|
||||
if(stristr($v, trim($disallow)))
|
||||
{
|
||||
$errMsg = ERR_DISALLOWED_TEXT;
|
||||
}
|
||||
}
|
||||
unset($tmp);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
echo 'Invalid vetMethod: '.$options['vetMethod'].'<br />'; // Really a debug aid - should never get here
|
||||
}
|
||||
if ($errMsg) { break; } // Just trap first error
|
||||
}
|
||||
// Add in other validation methods here
|
||||
}
|
||||
}
|
||||
if ($errMsg)
|
||||
{ // Update the error
|
||||
$targetData['errors'][$f] = $errMsg;
|
||||
$targetData['failed'][$f] = $v;
|
||||
unset($targetData['validate'][$f]); // Remove the valid entry
|
||||
$allOK = FALSE;
|
||||
}
|
||||
}
|
||||
return $allOK;
|
||||
}
|
||||
|
||||
|
||||
// Given a comma-separated string of required fields, and an array of data, adds an error message for each field which doesn't already have an entry.
|
||||
// Returns TRUE if no changes (which doesn't mean there are no errors - other routines may have found them). FALSE if new errors
|
||||
function checkMandatory($fieldList, &$target)
|
||||
{
|
||||
$fields = explode(',', $fieldList);
|
||||
$allOK = TRUE;
|
||||
foreach ($fields as $f)
|
||||
{
|
||||
if (!isset($target['validate'][$f]) && !isset($target['errors'][$f]))
|
||||
{
|
||||
$allOK = FALSE;
|
||||
$targetData['errors'][$f] = ERR_MISSING_VALUE;
|
||||
}
|
||||
}
|
||||
return $allOK;
|
||||
}
|
||||
|
||||
|
||||
// Given two arrays, returns an array of those elements in $input which are different from the corresponding element in $refs.
|
||||
// If $addMissing == TRUE, includes any element in $input for which there isn't a corresponding element in $refs
|
||||
function findChanges(&$input, &$refs, $addMissing = FALSE)
|
||||
{
|
||||
$ret = array();
|
||||
foreach ($input as $k => $v)
|
||||
{
|
||||
if (isset($refs[$k]))
|
||||
{
|
||||
if ($refs[$k] != $v) { $ret[$k] = $v; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($addMissing) { $ret[$k] = $v; }
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
// Given a vetted array of variables, generates a list of errors using the specified format string.
|
||||
// %n is the error number (as stored on the array)
|
||||
// %t is the corresponding error message, made by concatenating $constPrefix and the error number to form a constant (e.g. $constPrefix = 'USER_ERROR_')
|
||||
// %v calls up the entered value
|
||||
// %f is the field name
|
||||
// %x is the 'nice name' - possible if parameter list passed. Otherwise field name added
|
||||
// $EOL is inserted after all messages except the last.
|
||||
// If $EOL is an empty string, returns an array of messages.
|
||||
function makeErrorList($vars, $constPrefix, $format = '%n - %x %t: %v', $EOL = '<br />', $niceNames = NULL)
|
||||
{
|
||||
if (count($vars['errors']) == 0) return '';
|
||||
$eList = array();
|
||||
$checkNice = ($niceNames != NULL) && is_array($niceNames);
|
||||
foreach ($vars['errors'] as $f => $n)
|
||||
{
|
||||
$curLine = $format;
|
||||
$curLine = str_replace('%n', $n, $curLine);
|
||||
$curLine = str_replace('%t', constant($constPrefix.$n), $curLine);
|
||||
$curLine = str_replace('%v', $vars['failed'][$f],$curLine); // Possibly this should have some protection added
|
||||
$curLine = str_replace('%f', $f, $curLine);
|
||||
if ($checkNice & isset($niceNames[$f]['niceName']))
|
||||
{
|
||||
$curLine = str_replace('%x', $niceNames[$f]['niceName'], $curLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
$curLine = str_replace('%x', $f, $curLine); // Just use the field name
|
||||
}
|
||||
$eList[] = $curLine;
|
||||
}
|
||||
if ($EOL == '') return $eList;
|
||||
return implode($EOL, $eList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
Reference in New Issue
Block a user