[FrameworkBundle] Serializer groups support

This commit is contained in:
Kévin Dunglas 2014-12-25 04:17:33 +01:00 committed by Fabien Potencier
parent 6963887589
commit 83b56f60d0
9 changed files with 132 additions and 4 deletions

View File

@ -660,6 +660,10 @@ class Configuration implements ConfigurationInterface
->arrayNode('serializer')
->info('serializer configuration')
->canBeEnabled()
->children()
->booleanNode('enable_annotations')->defaultFalse()->end()
->scalarNode('cache')->end()
->end()
->end()
->end()
;

View File

@ -13,6 +13,7 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Reference;
@ -29,6 +30,7 @@ use Symfony\Component\Validator\Validation;
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jeremy Mikola <jmikola@gmail.com>
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class FrameworkExtension extends Extension
{
@ -121,11 +123,10 @@ class FrameworkExtension extends Extension
}
$this->registerAnnotationsConfiguration($config['annotations'], $container, $loader);
$this->registerPropertyAccessConfiguration($config['property_access'], $container);
if (isset($config['serializer']) && $config['serializer']['enabled']) {
$loader->load('serializer.xml');
if (isset($config['serializer'])) {
$this->registerSerializerConfiguration($config['serializer'], $container, $loader);
}
$loader->load('debug_prod.xml');
@ -866,6 +867,86 @@ class FrameworkExtension extends Extension
$loader->load('security_csrf.xml');
}
/**
* Loads the serializer configuration.
*
* @param array $config A serializer configuration array
* @param ContainerBuilder $container A ContainerBuilder instance
* @param XmlFileLoader $loader An XmlFileLoader instance
*/
private function registerSerializerConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
{
if (!$config['enabled']) {
return;
}
$loader->load('serializer.xml');
$chainLoader = $container->getDefinition('serializer.mapping.chain_loader');
$serializerLoaders = array();
if (isset($config['enable_annotations']) && $config['enable_annotations']) {
$annotationLoader = new Definition(
'Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader',
array(new Reference('annotation_reader'))
);
$annotationLoader->setPublic(false);
$serializerLoaders[] = $annotationLoader;
}
$bundles = $container->getParameter('kernel.bundles');
foreach ($bundles as $bundle) {
$reflection = new \ReflectionClass($bundle);
$dirname = dirname($reflection->getFilename());
if (is_file($file = $dirname.'/Resources/config/serialization.xml')) {
$definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader', array(realpath($file)));
$definition->setPublic(false);
$serializerLoaders[] = $definition;
$container->addResource(new FileResource($file));
}
if (is_file($file = $dirname.'/Resources/config/serialization.yml')) {
$definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader', array(realpath($file)));
$definition->setPublic(false);
$serializerLoaders[] = $definition;
$container->addResource(new FileResource($file));
}
if (is_dir($dir = $dirname.'/Resources/config/serialization')) {
foreach (Finder::create()->files()->in($dir)->name('*.xml') as $file) {
$definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader', array($file->getRealpath()));
$definition->setPublic(false);
$serializerLoaders[] = $definition;
}
foreach (Finder::create()->files()->in($dir)->name('*.yml') as $file) {
$definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader', array($file->getRealpath()));
$definition->setPublic(false);
$serializerLoaders[] = $definition;
}
$container->addResource(new DirectoryResource($dir));
}
}
$chainLoader->replaceArgument(0, $serializerLoaders);
if (isset($config['cache']) && $config['cache']) {
$container->setParameter(
'serializer.mapping.cache.prefix',
'serializer_'.hash('sha256', $container->getParameter('kernel.root_dir'))
);
$container->getDefinition('serializer.mapping.class_metadata_factory')->replaceArgument(
1, new Reference($config['cache'])
);
}
}
/**
* Returns the base path for the XSD files.
*

View File

@ -32,6 +32,7 @@
<xsd:element name="validation" type="validation" minOccurs="0" maxOccurs="1" />
<xsd:element name="annotations" type="annotations" minOccurs="0" maxOccurs="1" />
<xsd:element name="property-access" type="property_access" minOccurs="0" maxOccurs="1" />
<xsd:element name="serializer" type="serializer" minOccurs="0" maxOccurs="1" />
</xsd:all>
<xsd:attribute name="http-method-override" type="xsd:boolean" />
@ -210,4 +211,10 @@
<xsd:attribute name="magic-call" type="xsd:boolean" />
<xsd:attribute name="throw-exception-on-invalid-index" type="xsd:boolean" />
</xsd:complexType>
<xsd:complexType name="serializer">
<xsd:attribute name="enabled" type="xsd:boolean" />
<xsd:attribute name="cache" type="xsd:string" />
<xsd:attribute name="enable-annotations" type="xsd:boolean" />
</xsd:complexType>
</xsd:schema>

View File

@ -17,11 +17,31 @@
</service>
<!-- Normalizer -->
<service id="serializer.normalizer.get_set_method" class="Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer" public="false">
<service id="serializer.normalizer.object" class="Symfony\Component\Serializer\Normalizer\ObjectNormalizer" public="false">
<argument type="service" id="serializer.mapping.class_metadata_factory" />
<!-- Run after all custom serializers -->
<tag name="serializer.normalizer" priority="-1000" />
</service>
<!-- Loader -->
<service id="serializer.mapping.chain_loader" class="Symfony\Component\Serializer\Mapping\Loader\LoaderChain" public="false">
<argument type="collection" />
</service>
<!-- Class Metadata Factory -->
<service id="serializer.mapping.class_metadata_factory" class="Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory" public="false">
<argument type="service" id="serializer.mapping.chain_loader" />
<argument>null</argument>
</service>
<!-- Cache -->
<service id="serializer.mapping.cache.apc" class="Doctrine\Common\Cache\ApcCache" public="false">
<call method="setNamespace">
<argument>%serializer.mapping.cache.prefix%</argument>
</call>
</service>
<!-- Encoders -->
<service id="serializer.encoder.xml" class="%serializer.encoder.xml.class%" public="false" >
<tag name="serializer.encoder" />

View File

@ -161,6 +161,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
),
'serializer' => array(
'enabled' => false,
'enable_annotations' => false,
),
'property_access' => array(
'magic_call' => false,

View File

@ -60,6 +60,7 @@ $container->loadFromExtension('framework', array(
'debug' => true,
'file_cache_dir' => '%kernel.cache_dir%/annotations',
),
'serializer' => array('enabled' => true),
'ide' => 'file%%link%%format',
'request' => array(
'formats' => array(

View File

@ -37,5 +37,6 @@
<framework:translator enabled="true" fallback="fr" logging="true" />
<framework:validation enabled="true" cache="apc" />
<framework:annotations cache="file" debug="true" file-cache-dir="%kernel.cache_dir%/annotations" />
<framework:serializer enabled="true" />
</framework:config>
</container>

View File

@ -46,6 +46,7 @@ framework:
cache: file
debug: true
file_cache_dir: %kernel.cache_dir%/annotations
serializer: { enabled: true }
ide: file%%link%%format
request:
formats:

View File

@ -498,6 +498,18 @@ abstract class FrameworkExtensionTest extends TestCase
$this->assertTrue($container->has('debug.stopwatch'));
}
public function testSerializerDisabled()
{
$container = $this->createContainerFromFile('default_config');
$this->assertFalse($container->has('serializer'));
}
public function testSerializerEnabled()
{
$container = $this->createContainerFromFile('full');
$this->assertTrue($container->has('serializer'));
}
protected function createContainer(array $data = array())
{
return new ContainerBuilder(new ParameterBag(array_merge(array(