Completed
Push — master ( ac8ec4...1a57ac )
by Kévin
04:37 queued 11s
created

DependencyInjection/ApiPlatformExtension.php (1 issue)

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\MongoDbOdm\Filter\AbstractFilter as DoctrineMongoDbOdmAbstractFilter;
20
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\EagerLoadingExtension;
21
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\FilterEagerLoadingExtension;
22
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryCollectionExtensionInterface as DoctrineQueryCollectionExtensionInterface;
23
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryItemExtensionInterface;
24
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractContextAwareFilter as DoctrineOrmAbstractContextAwareFilter;
25
use ApiPlatform\Core\Bridge\Elasticsearch\DataProvider\Extension\RequestBodySearchCollectionExtensionInterface;
26
use ApiPlatform\Core\DataPersister\DataPersisterInterface;
27
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
28
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
29
use ApiPlatform\Core\DataProvider\SubresourceDataProviderInterface;
30
use ApiPlatform\Core\DataTransformer\DataTransformerInterface;
31
use ApiPlatform\Core\GraphQl\Resolver\MutationResolverInterface;
32
use ApiPlatform\Core\GraphQl\Resolver\QueryCollectionResolverInterface;
33
use ApiPlatform\Core\GraphQl\Resolver\QueryItemResolverInterface;
34
use ApiPlatform\Core\GraphQl\Type\Definition\TypeInterface as GraphQlTypeInterface;
35
use Doctrine\Common\Annotations\Annotation;
36
use phpDocumentor\Reflection\DocBlockFactoryInterface;
37
use Ramsey\Uuid\Uuid;
38
use Symfony\Component\BrowserKit\AbstractBrowser;
39
use Symfony\Component\Cache\Adapter\ArrayAdapter;
40
use Symfony\Component\Config\FileLocator;
41
use Symfony\Component\Config\Resource\DirectoryResource;
42
use Symfony\Component\DependencyInjection\ChildDefinition;
43
use Symfony\Component\DependencyInjection\ContainerBuilder;
44
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
45
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
46
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
47
use Symfony\Component\DependencyInjection\Reference;
48
use Symfony\Component\Finder\Finder;
49
use Symfony\Component\HttpClient\HttpClientTrait;
50
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
51
use Symfony\Component\Validator\Validator\ValidatorInterface;
52
use Symfony\Component\Yaml\Yaml;
53
54
/**
55
 * The extension of this bundle.
56
 *
57
 * @author Kévin Dunglas <[email protected]>
58
 */
59
final class ApiPlatformExtension extends Extension implements PrependExtensionInterface
60
{
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function prepend(ContainerBuilder $container): void
65
    {
66
        if (isset($container->getExtensions()['framework'])) {
67
            $container->prependExtensionConfig('framework', [
68
                'serializer' => [
69
                    'enabled' => true,
70
                ],
71
            ]);
72
            $container->prependExtensionConfig('framework', [
73
                'property_info' => [
74
                    'enabled' => true,
75
                ],
76
            ]);
77
        }
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83
    public function load(array $configs, ContainerBuilder $container): void
84
    {
85
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
86
87
        $configuration = new Configuration();
88
        $config = $this->processConfiguration($configuration, $configs);
89
90
        $formats = $this->getFormats($config['formats']);
91
        $patchFormats = $this->getFormats($config['patch_formats']);
92
        $errorFormats = $this->getFormats($config['error_formats']);
93
94
        // Backward Compatibility layer
95
        if (isset($formats['jsonapi']) && !isset($patchFormats['jsonapi'])) {
96
            $patchFormats['jsonapi'] = ['application/vnd.api+json'];
97
        }
98
99
        $this->registerCommonConfiguration($container, $config, $loader, $formats, $patchFormats, $errorFormats);
100
        $this->registerMetadataConfiguration($container, $config, $loader);
101
        $this->registerOAuthConfiguration($container, $config);
102
        $this->registerSwaggerConfiguration($container, $config, $loader);
103
        $this->registerJsonApiConfiguration($formats, $loader);
104
        $this->registerJsonLdHydraConfiguration($container, $formats, $loader, $config['enable_docs']);
105
        $this->registerJsonHalConfiguration($formats, $loader);
106
        $this->registerJsonProblemConfiguration($errorFormats, $loader);
107
        $this->registerGraphQlConfiguration($container, $config, $loader);
108
        $this->registerLegacyBundlesConfiguration($container, $config, $loader);
109
        $this->registerCacheConfiguration($container);
110
        $this->registerDoctrineOrmConfiguration($container, $config, $loader);
111
        $this->registerDoctrineMongoDbOdmConfiguration($container, $config, $loader);
112
        $this->registerHttpCacheConfiguration($container, $config, $loader);
113
        $this->registerValidatorConfiguration($container, $config, $loader);
114
        $this->registerDataCollectorConfiguration($container, $config, $loader);
115
        $this->registerMercureConfiguration($container, $config, $loader);
116
        $this->registerMessengerConfiguration($container, $config, $loader);
117
        $this->registerElasticsearchConfiguration($container, $config, $loader);
118
        $this->registerDataTransformerConfiguration($container);
119
        $this->registerSecurityConfiguration($container, $loader);
120
121
        $container->registerForAutoconfiguration(DataPersisterInterface::class)
122
            ->addTag('api_platform.data_persister');
123
        $container->registerForAutoconfiguration(ItemDataProviderInterface::class)
124
            ->addTag('api_platform.item_data_provider');
125
        $container->registerForAutoconfiguration(CollectionDataProviderInterface::class)
126
            ->addTag('api_platform.collection_data_provider');
127
        $container->registerForAutoconfiguration(SubresourceDataProviderInterface::class)
128
            ->addTag('api_platform.subresource_data_provider');
129
        $container->registerForAutoconfiguration(FilterInterface::class)
130
            ->addTag('api_platform.filter');
131
132
        if ($container->hasParameter('test.client.parameters')) {
133
            $loader->load('test.xml');
134
135
            if (!class_exists(AbstractBrowser::class) || !trait_exists(HttpClientTrait::class)) {
136
                $container->removeDefinition('test.api_platform.client');
137
            }
138
        }
139
    }
140
141
    private function registerCommonConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader, array $formats, array $patchFormats, array $errorFormats): void
142
    {
143
        $loader->load('api.xml');
144
        $loader->load('data_persister.xml');
145
        $loader->load('data_provider.xml');
146
        $loader->load('filter.xml');
147
148
        if (class_exists(Uuid::class)) {
149
            $loader->load('ramsey_uuid.xml');
150
        }
151
152
        $container->setParameter('api_platform.enable_entrypoint', $config['enable_entrypoint']);
153
        $container->setParameter('api_platform.enable_docs', $config['enable_docs']);
154
        $container->setParameter('api_platform.title', $config['title']);
155
        $container->setParameter('api_platform.description', $config['description']);
156
        $container->setParameter('api_platform.version', $config['version']);
157
        $container->setParameter('api_platform.show_webby', $config['show_webby']);
158
        $container->setParameter('api_platform.exception_to_status', $config['exception_to_status']);
159
        $container->setParameter('api_platform.formats', $formats);
160
        $container->setParameter('api_platform.patch_formats', $patchFormats);
161
        $container->setParameter('api_platform.error_formats', $errorFormats);
162
        $container->setParameter('api_platform.allow_plain_identifiers', $config['allow_plain_identifiers']);
163
        $container->setParameter('api_platform.eager_loading.enabled', $this->isConfigEnabled($container, $config['eager_loading']));
164
        $container->setParameter('api_platform.eager_loading.max_joins', $config['eager_loading']['max_joins']);
165
        $container->setParameter('api_platform.eager_loading.fetch_partial', $config['eager_loading']['fetch_partial']);
166
        $container->setParameter('api_platform.eager_loading.force_eager', $config['eager_loading']['force_eager']);
167
        $container->setParameter('api_platform.collection.exists_parameter_name', $config['collection']['exists_parameter_name']);
168
        $container->setParameter('api_platform.collection.order', $config['collection']['order']);
169
        $container->setParameter('api_platform.collection.order_parameter_name', $config['collection']['order_parameter_name']);
170
        $container->setParameter('api_platform.collection.pagination.enabled', $this->isConfigEnabled($container, $config['collection']['pagination']));
171
        $container->setParameter('api_platform.collection.pagination.partial', $config['collection']['pagination']['partial']);
172
        $container->setParameter('api_platform.collection.pagination.client_enabled', $config['collection']['pagination']['client_enabled']);
173
        $container->setParameter('api_platform.collection.pagination.client_items_per_page', $config['collection']['pagination']['client_items_per_page']);
174
        $container->setParameter('api_platform.collection.pagination.client_partial', $config['collection']['pagination']['client_partial']);
175
        $container->setParameter('api_platform.collection.pagination.items_per_page', $config['collection']['pagination']['items_per_page']);
176
        $container->setParameter('api_platform.collection.pagination.maximum_items_per_page', $config['collection']['pagination']['maximum_items_per_page']);
177
        $container->setParameter('api_platform.collection.pagination.page_parameter_name', $config['collection']['pagination']['page_parameter_name']);
178
        $container->setParameter('api_platform.collection.pagination.enabled_parameter_name', $config['collection']['pagination']['enabled_parameter_name']);
179
        $container->setParameter('api_platform.collection.pagination.items_per_page_parameter_name', $config['collection']['pagination']['items_per_page_parameter_name']);
180
        $container->setParameter('api_platform.collection.pagination.partial_parameter_name', $config['collection']['pagination']['partial_parameter_name']);
181
        $container->setParameter('api_platform.collection.pagination', $config['collection']['pagination']);
182
        $container->setParameter('api_platform.http_cache.etag', $config['http_cache']['etag']);
183
        $container->setParameter('api_platform.http_cache.max_age', $config['http_cache']['max_age']);
184
        $container->setParameter('api_platform.http_cache.shared_max_age', $config['http_cache']['shared_max_age']);
185
        $container->setParameter('api_platform.http_cache.vary', $config['http_cache']['vary']);
186
        $container->setParameter('api_platform.http_cache.public', $config['http_cache']['public']);
187
188
        $container->setAlias('api_platform.operation_path_resolver.default', $config['default_operation_path_resolver']);
189
        $container->setAlias('api_platform.path_segment_name_generator', $config['path_segment_name_generator']);
190
191
        if ($config['name_converter']) {
192
            $container->setAlias('api_platform.name_converter', $config['name_converter']);
193
        }
194
    }
195
196
    private function registerMetadataConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
197
    {
198
        $loader->load('metadata/metadata.xml');
199
        $loader->load('metadata/xml.xml');
200
201
        [$xmlResources, $yamlResources] = $this->getResourcesToWatch($container, $config);
202
203
        if (!empty($config['resource_class_directories'])) {
204
            $container->setParameter('api_platform.resource_class_directories', array_merge(
205
                $config['resource_class_directories'], $container->getParameter('api_platform.resource_class_directories')
206
            ));
207
        }
208
209
        $container->getDefinition('api_platform.metadata.extractor.xml')->replaceArgument(0, $xmlResources);
210
211
        if (class_exists(Annotation::class)) {
212
            $loader->load('metadata/annotation.xml');
213
        }
214
215
        if (class_exists(Yaml::class)) {
216
            $loader->load('metadata/yaml.xml');
217
            $container->getDefinition('api_platform.metadata.extractor.yaml')->replaceArgument(0, $yamlResources);
218
        }
219
220
        if (interface_exists(DocBlockFactoryInterface::class)) {
221
            $loader->load('metadata/php_doc.xml');
222
        }
223
    }
224
225
    private function getBundlesResourcesPaths(ContainerBuilder $container, array $config): array
226
    {
227
        $bundlesResourcesPaths = [];
228
229
        foreach ($container->getParameter('kernel.bundles_metadata') as $bundle) {
230
            $paths = [];
231
            $dirname = $bundle['path'];
232
            foreach (['.yaml', '.yml', '.xml', ''] as $extension) {
233
                $paths[] = "$dirname/Resources/config/api_resources$extension";
234
            }
235
            if ($this->isConfigEnabled($container, $config['doctrine'])) {
236
                $paths[] = "$dirname/Entity";
237
            }
238
            if ($this->isConfigEnabled($container, $config['doctrine_mongodb_odm'])) {
239
                $paths[] = "$dirname/Document";
240
            }
241
242
            foreach ($paths as $path) {
243
                if ($container->fileExists($path, false)) {
244
                    $bundlesResourcesPaths[] = $path;
245
                }
246
            }
247
        }
248
249
        return $bundlesResourcesPaths;
250
    }
251
252
    private function getResourcesToWatch(ContainerBuilder $container, array $config): array
253
    {
254
        $paths = array_unique(array_merge($config['mapping']['paths'], $this->getBundlesResourcesPaths($container, $config)));
255
256
        // Flex structure (only if nothing specified)
257
        $projectDir = $container->getParameter('kernel.project_dir');
258
        if (!$paths && is_dir($dir = "$projectDir/config/api_platform")) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $paths of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
259
            $paths = [$dir];
260
        }
261
262
        $resources = ['yml' => [], 'xml' => [], 'dir' => []];
263
264
        foreach ($paths as $path) {
265
            if (is_dir($path)) {
266
                foreach (Finder::create()->followLinks()->files()->in($path)->name('/\.(xml|ya?ml)$/') as $file) {
267
                    $resources['yaml' === ($extension = $file->getExtension()) ? 'yml' : $extension][] = $file->getRealPath();
268
                }
269
270
                $resources['dir'][] = $path;
271
                $container->addResource(new DirectoryResource($path, '/\.(xml|ya?ml|php)$/'));
272
273
                continue;
274
            }
275
276
            if ($container->fileExists($path, false)) {
277
                if (!preg_match('/\.(xml|ya?ml)$/', $path, $matches)) {
278
                    throw new RuntimeException(sprintf('Unsupported mapping type in "%s", supported types are XML & YAML.', $path));
279
                }
280
281
                $resources['yaml' === $matches[1] ? 'yml' : $matches[1]][] = $path;
282
283
                continue;
284
            }
285
286
            throw new RuntimeException(sprintf('Could not open file or directory "%s".', $path));
287
        }
288
289
        $container->setParameter('api_platform.resource_class_directories', $resources['dir']);
290
291
        return [$resources['xml'], $resources['yml']];
292
    }
293
294
    private function registerOAuthConfiguration(ContainerBuilder $container, array $config): void
295
    {
296
        if (!$config['oauth']) {
297
            return;
298
        }
299
300
        $container->setParameter('api_platform.oauth.enabled', $this->isConfigEnabled($container, $config['oauth']));
301
        $container->setParameter('api_platform.oauth.clientId', $config['oauth']['clientId']);
302
        $container->setParameter('api_platform.oauth.clientSecret', $config['oauth']['clientSecret']);
303
        $container->setParameter('api_platform.oauth.type', $config['oauth']['type']);
304
        $container->setParameter('api_platform.oauth.flow', $config['oauth']['flow']);
305
        $container->setParameter('api_platform.oauth.tokenUrl', $config['oauth']['tokenUrl']);
306
        $container->setParameter('api_platform.oauth.authorizationUrl', $config['oauth']['authorizationUrl']);
307
        $container->setParameter('api_platform.oauth.scopes', $config['oauth']['scopes']);
308
    }
309
310
    /**
311
     * Registers the Swagger, ReDoc and Swagger UI configuration.
312
     */
313
    private function registerSwaggerConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
314
    {
315
        if (empty($config['swagger']['versions'])) {
316
            return;
317
        }
318
319
        $loader->load('json_schema.xml');
320
        $loader->load('swagger.xml');
321
322
        if ($config['enable_swagger_ui'] || $config['enable_re_doc']) {
323
            $loader->load('swagger-ui.xml');
324
            $container->setParameter('api_platform.enable_swagger_ui', $config['enable_swagger_ui']);
325
            $container->setParameter('api_platform.enable_re_doc', $config['enable_re_doc']);
326
        }
327
328
        $container->setParameter('api_platform.swagger.versions', $config['swagger']['versions']);
329
        $container->setParameter('api_platform.swagger.api_keys', $config['swagger']['api_keys']);
330
    }
331
332
    private function registerJsonApiConfiguration(array $formats, XmlFileLoader $loader): void
333
    {
334
        if (!isset($formats['jsonapi'])) {
335
            return;
336
        }
337
338
        $loader->load('jsonapi.xml');
339
    }
340
341
    private function registerJsonLdHydraConfiguration(ContainerBuilder $container, array $formats, XmlFileLoader $loader, bool $docEnabled): void
342
    {
343
        if (!isset($formats['jsonld'])) {
344
            return;
345
        }
346
347
        $loader->load('jsonld.xml');
348
        $loader->load('hydra.xml');
349
350
        if (!$docEnabled) {
351
            $container->removeDefinition('api_platform.hydra.listener.response.add_link_header');
352
        }
353
    }
354
355
    private function registerJsonHalConfiguration(array $formats, XmlFileLoader $loader): void
356
    {
357
        if (!isset($formats['jsonhal'])) {
358
            return;
359
        }
360
361
        $loader->load('hal.xml');
362
    }
363
364
    private function registerJsonProblemConfiguration(array $errorFormats, XmlFileLoader $loader): void
365
    {
366
        if (!isset($errorFormats['jsonproblem'])) {
367
            return;
368
        }
369
370
        $loader->load('problem.xml');
371
    }
372
373
    private function registerGraphQlConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
374
    {
375
        $enabled = $this->isConfigEnabled($container, $config['graphql']);
376
377
        $container->setParameter('api_platform.graphql.enabled', $enabled);
378
        $container->setParameter('api_platform.graphql.graphiql.enabled', $enabled && $this->isConfigEnabled($container, $config['graphql']['graphiql']));
379
        $container->setParameter('api_platform.graphql.graphql_playground.enabled', $enabled && $this->isConfigEnabled($container, $config['graphql']['graphql_playground']));
380
        $container->setParameter('api_platform.graphql.collection.pagination', $config['graphql']['collection']['pagination']);
381
382
        if (!$enabled) {
383
            return;
384
        }
385
386
        $container->setParameter('api_platform.graphql.default_ide', $config['graphql']['default_ide']);
387
388
        $loader->load('graphql.xml');
389
390
        $container->registerForAutoconfiguration(QueryItemResolverInterface::class)
391
            ->addTag('api_platform.graphql.query_resolver');
392
        $container->registerForAutoconfiguration(QueryCollectionResolverInterface::class)
393
            ->addTag('api_platform.graphql.query_resolver');
394
        $container->registerForAutoconfiguration(MutationResolverInterface::class)
395
            ->addTag('api_platform.graphql.mutation_resolver');
396
        $container->registerForAutoconfiguration(GraphQlTypeInterface::class)
397
            ->addTag('api_platform.graphql.type');
398
    }
399
400
    private function registerLegacyBundlesConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
401
    {
402
        /** @var string[] $bundles */
403
        $bundles = $container->getParameter('kernel.bundles');
404
405
        if (isset($bundles['FOSUserBundle']) && $config['enable_fos_user']) {
406
            $loader->load('fos_user.xml');
407
        }
408
409
        if (isset($bundles['NelmioApiDocBundle']) && $config['enable_nelmio_api_doc']) {
410
            $loader->load('nelmio_api_doc.xml');
411
        }
412
    }
413
414
    private function registerCacheConfiguration(ContainerBuilder $container): void
415
    {
416
        if (!$container->hasParameter('kernel.debug') || !$container->getParameter('kernel.debug')) {
417
            $container->removeDefinition('api_platform.cache_warmer.cache_pool_clearer');
418
        }
419
420
        if (!$container->hasParameter('api_platform.metadata_cache')) {
421
            return;
422
        }
423
424
        @trigger_error('The "api_platform.metadata_cache" parameter is deprecated since version 2.4 and will have no effect in 3.0.', E_USER_DEPRECATED);
425
426
        // BC
427
        if (!$container->getParameter('api_platform.metadata_cache')) {
428
            $container->removeDefinition('api_platform.cache_warmer.cache_pool_clearer');
429
430
            $container->register('api_platform.cache.metadata.property', ArrayAdapter::class);
431
            $container->register('api_platform.cache.metadata.resource', ArrayAdapter::class);
432
            $container->register('api_platform.cache.route_name_resolver', ArrayAdapter::class);
433
            $container->register('api_platform.cache.identifiers_extractor', ArrayAdapter::class);
434
            $container->register('api_platform.cache.subresource_operation_factory', ArrayAdapter::class);
435
            $container->register('api_platform.elasticsearch.cache.metadata.document', ArrayAdapter::class);
436
        }
437
    }
438
439
    private function registerDoctrineOrmConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
440
    {
441
        if (!$this->isConfigEnabled($container, $config['doctrine'])) {
442
            return;
443
        }
444
445
        $container->registerForAutoconfiguration(QueryItemExtensionInterface::class)
446
            ->addTag('api_platform.doctrine.orm.query_extension.item');
447
        $container->registerForAutoconfiguration(DoctrineQueryCollectionExtensionInterface::class)
448
            ->addTag('api_platform.doctrine.orm.query_extension.collection');
449
        $container->registerForAutoconfiguration(DoctrineOrmAbstractContextAwareFilter::class)
450
            ->setBindings(['$requestStack' => null]);
451
452
        $loader->load('doctrine_orm.xml');
453
454
        if ($this->isConfigEnabled($container, $config['eager_loading'])) {
455
            return;
456
        }
457
458
        $container->removeAlias(EagerLoadingExtension::class);
459
        $container->removeDefinition('api_platform.doctrine.orm.query_extension.eager_loading');
460
        $container->removeAlias(FilterEagerLoadingExtension::class);
461
        $container->removeDefinition('api_platform.doctrine.orm.query_extension.filter_eager_loading');
462
    }
463
464
    private function registerDoctrineMongoDbOdmConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
465
    {
466
        if (!$this->isConfigEnabled($container, $config['doctrine_mongodb_odm'])) {
467
            return;
468
        }
469
470
        $container->registerForAutoconfiguration(AggregationItemExtensionInterface::class)
471
            ->addTag('api_platform.doctrine.mongodb.aggregation_extension.item');
472
        $container->registerForAutoconfiguration(AggregationCollectionExtensionInterface::class)
473
            ->addTag('api_platform.doctrine.mongodb.aggregation_extension.collection');
474
        $container->registerForAutoconfiguration(DoctrineMongoDbOdmAbstractFilter::class)
475
            ->setBindings(['$managerRegistry' => new Reference('doctrine_mongodb')]);
476
477
        $loader->load('doctrine_mongodb_odm.xml');
478
    }
479
480
    private function registerHttpCacheConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
481
    {
482
        $loader->load('http_cache.xml');
483
484
        if (!$this->isConfigEnabled($container, $config['http_cache']['invalidation'])) {
485
            return;
486
        }
487
488
        if ($this->isConfigEnabled($container, $config['doctrine'])) {
489
            $loader->load('doctrine_orm_http_cache_purger.xml');
490
        }
491
492
        $loader->load('http_cache_tags.xml');
493
494
        $definitions = [];
495
        foreach ($config['http_cache']['invalidation']['varnish_urls'] as $key => $url) {
496
            $definition = new ChildDefinition('api_platform.http_cache.purger.varnish_client');
497
            $definition->addArgument(['base_uri' => $url] + $config['http_cache']['invalidation']['request_options']);
498
499
            $definitions[] = $definition;
500
        }
501
502
        $container->getDefinition('api_platform.http_cache.purger.varnish')->addArgument($definitions);
503
        $container->setAlias('api_platform.http_cache.purger', 'api_platform.http_cache.purger.varnish');
504
    }
505
506
    /**
507
     * Normalizes the format from config to the one accepted by Symfony HttpFoundation.
508
     */
509
    private function getFormats(array $configFormats): array
510
    {
511
        $formats = [];
512
        foreach ($configFormats as $format => $value) {
513
            foreach ($value['mime_types'] as $mimeType) {
514
                $formats[$format][] = $mimeType;
515
            }
516
        }
517
518
        return $formats;
519
    }
520
521
    private function registerValidatorConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
522
    {
523
        if (interface_exists(ValidatorInterface::class)) {
524
            $loader->load('validator.xml');
525
        }
526
527
        if (!$config['validator']) {
528
            return;
529
        }
530
531
        $container->setParameter('api_platform.validator.serialize_payload_fields', $config['validator']['serialize_payload_fields']);
532
    }
533
534
    private function registerDataCollectorConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
535
    {
536
        if (!$config['enable_profiler']) {
537
            return;
538
        }
539
540
        $loader->load('data_collector.xml');
541
542
        if ($container->hasParameter('kernel.debug') && $container->getParameter('kernel.debug')) {
543
            $loader->load('debug.xml');
544
        }
545
    }
546
547
    private function registerMercureConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
548
    {
549
        if (!$this->isConfigEnabled($container, $config['mercure'])) {
550
            return;
551
        }
552
553
        $loader->load('mercure.xml');
554
        $container->getDefinition('api_platform.mercure.listener.response.add_link_header')->addArgument($config['mercure']['hub_url'] ?? '%mercure.default_hub%');
555
556
        if ($this->isConfigEnabled($container, $config['doctrine'])) {
557
            $loader->load('doctrine_orm_mercure_publisher.xml');
558
        }
559
    }
560
561
    private function registerMessengerConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
562
    {
563
        if (!$this->isConfigEnabled($container, $config['messenger'])) {
564
            return;
565
        }
566
567
        $loader->load('messenger.xml');
568
    }
569
570
    private function registerElasticsearchConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
571
    {
572
        $enabled = $this->isConfigEnabled($container, $config['elasticsearch']);
573
574
        $container->setParameter('api_platform.elasticsearch.enabled', $enabled);
575
576
        if (!$enabled) {
577
            return;
578
        }
579
580
        $loader->load('elasticsearch.xml');
581
582
        $container->registerForAutoconfiguration(RequestBodySearchCollectionExtensionInterface::class)
583
            ->addTag('api_platform.elasticsearch.request_body_search_extension.collection');
584
585
        $container->setParameter('api_platform.elasticsearch.hosts', $config['elasticsearch']['hosts']);
586
        $container->setParameter('api_platform.elasticsearch.mapping', $config['elasticsearch']['mapping']);
587
    }
588
589
    private function registerDataTransformerConfiguration(ContainerBuilder $container): void
590
    {
591
        $container->registerForAutoconfiguration(DataTransformerInterface::class)
592
            ->addTag('api_platform.data_transformer');
593
    }
594
595
    private function registerSecurityConfiguration(ContainerBuilder $container, XmlFileLoader $loader): void
596
    {
597
        /** @var string[] $bundles */
598
        $bundles = $container->getParameter('kernel.bundles');
599
600
        if (isset($bundles['SecurityBundle'])) {
601
            $loader->load('security.xml');
602
        }
603
    }
604
}
605