Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit eed29d8

Browse files
committed
[Validator] Improved performance of *ContextualValidator::validate()
1 parent 5c479d8 commit eed29d8

File tree

7 files changed

+121
-39
lines changed

7 files changed

+121
-39
lines changed

src/Symfony/Component/Validator/Exception/ValidatorException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111

1212
namespace Symfony\Component\Validator\Exception;
1313

14-
class ValidatorException extends \RuntimeException
14+
class ValidatorException extends RuntimeException
1515
{
1616
}

src/Symfony/Component/Validator/Tests/Fixtures/FakeClassMetadata.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@
1111

1212
namespace Symfony\Component\Validator\Tests\Fixtures;
1313

14-
use Symfony\Component\Validator\ClassBasedInterface;
1514
use Symfony\Component\Validator\Mapping\ClassMetadata;
16-
use Symfony\Component\Validator\MetadataInterface;
17-
use Symfony\Component\Validator\PropertyMetadataContainerInterface;
1815

1916
class FakeClassMetadata extends ClassMetadata
2017
{

src/Symfony/Component/Validator/Tests/Fixtures/FakeMetadataFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ public function hasMetadataFor($class)
4949
$hash = null;
5050

5151
if (is_object($class)) {
52+
$hash = spl_object_hash($class);
5253
$class = get_class($class);
53-
$hash = spl_object_hash($hash);
5454
}
5555

5656
if (!is_string($class)) {

src/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,4 +650,12 @@ public function testNoDuplicateValidationIfPropertyConstraintInMultipleGroups()
650650
/** @var ConstraintViolationInterface[] $violations */
651651
$this->assertCount(1, $violations);
652652
}
653+
654+
/**
655+
* @expectedException \Symfony\Component\Validator\Exception\RuntimeException
656+
*/
657+
public function testValidateFailsIfNoConstraintsAndNoObjectOrArray()
658+
{
659+
$this->validate('Foobar');
660+
}
653661
}

src/Symfony/Component/Validator/Tests/Validator/AbstractValidatorTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,8 @@ public function testValidateProperty()
837837
}
838838

839839
/**
840+
* Cannot be UnsupportedMetadataException for BC with Symfony < 2.5.
841+
*
840842
* @expectedException \Symfony\Component\Validator\Exception\ValidatorException
841843
*/
842844
public function testValidatePropertyFailsIfPropertiesNotSupported()
@@ -903,6 +905,8 @@ public function testValidatePropertyValue()
903905
}
904906

905907
/**
908+
* Cannot be UnsupportedMetadataException for BC with Symfony < 2.5.
909+
*
906910
* @expectedException \Symfony\Component\Validator\Exception\ValidatorException
907911
*/
908912
public function testValidatePropertyValueFailsIfPropertiesNotSupported()

src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313

1414
use Symfony\Component\Validator\Constraint;
1515
use Symfony\Component\Validator\Constraints\GroupSequence;
16-
use Symfony\Component\Validator\Constraints\Valid;
1716
use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
1817
use Symfony\Component\Validator\Context\ExecutionContextInterface;
1918
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
2019
use Symfony\Component\Validator\Exception\NoSuchMetadataException;
20+
use Symfony\Component\Validator\Exception\RuntimeException;
2121
use Symfony\Component\Validator\Exception\UnsupportedMetadataException;
2222
use Symfony\Component\Validator\Exception\ValidatorException;
2323
use Symfony\Component\Validator\Mapping\CascadingStrategy;
@@ -90,28 +90,59 @@ public function atPath($path)
9090
*/
9191
public function validate($value, $constraints = null, $groups = null)
9292
{
93-
if (null === $constraints) {
94-
$constraints = array(new Valid());
95-
} elseif (!is_array($constraints)) {
96-
$constraints = array($constraints);
93+
$groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups;
94+
95+
if (null !== $constraints) {
96+
if (!is_array($constraints)) {
97+
$constraints = array($constraints);
98+
}
99+
100+
$metadata = new GenericMetadata();
101+
$metadata->addConstraints($constraints);
102+
103+
$this->traverseGenericNode(
104+
$value,
105+
null,
106+
$metadata,
107+
$this->defaultPropertyPath,
108+
$groups,
109+
null,
110+
TraversalStrategy::IMPLICIT,
111+
$this->context
112+
);
113+
114+
return $this;
97115
}
98116

99-
$metadata = new GenericMetadata();
100-
$metadata->addConstraints($constraints);
101-
$groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups;
117+
if (is_object($value)) {
118+
$this->cascadeObject(
119+
$value,
120+
$this->defaultPropertyPath,
121+
$groups,
122+
TraversalStrategy::IMPLICIT,
123+
$this->context
124+
);
102125

103-
$this->traverseGenericNode(
104-
$value,
105-
null,
106-
$metadata,
107-
$this->defaultPropertyPath,
108-
$groups,
109-
null,
110-
TraversalStrategy::IMPLICIT,
111-
$this->context
112-
);
126+
return $this;
127+
}
113128

114-
return $this;
129+
if (is_array($value)) {
130+
$this->cascadeCollection(
131+
$value,
132+
$this->defaultPropertyPath,
133+
$groups,
134+
TraversalStrategy::IMPLICIT,
135+
$this->context
136+
);
137+
138+
return $this;
139+
}
140+
141+
throw new RuntimeException(sprintf(
142+
'Cannot validate values of type "%s" automatically. Please '.
143+
'provide a constraint.',
144+
gettype($value)
145+
));
115146
}
116147

117148
/**
@@ -122,6 +153,8 @@ public function validateProperty($object, $propertyName, $groups = null)
122153
$classMetadata = $this->metadataFactory->getMetadataFor($object);
123154

124155
if (!$classMetadata instanceof ClassMetadataInterface) {
156+
// Cannot be UnsupportedMetadataException because of BC with
157+
// Symfony < 2.5
125158
throw new ValidatorException(sprintf(
126159
'The metadata factory should return instances of '.
127160
'"\Symfony\Component\Validator\Mapping\ClassMetadataInterface", '.
@@ -159,6 +192,8 @@ public function validatePropertyValue($object, $propertyName, $value, $groups =
159192
$classMetadata = $this->metadataFactory->getMetadataFor($object);
160193

161194
if (!$classMetadata instanceof ClassMetadataInterface) {
195+
// Cannot be UnsupportedMetadataException because of BC with
196+
// Symfony < 2.5
162197
throw new ValidatorException(sprintf(
163198
'The metadata factory should return instances of '.
164199
'"\Symfony\Component\Validator\Mapping\ClassMetadataInterface", '.

src/Symfony/Component/Validator/Validator/TraversingContextualValidator.php

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@
1212
namespace Symfony\Component\Validator\Validator;
1313

1414
use Symfony\Component\Validator\Constraint;
15-
use Symfony\Component\Validator\Constraints\Valid;
1615
use Symfony\Component\Validator\Context\ExecutionContextInterface;
16+
use Symfony\Component\Validator\Exception\RuntimeException;
17+
use Symfony\Component\Validator\Exception\UnsupportedMetadataException;
1718
use Symfony\Component\Validator\Exception\ValidatorException;
1819
use Symfony\Component\Validator\Mapping\ClassMetadataInterface;
1920
use Symfony\Component\Validator\Mapping\GenericMetadata;
2021
use Symfony\Component\Validator\MetadataFactoryInterface;
22+
use Symfony\Component\Validator\Node\ClassNode;
23+
use Symfony\Component\Validator\Node\CollectionNode;
2124
use Symfony\Component\Validator\Node\GenericNode;
2225
use Symfony\Component\Validator\Node\PropertyNode;
2326
use Symfony\Component\Validator\NodeTraverser\NodeTraverserInterface;
@@ -79,22 +82,53 @@ public function atPath($path)
7982
*/
8083
public function validate($value, $constraints = null, $groups = null)
8184
{
82-
if (null === $constraints) {
83-
$constraints = array(new Valid());
84-
} elseif (!is_array($constraints)) {
85-
$constraints = array($constraints);
86-
}
87-
88-
$metadata = new GenericMetadata();
89-
$metadata->addConstraints($constraints);
9085
$groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups;
9186

92-
$node = new GenericNode(
93-
$value,
94-
$metadata,
95-
$this->defaultPropertyPath,
96-
$groups
97-
);
87+
if (null !== $constraints) {
88+
if (!is_array($constraints)) {
89+
$constraints = array($constraints);
90+
}
91+
92+
$metadata = new GenericMetadata();
93+
$metadata->addConstraints($constraints);
94+
95+
$node = new GenericNode(
96+
$value,
97+
$metadata,
98+
$this->defaultPropertyPath,
99+
$groups
100+
);
101+
} elseif (is_array($value) || $value instanceof \Traversable && !$this->metadataFactory->hasMetadataFor($value)) {
102+
$node = new CollectionNode(
103+
$value,
104+
$this->defaultPropertyPath,
105+
$groups
106+
);
107+
} elseif (is_object($value)) {
108+
$metadata = $this->metadataFactory->getMetadataFor($value);
109+
110+
if (!$metadata instanceof ClassMetadataInterface) {
111+
throw new UnsupportedMetadataException(sprintf(
112+
'The metadata factory should return instances of '.
113+
'"\Symfony\Component\Validator\Mapping\ClassMetadataInterface", '.
114+
'got: "%s".',
115+
is_object($metadata) ? get_class($metadata) : gettype($metadata)
116+
));
117+
}
118+
119+
$node = new ClassNode(
120+
$value,
121+
$metadata,
122+
$this->defaultPropertyPath,
123+
$groups
124+
);
125+
} else {
126+
throw new RuntimeException(sprintf(
127+
'Cannot validate values of type "%s" automatically. Please '.
128+
'provide a constraint.',
129+
gettype($value)
130+
));
131+
}
98132

99133
$this->nodeTraverser->traverse(array($node), $this->context);
100134

@@ -109,6 +143,8 @@ public function validateProperty($object, $propertyName, $groups = null)
109143
$classMetadata = $this->metadataFactory->getMetadataFor($object);
110144

111145
if (!$classMetadata instanceof ClassMetadataInterface) {
146+
// Cannot be UnsupportedMetadataException because of BC with
147+
// Symfony < 2.5
112148
throw new ValidatorException(sprintf(
113149
'The metadata factory should return instances of '.
114150
'"\Symfony\Component\Validator\Mapping\ClassMetadataInterface", '.
@@ -146,6 +182,8 @@ public function validatePropertyValue($object, $propertyName, $value, $groups =
146182
$classMetadata = $this->metadataFactory->getMetadataFor($object);
147183

148184
if (!$classMetadata instanceof ClassMetadataInterface) {
185+
// Cannot be UnsupportedMetadataException because of BC with
186+
// Symfony < 2.5
149187
throw new ValidatorException(sprintf(
150188
'The metadata factory should return instances of '.
151189
'"\Symfony\Component\Validator\Mapping\ClassMetadataInterface", '.

0 commit comments

Comments
 (0)