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:
384
dblayeroo.php
384
dblayeroo.php
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
/** DomFramework
|
||||
@package domframework
|
||||
@author Dominique Fournier <dominique@fournier38.fr> */
|
||||
* @package domframework
|
||||
* @author Dominique Fournier <dominique@fournier38.fr>
|
||||
*/
|
||||
|
||||
// dblayeroo.php
|
||||
|
||||
@@ -42,6 +43,12 @@ class dblayeroo
|
||||
/** Titles
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@@ -55,8 +62,8 @@ class dblayeroo
|
||||
* @param string|null $password Password to connect
|
||||
* @param string|null $driver_options Driver options to the database
|
||||
*/
|
||||
public function __construct ($dsn, $username=null, $password=null,
|
||||
$driver_options=null)
|
||||
public function __construct ($dsn, $username = null, $password = null,
|
||||
$driver_options = null)
|
||||
{
|
||||
$this->connect ($dsn, $username, $password, $driver_options);
|
||||
}
|
||||
@@ -68,8 +75,8 @@ class dblayeroo
|
||||
* @param string|null $password Password to connect
|
||||
* @param string|null $driver_options Driver options to the database
|
||||
*/
|
||||
public function connect ($dsn, $username=null, $password=null,
|
||||
$driver_options=null)
|
||||
public function connect ($dsn, $username = null, $password = null,
|
||||
$driver_options = null)
|
||||
/* {{{ */
|
||||
{
|
||||
if (! function_exists ("mb_strlen"))
|
||||
@@ -149,7 +156,7 @@ class dblayeroo
|
||||
$this->DBException ("No Database provided in DSN");
|
||||
// Force the GROUP_CONCAT value max to the max allowed from the server
|
||||
$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 ();
|
||||
if (! isset ($rows[0]))
|
||||
throw new \Exception (
|
||||
@@ -980,7 +987,7 @@ class dblayeroo
|
||||
/** Get/Set the table property
|
||||
* @param string|null $table The table to use
|
||||
*/
|
||||
public function table ($table=null)
|
||||
public function table ($table = null)
|
||||
/* {{{ */
|
||||
{
|
||||
$this->debugLog ("Entering table (",$table,")");
|
||||
@@ -998,7 +1005,7 @@ class dblayeroo
|
||||
/** Get/Set the tableprefix property
|
||||
* @param string|null $tableprefix The prefix to append
|
||||
*/
|
||||
public function tableprefix ($tableprefix=null)
|
||||
public function tableprefix ($tableprefix = null)
|
||||
/* {{{ */
|
||||
{
|
||||
$this->debugLog ("Entering tableprefix (",$tableprefix,")");
|
||||
@@ -1019,7 +1026,7 @@ class dblayeroo
|
||||
* array ("fieldName"=>array ("type"[, "not null"[, "autoincrement"]]))
|
||||
* @param array|null $fields The fields to define
|
||||
*/
|
||||
public function fields ($fields=null)
|
||||
public function fields ($fields = null)
|
||||
/* {{{ */
|
||||
{
|
||||
$this->debugLog ("Entering fields (VALUE)");
|
||||
@@ -1105,7 +1112,7 @@ class dblayeroo
|
||||
/** Get/Set the primary property
|
||||
* @param string|null $primary The primary key to use
|
||||
*/
|
||||
public function primary ($primary=null)
|
||||
public function primary ($primary = null)
|
||||
/* {{{ */
|
||||
{
|
||||
$this->debugLog ("Entering primary (",$primary,")");
|
||||
@@ -1125,7 +1132,7 @@ class dblayeroo
|
||||
/** Get/Set the unique property
|
||||
* @param array|null $unique The unique fields constraint to add
|
||||
*/
|
||||
public function unique ($unique=null)
|
||||
public function unique ($unique = null)
|
||||
/* {{{ */
|
||||
{
|
||||
$this->debugLog ("Entering unique (VALUE)");
|
||||
@@ -1171,7 +1178,7 @@ class dblayeroo
|
||||
* )
|
||||
* Multiple field and parnentField can be provided, separated by comma
|
||||
*/
|
||||
public function foreign ($foreign=null)
|
||||
public function foreign ($foreign = null)
|
||||
/* {{{ */
|
||||
{
|
||||
$this->debugLog ("Entering foreign (VALUE)");
|
||||
@@ -1232,7 +1239,7 @@ class dblayeroo
|
||||
/** Get/Set the debug property
|
||||
* @param integer|null $debug Set the debug value
|
||||
*/
|
||||
public function debug ($debug=null)
|
||||
public function debug ($debug = null)
|
||||
/* {{{ */
|
||||
{
|
||||
$this->debugLog ("Entering debug (",$debug,")");
|
||||
@@ -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 ///
|
||||
/////////////////////////////////////
|
||||
@@ -2138,7 +2182,7 @@ class dblayeroo
|
||||
* If the parameter $full is set, add the table prefix/name to the result
|
||||
* @param boolean|null $full Add the table prefix/name if set
|
||||
*/
|
||||
public function orderGet ($full=false)
|
||||
public function orderGet ($full = false)
|
||||
/* {{{ */
|
||||
{
|
||||
$order = array ();
|
||||
@@ -2189,7 +2233,7 @@ class dblayeroo
|
||||
* If the parameter $full is set, add the table prefix/name to the result
|
||||
* @param boolean|null $full Add the table prefix/name if set
|
||||
*/
|
||||
public function groupByGet ($full=false)
|
||||
public function groupByGet ($full = false)
|
||||
/* {{{ */
|
||||
{
|
||||
if ($this->joinObject)
|
||||
@@ -2846,6 +2890,9 @@ class dblayeroo
|
||||
$this->debugLog ("Entering checkValues (",$update,")");
|
||||
$update = !! $update;
|
||||
$values = $this->setValues;
|
||||
$errors = $this->checkRealType ($values, $update);
|
||||
if (count ($errors))
|
||||
$this->DBException (reset ($errors));
|
||||
$errors = $this->verify ($values, $update);
|
||||
if (count ($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
|
||||
* Return the content array if SELECT command is choosed
|
||||
* Return the Last ID if INSERT command is choosed
|
||||
@@ -3083,4 +3184,255 @@ class dblayeroo
|
||||
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