Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 460fe7b

Browse filesBrowse files
committed
[DoctrineBridge] Fixed validating custom doctrine type columns
1 parent 96e7ded commit 460fe7b
Copy full SHA for 460fe7b

File tree

5 files changed

+162
-2
lines changed
Filter options

5 files changed

+162
-2
lines changed
+41Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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+
34+
/**
35+
* @return StringWrapper|null
36+
*/
37+
public function getName()
38+
{
39+
return $this->name;
40+
}
41+
}
+36Lines 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+
}
+42Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php
+35Lines 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\CompositeObjectNoToStringIdEntity;
@@ -23,6 +24,8 @@
2324
use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity;
2425
use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity2;
2526
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity;
27+
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdStringWrapperNameEntity;
28+
use Symfony\Bridge\Doctrine\Tests\Fixtures\Type\StringWrapper;
2629
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
2730
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator;
2831
use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
@@ -59,6 +62,10 @@ protected function setUp()
5962
$config = DoctrineTestHelper::createTestConfiguration();
6063
$config->setRepositoryFactory($this->repositoryFactory);
6164

65+
if (!Type::hasType('string_wrapper')) {
66+
Type::addType('string_wrapper', 'Symfony\Bridge\Doctrine\Tests\Fixtures\Type\StringWrapperType');
67+
}
68+
6269
$this->em = DoctrineTestHelper::createTestEntityManager($config);
6370
$this->registry = $this->createRegistryMock($this->em);
6471
$this->createSchema($this->em);
@@ -142,6 +149,7 @@ private function createSchema(ObjectManager $em)
142149
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity'),
143150
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity2'),
144151
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeObjectNoToStringIdEntity'),
152+
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdStringWrapperNameEntity'),
145153
));
146154
}
147155

@@ -614,4 +622,31 @@ public function testValidateUniquenessWithCompositeObjectNoToStringIdEntity()
614622
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
615623
->assertRaised();
616624
}
625+
626+
public function testValidateUniquenessWithCustomDoctrineTypeValue()
627+
{
628+
$constraint = new UniqueEntity(array(
629+
'message' => 'myMessage',
630+
'fields' => array('name'),
631+
'em' => self::EM_NAME,
632+
));
633+
634+
$existingEntity = new SingleIntIdStringWrapperNameEntity(1, new StringWrapper('foo'));
635+
636+
$this->em->persist($existingEntity);
637+
$this->em->flush();
638+
639+
$newEntity = new SingleIntIdStringWrapperNameEntity(2, new StringWrapper('foo'));
640+
641+
$this->validator->validate($newEntity, $constraint);
642+
643+
$expectedValue = 'object("Symfony\Bridge\Doctrine\Tests\Fixtures\Type\StringWrapper")';
644+
645+
$this->buildViolation('myMessage')
646+
->atPath('property.path.name')
647+
->setParameter('{{ value }}', $expectedValue)
648+
->setInvalidValue($existingEntity->getName())
649+
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
650+
->assertRaised();
651+
}
617652
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php
+8-2Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,15 @@ private function formatWithIdentifiers(ObjectManager $em, ClassMetadata $class,
151151
return $this->formatValue($value, self::PRETTY_DATE);
152152
}
153153

154-
// non unique value is a composite PK
155154
if ($class->getName() !== $idClass = get_class($value)) {
156-
$identifiers = $em->getClassMetadata($idClass)->getIdentifierValues($value);
155+
// non unique value might be a composite PK that consists of other entity objects
156+
if ($em->getMetadataFactory()->hasMetadataFor($idClass)) {
157+
$identifiers = $em->getClassMetadata($idClass)->getIdentifierValues($value);
158+
} else {
159+
// this case might happen if the non unique column has a custom doctrine type and its value is an object
160+
// in which case we cannot get any identifiers for it
161+
$identifiers = array();
162+
}
157163
} else {
158164
$identifiers = $class->getIdentifierValues($value);
159165
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.