Validator: support for array and object types, better handling of null valued columns
This commit is contained in:
parent
d1ed73c6d9
commit
a9ccd9dc1e
@ -131,6 +131,7 @@ class Doctrine_DBStatement extends PDOStatement {
|
||||
*/
|
||||
public function execute(array $params = null) {
|
||||
$time = microtime();
|
||||
|
||||
$result = parent::execute($params);
|
||||
|
||||
$exectime = (microtime() - $time);
|
||||
|
@ -41,6 +41,7 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
|
||||
Doctrine_Record::initNullObject($this->null);
|
||||
Doctrine_Collection::initNullObject($this->null);
|
||||
Doctrine_Record_Iterator::initNullObject($this->null);
|
||||
Doctrine_Validator::initNullObject($this->null);
|
||||
}
|
||||
/**
|
||||
* @return Doctrine_Null
|
||||
|
@ -98,8 +98,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
||||
*/
|
||||
private static $index = 1;
|
||||
/**
|
||||
* @var Doctrine_Null $nullObject a Doctrine_Null object used for extremely fast
|
||||
* SQL null value testing
|
||||
* @var Doctrine_Null $null a Doctrine_Null object used for extremely fast
|
||||
* null value testing
|
||||
*/
|
||||
private static $null;
|
||||
/**
|
||||
@ -208,10 +208,12 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
||||
* modifies data array
|
||||
* example:
|
||||
*
|
||||
* $data = array("name"=>"John","lastname"=> null,"id"=>1,"unknown"=>"unknown");
|
||||
* $names = array("name","lastname","id");
|
||||
* $data = array("name"=>"John","lastname"=> null, "id" => 1,"unknown" => "unknown");
|
||||
* $names = array("name", "lastname", "id");
|
||||
* $data after operation:
|
||||
* $data = array("name"=>"John","lastname" => array(),"id"=>1);
|
||||
* $data = array("name"=>"John","lastname" => Object(Doctrine_Null));
|
||||
*
|
||||
* here column 'id' is removed since its auto-incremented primary key (protected)
|
||||
*/
|
||||
private function cleanData() {
|
||||
$tmp = $this->data;
|
||||
@ -219,14 +221,21 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
||||
$this->data = array();
|
||||
|
||||
foreach($this->table->getColumnNames() as $name) {
|
||||
$type = $this->table->getTypeOf($name);
|
||||
|
||||
if( ! isset($tmp[$name])) {
|
||||
$this->data[$name] = self::$null;
|
||||
if($type == 'array') {
|
||||
$this->data[$name] = array();
|
||||
$this->modified[] = $name;
|
||||
} else
|
||||
$this->data[$name] = self::$null;
|
||||
} else {
|
||||
switch($this->table->getTypeOf($name)):
|
||||
switch($type):
|
||||
case "array":
|
||||
case "object":
|
||||
if($tmp[$name] !== self::$null)
|
||||
$this->data[$name] = unserialize($tmp[$name]);
|
||||
|
||||
break;
|
||||
default:
|
||||
$this->data[$name] = $tmp[$name];
|
||||
@ -235,8 +244,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
||||
}
|
||||
}
|
||||
/**
|
||||
* prepares identifiers
|
||||
* prepares identifiers for later use
|
||||
*
|
||||
* @param boolean $exists whether or not this record exists in persistent data store
|
||||
* @return void
|
||||
*/
|
||||
private function prepareIdentifiers($exists = true) {
|
||||
@ -706,9 +716,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
||||
|
||||
foreach($this->modified as $k => $v) {
|
||||
$type = $this->table->getTypeOf($v);
|
||||
|
||||
|
||||
if($type == 'array' ||
|
||||
$type == 'object') {
|
||||
$type == 'object') {
|
||||
|
||||
$a[$v] = serialize($this->data[$v]);
|
||||
continue;
|
||||
|
@ -747,7 +747,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
|
||||
* @return boolean
|
||||
*/
|
||||
private function update(Doctrine_Record $record) {
|
||||
$array = $record->getModified();
|
||||
$array = $record->getPrepared();
|
||||
|
||||
if(empty($array))
|
||||
return false;
|
||||
|
@ -31,7 +31,7 @@ class Doctrine_Validator {
|
||||
/**
|
||||
* constant for blank validation error
|
||||
*/
|
||||
const ERR_BLANK = 4;
|
||||
const ERR_NOTBLANK = 4;
|
||||
/**
|
||||
* constant for date validation error
|
||||
*/
|
||||
@ -39,7 +39,7 @@ class Doctrine_Validator {
|
||||
/**
|
||||
* constant for null validation error
|
||||
*/
|
||||
const ERR_NULL = 6;
|
||||
const ERR_NOTNULL = 6;
|
||||
/**
|
||||
* constant for enum validation error
|
||||
*/
|
||||
@ -53,13 +53,27 @@ class Doctrine_Validator {
|
||||
|
||||
|
||||
/**
|
||||
* @var array $stack error stack
|
||||
* @var array $stack error stack
|
||||
*/
|
||||
private $stack = array();
|
||||
/**
|
||||
* @var array $validators an array of validator objects
|
||||
* @var array $validators an array of validator objects
|
||||
*/
|
||||
private static $validators = array();
|
||||
/**
|
||||
* @var Doctrine_Null $null a Doctrine_Null object used for extremely fast
|
||||
* null value testing
|
||||
*/
|
||||
private static $null;
|
||||
/**
|
||||
* initNullObject
|
||||
*
|
||||
* @param Doctrine_Null $null
|
||||
* @return void
|
||||
*/
|
||||
public static function initNullObject(Doctrine_Null $null) {
|
||||
self::$null = $null;
|
||||
}
|
||||
/**
|
||||
* returns a validator object
|
||||
*
|
||||
@ -86,24 +100,35 @@ class Doctrine_Validator {
|
||||
* @return void
|
||||
*/
|
||||
public function validateRecord(Doctrine_Record $record) {
|
||||
$modified = $record->getModified();
|
||||
$columns = $record->getTable()->getColumns();
|
||||
$name = $record->getTable()->getComponentName();
|
||||
|
||||
switch($record->getState()):
|
||||
case Doctrine_Record::STATE_TDIRTY:
|
||||
case Doctrine_Record::STATE_TCLEAN:
|
||||
$data = $record->getData();
|
||||
break;
|
||||
default:
|
||||
$data = $record->getModified();
|
||||
endswitch;
|
||||
|
||||
$err = array();
|
||||
foreach($modified as $key => $value) {
|
||||
|
||||
foreach($data as $key => $value) {
|
||||
if($value === self::$null)
|
||||
$value = null;
|
||||
|
||||
$column = $columns[$key];
|
||||
|
||||
if($column[0] == 'array' || $column[0] == 'object') {
|
||||
$value = serialize($value);
|
||||
}
|
||||
|
||||
if(strlen($value) > $column[1]) {
|
||||
$err[$key] = Doctrine_Validator::ERR_LENGTH;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(self::gettype($value) !== $column[0]) {
|
||||
$err[$key] = Doctrine_Validator::ERR_TYPE;
|
||||
continue;
|
||||
}
|
||||
|
||||
$e = explode("|",$column[2]);
|
||||
|
||||
foreach($e as $k => $arg) {
|
||||
@ -116,28 +141,22 @@ class Doctrine_Validator {
|
||||
|
||||
$validator = self::getValidator($args[0]);
|
||||
if( ! $validator->validate($record, $key, $value, $args[1])) {
|
||||
switch(strtolower($args[0])):
|
||||
case "unique":
|
||||
$err[$key] = Doctrine_Validator::ERR_UNIQUE;
|
||||
break;
|
||||
case "notnull":
|
||||
$err[$key] = Doctrine_Validator::ERR_NULL;
|
||||
break;
|
||||
case "notblank":
|
||||
$err[$key] = Doctrine_Validator::ERR_BLANK;
|
||||
break;
|
||||
case "enum":
|
||||
$err[$key] = Doctrine_Validator::ERR_VALID;
|
||||
break;
|
||||
default:
|
||||
$err[$key] = Doctrine_Validator::ERR_VALID;
|
||||
break;
|
||||
endswitch;
|
||||
}
|
||||
|
||||
// errors found quit validation looping for this column
|
||||
if(isset($err[$key]))
|
||||
|
||||
$constant = 'Doctrine_Validator::ERR_'.strtoupper($args[0]);
|
||||
|
||||
if(defined($constant))
|
||||
$err[$key] = constant($constant);
|
||||
else
|
||||
$err[$key] = Doctrine_Validator::ERR_VALID;
|
||||
|
||||
// errors found quit validation looping for this column
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(self::gettype($value) !== $column[0] && self::gettype($value) != 'NULL') {
|
||||
$err[$key] = Doctrine_Validator::ERR_TYPE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,27 @@
|
||||
<?php
|
||||
class Doctrine_ValidatorTestCase extends Doctrine_UnitTestCase {
|
||||
public function prepareTables() {
|
||||
$this->tables[] = "Validator_Test";
|
||||
parent::prepareTables();
|
||||
}
|
||||
public function testValidate2() {
|
||||
$test = new Validator_Test();
|
||||
$test->mymixed = "message";
|
||||
|
||||
$validator = new Doctrine_Validator();
|
||||
$validator->validateRecord($test);
|
||||
|
||||
$stack = $validator->getErrorStack();
|
||||
|
||||
$this->assertTrue(is_array($stack));
|
||||
|
||||
$stack = $stack['Validator_Test'][0];
|
||||
$this->assertEqual($stack['mystring'], Doctrine_Validator::ERR_NOTNULL);
|
||||
|
||||
$test->mystring = 'str';
|
||||
|
||||
$test->save();
|
||||
}
|
||||
|
||||
public function testValidate() {
|
||||
$user = $this->session->getTable("User")->find(4);
|
||||
@ -71,6 +93,5 @@ class Doctrine_ValidatorTestCase extends Doctrine_UnitTestCase {
|
||||
$this->assertEqual($a["User"][0]["name"], Doctrine_Validator::ERR_LENGTH);
|
||||
$this->manager->setAttribute(Doctrine::ATTR_VLD, false);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
@ -313,4 +313,13 @@ class Log_Status extends Doctrine_Record {
|
||||
$this->hasColumn("name", "string", 255);
|
||||
}
|
||||
}
|
||||
class Validator_Test extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn("mymixed","string", 100);
|
||||
$this->hasColumn("mystring","string", 100, "notnull|unique");
|
||||
$this->hasColumn("myarray", "array", 1000);
|
||||
$this->hasColumn("myobject", "object", 1000);
|
||||
$this->hasColumn("myinteger", "integer", 11);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -15,7 +15,6 @@ require_once("CollectionTestCase.php");
|
||||
|
||||
require_once("CacheSqliteTestCase.php");
|
||||
require_once("CollectionOffsetTestCase.php");
|
||||
require_once("SenseiTestCase.php");
|
||||
require_once("QueryTestCase.php");
|
||||
|
||||
error_reporting(E_ALL);
|
||||
|
Loading…
x
Reference in New Issue
Block a user