Skip to content

Commit

Permalink
bug #21656 [DoctrineBridge] Fixed validating custom doctrine type col…
Browse files Browse the repository at this point in the history
…umns (dmaicher)

This PR was merged into the 3.2 branch.

Discussion
----------

[DoctrineBridge] Fixed validating custom doctrine type columns

| Q             | A
| ------------- | ---
| Branch?       | 3.1
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #21619
| License       | MIT
| Doc PR        | -

This fixes #21619 by not assuming the invalid `$value` is a Doctrine entity if its an object

Commits
-------

ad59370 [DoctrineBridge] Fixed validating custom doctrine type columns
  • Loading branch information
fabpot committed Feb 21, 2017
2 parents 442cf59 + ad59370 commit fbcd227
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 2 deletions.
@@ -0,0 +1,33 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bridge\Doctrine\Tests\Fixtures;

use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Symfony\Bridge\Doctrine\Tests\Fixtures\Type\StringWrapper;

/** @Entity */
class SingleIntIdStringWrapperNameEntity
{
/** @Id @Column(type="integer") */
protected $id;

/** @Column(type="string_wrapper", nullable=true) */
public $name;

public function __construct($id, $name)
{
$this->id = $id;
$this->name = $name;
}
}
36 changes: 36 additions & 0 deletions src/Symfony/Bridge/Doctrine/Tests/Fixtures/Type/StringWrapper.php
@@ -0,0 +1,36 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bridge\Doctrine\Tests\Fixtures\Type;

class StringWrapper
{
/**
* @var string
*/
private $string;

/**
* @param string $string
*/
public function __construct($string = null)
{
$this->string = $string;
}

/**
* @return string
*/
public function getString()
{
return $this->string;
}
}
@@ -0,0 +1,42 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bridge\Doctrine\Tests\Fixtures\Type;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\StringType;

class StringWrapperType extends StringType
{
/**
* {@inheritdoc}
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return $value instanceof StringWrapper ? $value->getString() : null;
}

/**
* {@inheritdoc}
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return new StringWrapper($value);
}

/**
* {@inheritdoc}
*/
public function getName()
{
return 'string_wrapper';
}
}
Expand Up @@ -15,6 +15,7 @@
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ObjectRepository;
use Doctrine\DBAL\Types\Type;
use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper;
use Symfony\Bridge\Doctrine\Test\TestRepositoryFactory;
use Symfony\Bridge\Doctrine\Tests\Fixtures\Employee;
Expand All @@ -26,6 +27,8 @@
use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity;
use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity2;
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity;
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdStringWrapperNameEntity;
use Symfony\Bridge\Doctrine\Tests\Fixtures\Type\StringWrapper;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator;
use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
Expand Down Expand Up @@ -64,6 +67,10 @@ protected function setUp()
$config = DoctrineTestHelper::createTestConfiguration();
$config->setRepositoryFactory($this->repositoryFactory);

if (!Type::hasType('string_wrapper')) {
Type::addType('string_wrapper', 'Symfony\Bridge\Doctrine\Tests\Fixtures\Type\StringWrapperType');
}

$this->em = DoctrineTestHelper::createTestEntityManager($config);
$this->registry = $this->createRegistryMock($this->em);
$this->createSchema($this->em);
Expand Down Expand Up @@ -150,6 +157,7 @@ private function createSchema(ObjectManager $em)
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\Person'),
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\Employee'),
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeObjectNoToStringIdEntity'),
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdStringWrapperNameEntity'),
));
}

Expand Down Expand Up @@ -700,4 +708,31 @@ public function testValidateUniquenessWithCompositeObjectNoToStringIdEntity()
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
->assertRaised();
}

public function testValidateUniquenessWithCustomDoctrineTypeValue()
{
$constraint = new UniqueEntity(array(
'message' => 'myMessage',
'fields' => array('name'),
'em' => self::EM_NAME,
));

$existingEntity = new SingleIntIdStringWrapperNameEntity(1, new StringWrapper('foo'));

$this->em->persist($existingEntity);
$this->em->flush();

$newEntity = new SingleIntIdStringWrapperNameEntity(2, new StringWrapper('foo'));

$this->validator->validate($newEntity, $constraint);

$expectedValue = 'object("Symfony\Bridge\Doctrine\Tests\Fixtures\Type\StringWrapper")';

$this->buildViolation('myMessage')
->atPath('property.path.name')
->setParameter('{{ value }}', $expectedValue)
->setInvalidValue($existingEntity->name)
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
->assertRaised();
}
}
Expand Up @@ -176,9 +176,15 @@ private function formatWithIdentifiers(ObjectManager $em, ClassMetadata $class,
return $this->formatValue($value, self::PRETTY_DATE);
}

// non unique value is a composite PK
if ($class->getName() !== $idClass = get_class($value)) {
$identifiers = $em->getClassMetadata($idClass)->getIdentifierValues($value);
// non unique value might be a composite PK that consists of other entity objects
if ($em->getMetadataFactory()->hasMetadataFor($idClass)) {
$identifiers = $em->getClassMetadata($idClass)->getIdentifierValues($value);
} else {
// this case might happen if the non unique column has a custom doctrine type and its value is an object
// in which case we cannot get any identifiers for it
$identifiers = array();
}
} else {
$identifiers = $class->getIdentifierValues($value);
}
Expand Down

0 comments on commit fbcd227

Please sign in to comment.