Skip to content

Commit bab5be9

Browse files
committed
Add an option to totally disable doctrine support
Move doctrine dependencies in erquire-dev Throw an exception if no data provider tagged Test extension without doctrine Do not use Doctrine extractor in PropertyInfo when doctrine is not enabled Add Doctrine loader only when doctrine is enabled Do not use setters Order matters. :/ Fix style
1 parent 889b9f6 commit bab5be9

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)