Commit b0f05370 authored by romanb's avatar romanb

Necessary changes to the validation components. Further improvements and docs...

Necessary changes to the validation components. Further improvements and docs will follow in the next days.
Ticket: 150
parent 499da8f9
This diff is collapsed.
...@@ -27,10 +27,6 @@ ...@@ -27,10 +27,6 @@
* @license LGPL * @license LGPL
*/ */
class Doctrine_Validator { class Doctrine_Validator {
/**
* @var array $stack error stack
*/
private $stack = array();
/** /**
* @var array $validators an array of validator objects * @var array $validators an array of validator objects
*/ */
...@@ -78,6 +74,8 @@ class Doctrine_Validator { ...@@ -78,6 +74,8 @@ class Doctrine_Validator {
$columns = $record->getTable()->getColumns(); $columns = $record->getTable()->getColumns();
$component = $record->getTable()->getComponentName(); $component = $record->getTable()->getComponentName();
$errorStack = $record->getErrorStack();
switch($record->getState()): switch($record->getState()):
case Doctrine_Record::STATE_TDIRTY: case Doctrine_Record::STATE_TDIRTY:
case Doctrine_Record::STATE_TCLEAN: case Doctrine_Record::STATE_TCLEAN:
...@@ -102,7 +100,7 @@ class Doctrine_Validator { ...@@ -102,7 +100,7 @@ class Doctrine_Validator {
$value = $record->getTable()->enumIndex($key, $value); $value = $record->getTable()->enumIndex($key, $value);
if($value === false) { if($value === false) {
$err[$key] = 'enum'; $errorStack->add($key, 'enum');
continue; continue;
} }
} }
...@@ -113,7 +111,7 @@ class Doctrine_Validator { ...@@ -113,7 +111,7 @@ class Doctrine_Validator {
$length = strlen($value); $length = strlen($value);
if($length > $column[1]) { if($length > $column[1]) {
$err[$key] = 'length'; $errorStack->add($key, 'length');
continue; continue;
} }
...@@ -144,7 +142,7 @@ class Doctrine_Validator { ...@@ -144,7 +142,7 @@ class Doctrine_Validator {
if( ! $validator->validate($record, $key, $value, $args)) { if( ! $validator->validate($record, $key, $value, $args)) {
$err[$key] = $name; $errorStack->add($key, $name);
//$err[$key] = 'not valid'; //$err[$key] = 'not valid';
...@@ -153,17 +151,10 @@ class Doctrine_Validator { ...@@ -153,17 +151,10 @@ class Doctrine_Validator {
} }
} }
if( ! self::isValidType($value, $column[0])) { if( ! self::isValidType($value, $column[0])) {
$err[$key] = 'type'; $errorStack->add($key, 'type');
continue; continue;
} }
} }
if( ! empty($err)) {
$this->stack = $err;
return false;
}
return true;
} }
/** /**
* whether or not this validator has errors * whether or not this validator has errors
...@@ -173,14 +164,6 @@ class Doctrine_Validator { ...@@ -173,14 +164,6 @@ class Doctrine_Validator {
public function hasErrors() { public function hasErrors() {
return (count($this->stack) > 0); return (count($this->stack) > 0);
} }
/**
* returns the error stack
*
* @return array
*/
public function getErrorStack() {
return $this->stack;
}
/** /**
* converts a doctrine type to native php type * converts a doctrine type to native php type
* *
......
<?php <?php
/* /*
* $Id$ * $Id$
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* This software consists of voluntary contributions made by many individuals * This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see * and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>. * <http://www.phpdoctrine.com>.
*/ */
Doctrine::autoload('Doctrine_Access');
/** /**
* Doctrine_Validator_ErrorStack * Doctrine_Validator_ErrorStack
* *
* @author Konsta Vesterinen * @author Konsta Vesterinen
* @license LGPL * @author Roman Borschel
* @package Doctrine * @license LGPL
*/ * @package Doctrine
class Doctrine_Validator_ErrorStack extends Doctrine_Access implements Countable, IteratorAggregate { */
class Doctrine_Validator_ErrorStack implements ArrayAccess, Countable, IteratorAggregate {
private $errors = array();
/**
public function merge($stack) { * The errors of the error stack.
if(is_array($stack)) { *
$this->errors = array_merge($this->errors, $stack); * @var array
} */
} protected $errors = array();
public function get($name) { /**
if(isset($this->errors[$name])) * Constructor
return $this->errors[$name]; *
*/
return null; public function __construct()
} {}
public function set($name, $value) { /**
$this->errors[$name] = $value; * Adds an error to the stack.
} *
* @param string $invalidFieldName
public function getIterator() { * @param string $errorType
return new ArrayIterator($this->errors); */
} public function add($invalidFieldName, $errorType = 'general') {
public function count() { $this->errors[$invalidFieldName][] = array('type' => $errorType);
return count($this->errors); }
}
} /**
* Removes all existing errors for the specified field from the stack.
*
* @param string $fieldName
*/
public function remove($fieldName) {
if (isset($this->errors[$fieldName])) {
unset($this->errors[$fieldName]);
}
}
/**
* Enter description here...
*
* @param unknown_type $name
* @return unknown
*/
public function get($name) {
return $this[$name];
}
/** ArrayAccess implementation */
/**
* Gets all errors that occured for the specified field.
*
* @param string $offset
* @return The array containing the errors or NULL if no errors were found.
*/
public function offsetGet($offset) {
return isset($this->errors[$offset]) ? $this->errors[$offset] : null;
}
/**
* Enter description here...
*
* @param string $offset
* @param mixed $value
* @throws Doctrine_Validator_ErrorStack_Exception Always thrown since this operation is not allowed.
*/
public function offsetSet($offset, $value) {
throw new Doctrine_Validator_ErrorStack_Exception("Errors can only be added through
Doctrine_Validator_ErrorStack::add()");
}
/**
* Enter description here...
*
* @param unknown_type $offset
*/
public function offsetExists($offset) {
return isset($this->errors[$offset]);
}
/**
* Enter description here...
*
* @param unknown_type $offset
* @throws Doctrine_Validator_ErrorStack_Exception Always thrown since this operation is not allowed.
*/
public function offsetUnset($offset) {
throw new Doctrine_Validator_ErrorStack_Exception("Errors can only be removed
through Doctrine_Validator_ErrorStack::remove()");
}
/**
* Enter description here...
*
* @param unknown_type $stack
*/
/*
public function merge($stack) {
if(is_array($stack)) {
$this->errors = array_merge($this->errors, $stack);
}
}*/
/** IteratorAggregate implementation */
/**
* Enter description here...
*
* @return unknown
*/
public function getIterator() {
return new ArrayIterator($this->errors);
}
/** Countable implementation */
/**
* Enter description here...
*
* @return unknown
*/
public function count() {
return count($this->errors);
}
}
<?php <?php
class Doctrine_EnumTestCase extends Doctrine_UnitTestCase { class Doctrine_EnumTestCase extends Doctrine_UnitTestCase {
public function prepareData() { } public function prepareData() { }
public function prepareTables() { public function prepareTables() {
$this->tables = array("EnumTest"); $this->tables = array("EnumTest");
parent::prepareTables(); parent::prepareTables();
} }
public function testParameterConversion() { public function testParameterConversion() {
$test = new EnumTest(); $test = new EnumTest();
$test->status = 'open'; $test->status = 'open';
$this->assertEqual($test->status, 'open'); $this->assertEqual($test->status, 'open');
$test->save(); $test->save();
$query = new Doctrine_Query($this->connection); $query = new Doctrine_Query($this->connection);
$ret = $query->query('FROM EnumTest WHERE EnumTest.status = ?', array('open')); $ret = $query->query('FROM EnumTest WHERE EnumTest.status = ?', array('open'));
$this->assertEqual(count($ret), 1); $this->assertEqual(count($ret), 1);
$query = new Doctrine_Query($this->connection); $query = new Doctrine_Query($this->connection);
$ret = $query->query('FROM EnumTest WHERE EnumTest.status = open'); $ret = $query->query('FROM EnumTest WHERE EnumTest.status = open');
$this->assertEqual(count($ret), 1); $this->assertEqual(count($ret), 1);
} }
public function testEnumType() { public function testEnumType() {
$enum = new EnumTest(); $enum = new EnumTest();
$enum->status = "open"; $enum->status = "open";
$this->assertEqual($enum->status, "open"); $this->assertEqual($enum->status, "open");
$enum->save(); $enum->save();
$this->assertEqual($enum->status, "open"); $this->assertEqual($enum->status, "open");
$enum->refresh(); $enum->refresh();
$this->assertEqual($enum->status, "open"); $this->assertEqual($enum->status, "open");
$enum->status = "closed"; $enum->status = "closed";
$this->assertEqual($enum->status, "closed"); $this->assertEqual($enum->status, "closed");
$enum->save(); $enum->save();
$this->assertEqual($enum->status, "closed"); $this->assertEqual($enum->status, "closed");
$this->assertTrue(is_numeric($enum->id)); $this->assertTrue(is_numeric($enum->id));
$enum->refresh(); $enum->refresh();
$this->assertEqual($enum->status, "closed"); $this->assertEqual($enum->status, "closed");
} }
public function testEnumTypeWithCaseConversion() { public function testEnumTypeWithCaseConversion() {
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER); $this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER);
$enum = new EnumTest(); $enum = new EnumTest();
$enum->status = "open"; $enum->status = "open";
$this->assertEqual($enum->status, "open"); $this->assertEqual($enum->status, "open");
$enum->save(); $enum->save();
$this->assertEqual($enum->status, "open"); $this->assertEqual($enum->status, "open");
$enum->refresh(); $enum->refresh();
$this->assertEqual($enum->status, "open"); $this->assertEqual($enum->status, "open");
$enum->status = "closed"; $enum->status = "closed";
$this->assertEqual($enum->status, "closed"); $this->assertEqual($enum->status, "closed");
$enum->save(); $enum->save();
$this->assertEqual($enum->status, "closed"); $this->assertEqual($enum->status, "closed");
$enum->refresh(); $enum->refresh();
$this->assertEqual($enum->status, "closed"); $this->assertEqual($enum->status, "closed");
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL); $this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL);
} }
public function testFailingRefresh() { public function testFailingRefresh() {
$enum = $this->connection->getTable('EnumTest')->find(1); $enum = $this->connection->getTable('EnumTest')->find(1);
$this->dbh->query('DELETE FROM enum_test WHERE id = 1'); $this->dbh->query('DELETE FROM enum_test WHERE id = 1');
$f = false; $f = false;
try { try {
$enum->refresh(); $enum->refresh();
} catch(Doctrine_Record_Exception $e) { } catch(Doctrine_Record_Exception $e) {
$f = true; $f = true;
} }
$this->assertTrue($f); $this->assertTrue($f);
} }
} }
?> ?>
This diff is collapsed.
...@@ -97,6 +97,13 @@ class User extends Entity { ...@@ -97,6 +97,13 @@ class User extends Entity {
$this->hasMany("Group","Groupuser.group_id"); $this->hasMany("Group","Groupuser.group_id");
$this->setInheritanceMap(array("type"=>0)); $this->setInheritanceMap(array("type"=>0));
} }
/** Custom validation */
public function validate() {
// Allow only one name!
if ($this->name !== 'The Saint') {
$this->errorStack->add('name', 'notTheSaint');
}
}
} }
class Groupuser extends Doctrine_Record { class Groupuser extends Doctrine_Record {
public function setTableDefinition() { public function setTableDefinition() {
...@@ -541,4 +548,5 @@ class BoardWithPosition extends Doctrine_Record { ...@@ -541,4 +548,5 @@ class BoardWithPosition extends Doctrine_Record {
$this->hasOne("CategoryWithPosition as Category", "BoardWithPosition.category_id"); $this->hasOne("CategoryWithPosition as Category", "BoardWithPosition.category_id");
} }
} }
?> ?>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment