bug #31085 [DoctrineBridge] Unique mapping setting is optional (ksaveras)

This PR was squashed before being merged into the 4.3-dev branch (closes #31085).

Discussion
----------

[DoctrineBridge] Unique mapping setting is optional

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

```sh
Executed script cache:clear  [KO]
 [KO]
Script cache:clear returned with error code 1
!!
!!   // Clearing the cache for the dev environment with debug
!!   // true
!!
!!
In DoctrineLoader.php line 71:

  [ErrorException]
  Notice: Undefined index: unique

Exception trace:
 () at /home/ksaveras/Projects/mokytojas.local/vendor/symfony/doctrine-bridge/Validator/DoctrineLoader.php:71
 Symfony\Bridge\Doctrine\Validator\DoctrineLoader->loadClassMetadata() at /home/ksaveras/Projects/mokytojas.local/vendor/symfony/validator/Mapping/Loader/LoaderChain.php:54
 Symfony\Component\Validator\Mapping\Loader\LoaderChain->loadClassMetadata() at /home/ksaveras/Projects/mokytojas.local/vendor/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php:105
 Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory->getMetadataFor() at /home/ksaveras/Projects/mokytojas.local/vendor/symfony/framework-bundle/CacheWarmer/ValidatorCacheWarmer.php:63
 Symfony\Bundle\FrameworkBundle\CacheWarmer\ValidatorCacheWarmer->doWarmUp() at /home/ksaveras/Projects/mokytojas.local/vendor/symfony/framework-bundle/CacheWarmer/AbstractPhpFileCacheWarmer.php:51
 Symfony\Bundle\FrameworkBundle\CacheWarmer\AbstractPhpFileCacheWarmer->warmUp() at /home/ksaveras/Projects/mokytojas.local/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php:96
 Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate->warmUp() at /home/ksaveras/Projects/mokytojas.local/vendor/symfony/framework-bundle/Command/CacheClearCommand.php:194
 Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand->warmup() at /home/ksaveras/Projects/mokytojas.local/vendor/symfony/framework-bundle/Command/CacheClearCommand.php:129
 Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand->execute() at /home/ksaveras/Projects/mokytojas.local/vendor/symfony/console/Command/Command.php:255
 Symfony\Component\Console\Command\Command->run() at /home/ksaveras/Projects/mokytojas.local/vendor/symfony/console/Application.php:930
 Symfony\Component\Console\Application->doRunCommand() at /home/ksaveras/Projects/mokytojas.local/vendor/symfony/framework-bundle/Console/Application.php:87
 Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /home/ksaveras/Projects/mokytojas.local/vendor/symfony/console/Application.php:273
 Symfony\Component\Console\Application->doRun() at /home/ksaveras/Projects/mokytojas.local/vendor/symfony/framework-bundle/Console/Application.php:73
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /home/ksaveras/Projects/mokytojas.local/vendor/symfony/console/Application.php:149
 Symfony\Component\Console\Application->run() at /home/ksaveras/Projects/mokytojas.local/bin/console:40

cache:clear [--no-warmup] [--no-optional-warmers] [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-e|--env ENV] [--no-debug] [--] <command>

./bin/console ca:cl
```

Commits
-------

fde4dc9922 [DoctrineBridge] Unique mapping setting is optional
This commit is contained in:
Fabien Potencier 2019-04-22 11:07:11 +02:00
commit 7e56ef1a3d
6 changed files with 128 additions and 1 deletions

View File

@ -13,9 +13,12 @@ namespace Symfony\Bridge\Doctrine\Test;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Cache\ArrayCache;
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
use Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
use Doctrine\ORM\Mapping\Driver\XmlDriver;
use PHPUnit\Framework\TestCase;
/**
@ -67,6 +70,28 @@ class DoctrineTestHelper
return $config;
}
/**
* @return Configuration
*/
public static function createTestConfigurationWithXmlLoader()
{
$config = static::createTestConfiguration();
$driverChain = new MappingDriverChain();
$driverChain->addDriver(
new XmlDriver(
new SymfonyFileLocator(
[__DIR__.'/../Tests/Resources/orm' => 'Symfony\\Bridge\\Doctrine\\Tests\\Fixtures'], '.orm.xml'
)
),
'Symfony\\Bridge\\Doctrine\\Tests\\Fixtures'
);
$config->setMetadataDriverImpl($driverChain);
return $config;
}
/**
* This class cannot be instantiated.
*/

View File

@ -0,0 +1,47 @@
<?php
namespace Symfony\Bridge\Doctrine\Tests\Fixtures;
/**
* Class BaseUser.
*/
class BaseUser
{
/**
* @var int
*/
private $id;
/**
* @var string
*/
private $username;
/**
* BaseUser constructor.
*
* @param int $id
* @param string $username
*/
public function __construct(int $id, string $username)
{
$this->id = $id;
$this->username = $username;
}
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @return string
*/
public function getUsername()
{
return $this->username;
}
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<mapped-superclass name="Symfony\Bridge\Doctrine\Tests\Fixtures\BaseUser">
<field name="username" column="username" type="string" length="120" />
</mapped-superclass>
</doctrine-mapping>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
<class name="Symfony\Bridge\Doctrine\Tests\Fixtures\BaseUser">
<property name="username">
<constraint name="NotBlank">
<option name="groups">Registration</option>
</constraint>
<constraint name="Length">
<option name="min">2</option>
<option name="max">120</option>
<option name="groups">Registration</option>
</constraint>
</property>
</class>
</constraint-mapping>

View File

@ -13,6 +13,7 @@ namespace Symfony\Bridge\Doctrine\Tests\Validator;
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper;
use Symfony\Bridge\Doctrine\Tests\Fixtures\BaseUser;
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderEntity;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Bridge\Doctrine\Validator\DoctrineLoader;
@ -72,6 +73,30 @@ class DoctrineLoaderTest extends TestCase
$this->assertSame(1, $alreadyMappedMaxLengthConstraints[0]->min);
}
public function testFieldMappingsConfiguration()
{
if (!method_exists(ValidatorBuilder::class, 'addLoader')) {
$this->markTestSkipped('Auto-mapping requires symfony/validation 4.2+');
}
$validator = Validation::createValidatorBuilder()
->enableAnnotationMapping()
->addXmlMappings([__DIR__.'/../Resources/validator/BaseUser.xml'])
->addLoader(
new DoctrineLoader(
DoctrineTestHelper::createTestEntityManager(
DoctrineTestHelper::createTestConfigurationWithXmlLoader()
), '{}'
)
)
->getValidator();
$classMetadata = $validator->getMetadataFor(new BaseUser(1, 'DemoUser'));
$constraints = $classMetadata->getConstraints();
$this->assertCount(0, $constraints);
}
/**
* @dataProvider regexpProvider
*/

View File

@ -68,7 +68,7 @@ final class DoctrineLoader implements LoaderInterface
// Type and nullable aren't handled here, use the PropertyInfo Loader instead.
foreach ($doctrineMetadata->fieldMappings as $mapping) {
if (true === $mapping['unique'] && !isset($existingUniqueFields[$mapping['fieldName']])) {
if (true === ($mapping['unique'] ?? false) && !isset($existingUniqueFields[$mapping['fieldName']])) {
$metadata->addConstraint(new UniqueEntity(['fields' => $mapping['fieldName']]));
}