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 5568b27

Browse filesBrowse files
committed
[FrameworkBundle] Introduce a cache warmer for Validator based on PhpArrayAdapter
1 parent 983b560 commit 5568b27
Copy full SHA for 5568b27

File tree

18 files changed

+349
-76
lines changed
Filter options

18 files changed

+349
-76
lines changed
+112Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
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\Bundle\FrameworkBundle\CacheWarmer;
13+
14+
use Psr\Cache\CacheItemPoolInterface;
15+
use Symfony\Component\Cache\Adapter\AdapterInterface;
16+
use Symfony\Component\Cache\Adapter\ArrayAdapter;
17+
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
18+
use Symfony\Component\Cache\Adapter\ProxyAdapter;
19+
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
20+
use Symfony\Component\Validator\Mapping\Cache\Psr6Cache;
21+
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
22+
use Symfony\Component\Validator\Mapping\Loader\LoaderChain;
23+
use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
24+
use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader;
25+
use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader;
26+
use Symfony\Component\Validator\ValidatorBuilderInterface;
27+
28+
/**
29+
* Warms up XML and YAML validator metadata.
30+
*
31+
* @author Titouan Galopin <galopintitouan@gmail.com>
32+
*/
33+
class ValidatorCacheWarmer implements CacheWarmerInterface
34+
{
35+
private $validatorBuilder;
36+
private $phpArrayFile;
37+
private $fallbackPool;
38+
39+
/**
40+
* @param ValidatorBuilderInterface $validatorBuilder
41+
* @param string $phpArrayFile The PHP file where metadata are cached.
42+
* @param CacheItemPoolInterface $fallbackPool The pool where runtime-discovered metadata are cached.
43+
*/
44+
public function __construct(ValidatorBuilderInterface $validatorBuilder, $phpArrayFile, CacheItemPoolInterface $fallbackPool)
45+
{
46+
$this->validatorBuilder = $validatorBuilder;
47+
$this->phpArrayFile = $phpArrayFile;
48+
if (!$fallbackPool instanceof AdapterInterface) {
49+
$fallbackPool = new ProxyAdapter($fallbackPool);
50+
}
51+
$this->fallbackPool = $fallbackPool;
52+
}
53+
54+
/**
55+
* {@inheritdoc}
56+
*/
57+
public function warmUp($cacheDir)
58+
{
59+
if (!method_exists($this->validatorBuilder, 'getLoaders')) {
60+
return;
61+
}
62+
63+
$adapter = new PhpArrayAdapter($this->phpArrayFile, $this->fallbackPool);
64+
$arrayPool = new ArrayAdapter(0, false);
65+
66+
$loaders = $this->validatorBuilder->getLoaders();
67+
$metadataFactory = new LazyLoadingMetadataFactory(new LoaderChain($loaders), new Psr6Cache($arrayPool));
68+
69+
foreach ($this->extractSupportedLoaders($loaders) as $loader) {
70+
foreach ($loader->getMappedClasses() as $mappedClass) {
71+
$metadataFactory->getMetadataFor($mappedClass);
72+
}
73+
}
74+
75+
$values = $arrayPool->getValues();
76+
$adapter->warmUp($values);
77+
78+
foreach ($values as $k => $v) {
79+
$item = $this->fallbackPool->getItem($k);
80+
$this->fallbackPool->saveDeferred($item->set($v));
81+
}
82+
$this->fallbackPool->commit();
83+
}
84+
85+
/**
86+
* {@inheritdoc}
87+
*/
88+
public function isOptional()
89+
{
90+
return true;
91+
}
92+
93+
/**
94+
* @param LoaderInterface[] $loaders
95+
*
96+
* @return XmlFileLoader[]|YamlFileLoader[]
97+
*/
98+
private function extractSupportedLoaders(array $loaders)
99+
{
100+
$supportedLoaders = array();
101+
102+
foreach ($loaders as $loader) {
103+
if ($loader instanceof XmlFileLoader || $loader instanceof YamlFileLoader) {
104+
$supportedLoaders[] = $loader;
105+
} elseif ($loader instanceof LoaderChain) {
106+
$supportedLoaders = array_merge($supportedLoaders, $this->extractSupportedLoaders($loader->getDelegatedLoaders()));
107+
}
108+
}
109+
110+
return $supportedLoaders;
111+
}
112+
}

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ private function addValidationSection(ArrayNodeDefinition $rootNode)
567567
->info('validation configuration')
568568
->canBeEnabled()
569569
->children()
570-
->scalarNode('cache')->defaultValue('validator.mapping.cache.symfony')->end()
570+
->scalarNode('cache')->end()
571571
->booleanNode('enable_annotations')->defaultFalse()->end()
572572
->arrayNode('static_method')
573573
->defaultValue(array('loadValidatorMetadata'))

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -858,13 +858,17 @@ private function registerValidationConfiguration(array $config, ContainerBuilder
858858
}
859859
}
860860

861-
if (!$container->getParameter('kernel.debug')) {
861+
if (isset($config['cache']) && $config['cache']) {
862+
@trigger_error('The "framework.validation.cache" option is deprecated since Symfony 3.2 and will be removed in 4.0. Configure the "cache.validator" service under "framework.cache.pools" instead.', E_USER_DEPRECATED);
863+
862864
$container->setParameter(
863865
'validator.mapping.cache.prefix',
864866
'validator_'.$this->getKernelRootHash($container)
865867
);
866868

867869
$validatorBuilder->addMethodCall('setMetadataCache', array(new Reference($config['cache'])));
870+
} elseif (!$container->getParameter('kernel.debug')) {
871+
$validatorBuilder->addMethodCall('setMetadataCache', array(new Reference('validator.mapping.cache.symfony')));
868872
}
869873
}
870874

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml
+15-1Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
<parameters>
88
<parameter key="validator.mapping.cache.prefix" />
9+
<parameter key="validator.mapping.cache.file">%kernel.cache_dir%/validation.php</parameter>
910
</parameters>
1011

1112
<services>
@@ -28,8 +29,21 @@
2829

2930
<service id="validator.mapping.class_metadata_factory" alias="validator" public="false" />
3031

31-
<service id="validator.mapping.cache.symfony" class="Symfony\Component\Validator\Mapping\Cache\Psr6Cache" public="false">
32+
<service id="validator.mapping.cache_warmer" class="Symfony\Bundle\FrameworkBundle\CacheWarmer\ValidatorCacheWarmer" public="false">
33+
<argument type="service" id="validator.builder" />
34+
<argument>%validator.mapping.cache.file%</argument>
3235
<argument type="service" id="cache.validator" />
36+
<tag name="kernel.cache_warmer" />
37+
</service>
38+
39+
<service id="validator.mapping.cache.symfony" class="Symfony\Component\Validator\Mapping\Cache\Psr6Cache" public="false">
40+
<argument type="service">
41+
<service class="Symfony\Component\Cache\Adapter\PhpArrayAdapter">
42+
<factory class="Symfony\Component\Cache\Adapter\PhpArrayAdapter" method="create" />
43+
<argument>%validator.mapping.cache.file%</argument>
44+
<argument type="service" id="cache.validator" />
45+
</service>
46+
</argument>
3347
</service>
3448

3549
<service id="validator.mapping.cache.doctrine.apc" class="Symfony\Component\Validator\Mapping\Cache\DoctrineCache" public="false">
+78Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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\Bundle\FrameworkBundle\Tests\CacheWarmer;
13+
14+
use Symfony\Bundle\FrameworkBundle\CacheWarmer\ValidatorCacheWarmer;
15+
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
16+
use Symfony\Component\Cache\Adapter\ArrayAdapter;
17+
use Symfony\Component\Validator\ValidatorBuilder;
18+
19+
class ValidatorCacheWarmerTest extends TestCase
20+
{
21+
public function testWarmUp()
22+
{
23+
$validatorBuilder = new ValidatorBuilder();
24+
$validatorBuilder->addXmlMapping(__DIR__.'/../Fixtures/Validation/Resources/person.xml');
25+
$validatorBuilder->addYamlMapping(__DIR__.'/../Fixtures/Validation/Resources/author.yml');
26+
$validatorBuilder->addMethodMapping('loadValidatorMetadata');
27+
$validatorBuilder->enableAnnotationMapping();
28+
29+
$file = sys_get_temp_dir().'/cache-validator.php';
30+
@unlink($file);
31+
32+
$fallbackPool = new ArrayAdapter();
33+
34+
$warmer = new ValidatorCacheWarmer($validatorBuilder, $file, $fallbackPool);
35+
$warmer->warmUp(dirname($file));
36+
37+
$this->assertFileExists($file);
38+
39+
$values = require $file;
40+
41+
$this->assertInternalType('array', $values);
42+
$this->assertCount(2, $values);
43+
$this->assertArrayHasKey('Symfony.Bundle.FrameworkBundle.Tests.Fixtures.Validation.Person', $values);
44+
$this->assertArrayHasKey('Symfony.Bundle.FrameworkBundle.Tests.Fixtures.Validation.Person', $values);
45+
46+
$values = $fallbackPool->getValues();
47+
48+
$this->assertInternalType('array', $values);
49+
$this->assertCount(2, $values);
50+
$this->assertArrayHasKey('Symfony.Bundle.FrameworkBundle.Tests.Fixtures.Validation.Person', $values);
51+
$this->assertArrayHasKey('Symfony.Bundle.FrameworkBundle.Tests.Fixtures.Validation.Person', $values);
52+
}
53+
54+
public function testWarmUpWithoutLoader()
55+
{
56+
$validatorBuilder = new ValidatorBuilder();
57+
58+
$file = sys_get_temp_dir().'/cache-validator-without-loaders.php';
59+
@unlink($file);
60+
61+
$fallbackPool = new ArrayAdapter();
62+
63+
$warmer = new ValidatorCacheWarmer($validatorBuilder, $file, $fallbackPool);
64+
$warmer->warmUp(dirname($file));
65+
66+
$this->assertFileExists($file);
67+
68+
$values = require $file;
69+
70+
$this->assertInternalType('array', $values);
71+
$this->assertCount(0, $values);
72+
73+
$values = $fallbackPool->getValues();
74+
75+
$this->assertInternalType('array', $values);
76+
$this->assertCount(0, $values);
77+
}
78+
}

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ protected static function getBundleDefaultConfig()
211211
'static_method' => array('loadValidatorMetadata'),
212212
'translation_domain' => 'validators',
213213
'strict_email' => false,
214-
'cache' => 'validator.mapping.cache.symfony',
215214
),
216215
'annotations' => array(
217216
'cache' => 'php_array',

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
),
5757
'validation' => array(
5858
'enabled' => true,
59-
'cache' => 'validator.mapping.cache.doctrine.apc',
6059
),
6160
'annotations' => array(
6261
'cache' => 'file',

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
<framework:translator enabled="true" fallback="fr" logging="true">
3939
<framework:path>%kernel.root_dir%/Fixtures/translations</framework:path>
4040
</framework:translator>
41-
<framework:validation enabled="true" cache="validator.mapping.cache.doctrine.apc" />
41+
<framework:validation enabled="true" />
4242
<framework:annotations cache="file" debug="true" file-cache-dir="%kernel.cache_dir%/annotations" />
4343
<framework:serializer enabled="true" enable-annotations="true" name-converter="serializer.name_converter.camel_case_to_snake_case" />
4444
<framework:property-info />

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ framework:
4444
paths: ['%kernel.root_dir%/Fixtures/translations']
4545
validation:
4646
enabled: true
47-
cache: validator.mapping.cache.doctrine.apc
4847
annotations:
4948
cache: file
5049
debug: true

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ public function testValidation()
336336
$this->assertSame('addMethodMapping', $calls[4][0]);
337337
$this->assertSame(array('loadValidatorMetadata'), $calls[4][1]);
338338
$this->assertSame('setMetadataCache', $calls[5][0]);
339-
$this->assertEquals(array(new Reference('validator.mapping.cache.doctrine.apc')), $calls[5][1]);
339+
$this->assertEquals(array(new Reference('validator.mapping.cache.symfony')), $calls[5][1]);
340340
}
341341

342342
public function testValidationService()
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Validation;
4+
5+
class Author
6+
{
7+
public $gender;
8+
}
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Validation;
4+
5+
class Person
6+
{
7+
public $gender;
8+
}
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Validation\Author:
2+
properties:
3+
gender:
4+
- Choice: { choices: [male, female, other], message: Choose a valid gender. }
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
5+
6+
<class name="Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Validation\Person">
7+
<property name="gender">
8+
<constraint name="Choice">
9+
<option name="choices">
10+
<value>male</value>
11+
<value>female</value>
12+
<value>other</value>
13+
</option>
14+
<option name="message">Choose a valid gender.</option>
15+
</constraint>
16+
</property>
17+
</class>
18+
</constraint-mapping>

‎src/Symfony/Bundle/FrameworkBundle/composer.json

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/composer.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"symfony/expression-language": "~2.8|~3.0",
4949
"symfony/process": "~2.8|~3.0",
5050
"symfony/serializer": "~2.8|^3.0",
51-
"symfony/validator": "~3.1",
51+
"symfony/validator": "~3.2",
5252
"symfony/yaml": "~3.2",
5353
"symfony/property-info": "~2.8|~3.0",
5454
"phpdocumentor/reflection-docblock": "^3.0",

0 commit comments

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