From 65553e4671a4b47b72b31cdbae09addda148e9a3 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Tue, 12 Nov 2013 23:15:00 +0100 Subject: [PATCH] Implemented allowEmpty for validator --- Cake/ORM/Validation/ValidationSet.php | 43 +------------- Cake/ORM/Validator.php | 57 +++++++++++++++++- Cake/Test/TestCase/ORM/ValidatorTest.php | 76 ++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 45 deletions(-) diff --git a/Cake/ORM/Validation/ValidationSet.php b/Cake/ORM/Validation/ValidationSet.php index c96ca2418a0..4dcb6735215 100644 --- a/Cake/ORM/Validation/ValidationSet.php +++ b/Cake/ORM/Validation/ValidationSet.php @@ -47,13 +47,6 @@ class ValidationSet implements \ArrayAccess, \IteratorAggregate, \Countable { */ protected $_validationDomain = null; -/** - * Holds the fieldname - * - * @var string - */ - public $field = null; - /** * Holds the original ruleSet * @@ -98,7 +91,7 @@ public function isPresenceRequired($validatePresent = null) { * @param boolean|string $allowEmpty Valid values are true, false, 'create', 'update' * @return boolean|string */ - public function allowEmpty($allowEmpty = null) { + public function isEmptyAllowed($allowEmpty = null) { if ($allowEmpty === null) { return $this->_allowEmpty; } @@ -146,40 +139,6 @@ public function validate($data, $isUpdate = false) { return $errors; } -/** - * Returns whether the field can be left blank according to `allowEmpty` - * - * @return boolean - */ - public function isEmptyAllowed() { - if (in_array($this->_allowEmpty, array('create', 'update'), true)) { - return ( - ($this->_allowEmpty === 'create' && !$this->_isUpdate) || - ($this->_allowEmpty === 'update' && $this->_isUpdate) - ); - } - - return $this->_allowEmpty; - } - - -/** - * Checks if the `allowEmpty` property applies - * - * @param string $field Field to check - * @param array $data data to check against - * @return boolean - */ - public function checkEmpty($field, $data) { - if (!array_key_exists($field, $data)) { - return false; - } - if (empty($data[$field]) && $data[$field] != '0' && $this->isEmptyAllowed()) { - return true; - } - return false; - } - /** * Gets a rule for a given name if exists * diff --git a/Cake/ORM/Validator.php b/Cake/ORM/Validator.php index 9bf2e65298e..cfd2d6e1c72 100644 --- a/Cake/ORM/Validator.php +++ b/Cake/ORM/Validator.php @@ -58,6 +58,11 @@ public function errors(array $data, $newRecord = true) { if (!$keyPresent && !$this->_checkPresence($field, $newRecord)) { $errors[$name][] = __d('cake', 'This field is required'); } + if ($keyPresent && !$this->_checkEmpty($field, $newRecord)) { + if ($this->_fieldIsEmpty($data[$name])) { + $errors[$name][] = __d('cake', 'This field cannot be left empty'); + } + } } return $errors; @@ -221,11 +226,24 @@ public function remove($field, $rule = null) { * Sets whether a field is required to be present in data array. * * @param string $field the name of the field - * @param boolean|string $allowEmpty Valid values are true, false, 'create', 'update' + * @param boolean|string $mode Valid values are true, false, 'create', 'update' + * @return Validator this instance + */ + public function validatePresence($field, $mode = true) { + $this->field($field)->isPresenceRequired($mode); + return $this; + } + +/** + * Sets whether a field is allowed to be empty. If it is, all other validation + * rules will be ignored + * + * @param string $field the name of the field + * @param boolean|string $mode Valid values are true, false, 'create', 'update' * @return Validator this instance */ - public function validatePresence($field, $type = true) { - $this->field($field)->isPresenceRequired($type); + public function allowEmpty($field, $mode = true) { + $this->field($field)->isEmptyAllowed($mode); return $this; } @@ -249,4 +267,37 @@ protected function _checkPresence($field, $newRecord) { return !$required; } +/** + * + * Returns whether the field can be left blank according to `allowEmpty` + * + * @param ValidationSet $field the set of rules for a field + * @param boolean $newRecord whether the data to be validated is new or to be updated. + * @return boolean + */ + protected function _checkEmpty($field, $newRecord) { + $allowed = $field->isEmptyAllowed(); + if (in_array($allowed, array('create', 'update'), true)) { + $allowed = ( + ($allowed === 'create' && $newRecord) || + ($allowed === 'update' && !$newRecord) + ); + } + + return $allowed; + } + +/** + * Returns true if the field is empty in the passed data array + * + * @param mixed $data value to check against + * @return boolean + */ + protected function _fieldIsEmpty($data) { + if (empty($data) && $data !== '0' && $data !== false && $data !== 0) { + return true; + } + return false; + } + } diff --git a/Cake/Test/TestCase/ORM/ValidatorTest.php b/Cake/Test/TestCase/ORM/ValidatorTest.php index cbdd21c8f0c..b6a279ee888 100644 --- a/Cake/Test/TestCase/ORM/ValidatorTest.php +++ b/Cake/Test/TestCase/ORM/ValidatorTest.php @@ -127,7 +127,83 @@ public function testErrorsWithPresenceRequired() { $validator->validatePresence('title', false); $this->assertEmpty($validator->errors(['foo' => 'bar'])); + } + +/** + * Tests the allowEmpty method + * + * @return void + */ + public function testAllowEmpty() { + $validator = new Validator; + $this->assertSame($validator, $validator->allowEmpty('title')); + $this->assertTrue($validator->field('title')->isEmptyAllowed()); + + $validator->allowEmpty('title', false); + $this->assertFalse($validator->field('title')->isEmptyAllowed()); + + $validator->allowEmpty('title', 'created'); + $this->assertEquals('created', $validator->field('title')->isEmptyAllowed()); + + $validator->allowEmpty('title', 'updated'); + $this->assertEquals('updated', $validator->field('title')->isEmptyAllowed()); + } + +/** + * Tests errors generated when a field is not allowed to be empty + * + * @return void + */ + public function testErrorsWithEmptyNotAllowed() { + $validator = new Validator; + $validator->allowEmpty('title', false); + $errors = $validator->errors(['title' => '']); + $expected = ['title' => ['This field cannot be left empty']]; + $this->assertEquals($expected, $errors); + + $errors = $validator->errors(['title' => []]); + $expected = ['title' => ['This field cannot be left empty']]; + $this->assertEquals($expected, $errors); + + $errors = $validator->errors(['title' => null]); + $expected = ['title' => ['This field cannot be left empty']]; + $this->assertEquals($expected, $errors); + + $errors = $validator->errors(['title' => 0]); + $this->assertEmpty($errors); + + $errors = $validator->errors(['title' => '0']); + $this->assertEmpty($errors); + + $errors = $validator->errors(['title' => false]); + $this->assertEmpty($errors); + } + +/** + * Tests errors generated when a field is allowed to be empty + * + * @return void + */ + public function testErrorsWithEmptyAllowed() { + $validator = new Validator; + $validator->allowEmpty('title'); + $errors = $validator->errors(['title' => '']); + $this->assertEmpty($errors); + + $errors = $validator->errors(['title' => []]); + $this->assertEmpty($errors); + + $errors = $validator->errors(['title' => null]); + $this->assertEmpty($errors); + + $errors = $validator->errors(['title' => 0]); + $this->assertEmpty($errors); + + $errors = $validator->errors(['title' => '0']); + $this->assertEmpty($errors); + $errors = $validator->errors(['title' => false]); + $this->assertEmpty($errors); } }