feature #33459 [Validator] Deprecated CacheInterface in favor of PSR-6 (derrabus)
This PR was merged into the 4.4 branch.
Discussion
----------
[Validator] Deprecated CacheInterface in favor of PSR-6
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | yes
| Tests pass? | yes
| Fixed tickets | #33414
| License | MIT
| Doc PR | TODO
With PSR-6, the validator component does not need its own `CacheInterface`, so let's remove it.
Note that I still use the now deprecated `Psr6Cache` class to keep the logic inside `LazyLoadingMetadataFactory` simple. My plan would be to inline all logic from `Psr6Cache` into `LazyLoadingMetadataFactory` for 5.0.
Commits
-------
0b08040459
[Validator] Deprecated CacheInterface in favor of PSR-6.
This commit is contained in:
commit
eb0ffbc8a4
@ -313,6 +313,8 @@ Validator
|
|||||||
Set it to `true` to keep the current behavior and `false` to reject empty strings.
|
Set it to `true` to keep the current behavior and `false` to reject empty strings.
|
||||||
In 5.0, it'll become optional and will default to `false`.
|
In 5.0, it'll become optional and will default to `false`.
|
||||||
* Overriding the methods `ConstraintValidatorTestCase::setUp()` and `ConstraintValidatorTestCase::tearDown()` without the `void` return-type is deprecated.
|
* Overriding the methods `ConstraintValidatorTestCase::setUp()` and `ConstraintValidatorTestCase::tearDown()` without the `void` return-type is deprecated.
|
||||||
|
* deprecated `Symfony\Component\Validator\Mapping\Cache\CacheInterface` and all implementations in favor of PSR-6.
|
||||||
|
* deprecated `ValidatorBuilder::setMetadataCache`, use `ValidatorBuilder::setMappingCache` instead.
|
||||||
|
|
||||||
WebProfilerBundle
|
WebProfilerBundle
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -567,6 +567,8 @@ Validator
|
|||||||
* The `symfony/expression-language` component is now required for using the `Expression` constraint
|
* The `symfony/expression-language` component is now required for using the `Expression` constraint
|
||||||
* Changed the default value of `Length::$allowEmptyString` to `false` and made it optional
|
* Changed the default value of `Length::$allowEmptyString` to `false` and made it optional
|
||||||
* Added support for PHPUnit 8. A `void` return-type was added to the `ConstraintValidatorTestCase::setUp()` and `ConstraintValidatorTestCase::tearDown()` methods.
|
* Added support for PHPUnit 8. A `void` return-type was added to the `ConstraintValidatorTestCase::setUp()` and `ConstraintValidatorTestCase::tearDown()` methods.
|
||||||
|
* The `Symfony\Component\Validator\Mapping\Cache\CacheInterface` and all its implementations have been removed.
|
||||||
|
* The `ValidatorBuilder::setMetadataCache` has been removed, use `ValidatorBuilder::setMappingCache` instead.
|
||||||
|
|
||||||
WebProfilerBundle
|
WebProfilerBundle
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -15,7 +15,6 @@ use Doctrine\Common\Annotations\AnnotationException;
|
|||||||
use Psr\Cache\CacheItemPoolInterface;
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||||
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
|
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
|
||||||
use Symfony\Component\Validator\Mapping\Cache\Psr6Cache;
|
|
||||||
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
|
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
|
||||||
use Symfony\Component\Validator\Mapping\Loader\LoaderChain;
|
use Symfony\Component\Validator\Mapping\Loader\LoaderChain;
|
||||||
use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
|
use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
|
||||||
@ -59,7 +58,7 @@ class ValidatorCacheWarmer extends AbstractPhpFileCacheWarmer
|
|||||||
}
|
}
|
||||||
|
|
||||||
$loaders = $this->validatorBuilder->getLoaders();
|
$loaders = $this->validatorBuilder->getLoaders();
|
||||||
$metadataFactory = new LazyLoadingMetadataFactory(new LoaderChain($loaders), new Psr6Cache($arrayAdapter));
|
$metadataFactory = new LazyLoadingMetadataFactory(new LoaderChain($loaders), $arrayAdapter);
|
||||||
|
|
||||||
foreach ($this->extractSupportedLoaders($loaders) as $loader) {
|
foreach ($this->extractSupportedLoaders($loaders) as $loader) {
|
||||||
foreach ($loader->getMappedClasses() as $mappedClass) {
|
foreach ($loader->getMappedClasses() as $mappedClass) {
|
||||||
|
@ -1288,7 +1288,7 @@ class FrameworkExtension extends Extension
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$container->getParameter('kernel.debug')) {
|
if (!$container->getParameter('kernel.debug')) {
|
||||||
$validatorBuilder->addMethodCall('setMetadataCache', [new Reference('validator.mapping.cache.symfony')]);
|
$validatorBuilder->addMethodCall('setMappingCache', [new Reference('validator.mapping.cache.adapter')]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$container->setParameter('validator.auto_mapping', $config['auto_mapping']);
|
$container->setParameter('validator.auto_mapping', $config['auto_mapping']);
|
||||||
|
@ -39,14 +39,15 @@
|
|||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="validator.mapping.cache.symfony" class="Symfony\Component\Validator\Mapping\Cache\Psr6Cache">
|
<service id="validator.mapping.cache.symfony" class="Symfony\Component\Validator\Mapping\Cache\Psr6Cache">
|
||||||
<argument type="service">
|
<argument type="service" id="validator.mapping.cache.adapter" />
|
||||||
<service class="Symfony\Component\Cache\Adapter\PhpArrayAdapter">
|
<deprecated>The "%service_id%" service is deprecated since Symfony 4.4. Use validator.mapping.cache.adapter instead.</deprecated>
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<service id="validator.mapping.cache.adapter" class="Symfony\Component\Cache\Adapter\PhpArrayAdapter">
|
||||||
<factory class="Symfony\Component\Cache\Adapter\PhpArrayAdapter" method="create" />
|
<factory class="Symfony\Component\Cache\Adapter\PhpArrayAdapter" method="create" />
|
||||||
<argument>%validator.mapping.cache.file%</argument>
|
<argument>%validator.mapping.cache.file%</argument>
|
||||||
<argument type="service" id="cache.validator" />
|
<argument type="service" id="cache.validator" />
|
||||||
</service>
|
</service>
|
||||||
</argument>
|
|
||||||
</service>
|
|
||||||
|
|
||||||
<service id="validator.validator_factory" class="Symfony\Component\Validator\ContainerConstraintValidatorFactory">
|
<service id="validator.validator_factory" class="Symfony\Component\Validator\ContainerConstraintValidatorFactory">
|
||||||
<argument /> <!-- Constraint validators locator -->
|
<argument /> <!-- Constraint validators locator -->
|
||||||
|
@ -908,8 +908,8 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||||||
}
|
}
|
||||||
$this->assertSame('addMethodMapping', $calls[++$i][0]);
|
$this->assertSame('addMethodMapping', $calls[++$i][0]);
|
||||||
$this->assertSame(['loadValidatorMetadata'], $calls[$i][1]);
|
$this->assertSame(['loadValidatorMetadata'], $calls[$i][1]);
|
||||||
$this->assertSame('setMetadataCache', $calls[++$i][0]);
|
$this->assertSame('setMappingCache', $calls[++$i][0]);
|
||||||
$this->assertEquals([new Reference('validator.mapping.cache.symfony')], $calls[$i][1]);
|
$this->assertEquals([new Reference('validator.mapping.cache.adapter')], $calls[$i][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidationService()
|
public function testValidationService()
|
||||||
@ -951,8 +951,8 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||||||
$this->assertEquals([new Reference('annotation_reader')], $calls[4][1]);
|
$this->assertEquals([new Reference('annotation_reader')], $calls[4][1]);
|
||||||
$this->assertSame('addMethodMapping', $calls[5][0]);
|
$this->assertSame('addMethodMapping', $calls[5][0]);
|
||||||
$this->assertSame(['loadValidatorMetadata'], $calls[5][1]);
|
$this->assertSame(['loadValidatorMetadata'], $calls[5][1]);
|
||||||
$this->assertSame('setMetadataCache', $calls[6][0]);
|
$this->assertSame('setMappingCache', $calls[6][0]);
|
||||||
$this->assertEquals([new Reference('validator.mapping.cache.symfony')], $calls[6][1]);
|
$this->assertEquals([new Reference('validator.mapping.cache.adapter')], $calls[6][1]);
|
||||||
// no cache this time
|
// no cache this time
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -973,8 +973,8 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||||||
$this->assertSame('enableAnnotationMapping', $calls[5][0]);
|
$this->assertSame('enableAnnotationMapping', $calls[5][0]);
|
||||||
$this->assertSame('addMethodMapping', $calls[6][0]);
|
$this->assertSame('addMethodMapping', $calls[6][0]);
|
||||||
$this->assertSame(['loadValidatorMetadata'], $calls[6][1]);
|
$this->assertSame(['loadValidatorMetadata'], $calls[6][1]);
|
||||||
$this->assertSame('setMetadataCache', $calls[7][0]);
|
$this->assertSame('setMappingCache', $calls[7][0]);
|
||||||
$this->assertEquals([new Reference('validator.mapping.cache.symfony')], $calls[7][1]);
|
$this->assertEquals([new Reference('validator.mapping.cache.adapter')], $calls[7][1]);
|
||||||
|
|
||||||
$xmlMappings = $calls[3][1][0];
|
$xmlMappings = $calls[3][1][0];
|
||||||
$this->assertCount(3, $xmlMappings);
|
$this->assertCount(3, $xmlMappings);
|
||||||
@ -1033,8 +1033,8 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||||||
if ($annotations) {
|
if ($annotations) {
|
||||||
$this->assertSame('enableAnnotationMapping', $calls[++$i][0]);
|
$this->assertSame('enableAnnotationMapping', $calls[++$i][0]);
|
||||||
}
|
}
|
||||||
$this->assertSame('setMetadataCache', $calls[++$i][0]);
|
$this->assertSame('setMappingCache', $calls[++$i][0]);
|
||||||
$this->assertEquals([new Reference('validator.mapping.cache.symfony')], $calls[$i][1]);
|
$this->assertEquals([new Reference('validator.mapping.cache.adapter')], $calls[$i][1]);
|
||||||
// no cache, no annotations, no static methods
|
// no cache, no annotations, no static methods
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
"symfony/translation": "^4.3|^5.0",
|
"symfony/translation": "^4.3|^5.0",
|
||||||
"symfony/templating": "^3.4|^4.0|^5.0",
|
"symfony/templating": "^3.4|^4.0|^5.0",
|
||||||
"symfony/twig-bundle": "^4.4|^5.0",
|
"symfony/twig-bundle": "^4.4|^5.0",
|
||||||
"symfony/validator": "^4.1|^5.0",
|
"symfony/validator": "^4.4|^5.0",
|
||||||
"symfony/var-dumper": "^4.3|^5.0",
|
"symfony/var-dumper": "^4.3|^5.0",
|
||||||
"symfony/workflow": "^4.3|^5.0",
|
"symfony/workflow": "^4.3|^5.0",
|
||||||
"symfony/yaml": "^3.4|^4.0|^5.0",
|
"symfony/yaml": "^3.4|^4.0|^5.0",
|
||||||
@ -83,7 +83,7 @@
|
|||||||
"symfony/translation": "<4.3",
|
"symfony/translation": "<4.3",
|
||||||
"symfony/twig-bridge": "<4.1.1",
|
"symfony/twig-bridge": "<4.1.1",
|
||||||
"symfony/twig-bundle": "<4.4",
|
"symfony/twig-bundle": "<4.4",
|
||||||
"symfony/validator": "<4.1",
|
"symfony/validator": "<4.4",
|
||||||
"symfony/workflow": "<4.3"
|
"symfony/workflow": "<4.3"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
|
@ -22,6 +22,8 @@ CHANGELOG
|
|||||||
be used in the violation builder when both `min` and `max` are not null
|
be used in the violation builder when both `min` and `max` are not null
|
||||||
* added ability to use stringable objects as violation messages
|
* added ability to use stringable objects as violation messages
|
||||||
* Overriding the methods `ConstraintValidatorTestCase::setUp()` and `ConstraintValidatorTestCase::tearDown()` without the `void` return-type is deprecated.
|
* Overriding the methods `ConstraintValidatorTestCase::setUp()` and `ConstraintValidatorTestCase::tearDown()` without the `void` return-type is deprecated.
|
||||||
|
* deprecated `Symfony\Component\Validator\Mapping\Cache\CacheInterface` in favor of PSR-6.
|
||||||
|
* deprecated `ValidatorBuilder::setMetadataCache`, use `ValidatorBuilder::setMappingCache` instead.
|
||||||
|
|
||||||
4.3.0
|
4.3.0
|
||||||
-----
|
-----
|
||||||
|
@ -13,10 +13,14 @@ namespace Symfony\Component\Validator\Mapping\Cache;
|
|||||||
|
|
||||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
|
||||||
|
@trigger_error(sprintf('The "%s" interface is deprecated since Symfony 4.4.', CacheInterface::class), E_USER_DEPRECATED);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persists ClassMetadata instances in a cache.
|
* Persists ClassMetadata instances in a cache.
|
||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*
|
||||||
|
* @deprecated since Symfony 4.4.
|
||||||
*/
|
*/
|
||||||
interface CacheInterface
|
interface CacheInterface
|
||||||
{
|
{
|
||||||
|
@ -14,10 +14,14 @@ namespace Symfony\Component\Validator\Mapping\Cache;
|
|||||||
use Doctrine\Common\Cache\Cache;
|
use Doctrine\Common\Cache\Cache;
|
||||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
|
||||||
|
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4.', DoctrineCache::class), E_USER_DEPRECATED);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapts a Doctrine cache to a CacheInterface.
|
* Adapts a Doctrine cache to a CacheInterface.
|
||||||
*
|
*
|
||||||
* @author Florian Voutzinos <florian@voutzinos.com>
|
* @author Florian Voutzinos <florian@voutzinos.com>
|
||||||
|
*
|
||||||
|
* @deprecated since Symfony 4.4.
|
||||||
*/
|
*/
|
||||||
final class DoctrineCache implements CacheInterface
|
final class DoctrineCache implements CacheInterface
|
||||||
{
|
{
|
||||||
|
@ -14,10 +14,14 @@ namespace Symfony\Component\Validator\Mapping\Cache;
|
|||||||
use Psr\Cache\CacheItemPoolInterface;
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
|
||||||
|
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4.', Psr6Cache::class), E_USER_DEPRECATED);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PSR-6 adapter.
|
* PSR-6 adapter.
|
||||||
*
|
*
|
||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*
|
||||||
|
* @deprecated since Symfony 4.4.
|
||||||
*/
|
*/
|
||||||
class Psr6Cache implements CacheInterface
|
class Psr6Cache implements CacheInterface
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Validator\Mapping\Factory;
|
namespace Symfony\Component\Validator\Mapping\Factory;
|
||||||
|
|
||||||
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
use Symfony\Component\Validator\Exception\NoSuchMetadataException;
|
use Symfony\Component\Validator\Exception\NoSuchMetadataException;
|
||||||
use Symfony\Component\Validator\Mapping\Cache\CacheInterface;
|
use Symfony\Component\Validator\Mapping\Cache\CacheInterface;
|
||||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
@ -51,12 +52,17 @@ class LazyLoadingMetadataFactory implements MetadataFactoryInterface
|
|||||||
/**
|
/**
|
||||||
* Creates a new metadata factory.
|
* Creates a new metadata factory.
|
||||||
*
|
*
|
||||||
* @param LoaderInterface|null $loader The loader for configuring new metadata
|
* @param CacheItemPoolInterface|null $cache The cache for persisting metadata
|
||||||
* @param CacheInterface|null $cache The cache for persisting metadata
|
|
||||||
* between multiple PHP requests
|
* between multiple PHP requests
|
||||||
*/
|
*/
|
||||||
public function __construct(LoaderInterface $loader = null, CacheInterface $cache = null)
|
public function __construct(LoaderInterface $loader = null, $cache = null)
|
||||||
{
|
{
|
||||||
|
if ($cache instanceof CacheInterface) {
|
||||||
|
@trigger_error(sprintf('Passing a "%s" to "%s" is deprecated in Symfony 4.4 and will trigger a TypeError in 5.0. Please pass an implementation of "%s" instead.', \get_class($cache), __METHOD__, CacheItemPoolInterface::class), E_USER_DEPRECATED);
|
||||||
|
} elseif (!$cache instanceof CacheItemPoolInterface && null !== $cache) {
|
||||||
|
throw new \TypeError(sprintf('Expected an instance of %s, got %s.', CacheItemPoolInterface::class, \is_object($cache) ? \get_class($cache) : \gettype($cache)));
|
||||||
|
}
|
||||||
|
|
||||||
$this->loader = $loader;
|
$this->loader = $loader;
|
||||||
$this->cache = $cache;
|
$this->cache = $cache;
|
||||||
}
|
}
|
||||||
@ -92,12 +98,25 @@ class LazyLoadingMetadataFactory implements MetadataFactoryInterface
|
|||||||
throw new NoSuchMetadataException(sprintf('The class or interface "%s" does not exist.', $class));
|
throw new NoSuchMetadataException(sprintf('The class or interface "%s" does not exist.', $class));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $this->cache && false !== ($metadata = $this->cache->read($class))) {
|
$cacheItem = null;
|
||||||
|
if ($this->cache instanceof CacheInterface) {
|
||||||
|
if ($metadata = $this->cache->read($class)) {
|
||||||
// Include constraints from the parent class
|
// Include constraints from the parent class
|
||||||
$this->mergeConstraints($metadata);
|
$this->mergeConstraints($metadata);
|
||||||
|
|
||||||
return $this->loadedClasses[$class] = $metadata;
|
return $this->loadedClasses[$class] = $metadata;
|
||||||
}
|
}
|
||||||
|
} elseif (null !== $this->cache) {
|
||||||
|
$cacheItem = $this->cache->getItem($this->escapeClassName($class));
|
||||||
|
if ($cacheItem->isHit()) {
|
||||||
|
$metadata = $cacheItem->get();
|
||||||
|
|
||||||
|
// Include constraints from the parent class
|
||||||
|
$this->mergeConstraints($metadata);
|
||||||
|
|
||||||
|
return $this->loadedClasses[$class] = $metadata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$metadata = new ClassMetadata($class);
|
$metadata = new ClassMetadata($class);
|
||||||
|
|
||||||
@ -105,8 +124,10 @@ class LazyLoadingMetadataFactory implements MetadataFactoryInterface
|
|||||||
$this->loader->loadClassMetadata($metadata);
|
$this->loader->loadClassMetadata($metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $this->cache) {
|
if ($this->cache instanceof CacheInterface) {
|
||||||
$this->cache->write($metadata);
|
$this->cache->write($metadata);
|
||||||
|
} elseif (null !== $cacheItem) {
|
||||||
|
$this->cache->save($cacheItem->set($metadata));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include constraints from the parent class
|
// Include constraints from the parent class
|
||||||
@ -162,4 +183,17 @@ class LazyLoadingMetadataFactory implements MetadataFactoryInterface
|
|||||||
|
|
||||||
return class_exists($class) || interface_exists($class, false);
|
return class_exists($class) || interface_exists($class, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces backslashes by dots in a class name.
|
||||||
|
*/
|
||||||
|
private function escapeClassName(string $class): string
|
||||||
|
{
|
||||||
|
if (false !== strpos($class, '@')) {
|
||||||
|
// anonymous class: replace all PSR6-reserved characters
|
||||||
|
return str_replace(["\0", '\\', '/', '@', ':', '{', '}', '(', ')'], '.', $class);
|
||||||
|
}
|
||||||
|
|
||||||
|
return str_replace('\\', '.', $class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,9 @@ namespace Symfony\Component\Validator\Tests\Mapping\Cache;
|
|||||||
use Doctrine\Common\Cache\ArrayCache;
|
use Doctrine\Common\Cache\ArrayCache;
|
||||||
use Symfony\Component\Validator\Mapping\Cache\DoctrineCache;
|
use Symfony\Component\Validator\Mapping\Cache\DoctrineCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
class DoctrineCacheTest extends AbstractCacheTest
|
class DoctrineCacheTest extends AbstractCacheTest
|
||||||
{
|
{
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
|
@ -8,6 +8,8 @@ use Symfony\Component\Validator\Mapping\ClassMetadata;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
class Psr6CacheTest extends AbstractCacheTest
|
class Psr6CacheTest extends AbstractCacheTest
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
namespace Symfony\Component\Validator\Tests\Mapping\Factory;
|
namespace Symfony\Component\Validator\Tests\Mapping\Factory;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
|
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||||
use Symfony\Component\Validator\Constraints\Callback;
|
use Symfony\Component\Validator\Constraints\Callback;
|
||||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
|
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
|
||||||
@ -76,7 +78,36 @@ class LazyLoadingMetadataFactoryTest extends TestCase
|
|||||||
$this->assertEquals($constraints, $metadata->getConstraints());
|
$this->assertEquals($constraints, $metadata->getConstraints());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testWriteMetadataToCache()
|
public function testCachedMetadata()
|
||||||
|
{
|
||||||
|
$cache = new ArrayAdapter();
|
||||||
|
$factory = new LazyLoadingMetadataFactory(new TestLoader(), $cache);
|
||||||
|
|
||||||
|
$expectedConstraints = [
|
||||||
|
new ConstraintA(['groups' => ['Default', 'EntityParent']]),
|
||||||
|
new ConstraintA(['groups' => ['Default', 'EntityInterfaceA', 'EntityParent']]),
|
||||||
|
];
|
||||||
|
|
||||||
|
$metadata = $factory->getMetadataFor(self::PARENT_CLASS);
|
||||||
|
|
||||||
|
$this->assertEquals(self::PARENT_CLASS, $metadata->getClassName());
|
||||||
|
$this->assertEquals($expectedConstraints, $metadata->getConstraints());
|
||||||
|
|
||||||
|
$loader = $this->createMock(LoaderInterface::class);
|
||||||
|
$loader->expects($this->never())->method('loadClassMetadata');
|
||||||
|
|
||||||
|
$factory = new LazyLoadingMetadataFactory($loader, $cache);
|
||||||
|
|
||||||
|
$metadata = $factory->getMetadataFor(self::PARENT_CLASS);
|
||||||
|
|
||||||
|
$this->assertEquals(self::PARENT_CLASS, $metadata->getClassName());
|
||||||
|
$this->assertEquals($expectedConstraints, $metadata->getConstraints());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
|
public function testWriteMetadataToLegacyCache()
|
||||||
{
|
{
|
||||||
$cache = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Cache\CacheInterface')->getMock();
|
$cache = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Cache\CacheInterface')->getMock();
|
||||||
$factory = new LazyLoadingMetadataFactory(new TestLoader(), $cache);
|
$factory = new LazyLoadingMetadataFactory(new TestLoader(), $cache);
|
||||||
@ -115,7 +146,10 @@ class LazyLoadingMetadataFactoryTest extends TestCase
|
|||||||
$this->assertEquals($parentClassConstraints, $metadata->getConstraints());
|
$this->assertEquals($parentClassConstraints, $metadata->getConstraints());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testReadMetadataFromCache()
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
|
public function testReadMetadataFromLegacyCache()
|
||||||
{
|
{
|
||||||
$loader = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Loader\LoaderInterface')->getMock();
|
$loader = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Loader\LoaderInterface')->getMock();
|
||||||
$cache = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Cache\CacheInterface')->getMock();
|
$cache = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Cache\CacheInterface')->getMock();
|
||||||
@ -154,29 +188,19 @@ class LazyLoadingMetadataFactoryTest extends TestCase
|
|||||||
$this->expectException('Symfony\Component\Validator\Exception\NoSuchMetadataException');
|
$this->expectException('Symfony\Component\Validator\Exception\NoSuchMetadataException');
|
||||||
$testedValue = 'error@example.com';
|
$testedValue = 'error@example.com';
|
||||||
$loader = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Loader\LoaderInterface')->getMock();
|
$loader = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Loader\LoaderInterface')->getMock();
|
||||||
$cache = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Cache\CacheInterface')->getMock();
|
$cache = $this->createMock(CacheItemPoolInterface::class);
|
||||||
$factory = new LazyLoadingMetadataFactory($loader, $cache);
|
$factory = new LazyLoadingMetadataFactory($loader, $cache);
|
||||||
$cache
|
$cache
|
||||||
->expects($this->never())
|
->expects($this->never())
|
||||||
->method('read');
|
->method('getItem');
|
||||||
$factory->getMetadataFor($testedValue);
|
$factory->getMetadataFor($testedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMetadataCacheWithRuntimeConstraint()
|
public function testMetadataCacheWithRuntimeConstraint()
|
||||||
{
|
{
|
||||||
$cache = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Cache\CacheInterface')->getMock();
|
$cache = new ArrayAdapter();
|
||||||
$factory = new LazyLoadingMetadataFactory(new TestLoader(), $cache);
|
$factory = new LazyLoadingMetadataFactory(new TestLoader(), $cache);
|
||||||
|
|
||||||
$cache
|
|
||||||
->expects($this->any())
|
|
||||||
->method('write')
|
|
||||||
->willReturnCallback(function ($metadata) { serialize($metadata); })
|
|
||||||
;
|
|
||||||
|
|
||||||
$cache->expects($this->any())
|
|
||||||
->method('read')
|
|
||||||
->willReturn(false);
|
|
||||||
|
|
||||||
$metadata = $factory->getMetadataFor(self::PARENT_CLASS);
|
$metadata = $factory->getMetadataFor(self::PARENT_CLASS);
|
||||||
$metadata->addConstraint(new Callback(function () {}));
|
$metadata->addConstraint(new Callback(function () {}));
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\Validator\Tests;
|
namespace Symfony\Component\Validator\Tests;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
use Symfony\Component\Validator\Util\LegacyTranslatorProxy;
|
use Symfony\Component\Validator\Util\LegacyTranslatorProxy;
|
||||||
use Symfony\Component\Validator\ValidatorBuilder;
|
use Symfony\Component\Validator\ValidatorBuilder;
|
||||||
use Symfony\Component\Validator\ValidatorBuilderInterface;
|
use Symfony\Component\Validator\ValidatorBuilderInterface;
|
||||||
@ -85,6 +86,15 @@ class ValidatorBuilderTest extends TestCase
|
|||||||
$this->assertSame($this->builder, $this->builder->disableAnnotationMapping());
|
$this->assertSame($this->builder, $this->builder->disableAnnotationMapping());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSetMappingCache()
|
||||||
|
{
|
||||||
|
$this->assertSame($this->builder, $this->builder->setMappingCache($this->createMock(CacheItemPoolInterface::class)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
* @expectedDeprecation Symfony\Component\Validator\ValidatorBuilder::setMetadataCache is deprecated since Symfony 4.4. Use setMappingCache() instead.
|
||||||
|
*/
|
||||||
public function testSetMetadataCache()
|
public function testSetMetadataCache()
|
||||||
{
|
{
|
||||||
$this->assertSame($this->builder, $this->builder->setMetadataCache(
|
$this->assertSame($this->builder, $this->builder->setMetadataCache(
|
||||||
|
@ -15,6 +15,7 @@ use Doctrine\Common\Annotations\AnnotationReader;
|
|||||||
use Doctrine\Common\Annotations\CachedReader;
|
use Doctrine\Common\Annotations\CachedReader;
|
||||||
use Doctrine\Common\Annotations\Reader;
|
use Doctrine\Common\Annotations\Reader;
|
||||||
use Doctrine\Common\Cache\ArrayCache;
|
use Doctrine\Common\Cache\ArrayCache;
|
||||||
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
|
use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
|
||||||
use Symfony\Component\Validator\Context\ExecutionContextFactory;
|
use Symfony\Component\Validator\Context\ExecutionContextFactory;
|
||||||
use Symfony\Component\Validator\Exception\LogicException;
|
use Symfony\Component\Validator\Exception\LogicException;
|
||||||
@ -63,9 +64,9 @@ class ValidatorBuilder implements ValidatorBuilderInterface
|
|||||||
private $validatorFactory;
|
private $validatorFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var CacheInterface|null
|
* @var CacheItemPoolInterface|null
|
||||||
*/
|
*/
|
||||||
private $metadataCache;
|
private $mappingCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var TranslatorInterface|null
|
* @var TranslatorInterface|null
|
||||||
@ -228,15 +229,37 @@ class ValidatorBuilder implements ValidatorBuilderInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* Sets the cache for caching class metadata.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*
|
||||||
|
* @deprecated since Symfony 4.4.
|
||||||
*/
|
*/
|
||||||
public function setMetadataCache(CacheInterface $cache)
|
public function setMetadataCache(CacheInterface $cache)
|
||||||
{
|
{
|
||||||
|
@trigger_error(sprintf('%s is deprecated since Symfony 4.4. Use setMappingCache() instead.', __METHOD__), E_USER_DEPRECATED);
|
||||||
|
|
||||||
if (null !== $this->metadataFactory) {
|
if (null !== $this->metadataFactory) {
|
||||||
throw new ValidatorException('You cannot set a custom metadata cache after setting a custom metadata factory. Configure your metadata factory instead.');
|
throw new ValidatorException('You cannot set a custom metadata cache after setting a custom metadata factory. Configure your metadata factory instead.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->metadataCache = $cache;
|
$this->mappingCache = $cache;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cache for caching class metadata.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setMappingCache(CacheItemPoolInterface $cache)
|
||||||
|
{
|
||||||
|
$this->mappingCache = $cache;
|
||||||
|
|
||||||
|
if (null !== $this->metadataFactory) {
|
||||||
|
throw new ValidatorException('You cannot set a custom mapping cache after setting a custom metadata factory. Configure your metadata factory instead.');
|
||||||
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -330,7 +353,7 @@ class ValidatorBuilder implements ValidatorBuilderInterface
|
|||||||
$loader = $loaders[0];
|
$loader = $loaders[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
$metadataFactory = new LazyLoadingMetadataFactory($loader, $this->metadataCache);
|
$metadataFactory = new LazyLoadingMetadataFactory($loader, $this->mappingCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
$validatorFactory = $this->validatorFactory ?: new ConstraintValidatorFactory();
|
$validatorFactory = $this->validatorFactory ?: new ConstraintValidatorFactory();
|
||||||
|
Reference in New Issue
Block a user