10000 bug #21115 [Validator] do not guess getter method names (xabbuh) · rubenrua/symfony@eb0ffaa · GitHub
[go: up one dir, main page]

Skip to content

Commit eb0ffaa

Browse files
committed
bug symfony#21115 [Validator] do not guess getter method names (xabbuh)
This PR was merged into the 2.7 branch. Discussion ---------- [Validator] do not guess getter method names | Q | A | ------------- | --- | Branch? | 2.7 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony#5219, symfony#18700 | License | MIT | Doc PR | TODO Commits ------- bd3a90a [Validator] do not guess getter method names
2 parents 00c61da + bd3a90a commit eb0ffaa

File tree

6 files changed

+79
-20
lines changed

6 files changed

+79
-20
lines changed

src/Symfony/Component/Validator/Mapping/ClassMetadata.php

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,9 @@ public function addPropertyConstraints($property, array $constraints)
299299
* The name of the getter is assumed to be the name of the property with an
300300
* uppercased first letter and either the prefix "get" or "is".
301301
*
302-
* @param string $property The name of the property
303-
* @param Constraint $constraint The constraint
302+
* @param string $property The name of the property
303+
* @param Constraint $constraint The constraint
304+
* @param string|null $method The method that is called to retrieve the value being validated (null for auto-detection)
304305
*
305306
* @return $this
306307
*/
@@ -319,6 +320,30 @@ public function addGetterConstraint($property, Constraint $constraint)
319320
return $this;
320321
}
321322

323+
/**
324+
* Adds a constraint to the getter of the given property.
325+
*
326+
* @param string $property The name of the property
327+
* @param string $method The name of the getter method
328+
* @param Constraint $constraint The constraint
329+
*
330+
* @return $this
331+
*/
332+
public function addGetterMethodConstraint($property, $method, Constraint $constraint)
333+
{
334+
if (!isset($this->getters[$property])) {
335+
$this->getters[$property] = new GetterMetadata($this->getClassName(), $property, $method);
336+
337+
$this->addPropertyMetadata($this->getters[$property]);
338+
}
339+
340+
$constraint->addImplicitGroupName($this->getDefaultGroup());
341+
342+
$this->getters[$property]->addConstraint($constraint);
343+
344+
return $this;
345+
}
346+
322347
/**
323348
* @param string $property
324349
* @param Constraint[] $constraints
@@ -334,6 +359,22 @@ public function addGetterConstraints($property, array $constraints)
334359
return $this;
335360
}
336361

362+
/**
363+
* @param string $property
364+
* @param string $method
365+
* @param Constraint[] $constraints
366+
*
367+
* @return $this
368+
*/
369+
public function addGetterMethodConstraints($property, $method, array $constraints)
370+
{
371+
foreach ($constraints as $constraint) {
372+
$this->addGetterMethodConstraint($property, $method, $constraint);
373+
}
374+
375+
return $this;
376+
}
377+
337378
/**
338379
* Merges the constraints of the given metadata into this object.
339380
*

src/Symfony/Component/Validator/Mapping/GetterMetadata.php

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,30 @@ class GetterMetadata extends MemberMetadata
3535
/**
3636
* Constructor.
3737
*
38-
* @param string $class The class the getter is defined on
39-
* @param string $property The property which the getter returns
38+
* @param string $class The class the getter is defined on
39+
* @param string $property The property which the getter returns
40+
* @param string|null $method The method that is called to retrieve the value being validated (null for auto-detection)
4041
*
4142
* @throws ValidatorException
4243
*/
43-
public function __construct($class, $property)
44+
public function __construct($class, $property, $method = null)
4445
{
45-
$getMethod = 'get'.ucfirst($property);
46-
$isMethod = 'is'.ucfirst($property);
47-
$hasMethod = 'has'.ucfirst($property);
46+
if (null === $method) {
47+
$getMethod = 'get'.ucfirst($property);
48+
$isMethod = 'is'.ucfirst($property);
49+
$hasMethod = 'has'.ucfirst($property);
4850

49-
if (method_exists($class, $getMethod)) {
50-
$method = $getMethod;
51-
} elseif (method_exists($class, $isMethod)) {
52-
$method = $isMethod;
53-
} elseif (method_exists($class, $hasMethod)) {
54-
$method = $hasMethod;
55-
} else {
56-
throw new ValidatorException(sprintf('Neither of these methods exist in class %s: %s, %s, %s', $class, $getMethod, $isMethod, $hasMethod));
51+
if (method_exists($class, $getMethod)) {
52+
$method = $getMethod;
53+
} elseif (method_exists($class, $isMethod)) {
54+
$method = $isMethod;
55+
} elseif (method_exists($class, $hasMethod)) {
56+
$method = $hasMethod;
57+
} else {
58+
throw new ValidatorException(sprintf('Neither of these methods exist in class %s: %s, %s, %s', $class, $getMethod, $isMethod, $hasMethod));
59+
}
60+
} elseif (!method_exists($class, $method)) {
61+
throw new ValidatorException(sprintf('The %s() method does not exist in class %s.', $method, $class));
5762
}
5863

5964
parent::__construct($class, $method, $property);

src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public function loadClassMetadata(ClassMetadata $metadata)
7979
$metadata->addConstraint($constraint);
8080
} elseif ($constraint instanceof Constraint) {
8181
if (preg_match('/^(get|is|has)(.+)$/i', $method->name, $matches)) {
82-
$metadata->addGetterConstraint(lcfirst($matches[2]), $constraint);
82+
$metadata->addGetterMethodConstraint(lcfirst($matches[2]), $matches[0], $constraint);
8383
} else {
8484
throw new MappingException(sprintf('The constraint on "%s::%s" cannot be added. Constraints can only be added on methods beginning with "get", "is" or "has".', $className, $method->name));
8585
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ public function getLastName()
6363
return $this->lastName;
6464
}
6565

66+
public function getValid()
67+
{
68+
}
69+
6670
/**
6771
* @Assert\IsTrue
6872
*/

src/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function testGetPropertyValueFromOverriddenPublicGetter()
4848
public function testGetPropertyValueFromIsser()
4949
{
5050
$entity = new Entity();
51-
$metadata = new GetterMetadata(self::CLASSNAME, 'valid');
51+
$metadata = new GetterMetadata(self::CLASSNAME, 'valid', 'isValid');
5252

5353
$this->assertEquals('valid', $metadata->getPropertyValue($entity));
5454
}
@@ -60,4 +60,13 @@ public function testGetPropertyValueFromHasser()
6060

6161
$this->assertEquals('permissions', $metadata->getPropertyValue($entity));
6262
}
63+
64+
/**
65+
* @expectedException \Symfony\Component\Validator\Exception\ValidatorException
66+
* @expectedExceptionMessage The hasLastName() method does not exist in class Symfony\Component\Validator\Tests\Fixtures\Entity.
67+
*/
68+
public function testUndefinedMethodNameThrowsException()
69+
{
70+
new GetterMetadata(self::CLASSNAME, 'lastName', 'hasLastName');
71+
}
6372
}

src/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public function testLoadClassMetadata()
6969
'choices' => array('A', 'B'),
7070
)));
7171
$expected->addGetterConstraint('lastName', new NotNull());
72-
$expected->addGetterConstraint('valid', new IsTrue());
72+
$expected->addGetterMethodConstraint('valid', 'isValid', new IsTrue());
7373
$expected->addGetterConstraint('permissions', new IsTrue());
7474

7575
// load reflection class so that the comparison passes
@@ -139,7 +139,7 @@ public function testLoadClassMetadataAndMerge()
139139
'choices' => array('A', 'B'),
140140
)));
141141
$expected->addGetterConstraint('lastName', new NotNull());
142-
$expected->addGetterConstraint('valid', new IsTrue());
142+
$expected->addGetterMethodConstraint('valid', 'isValid', new IsTrue());
143143
$expected->addGetterConstraint('permissions', new IsTrue());
144144

145145
// load reflection class so that the comparison passes

0 commit comments

Comments
 (0)
0