8000 feature #15002 [DoctrineBridge] Add a way to select the repository us… · symfony/symfony@69e8654 · GitHub
[go: up one dir, main page]

Skip to content

Commit 69e8654

Browse files
committed
feature #15002 [DoctrineBridge] Add a way to select the repository used by the UniqueEntity validator (ogizanagi)
This PR was merged into the 3.2-dev branch. Discussion ---------- [DoctrineBridge] Add a way to select the repository used by the UniqueEntity validator | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #12573, #4087, #12977 | License | MIT | Doc PR | symfony/symfony-docs#7057 This is a cherry pick of #12977 on ~~2.8~~ 3.2 branch, as it is clearly a new feature, even if it was primary introduced in order to fix an inappropriate behavior that might be considered as a bug. Commits ------- 00d5459 [Doctrine] [Bridge] Add a way to select the repository used by the UniqueEntity validator
2 parents ac3eb5d + 00d5459 commit 69e8654

File tree

5 files changed

+134
-1
lines changed

5 files changed

+134
-1
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Tests\Fixtures;
13+
14+
use Doctrine\ORM\Mapping\Entity;
15+
16+
/** @Entity */
17+
class Employee extends Person
18+
{
19+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Tests\Fixtures;
13+
14+
use Doctrine\ORM\Mapping\DiscriminatorColumn;
15+
use Doctrine\ORM\Mapping\DiscriminatorMap;
16+
use Doctrine\ORM\Mapping\Id;
17+
use Doctrine\ORM\Mapping\Column;
18+
use Doctrine\ORM\Mapping\Entity;
19+
use Doctrine\ORM\Mapping\InheritanceType;
20+
21+
/**
22+
* @Entity
23+
* @InheritanceType("SINGLE_TABLE")
24+
* @DiscriminatorColumn(name="discr", type="string")
25+
* @DiscriminatorMap({"person" = "Person", "employee" = "Employee"})
26+
*/
27+
class Person
28+
{
29+
/** @Id @Column(type="integer") */
30+
protected $id;
31+
32+
/** @Column(type="string") */
33+
public $name;
34+
35+
public function __construct($id, $name)
36+
{
37+
$this->id = $id;
38+
$this->name = $name;
39+
}
40+
41+
public function __toString()
42+
{
43+
return (string) $this->name;
44+
}
45+
}

src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
use Doctrine\Common\Persistence\ObjectManager;
1717
use Doctrine\Common\Persistence\ObjectRepository;
1818
use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper;
19+
use Symfony\Bridge\Doctrine\Tests\Fixtures\Employee;
20+
use Symfony\Bridge\Doctrine\Tests\Fixtures\Person;
1921
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity;
2022
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity;
2123
use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity;
@@ -134,6 +136,8 @@ private function createSchema(ObjectManager $em)
134136
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity'),
135137
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity'),
136138
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity2'),
139+
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\Person'),
140+
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\Employee'),
137141
));
138142
}
139143

@@ -517,4 +521,54 @@ public function testEntityManagerNullObject()
517521

518522
$this->validator->validate($entity, $constraint);
519523
}
524+
525+
public function testValidateInheritanceUniqueness()
526+
{
527+
$constraint = new UniqueEntity(array(
528+
'message' => 'myMessage',
529+
'fields' => array('name'),
530+
'em' => self::EM_NAME,
531+
'entityClass' => 'Symfony\Bridge\Doctrine\Tests\Fixtures\Person',
532+
));
533+
534+
$entity1 = new Person(1, 'Foo');
535+
$entity2 = new Employee(2, 'Foo');
536+
537+
$this->validator->validate($entity1, $constraint);
538+
539+
$this->assertNoViolation();
540+
541+
$this->em->persist($entity1);
542+
$this->em->flush();
543+
544+
$this->validator->validate($entity1, $constraint);
545+
546+
$this->assertNoViolation();
547+
548+
$this->validator->validate($entity2, $constraint);
549+
550+
$this->buildViolation('myMessage')
551+
->atPath('property.path.name')
552+
->setInvalidValue('Foo')
553+
->setCode('23bd9dbf-6b9b-41cd-a99e-4844bcf3077f')
554+
->setParameters(array('{{ value }}' => 'Foo'))
555+
->assertRaised();
556+
}
557+
558+
/**
559+
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
560+
* @expectedExceptionMessage The "Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity" entity repository does not support the "Symfony\Bridge\Doctrine\Tests\Fixtures\Person" entity. The entity should be an instance of or extend "Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity".
561+
*/
562+
public function testInvalidateRepositoryForInheritance()
563+
{
564+
$constraint = new UniqueEntity(array(
565+
'message' => 'myMessage',
566+
'fields' => array('name'),
567+
'em' => self::EM_NAME,
568+
'entityClass' => 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity',
569+
));
570+
571+
$entity = new Person(1, 'Foo');
572+
$this->validator->validate($entity, $constraint);
573+
}
520574
}

src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class UniqueEntity extends Constraint
2828
public $message = 'This value is already used.';
2929
public $service = 'doctrine.orm.validator.unique';
3030
public $em = null;
31+
public $entityClass = null;
3132
public $repositoryMethod = 'findBy';
3233
public $fields = array();
3334
public $errorPath = null;

src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,21 @@ public function validate($entity, Constraint $constraint)
9999
}
100100
}
101101

102-
$repository = $em->getRepository(get_class($entity));
102+
if (null !== $constraint->entityClass) {
103+
/* Retrieve repository from given entity name.
104+
* We ensure the retrieved repository can handle the entity
105+
* by checking the entity is the same, or subclass of the supported entity.
106+
*/
107+
$repository = $em->getRepository($constraint->entityClass);
108+
$supportedClass = $repository->getClassName();
109+
110+
if (!$entity instanceof $supportedClass) {
111+
throw new ConstraintDefinitionException(sprintf('The "%s" entity repository does not support the "%s" entity. The entity should be an instance of or extend "%s".', $constraint->entityClass, $class->getName(), $supportedClass));
112+
}
113+
} else {
114+
$repository = $em->getRepository(get_class($entity));
115+
}
116+
103117
$result = $repository->{$constraint->repositoryMethod}($criteria);
104118

105119
if ($result instanceof \IteratorAggregate) {

0 commit comments

Comments
 (0)
0