From 02dd8b1a79319d0b6f2b2ff23236046ab3b8370a Mon Sep 17 00:00:00 2001 From: romanb Date: Sat, 29 Sep 2007 12:31:56 +0000 Subject: [PATCH] Validator refactoring. 2 new validators: past & future --- lib/Doctrine/Validator.php | 55 +++++++++++++++++-- lib/Doctrine/Validator/Date.php | 2 +- lib/Doctrine/Validator/Email.php | 2 +- lib/Doctrine/Validator/Future.php | 79 ++++++++++++++++++++++++++++ lib/Doctrine/Validator/Past.php | 79 ++++++++++++++++++++++++++++ models/ValidatorTest.php | 6 +-- models/ValidatorTest_DateModel.php | 7 +++ tests/Validator/FutureTestCase.php | 84 ++++++++++++++++++++++++++++++ tests/Validator/PastTestCase.php | 84 ++++++++++++++++++++++++++++++ tests/run.php | 3 ++ 10 files changed, 391 insertions(+), 10 deletions(-) create mode 100644 lib/Doctrine/Validator/Future.php create mode 100644 lib/Doctrine/Validator/Past.php create mode 100644 models/ValidatorTest_DateModel.php create mode 100644 tests/Validator/FutureTestCase.php create mode 100644 tests/Validator/PastTestCase.php diff --git a/lib/Doctrine/Validator.php b/lib/Doctrine/Validator.php index ea59776bb..4afa11b27 100644 --- a/lib/Doctrine/Validator.php +++ b/lib/Doctrine/Validator.php @@ -77,7 +77,7 @@ class Doctrine_Validator extends Doctrine_Object foreach ($data as $key => $value) { if ($value === self::$_null) { $value = null; - } elseif ($value instanceof Doctrine_Record) { + } else if ($value instanceof Doctrine_Record) { $value = $value->getIncremented(); } @@ -191,7 +191,7 @@ class Doctrine_Validator extends Doctrine_Object * * @param $portableType portable doctrine type * @return string - */ + *//* public static function phpType($portableType) { switch ($portableType) { @@ -208,7 +208,7 @@ class Doctrine_Validator extends Doctrine_Object default: return $portableType; } - } + }*/ /** * returns whether or not the given variable is * valid type @@ -217,6 +217,7 @@ class Doctrine_Validator extends Doctrine_Object * @param string $type * @return boolean */ + /* public static function isValidType($var, $type) { if ($type == 'boolean') { @@ -242,13 +243,57 @@ class Doctrine_Validator extends Doctrine_Object return true; break; } + }*/ + + + /** + * returns whether or not the given variable is + * valid type + * + * @param mixed $var + * @param string $type + * @return boolean + */ + public static function isValidType($var, $type) + { + if ($var === null) { + return true; + } else if (is_object($var)) { + return $type == 'object'; + } + + switch ($type) { + case 'float': + case 'double': + return (String)$var == strval(floatval($var)); + case 'integer': + return (String)$var == strval(intval($var)); + case 'string': + return is_string($var) || is_int($var) || is_float($var); + case 'array': + return is_array($var); + case 'object': + return is_object($var); + case 'boolean': + return is_bool($var); + case 'timestamp': + // todo: validate the timestamp is in YYYY-MM-DD HH:MM:SS format + return true; + case 'date': + $validator = self::getValidator('date'); + return $validator->validate($var); + default: + return false; + } } + + /** * returns the type of loosely typed variable * * @param mixed $var * @return string - */ + *//* public static function gettype($var) { $type = gettype($var); @@ -265,5 +310,5 @@ class Doctrine_Validator extends Doctrine_Object default: return $type; } - } + }*/ } diff --git a/lib/Doctrine/Validator/Date.php b/lib/Doctrine/Validator/Date.php index 388a99710..32cf7a2b8 100644 --- a/lib/Doctrine/Validator/Date.php +++ b/lib/Doctrine/Validator/Date.php @@ -40,7 +40,7 @@ class Doctrine_Validator_Date */ public function validate($value) { - if (empty($value)) { + if ($value === null) { return true; } $e = explode('-', $value); diff --git a/lib/Doctrine/Validator/Email.php b/lib/Doctrine/Validator/Email.php index e19e57547..2ae67514e 100644 --- a/lib/Doctrine/Validator/Email.php +++ b/lib/Doctrine/Validator/Email.php @@ -41,7 +41,7 @@ class Doctrine_Validator_Email */ public function validate($value) { - if (empty($value)) { + if ($value === null) { return true; } if (isset($this->args)) { diff --git a/lib/Doctrine/Validator/Future.php b/lib/Doctrine/Validator/Future.php new file mode 100644 index 000000000..76f4cc63a --- /dev/null +++ b/lib/Doctrine/Validator/Future.php @@ -0,0 +1,79 @@ +. + */ + +/** + * Doctrine_Validator_Future + * + * @package Doctrine + * @category Object Relational Mapping + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.phpdoctrine.com + * @since 1.0 + * @version $Revision$ + * @author Roman Borschel + */ +class Doctrine_Validator_Future +{ + /** + * checks if the given value is a valid date in the future. + * + * @param mixed $value + * @return boolean + */ + public function validate($value) + { + if ($value === null) { + return true; + } + $e = explode('-', $value); + + if (count($e) !== 3) { + return false; + } + + if (is_array($this->args) && isset($this->args['timezone'])) { + switch (strtolower($this->args['timezone'])) { + case 'gmt': + $now = gmdate("U") - date("Z"); + break; + default: + $now = getdate(); + break; + } + } else { + $now = getdate(); + } + + if ($now['year'] > $e[0]) { + return false; + } else if ($now['year'] == $e[0]) { + if ($now['mon'] > $e[1]) { + return false; + } else if ($now['mon'] == $e[1]) { + return $now['mday'] < $e[2]; + } else { + return true; + } + } else { + return true; + } + } +} \ No newline at end of file diff --git a/lib/Doctrine/Validator/Past.php b/lib/Doctrine/Validator/Past.php new file mode 100644 index 000000000..8cda1607c --- /dev/null +++ b/lib/Doctrine/Validator/Past.php @@ -0,0 +1,79 @@ +. + */ + +/** + * Doctrine_Validator_Past + * + * @package Doctrine + * @category Object Relational Mapping + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.phpdoctrine.com + * @since 1.0 + * @version $Revision$ + * @author Roman Borschel + */ +class Doctrine_Validator_Past +{ + /** + * checks if the given value is a valid date in the past. + * + * @param mixed $value + * @return boolean + */ + public function validate($value) + { + if ($value === null) { + return true; + } + $e = explode('-', $value); + + if (count($e) !== 3) { + return false; + } + + if (is_array($this->args) && isset($this->args['timezone'])) { + switch (strtolower($this->args['timezone'])) { + case 'gmt': + $now = gmdate("U") - date("Z"); + break; + default: + $now = getdate(); + break; + } + } else { + $now = getdate(); + } + + if ($now['year'] < $e[0]) { + return false; + } else if ($now['year'] == $e[0]) { + if ($now['mon'] < $e[1]) { + return false; + } else if ($now['mon'] == $e[1]) { + return $now['mday'] > $e[2]; + } else { + return true; + } + } else { + return true; + } + } +} \ No newline at end of file diff --git a/models/ValidatorTest.php b/models/ValidatorTest.php index 48aefb947..052d6bc51 100644 --- a/models/ValidatorTest.php +++ b/models/ValidatorTest.php @@ -2,14 +2,14 @@ class ValidatorTest extends Doctrine_Record { public function setTableDefinition() { $this->hasColumn('mymixed', 'string', 100); - $this->hasColumn('mystring', 'string', 100, 'notnull|unique'); + $this->hasColumn('mystring', 'string', 100, array('notnull', 'unique')); $this->hasColumn('myarray', 'array', 1000); $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('myemail', 'string', 100, 'email'); - $this->hasColumn('myemail2', 'string', 100, 'email|notblank'); + $this->hasColumn('myemail', 'string', 100, array('email')); + $this->hasColumn('myemail2', 'string', 100, array('email', 'notblank')); } } diff --git a/models/ValidatorTest_DateModel.php b/models/ValidatorTest_DateModel.php new file mode 100644 index 000000000..0aaf1d5eb --- /dev/null +++ b/models/ValidatorTest_DateModel.php @@ -0,0 +1,7 @@ +hasColumn('birthday', 'date', null, array('past')); + $this->hasColumn('death', 'date', null, array('future')); + } +} diff --git a/tests/Validator/FutureTestCase.php b/tests/Validator/FutureTestCase.php new file mode 100644 index 000000000..64b570e10 --- /dev/null +++ b/tests/Validator/FutureTestCase.php @@ -0,0 +1,84 @@ +. + */ + +/** + * Doctrine_Validator_FutureTestCase + * + * @package Doctrine + * @author Roman Borschel + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @category Object Relational Mapping + * @link www.phpdoctrine.com + * @since 1.0 + * @version $Revision$ + */ +class Doctrine_Validator_Future_TestCase extends Doctrine_UnitTestCase +{ + public function prepareTables() + { + $this->tables[] = 'ValidatorTest_DateModel'; + parent::prepareTables(); + } + + public function prepareData() + { + + } + + public function testValidFutureDates() + { + $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL); + + // one year ahead + $user1 = new ValidatorTest_DateModel(); + $user1->death = date('Y-m-d', time() + 365 * 24 * 60 * 60); + $this->assertTrue($user1->trySave()); + + // one month ahead + $user1 = new ValidatorTest_DateModel(); + $user1->death = date('Y-m-d', time() + 30 * 24 * 60 * 60); + $this->assertTrue($user1->trySave()); + + // one day ahead + $user1->death = date('Y-m-d', time() + 24 * 60 * 60); + $this->assertTrue($user1->trySave()); + + $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_NONE); + } + + public function testInvalidFutureDates() + { + $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL); + + $user1 = new ValidatorTest_DateModel(); + $user1->death = date('Y-m-d', 42); + $this->assertFalse($user1->trySave()); + + $user1->death = date('Y-m-d', time()); + $this->assertFalse($user1->trySave()); + + $user1->death = date('Y-m-d', time() + 60); + $this->assertFalse($user1->trySave()); + + $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_NONE); + } + +} diff --git a/tests/Validator/PastTestCase.php b/tests/Validator/PastTestCase.php new file mode 100644 index 000000000..7afb7f019 --- /dev/null +++ b/tests/Validator/PastTestCase.php @@ -0,0 +1,84 @@ +. + */ + +/** + * Doctrine_Validator_FutureTestCase + * + * @package Doctrine + * @author Roman Borschel + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @category Object Relational Mapping + * @link www.phpdoctrine.com + * @since 1.0 + * @version $Revision$ + */ +class Doctrine_Validator_Past_TestCase extends Doctrine_UnitTestCase +{ + public function prepareTables() + { + $this->tables[] = 'ValidatorTest_DateModel'; + parent::prepareTables(); + } + + public function prepareData() + { + + } + + public function testInvalidPastDates() + { + $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL); + + // one year ahead + $user1 = new ValidatorTest_DateModel(); + $user1->birthday = date('Y-m-d', time() + 365 * 24 * 60 * 60); + $this->assertFalse($user1->trySave()); + + // one month ahead + $user1 = new ValidatorTest_DateModel(); + $user1->birthday = date('Y-m-d', time() + 30 * 24 * 60 * 60); + $this->assertFalse($user1->trySave()); + + // one day ahead + $user1->birthday = date('Y-m-d', time() + 24 * 60 * 60); + $this->assertFalse($user1->trySave()); + + $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_NONE); + } + + public function testValidPastDates() + { + $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL); + + $user1 = new ValidatorTest_DateModel(); + $user1->birthday = date('Y-m-d', 42); + $this->assertTrue($user1->trySave()); + + $user1->birthday = date('Y-m-d', mktime(0,0,0,6,3,1981)); + $this->assertTrue($user1->trySave()); + + $user1->birthday = date('Y-m-d', mktime(0,0,0,3,9,1983)); + $this->assertTrue($user1->trySave()); + + $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_NONE); + } + +} diff --git a/tests/run.php b/tests/run.php index 476fcc4b7..e3abceb79 100644 --- a/tests/run.php +++ b/tests/run.php @@ -1,6 +1,7 @@ addTestCase(new Doctrine_PessimisticLocking_TestCase()); $plugins->addTestCase(new Doctrine_View_TestCase()); $plugins->addTestCase(new Doctrine_Validator_TestCase()); +$plugins->addTestCase(new Doctrine_Validator_Future_TestCase()); +$plugins->addTestCase(new Doctrine_Validator_Past_TestCase()); $plugins->addTestCase(new Doctrine_Hook_TestCase()); $plugins->addTestCase(new Doctrine_I18n_TestCase()); $test->addTestCase($plugins);