Skip to content

Commit

Permalink
[FrameworkBundle] Serializer groups support
Browse files Browse the repository at this point in the history
  • Loading branch information
dunglas authored and fabpot committed Mar 18, 2015
1 parent 6963887 commit 83b56f6
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 4 deletions.
Expand Up @@ -660,6 +660,10 @@ private function addSerializerSection(ArrayNodeDefinition $rootNode)
->arrayNode('serializer')
->info('serializer configuration')
->canBeEnabled()
->children()
->booleanNode('enable_annotations')->defaultFalse()->end()
->scalarNode('cache')->end()
->end()
->end()
->end()
;
Expand Down
Expand Up @@ -13,6 +13,7 @@

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;
Expand All @@ -29,6 +30,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jeremy Mikola <jmikola@gmail.com>
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class FrameworkExtension extends Extension
{
Expand Down Expand Up @@ -121,11 +123,10 @@ public function load(array $configs, ContainerBuilder $container)
}

$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');
Expand Down Expand Up @@ -866,6 +867,86 @@ private function registerSecurityCsrfConfiguration(array $config, ContainerBuild
$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.
*
Expand Down
Expand Up @@ -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" />
Expand Down Expand Up @@ -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>
Expand Up @@ -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" />
Expand Down
Expand Up @@ -161,6 +161,7 @@ protected static function getBundleDefaultConfig()
),
'serializer' => array(
'enabled' => false,
'enable_annotations' => false,
),
'property_access' => array(
'magic_call' => false,
Expand Down
Expand Up @@ -60,6 +60,7 @@
'debug' => true,
'file_cache_dir' => '%kernel.cache_dir%/annotations',
),
'serializer' => array('enabled' => true),
'ide' => 'file%%link%%format',
'request' => array(
'formats' => array(
Expand Down
Expand Up @@ -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>
Expand Up @@ -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:
Expand Down
Expand Up @@ -498,6 +498,18 @@ public function testStopwatchEnabledWithDebugModeDisabled()
$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(
Expand Down

0 comments on commit 83b56f6

Please sign in to comment.