Finished the validation changes.
Ticket: 150
This commit is contained in:
parent
42f7cb706f
commit
db25f46e52
@ -244,6 +244,11 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
||||
$validator = new Doctrine_Validator();
|
||||
$validator->validateRecord($this);
|
||||
$this->validate();
|
||||
if ($this->state == self::STATE_TDIRTY || $this->state == self::STATE_TCLEAN) {
|
||||
$this->validateOnInsert();
|
||||
} else {
|
||||
$this->validateOnUpdate();
|
||||
}
|
||||
|
||||
return $this->errorStack->count() == 0 ? true : false;
|
||||
//$this->errorStack->merge($validator->getErrorStack());
|
||||
@ -254,6 +259,18 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
||||
* validations that are neccessary.
|
||||
*/
|
||||
protected function validate() {}
|
||||
/**
|
||||
* Empty tempalte method to provide concrete Record classes with the possibility
|
||||
* to hook into the validation procedure only when the record is going to be
|
||||
* updated.
|
||||
*/
|
||||
protected function validateOnUpdate() {}
|
||||
/**
|
||||
* Empty tempalte method to provide concrete Record classes with the possibility
|
||||
* to hook into the validation procedure only when the record is going to be
|
||||
* inserted into the data store the first time.
|
||||
*/
|
||||
protected function validateOnInsert() {}
|
||||
/**
|
||||
* getErrorStack
|
||||
*
|
||||
@ -840,7 +857,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
||||
$conn = $this->table->getConnection();
|
||||
}
|
||||
$conn->beginTransaction();
|
||||
|
||||
|
||||
$saveLater = $conn->saveRelated($this);
|
||||
|
||||
if ($this->isValid()) {
|
||||
|
@ -1,25 +1,25 @@
|
||||
<?php
|
||||
class Doctrine_Validator_Regexp {
|
||||
/**
|
||||
* @param Doctrine_Record $record
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param string $args
|
||||
* @return boolean
|
||||
*/
|
||||
public function validate(Doctrine_Record $record, $key, $value, $args) {
|
||||
if(is_array($args)) {
|
||||
foreach($args as $regexp) {
|
||||
if( ! preg_match("/$args/", $value))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if(preg_match("/$args/", $value))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
<?php
|
||||
class Doctrine_Validator_Regexp {
|
||||
/**
|
||||
* @param Doctrine_Record $record
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param string $args
|
||||
* @return boolean
|
||||
*/
|
||||
public function validate(Doctrine_Record $record, $key, $value, $args) {
|
||||
if(is_array($args)) {
|
||||
foreach($args as $regexp) {
|
||||
if( ! preg_match($args, $value))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if(preg_match($args, $value))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,17 +10,19 @@ class User extends Doctrine_Record {
|
||||
$this->hasColumn("email_id","integer");
|
||||
$this->hasColumn("created","integer",11);
|
||||
}
|
||||
// Our own validation
|
||||
protected function validate() {
|
||||
if ($this->name == 'God') {
|
||||
// Blasphemy! Stop that! ;-)
|
||||
// syntax: add(<fieldName>, <error code/identifier>)
|
||||
$this->errorStack->add('name', 'forbiddenName');
|
||||
}
|
||||
}
|
||||
}
|
||||
class Email extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
// validators 'email' and 'unique' used
|
||||
$this->hasColumn("address","string",150, array("email", "unique" => true));
|
||||
}
|
||||
protected function validate() {
|
||||
if ($this->address !== 'the-only-allowed-mail@address.com') {
|
||||
// syntax: add(<fieldName>, <error code>)
|
||||
$this->errorStack->add('address', 'myCustomErrorCode');
|
||||
}
|
||||
$this->hasColumn("address","string",150, array("email", "unique"));
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -4,6 +4,8 @@ try {
|
||||
$user->Email->address = "drink@@notvalid..";
|
||||
$user->save();
|
||||
} catch(Doctrine_Validator_Exception $e) {
|
||||
// Note: you could also use $e->getInvalidRecords(). The direct way
|
||||
// used here is just more simple when you know the records you're dealing with.
|
||||
$userErrors = $user->getErrorStack();
|
||||
$emailErrors = $user->Email->getErrorStack();
|
||||
|
||||
|
@ -14,10 +14,15 @@ a predefined validator you have three options:<br />
|
||||
<br />
|
||||
The first two options are advisable if it is likely that the validation is of general use
|
||||
and is potentially applicable in many situations. In that case it is a good idea to implement
|
||||
a new validator. However if the validation is special it is better to use hooks provided by Doctrine.
|
||||
One of these hooks is the validate() method. If you need a special validation in your active record
|
||||
you can simply override validate() in your active record class (a descendant of Doctrine_Record).
|
||||
Within this method you can use all the power of PHP to validate your fields. When a field
|
||||
a new validator. However if the validation is special it is better to use hooks provided by Doctrine:<br />
|
||||
<br />
|
||||
- validate() (Executed every time the record gets validated)<br />
|
||||
- validateOnInsert() (Executed when the record is new and gets validated)<br />
|
||||
- validateOnUpdate() (Executed when the record is not new and gets validated)<br />
|
||||
<br />
|
||||
If you need a special validation in your active record
|
||||
you can simply override one of these methods in your active record class (a descendant of Doctrine_Record).
|
||||
Within thess methods you can use all the power of PHP to validate your fields. When a field
|
||||
doesnt pass your validation you can then add errors to the record's error stack.
|
||||
The following code snippet shows an example of how to define validators together with custom
|
||||
validation:<br />
|
||||
|
@ -202,14 +202,17 @@ class Doctrine_ValidatorTestCase extends Doctrine_UnitTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether custom validation through template methods works correctly
|
||||
* Tests whether the validate() callback works correctly
|
||||
* in descendants of Doctrine_Record.
|
||||
*/
|
||||
public function testCustomValidation() {
|
||||
public function testValidationHooks() {
|
||||
$this->manager->setAttribute(Doctrine::ATTR_VLD, true);
|
||||
$user = $this->connection->getTable("User")->find(4);
|
||||
|
||||
// Tests validate() and validateOnInsert()
|
||||
$user = new User();
|
||||
try {
|
||||
$user->name = "I'm not The Saint";
|
||||
$user->password = "1234";
|
||||
$user->save();
|
||||
} catch(Doctrine_Validator_Exception $e) {
|
||||
$this->assertEqual($e->count(), 1);
|
||||
@ -217,16 +220,49 @@ class Doctrine_ValidatorTestCase extends Doctrine_UnitTestCase {
|
||||
$this->assertEqual(count($invalidRecords), 1);
|
||||
|
||||
$stack = $invalidRecords[0]->getErrorStack();
|
||||
|
||||
$this->assertEqual($stack->count(), 1);
|
||||
$this->assertTrue(in_array('notTheSaint', $stack['name']));
|
||||
|
||||
$this->assertEqual($stack->count(), 2);
|
||||
$this->assertTrue(in_array('notTheSaint', $stack['name'])); // validate() hook constraint
|
||||
$this->assertTrue(in_array('pwNotTopSecret', $stack['password'])); // validateOnInsert() hook constraint
|
||||
}
|
||||
|
||||
// Tests validateOnUpdate()
|
||||
$user = $this->connection->getTable("User")->find(4);
|
||||
try {
|
||||
$user->name = "The Saint";
|
||||
$user->name = "The Saint"; // Set correct name
|
||||
$user->password = "Top Secret"; // Set correct password
|
||||
$user->loginname = "Somebody"; // Wrong login name!
|
||||
$user->save();
|
||||
} catch(Doctrine_Validator_Exception $e) {
|
||||
$this->fail();
|
||||
} catch(Doctrine_Validator_Exception $e) {
|
||||
$invalidRecords = $e->getInvalidRecords();
|
||||
$this->assertEqual(count($invalidRecords), 1);
|
||||
|
||||
$stack = $invalidRecords[0]->getErrorStack();
|
||||
|
||||
$this->assertEqual($stack->count(), 1);
|
||||
$this->assertTrue(in_array('notNobody', $stack['loginname'])); // validateOnUpdate() hook constraint
|
||||
}
|
||||
|
||||
$this->manager->setAttribute(Doctrine::ATTR_VLD, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the validateOnInsert() callback works correctly
|
||||
* in descendants of Doctrine_Record.
|
||||
*/
|
||||
public function testHookValidateOnInsert() {
|
||||
$this->manager->setAttribute(Doctrine::ATTR_VLD, true);
|
||||
|
||||
$user = new User();
|
||||
$user->password = "1234";
|
||||
|
||||
try {
|
||||
$user->save();
|
||||
$this->fail();
|
||||
} catch (Doctrine_Validator_Exception $ex) {
|
||||
$errors = $user->getErrorStack();
|
||||
$this->assertTrue(in_array('pwNotTopSecret', $errors['password']));
|
||||
}
|
||||
|
||||
$this->manager->setAttribute(Doctrine::ATTR_VLD, false);
|
||||
|
@ -9,7 +9,7 @@ class Entity extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn("id","integer",20,"autoincrement|primary");
|
||||
$this->hasColumn("name","string",50);
|
||||
$this->hasColumn("loginname","string",20,"unique");
|
||||
$this->hasColumn("loginname","string",20, array("unique"));
|
||||
$this->hasColumn("password","string",16);
|
||||
$this->hasColumn("type","integer",1);
|
||||
$this->hasColumn("created","integer",11);
|
||||
@ -104,6 +104,16 @@ class User extends Entity {
|
||||
$this->errorStack->add('name', 'notTheSaint');
|
||||
}
|
||||
}
|
||||
public function validateOnInsert() {
|
||||
if ($this->password !== 'Top Secret') {
|
||||
$this->errorStack->add('password', 'pwNotTopSecret');
|
||||
}
|
||||
}
|
||||
public function validateOnUpdate() {
|
||||
if ($this->loginname !== 'Nobody') {
|
||||
$this->errorStack->add('loginname', 'notNobody');
|
||||
}
|
||||
}
|
||||
}
|
||||
class Groupuser extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
@ -421,7 +431,7 @@ class ValidatorTest extends Doctrine_Record {
|
||||
$this->hasColumn("myobject", "object", 1000);
|
||||
$this->hasColumn("myinteger", "integer", 11);
|
||||
$this->hasColumn("myrange", "integer", 11, array('range' => array(4,123)));
|
||||
$this->hasColumn("myregexp", "string", 5, array('regexp' => '^[0-9]+$'));
|
||||
$this->hasColumn("myregexp", "string", 5, array('regexp' => '/^[0-9]+$/'));
|
||||
|
||||
$this->hasColumn("myemail", "string", 100, "email");
|
||||
$this->hasColumn("myemail2", "string", 100, "email|notblank");
|
||||
|
Loading…
x
Reference in New Issue
Block a user