Skip to content

Commit 0ad4aa0

Browse files
committed
Merge pull request #933 from FriendsOfSymfony/auto_config_serializer
Automatically fallback to the core serializer if available
2 parents e78ab7e + 20d4abf commit 0ad4aa0

File tree

7 files changed

+154
-40
lines changed

7 files changed

+154
-40
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the FOSRestBundle package.
5+
*
6+
* (c) FriendsOfSymfony <http://friendsofsymfony.github.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 FOS\RestBundle\DependencyInjection\Compiler;
13+
14+
use Symfony\Component\DependencyInjection\ContainerBuilder;
15+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
16+
17+
/**
18+
* Checks if a serializer is either set or can be auto-configured.
19+
*/
20+
class SerializerConfigurationPass implements CompilerPassInterface
21+
{
22+
public function process(ContainerBuilder $container)
23+
{
24+
if ($container->has('fos_rest.serializer')) {
25+
return;
26+
}
27+
28+
if ($container->has('jms_serializer.serializer')) {
29+
$container->setAlias('fos_rest.serializer', 'jms_serializer.serializer');
30+
} elseif ($container->has('serializer')) {
31+
$container->setAlias('fos_rest.serializer', 'serializer');
32+
} else {
33+
throw new \InvalidArgumentException('Neither a service called "jms_serializer.serializer" nor "serializer" is available and no serializer is explicitly configured. You must either enable the JMSSerializerBundle, enable the FrameworkBundle serializer or configure a custom serializer.');
34+
}
35+
}
36+
}

DependencyInjection/FOSRestExtension.php

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,10 @@ public function load(array $configs, ContainerBuilder $container)
8080
$validator = $config['service']['validator'];
8181
unset($config['service']['validator']);
8282

83-
if (null === $config['service']['serializer']) {
84-
$bundles = $container->getParameter('kernel.bundles');
85-
86-
if (isset($bundles['JMSSerializerBundle'])) {
87-
$config['service']['serializer'] = 'jms_serializer.serializer';
88-
} else {
89-
throw new \InvalidArgumentException('JMSSerializerBundle is not available and no other serializer is configured. You must either enable the JMSSerializerBundle or configure a custom serializer.');
90-
}
91-
}
92-
9383
foreach ($config['service'] as $key => $service) {
94-
$container->setAlias($this->getAlias().'.'.$key, $service);
84+
if (null !== $service) {
85+
$container->setAlias($this->getAlias().'.'.$key, $service);
86+
}
9587
}
9688

9789
if (!empty($config['serializer']['version'])) {

FOSRestBundle.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\DependencyInjection\ContainerBuilder;
1515
use Symfony\Component\HttpKernel\Bundle\Bundle;
16+
use FOS\RestBundle\DependencyInjection\Compiler\SerializerConfigurationPass;
1617
use FOS\RestBundle\DependencyInjection\Compiler\ConfigurationCheckPass;
1718
use FOS\RestBundle\DependencyInjection\Compiler\FormatListenerRulesPass;
1819
use FOS\RestBundle\DependencyInjection\Compiler\TwigExceptionPass;
@@ -28,6 +29,7 @@ class FOSRestBundle extends Bundle
2829
*/
2930
public function build(ContainerBuilder $container)
3031
{
32+
$container->addCompilerPass(new SerializerConfigurationPass());
3133
$container->addCompilerPass(new ConfigurationCheckPass());
3234
$container->addCompilerPass(new FormatListenerRulesPass());
3335
$container->addCompilerPass(new TwigExceptionPass());

Resources/doc/1-setting_up_the_bundle.rst

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,6 @@ following command to download the latest stable version of this bundle:
1414
This command requires you to have Composer installed globally, as explained
1515
in the `installation chapter`_ of the Composer documentation.
1616

17-
.. note::
18-
19-
This bundle recommends using `JMSSerializer`_ which is integrated into Symfony
20-
via `JMSSerializerBundle`_.
21-
22-
If you want to use JMSSerializer, take a look into the instructions of the
23-
bundle to install it and set it up. You can also use `Symfony Serializer`_.
24-
But in this case, you need to manually set it up and configure FOSRestBundle
25-
to use it via the ``service`` section in the app config
26-
2717
B) Enable the Bundle
2818
--------------------
2919

@@ -41,14 +31,26 @@ file of your project:
4131
// ...
4232
new FOS\RestBundle\FOSRestBundle(),
4333
);
44-
34+
4535
// ...
4636
}
4737
}
4838
39+
C) Enable a Serializer
40+
----------------------
41+
42+
This bundle needs a serializer to work correctly. In most cases,
43+
you'll need to enable a serializer or install one. This bundle tries
44+
the following this (in this order) to determine the serializer to use:
45+
46+
#. The one you configured using ``fos_rest.services.serializer`` (if you did).
47+
#. The JMS serializer, if the `JMSSerializerBundle`_ is available (and registered).
48+
#. The `Symfony Serializer`_ if it's enabled (or any service called ``serializer``).
49+
4950
That was it!
5051

5152
.. _`installation chapter`: https://getcomposer.org/doc/00-intro.md
5253
.. _`JMSSerializer`: https://github.com/schmittjoh/serializer
5354
.. _`JMSSerializerBundle`: https://github.com/schmittjoh/JMSSerializerBundle
5455
.. _`Symfony Serializer`: https://github.com/symfony/Serializer
56+
.. _`enable the core Serializer`: http://symfony.com/doc/current/cookbook/serializer.html
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the FOSRestBundle package.
5+
*
6+
* (c) FriendsOfSymfony <http://friendsofsymfony.github.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 FOS\RestBundle\Tests\DependencyInjection\Compiler;
13+
14+
use FOS\RestBundle\DependencyInjection\Compiler\SerializerConfigurationPass;
15+
16+
/**
17+
* SerializerConfigurationPassTest test
18+
*/
19+
class SerializerConfigurationPassTest extends \PHPUnit_Framework_TestCase
20+
{
21+
public function testShouldDoNothingIfSerializerIsFound()
22+
{
23+
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')
24+
->setMethods(array('has'))
25+
->getMock();
26+
27+
$container->expects($this->once())
28+
->method('has')
29+
->with($this->equalTo('fos_rest.serializer'))
30+
->will($this->returnValue(true));
31+
32+
$container->expects($this->never())
33+
->method('setAlias');
34+
35+
$compiler = new SerializerConfigurationPass();
36+
$compiler->process($container);
37+
}
38+
39+
/**
40+
* @expectedException \InvalidArgumentException
41+
*/
42+
public function testShouldThrowInvalidArgumentExceptionWhenNoSerializerIsFound()
43+
{
44+
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')
45+
->setMethods(array('has'))
46+
->getMock();
47+
48+
$container->method('has')
49+
->will($this->returnValueMap(array(
50+
array('fos_rest.serializer', false),
51+
array('jms_serializer.serializer', false),
52+
array('serializer', false))));
53+
54+
$compiler = new SerializerConfigurationPass();
55+
$compiler->process($container);
56+
}
57+
58+
public function testShouldConfigureJMSSerializer()
59+
{
60+
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')
61+
->setMethods(array('has', 'setAlias'))
62+
->getMock();
63+
64+
$container->method('has')
65+
->will($this->returnValueMap(array(
66+
array('fos_rest.serializer', false),
67+
array('jms_serializer.serializer', true),
68+
array('serializer', true))));
69+
70+
71+
$container->expects($this->once())
72+
->method('setAlias')
73+
->with($this->equalTo('fos_rest.serializer'), $this->equalTo('jms_serializer.serializer'));
74+
75+
$compiler = new SerializerConfigurationPass();
76+
$compiler->process($container);
77+
}
78+
79+
public function testShouldConfigureCoreSerializer()
80+
{
81+
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')
82+
->setMethods(array('has', 'setAlias'))
83+
->getMock();
84+
85+
$container->method('has')
86+
->will($this->returnValueMap(array(
87+
array('fos_rest.serializer', false),
88+
array('jms_serializer.serializer', false),
89+
array('serializer', true))));
90+
91+
92+
$container->expects($this->once())
93+
->method('setAlias')
94+
->with($this->equalTo('fos_rest.serializer'), $this->equalTo('serializer'));
95+
96+
$compiler = new SerializerConfigurationPass();
97+
$compiler->process($container);
98+
}
99+
}

Tests/DependencyInjection/FOSRestExtensionTest.php

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -535,23 +535,6 @@ public function testExceptionThrownIfCallbackFilterIsUsed()
535535
$this->extension->load(array('fos_rest' => array('view' => array('jsonp_handler' => array('callback_filter' => 'foo')))), $this->container);
536536
}
537537

538-
public function testSerializerDefaultWhenJMSIsAvailable()
539-
{
540-
$this->extension->load(array(), $this->container);
541-
542-
$this->assertEquals('jms_serializer.serializer', $this->container->getAlias('fos_rest.serializer'));
543-
}
544-
545-
/**
546-
* @expectedException \InvalidArgumentException
547-
*/
548-
public function testSerializerRequiredWhenJMSIsNotAvailable()
549-
{
550-
$this->container->setParameter('kernel.bundles', array());
551-
552-
$this->extension->load(array(), $this->container);
553-
}
554-
555538
/**
556539
* Asserts the service definition has the method call with the specified arguments.
557540
*

Tests/FOSRestBundleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function testBuild()
2525
$container = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerBuilder')
2626
->setMethods(array('addCompilerPass'))
2727
->getMock();
28-
$container->expects($this->exactly(3))
28+
$container->expects($this->exactly(4))
2929
->method('addCompilerPass')
3030
->with($this->isInstanceOf('\Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface'));
3131

0 commit comments

Comments
 (0)