do not merge constraints within interfaces
This commit is contained in:
parent
932a4f86ed
commit
67f336b808
@ -117,34 +117,25 @@ class LazyLoadingMetadataFactory implements MetadataFactoryInterface
|
|||||||
|
|
||||||
private function mergeConstraints(ClassMetadata $metadata)
|
private function mergeConstraints(ClassMetadata $metadata)
|
||||||
{
|
{
|
||||||
|
if ($metadata->getReflectionClass()->isInterface()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Include constraints from the parent class
|
// Include constraints from the parent class
|
||||||
if ($parent = $metadata->getReflectionClass()->getParentClass()) {
|
if ($parent = $metadata->getReflectionClass()->getParentClass()) {
|
||||||
$metadata->mergeConstraints($this->getMetadataFor($parent->name));
|
$metadata->mergeConstraints($this->getMetadataFor($parent->name));
|
||||||
}
|
}
|
||||||
|
|
||||||
$interfaces = $metadata->getReflectionClass()->getInterfaces();
|
|
||||||
|
|
||||||
$interfaces = array_filter($interfaces, function ($interface) use ($parent, $interfaces) {
|
|
||||||
$interfaceName = $interface->getName();
|
|
||||||
|
|
||||||
if ($parent && $parent->implementsInterface($interfaceName)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($interfaces as $i) {
|
|
||||||
if ($i !== $interface && $i->implementsInterface($interfaceName)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Include constraints from all directly implemented interfaces
|
// Include constraints from all directly implemented interfaces
|
||||||
foreach ($interfaces as $interface) {
|
foreach ($metadata->getReflectionClass()->getInterfaces() as $interface) {
|
||||||
if ('Symfony\Component\Validator\GroupSequenceProviderInterface' === $interface->name) {
|
if ('Symfony\Component\Validator\GroupSequenceProviderInterface' === $interface->name) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($parent && \in_array($interface->getName(), $parent->getInterfaceNames(), true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$metadata->mergeConstraints($this->getMetadataFor($interface->name));
|
$metadata->mergeConstraints($this->getMetadataFor($interface->name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Fixtures;
|
||||||
|
|
||||||
|
abstract class AbstractPropertyGetter implements PropertyGetterInterface
|
||||||
|
{
|
||||||
|
private $property;
|
||||||
|
|
||||||
|
public function getProperty()
|
||||||
|
{
|
||||||
|
return $this->property;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Fixtures;
|
||||||
|
|
||||||
|
interface ChildGetterInterface extends PropertyGetterInterface
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Fixtures;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class has two paths to PropertyGetterInterface:
|
||||||
|
* PropertyGetterInterface <- AbstractPropertyGetter <- PropertyGetter
|
||||||
|
* PropertyGetterInterface <- ChildGetterInterface <- PropertyGetter
|
||||||
|
*/
|
||||||
|
class PropertyGetter extends AbstractPropertyGetter implements ChildGetterInterface
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Fixtures;
|
||||||
|
|
||||||
|
interface PropertyGetterInterface
|
||||||
|
{
|
||||||
|
public function getProperty();
|
||||||
|
}
|
@ -14,11 +14,14 @@ namespace Symfony\Component\Validator\Tests\Mapping\Factory;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||||
use Symfony\Component\Validator\Constraints\Callback;
|
use Symfony\Component\Validator\Constraints\Callback;
|
||||||
|
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||||
use Symfony\Component\Validator\Mapping\Cache\Psr6Cache;
|
use Symfony\Component\Validator\Mapping\Cache\Psr6Cache;
|
||||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
|
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
|
||||||
use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
|
use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
|
||||||
use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
|
use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
|
||||||
|
use Symfony\Component\Validator\Tests\Fixtures\PropertyGetter;
|
||||||
|
use Symfony\Component\Validator\Tests\Fixtures\PropertyGetterInterface;
|
||||||
|
|
||||||
class LazyLoadingMetadataFactoryTest extends TestCase
|
class LazyLoadingMetadataFactoryTest extends TestCase
|
||||||
{
|
{
|
||||||
@ -70,7 +73,6 @@ class LazyLoadingMetadataFactoryTest extends TestCase
|
|||||||
new ConstraintA(['groups' => [
|
new ConstraintA(['groups' => [
|
||||||
'Default',
|
'Default',
|
||||||
'EntityParentInterface',
|
'EntityParentInterface',
|
||||||
'EntityInterfaceB',
|
|
||||||
'Entity',
|
'Entity',
|
||||||
]]),
|
]]),
|
||||||
];
|
];
|
||||||
@ -186,6 +188,15 @@ class LazyLoadingMetadataFactoryTest extends TestCase
|
|||||||
$this->assertContains('EntityStaticCar', $groups);
|
$this->assertContains('EntityStaticCar', $groups);
|
||||||
$this->assertContains('EntityStaticVehicle', $groups);
|
$this->assertContains('EntityStaticVehicle', $groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMultipathInterfaceConstraint()
|
||||||
|
{
|
||||||
|
$factory = new LazyLoadingMetadataFactory(new PropertyGetterInterfaceConstraintLoader());
|
||||||
|
$metadata = $factory->getMetadataFor(PropertyGetter::class);
|
||||||
|
$constraints = $metadata->getPropertyMetadata('property');
|
||||||
|
|
||||||
|
$this->assertCount(1, $constraints);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestLoader implements LoaderInterface
|
class TestLoader implements LoaderInterface
|
||||||
@ -195,3 +206,15 @@ class TestLoader implements LoaderInterface
|
|||||||
$metadata->addConstraint(new ConstraintA());
|
$metadata->addConstraint(new ConstraintA());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PropertyGetterInterfaceConstraintLoader implements LoaderInterface
|
||||||
|
{
|
||||||
|
public function loadClassMetadata(ClassMetadata $metadata)
|
||||||
|
{
|
||||||
|
if (PropertyGetterInterface::class === $metadata->getClassName()) {
|
||||||
|
$metadata->addGetterConstraint('property', new NotBlank());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user