1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the API Platform project. |
5
|
|
|
* |
6
|
|
|
* (c) Kévin Dunglas <[email protected]> |
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
|
|
|
declare(strict_types=1); |
13
|
|
|
|
14
|
|
|
namespace ApiPlatform\Core\Bridge\Symfony\Bundle\DependencyInjection; |
15
|
|
|
|
16
|
|
|
use ApiPlatform\Core\Api\FilterInterface; |
17
|
|
|
use ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\Extension\AggregationCollectionExtensionInterface; |
18
|
|
|
use ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\Extension\AggregationItemExtensionInterface; |
19
|
|
|
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\EagerLoadingExtension; |
20
|
|
|
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\FilterEagerLoadingExtension; |
21
|
|
|
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryCollectionExtensionInterface as DoctrineQueryCollectionExtensionInterface; |
22
|
|
|
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryItemExtensionInterface; |
23
|
|
|
use ApiPlatform\Core\Bridge\Elasticsearch\DataProvider\Extension\RequestBodySearchCollectionExtensionInterface; |
24
|
|
|
use ApiPlatform\Core\DataPersister\DataPersisterInterface; |
25
|
|
|
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface; |
26
|
|
|
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface; |
27
|
|
|
use ApiPlatform\Core\DataProvider\SubresourceDataProviderInterface; |
28
|
|
|
use ApiPlatform\Core\DataTransformer\DataTransformerInterface; |
29
|
|
|
use ApiPlatform\Core\Exception\RuntimeException; |
30
|
|
|
use ApiPlatform\Core\GraphQl\Type\Definition\TypeInterface as GraphQlTypeInterface; |
31
|
|
|
use Doctrine\Common\Annotations\Annotation; |
32
|
|
|
use Doctrine\ORM\Version; |
33
|
|
|
use Elasticsearch\Client; |
34
|
|
|
use phpDocumentor\Reflection\DocBlockFactoryInterface; |
35
|
|
|
use Ramsey\Uuid\Uuid; |
36
|
|
|
use Symfony\Component\Cache\Adapter\ArrayAdapter; |
37
|
|
|
use Symfony\Component\Config\FileLocator; |
38
|
|
|
use Symfony\Component\Config\Resource\DirectoryResource; |
39
|
|
|
use Symfony\Component\DependencyInjection\ChildDefinition; |
40
|
|
|
use Symfony\Component\DependencyInjection\ContainerBuilder; |
41
|
|
|
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; |
42
|
|
|
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; |
43
|
|
|
use Symfony\Component\Finder\Finder; |
44
|
|
|
use Symfony\Component\HttpKernel\DependencyInjection\Extension; |
45
|
|
|
use Symfony\Component\Validator\Validator\ValidatorInterface; |
46
|
|
|
use Symfony\Component\Yaml\Yaml; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* The extension of this bundle. |
50
|
|
|
* |
51
|
|
|
* @author Kévin Dunglas <[email protected]> |
52
|
|
|
*/ |
53
|
|
|
final class ApiPlatformExtension extends Extension implements PrependExtensionInterface |
54
|
|
|
{ |
55
|
|
|
/** |
56
|
|
|
* {@inheritdoc} |
57
|
|
|
*/ |
58
|
|
|
public function prepend(ContainerBuilder $container) |
59
|
|
|
{ |
60
|
|
|
if (!$frameworkConfiguration = $container->getExtensionConfig('framework')) { |
61
|
|
|
return; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
$serializerConfig = $propertyInfoConfig = null; |
65
|
|
|
|
66
|
|
|
foreach ($frameworkConfiguration as $frameworkParameters) { |
67
|
|
|
if (isset($frameworkParameters['serializer'])) { |
68
|
|
|
$serializerConfig = $serializerConfig ?? $frameworkParameters['serializer']; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
if (isset($frameworkParameters['property_info'])) { |
72
|
|
|
$propertyInfoConfig = $propertyInfoConfig ?? $frameworkParameters['property_info']; |
73
|
|
|
} |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
if (!isset($serializerConfig['enabled'])) { |
77
|
|
|
$container->prependExtensionConfig('framework', ['serializer' => ['enabled' => true]]); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
if (!isset($propertyInfoConfig['enabled'])) { |
81
|
|
|
$container->prependExtensionConfig('framework', ['property_info' => ['enabled' => true]]); |
82
|
|
|
} |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* {@inheritdoc} |
87
|
|
|
*/ |
88
|
|
|
public function load(array $configs, ContainerBuilder $container) |
89
|
|
|
{ |
90
|
|
|
$configuration = new Configuration(); |
91
|
|
|
$config = $this->processConfiguration($configuration, $configs); |
92
|
|
|
$formats = $this->getFormats($config['formats']); |
93
|
|
|
$errorFormats = $this->getFormats($config['error_formats']); |
94
|
|
|
$this->handleConfig($container, $config, $formats, $errorFormats); |
95
|
|
|
|
96
|
|
|
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); |
97
|
|
|
$loader->load('api.xml'); |
98
|
|
|
$loader->load('data_persister.xml'); |
99
|
|
|
$loader->load('data_provider.xml'); |
100
|
|
|
$loader->load('filter.xml'); |
101
|
|
|
|
102
|
|
|
$container->registerForAutoconfiguration(DataPersisterInterface::class) |
103
|
|
|
->addTag('api_platform.data_persister'); |
104
|
|
|
$container->registerForAutoconfiguration(ItemDataProviderInterface::class) |
105
|
|
|
->addTag('api_platform.item_data_provider'); |
106
|
|
|
$container->registerForAutoconfiguration(CollectionDataProviderInterface::class) |
107
|
|
|
->addTag('api_platform.collection_data_provider'); |
108
|
|
|
$container->registerForAutoconfiguration(SubresourceDataProviderInterface::class) |
109
|
|
|
->addTag('api_platform.subresource_data_provider'); |
110
|
|
|
$container->registerForAutoconfiguration(FilterInterface::class) |
111
|
|
|
->addTag('api_platform.filter'); |
112
|
|
|
$container->registerForAutoconfiguration(GraphQlTypeInterface::class) |
113
|
|
|
->addTag('api_platform.graphql.type'); |
114
|
|
|
|
115
|
|
|
if (interface_exists(ValidatorInterface::class)) { |
116
|
|
|
$loader->load('validator.xml'); |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
$bundles = $container->getParameter('kernel.bundles'); |
120
|
|
|
if (isset($bundles['SecurityBundle'])) { |
121
|
|
|
$loader->load('security.xml'); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
if (class_exists(Uuid::class)) { |
125
|
|
|
$loader->load('ramsey_uuid.xml'); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
$useDoctrine = $config['doctrine']['enabled'] && isset($bundles['DoctrineBundle']) && class_exists(Version::class); |
129
|
|
|
|
130
|
|
|
$this->registerMetadataConfiguration($container, $config, $loader); |
131
|
|
|
$this->registerOAuthConfiguration($container, $config); |
132
|
|
|
$this->registerApiKeysConfiguration($container, $config); |
133
|
|
|
$this->registerSwaggerConfiguration($container, $config, $loader); |
134
|
|
|
$this->registerJsonLdConfiguration($container, $formats, $loader, $config['enable_docs']); |
135
|
|
|
$this->registerGraphqlConfiguration($container, $config, $loader); |
136
|
|
|
$this->registerJsonHalConfiguration($formats, $loader); |
137
|
|
|
$this->registerJsonProblemConfiguration($errorFormats, $loader); |
138
|
|
|
$this->registerJsonApiConfiguration($formats, $loader); |
139
|
|
|
$this->registerBundlesConfiguration($bundles, $config, $loader); |
140
|
|
|
$this->registerCacheConfiguration($container); |
141
|
|
|
$this->registerDoctrineConfiguration($container, $config, $loader, $useDoctrine); |
142
|
|
|
$this->registerDoctrineMongoDbOdmConfiguration($container, $config, $loader); |
143
|
|
|
$this->registerHttpCacheConfiguration($container, $config, $loader, $useDoctrine); |
144
|
|
|
$this->registerValidatorConfiguration($container, $config); |
145
|
|
|
$this->registerDataCollectorConfiguration($container, $config, $loader); |
146
|
|
|
$this->registerMercureConfiguration($container, $config, $loader, $useDoctrine); |
147
|
|
|
$this->registerMessengerConfiguration($config, $loader); |
148
|
|
|
$this->registerElasticsearchConfiguration($container, $config, $loader); |
149
|
|
|
$this->registerDataTransformerConfiguration($container); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* Handles configuration. |
154
|
|
|
*/ |
155
|
|
|
private function handleConfig(ContainerBuilder $container, array $config, array $formats, array $errorFormats) |
156
|
|
|
{ |
157
|
|
|
$container->setParameter('api_platform.enable_entrypoint', $config['enable_entrypoint']); |
158
|
|
|
$container->setParameter('api_platform.enable_docs', $config['enable_docs']); |
159
|
|
|
$container->setParameter('api_platform.title', $config['title']); |
160
|
|
|
$container->setParameter('api_platform.description', $config['description']); |
161
|
|
|
$container->setParameter('api_platform.version', $config['version']); |
162
|
|
|
$container->setParameter('api_platform.show_webby', $config['show_webby']); |
163
|
|
|
$container->setParameter('api_platform.exception_to_status', $config['exception_to_status']); |
164
|
|
|
$container->setParameter('api_platform.formats', $formats); |
165
|
|
|
$container->setParameter('api_platform.error_formats', $errorFormats); |
166
|
|
|
$container->setParameter('api_platform.allow_plain_identifiers', $config['allow_plain_identifiers']); |
167
|
|
|
$container->setParameter('api_platform.eager_loading.enabled', $config['eager_loading']['enabled']); |
168
|
|
|
$container->setParameter('api_platform.eager_loading.max_joins', $config['eager_loading']['max_joins']); |
169
|
|
|
$container->setParameter('api_platform.eager_loading.fetch_partial', $config['eager_loading']['fetch_partial']); |
170
|
|
|
$container->setParameter('api_platform.eager_loading.force_eager', $config['eager_loading']['force_eager']); |
171
|
|
|
$container->setParameter('api_platform.collection.order', $config['collection']['order']); |
172
|
|
|
$container->setParameter('api_platform.collection.order_parameter_name', $config['collection']['order_parameter_name']); |
173
|
|
|
$container->setParameter('api_platform.collection.pagination.enabled', $config['collection']['pagination']['enabled']); |
174
|
|
|
$container->setParameter('api_platform.collection.pagination.partial', $config['collection']['pagination']['partial']); |
175
|
|
|
$container->setParameter('api_platform.collection.pagination.client_enabled', $config['collection']['pagination']['client_enabled']); |
176
|
|
|
$container->setParameter('api_platform.collection.pagination.client_items_per_page', $config['collection']['pagination']['client_items_per_page']); |
177
|
|
|
$container->setParameter('api_platform.collection.pagination.client_partial', $config['collection']['pagination']['client_partial']); |
178
|
|
|
$container->setParameter('api_platform.collection.pagination.items_per_page', $config['collection']['pagination']['items_per_page']); |
179
|
|
|
$container->setParameter('api_platform.collection.pagination.maximum_items_per_page', $config['collection']['pagination']['maximum_items_per_page']); |
180
|
|
|
$container->setParameter('api_platform.collection.pagination.page_parameter_name', $config['collection']['pagination']['page_parameter_name']); |
181
|
|
|
$container->setParameter('api_platform.collection.pagination.enabled_parameter_name', $config['collection']['pagination']['enabled_parameter_name']); |
182
|
|
|
$container->setParameter('api_platform.collection.pagination.items_per_page_parameter_name', $config['collection']['pagination']['items_per_page_parameter_name']); |
183
|
|
|
$container->setParameter('api_platform.collection.pagination.partial_parameter_name', $config['collection']['pagination']['partial_parameter_name']); |
184
|
|
|
$container->setParameter('api_platform.collection.pagination', $config['collection']['pagination']); |
185
|
|
|
$container->setParameter('api_platform.http_cache.etag', $config['http_cache']['etag']); |
186
|
|
|
$container->setParameter('api_platform.http_cache.max_age', $config['http_cache']['max_age']); |
187
|
|
|
$container->setParameter('api_platform.http_cache.shared_max_age', $config['http_cache']['shared_max_age']); |
188
|
|
|
$container->setParameter('api_platform.http_cache.vary', $config['http_cache']['vary']); |
189
|
|
|
$container->setParameter('api_platform.http_cache.public', $config['http_cache']['public']); |
190
|
|
|
|
191
|
|
|
$container->setAlias('api_platform.operation_path_resolver.default', $config['default_operation_path_resolver']); |
192
|
|
|
$container->setAlias('api_platform.path_segment_name_generator', $config['path_segment_name_generator']); |
193
|
|
|
|
194
|
|
|
if ($config['name_converter']) { |
195
|
|
|
$container->setAlias('api_platform.name_converter', $config['name_converter']); |
196
|
|
|
} |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
/** |
200
|
|
|
* Registers metadata configuration. |
201
|
|
|
*/ |
202
|
|
|
private function registerMetadataConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader) |
203
|
|
|
{ |
204
|
|
|
$loader->load('metadata/metadata.xml'); |
205
|
|
|
$loader->load('metadata/xml.xml'); |
206
|
|
|
|
207
|
|
|
list($xmlResources, $yamlResources) = $this->getResourcesToWatch($container, $config); |
208
|
|
|
|
209
|
|
|
if (!empty($config['resource_class_directories'])) { |
210
|
|
|
$container->setParameter('api_platform.resource_class_directories', array_merge( |
211
|
|
|
$config['resource_class_directories'], $container->getParameter('api_platform.resource_class_directories') |
212
|
|
|
)); |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
$container->getDefinition('api_platform.metadata.extractor.xml')->replaceArgument(0, $xmlResources); |
216
|
|
|
|
217
|
|
|
if (class_exists(Annotation::class)) { |
218
|
|
|
$loader->load('metadata/annotation.xml'); |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
if (class_exists(Yaml::class)) { |
222
|
|
|
$loader->load('metadata/yaml.xml'); |
223
|
|
|
$container->getDefinition('api_platform.metadata.extractor.yaml')->replaceArgument(0, $yamlResources); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
if (interface_exists(DocBlockFactoryInterface::class)) { |
227
|
|
|
$loader->load('metadata/php_doc.xml'); |
228
|
|
|
} |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
private function getBundlesResourcesPaths(ContainerBuilder $container, array $config): array |
232
|
|
|
{ |
233
|
|
|
$bundlesResourcesPaths = []; |
234
|
|
|
|
235
|
|
|
foreach ($container->getParameter('kernel.bundles_metadata') as $bundle) { |
236
|
|
|
$paths = []; |
237
|
|
|
$dirname = $bundle['path']; |
238
|
|
|
foreach (['.yaml', '.yml', '.xml', ''] as $extension) { |
239
|
|
|
$paths[] = "$dirname/Resources/config/api_resources$extension"; |
240
|
|
|
} |
241
|
|
|
if ($config['doctrine']['enabled']) { |
242
|
|
|
$paths[] = "$dirname/Entity"; |
243
|
|
|
} |
244
|
|
|
if ($config['doctrine_mongodb_odm']['enabled']) { |
245
|
|
|
$paths[] = "$dirname/Document"; |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
foreach ($paths as $path) { |
249
|
|
|
if ($container->fileExists($path, false)) { |
250
|
|
|
$bundlesResourcesPaths[] = $path; |
251
|
|
|
} |
252
|
|
|
} |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
return $bundlesResourcesPaths; |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
private function getResourcesToWatch(ContainerBuilder $container, array $config): array |
259
|
|
|
{ |
260
|
|
|
$paths = array_unique(array_merge($config['mapping']['paths'], $this->getBundlesResourcesPaths($container, $config))); |
261
|
|
|
|
262
|
|
|
// Flex structure (only if nothing specified) |
263
|
|
|
$projectDir = $container->getParameter('kernel.project_dir'); |
264
|
|
|
if (!$paths && is_dir($dir = "$projectDir/config/api_platform")) { |
|
|
|
|
265
|
|
|
$paths = [$dir]; |
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
$resources = ['yml' => [], 'xml' => [], 'dir' => []]; |
269
|
|
|
|
270
|
|
|
foreach ($paths as $path) { |
271
|
|
|
if (is_dir($path)) { |
272
|
|
|
foreach (Finder::create()->followLinks()->files()->in($path)->name('/\.(xml|ya?ml)$/') as $file) { |
273
|
|
|
$resources['yaml' === ($extension = $file->getExtension()) ? 'yml' : $extension][] = $file->getRealPath(); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
$resources['dir'][] = $path; |
277
|
|
|
$container->addResource(new DirectoryResource($path, '/\.(xml|ya?ml|php)$/')); |
278
|
|
|
|
279
|
|
|
continue; |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
if ($container->fileExists($path, false)) { |
283
|
|
|
if (!preg_match('/\.(xml|ya?ml)$/', $path, $matches)) { |
284
|
|
|
throw new RuntimeException(sprintf('Unsupported mapping type in "%s", supported types are XML & Yaml.', $path)); |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
$resources['yaml' === $matches[1] ? 'yml' : $matches[1]][] = $path; |
288
|
|
|
|
289
|
|
|
continue; |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
throw new RuntimeException(sprintf('Could not open file or directory "%s".', $path)); |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
$container->setParameter('api_platform.resource_class_directories', $resources['dir']); |
296
|
|
|
|
297
|
|
|
return [$resources['xml'], $resources['yml']]; |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
/** |
301
|
|
|
* Registers the OAuth configuration. |
302
|
|
|
*/ |
303
|
|
|
private function registerOAuthConfiguration(ContainerBuilder $container, array $config) |
304
|
|
|
{ |
305
|
|
|
if (!$config['oauth']) { |
306
|
|
|
return; |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
$container->setParameter('api_platform.oauth.enabled', $config['oauth']['enabled']); |
310
|
|
|
$container->setParameter('api_platform.oauth.clientId', $config['oauth']['clientId']); |
311
|
|
|
$container->setParameter('api_platform.oauth.clientSecret', $config['oauth']['clientSecret']); |
312
|
|
|
$container->setParameter('api_platform.oauth.type', $config['oauth']['type']); |
313
|
|
|
$container->setParameter('api_platform.oauth.flow', $config['oauth']['flow']); |
314
|
|
|
$container->setParameter('api_platform.oauth.tokenUrl', $config['oauth']['tokenUrl']); |
315
|
|
|
$container->setParameter('api_platform.oauth.authorizationUrl', $config['oauth']['authorizationUrl']); |
316
|
|
|
$container->setParameter('api_platform.oauth.scopes', $config['oauth']['scopes']); |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
/** |
320
|
|
|
* Registers the api keys configuration. |
321
|
|
|
*/ |
322
|
|
|
private function registerApiKeysConfiguration(ContainerBuilder $container, array $config) |
323
|
|
|
{ |
324
|
|
|
$container->setParameter('api_platform.swagger.api_keys', $config['swagger']['api_keys']); |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
/** |
328
|
|
|
* Registers the Swagger, ReDoc and Swagger UI configuration. |
329
|
|
|
*/ |
330
|
|
|
private function registerSwaggerConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader) |
331
|
|
|
{ |
332
|
|
|
if (!$config['enable_swagger']) { |
333
|
|
|
return; |
334
|
|
|
} |
335
|
|
|
|
336
|
|
|
$loader->load('swagger.xml'); |
337
|
|
|
|
338
|
|
|
if ($config['enable_swagger_ui'] || $config['enable_re_doc']) { |
339
|
|
|
$loader->load('swagger-ui.xml'); |
340
|
|
|
$container->setParameter('api_platform.enable_swagger_ui', $config['enable_swagger_ui']); |
341
|
|
|
$container->setParameter('api_platform.enable_re_doc', $config['enable_re_doc']); |
342
|
|
|
} |
343
|
|
|
|
344
|
|
|
$container->setParameter('api_platform.enable_swagger', $config['enable_swagger']); |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
/** |
348
|
|
|
* Registers the JsonApi configuration. |
349
|
|
|
*/ |
350
|
|
|
private function registerJsonApiConfiguration(array $formats, XmlFileLoader $loader) |
351
|
|
|
{ |
352
|
|
|
if (!isset($formats['jsonapi'])) { |
353
|
|
|
return; |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
$loader->load('jsonapi.xml'); |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
/** |
360
|
|
|
* Registers the JSON-LD and Hydra configuration. |
361
|
|
|
*/ |
362
|
|
|
private function registerJsonLdConfiguration(ContainerBuilder $container, array $formats, XmlFileLoader $loader, bool $docEnabled) |
363
|
|
|
{ |
364
|
|
|
if (!isset($formats['jsonld'])) { |
365
|
|
|
return; |
366
|
|
|
} |
367
|
|
|
|
368
|
|
|
$loader->load('jsonld.xml'); |
369
|
|
|
$loader->load('hydra.xml'); |
370
|
|
|
|
371
|
|
|
if (!$docEnabled) { |
372
|
|
|
$container->removeDefinition('api_platform.hydra.listener.response.add_link_header'); |
373
|
|
|
} |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
/** |
377
|
|
|
* Registers the HAL configuration. |
378
|
|
|
*/ |
379
|
|
|
private function registerJsonHalConfiguration(array $formats, XmlFileLoader $loader) |
380
|
|
|
{ |
381
|
|
|
if (!isset($formats['jsonhal'])) { |
382
|
|
|
return; |
383
|
|
|
} |
384
|
|
|
|
385
|
|
|
$loader->load('hal.xml'); |
386
|
|
|
} |
387
|
|
|
|
388
|
|
|
/** |
389
|
|
|
* Registers the JSON Problem configuration. |
390
|
|
|
*/ |
391
|
|
|
private function registerJsonProblemConfiguration(array $errorFormats, XmlFileLoader $loader) |
392
|
|
|
{ |
393
|
|
|
if (!isset($errorFormats['jsonproblem'])) { |
394
|
|
|
return; |
395
|
|
|
} |
396
|
|
|
|
397
|
|
|
$loader->load('problem.xml'); |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
/** |
401
|
|
|
* Registers the GraphQL configuration. |
402
|
|
|
*/ |
403
|
|
|
private function registerGraphqlConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader) |
404
|
|
|
{ |
405
|
|
|
if (!$config['graphql']) { |
406
|
|
|
return; |
407
|
|
|
} |
408
|
|
|
|
409
|
|
|
$container->setParameter('api_platform.graphql.enabled', $config['graphql']['enabled']); |
410
|
|
|
$container->setParameter('api_platform.graphql.graphiql.enabled', $config['graphql']['graphiql']['enabled']); |
411
|
|
|
|
412
|
|
|
$loader->load('graphql.xml'); |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
/** |
416
|
|
|
* Registers configuration for integration with third-party bundles. |
417
|
|
|
* |
418
|
|
|
* @param string[] $bundles |
419
|
|
|
*/ |
420
|
|
|
private function registerBundlesConfiguration(array $bundles, array $config, XmlFileLoader $loader) |
421
|
|
|
{ |
422
|
|
|
// FOSUser support |
423
|
|
|
if (isset($bundles['FOSUserBundle']) && $config['enable_fos_user']) { |
424
|
|
|
$loader->load('fos_user.xml'); |
425
|
|
|
} |
426
|
|
|
|
427
|
|
|
// NelmioApiDoc support |
428
|
|
|
if (isset($bundles['NelmioApiDocBundle']) && $config['enable_nelmio_api_doc']) { |
429
|
|
|
$loader->load('nelmio_api_doc.xml'); |
430
|
|
|
} |
431
|
|
|
} |
432
|
|
|
|
433
|
|
|
/** |
434
|
|
|
* Registers the cache configuration. |
435
|
|
|
*/ |
436
|
|
|
private function registerCacheConfiguration(ContainerBuilder $container) |
437
|
|
|
{ |
438
|
|
|
// Don't use system cache pool in dev |
439
|
|
|
if ($container->hasParameter('api_platform.metadata_cache') ? $container->getParameter('api_platform.metadata_cache') : !$container->getParameter('kernel.debug')) { |
440
|
|
|
return; |
441
|
|
|
} |
442
|
|
|
|
443
|
|
|
$container->register('api_platform.cache.metadata.property', ArrayAdapter::class); |
444
|
|
|
$container->register('api_platform.cache.metadata.resource', ArrayAdapter::class); |
445
|
|
|
$container->register('api_platform.cache.route_name_resolver', ArrayAdapter::class); |
446
|
|
|
$container->register('api_platform.cache.identifiers_extractor', ArrayAdapter::class); |
447
|
|
|
$container->register('api_platform.cache.subresource_operation_factory', ArrayAdapter::class); |
448
|
|
|
$container->register('api_platform.elasticsearch.cache.metadata.document', ArrayAdapter::class); |
449
|
|
|
} |
450
|
|
|
|
451
|
|
|
/** |
452
|
|
|
* Manipulate doctrine services according to the configuration. |
453
|
|
|
*/ |
454
|
|
|
private function registerDoctrineConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader, bool $useDoctrine) |
455
|
|
|
{ |
456
|
|
|
if (!$useDoctrine) { |
457
|
|
|
return; |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
$container->registerForAutoconfiguration(QueryItemExtensionInterface::class) |
461
|
|
|
->addTag('api_platform.doctrine.orm.query_extension.item'); |
462
|
|
|
$container->registerForAutoconfiguration(DoctrineQueryCollectionExtensionInterface::class) |
463
|
|
|
->addTag('api_platform.doctrine.orm.query_extension.collection'); |
464
|
|
|
|
465
|
|
|
$loader->load('doctrine_orm.xml'); |
466
|
|
|
|
467
|
|
|
if ($config['eager_loading']['enabled']) { |
468
|
|
|
return; |
469
|
|
|
} |
470
|
|
|
|
471
|
|
|
$container->removeAlias(EagerLoadingExtension::class); |
472
|
|
|
$container->removeDefinition('api_platform.doctrine.orm.query_extension.eager_loading'); |
473
|
|
|
$container->removeAlias(FilterEagerLoadingExtension::class); |
474
|
|
|
$container->removeDefinition('api_platform.doctrine.orm.query_extension.filter_eager_loading'); |
475
|
|
|
} |
476
|
|
|
|
477
|
|
|
/** |
478
|
|
|
* Register the Doctrine MongoDB ODM configuration. |
479
|
|
|
*/ |
480
|
|
|
private function registerDoctrineMongoDbOdmConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader) |
481
|
|
|
{ |
482
|
|
|
if (!$config['doctrine_mongodb_odm']['enabled']) { |
483
|
|
|
return; |
484
|
|
|
} |
485
|
|
|
|
486
|
|
|
$container->registerForAutoconfiguration(AggregationItemExtensionInterface::class) |
487
|
|
|
->addTag('api_platform.doctrine.mongodb.aggregation_extension.item'); |
488
|
|
|
$container->registerForAutoconfiguration(AggregationCollectionExtensionInterface::class) |
489
|
|
|
->addTag('api_platform.doctrine.mongodb.aggregation_extension.collection'); |
490
|
|
|
|
491
|
|
|
$loader->load('doctrine_mongodb_odm.xml'); |
492
|
|
|
} |
493
|
|
|
|
494
|
|
|
private function registerHttpCacheConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader, bool $useDoctrine) |
495
|
|
|
{ |
496
|
|
|
$loader->load('http_cache.xml'); |
497
|
|
|
|
498
|
|
|
if (!$config['http_cache']['invalidation']['enabled']) { |
499
|
|
|
return; |
500
|
|
|
} |
501
|
|
|
|
502
|
|
|
if ($useDoctrine) { |
503
|
|
|
$loader->load('doctrine_orm_http_cache_purger.xml'); |
504
|
|
|
} |
505
|
|
|
|
506
|
|
|
$loader->load('http_cache_tags.xml'); |
507
|
|
|
|
508
|
|
|
$definitions = []; |
509
|
|
|
foreach ($config['http_cache']['invalidation']['varnish_urls'] as $key => $url) { |
510
|
|
|
$definition = new ChildDefinition('api_platform.http_cache.purger.varnish_client'); |
511
|
|
|
$definition->addArgument(['base_uri' => $url] + $config['http_cache']['invalidation']['request_options']); |
512
|
|
|
|
513
|
|
|
$definitions[] = $definition; |
514
|
|
|
} |
515
|
|
|
|
516
|
|
|
$container->getDefinition('api_platform.http_cache.purger.varnish')->addArgument($definitions); |
517
|
|
|
$container->setAlias('api_platform.http_cache.purger', 'api_platform.http_cache.purger.varnish'); |
518
|
|
|
} |
519
|
|
|
|
520
|
|
|
/** |
521
|
|
|
* Normalizes the format from config to the one accepted by Symfony HttpFoundation. |
522
|
|
|
*/ |
523
|
|
|
private function getFormats(array $configFormats): array |
524
|
|
|
{ |
525
|
|
|
$formats = []; |
526
|
|
|
foreach ($configFormats as $format => $value) { |
527
|
|
|
foreach ($value['mime_types'] as $mimeType) { |
528
|
|
|
$formats[$format][] = $mimeType; |
529
|
|
|
} |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
return $formats; |
533
|
|
|
} |
534
|
|
|
|
535
|
|
|
/** |
536
|
|
|
* Registers the Validator configuration. |
537
|
|
|
*/ |
538
|
|
|
private function registerValidatorConfiguration(ContainerBuilder $container, array $config) |
539
|
|
|
{ |
540
|
|
|
if (!$config['validator']) { |
541
|
|
|
return; |
542
|
|
|
} |
543
|
|
|
|
544
|
|
|
$container->setParameter('api_platform.validator.serialize_payload_fields', $config['validator']['serialize_payload_fields']); |
545
|
|
|
} |
546
|
|
|
|
547
|
|
|
/** |
548
|
|
|
* Registers the DataCollector configuration. |
549
|
|
|
*/ |
550
|
|
|
private function registerDataCollectorConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader) |
551
|
|
|
{ |
552
|
|
|
if (!$config['enable_profiler']) { |
553
|
|
|
return; |
554
|
|
|
} |
555
|
|
|
|
556
|
|
|
$loader->load('data_collector.xml'); |
557
|
|
|
|
558
|
|
|
if ($container->hasParameter('kernel.debug') && $container->getParameter('kernel.debug')) { |
559
|
|
|
$loader->load('debug.xml'); |
560
|
|
|
} |
561
|
|
|
} |
562
|
|
|
|
563
|
|
|
private function registerMercureConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader, bool $useDoctrine) |
564
|
|
|
{ |
565
|
|
|
if (!$config['mercure']['enabled']) { |
566
|
|
|
return; |
567
|
|
|
} |
568
|
|
|
|
569
|
|
|
$loader->load('mercure.xml'); |
570
|
|
|
$container->getDefinition('api_platform.mercure.listener.response.add_link_header')->addArgument($config['mercure']['hub_url'] ?? '%mercure.default_hub%'); |
571
|
|
|
|
572
|
|
|
if ($useDoctrine) { |
573
|
|
|
$loader->load('doctrine_orm_mercure_publisher.xml'); |
574
|
|
|
} |
575
|
|
|
} |
576
|
|
|
|
577
|
|
|
private function registerMessengerConfiguration(array $config, XmlFileLoader $loader) |
578
|
|
|
{ |
579
|
|
|
if (!$config['messenger']['enabled']) { |
580
|
|
|
return; |
581
|
|
|
} |
582
|
|
|
|
583
|
|
|
$loader->load('messenger.xml'); |
584
|
|
|
} |
585
|
|
|
|
586
|
|
|
private function registerElasticsearchConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader) |
587
|
|
|
{ |
588
|
|
|
$enabled = $config['elasticsearch']['enabled'] && class_exists(Client::class); |
589
|
|
|
|
590
|
|
|
$container->setParameter('api_platform.elasticsearch.enabled', $enabled); |
591
|
|
|
|
592
|
|
|
if (!$enabled) { |
593
|
|
|
return; |
594
|
|
|
} |
595
|
|
|
|
596
|
|
|
$loader->load('elasticsearch.xml'); |
597
|
|
|
|
598
|
|
|
$container->registerForAutoconfiguration(RequestBodySearchCollectionExtensionInterface::class) |
599
|
|
|
->addTag('api_platform.elasticsearch.request_body_search_extension.collection'); |
600
|
|
|
|
601
|
|
|
$container->setParameter('api_platform.elasticsearch.hosts', $config['elasticsearch']['hosts']); |
602
|
|
|
$container->setParameter('api_platform.elasticsearch.mapping', $config['elasticsearch']['mapping']); |
603
|
|
|
} |
604
|
|
|
|
605
|
|
|
private function registerDataTransformerConfiguration(ContainerBuilder $container) |
606
|
|
|
{ |
607
|
|
|
$container->registerForAutoconfiguration(DataTransformerInterface::class) |
608
|
|
|
->addTag('api_platform.data_transformer'); |
609
|
|
|
} |
610
|
|
|
} |
611
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.