• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

api-platform / core / 7142557150

08 Dec 2023 02:28PM UTC coverage: 36.003% (-1.4%) from 37.36%
7142557150

push

github

web-flow
fix(jsonld): remove link to ApiDocumentation when doc is disabled (#6029)

0 of 1 new or added line in 1 file covered. (0.0%)

2297 existing lines in 182 files now uncovered.

9992 of 27753 relevant lines covered (36.0%)

147.09 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php
1
<?php
2

3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <dunglas@gmail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types=1);
13

14
namespace ApiPlatform\Symfony\Bundle\DependencyInjection;
15

16
use ApiPlatform\Doctrine\Odm\Extension\AggregationCollectionExtensionInterface;
17
use ApiPlatform\Doctrine\Odm\Extension\AggregationItemExtensionInterface;
18
use ApiPlatform\Doctrine\Odm\Filter\AbstractFilter as DoctrineMongoDbOdmAbstractFilter;
19
use ApiPlatform\Doctrine\Odm\State\LinksHandlerInterface as OdmLinksHandlerInterface;
20
use ApiPlatform\Doctrine\Orm\Extension\EagerLoadingExtension;
21
use ApiPlatform\Doctrine\Orm\Extension\FilterEagerLoadingExtension;
22
use ApiPlatform\Doctrine\Orm\Extension\QueryCollectionExtensionInterface as DoctrineQueryCollectionExtensionInterface;
23
use ApiPlatform\Doctrine\Orm\Extension\QueryItemExtensionInterface;
24
use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter as DoctrineOrmAbstractFilter;
25
use ApiPlatform\Doctrine\Orm\State\LinksHandlerInterface as OrmLinksHandlerInterface;
26
use ApiPlatform\Elasticsearch\Extension\RequestBodySearchCollectionExtensionInterface;
27
use ApiPlatform\GraphQl\Error\ErrorHandlerInterface;
28
use ApiPlatform\GraphQl\Resolver\MutationResolverInterface;
29
use ApiPlatform\GraphQl\Resolver\QueryCollectionResolverInterface;
30
use ApiPlatform\GraphQl\Resolver\QueryItemResolverInterface;
31
use ApiPlatform\GraphQl\Type\Definition\TypeInterface as GraphQlTypeInterface;
32
use ApiPlatform\Metadata\ApiResource;
33
use ApiPlatform\Metadata\FilterInterface;
34
use ApiPlatform\Metadata\UrlGeneratorInterface;
35
use ApiPlatform\Metadata\Util\Inflector;
36
use ApiPlatform\State\ApiResource\Error;
37
use ApiPlatform\State\ProcessorInterface;
38
use ApiPlatform\State\ProviderInterface;
39
use ApiPlatform\Symfony\GraphQl\Resolver\Factory\DataCollectorResolverFactory;
40
use ApiPlatform\Symfony\Validator\Exception\ValidationException;
41
use ApiPlatform\Symfony\Validator\Metadata\Property\Restriction\PropertySchemaRestrictionMetadataInterface;
42
use ApiPlatform\Symfony\Validator\ValidationGroupsGeneratorInterface;
43
use Doctrine\Persistence\ManagerRegistry;
44
use phpDocumentor\Reflection\DocBlockFactoryInterface;
45
use PHPStan\PhpDocParser\Parser\PhpDocParser;
46
use Ramsey\Uuid\Uuid;
47
use Symfony\Component\Config\FileLocator;
48
use Symfony\Component\Config\Resource\DirectoryResource;
49
use Symfony\Component\DependencyInjection\ContainerBuilder;
50
use Symfony\Component\DependencyInjection\ContainerInterface;
51
use Symfony\Component\DependencyInjection\Definition;
52
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
53
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
54
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
55
use Symfony\Component\DependencyInjection\Reference;
56
use Symfony\Component\Finder\Finder;
57
use Symfony\Component\HttpClient\ScopingHttpClient;
58
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
59
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
60
use Symfony\Component\Uid\AbstractUid;
61
use Symfony\Component\Validator\Validator\ValidatorInterface;
62
use Symfony\Component\Yaml\Yaml;
63
use Twig\Environment;
64

65
/**
66
 * The extension of this bundle.
67
 *
68
 * @author Kévin Dunglas <dunglas@gmail.com>
69
 */
70
final class ApiPlatformExtension extends Extension implements PrependExtensionInterface
71
{
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function prepend(ContainerBuilder $container): void
76
    {
UNCOV
77
        if (isset($container->getExtensions()['framework'])) {
×
UNCOV
78
            $container->prependExtensionConfig('framework', [
×
UNCOV
79
                'serializer' => [
×
UNCOV
80
                    'enabled' => true,
×
UNCOV
81
                ],
×
UNCOV
82
            ]);
×
UNCOV
83
            $container->prependExtensionConfig('framework', [
×
UNCOV
84
                'property_info' => [
×
UNCOV
85
                    'enabled' => true,
×
UNCOV
86
                ],
×
UNCOV
87
            ]);
×
88
        }
UNCOV
89
        if (isset($container->getExtensions()['lexik_jwt_authentication'])) {
×
90
            $container->prependExtensionConfig('lexik_jwt_authentication', [
×
91
                'api_platform' => [
×
92
                    'enabled' => true,
×
93
                ],
×
94
            ]);
×
95
        }
96
    }
97

98
    /**
99
     * {@inheritdoc}
100
     */
101
    public function load(array $configs, ContainerBuilder $container): void
102
    {
UNCOV
103
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
×
104

UNCOV
105
        $configuration = new Configuration();
×
UNCOV
106
        $config = $this->processConfiguration($configuration, $configs);
×
107

UNCOV
108
        if (!$config['formats']) {
×
109
            trigger_deprecation('api-platform/core', '3.2', 'Setting the "formats" section will be mandatory in API Platform 4.');
×
110
            $config['formats'] = [
×
111
                'jsonld' => ['mime_types' => ['application/ld+json']],
×
112
                // Note that in API Platform 4 this will be removed as it was used for documentation only and are is now present in the docsFormats
113
                'json' => ['mime_types' => ['application/json']], // Swagger support
×
114
            ];
×
115
        }
116

UNCOV
117
        $formats = $this->getFormats($config['formats']);
×
UNCOV
118
        $patchFormats = $this->getFormats($config['patch_formats']);
×
UNCOV
119
        $errorFormats = $this->getFormats($config['error_formats']);
×
UNCOV
120
        $docsFormats = $this->getFormats($config['docs_formats']);
×
121

UNCOV
122
        if (!isset($errorFormats['json'])) {
×
UNCOV
123
            $errorFormats['json'] = ['application/problem+json', 'application/json'];
×
124
        }
125

UNCOV
126
        if (!isset($errorFormats['jsonproblem'])) {
×
127
            $errorFormats['jsonproblem'] = ['application/problem+json'];
×
128
        }
129

UNCOV
130
        if ($this->isConfigEnabled($container, $config['graphql']) && !isset($formats['json'])) {
×
UNCOV
131
            trigger_deprecation('api-platform/core', '3.2', 'Add the "json" format to the configuration to use GraphQL.');
×
UNCOV
132
            $formats['json'] = ['application/json'];
×
133
        }
134

135
        // Backward Compatibility layer
UNCOV
136
        if (isset($formats['jsonapi']) && !isset($patchFormats['jsonapi'])) {
×
UNCOV
137
            $patchFormats['jsonapi'] = ['application/vnd.api+json'];
×
138
        }
139

UNCOV
140
        if (isset($docsFormats['json']) && !isset($docsFormats['jsonopenapi'])) {
×
141
            trigger_deprecation('api-platform/core', '3.2', 'The "json" format is too broad, use ["jsonopenapi" => ["application/vnd.openapi+json"]] instead.');
×
142
            $docsFormats['jsonopenapi'] = ['application/vnd.openapi+json'];
×
143
        }
144

UNCOV
145
        $this->registerCommonConfiguration($container, $config, $loader, $formats, $patchFormats, $errorFormats, $docsFormats);
×
UNCOV
146
        $this->registerMetadataConfiguration($container, $config, $loader);
×
UNCOV
147
        $this->registerOAuthConfiguration($container, $config);
×
UNCOV
148
        $this->registerOpenApiConfiguration($container, $config, $loader);
×
UNCOV
149
        $this->registerSwaggerConfiguration($container, $config, $loader);
×
UNCOV
150
        $this->registerJsonApiConfiguration($formats, $loader, $config);
×
UNCOV
151
        $this->registerJsonLdHydraConfiguration($container, $formats, $loader, $config);
×
UNCOV
152
        $this->registerJsonHalConfiguration($formats, $loader);
×
UNCOV
153
        $this->registerJsonProblemConfiguration($errorFormats, $loader);
×
UNCOV
154
        $this->registerGraphQlConfiguration($container, $config, $loader);
×
UNCOV
155
        $this->registerCacheConfiguration($container);
×
UNCOV
156
        $this->registerDoctrineOrmConfiguration($container, $config, $loader);
×
UNCOV
157
        $this->registerDoctrineMongoDbOdmConfiguration($container, $config, $loader);
×
UNCOV
158
        $this->registerHttpCacheConfiguration($container, $config, $loader);
×
UNCOV
159
        $this->registerValidatorConfiguration($container, $config, $loader);
×
UNCOV
160
        $this->registerDataCollectorConfiguration($container, $config, $loader);
×
UNCOV
161
        $this->registerMercureConfiguration($container, $config, $loader);
×
UNCOV
162
        $this->registerMessengerConfiguration($container, $config, $loader);
×
UNCOV
163
        $this->registerElasticsearchConfiguration($container, $config, $loader);
×
UNCOV
164
        $this->registerSecurityConfiguration($container, $config, $loader);
×
UNCOV
165
        $this->registerMakerConfiguration($container, $config, $loader);
×
UNCOV
166
        $this->registerArgumentResolverConfiguration($loader);
×
167

UNCOV
168
        $container->registerForAutoconfiguration(FilterInterface::class)
×
UNCOV
169
            ->addTag('api_platform.filter');
×
UNCOV
170
        $container->registerForAutoconfiguration(ProviderInterface::class)
×
UNCOV
171
            ->addTag('api_platform.state_provider');
×
UNCOV
172
        $container->registerForAutoconfiguration(ProcessorInterface::class)
×
UNCOV
173
            ->addTag('api_platform.state_processor');
×
174

UNCOV
175
        if (!$container->has('api_platform.state.item_provider')) {
×
176
            $container->setAlias('api_platform.state.item_provider', 'api_platform.state_provider.object');
×
177
        }
178

UNCOV
179
        $this->registerInflectorConfiguration($config);
×
180
    }
181

182
    private function registerCommonConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader, array $formats, array $patchFormats, array $errorFormats, array $docsFormats): void
183
    {
UNCOV
184
        $loader->load('symfony/events.xml');
×
UNCOV
185
        $loader->load('symfony/controller.xml');
×
UNCOV
186
        $loader->load('api.xml');
×
UNCOV
187
        $loader->load('state.xml');
×
UNCOV
188
        $loader->load('filter.xml');
×
189

UNCOV
190
        if (class_exists(Uuid::class)) {
×
UNCOV
191
            $loader->load('ramsey_uuid.xml');
×
192
        }
193

UNCOV
194
        if (class_exists(AbstractUid::class)) {
×
UNCOV
195
            $loader->load('symfony/uid.xml');
×
196
        }
197

198
        // TODO: remove in 4.x
UNCOV
199
        $container->setParameter('api_platform.event_listeners_backward_compatibility_layer', $config['event_listeners_backward_compatibility_layer']);
×
UNCOV
200
        $loader->load('legacy/events.xml');
×
201

UNCOV
202
        $container->setParameter('api_platform.enable_entrypoint', $config['enable_entrypoint']);
×
UNCOV
203
        $container->setParameter('api_platform.enable_docs', $config['enable_docs']);
×
UNCOV
204
        $container->setParameter('api_platform.keep_legacy_inflector', $config['keep_legacy_inflector']);
×
UNCOV
205
        $container->setParameter('api_platform.title', $config['title']);
×
UNCOV
206
        $container->setParameter('api_platform.description', $config['description']);
×
UNCOV
207
        $container->setParameter('api_platform.version', $config['version']);
×
UNCOV
208
        $container->setParameter('api_platform.show_webby', $config['show_webby']);
×
UNCOV
209
        $container->setParameter('api_platform.url_generation_strategy', $config['defaults']['url_generation_strategy'] ?? UrlGeneratorInterface::ABS_PATH);
×
UNCOV
210
        $container->setParameter('api_platform.exception_to_status', $config['exception_to_status']);
×
UNCOV
211
        $container->setParameter('api_platform.formats', $formats);
×
UNCOV
212
        $container->setParameter('api_platform.patch_formats', $patchFormats);
×
UNCOV
213
        $container->setParameter('api_platform.error_formats', $errorFormats);
×
UNCOV
214
        $container->setParameter('api_platform.docs_formats', $docsFormats);
×
UNCOV
215
        $container->setParameter('api_platform.eager_loading.enabled', $this->isConfigEnabled($container, $config['eager_loading']));
×
UNCOV
216
        $container->setParameter('api_platform.eager_loading.max_joins', $config['eager_loading']['max_joins']);
×
UNCOV
217
        $container->setParameter('api_platform.eager_loading.fetch_partial', $config['eager_loading']['fetch_partial']);
×
UNCOV
218
        $container->setParameter('api_platform.eager_loading.force_eager', $config['eager_loading']['force_eager']);
×
UNCOV
219
        $container->setParameter('api_platform.collection.exists_parameter_name', $config['collection']['exists_parameter_name']);
×
UNCOV
220
        $container->setParameter('api_platform.collection.order', $config['collection']['order']);
×
UNCOV
221
        $container->setParameter('api_platform.collection.order_parameter_name', $config['collection']['order_parameter_name']);
×
UNCOV
222
        $container->setParameter('api_platform.collection.order_nulls_comparison', $config['collection']['order_nulls_comparison']);
×
UNCOV
223
        $container->setParameter('api_platform.collection.pagination.enabled', $config['defaults']['pagination_enabled'] ?? true);
×
UNCOV
224
        $container->setParameter('api_platform.collection.pagination.partial', $config['defaults']['pagination_partial'] ?? false);
×
UNCOV
225
        $container->setParameter('api_platform.collection.pagination.client_enabled', $config['defaults']['pagination_client_enabled'] ?? false);
×
UNCOV
226
        $container->setParameter('api_platform.collection.pagination.client_items_per_page', $config['defaults']['pagination_client_items_per_page'] ?? false);
×
UNCOV
227
        $container->setParameter('api_platform.collection.pagination.client_partial', $config['defaults']['pagination_client_partial'] ?? false);
×
UNCOV
228
        $container->setParameter('api_platform.collection.pagination.items_per_page', $config['defaults']['pagination_items_per_page'] ?? 30);
×
UNCOV
229
        $container->setParameter('api_platform.collection.pagination.maximum_items_per_page', $config['defaults']['pagination_maximum_items_per_page'] ?? null);
×
UNCOV
230
        $container->setParameter('api_platform.collection.pagination.page_parameter_name', $config['defaults']['pagination_page_parameter_name'] ?? $config['collection']['pagination']['page_parameter_name']);
×
UNCOV
231
        $container->setParameter('api_platform.collection.pagination.enabled_parameter_name', $config['defaults']['pagination_enabled_parameter_name'] ?? $config['collection']['pagination']['enabled_parameter_name']);
×
UNCOV
232
        $container->setParameter('api_platform.collection.pagination.items_per_page_parameter_name', $config['defaults']['pagination_items_per_page_parameter_name'] ?? $config['collection']['pagination']['items_per_page_parameter_name']);
×
UNCOV
233
        $container->setParameter('api_platform.collection.pagination.partial_parameter_name', $config['defaults']['pagination_partial_parameter_name'] ?? $config['collection']['pagination']['partial_parameter_name']);
×
UNCOV
234
        $container->setParameter('api_platform.collection.pagination', $this->getPaginationDefaults($config['defaults'] ?? [], $config['collection']['pagination']));
×
UNCOV
235
        $container->setParameter('api_platform.http_cache.etag', $config['defaults']['cache_headers']['etag'] ?? true);
×
UNCOV
236
        $container->setParameter('api_platform.http_cache.max_age', $config['defaults']['cache_headers']['max_age'] ?? null);
×
UNCOV
237
        $container->setParameter('api_platform.http_cache.shared_max_age', $config['defaults']['cache_headers']['shared_max_age'] ?? null);
×
UNCOV
238
        $container->setParameter('api_platform.http_cache.vary', $config['defaults']['cache_headers']['vary'] ?? ['Accept']);
×
UNCOV
239
        $container->setParameter('api_platform.http_cache.public', $config['defaults']['cache_headers']['public'] ?? $config['http_cache']['public']);
×
UNCOV
240
        $container->setParameter('api_platform.http_cache.invalidation.max_header_length', $config['defaults']['cache_headers']['invalidation']['max_header_length'] ?? $config['http_cache']['invalidation']['max_header_length']);
×
UNCOV
241
        $container->setParameter('api_platform.http_cache.invalidation.xkey.glue', $config['defaults']['cache_headers']['invalidation']['xkey']['glue'] ?? $config['http_cache']['invalidation']['xkey']['glue']);
×
242

UNCOV
243
        $container->setAlias('api_platform.path_segment_name_generator', $config['path_segment_name_generator']);
×
244

UNCOV
245
        if ($config['name_converter']) {
×
UNCOV
246
            $container->setAlias('api_platform.name_converter', $config['name_converter']);
×
247
        }
UNCOV
248
        $container->setParameter('api_platform.asset_package', $config['asset_package']);
×
UNCOV
249
        $container->setParameter('api_platform.defaults', $this->normalizeDefaults($config['defaults'] ?? []));
×
UNCOV
250
        $container->setParameter('api_platform.rfc_7807_compliant_errors', $config['defaults']['extra_properties']['rfc_7807_compliant_errors'] ?? false);
×
251

UNCOV
252
        if ($container->getParameter('kernel.debug')) {
×
UNCOV
253
            $container->removeDefinition('api_platform.serializer.mapping.cache_class_metadata_factory');
×
254
        }
255
    }
256

257
    /**
258
     * This method will be removed in 3.0 when "defaults" will be the regular configuration path for the pagination.
259
     */
260
    private function getPaginationDefaults(array $defaults, array $collectionPaginationConfiguration): array
261
    {
UNCOV
262
        $paginationOptions = [];
×
263

UNCOV
264
        foreach ($defaults as $key => $value) {
×
UNCOV
265
            if (!str_starts_with($key, 'pagination_')) {
×
UNCOV
266
                continue;
×
267
            }
268

UNCOV
269
            $paginationOptions[str_replace('pagination_', '', $key)] = $value;
×
270
        }
271

UNCOV
272
        return array_merge($collectionPaginationConfiguration, $paginationOptions);
×
273
    }
274

275
    private function normalizeDefaults(array $defaults): array
276
    {
UNCOV
277
        $normalizedDefaults = ['extra_properties' => $defaults['extra_properties'] ?? []];
×
UNCOV
278
        unset($defaults['extra_properties']);
×
279

UNCOV
280
        $rc = new \ReflectionClass(ApiResource::class);
×
UNCOV
281
        $publicProperties = [];
×
UNCOV
282
        foreach ($rc->getConstructor()->getParameters() as $param) {
×
UNCOV
283
            $publicProperties[$param->getName()] = true;
×
284
        }
285

UNCOV
286
        $nameConverter = new CamelCaseToSnakeCaseNameConverter();
×
UNCOV
287
        foreach ($defaults as $option => $value) {
×
UNCOV
288
            if (isset($publicProperties[$nameConverter->denormalize($option)])) {
×
UNCOV
289
                $normalizedDefaults[$option] = $value;
×
290

UNCOV
291
                continue;
×
292
            }
293

UNCOV
294
            $normalizedDefaults['extra_properties'][$option] = $value;
×
295
        }
296

UNCOV
297
        return $normalizedDefaults;
×
298
    }
299

300
    private function registerMetadataConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
301
    {
UNCOV
302
        [$xmlResources, $yamlResources] = $this->getResourcesToWatch($container, $config);
×
303

UNCOV
304
        $container->setParameter('api_platform.class_name_resources', $this->getClassNameResources());
×
305

UNCOV
306
        $loader->load('metadata/resource_name.xml');
×
UNCOV
307
        $loader->load('metadata/property_name.xml');
×
308

UNCOV
309
        if (!empty($config['resource_class_directories'])) {
×
310
            $container->setParameter('api_platform.resource_class_directories', array_merge(
×
311
                $config['resource_class_directories'],
×
312
                $container->getParameter('api_platform.resource_class_directories')
×
313
            ));
×
314
        }
315

316
        // V3 metadata
UNCOV
317
        $loader->load('metadata/xml.xml');
×
UNCOV
318
        $loader->load('metadata/links.xml');
×
UNCOV
319
        $loader->load('metadata/property.xml');
×
UNCOV
320
        $loader->load('metadata/resource.xml');
×
UNCOV
321
        $loader->load('metadata/operation.xml');
×
322

UNCOV
323
        $container->getDefinition('api_platform.metadata.resource_extractor.xml')->replaceArgument(0, $xmlResources);
×
UNCOV
324
        $container->getDefinition('api_platform.metadata.property_extractor.xml')->replaceArgument(0, $xmlResources);
×
325

UNCOV
326
        if (class_exists(PhpDocParser::class) || interface_exists(DocBlockFactoryInterface::class)) {
×
UNCOV
327
            $loader->load('metadata/php_doc.xml');
×
328
        }
329

UNCOV
330
        if (class_exists(Yaml::class)) {
×
UNCOV
331
            $loader->load('metadata/yaml.xml');
×
UNCOV
332
            $container->getDefinition('api_platform.metadata.resource_extractor.yaml')->replaceArgument(0, $yamlResources);
×
UNCOV
333
            $container->getDefinition('api_platform.metadata.property_extractor.yaml')->replaceArgument(0, $yamlResources);
×
334
        }
335
    }
336

337
    private function getClassNameResources(): array
338
    {
UNCOV
339
        return [
×
UNCOV
340
            Error::class,
×
UNCOV
341
            ValidationException::class,
×
UNCOV
342
        ];
×
343
    }
344

345
    private function getBundlesResourcesPaths(ContainerBuilder $container, array $config): array
346
    {
UNCOV
347
        $bundlesResourcesPaths = [];
×
348

UNCOV
349
        foreach ($container->getParameter('kernel.bundles_metadata') as $bundle) {
×
UNCOV
350
            $dirname = $bundle['path'];
×
UNCOV
351
            $paths = [
×
UNCOV
352
                "$dirname/ApiResource",
×
UNCOV
353
                "$dirname/src/ApiResource",
×
UNCOV
354
            ];
×
UNCOV
355
            foreach (['.yaml', '.yml', '.xml', ''] as $extension) {
×
UNCOV
356
                $paths[] = "$dirname/Resources/config/api_resources$extension";
×
UNCOV
357
                $paths[] = "$dirname/config/api_resources$extension";
×
358
            }
UNCOV
359
            if ($this->isConfigEnabled($container, $config['doctrine'])) {
×
UNCOV
360
                $paths[] = "$dirname/Entity";
×
UNCOV
361
                $paths[] = "$dirname/src/Entity";
×
362
            }
UNCOV
363
            if ($this->isConfigEnabled($container, $config['doctrine_mongodb_odm'])) {
×
UNCOV
364
                $paths[] = "$dirname/Document";
×
UNCOV
365
                $paths[] = "$dirname/src/Document";
×
366
            }
367

UNCOV
368
            foreach ($paths as $path) {
×
UNCOV
369
                if ($container->fileExists($path, false)) {
×
UNCOV
370
                    $bundlesResourcesPaths[] = $path;
×
371
                }
372
            }
373
        }
374

UNCOV
375
        return $bundlesResourcesPaths;
×
376
    }
377

378
    private function getResourcesToWatch(ContainerBuilder $container, array $config): array
379
    {
UNCOV
380
        $paths = array_unique(array_merge($this->getBundlesResourcesPaths($container, $config), $config['mapping']['paths']));
×
381

UNCOV
382
        if (!$config['mapping']['paths']) {
×
UNCOV
383
            $projectDir = $container->getParameter('kernel.project_dir');
×
UNCOV
384
            foreach (["$projectDir/config/api_platform", "$projectDir/src/ApiResource"] as $dir) {
×
UNCOV
385
                if (is_dir($dir)) {
×
UNCOV
386
                    $paths[] = $dir;
×
387
                }
388
            }
389

UNCOV
390
            if ($this->isConfigEnabled($container, $config['doctrine']) && is_dir($doctrinePath = "$projectDir/src/Entity")) {
×
391
                $paths[] = $doctrinePath;
×
392
            }
393

UNCOV
394
            if ($this->isConfigEnabled($container, $config['doctrine_mongodb_odm']) && is_dir($documentPath = "$projectDir/src/Document")) {
×
395
                $paths[] = $documentPath;
×
396
            }
397
        }
398

UNCOV
399
        $resources = ['yml' => [], 'xml' => [], 'dir' => []];
×
400

UNCOV
401
        foreach ($paths as $path) {
×
UNCOV
402
            if (is_dir($path)) {
×
UNCOV
403
                foreach (Finder::create()->followLinks()->files()->in($path)->name('/\.(xml|ya?ml)$/')->sortByName() as $file) {
×
UNCOV
404
                    $resources['yaml' === ($extension = $file->getExtension()) ? 'yml' : $extension][] = $file->getRealPath();
×
405
                }
406

UNCOV
407
                $resources['dir'][] = $path;
×
UNCOV
408
                $container->addResource(new DirectoryResource($path, '/\.(xml|ya?ml|php)$/'));
×
409

UNCOV
410
                continue;
×
411
            }
412

413
            if ($container->fileExists($path, false)) {
×
414
                if (!preg_match('/\.(xml|ya?ml)$/', (string) $path, $matches)) {
×
415
                    throw new RuntimeException(sprintf('Unsupported mapping type in "%s", supported types are XML & YAML.', $path));
×
416
                }
417

418
                $resources['yaml' === $matches[1] ? 'yml' : $matches[1]][] = $path;
×
419

420
                continue;
×
421
            }
422

423
            throw new RuntimeException(sprintf('Could not open file or directory "%s".', $path));
×
424
        }
425

UNCOV
426
        $container->setParameter('api_platform.resource_class_directories', $resources['dir']);
×
427

UNCOV
428
        return [$resources['xml'], $resources['yml']];
×
429
    }
430

431
    private function registerOAuthConfiguration(ContainerBuilder $container, array $config): void
432
    {
UNCOV
433
        if (!$config['oauth']) {
×
434
            return;
×
435
        }
436

UNCOV
437
        $container->setParameter('api_platform.oauth.enabled', $this->isConfigEnabled($container, $config['oauth']));
×
UNCOV
438
        $container->setParameter('api_platform.oauth.clientId', $config['oauth']['clientId']);
×
UNCOV
439
        $container->setParameter('api_platform.oauth.clientSecret', $config['oauth']['clientSecret']);
×
UNCOV
440
        $container->setParameter('api_platform.oauth.type', $config['oauth']['type']);
×
UNCOV
441
        $container->setParameter('api_platform.oauth.flow', $config['oauth']['flow']);
×
UNCOV
442
        $container->setParameter('api_platform.oauth.tokenUrl', $config['oauth']['tokenUrl']);
×
UNCOV
443
        $container->setParameter('api_platform.oauth.authorizationUrl', $config['oauth']['authorizationUrl']);
×
UNCOV
444
        $container->setParameter('api_platform.oauth.refreshUrl', $config['oauth']['refreshUrl']);
×
UNCOV
445
        $container->setParameter('api_platform.oauth.scopes', $config['oauth']['scopes']);
×
UNCOV
446
        $container->setParameter('api_platform.oauth.pkce', $config['oauth']['pkce']);
×
447

UNCOV
448
        if ($container->hasDefinition('api_platform.swagger_ui.action')) {
×
449
            $container->getDefinition('api_platform.swagger_ui.action')->setArgument(10, $config['oauth']['pkce']);
×
450
        }
451
    }
452

453
    /**
454
     * Registers the Swagger, ReDoc and Swagger UI configuration.
455
     */
456
    private function registerSwaggerConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
457
    {
UNCOV
458
        foreach (array_keys($config['swagger']['api_keys']) as $keyName) {
×
UNCOV
459
            if (!preg_match('/^[a-zA-Z0-9._-]+$/', $keyName)) {
×
460
                trigger_deprecation('api-platform/core', '3.1', sprintf('The swagger api_keys key "%s" is not valid with OpenAPI 3.1 it should match "^[a-zA-Z0-9._-]+$"', $keyName));
×
461
            }
462
        }
463

UNCOV
464
        $container->setParameter('api_platform.swagger.versions', $config['swagger']['versions']);
×
465

UNCOV
466
        if (!$config['enable_swagger'] && $config['enable_swagger_ui']) {
×
467
            throw new RuntimeException('You can not enable the Swagger UI without enabling Swagger, fix this by enabling swagger via the configuration "enable_swagger: true".');
×
468
        }
469

UNCOV
470
        if (!$config['enable_swagger']) {
×
471
            return;
×
472
        }
473

UNCOV
474
        $loader->load('openapi.xml');
×
UNCOV
475
        $loader->load('swagger_ui.xml');
×
476

UNCOV
477
        $loader->load('legacy/swagger_ui.xml');
×
478

UNCOV
479
        if (!$config['enable_swagger_ui'] && !$config['enable_re_doc']) {
×
480
            // Remove the listener but keep the controller to allow customizing the path of the UI
481
            $container->removeDefinition('api_platform.swagger.listener.ui');
×
482
        }
483

UNCOV
484
        $container->setParameter('api_platform.enable_swagger_ui', $config['enable_swagger_ui']);
×
UNCOV
485
        $container->setParameter('api_platform.enable_re_doc', $config['enable_re_doc']);
×
UNCOV
486
        $container->setParameter('api_platform.swagger.api_keys', $config['swagger']['api_keys']);
×
UNCOV
487
        if ($config['openapi']['swagger_ui_extra_configuration'] && $config['swagger']['swagger_ui_extra_configuration']) {
×
488
            throw new RuntimeException('You can not set "swagger_ui_extra_configuration" twice - in "openapi" and "swagger" section.');
×
489
        }
UNCOV
490
        $container->setParameter('api_platform.swagger_ui.extra_configuration', $config['openapi']['swagger_ui_extra_configuration'] ?: $config['swagger']['swagger_ui_extra_configuration']);
×
491
    }
492

493
    private function registerJsonApiConfiguration(array $formats, XmlFileLoader $loader, array $config): void
494
    {
UNCOV
495
        if (!isset($formats['jsonapi'])) {
×
UNCOV
496
            return;
×
497
        }
498

UNCOV
499
        $loader->load('jsonapi.xml');
×
UNCOV
500
        $loader->load('legacy/jsonapi.xml');
×
501
    }
502

503
    private function registerJsonLdHydraConfiguration(ContainerBuilder $container, array $formats, XmlFileLoader $loader, array $config): void
504
    {
UNCOV
505
        if (!isset($formats['jsonld'])) {
×
506
            return;
×
507
        }
508

UNCOV
509
        $loader->load('jsonld.xml');
×
UNCOV
510
        $loader->load('legacy/hydra.xml');
×
UNCOV
511
        $loader->load('hydra.xml');
×
512

UNCOV
513
        if (!$container->has('api_platform.json_schema.schema_factory')) {
×
514
            $container->removeDefinition('api_platform.hydra.json_schema.schema_factory');
×
515
        }
516

UNCOV
517
        if (!$config['enable_docs']) {
×
518
            $container->removeDefinition('api_platform.hydra.listener.response.add_link_header');
×
NEW
519
            $container->removeDefinition('api_platform.hydra.processor.link');
×
520
        }
521
    }
522

523
    private function registerJsonHalConfiguration(array $formats, XmlFileLoader $loader): void
524
    {
UNCOV
525
        if (!isset($formats['jsonhal'])) {
×
526
            return;
×
527
        }
528

UNCOV
529
        $loader->load('hal.xml');
×
530
    }
531

532
    private function registerJsonProblemConfiguration(array $errorFormats, XmlFileLoader $loader): void
533
    {
UNCOV
534
        if (!isset($errorFormats['jsonproblem'])) {
×
535
            return;
×
536
        }
537

UNCOV
538
        $loader->load('problem.xml');
×
539
    }
540

541
    private function registerGraphQlConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
542
    {
UNCOV
543
        $enabled = $this->isConfigEnabled($container, $config['graphql']);
×
544

UNCOV
545
        $graphqlIntrospectionEnabled = $enabled && $this->isConfigEnabled($container, $config['graphql']['introspection']);
×
546

UNCOV
547
        $graphiqlEnabled = $enabled && $this->isConfigEnabled($container, $config['graphql']['graphiql']);
×
UNCOV
548
        $graphqlPlayGroundEnabled = $enabled && $this->isConfigEnabled($container, $config['graphql']['graphql_playground']);
×
UNCOV
549
        if ($graphqlPlayGroundEnabled) {
×
550
            trigger_deprecation('api-platform/core', '3.1', 'GraphQL Playground is deprecated and will be removed in API Platform 4.0. Only GraphiQL will be available in the future. Set api_platform.graphql.graphql_playground to false in the configuration to remove this deprecation.');
×
551
        }
552

UNCOV
553
        $container->setParameter('api_platform.graphql.enabled', $enabled);
×
UNCOV
554
        $container->setParameter('api_platform.graphql.introspection.enabled', $graphqlIntrospectionEnabled);
×
UNCOV
555
        $container->setParameter('api_platform.graphql.graphiql.enabled', $graphiqlEnabled);
×
UNCOV
556
        $container->setParameter('api_platform.graphql.graphql_playground.enabled', $graphqlPlayGroundEnabled);
×
UNCOV
557
        $container->setParameter('api_platform.graphql.collection.pagination', $config['graphql']['collection']['pagination']);
×
558

UNCOV
559
        if (!$enabled) {
×
560
            return;
×
561
        }
562

UNCOV
563
        $container->setParameter('api_platform.graphql.default_ide', $config['graphql']['default_ide']);
×
UNCOV
564
        $container->setParameter('api_platform.graphql.nesting_separator', $config['graphql']['nesting_separator']);
×
565

UNCOV
566
        $loader->load('graphql.xml');
×
567

568
        // @phpstan-ignore-next-line because PHPStan uses the container of the test env cache and in test the parameter kernel.bundles always contains the key TwigBundle
UNCOV
569
        if (!class_exists(Environment::class) || !isset($container->getParameter('kernel.bundles')['TwigBundle'])) {
×
UNCOV
570
            if ($graphiqlEnabled || $graphqlPlayGroundEnabled) {
×
UNCOV
571
                throw new RuntimeException(sprintf('GraphiQL and GraphQL Playground interfaces depend on Twig. Please activate TwigBundle for the %s environnement or disable GraphiQL and GraphQL Playground.', $container->getParameter('kernel.environment')));
×
572
            }
UNCOV
573
            $container->removeDefinition('api_platform.graphql.action.graphiql');
×
UNCOV
574
            $container->removeDefinition('api_platform.graphql.action.graphql_playground');
×
575
        }
576

UNCOV
577
        $container->registerForAutoconfiguration(QueryItemResolverInterface::class)
×
UNCOV
578
            ->addTag('api_platform.graphql.resolver');
×
UNCOV
579
        $container->registerForAutoconfiguration(QueryCollectionResolverInterface::class)
×
UNCOV
580
            ->addTag('api_platform.graphql.resolver');
×
UNCOV
581
        $container->registerForAutoconfiguration(MutationResolverInterface::class)
×
UNCOV
582
            ->addTag('api_platform.graphql.resolver');
×
UNCOV
583
        $container->registerForAutoconfiguration(GraphQlTypeInterface::class)
×
UNCOV
584
            ->addTag('api_platform.graphql.type');
×
UNCOV
585
        $container->registerForAutoconfiguration(ErrorHandlerInterface::class)
×
UNCOV
586
            ->addTag('api_platform.graphql.error_handler');
×
587

588
        /* TODO: remove these in 4.x only one resolver factory is used and we're using providers/processors */
UNCOV
589
        if ($config['event_listeners_backward_compatibility_layer'] ?? true) {
×
590
            // @TODO: API Platform 3.3 trigger_deprecation('api-platform/core', '3.3', 'In API Platform 4 only one factory "api_platform.graphql.resolver.factory.item" will remain. Stages are deprecated in favor of using a provider/processor.');
591
            // + deprecate every service from legacy/graphql.xml
UNCOV
592
            $loader->load('legacy/graphql.xml');
×
593

UNCOV
594
            if (!$container->getParameter('kernel.debug')) {
×
UNCOV
595
                return;
×
596
            }
597

UNCOV
598
            $requestStack = new Reference('request_stack', ContainerInterface::NULL_ON_INVALID_REFERENCE);
×
UNCOV
599
            $collectionDataCollectorResolverFactory = (new Definition(DataCollectorResolverFactory::class))
×
UNCOV
600
                ->setDecoratedService('api_platform.graphql.resolver.factory.collection')
×
UNCOV
601
                ->setArguments([new Reference('api_platform.graphql.data_collector.resolver.factory.collection.inner'), $requestStack]);
×
602

UNCOV
603
            $itemDataCollectorResolverFactory = (new Definition(DataCollectorResolverFactory::class))
×
UNCOV
604
                ->setDecoratedService('api_platform.graphql.resolver.factory.item')
×
UNCOV
605
                ->setArguments([new Reference('api_platform.graphql.data_collector.resolver.factory.item.inner'), $requestStack]);
×
606

UNCOV
607
            $itemMutationDataCollectorResolverFactory = (new Definition(DataCollectorResolverFactory::class))
×
UNCOV
608
                ->setDecoratedService('api_platform.graphql.resolver.factory.item_mutation')
×
UNCOV
609
                ->setArguments([new Reference('api_platform.graphql.data_collector.resolver.factory.item_mutation.inner'), $requestStack]);
×
610

UNCOV
611
            $itemSubscriptionDataCollectorResolverFactory = (new Definition(DataCollectorResolverFactory::class))
×
UNCOV
612
                ->setDecoratedService('api_platform.graphql.resolver.factory.item_subscription')
×
UNCOV
613
                ->setArguments([new Reference('api_platform.graphql.data_collector.resolver.factory.item_subscription.inner'), $requestStack]);
×
614

UNCOV
615
            $container->addDefinitions([
×
UNCOV
616
                'api_platform.graphql.data_collector.resolver.factory.collection' => $collectionDataCollectorResolverFactory,
×
UNCOV
617
                'api_platform.graphql.data_collector.resolver.factory.item' => $itemDataCollectorResolverFactory,
×
UNCOV
618
                'api_platform.graphql.data_collector.resolver.factory.item_mutation' => $itemMutationDataCollectorResolverFactory,
×
UNCOV
619
                'api_platform.graphql.data_collector.resolver.factory.item_subscription' => $itemSubscriptionDataCollectorResolverFactory,
×
UNCOV
620
            ]);
×
621
        }
622
    }
623

624
    private function registerCacheConfiguration(ContainerBuilder $container): void
625
    {
UNCOV
626
        if (!$container->hasParameter('kernel.debug') || !$container->getParameter('kernel.debug')) {
×
UNCOV
627
            $container->removeDefinition('api_platform.cache_warmer.cache_pool_clearer');
×
628
        }
629
    }
630

631
    private function registerDoctrineOrmConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
632
    {
UNCOV
633
        if (!$this->isConfigEnabled($container, $config['doctrine'])) {
×
634
            return;
×
635
        }
636

637
        // For older versions of doctrine bridge this allows autoconfiguration for filters
UNCOV
638
        if (!$container->has(ManagerRegistry::class)) {
×
UNCOV
639
            $container->setAlias(ManagerRegistry::class, 'doctrine');
×
640
        }
641

UNCOV
642
        $container->registerForAutoconfiguration(QueryItemExtensionInterface::class)
×
UNCOV
643
            ->addTag('api_platform.doctrine.orm.query_extension.item');
×
UNCOV
644
        $container->registerForAutoconfiguration(DoctrineQueryCollectionExtensionInterface::class)
×
UNCOV
645
            ->addTag('api_platform.doctrine.orm.query_extension.collection');
×
UNCOV
646
        $container->registerForAutoconfiguration(DoctrineOrmAbstractFilter::class);
×
647

UNCOV
648
        $container->registerForAutoconfiguration(OrmLinksHandlerInterface::class)
×
UNCOV
649
            ->addTag('api_platform.doctrine.orm.links_handler');
×
650

UNCOV
651
        $loader->load('doctrine_orm.xml');
×
652

UNCOV
653
        if ($this->isConfigEnabled($container, $config['eager_loading'])) {
×
UNCOV
654
            return;
×
655
        }
656

657
        $container->removeAlias(EagerLoadingExtension::class);
×
658
        $container->removeDefinition('api_platform.doctrine.orm.query_extension.eager_loading');
×
659
        $container->removeAlias(FilterEagerLoadingExtension::class);
×
660
        $container->removeDefinition('api_platform.doctrine.orm.query_extension.filter_eager_loading');
×
661
    }
662

663
    private function registerDoctrineMongoDbOdmConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
664
    {
UNCOV
665
        if (!$this->isConfigEnabled($container, $config['doctrine_mongodb_odm'])) {
×
UNCOV
666
            return;
×
667
        }
668

UNCOV
669
        $container->registerForAutoconfiguration(AggregationItemExtensionInterface::class)
×
UNCOV
670
            ->addTag('api_platform.doctrine_mongodb.odm.aggregation_extension.item');
×
UNCOV
671
        $container->registerForAutoconfiguration(AggregationCollectionExtensionInterface::class)
×
UNCOV
672
            ->addTag('api_platform.doctrine_mongodb.odm.aggregation_extension.collection');
×
UNCOV
673
        $container->registerForAutoconfiguration(DoctrineMongoDbOdmAbstractFilter::class)
×
UNCOV
674
            ->setBindings(['$managerRegistry' => new Reference('doctrine_mongodb')]);
×
UNCOV
675
        $container->registerForAutoconfiguration(OdmLinksHandlerInterface::class)
×
UNCOV
676
            ->addTag('api_platform.doctrine.odm.links_handler');
×
677

UNCOV
678
        $loader->load('doctrine_mongodb_odm.xml');
×
679
    }
680

681
    private function registerHttpCacheConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
682
    {
UNCOV
683
        $loader->load('http_cache.xml');
×
UNCOV
684
        $loader->load('legacy/http_cache.xml');
×
685

UNCOV
686
        if (!$this->isConfigEnabled($container, $config['http_cache']['invalidation'])) {
×
687
            return;
×
688
        }
689

UNCOV
690
        if ($this->isConfigEnabled($container, $config['doctrine'])) {
×
UNCOV
691
            $loader->load('doctrine_orm_http_cache_purger.xml');
×
692
        }
693

UNCOV
694
        $loader->load('http_cache_purger.xml');
×
UNCOV
695
        $loader->load('legacy/http_cache_purger.xml');
×
696

UNCOV
697
        foreach ($config['http_cache']['invalidation']['scoped_clients'] as $client) {
×
UNCOV
698
            $definition = $container->getDefinition($client);
×
UNCOV
699
            $definition->addTag('api_platform.http_cache.http_client');
×
700
        }
701

UNCOV
702
        if (!($urls = $config['http_cache']['invalidation']['urls'])) {
×
UNCOV
703
            $urls = $config['http_cache']['invalidation']['varnish_urls'];
×
704
        }
705

UNCOV
706
        foreach ($urls as $key => $url) {
×
UNCOV
707
            $definition = new Definition(ScopingHttpClient::class, [new Reference('http_client'), $url, ['base_uri' => $url] + $config['http_cache']['invalidation']['request_options']]);
×
UNCOV
708
            $definition->setFactory([ScopingHttpClient::class, 'forBaseUri']);
×
UNCOV
709
            $definition->addTag('api_platform.http_cache.http_client');
×
UNCOV
710
            $container->setDefinition('api_platform.invalidation_http_client.'.$key, $definition);
×
711
        }
712

UNCOV
713
        $serviceName = $config['http_cache']['invalidation']['purger'];
×
714

UNCOV
715
        if (!$container->hasDefinition('api_platform.http_cache.purger')) {
×
UNCOV
716
            $container->setAlias('api_platform.http_cache.purger', $serviceName);
×
717
        }
718
    }
719

720
    /**
721
     * Normalizes the format from config to the one accepted by Symfony HttpFoundation.
722
     */
723
    private function getFormats(array $configFormats): array
724
    {
UNCOV
725
        $formats = [];
×
UNCOV
726
        foreach ($configFormats as $format => $value) {
×
UNCOV
727
            foreach ($value['mime_types'] as $mimeType) {
×
UNCOV
728
                $formats[$format][] = $mimeType;
×
729
            }
730
        }
731

UNCOV
732
        return $formats;
×
733
    }
734

735
    private function registerValidatorConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
736
    {
UNCOV
737
        if (interface_exists(ValidatorInterface::class)) {
×
UNCOV
738
            $loader->load('metadata/validator.xml');
×
UNCOV
739
            $loader->load('symfony/validator.xml');
×
740

UNCOV
741
            if ($this->isConfigEnabled($container, $config['graphql'])) {
×
UNCOV
742
                $loader->load('graphql/validator.xml');
×
743
            }
744

UNCOV
745
            $container->registerForAutoconfiguration(ValidationGroupsGeneratorInterface::class)
×
UNCOV
746
                ->addTag('api_platform.validation_groups_generator');
×
UNCOV
747
            $container->registerForAutoconfiguration(PropertySchemaRestrictionMetadataInterface::class)
×
UNCOV
748
                ->addTag('api_platform.metadata.property_schema_restriction');
×
749

UNCOV
750
            $loader->load('legacy/validator.xml');
×
751
        }
752

UNCOV
753
        if (!$config['validator']) {
×
754
            return;
×
755
        }
756

UNCOV
757
        $container->setParameter('api_platform.validator.serialize_payload_fields', $config['validator']['serialize_payload_fields']);
×
UNCOV
758
        $container->setParameter('api_platform.validator.query_parameter_validation', $config['validator']['query_parameter_validation']);
×
759

UNCOV
760
        if (!$config['validator']['query_parameter_validation']) {
×
761
            $container->removeDefinition('api_platform.listener.view.validate_query_parameters');
×
762
            $container->removeDefinition('api_platform.validator.query_parameter_validator');
×
763
        }
764
    }
765

766
    private function registerDataCollectorConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
767
    {
UNCOV
768
        if (!$config['enable_profiler']) {
×
769
            return;
×
770
        }
771

UNCOV
772
        $loader->load('data_collector.xml');
×
773

UNCOV
774
        if ($container->hasParameter('kernel.debug') && $container->getParameter('kernel.debug')) {
×
UNCOV
775
            $loader->load('debug.xml');
×
776
        }
777
    }
778

779
    private function registerMercureConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
780
    {
UNCOV
781
        if (!$this->isConfigEnabled($container, $config['mercure'])) {
×
782
            return;
×
783
        }
784

UNCOV
785
        $container->setParameter('api_platform.mercure.include_type', $config['mercure']['include_type']);
×
786

UNCOV
787
        $loader->load('legacy/mercure.xml');
×
UNCOV
788
        $loader->load('mercure.xml');
×
789

UNCOV
790
        if ($this->isConfigEnabled($container, $config['doctrine'])) {
×
UNCOV
791
            $loader->load('doctrine_orm_mercure_publisher.xml');
×
792
        }
UNCOV
793
        if ($this->isConfigEnabled($container, $config['doctrine_mongodb_odm'])) {
×
UNCOV
794
            $loader->load('doctrine_odm_mercure_publisher.xml');
×
795
        }
796

UNCOV
797
        if ($this->isConfigEnabled($container, $config['graphql'])) {
×
UNCOV
798
            $loader->load('graphql_mercure.xml');
×
799
        }
800
    }
801

802
    private function registerMessengerConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
803
    {
UNCOV
804
        if (!$this->isConfigEnabled($container, $config['messenger'])) {
×
805
            return;
×
806
        }
807

UNCOV
808
        $loader->load('messenger.xml');
×
809
    }
810

811
    private function registerElasticsearchConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
812
    {
UNCOV
813
        $enabled = $this->isConfigEnabled($container, $config['elasticsearch']);
×
814

UNCOV
815
        $container->setParameter('api_platform.elasticsearch.enabled', $enabled);
×
816

UNCOV
817
        if (!$enabled) {
×
UNCOV
818
            return;
×
819
        }
820

UNCOV
821
        $clientClass = class_exists(\Elasticsearch\Client::class) ? \Elasticsearch\Client::class : \Elastic\Elasticsearch\Client::class;
×
822

UNCOV
823
        $clientDefinition = new Definition($clientClass);
×
UNCOV
824
        $container->setDefinition('api_platform.elasticsearch.client', $clientDefinition);
×
UNCOV
825
        $container->registerForAutoconfiguration(RequestBodySearchCollectionExtensionInterface::class)
×
UNCOV
826
            ->addTag('api_platform.elasticsearch.request_body_search_extension.collection');
×
UNCOV
827
        $container->setParameter('api_platform.elasticsearch.hosts', $config['elasticsearch']['hosts']);
×
UNCOV
828
        $loader->load('elasticsearch.xml');
×
829

830
        // @phpstan-ignore-next-line
UNCOV
831
        if (\Elasticsearch\Client::class === $clientClass) {
×
832
            $loader->load('legacy/elasticsearch.xml');
×
833
            $container->setParameter('api_platform.elasticsearch.mapping', $config['elasticsearch']['mapping']);
×
834
            $container->setDefinition('api_platform.elasticsearch.client_for_metadata', $clientDefinition);
×
835
        }
836
    }
837

838
    private function registerSecurityConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
839
    {
840
        /** @var string[] $bundles */
UNCOV
841
        $bundles = $container->getParameter('kernel.bundles');
×
842

UNCOV
843
        if (!isset($bundles['SecurityBundle'])) {
×
844
            return;
×
845
        }
846

UNCOV
847
        $loader->load('security.xml');
×
UNCOV
848
        $loader->load('legacy/security.xml');
×
849

UNCOV
850
        if (interface_exists(ValidatorInterface::class)) {
×
UNCOV
851
            $loader->load('symfony/security_validator.xml');
×
852
        }
853

UNCOV
854
        if ($this->isConfigEnabled($container, $config['graphql'])) {
×
UNCOV
855
            $loader->load('graphql/security.xml');
×
856
        }
857
    }
858

859
    private function registerOpenApiConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
860
    {
UNCOV
861
        $container->setParameter('api_platform.openapi.termsOfService', $config['openapi']['termsOfService']);
×
UNCOV
862
        $container->setParameter('api_platform.openapi.contact.name', $config['openapi']['contact']['name']);
×
UNCOV
863
        $container->setParameter('api_platform.openapi.contact.url', $config['openapi']['contact']['url']);
×
UNCOV
864
        $container->setParameter('api_platform.openapi.contact.email', $config['openapi']['contact']['email']);
×
UNCOV
865
        $container->setParameter('api_platform.openapi.license.name', $config['openapi']['license']['name']);
×
UNCOV
866
        $container->setParameter('api_platform.openapi.license.url', $config['openapi']['license']['url']);
×
867

UNCOV
868
        $loader->load('json_schema.xml');
×
869
    }
870

871
    private function registerMakerConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
872
    {
UNCOV
873
        if (!$this->isConfigEnabled($container, $config['maker'])) {
×
874
            return;
×
875
        }
876

UNCOV
877
        $loader->load('maker.xml');
×
878
    }
879

880
    private function registerArgumentResolverConfiguration(XmlFileLoader $loader): void
881
    {
UNCOV
882
        $loader->load('argument_resolver.xml');
×
883
    }
884

885
    private function registerInflectorConfiguration(array $config): void
886
    {
UNCOV
887
        if ($config['keep_legacy_inflector']) {
×
888
            Inflector::keepLegacyInflector(true);
×
889
            trigger_deprecation('api-platform/core', '3.2', 'Using doctrine/inflector is deprecated since API Platform 3.2 and will be removed in API Platform 4. Use symfony/string instead. Run "composer require symfony/string" and set "keep_legacy_inflector" to false in config.');
×
890
        } else {
UNCOV
891
            Inflector::keepLegacyInflector(false);
×
892
        }
893
    }
894
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc