From dce5292bf02911a4104833e5fcf231cf3cb384b1 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Sun, 17 Nov 2013 12:54:07 +0100 Subject: [PATCH] Adding validation to the saving process --- Cake/ORM/Table.php | 32 ++++++++++++- Cake/Test/TestCase/ORM/TableTest.php | 67 ++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/Cake/ORM/Table.php b/Cake/ORM/Table.php index e5fd4a0ba4e..d859f668c3f 100644 --- a/Cake/ORM/Table.php +++ b/Cake/ORM/Table.php @@ -887,7 +887,11 @@ public function exists(array $conditions) { * @return \Cake\ORM\Entity|boolean */ public function save(Entity $entity, array $options = []) { - $options = new \ArrayObject($options + ['atomic' => true, 'fieldList' => []]); + $options = new \ArrayObject($options + [ + 'atomic' => true, + 'fieldList' => [], + 'validate' => true + ]); if ($options['atomic']) { $connection = $this->connection(); $success = $connection->transactional(function() use ($entity, $options) { @@ -917,6 +921,10 @@ protected function _processSave($entity, $options) { $entity->isNew(true); } + if (!$this->_processValidation($entity, $options)) { + return false; + } + $event = new Event('Model.beforeSave', $this, compact('entity', 'options')); $this->getEventManager()->dispatch($event); @@ -1034,6 +1042,28 @@ protected function _update($entity, $data) { return $success; } +/** + * Validates the $entity if the 'validate' key is not set to false in $options + * + * @param \Cake\ORM\Entity The entity to validate + * @param \ArrayObject $options + * @return boolean true if the entity is valid, false otherwise + */ + protected function _processValidation($entity, $options) { + if (empty($options['validate'])) { + return true; + } + + $type = is_string($options['validate']) ? $options['validate'] : 'default'; + $validator = $this->validator($type); + + if (!count($validator)) { + return true; + } + + return $entity->validate($validator, $options['fieldList']); + } + /** * Delete a single entity. * diff --git a/Cake/Test/TestCase/ORM/TableTest.php b/Cake/Test/TestCase/ORM/TableTest.php index 75c9ed371fa..0a3707f1aa4 100644 --- a/Cake/Test/TestCase/ORM/TableTest.php +++ b/Cake/Test/TestCase/ORM/TableTest.php @@ -21,6 +21,7 @@ use Cake\Database\Expression\QueryExpression; use Cake\ORM\Table; use Cake\ORM\TableRegistry; +use Cake\Validation\Validator; /** * Used to test correct class is instantiated when using TableRegistry::get(); @@ -1836,4 +1837,70 @@ public function testValidatorSetter() { $this->assertSame($validator, $table->validator('other')); } +/** + * Tests saving with validation + * + * @return void + */ + public function testSaveWithValidationError() { + $entity = new \Cake\ORM\Entity([ + 'username' => 'superuser' + ]); + $table = TableRegistry::get('users'); + $table->validator()->validatePresence('password'); + $this->assertFalse($table->save($entity)); + $this->assertNotEmpty($entity->errors('password')); + } + +/** + * Tests saving with validation and field list + * + * @return void + */ + public function testSaveWithValidationErrorAndFieldList() { + $entity = new \Cake\ORM\Entity([ + 'username' => 'superuser' + ]); + $table = TableRegistry::get('users'); + $table->validator()->validatePresence('password'); + $this->assertFalse($table->save($entity, [ + 'fieldList' => ['username', 'password'] + ])); + $this->assertNotEmpty($entity->errors('password')); + } + +/** + * Tests using a custom validation object when saving + * + * @return void + */ + public function testSaveWithDifferentValidator() { + $entity = new \Cake\ORM\Entity([ + 'username' => 'superuser' + ]); + $table = TableRegistry::get('users'); + $validator = (new Validator)->validatePresence('password'); + $table->validator('custom', $validator); + $this->assertFalse($table->save($entity, ['validate' => 'custom'])); + $this->assertNotEmpty($entity->errors('password')); + + $this->assertSame($entity, $table->save($entity), 'default was not used'); + } + +/** + * Tests saving with successful validation + * + * @return void + */ + public function testSaveWithValidationSuccess() { + $entity = new \Cake\ORM\Entity([ + 'username' => 'superuser', + 'password' => 'hey' + ]); + $table = TableRegistry::get('users'); + $table->validator()->validatePresence('password'); + $this->assertSame($entity, $table->save($entity)); + $this->assertEmpty($entity->errors('password')); + } + }