dblayeroo : Add the "realTypes" support with basic associated tests. If the user want some custom tests, it must extends the class and create checkRealType_XXX tests
git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@4621 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
This commit is contained in:
358
dblayeroo.php
358
dblayeroo.php
@@ -1,7 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
/** DomFramework
|
/** DomFramework
|
||||||
@package domframework
|
* @package domframework
|
||||||
@author Dominique Fournier <dominique@fournier38.fr> */
|
* @author Dominique Fournier <dominique@fournier38.fr>
|
||||||
|
*/
|
||||||
|
|
||||||
// dblayeroo.php
|
// dblayeroo.php
|
||||||
|
|
||||||
@@ -42,6 +43,12 @@ class dblayeroo
|
|||||||
/** Titles
|
/** Titles
|
||||||
*/
|
*/
|
||||||
private $titles = array ();
|
private $titles = array ();
|
||||||
|
/** The real types of each fields. The real types are different of the SQL
|
||||||
|
* types : a "mail" type is stored in a "VARCHAR(255)" in SQL.
|
||||||
|
* The real types are optional : if not set, there is no check.
|
||||||
|
* They are more strict than the SQL types
|
||||||
|
*/
|
||||||
|
private $realTypes = array ();
|
||||||
|
|
||||||
/** Limit to one instance of the connection to the same database
|
/** Limit to one instance of the connection to the same database
|
||||||
*/
|
*/
|
||||||
@@ -149,7 +156,7 @@ class dblayeroo
|
|||||||
$this->DBException ("No Database provided in DSN");
|
$this->DBException ("No Database provided in DSN");
|
||||||
// Force the GROUP_CONCAT value max to the max allowed from the server
|
// Force the GROUP_CONCAT value max to the max allowed from the server
|
||||||
$st = self::$instance[$this->dsn]->query (
|
$st = self::$instance[$this->dsn]->query (
|
||||||
"SHOW VARIABLES LIKE 'max_allowed_packet'", PDO::FETCH_COLUMN, 1);
|
"SHOW VARIABLES LIKE 'max_allowed_packet'", \PDO::FETCH_COLUMN, 1);
|
||||||
$rows = $st->fetchAll ();
|
$rows = $st->fetchAll ();
|
||||||
if (! isset ($rows[0]))
|
if (! isset ($rows[0]))
|
||||||
throw new \Exception (
|
throw new \Exception (
|
||||||
@@ -1332,6 +1339,43 @@ class dblayeroo
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/** Define a real type array
|
||||||
|
* Must be array ("field" => "realtype")
|
||||||
|
* @param array $realTypes The realTypes to set
|
||||||
|
* The allowed real types are defined in test method :
|
||||||
|
* checkRealType_TYPE ($val, $definition)
|
||||||
|
* The allowed real types are : mail, date, datetime, allowedchars(a23d),
|
||||||
|
* uuid, time, array('val1','val2','val3'), regex(/^[a-zA-Z]{3,}$/i)
|
||||||
|
* integer, integerPositive,
|
||||||
|
* To be done :
|
||||||
|
* integerNegative,
|
||||||
|
* php_function(), function($val) { if ($val > 0) return "MESSAGE";}
|
||||||
|
*/
|
||||||
|
public function realTypes ($realTypes = null)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
if ($realTypes === null)
|
||||||
|
return $this->realTypes;
|
||||||
|
if (! is_array ($realTypes))
|
||||||
|
$this->DBException ("Invalid setRealType provided : not an array", 500);
|
||||||
|
foreach ($realTypes as $field => $realType)
|
||||||
|
{
|
||||||
|
if (! key_exists ($field, $this->fields))
|
||||||
|
$this->DBException ("Invalid setRealType provided : ".
|
||||||
|
"field '$field' doesn't exists");
|
||||||
|
list ($func, $param) = explode ("(", $realType);
|
||||||
|
$func = trim ($func);
|
||||||
|
$method = "checkRealType_".$func;
|
||||||
|
if (! method_exists ($this, $method))
|
||||||
|
$this->DBException ("Invalid setRealType provided : ".
|
||||||
|
"field '$field' : unknown realType provided '$func'");
|
||||||
|
}
|
||||||
|
$this->realTypes = $realTypes;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
/// MANAGE THE REQUEST BY OOP ///
|
/// MANAGE THE REQUEST BY OOP ///
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
@@ -2846,6 +2890,9 @@ class dblayeroo
|
|||||||
$this->debugLog ("Entering checkValues (",$update,")");
|
$this->debugLog ("Entering checkValues (",$update,")");
|
||||||
$update = !! $update;
|
$update = !! $update;
|
||||||
$values = $this->setValues;
|
$values = $this->setValues;
|
||||||
|
$errors = $this->checkRealType ($values, $update);
|
||||||
|
if (count ($errors))
|
||||||
|
$this->DBException (reset ($errors));
|
||||||
$errors = $this->verify ($values, $update);
|
$errors = $this->verify ($values, $update);
|
||||||
if (count ($errors))
|
if (count ($errors))
|
||||||
$this->DBException (reset ($errors));
|
$this->DBException (reset ($errors));
|
||||||
@@ -2853,6 +2900,60 @@ class dblayeroo
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/** Check the types of the data against the realTypes
|
||||||
|
* Return an array with the field name in error and a message
|
||||||
|
* If allowEmpty is set, do not test the "NOT NULL" feature
|
||||||
|
* In UPDATE, the values don't need be not set : they are already in database
|
||||||
|
* so $allowEmpty is true
|
||||||
|
* @param array $values The values to test
|
||||||
|
* @param boolean|null $allowEmpty Allow the "not null" to not be set
|
||||||
|
* @return array empty array if no error
|
||||||
|
*/
|
||||||
|
public function checkRealType ($values, $allowEmpty = false)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
$this->debugLog ("Entering checkRealType (",$values,",",$allowEmpty,")");
|
||||||
|
if (! is_array ($values))
|
||||||
|
$this->DBException ("Invalid checkRealType provided : not an array", 500);
|
||||||
|
$errors = array ();
|
||||||
|
foreach ($this->fields as $field => $params)
|
||||||
|
{
|
||||||
|
if (! key_exists ($field, $values) || trim ($values[$field]) === "")
|
||||||
|
{
|
||||||
|
if (in_array ("not null", $params) &&
|
||||||
|
! in_array ("autoincrement", $params))
|
||||||
|
{
|
||||||
|
if ($allowEmpty === false)
|
||||||
|
$errors[$field] = dgettext ("domframework",
|
||||||
|
"The field can not be empty");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Empty value is not tested and do not generate an error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif (! is_string ($values[$field]))
|
||||||
|
{
|
||||||
|
$errors[$field] = dgettext ("domframework",
|
||||||
|
"The value is not a string");
|
||||||
|
}
|
||||||
|
elseif (key_exists ($field, $this->realTypes))
|
||||||
|
{
|
||||||
|
$val = trim ($values[$field]);
|
||||||
|
list ($func, $param) = explode ("(", $this->realTypes[$field]);
|
||||||
|
$func = trim ($func);
|
||||||
|
$method = "checkRealType_".$func;
|
||||||
|
$res = $this->$method ($val, $this->realTypes[$field]);
|
||||||
|
if (is_string ($res))
|
||||||
|
$errors[$field] = $res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->debugLog ("End checkRealType (", $values, ",", $allowEmpty, ") : ",
|
||||||
|
$errors);
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
/** Execute the pre-defined query
|
/** Execute the pre-defined query
|
||||||
* Return the content array if SELECT command is choosed
|
* Return the content array if SELECT command is choosed
|
||||||
* Return the Last ID if INSERT command is choosed
|
* Return the Last ID if INSERT command is choosed
|
||||||
@@ -3083,4 +3184,255 @@ class dblayeroo
|
|||||||
echo "\n";
|
echo "\n";
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
//////////////////////////////////////////////
|
||||||
|
//// ALL THE CHECK REALTYPES METHODS ////
|
||||||
|
//////////////////////////////////////////////
|
||||||
|
// {{{
|
||||||
|
/** Check the type "integerPositive"
|
||||||
|
* @param string $val The value to check
|
||||||
|
* @param string $definition The definition of the type
|
||||||
|
* @return string or null
|
||||||
|
*/
|
||||||
|
private function checkRealType_integerPositive ($val, $definition)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
if (substr ($val, 0, 1) === "-")
|
||||||
|
return dgettext ("domframework", "Invalid positive integer : ".
|
||||||
|
"can not start by minus sign");
|
||||||
|
if (strspn ($val, "0123456789") !== strlen ($val))
|
||||||
|
return dgettext ("domframework", "Invalid positive integer : ".
|
||||||
|
"invalid char");
|
||||||
|
if (substr ($val, 0, 1) === "0" && $val !== "0")
|
||||||
|
return dgettext ("domframework", "Invalid positive integer : ".
|
||||||
|
"can not start by Zero");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
/** Check the type "integer"
|
||||||
|
* @param string $val The value to check
|
||||||
|
* @param string $definition The definition of the type
|
||||||
|
* @return string or null
|
||||||
|
*/
|
||||||
|
private function checkRealType_integer ($val, $definition)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
if (strspn ($val, "0123456789-") !== strlen ($val))
|
||||||
|
return dgettext ("domframework", "Invalid integer : ".
|
||||||
|
"invalid char");
|
||||||
|
if (substr ($val, 0, 1) === "0" && $val !== "0")
|
||||||
|
return dgettext ("domframework", "Invalid integer : ".
|
||||||
|
"can not start by Zero");
|
||||||
|
if (substr ($val, 0, 2) === "-0")
|
||||||
|
return dgettext ("domframework", "Invalid integer : ".
|
||||||
|
"can not start by Minus Zero");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
/** Check the type "allowedchars"
|
||||||
|
* the chars must be in UTF-8
|
||||||
|
* @param string $val The value to check
|
||||||
|
* @param string $definition The definition of the type
|
||||||
|
* @return string or null
|
||||||
|
*/
|
||||||
|
private function checkRealType_allowedchars ($val, $definition)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
list ($func, $param) = explode ("(", $definition);
|
||||||
|
if ($param === null)
|
||||||
|
$this->DBException ("Invalid allowedchars definied : ".
|
||||||
|
"must have a starting parenthesis");
|
||||||
|
if (substr ($param, -1) !== ")")
|
||||||
|
$this->DBException ("Invalid allowedchars definied : ".
|
||||||
|
"must have a ending parenthesis");
|
||||||
|
$allowedChars = mb_substr ($param, 0, -1);
|
||||||
|
$allowedChars = preg_quote ($allowedChars, "#");
|
||||||
|
preg_match ('#^['.$allowedChars.']+#u', $val, $matches);
|
||||||
|
if (isset ($matches[0]) &&
|
||||||
|
mb_strlen ($matches[0]) === mb_strlen ($val))
|
||||||
|
return;
|
||||||
|
return dgettext ("domframework", "Invalid char provided");
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
/** Check the type "array"
|
||||||
|
* @param string $val The value to check
|
||||||
|
* @param string $definition The definition of the type
|
||||||
|
* @return string or null
|
||||||
|
*/
|
||||||
|
private function checkRealType_array ($val, $definition)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
list ($func, $param) = explode ("(", $definition);
|
||||||
|
if ($param === null)
|
||||||
|
$this->DBException ("Invalid array definied : ".
|
||||||
|
"must have a starting parenthesis");
|
||||||
|
if (substr ($param, -1) !== ")")
|
||||||
|
$this->DBException ("Invalid array definied : ".
|
||||||
|
"must have a ending parenthesis");
|
||||||
|
$param = mb_substr ($param, 0, -1);
|
||||||
|
$array = explode (",", $param);
|
||||||
|
foreach ($array as $key => $tmp)
|
||||||
|
{
|
||||||
|
$array[$key] = mb_substr ($tmp, 1, -1);
|
||||||
|
}
|
||||||
|
if (in_array ($val, $array))
|
||||||
|
return;
|
||||||
|
return dgettext ("domframework", "Invalid value provided : ".
|
||||||
|
"not in allowed list");
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
/** Check the type "regex"
|
||||||
|
* Do not forget to add the separators, the ^ and $
|
||||||
|
* @param string $val The value to check
|
||||||
|
* @param string $definition The definition of the type
|
||||||
|
* @return string or null
|
||||||
|
*/
|
||||||
|
private function checkRealType_regex ($val, $definition)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
list ($func, $param) = explode ("(", $definition);
|
||||||
|
if ($param === null)
|
||||||
|
$this->DBException ("Invalid regex definied : ".
|
||||||
|
"must have a starting parenthesis");
|
||||||
|
if (substr ($param, -1) !== ")")
|
||||||
|
$this->DBException ("Invalid regex definied : ".
|
||||||
|
"must have a ending parenthesis");
|
||||||
|
$param = mb_substr ($param, 0, -1);
|
||||||
|
if (@preg_match ($param, $val) === false)
|
||||||
|
$this->DBException ("Invalid regex definied : ".
|
||||||
|
"must have a ending parenthesis");
|
||||||
|
if (preg_match ($param, $val))
|
||||||
|
return;
|
||||||
|
return dgettext ("domframework", "Invalid value provided : ".
|
||||||
|
"do not match the regex");
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
/** Check the type "mail"
|
||||||
|
* @param string $val The value to check
|
||||||
|
* @param string $definition The definition of the type
|
||||||
|
* @return string or null
|
||||||
|
*/
|
||||||
|
private function checkRealType_mail ($val, $definition)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
if (!! filter_var ($val, FILTER_VALIDATE_EMAIL))
|
||||||
|
return;
|
||||||
|
return dgettext ("domframework", "Invalid mail provided");
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
/** Check the type "uuid"
|
||||||
|
* @param string $val The value to check
|
||||||
|
* @param string $definition The definition of the type
|
||||||
|
* @return string or null
|
||||||
|
*/
|
||||||
|
private function checkRealType_uuid ($val, $definition)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
if (strlen ($val) !== 36)
|
||||||
|
return dgettext ("domframework", "Invalid UUID provided : ".
|
||||||
|
"invalid length");
|
||||||
|
if (strspn ($val, "0123456789abcdefABCDEF-") !== strlen ($val))
|
||||||
|
return dgettext ("domframework", "Invalid UUID provided : invalid char");
|
||||||
|
if ($val[8] !== "-" || $val[13] !== "-" || $val[18] !== "-" ||
|
||||||
|
$val[23] !== "-")
|
||||||
|
return dgettext ("domframework", "Invalid UUID provided : missing dash");
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
/** Check the type "sqldate"
|
||||||
|
* @param string $val The value to check
|
||||||
|
* @param string $definition The definition of the type
|
||||||
|
* @return string or null
|
||||||
|
*/
|
||||||
|
private function checkRealType_sqldate ($val, $definition)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
if (strlen ($val) !== 10)
|
||||||
|
return dgettext ("domframework", "Invalid date provided : ".
|
||||||
|
"invalid length");
|
||||||
|
if (strspn ($val, "0123456789-") !== strlen ($val))
|
||||||
|
return dgettext ("domframework", "Invalid date provided : ".
|
||||||
|
"invalid chars");
|
||||||
|
$arr = \date_parse ($val);
|
||||||
|
if ($arr["warning_count"] !== 0)
|
||||||
|
return dgettext ("domframework", "Invalid date provided : ".
|
||||||
|
"can not parse the date");
|
||||||
|
if ($arr["error_count"] !== 0)
|
||||||
|
return dgettext ("domframework", "Invalid date provided : ".
|
||||||
|
"can not parse the date");
|
||||||
|
if (isset ($arr["tz_abbr"]))
|
||||||
|
return dgettext ("domframework", "Invalid date provided : ".
|
||||||
|
"can not parse the date");
|
||||||
|
if (\DateTime::createFromFormat("Y-m-d", $val) === false)
|
||||||
|
return dgettext ("domframework", "Invalid date provided : ".
|
||||||
|
"the date doesn't exists");
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
/** Check the type "sqltime"
|
||||||
|
* @param string $val The value to check
|
||||||
|
* @param string $definition The definition of the type
|
||||||
|
* @return string or null
|
||||||
|
*/
|
||||||
|
private function checkRealType_sqltime ($val, $definition)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
if (strlen ($val) !== 8)
|
||||||
|
return dgettext ("domframework", "Invalid time provided : ".
|
||||||
|
"invalid length");
|
||||||
|
if (strspn ($val, "0123456789:") !== strlen ($val))
|
||||||
|
return dgettext ("domframework", "Invalid time provided : ".
|
||||||
|
"invalid chars");
|
||||||
|
$arr = \date_parse ($val);
|
||||||
|
if ($arr["warning_count"] !== 0)
|
||||||
|
return dgettext ("domframework", "Invalid time provided : ".
|
||||||
|
"can not parse the time");
|
||||||
|
if ($arr["error_count"] !== 0)
|
||||||
|
return dgettext ("domframework", "Invalid time provided : ".
|
||||||
|
"can not parse the time");
|
||||||
|
if (isset ($arr["tz_abbr"]))
|
||||||
|
return dgettext ("domframework", "Invalid time provided : ".
|
||||||
|
"can not parse the date");
|
||||||
|
if (\DateTime::createFromFormat("H:i:s", $val) === false)
|
||||||
|
return dgettext ("domframework", "Invalid time provided : ".
|
||||||
|
"the time doesn't exists");
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
/** Check the type "sqldatetime"
|
||||||
|
* @param string $val The value to check
|
||||||
|
* @param string $definition The definition of the type
|
||||||
|
* @return string or null
|
||||||
|
*/
|
||||||
|
private function checkRealType_sqldatetime ($val, $definition)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
if (strlen ($val) !== 19)
|
||||||
|
return dgettext ("domframework", "Invalid date and time provided : ".
|
||||||
|
"invalid length");
|
||||||
|
if (strspn ($val, "0123456789 :-") !== strlen ($val))
|
||||||
|
return dgettext ("domframework", "Invalid date and time provided : ".
|
||||||
|
"invalid chars");
|
||||||
|
$arr = \date_parse ($val);
|
||||||
|
if ($arr["warning_count"] !== 0)
|
||||||
|
return dgettext ("domframework", "Invalid date and time provided : ".
|
||||||
|
"can not parse the date");
|
||||||
|
if ($arr["error_count"] !== 0)
|
||||||
|
return dgettext ("domframework", "Invalid date and time provided : ".
|
||||||
|
"can not parse the date");
|
||||||
|
if (isset ($arr["tz_abbr"]))
|
||||||
|
return dgettext ("domframework", "Invalid date and time provided : ".
|
||||||
|
"can not parse the date");
|
||||||
|
if (\DateTime::createFromFormat("Y-m-d H:i:s", $val) === false)
|
||||||
|
return dgettext ("domframework", "Invalid date and time provided : ".
|
||||||
|
"the date doesn't exists");
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
// }}}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user