Skip to content

Commit fb6b2b4

Browse files
committed
Merge pull request #294 from odolbeau/disable-doctrine
Add an option to totally disable doctrine support
2 parents 889b9f6 + bab5be9 commit fb6b2b4

File tree

10 files changed

+100
-21
lines changed

10 files changed

+100
-21
lines changed

DependencyInjection/Compiler/DataProviderPass.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1515
use Symfony\Component\DependencyInjection\ContainerBuilder;
1616
use Symfony\Component\DependencyInjection\Reference;
17+
use Dunglas\ApiBundle\Exception\RuntimeException;
1718

1819
/**
1920
* Injects data managers in the chain.
@@ -27,8 +28,13 @@ class DataProviderPass implements CompilerPassInterface
2728
*/
2829
public function process(ContainerBuilder $container)
2930
{
31+
$taggedServices = $container->findTaggedServiceIds('api.data_provider');
32+
if (0 === count($taggedServices)) {
33+
throw new RuntimeException('No DataProvider found. Did you forget to tag your own data provider?');
34+
}
35+
3036
$sortedServices = [];
31-
foreach ($container->findTaggedServiceIds('api.data_provider') as $serviceId => $tags) {
37+
foreach ($taggedServices as $serviceId => $tags) {
3238
foreach ($tags as $tag) {
3339
$priority = isset($tag['priority']) ? $tag['priority'] : 0;
3440
$sortedServices[$priority][] = new Reference($serviceId);

DependencyInjection/Configuration.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,15 @@ public function getConfigTreeBuilder()
2929
$treeBuilder = new TreeBuilder();
3030
$rootNode = $treeBuilder->root('dunglas_api');
3131

32+
// We chack if symfony's doctrine bridge is enabled or not to choose the defaultValue for `enable_doctrine_orm`.
33+
$enableDoctrineOrm = interface_exists('\Symfony\Bridge\Doctrine\RegistryInterface');
34+
3235
$rootNode
3336
->children()
3437
->scalarNode('title')->cannotBeEmpty()->isRequired()->info('The title of the API.')->end()
3538
->scalarNode('description')->cannotBeEmpty()->isRequired()->info('The description of the API.')->end()
3639
->scalarNode('cache')->defaultFalse()->info('The caching service to use. Set to "dunglas_api.mapping.cache.apc" to enable APC metadata caching.')->end()
40+
->booleanNode('enable_doctrine_orm')->defaultValue($enableDoctrineOrm)->info('Enable the Doctrine ORM integration.')->end()
3741
->booleanNode('enable_fos_user')->defaultValue(false)->info('Enable the FOSUserBundle integration.')->end()
3842
->arrayNode('collection')
3943
->addDefaultsIfNotSet()

DependencyInjection/DunglasApiExtension.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,12 @@ public function load(array $configs, ContainerBuilder $container)
6262
$loader->load('api.xml');
6363
$loader->load('property_info.xml');
6464
$loader->load('mapping.xml');
65-
$loader->load('doctrine_orm.xml');
65+
66+
if ($config['enable_doctrine_orm']) {
67+
$loader->load('doctrine_orm.xml');
68+
69+
$this->enableDoctrine($container);
70+
}
6671

6772
// JSON-LD and Hydra support
6873
$loader->load('json_ld.xml');
@@ -87,4 +92,29 @@ public function load(array $configs, ContainerBuilder $container)
8792
$container->removeDefinition('api.cache_warmer.metadata');
8893
}
8994
}
95+
96+
private function enableDoctrine(ContainerBuilder $container)
97+
{
98+
$propertyInfoDefinition = $container->getDefinition('api.property_info');
99+
$propertyInfoDefinition->replaceArgument(
100+
0,
101+
array_merge(
102+
[
103+
$container->getDefinition('api.property_info.doctrine_extractor'),
104+
],
105+
$propertyInfoDefinition->getArgument(0)
106+
)
107+
);
108+
109+
$loaderChainDefintion = $container->getDefinition('api.mapping.loaders.chain');
110+
$loaderChainDefintion->replaceArgument(
111+
0,
112+
array_merge(
113+
$loaderChainDefintion->getArgument(0),
114+
[
115+
$container->getDefinition('api.mapping.loaders.doctrine_identifier'),
116+
]
117+
)
118+
);
119+
}
90120
}

Resources/config/doctrine_orm.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@
4747
<service id="api.mapping.loaders.doctrine_identifier" class="Dunglas\ApiBundle\Mapping\Loader\DoctrineIdentifierLoader" public="false">
4848
<argument type="service" id="doctrine" />
4949
</service>
50+
51+
<service id="api.property_info.doctrine_extractor" class="PropertyInfo\Extractors\DoctrineExtractor" public="false">
52+
<argument type="service" id="api.doctrine.metadata_factory" />
53+
</service>
5054
</services>
5155

5256
</container>

Resources/config/mapping.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
<argument type="service" id="api.mapping.loaders.attributes" />
3636
<argument type="service" id="api.mapping.loaders.validator_metadata" />
3737
<argument type="service" id="api.mapping.loaders.phpdoc" />
38-
<argument type="service" id="api.mapping.loaders.doctrine_identifier" on-invalid="ignore" />
3938
<argument type="service" id="api.mapping.loaders.annotation" />
4039
</argument>
4140
</service>

Resources/config/property_info.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
<services>
88
<service id="api.property_info" class="PropertyInfo\PropertyInfo" public="false">
99
<argument type="collection">
10-
<argument type="service" id="api.property_info.doctrine_extractor" />
1110
<argument type="service" id="api.property_info.setter_extractor" />
1211
<argument type="service" id="api.property_info.php_doc_extractor" />
1312
</argument>
@@ -16,10 +15,6 @@
1615
</argument>
1716
</service>
1817

19-
<service id="api.property_info.doctrine_extractor" class="PropertyInfo\Extractors\DoctrineExtractor" public="false">
20-
<argument type="service" id="api.doctrine.metadata_factory" />
21-
</service>
22-
2318
<service id="api.property_info.php_doc_extractor" class="PropertyInfo\Extractors\PhpDocExtractor" public="false" />
2419

2520
<service id="api.property_info.setter_extractor" class="PropertyInfo\Extractors\SetterExtractor" public="false" />

Tests/DependencyInjection/Compiler/DataProviderPassTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,21 @@ public function testProcess()
3636

3737
$dataProviderPass->process($containerBuilder);
3838
}
39+
40+
/**
41+
* @expectedException \Dunglas\ApiBundle\Exception\RuntimeException
42+
* @expectedExceptionMessage No DataProvider found. Did you forget to tag your own data provider?
43+
*/
44+
public function testProcessWithoutTaggedServices()
45+
{
46+
$dataProviderPass = new DataProviderPass();
47+
48+
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface', $dataProviderPass);
49+
50+
$containerBuilderProphecy = $this->prophesize('Symfony\Component\DependencyInjection\ContainerBuilder');
51+
$containerBuilderProphecy->findTaggedServiceIds('api.data_provider')->willReturn([])->shouldBeCalled();
52+
$containerBuilder = $containerBuilderProphecy->reveal();
53+
54+
$dataProviderPass->process($containerBuilder);
55+
}
3956
}

Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
2323
'title' => 'title',
2424
'description' => 'description',
2525
'cache' => false,
26+
'enable_doctrine_orm' => true,
2627
'enable_fos_user' => false,
2728
'collection' => [
2829
'filter_name' => [

Tests/DependencyInjection/DunglasApiExtensionTest.php

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,16 @@ public function testEnableCache()
120120
$this->extension->load(array_merge_recursive(self::$defaultConfig, ['dunglas_api' => ['cache' => true]]), $containerBuilder);
121121
}
122122

123-
private function getContainerBuilderProphecy()
123+
public function testDisableDoctrine()
124+
{
125+
$containerBuilderProphecy = $this->getContainerBuilderProphecy(false);
126+
$containerBuilderProphecy->removeDefinition('api.cache_warmer.metadata')->shouldBeCalled();
127+
$containerBuilder = $containerBuilderProphecy->reveal();
128+
129+
$this->extension->load(array_merge_recursive(self::$defaultConfig, ['dunglas_api' => ['enable_doctrine_orm' => false]]), $containerBuilder);
130+
}
131+
132+
private function getContainerBuilderProphecy($withDoctrine = true)
124133
{
125134
$parameterBagProphecy = $this->prophesize('Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface');
126135
$parameterBagProphecy->add(Argument::any())->shouldBeCalled();
@@ -148,7 +157,6 @@ private function getContainerBuilderProphecy()
148157
$containerBuilderProphecy->setDefinition('api.router', $definitionArgument)->shouldBeCalled();
149158
$containerBuilderProphecy->setDefinition('api.iri_converter', $definitionArgument)->shouldBeCalled();
150159
$containerBuilderProphecy->setDefinition('api.property_info', $definitionArgument)->shouldBeCalled();
151-
$containerBuilderProphecy->setDefinition('api.property_info.doctrine_extractor', $definitionArgument)->shouldBeCalled();
152160
$containerBuilderProphecy->setDefinition('api.property_info.php_doc_extractor', $definitionArgument)->shouldBeCalled();
153161
$containerBuilderProphecy->setDefinition('api.property_info.setter_extractor', $definitionArgument)->shouldBeCalled();
154162
$containerBuilderProphecy->setDefinition('api.mapping.class_metadata_factory', $definitionArgument)->shouldBeCalled();
@@ -159,14 +167,6 @@ private function getContainerBuilderProphecy()
159167
$containerBuilderProphecy->setDefinition('api.mapping.loaders.validator_metadata', $definitionArgument)->shouldBeCalled();
160168
$containerBuilderProphecy->setDefinition('api.mapping.loaders.phpdoc', $definitionArgument)->shouldBeCalled();
161169
$containerBuilderProphecy->setDefinition('api.mapping.loaders.annotation', $definitionArgument)->shouldBeCalled();
162-
$containerBuilderProphecy->setDefinition('api.doctrine.metadata_factory', $definitionArgument)->shouldBeCalled();
163-
$containerBuilderProphecy->setDefinition('api.doctrine.event_subscriber', $definitionArgument)->shouldBeCalled();
164-
$containerBuilderProphecy->setDefinition('api.doctrine.orm.data_provider', $definitionArgument)->shouldBeCalled();
165-
$containerBuilderProphecy->setDefinition('api.doctrine.orm.default_data_provider', $definitionArgument)->shouldBeCalled();
166-
$containerBuilderProphecy->setDefinition('api.doctrine.orm.search_filter', $definitionArgument)->shouldBeCalled();
167-
$containerBuilderProphecy->setDefinition('api.doctrine.orm.order_filter', $definitionArgument)->shouldBeCalled();
168-
$containerBuilderProphecy->setDefinition('api.doctrine.orm.date_filter', $definitionArgument)->shouldBeCalled();
169-
$containerBuilderProphecy->setDefinition('api.mapping.loaders.doctrine_identifier', $definitionArgument)->shouldBeCalled();
170170
$containerBuilderProphecy->setDefinition('api.json_ld.entrypoint_builder', $definitionArgument)->shouldBeCalled();
171171
$containerBuilderProphecy->setDefinition('api.json_ld.context_builder', $definitionArgument)->shouldBeCalled();
172172
$containerBuilderProphecy->setDefinition('api.json_ld.resource_context_builder_listener', $definitionArgument)->shouldBeCalled();
@@ -180,6 +180,28 @@ private function getContainerBuilderProphecy()
180180
$containerBuilderProphecy->setDefinition('api.hydra.normalizer.constraint_violation_list', $definitionArgument)->shouldBeCalled();
181181
$containerBuilderProphecy->setDefinition('api.hydra.normalizer.error', $definitionArgument)->shouldBeCalled();
182182

183+
if ($withDoctrine) {
184+
$definitionProphecy = $this->prophesize('Symfony\Component\DependencyInjection\Definition');
185+
$definitionProphecy->getArgument(Argument::exact(0))->willReturn([])->shouldBeCalled();
186+
$definitionProphecy->replaceArgument(Argument::exact(0), Argument::type('array'))->shouldBeCalled();
187+
$definition = $definitionProphecy->reveal();
188+
189+
$containerBuilderProphecy->getDefinition('api.property_info')->shouldBeCalled()->willReturn($definition);
190+
$containerBuilderProphecy->getDefinition('api.property_info.doctrine_extractor')->shouldBeCalled()->willReturn($definition);
191+
$containerBuilderProphecy->getDefinition('api.mapping.loaders.chain')->shouldBeCalled()->willReturn($definition);
192+
$containerBuilderProphecy->getDefinition('api.mapping.loaders.doctrine_identifier')->shouldBeCalled()->willReturn($definition);
193+
194+
$containerBuilderProphecy->setDefinition('api.doctrine.metadata_factory', $definitionArgument)->shouldBeCalled();
195+
$containerBuilderProphecy->setDefinition('api.doctrine.event_subscriber', $definitionArgument)->shouldBeCalled();
196+
$containerBuilderProphecy->setDefinition('api.doctrine.orm.data_provider', $definitionArgument)->shouldBeCalled();
197+
$containerBuilderProphecy->setDefinition('api.doctrine.orm.default_data_provider', $definitionArgument)->shouldBeCalled();
198+
$containerBuilderProphecy->setDefinition('api.doctrine.orm.search_filter', $definitionArgument)->shouldBeCalled();
199+
$containerBuilderProphecy->setDefinition('api.doctrine.orm.order_filter', $definitionArgument)->shouldBeCalled();
200+
$containerBuilderProphecy->setDefinition('api.doctrine.orm.date_filter', $definitionArgument)->shouldBeCalled();
201+
$containerBuilderProphecy->setDefinition('api.mapping.loaders.doctrine_identifier', $definitionArgument)->shouldBeCalled();
202+
$containerBuilderProphecy->setDefinition('api.property_info.doctrine_extractor', $definitionArgument)->shouldBeCalled();
203+
}
204+
183205
return $containerBuilderProphecy;
184206
}
185207
}

composer.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919
"symfony/framework-bundle": "~2.6|~3.0",
2020
"symfony/proxy-manager-bridge": "~2.3",
2121
"ocramius/proxy-manager": "~1.0",
22-
"doctrine/orm": "~2.2,>=2.2.3",
2322
"doctrine/inflector": "~1.0",
24-
"doctrine/doctrine-bundle": "~1.2",
2523
"dunglas/php-property-info": "~0.2",
2624
"phpdocumentor/reflection": "^1.0.7"
2725
},
@@ -34,9 +32,12 @@
3432
"behat/mink-browserkit-driver": "~1.1",
3533
"behatch/contexts": "dev-master#eef7ab39ca896796bf3ba25a0fa5a95f15276eb7",
3634
"symfony/finder": "~2.3",
37-
"phpunit/phpunit": "~4.6"
35+
"phpunit/phpunit": "~4.6",
36+
"doctrine/orm": "~2.2,>=2.2.3",
37+
"doctrine/doctrine-bundle": "~1.2"
3838
},
3939
"suggest": {
40+
"doctrine/doctrine-bundle": "To use the Doctrine ORM bridge.",
4041
"friendsofsymfony/user-bundle": "To use the FOSUserBundle bridge."
4142
},
4243
"autoload": {

0 commit comments

Comments
 (0)