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) {
|
public function execute(array $params = null) {
|
||||||
$time = microtime();
|
$time = microtime();
|
||||||
|
|
||||||
$result = parent::execute($params);
|
$result = parent::execute($params);
|
||||||
|
|
||||||
$exectime = (microtime() - $time);
|
$exectime = (microtime() - $time);
|
||||||
|
@ -41,6 +41,7 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
|
|||||||
Doctrine_Record::initNullObject($this->null);
|
Doctrine_Record::initNullObject($this->null);
|
||||||
Doctrine_Collection::initNullObject($this->null);
|
Doctrine_Collection::initNullObject($this->null);
|
||||||
Doctrine_Record_Iterator::initNullObject($this->null);
|
Doctrine_Record_Iterator::initNullObject($this->null);
|
||||||
|
Doctrine_Validator::initNullObject($this->null);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @return Doctrine_Null
|
* @return Doctrine_Null
|
||||||
|
@ -98,8 +98,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
|||||||
*/
|
*/
|
||||||
private static $index = 1;
|
private static $index = 1;
|
||||||
/**
|
/**
|
||||||
* @var Doctrine_Null $nullObject a Doctrine_Null object used for extremely fast
|
* @var Doctrine_Null $null a Doctrine_Null object used for extremely fast
|
||||||
* SQL null value testing
|
* null value testing
|
||||||
*/
|
*/
|
||||||
private static $null;
|
private static $null;
|
||||||
/**
|
/**
|
||||||
@ -208,10 +208,12 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
|||||||
* modifies data array
|
* modifies data array
|
||||||
* example:
|
* example:
|
||||||
*
|
*
|
||||||
* $data = array("name"=>"John","lastname"=> null,"id"=>1,"unknown"=>"unknown");
|
* $data = array("name"=>"John","lastname"=> null, "id" => 1,"unknown" => "unknown");
|
||||||
* $names = array("name","lastname","id");
|
* $names = array("name", "lastname", "id");
|
||||||
* $data after operation:
|
* $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() {
|
private function cleanData() {
|
||||||
$tmp = $this->data;
|
$tmp = $this->data;
|
||||||
@ -219,14 +221,21 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
|||||||
$this->data = array();
|
$this->data = array();
|
||||||
|
|
||||||
foreach($this->table->getColumnNames() as $name) {
|
foreach($this->table->getColumnNames() as $name) {
|
||||||
|
$type = $this->table->getTypeOf($name);
|
||||||
|
|
||||||
if( ! isset($tmp[$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 {
|
} else {
|
||||||
switch($this->table->getTypeOf($name)):
|
switch($type):
|
||||||
case "array":
|
case "array":
|
||||||
case "object":
|
case "object":
|
||||||
if($tmp[$name] !== self::$null)
|
if($tmp[$name] !== self::$null)
|
||||||
$this->data[$name] = unserialize($tmp[$name]);
|
$this->data[$name] = unserialize($tmp[$name]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$this->data[$name] = $tmp[$name];
|
$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
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function prepareIdentifiers($exists = true) {
|
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) {
|
foreach($this->modified as $k => $v) {
|
||||||
$type = $this->table->getTypeOf($v);
|
$type = $this->table->getTypeOf($v);
|
||||||
|
|
||||||
if($type == 'array' ||
|
if($type == 'array' ||
|
||||||
$type == 'object') {
|
$type == 'object') {
|
||||||
|
|
||||||
$a[$v] = serialize($this->data[$v]);
|
$a[$v] = serialize($this->data[$v]);
|
||||||
continue;
|
continue;
|
||||||
|
@ -747,7 +747,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
|
|||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
private function update(Doctrine_Record $record) {
|
private function update(Doctrine_Record $record) {
|
||||||
$array = $record->getModified();
|
$array = $record->getPrepared();
|
||||||
|
|
||||||
if(empty($array))
|
if(empty($array))
|
||||||
return false;
|
return false;
|
||||||
|
@ -31,7 +31,7 @@ class Doctrine_Validator {
|
|||||||
/**
|
/**
|
||||||
* constant for blank validation error
|
* constant for blank validation error
|
||||||
*/
|
*/
|
||||||
const ERR_BLANK = 4;
|
const ERR_NOTBLANK = 4;
|
||||||
/**
|
/**
|
||||||
* constant for date validation error
|
* constant for date validation error
|
||||||
*/
|
*/
|
||||||
@ -39,7 +39,7 @@ class Doctrine_Validator {
|
|||||||
/**
|
/**
|
||||||
* constant for null validation error
|
* constant for null validation error
|
||||||
*/
|
*/
|
||||||
const ERR_NULL = 6;
|
const ERR_NOTNULL = 6;
|
||||||
/**
|
/**
|
||||||
* constant for enum validation error
|
* 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();
|
private $stack = array();
|
||||||
/**
|
/**
|
||||||
* @var array $validators an array of validator objects
|
* @var array $validators an array of validator objects
|
||||||
*/
|
*/
|
||||||
private static $validators = array();
|
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
|
* returns a validator object
|
||||||
*
|
*
|
||||||
@ -86,24 +100,35 @@ class Doctrine_Validator {
|
|||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function validateRecord(Doctrine_Record $record) {
|
public function validateRecord(Doctrine_Record $record) {
|
||||||
$modified = $record->getModified();
|
|
||||||
$columns = $record->getTable()->getColumns();
|
$columns = $record->getTable()->getColumns();
|
||||||
$name = $record->getTable()->getComponentName();
|
$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();
|
$err = array();
|
||||||
foreach($modified as $key => $value) {
|
|
||||||
|
foreach($data as $key => $value) {
|
||||||
|
if($value === self::$null)
|
||||||
|
$value = null;
|
||||||
|
|
||||||
$column = $columns[$key];
|
$column = $columns[$key];
|
||||||
|
|
||||||
|
if($column[0] == 'array' || $column[0] == 'object') {
|
||||||
|
$value = serialize($value);
|
||||||
|
}
|
||||||
|
|
||||||
if(strlen($value) > $column[1]) {
|
if(strlen($value) > $column[1]) {
|
||||||
$err[$key] = Doctrine_Validator::ERR_LENGTH;
|
$err[$key] = Doctrine_Validator::ERR_LENGTH;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(self::gettype($value) !== $column[0]) {
|
|
||||||
$err[$key] = Doctrine_Validator::ERR_TYPE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$e = explode("|",$column[2]);
|
$e = explode("|",$column[2]);
|
||||||
|
|
||||||
foreach($e as $k => $arg) {
|
foreach($e as $k => $arg) {
|
||||||
@ -116,28 +141,22 @@ class Doctrine_Validator {
|
|||||||
|
|
||||||
$validator = self::getValidator($args[0]);
|
$validator = self::getValidator($args[0]);
|
||||||
if( ! $validator->validate($record, $key, $value, $args[1])) {
|
if( ! $validator->validate($record, $key, $value, $args[1])) {
|
||||||
switch(strtolower($args[0])):
|
|
||||||
case "unique":
|
$constant = 'Doctrine_Validator::ERR_'.strtoupper($args[0]);
|
||||||
$err[$key] = Doctrine_Validator::ERR_UNIQUE;
|
|
||||||
break;
|
if(defined($constant))
|
||||||
case "notnull":
|
$err[$key] = constant($constant);
|
||||||
$err[$key] = Doctrine_Validator::ERR_NULL;
|
else
|
||||||
break;
|
$err[$key] = Doctrine_Validator::ERR_VALID;
|
||||||
case "notblank":
|
|
||||||
$err[$key] = Doctrine_Validator::ERR_BLANK;
|
// errors found quit validation looping for this column
|
||||||
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]))
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(self::gettype($value) !== $column[0] && self::gettype($value) != 'NULL') {
|
||||||
|
$err[$key] = Doctrine_Validator::ERR_TYPE;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,27 @@
|
|||||||
<?php
|
<?php
|
||||||
class Doctrine_ValidatorTestCase extends Doctrine_UnitTestCase {
|
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() {
|
public function testValidate() {
|
||||||
$user = $this->session->getTable("User")->find(4);
|
$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->assertEqual($a["User"][0]["name"], Doctrine_Validator::ERR_LENGTH);
|
||||||
$this->manager->setAttribute(Doctrine::ATTR_VLD, false);
|
$this->manager->setAttribute(Doctrine::ATTR_VLD, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
@ -313,4 +313,13 @@ class Log_Status extends Doctrine_Record {
|
|||||||
$this->hasColumn("name", "string", 255);
|
$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("CacheSqliteTestCase.php");
|
||||||
require_once("CollectionOffsetTestCase.php");
|
require_once("CollectionOffsetTestCase.php");
|
||||||
require_once("SenseiTestCase.php");
|
|
||||||
require_once("QueryTestCase.php");
|
require_once("QueryTestCase.php");
|
||||||
|
|
||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user