/** * Checks if the given value is valid according to the validator, and returns * the Error Messages object which occurred. Will skip validation if value is * an uninitialized lazy loading proxy. * * @param mixed $value The value that should be validated * @return \Neos\Error\Messages\Result * @api */ public function validate($value) { $this->result = new Result(); /** * The idea is that Aggregates form a consistency boundary, and an Aggregate only needs to be * validated if it changed state. Also since all entity relations are lazy loaded by default, * and the relation will only be initialized when it gets accessed (e.g. during property mapping), * we can just skip validation of an uninitialized aggregate. * This greatly improves validation performance for domain models with lots of small aggregate * relations. Therefore proper Aggregate Design becomes a performance optimization. */ if ($value instanceof \Doctrine\ORM\Proxy\Proxy && !$value->__isInitialized()) { return $this->result; } return parent::validate($value); }
/** * @test */ public function collectionValidatorValidatesNestedObjectStructuresWithoutEndlessLooping() { $classNameA = 'A' . md5(uniqid(mt_rand(), true)); eval('class ' . $classNameA . '{ public $b = array(); public $integer = 5; }'); $classNameB = 'B' . md5(uniqid(mt_rand(), true)); eval('class ' . $classNameB . '{ public $a; public $c; public $integer = "Not an integer"; }'); $A = new $classNameA(); $B = new $classNameB(); $A->b = [$B]; $B->a = $A; $B->c = [$A]; $this->mockValidatorResolver->expects($this->any())->method('createValidator')->with('Integer')->will($this->returnValue(new IntegerValidator())); $this->mockValidatorResolver->expects($this->any())->method('buildBaseValidatorConjunction')->will($this->returnValue(new GenericObjectValidator())); // Create validators $aValidator = new GenericObjectValidator([]); $this->validator->_set('options', ['elementValidator' => 'Integer', 'elementValidatorOptions' => []]); $integerValidator = new IntegerValidator([]); // Add validators to properties $aValidator->addPropertyValidator('b', $this->validator); $aValidator->addPropertyValidator('integer', $integerValidator); $result = $aValidator->validate($A)->getFlattenedErrors(); $this->assertEquals('A valid integer number is expected.', $result['b.0'][0]->getMessage()); }