feature #13107 [FrameworkBundle] Serializer groups support (dunglas)
This PR was squashed before being merged into the 2.7 branch (closes #13107).
Discussion
----------
[FrameworkBundle] Serializer groups support
| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| License | MIT
| Doc PR | not yet
This PR enables serializer groups in the full stack framework (including XML, YAML, annotations and caching).
Commits
-------
83b56f6
[FrameworkBundle] Serializer groups support
This commit is contained in:
commit
74ec8953c6
@ -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()
|
||||
;
|
||||
|
@ -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
|
||||
{
|
||||
@ -122,11 +124,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');
|
||||
@ -874,6 +875,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.
|
||||
*
|
||||
|
@ -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>
|
||||
|
@ -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" />
|
||||
|
@ -162,6 +162,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
|
||||
),
|
||||
'serializer' => array(
|
||||
'enabled' => false,
|
||||
'enable_annotations' => false,
|
||||
),
|
||||
'property_access' => array(
|
||||
'magic_call' => false,
|
||||
|
@ -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(
|
||||
|
@ -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>
|
||||
|
@ -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:
|
||||
|
@ -503,6 +503,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(
|
||||
|
Reference in New Issue
Block a user