Browse Source

Moving the EntityInterface::validate() method to another interface

Since we have validation hapening in the marshaller instead, moving
this type of validation as an opt-in feature seems to be the best
for now
Jose Lorenzo Rodriguez 11 years ago
parent
commit
87bcb025be

+ 0 - 13
src/Datasource/EntityInterface.php

@@ -150,19 +150,6 @@ interface EntityInterface extends ArrayAccess, JsonSerializable {
 	public function isNew($new = null);
 
 /**
- * Validates the internal properties using a validator object. The resulting
- * errors will be copied inside this entity and can be retrieved using the
- * `errors` method.
- *
- * This function returns true if there were no validation errors or false
- * otherwise.
- *
- * @param \Cake\Validation\Validator $validator The validator to use when validating the entity.
- * @return bool
- */
-	public function validate(Validator $validator);
-
-/**
  * Sets the error messages for a field or a list of fields. When called
  * without the second argument it returns the validation
  * errors for the specified fields. If called with no arguments it returns

+ 0 - 20
src/Datasource/EntityTrait.php

@@ -16,7 +16,6 @@ namespace Cake\Datasource;
 
 use Cake\Collection\Collection;
 use Cake\Utility\Inflector;
-use Cake\Validation\Validator;
 use Traversable;
 
 /**
@@ -586,25 +585,6 @@ trait EntityTrait {
 	}
 
 /**
- * Validates the internal properties using a validator object. The resulting
- * errors will be copied inside this entity and can be retrieved using the
- * `errors` method.
- *
- * This function returns true if there were no validation errors or false
- * otherwise.
- *
- * @param \Cake\Validation\Validator $validator The validator to use when validating the entity.
- * @return bool
- */
-	public function validate(Validator $validator) {
-		$data = $this->_properties;
-		$new = $this->isNew();
-		$validator->provider('entity', $this);
-		$this->errors($validator->errors($data, $new === null ? true : $new));
-		return empty($this->_errors);
-	}
-
-/**
  * Sets the error messages for a field or a list of fields. When called
  * without the second argument it returns the validation
  * errors for the specified fields. If called with no arguments it returns

+ 0 - 1
src/Datasource/composer.json

@@ -13,7 +13,6 @@
 	},
 	"suggest": {
 		"cakephp/utility": "Require this if you decide to use EntityTrait",
-		"cakephp/validation": "Require this if you decide to use EntityTrait",
 		"cakephp/collection": "Require this if you decide to use ResultSetInterface"
 	},
 	"autoload": {

+ 7 - 1
src/ORM/EntityValidator.php

@@ -18,6 +18,7 @@ use ArrayObject;
 use Cake\Datasource\EntityInterface;
 use Cake\ORM\Association;
 use Cake\ORM\Table;
+use Cake\Validation\ValidatableInterface;
 
 /**
  * Contains logic for validating entities and their associations.
@@ -118,6 +119,11 @@ class EntityValidator {
 		if (!isset($options['validate'])) {
 			$options['validate'] = true;
 		}
+
+		if (!($entity instanceof ValidatableInterface)) {
+			return $valid;
+		}
+
 		return $this->_processValidation($entity, $options) && $valid;
 	}
 
@@ -168,7 +174,7 @@ class EntityValidator {
 			return true;
 		}
 
-		$success = $entity->validate($validator);
+		$success = empty($entity->validate($validator));
 
 		$event = $this->_table->dispatchEvent('Model.afterValidate', $pass);
 		if ($event->isStopped()) {

+ 40 - 0
src/ORM/EntityValidatorTrait.php

@@ -0,0 +1,40 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\ORM;
+
+use Cake\Validation\Validator;
+
+/**
+ * Contains a method that can be used to apply a validator to an entity's internal
+ * properties. This trait can be used to satisfy the Cake\Validation\ValidatableInterface
+ */
+trait EntityValidatorTrait {
+
+/**
+ * Validates the internal properties using a validator object and returns any
+ * validation errors found.
+ *
+ * @param \Cake\Validation\Validator $validator The validator to use when validating the entity.
+ * @return array
+ */
+	public function validate(Validator $validator) {
+		$data = $this->_properties;
+		$new = $this->isNew();
+		$validator->provider('entity', $this);
+		$this->errors($validator->errors($data, $new === null ? true : $new));
+		return $this->_errors;
+	}
+
+}

+ 31 - 0
src/Validation/ValidatableInterface.php

@@ -0,0 +1,31 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Validation;
+
+/**
+ * Describes objects that can be validated by passing a Validator object.
+ */
+interface ValidatableInterface {
+
+/**
+ * Validates the internal properties using a validator object and returns any
+ * validation errors found.
+ *
+ * @param \Cake\Validation\Validator $validator The validator to use when validating the entity.
+ * @return array
+ */
+	public function validate(Validator $validator);
+
+}

+ 5 - 4
tests/TestCase/ORM/EntityTest.php

@@ -19,6 +19,7 @@ use Cake\TestSuite\TestCase;
 use Cake\Validation\Validator;
 use TestApp\Model\Entity\Extending;
 use TestApp\Model\Entity\NonExtending;
+use TestApp\Model\Entity\ValidatableEntity;
 
 /**
  * Entity test case.
@@ -741,7 +742,7 @@ class EntityTest extends TestCase {
  * @return void
  */
 	public function testValidateMissingFields() {
-		$entity = $this->getMockBuilder('\Cake\ORM\Entity')
+		$entity = $this->getMockBuilder('TestApp\Model\Entity\ValidatableEntity')
 			->setMethods(['getSomething'])
 			->disableOriginalConstructor()
 			->getMock();
@@ -756,7 +757,7 @@ class EntityTest extends TestCase {
 		$validator->expects($this->once())->method('errors')
 			->with(['a' => 'b'], true)
 			->will($this->returnValue(['a' => ['not valid']]));
-		$this->assertFalse($entity->validate($validator));
+		$this->assertNotEmpty($entity->validate($validator));
 		$this->assertEquals(['a' => ['not valid']], $entity->errors());
 	}
 
@@ -772,7 +773,7 @@ class EntityTest extends TestCase {
 			'cool' => false,
 			'something' => true
 		];
-		$entity = new Entity($data);
+		$entity = new ValidatableEntity($data);
 		$entity->isNew(true);
 
 		$validator->expects($this->once())
@@ -781,7 +782,7 @@ class EntityTest extends TestCase {
 		$validator->expects($this->once())->method('errors')
 			->with($data, true)
 			->will($this->returnValue([]));
-		$this->assertTrue($entity->validate($validator));
+		$this->assertEmpty($entity->validate($validator));
 		$this->assertEquals([], $entity->errors());
 	}
 

+ 43 - 37
tests/TestCase/ORM/EntityValidatorTest.php

@@ -63,7 +63,7 @@ class EntityValidatorTest extends TestCase {
  * @return void
  */
 	public function testOneSuccess() {
-		$entity = $this->getMock('\Cake\ORM\Entity', ['validate']);
+		$entity = $this->getMock('TestApp\Model\Entity\ValidatableEntity', ['validate']);
 		$validator = $this->getMock('\Cake\Validation\Validator');
 		$this->articles->validator('default', $validator);
 		$entityValidator = new EntityValidator($this->articles);
@@ -74,7 +74,7 @@ class EntityValidatorTest extends TestCase {
 		$entity->expects($this->once())
 			->method('validate')
 			->with($validator)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$this->assertTrue($entityValidator->one($entity));
 	}
@@ -85,7 +85,7 @@ class EntityValidatorTest extends TestCase {
  * @return void
  */
 	public function testOneFail() {
-		$entity = $this->getMock('\Cake\ORM\Entity', ['validate']);
+		$entity = $this->getMock('TestApp\Model\Entity\ValidatableEntity', ['validate']);
 		$validator = $this->getMock('\Cake\Validation\Validator');
 		$this->articles->validator('default', $validator);
 		$entityValidator = new EntityValidator($this->articles);
@@ -96,7 +96,7 @@ class EntityValidatorTest extends TestCase {
 		$entity->expects($this->once())
 			->method('validate')
 			->with($validator)
-			->will($this->returnValue(false));
+			->will($this->returnValue(['one' => ['error']]));
 
 		$this->assertFalse($entityValidator->one($entity));
 	}
@@ -107,10 +107,11 @@ class EntityValidatorTest extends TestCase {
  * @return void
  */
 	public function testOneAssociationsSuccess() {
-		$article = $this->getMock('\Cake\ORM\Entity', ['validate']);
-		$comment1 = $this->getMock('\Cake\ORM\Entity', ['validate']);
-		$comment2 = $this->getMock('\Cake\ORM\Entity', ['validate']);
-		$user = $this->getMock('\Cake\ORM\Entity', ['validate']);
+		$class = 'TestApp\Model\Entity\ValidatableEntity';
+		$article = $this->getMock($class, ['validate']);
+		$comment1 = $this->getMock($class, ['validate']);
+		$comment2 = $this->getMock($class, ['validate']);
+		$user = $this->getMock($class, ['validate']);
 		$article->set('comments', [$comment1, $comment2]);
 		$article->set('user', $user);
 
@@ -137,22 +138,22 @@ class EntityValidatorTest extends TestCase {
 		$article->expects($this->once())
 			->method('validate')
 			->with($validator1)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$comment1->expects($this->once())
 			->method('validate')
 			->with($validator2)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$comment2->expects($this->once())
 			->method('validate')
 			->with($validator2)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$user->expects($this->once())
 			->method('validate')
 			->with($validator3)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$options = ['associated' => ['Comments', 'Users']];
 		$this->assertTrue($entityValidator->one($article, $options));
@@ -167,10 +168,11 @@ class EntityValidatorTest extends TestCase {
  * @return void
  */
 	public function testOneAssociationsNoEntities() {
-		$article = $this->getMock('\Cake\ORM\Entity', ['validate']);
+		$class = 'TestApp\Model\Entity\ValidatableEntity';
+		$article = $this->getMock($class, ['validate']);
 		$comment1 = ['comment' => 'test'];
 		$comment2 = ['comment' => 'omg'];
-		$user = $this->getMock('\Cake\ORM\Entity', ['validate']);
+		$user = $this->getMock($class, ['validate']);
 		$article->set('comments', [$comment1, $comment2]);
 
 		$validator1 = $this->getMock('\Cake\Validation\Validator');
@@ -192,7 +194,7 @@ class EntityValidatorTest extends TestCase {
 		$article->expects($this->once())
 			->method('validate')
 			->with($validator1)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$options = ['associated' => ['Comments']];
 		$this->assertFalse($entityValidator->one($article, $options));
@@ -204,10 +206,11 @@ class EntityValidatorTest extends TestCase {
  * @return void
  */
 	public function testOneAssociationsFail() {
-		$article = $this->getMock('\Cake\ORM\Entity', ['validate']);
-		$comment1 = $this->getMock('\Cake\ORM\Entity', ['validate']);
-		$comment2 = $this->getMock('\Cake\ORM\Entity', ['validate']);
-		$user = $this->getMock('\Cake\ORM\Entity', ['validate']);
+		$class = 'TestApp\Model\Entity\ValidatableEntity';
+		$article = $this->getMock($class, ['validate']);
+		$comment1 = $this->getMock($class, ['validate']);
+		$comment2 = $this->getMock($class, ['validate']);
+		$user = $this->getMock($class, ['validate']);
 		$article->set('comments', [$comment1, $comment2]);
 		$article->set('user', $user);
 
@@ -234,22 +237,22 @@ class EntityValidatorTest extends TestCase {
 		$article->expects($this->once())
 			->method('validate')
 			->with($validator1)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$comment1->expects($this->once())
 			->method('validate')
 			->with($validator2)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$comment2->expects($this->once())
 			->method('validate')
 			->with($validator2)
-			->will($this->returnValue(false));
+			->will($this->returnValue(['some' => ['error']]));
 
 		$user->expects($this->once())
 			->method('validate')
 			->with($validator3)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$options = ['associated' => ['Comments', 'Users']];
 		$this->assertFalse($entityValidator->one($article, $options));
@@ -262,9 +265,10 @@ class EntityValidatorTest extends TestCase {
  * @return void
  */
 	public function testOneDeepAssociationsAndCustomValidators() {
-		$comment = $this->getMock('\Cake\ORM\Entity', ['validate']);
-		$article = $this->getMock('\Cake\ORM\Entity', ['validate']);
-		$user = $this->getMock('\Cake\ORM\Entity', ['validate']);
+		$class = 'TestApp\Model\Entity\ValidatableEntity';
+		$comment = $this->getMock($class, ['validate']);
+		$article = $this->getMock($class, ['validate']);
+		$user = $this->getMock($class, ['validate']);
 
 		$comment->set('article', $article);
 		$article->set('user', $user);
@@ -291,17 +295,17 @@ class EntityValidatorTest extends TestCase {
 		$comment->expects($this->once())
 			->method('validate')
 			->with($validator2)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$article->expects($this->once())
 			->method('validate')
 			->with($validator1)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$user->expects($this->once())
 			->method('validate')
 			->with($validator3)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$this->assertTrue($entityValidator->one($comment, [
 			'associated' => [
@@ -319,8 +323,9 @@ class EntityValidatorTest extends TestCase {
  * @return void
  */
 	public function testManySuccess() {
-		$comment1 = $this->getMock('\Cake\ORM\Entity', ['validate']);
-		$comment2 = $this->getMock('\Cake\ORM\Entity', ['validate']);
+		$class = 'TestApp\Model\Entity\ValidatableEntity';
+		$comment1 = $this->getMock($class, ['validate']);
+		$comment2 = $this->getMock($class, ['validate']);
 		$validator = $this->getMock('\Cake\Validation\Validator');
 		$data = [$comment1, $comment2];
 		$this->comments->validator('default', $validator);
@@ -332,12 +337,12 @@ class EntityValidatorTest extends TestCase {
 		$comment1->expects($this->once())
 			->method('validate')
 			->with($validator)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$comment2->expects($this->once())
 			->method('validate')
 			->with($validator)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$this->assertTrue($entityValidator->many($data));
 	}
@@ -348,8 +353,9 @@ class EntityValidatorTest extends TestCase {
  * @return void
  */
 	public function testManyFailure() {
-		$comment1 = $this->getMock('\Cake\ORM\Entity', ['validate']);
-		$comment2 = $this->getMock('\Cake\ORM\Entity', ['validate']);
+		$class = 'TestApp\Model\Entity\ValidatableEntity';
+		$comment1 = $this->getMock($class, ['validate']);
+		$comment2 = $this->getMock($class, ['validate']);
 		$validator = $this->getMock('\Cake\Validation\Validator');
 		$data = [$comment1, $comment2];
 		$this->comments->validator('default', $validator);
@@ -362,12 +368,12 @@ class EntityValidatorTest extends TestCase {
 		$comment1->expects($this->once())
 			->method('validate')
 			->with($validator)
-			->will($this->returnValue(false));
+			->will($this->returnValue(['some' => ['error']]));
 
 		$comment2->expects($this->once())
 			->method('validate')
 			->with($validator)
-			->will($this->returnValue(true));
+			->will($this->returnValue([]));
 
 		$this->assertFalse($entityValidator->many($data));
 	}

+ 17 - 0
tests/test_app/TestApp/Model/Entity/ValidatableEntity.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace TestApp\Model\Entity;
+
+use Cake\ORM\Entity;
+use Cake\ORM\EntityValidatorTrait;
+use Cake\Validation\ValidatableInterface;
+
+/**
+ * Tests entity class used for asserting correct loading
+ *
+ */
+class ValidatableEntity extends Entity implements ValidatableInterface {
+
+	use EntityValidatorTrait;
+
+}