Skip to content

Commit

Permalink
do not merge constraints within interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
greedyivan committed Feb 4, 2020
1 parent c2e0aab commit ba54d3e
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 24 deletions.
Expand Up @@ -117,35 +117,24 @@ public function getMetadataFor($value)

private function mergeConstraints(ClassMetadata $metadata)
{
// Include constraints from the parent class
if ($parent = $metadata->getReflectionClass()->getParentClass()) {
$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;
if (!$metadata->getReflectionClass()->isInterface()) {
// Include constraints from the parent class
if ($parent = $metadata->getReflectionClass()->getParentClass()) {
$metadata->mergeConstraints($this->getMetadataFor($parent->name));
}

foreach ($interfaces as $i) {
if ($i !== $interface && $i->implementsInterface($interfaceName)) {
return false;
// Include constraints from all directly implemented interfaces
foreach ($metadata->getReflectionClass()->getInterfaces() as $interface) {
if ('Symfony\Component\Validator\GroupSequenceProviderInterface' === $interface->name) {
continue;
}
}

return true;
});
if ($parent && \in_array($interface->getName(), $parent->getInterfaceNames(), true)) {
continue;
}

// Include constraints from all directly implemented interfaces
foreach ($interfaces as $interface) {
if ('Symfony\Component\Validator\GroupSequenceProviderInterface' === $interface->name) {
continue;
$metadata->mergeConstraints($this->getMetadataFor($interface->name));
}
$metadata->mergeConstraints($this->getMetadataFor($interface->name));
}
}

Expand Down
@@ -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
{
}
12 changes: 12 additions & 0 deletions src/Symfony/Component/Validator/Tests/Fixtures/PropertyGetter.php
@@ -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();
}
Expand Up @@ -14,11 +14,14 @@
use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Mapping\Cache\Psr6Cache;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
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
{
Expand Down Expand Up @@ -70,7 +73,6 @@ public function testMergeParentConstraints()
new ConstraintA(['groups' => [
'Default',
'EntityParentInterface',
'EntityInterfaceB',
'Entity',
]]),
];
Expand Down Expand Up @@ -186,6 +188,15 @@ public function testGroupsFromParent()
$this->assertContains('EntityStaticCar', $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
Expand All @@ -195,3 +206,15 @@ public function loadClassMetadata(ClassMetadata $metadata)
$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;
}
}

0 comments on commit ba54d3e

Please sign in to comment.