8000 [DoctrineBridge] Fixed validating custom doctrine type columns · symfony/symfony@70d962c · GitHub
[go: up one dir, main page]

Skip to content

Commit 70d962c

Browse files
committed
[DoctrineBridge] Fixed validating custom doctrine type columns
1 parent 6ea510f commit 70d962c

File tree

5 files changed

+154
-2
lines changed

5 files changed

+154
-2
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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\Id;
15+
use Doctrine\ORM\Mapping\Column;
16+
use Doctrine\ORM\Mapping\Entity;
17+
use Symfony\Bridge\Doctrine\Tests\Fixtures\Type\StringWrapper;
18+
19+
/** @Entity */
20+
class SingleIntIdStringWrapperNameEntity
21+
{
22+
/** @Id @Column(type="integer") */
23+
protected $id;
24+
25+
/** @Column(type="string_wrapper", nullable=true) */
26+
public $name;
27+
28+
public function __construct($id, $name)
29+
{
30+
$this->id = $id;
31+
$this->name = $name;
32+
}
33+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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\Type;
13+
14+
class StringWrapper
15+
{
16+
/**
17+
* @var string
18+
*/
19+
private $string;
20+
21+
/**
22+
* @param string $string
23+
*/
24+
public function __construct($string = null)
25+
{
26+
$this->string = $string;
27+
}
28+
29+
/**
30+
* @return string
31+
*/
32+
public function getString()
33+
{
34+
return $this->string;
35+
}
36+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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\Type;
13+
14+
use Doctrine\DBAL\Platforms\AbstractPlatform;
15+
use Doctrine\DBAL\Types\StringType;
16+
17+
class StringWrapperType extends StringType
18+
{
19+
/**
20+
* {@inheritdoc}
21+
*/
22+
public function convertToDatabaseValue($value, AbstractPlatform $platform)
23+
{
24+
return $value instanceof StringWrapper ? $value->getString() : null;
25+
}
26+
27+
/**
28+
* {@inheritdoc}
29+
*/
30+
public function convertToPHPValue($value, AbstractPlatform $platform)
31+
{
32+
return new StringWrapper($value);
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
public function getName()
39+
{
40+
return 'string_wrapper';
41+
}
42+
}

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Doctrine\Common\Persistence\ManagerRegistry;
1616
use Doctrine\Common\Persistence\ObjectManager;
1717
use Doctrine\Common\Persistence\ObjectRepository;
18+
use Doctrine\DBAL\Types\Type;
1819
use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper;
1920
use Symfony\Bridge\Doctrine\Test\TestRepositoryFactory;
2021
use Symfony\Bridge\Doctrine\Tests\Fixtures\Employee;
@@ -26,6 +27,8 @@
2627
use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity;
2728
use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity2;
2829
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity;
30+
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdStringWrapperNameEntity;
31+
use Symfony\Bridge\Doctrine\Tests\Fixtures\Type\StringWrapper;
2932
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
3033
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator;
3134
use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
@@ -64,6 +67,10 @@ protected function setUp()
6467
$config = DoctrineTestHelper::createTestConfiguration();
6568
$config->setRepositoryFactory($this->repositoryFactory);
6669

70+
if (!Type::hasType('string_wrapper')) {
71+
Type::addType('string_wrapper', 'Symfony\Bridge\Doctrine\Tests\Fixtures\Type\StringWrapperType');
72+
}
73+
6774
$this->em = DoctrineTestHelper::createTestEntityManager($config);
6875
$this->registry = $this->createRegistryMock($this->em);
6976
$this->createSchema($this->em);
@@ -150,6 +157,7 @@ private function createSchema(ObjectManager $em)
150157
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\Person'),
151158
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\Employee'),
152159
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeObjectNoToStringIdEntity'),
160+
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdStringWrapperNameEntity'),
153161
));
154162
}
155163

@@ -700,4 +708,31 @@ public function testValidateUniquenessWithCompositeObjectNoToStringIdEntity()
700708
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
701709
->assertRaised();
702710
}
711+
712+
public function testValidateUniquenessWithCustomDoctrineTypeValue()
713+
{
714+
$constraint = new UniqueEntity(array(
715+
'message' => 'myMessage',
716+
'fields' => array('name'),
717+
'em' => self::EM_NAME,
718+
));
719+
720+
$existingEntity = new SingleIntIdStringWrapperNameEntity(1, new StringWrapper('foo'));
721+
722+
$this->em->persist($existingEntity);
723+
$this->em->flush();
724+
725+
$newEntity = new SingleIntIdStringWrapperNameEntity(2, new StringWrapper('foo'));
726+
727+
$this->validator->validate($newEntity, $constraint);
728+
729+
$expectedValue = 'object("Symfony\Bridge\Doctrine\Tests\Fixtures\Type\StringWrapper")';
730+
731+
$this->buildViolation('myMessage')
732+
->atPath('property.path.name')
733+
->setParameter('{{ value }}', $expectedValue)
734+
->setInvalidValue($existingEntity->name)
735+
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
736+
->assertRaised();
737+
}
703738
}

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,15 @@ private function formatWithIdentifiers(ObjectManager $em, ClassMetadata $class,
176176
return $this->formatValue($value, self::PRETTY_DATE);
177177
}
178178

179-
// non unique value is a composite PK
180179
if ($class->getName() !== $idClass = get_class($value)) {
181-
$identifiers = $em->getClassMetadata($idClass)->getIdentifierValues($value);
180+
// non unique value might be a composite PK that consists of other entity objects
181+
if ($em->getMetadataFactory()->hasMetadataFor($idClass)) {
182+
$identifiers = $em->getClassMetadata($idClass)->getIdentifierValues($value);
183+
} else {
184+
// this case might happen if the non unique column has a custom doctrine type and its value is an object
185+
// in which case we cannot get any identifiers for it
186+
$identifiers = array();
187+
}
182188
} else {
183189
$identifiers = $class->getIdentifierValues($value);
184190
}

0 commit comments

Comments
 (0)
0