Skip to content

Commit

Permalink
Adding validation to the saving process
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Nov 20, 2013
1 parent a281906 commit dce5292
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 1 deletion.
32 changes: 31 additions & 1 deletion Cake/ORM/Table.php
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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.
*
Expand Down
67 changes: 67 additions & 0 deletions Cake/Test/TestCase/ORM/TableTest.php
Expand Up @@ -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();
Expand Down Expand Up @@ -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'));
}

}

0 comments on commit dce5292

Please sign in to comment.