Skip to content

Commit 826b187

Browse files
committed
Add the discriminator_class_mapping in the framework extension
1 parent d0d0264 commit 826b187

File tree

9 files changed

+90
-9
lines changed

9 files changed

+90
-9
lines changed

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,19 @@ private function addSerializerSection(ArrayNodeDefinition $rootNode)
770770
->end()
771771
->end()
772772
->end()
773+
->arrayNode('discriminator_class_mapping')
774+
->useAttributeAsKey('class')
775+
->prototype('array')
776+
->children()
777+
->scalarNode('type_property')->isRequired()->end()
778+
->arrayNode('mapping')
779+
->useAttributeAsKey('type')
780+
->fixXmlConfig('mapping')
781+
->prototype('scalar')
782+
->end()
783+
->end()
784+
->end()
785+
->end()
773786
->end()
774787
->end()
775788
->end()

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
use Symfony\Component\Serializer\Encoder\DecoderInterface;
7474
use Symfony\Component\Serializer\Encoder\EncoderInterface;
7575
use Symfony\Component\Serializer\Encoder\YamlEncoder;
76+
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorMapping;
7677
use Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory;
7778
use Symfony\Component\Serializer\Normalizer\DataUriNormalizer;
7879
use Symfony\Component\Serializer\Normalizer\DateIntervalNormalizer;
@@ -1660,6 +1661,13 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder
16601661
if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) {
16611662
$container->getDefinition('serializer.normalizer.object')->addMethodCall('setCircularReferenceHandler', array(new Reference($config['circular_reference_handler'])));
16621663
}
1664+
1665+
foreach ($config['discriminator_class_mapping'] as $className => $classMapping) {
1666+
$container->getDefinition('serializer.mapping.class_discriminator_resolver')->addMethodCall('addClassMapping', array(
1667+
$className,
1668+
new ClassDiscriminatorMapping($classMapping['type_property'], $classMapping['mapping'])
1669+
));
1670+
}
16631671
}
16641672

16651673
/**

src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,16 @@
2424

2525
<service id="serializer.property_accessor" alias="property_accessor" />
2626

27+
<!-- Discriminator Map -->
28+
<service id="serializer.mapping.class_discriminator_resolver" class="Symfony\Component\Serializer\Mapping\ClassDiscriminatorResolver" />
29+
2730
<!-- Normalizer -->
2831
<service id="serializer.normalizer.object" class="Symfony\Component\Serializer\Normalizer\ObjectNormalizer">
2932
<argument type="service" id="serializer.mapping.class_metadata_factory" />
3033
<argument>null</argument> <!-- name converter -->
3134
<argument type="service" id="serializer.property_accessor" />
3235
<argument type="service" id="property_info" on-invalid="ignore" />
36+
<argument type="service" id="serializer.mapping.class_discriminator_resolver" />
3337

3438
<!-- Run after all custom normalizers -->
3539
<tag name="serializer.normalizer" priority="-1000" />

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ protected static function getBundleDefaultConfig()
279279
'enabled' => !class_exists(FullStack::class),
280280
'enable_annotations' => !class_exists(FullStack::class),
281281
'mapping' => array('paths' => array()),
282+
'discriminator_class_mapping' => array(),
282283
),
283284
'property_access' => array(
284285
'magic_call' => false,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', array(
4+
'serializer' => array(
5+
'discriminator_class_mapping' => array(
6+
'App\CodeRepository' => array(
7+
'type_property' => 'type',
8+
'mapping' => array(
9+
'github' => 'App\GitHubCodeRepository',
10+
'bitbucket' => 'App\BitBucketCodeRepository',
11+
),
12+
),
13+
),
14+
),
15+
));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xmlns:framework="http://symfony.com/schema/dic/symfony">
6+
7+
<framework:config>
8+
<framework:serializer enable-annotations="true">
9+
<framework:discriminator-class-mapping>
10+
<framework:class-mapping class="App\CodeRepository" type-property="type">
11+
<framework:mapping type="github">App\GitHubCodeRepository</framework:mapping>
12+
<framework:mapping type="bitbucket">App\BitBucketCodeRepository</framework:mapping>
13+
</framework:class-mapping>
14+
</framework:discriminator-class-mapping>
15+
</framework:serializer>
16+
</framework:config>
17+
</container>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
framework:
2+
serializer:
3+
discriminator_class_mapping:
4+
App\CodeRepository:
5+
type_property: type
6+
mapping:
7+
github: App\GitHubCodeRepository
8+
bitbucket: App\BitBucketCodeRepository

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,19 @@ public function testDeprecatedSerializerCacheOption()
868868
$this->assertEquals(new Reference('foo'), $cache);
869869
}
870870

871+
public function testSerializerWithDiscriminatorClassMapping()
872+
{
873+
$container = $this->createContainerFromFile('serializer_discriminator_map');
874+
$calls = $container->getDefinition('serializer.mapping.class_discriminator_resolver')->getMethodCalls();
875+
$this->assertEquals(1, count($calls));
876+
877+
$firstCallClass = $calls[0][1][0];
878+
$firstCallMapping = $calls[0][1][1];
879+
880+
$this->assertEquals('App\CodeRepository', $firstCallClass);
881+
$this->assertEquals(array('github' => 'App\GitHubCodeRepository', 'bitbucket' => 'App\BitBucketCodeRepository'), $firstCallMapping->getTypesMapping());
882+
}
883+
871884
public function testSerializerMapping()
872885
{
873886
$container = $this->createContainerFromFile('serializer_mapping', array('kernel.bundles_metadata' => array('TestBundle' => array('namespace' => 'Symfony\\Bundle\\FrameworkBundle\\Tests', 'path' => __DIR__.'/Fixtures/TestBundle', 'parent' => null))));

src/Symfony/Component/Serializer/Mapping/ClassDiscriminatorMapping.php

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,14 @@ public function __construct(string $typeProperty, array $typesMapping = array())
2525
$this->typesMapping = $typesMapping;
2626
}
2727

28+
/**
29+
* @return string
30+
*/
2831
public function getTypeProperty(): string
2932
{
3033
return $this->typeProperty;
3134
}
3235

33-
public function addTypeMapping(string $type, string $typeClass)
34-
{
35-
if (isset($this->typesMapping[$type])) {
36-
throw new \InvalidArgumentException(sprintf('Mapping for type "%s" already exists', $type));
37-
}
38-
39-
$this->typesMapping[$type] = $typeClass;
40-
}
41-
4236
/**
4337
* @param string $type
4438
*
@@ -68,4 +62,12 @@ public function getMappedObjectType($object)
6862

6963
return null;
7064
}
65+
66+
/**
67+
* @return array
68+
*/
69+
public function getTypesMapping(): array
70+
{
71+
return $this->typesMapping;
72+
}
7173
}

0 commit comments

Comments
 (0)