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

api-platform / core / 15255731762

26 May 2025 01:55PM UTC coverage: 0.0% (-26.5%) from 26.526%
15255731762

Pull #7176

github

web-flow
Merge 66f6cf4d2 into 79edced67
Pull Request #7176: Merge 4.1

0 of 387 new or added lines in 28 files covered. (0.0%)

11394 existing lines in 372 files now uncovered.

0 of 51334 relevant lines covered (0.0%)

0.0 hits per line

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

0.0
/src/Laravel/ApiPlatformProvider.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\Laravel;
15

16
use ApiPlatform\GraphQl\Error\ErrorHandler as GraphQlErrorHandler;
17
use ApiPlatform\GraphQl\Error\ErrorHandlerInterface;
18
use ApiPlatform\GraphQl\Executor;
19
use ApiPlatform\GraphQl\ExecutorInterface;
20
use ApiPlatform\GraphQl\Metadata\RuntimeOperationMetadataFactory;
21
use ApiPlatform\GraphQl\Resolver\Factory\ResolverFactory;
22
use ApiPlatform\GraphQl\Resolver\Factory\ResolverFactoryInterface;
23
use ApiPlatform\GraphQl\Resolver\QueryCollectionResolverInterface;
24
use ApiPlatform\GraphQl\Resolver\QueryItemResolverInterface;
25
use ApiPlatform\GraphQl\Resolver\ResourceFieldResolver;
26
use ApiPlatform\GraphQl\Serializer\Exception\ErrorNormalizer as GraphQlErrorNormalizer;
27
use ApiPlatform\GraphQl\Serializer\Exception\HttpExceptionNormalizer as GraphQlHttpExceptionNormalizer;
28
use ApiPlatform\GraphQl\Serializer\Exception\RuntimeExceptionNormalizer as GraphQlRuntimeExceptionNormalizer;
29
use ApiPlatform\GraphQl\Serializer\Exception\ValidationExceptionNormalizer as GraphQlValidationExceptionNormalizer;
30
use ApiPlatform\GraphQl\Serializer\ItemNormalizer as GraphQlItemNormalizer;
31
use ApiPlatform\GraphQl\Serializer\ObjectNormalizer as GraphQlObjectNormalizer;
32
use ApiPlatform\GraphQl\Serializer\SerializerContextBuilder as GraphQlSerializerContextBuilder;
33
use ApiPlatform\GraphQl\State\Processor\NormalizeProcessor;
34
use ApiPlatform\GraphQl\State\Provider\DenormalizeProvider as GraphQlDenormalizeProvider;
35
use ApiPlatform\GraphQl\State\Provider\ReadProvider as GraphQlReadProvider;
36
use ApiPlatform\GraphQl\State\Provider\ResolverProvider;
37
use ApiPlatform\GraphQl\Type\ContextAwareTypeBuilderInterface;
38
use ApiPlatform\GraphQl\Type\FieldsBuilderEnumInterface;
39
use ApiPlatform\GraphQl\Type\SchemaBuilder;
40
use ApiPlatform\GraphQl\Type\SchemaBuilderInterface;
41
use ApiPlatform\GraphQl\Type\TypeBuilder;
42
use ApiPlatform\GraphQl\Type\TypeConverter;
43
use ApiPlatform\GraphQl\Type\TypeConverterInterface;
44
use ApiPlatform\GraphQl\Type\TypesContainer;
45
use ApiPlatform\GraphQl\Type\TypesContainerInterface;
46
use ApiPlatform\GraphQl\Type\TypesFactory;
47
use ApiPlatform\GraphQl\Type\TypesFactoryInterface;
48
use ApiPlatform\Hal\Serializer\CollectionNormalizer as HalCollectionNormalizer;
49
use ApiPlatform\Hal\Serializer\EntrypointNormalizer as HalEntrypointNormalizer;
50
use ApiPlatform\Hal\Serializer\ItemNormalizer as HalItemNormalizer;
51
use ApiPlatform\Hal\Serializer\ObjectNormalizer as HalObjectNormalizer;
52
use ApiPlatform\Hydra\JsonSchema\SchemaFactory as HydraSchemaFactory;
53
use ApiPlatform\Hydra\Serializer\CollectionFiltersNormalizer as HydraCollectionFiltersNormalizer;
54
use ApiPlatform\Hydra\Serializer\CollectionNormalizer as HydraCollectionNormalizer;
55
use ApiPlatform\Hydra\Serializer\DocumentationNormalizer as HydraDocumentationNormalizer;
56
use ApiPlatform\Hydra\Serializer\EntrypointNormalizer as HydraEntrypointNormalizer;
57
use ApiPlatform\Hydra\Serializer\HydraPrefixNameConverter;
58
use ApiPlatform\Hydra\Serializer\PartialCollectionViewNormalizer as HydraPartialCollectionViewNormalizer;
59
use ApiPlatform\Hydra\State\HydraLinkProcessor;
60
use ApiPlatform\JsonApi\JsonSchema\SchemaFactory as JsonApiSchemaFactory;
61
use ApiPlatform\JsonApi\Serializer\CollectionNormalizer as JsonApiCollectionNormalizer;
62
use ApiPlatform\JsonApi\Serializer\EntrypointNormalizer as JsonApiEntrypointNormalizer;
63
use ApiPlatform\JsonApi\Serializer\ErrorNormalizer as JsonApiErrorNormalizer;
64
use ApiPlatform\JsonApi\Serializer\ItemNormalizer as JsonApiItemNormalizer;
65
use ApiPlatform\JsonApi\Serializer\ObjectNormalizer as JsonApiObjectNormalizer;
66
use ApiPlatform\JsonApi\Serializer\ReservedAttributeNameConverter;
67
use ApiPlatform\JsonLd\AnonymousContextBuilderInterface;
68
use ApiPlatform\JsonLd\ContextBuilder as JsonLdContextBuilder;
69
use ApiPlatform\JsonLd\ContextBuilderInterface;
70
use ApiPlatform\JsonLd\Serializer\ItemNormalizer as JsonLdItemNormalizer;
71
use ApiPlatform\JsonLd\Serializer\ObjectNormalizer as JsonLdObjectNormalizer;
72
use ApiPlatform\JsonSchema\DefinitionNameFactory;
73
use ApiPlatform\JsonSchema\DefinitionNameFactoryInterface;
74
use ApiPlatform\JsonSchema\Metadata\Property\Factory\SchemaPropertyMetadataFactory;
75
use ApiPlatform\JsonSchema\SchemaFactory;
76
use ApiPlatform\JsonSchema\SchemaFactoryInterface;
77
use ApiPlatform\Laravel\ApiResource\Error;
78
use ApiPlatform\Laravel\ApiResource\ValidationError;
79
use ApiPlatform\Laravel\Controller\DocumentationController;
80
use ApiPlatform\Laravel\Controller\EntrypointController;
81
use ApiPlatform\Laravel\Eloquent\Filter\JsonApi\SortFilterParameterProvider;
82
use ApiPlatform\Laravel\Eloquent\Metadata\Factory\Property\EloquentAttributePropertyMetadataFactory;
83
use ApiPlatform\Laravel\Eloquent\Metadata\Factory\Property\EloquentPropertyMetadataFactory;
84
use ApiPlatform\Laravel\Eloquent\Metadata\Factory\Property\EloquentPropertyNameCollectionMetadataFactory;
85
use ApiPlatform\Laravel\Eloquent\Metadata\IdentifiersExtractor as EloquentIdentifiersExtractor;
86
use ApiPlatform\Laravel\Eloquent\Metadata\ModelMetadata;
87
use ApiPlatform\Laravel\Eloquent\Metadata\ResourceClassResolver as EloquentResourceClassResolver;
88
use ApiPlatform\Laravel\Eloquent\PropertyAccess\PropertyAccessor as EloquentPropertyAccessor;
89
use ApiPlatform\Laravel\Eloquent\Serializer\SerializerContextBuilder as EloquentSerializerContextBuilder;
90
use ApiPlatform\Laravel\GraphQl\Controller\EntrypointController as GraphQlEntrypointController;
91
use ApiPlatform\Laravel\GraphQl\Controller\GraphiQlController;
92
use ApiPlatform\Laravel\JsonApi\State\JsonApiProvider;
93
use ApiPlatform\Laravel\Metadata\CachePropertyMetadataFactory;
94
use ApiPlatform\Laravel\Metadata\CachePropertyNameCollectionMetadataFactory;
95
use ApiPlatform\Laravel\Routing\IriConverter;
96
use ApiPlatform\Laravel\Routing\Router as UrlGeneratorRouter;
97
use ApiPlatform\Laravel\Routing\SkolemIriConverter;
98
use ApiPlatform\Laravel\Security\ResourceAccessChecker;
99
use ApiPlatform\Laravel\State\AccessCheckerProvider;
100
use ApiPlatform\Laravel\State\SwaggerUiProcessor;
101
use ApiPlatform\Laravel\State\SwaggerUiProvider;
102
use ApiPlatform\Laravel\State\ValidateProvider;
103
use ApiPlatform\Metadata\IdentifiersExtractor;
104
use ApiPlatform\Metadata\IdentifiersExtractorInterface;
105
use ApiPlatform\Metadata\InflectorInterface;
106
use ApiPlatform\Metadata\IriConverterInterface;
107
use ApiPlatform\Metadata\Operation\Factory\OperationMetadataFactory;
108
use ApiPlatform\Metadata\Operation\Factory\OperationMetadataFactoryInterface;
109
use ApiPlatform\Metadata\Operation\PathSegmentNameGeneratorInterface;
110
use ApiPlatform\Metadata\Operation\UnderscorePathSegmentNameGenerator;
111
use ApiPlatform\Metadata\Property\Factory\AttributePropertyMetadataFactory;
112
use ApiPlatform\Metadata\Property\Factory\ClassLevelAttributePropertyNameCollectionFactory;
113
use ApiPlatform\Metadata\Property\Factory\ConcernsPropertyNameCollectionMetadataFactory;
114
use ApiPlatform\Metadata\Property\Factory\PropertyInfoPropertyMetadataFactory;
115
use ApiPlatform\Metadata\Property\Factory\PropertyInfoPropertyNameCollectionFactory;
116
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
117
use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
118
use ApiPlatform\Metadata\Property\Factory\SerializerPropertyMetadataFactory;
119
use ApiPlatform\Metadata\Resource\Factory\AttributesResourceNameCollectionFactory;
120
use ApiPlatform\Metadata\Resource\Factory\ConcernsResourceNameCollectionFactory;
121
use ApiPlatform\Metadata\Resource\Factory\LinkFactory;
122
use ApiPlatform\Metadata\Resource\Factory\LinkFactoryInterface;
123
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
124
use ApiPlatform\Metadata\Resource\Factory\ResourceNameCollectionFactoryInterface;
125
use ApiPlatform\Metadata\ResourceAccessCheckerInterface;
126
use ApiPlatform\Metadata\ResourceClassResolver;
127
use ApiPlatform\Metadata\ResourceClassResolverInterface;
128
use ApiPlatform\Metadata\UrlGeneratorInterface;
129
use ApiPlatform\Metadata\Util\Inflector;
130
use ApiPlatform\OpenApi\Command\OpenApiCommand;
131
use ApiPlatform\OpenApi\Factory\OpenApiFactory;
132
use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface;
133
use ApiPlatform\OpenApi\Options;
134
use ApiPlatform\OpenApi\Serializer\OpenApiNormalizer;
135
use ApiPlatform\Serializer\ItemNormalizer;
136
use ApiPlatform\Serializer\JsonEncoder;
137
use ApiPlatform\Serializer\Mapping\Factory\ClassMetadataFactory as SerializerClassMetadataFactory;
138
use ApiPlatform\Serializer\Mapping\Loader\PropertyMetadataLoader;
139
use ApiPlatform\Serializer\SerializerContextBuilder;
140
use ApiPlatform\State\CallableProcessor;
141
use ApiPlatform\State\CallableProvider;
142
use ApiPlatform\State\ErrorProvider;
143
use ApiPlatform\State\Pagination\Pagination;
144
use ApiPlatform\State\Pagination\PaginationOptions;
145
use ApiPlatform\State\Processor\AddLinkHeaderProcessor;
146
use ApiPlatform\State\Processor\RespondProcessor;
147
use ApiPlatform\State\Processor\SerializeProcessor;
148
use ApiPlatform\State\Processor\WriteProcessor;
149
use ApiPlatform\State\ProcessorInterface;
150
use ApiPlatform\State\Provider\ContentNegotiationProvider;
151
use ApiPlatform\State\Provider\DeserializeProvider;
152
use ApiPlatform\State\Provider\ParameterProvider;
153
use ApiPlatform\State\Provider\ReadProvider;
154
use ApiPlatform\State\ProviderInterface;
155
use ApiPlatform\State\SerializerContextBuilderInterface;
156
use Illuminate\Config\Repository as ConfigRepository;
157
use Illuminate\Contracts\Foundation\Application;
158
use Illuminate\Routing\Router;
159
use Illuminate\Support\ServiceProvider;
160
use Negotiation\Negotiator;
161
use phpDocumentor\Reflection\DocBlockFactory;
162
use Psr\Log\LoggerInterface;
163
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
164
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
165
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
166
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
167
use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;
168
use Symfony\Component\Routing\RequestContext;
169
use Symfony\Component\Serializer\Encoder\CsvEncoder;
170
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
171
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
172
use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader;
173
use Symfony\Component\Serializer\Mapping\Loader\LoaderChain;
174
use Symfony\Component\Serializer\Mapping\Loader\LoaderInterface;
175
use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter;
176
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
177
use Symfony\Component\Serializer\NameConverter\SnakeCaseToCamelCaseNameConverter;
178
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
179
use Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer;
180
use Symfony\Component\Serializer\Normalizer\DateIntervalNormalizer;
181
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
182
use Symfony\Component\Serializer\Normalizer\DateTimeZoneNormalizer;
183
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
184
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
185
use Symfony\Component\Serializer\Serializer;
186
use Symfony\Component\Serializer\SerializerInterface;
187
use Symfony\Component\WebLink\HttpHeaderSerializer;
188

189
class ApiPlatformProvider extends ServiceProvider
190
{
191
    /**
192
     * Register services.
193
     */
194
    public function register(): void
195
    {
196
        $this->mergeConfigFrom(__DIR__.'/config/api-platform.php', 'api-platform');
×
197

198
        $this->app->singleton(PropertyInfoExtractorInterface::class, function () {
×
199
            $phpDocExtractor = class_exists(DocBlockFactory::class) ? new PhpDocExtractor() : null;
×
200
            $reflectionExtractor = new ReflectionExtractor();
×
201

202
            return new PropertyInfoExtractor(
×
203
                [$reflectionExtractor],
×
204
                $phpDocExtractor ? [$phpDocExtractor, $reflectionExtractor] : [$reflectionExtractor],
×
205
                $phpDocExtractor ? [$phpDocExtractor] : [],
×
206
                [$reflectionExtractor],
×
207
                [$reflectionExtractor]
×
208
            );
×
209
        });
×
210

NEW
211
        $this->app->singleton(ModelMetadata::class, function () {
×
NEW
212
            return new ModelMetadata();
×
NEW
213
        });
×
214

215
        $this->app->bind(LoaderInterface::class, AttributeLoader::class);
×
216
        $this->app->bind(ClassMetadataFactoryInterface::class, ClassMetadataFactory::class);
×
217
        $this->app->singleton(ClassMetadataFactory::class, function (Application $app) {
×
218
            return new ClassMetadataFactory(
×
219
                new LoaderChain([
×
220
                    new PropertyMetadataLoader(
×
221
                        $app->make(PropertyNameCollectionFactoryInterface::class),
×
222
                    ),
×
223
                    new AttributeLoader(),
×
224
                ])
×
225
            );
×
226
        });
×
227

228
        $this->app->singleton(SerializerClassMetadataFactory::class, function (Application $app) {
×
229
            return new SerializerClassMetadataFactory($app->make(ClassMetadataFactoryInterface::class));
×
230
        });
×
231

232
        $this->app->bind(PathSegmentNameGeneratorInterface::class, UnderscorePathSegmentNameGenerator::class);
×
233

234
        $this->app->singleton(ResourceNameCollectionFactoryInterface::class, function (Application $app) {
×
235
            /** @var ConfigRepository */
236
            $config = $app['config'];
×
237
            $paths = $config->get('api-platform.resources') ?? [];
×
238
            $refl = new \ReflectionClass(Error::class);
×
239
            $paths[] = \dirname($refl->getFileName());
×
240

241
            $logger = $app->make(LoggerInterface::class);
×
242

243
            foreach ($paths as $i => $path) {
×
244
                if (!file_exists($path)) {
×
245
                    $logger->warning(\sprintf('We skipped reading resources in "%s" as the path does not exist. Please check the configuration at "api-platform.resources".', $path));
×
246
                    unset($paths[$i]);
×
247
                }
248
            }
249

250
            return new ConcernsResourceNameCollectionFactory($paths, new AttributesResourceNameCollectionFactory($paths));
×
251
        });
×
252

253
        $this->app->bind(ResourceClassResolverInterface::class, ResourceClassResolver::class);
×
254
        $this->app->singleton(ResourceClassResolver::class, function (Application $app) {
×
255
            return new EloquentResourceClassResolver(new ResourceClassResolver($app->make(ResourceNameCollectionFactoryInterface::class)));
×
256
        });
×
257

258
        $this->app->singleton(PropertyMetadataFactoryInterface::class, function (Application $app) {
×
259
            /** @var ConfigRepository $config */
260
            $config = $app['config'];
×
261

262
            return new CachePropertyMetadataFactory(
×
263
                new SchemaPropertyMetadataFactory(
×
264
                    $app->make(ResourceClassResolverInterface::class),
×
NEW
265
                    new PropertyInfoPropertyMetadataFactory(
×
NEW
266
                        $app->make(PropertyInfoExtractorInterface::class),
×
NEW
267
                        new SerializerPropertyMetadataFactory(
×
NEW
268
                            $app->make(SerializerClassMetadataFactory::class),
×
NEW
269
                            new AttributePropertyMetadataFactory(
×
NEW
270
                                new EloquentAttributePropertyMetadataFactory(
×
NEW
271
                                    new EloquentPropertyMetadataFactory(
×
NEW
272
                                        $app->make(ModelMetadata::class),
×
NEW
273
                                    ),
×
NEW
274
                                )
×
NEW
275
                            ),
×
NEW
276
                            $app->make(ResourceClassResolverInterface::class)
×
277
                        ),
×
NEW
278
                    )
×
279
                ),
×
280
                true === $config->get('app.debug') ? 'array' : $config->get('api-platform.cache', 'file')
×
281
            );
×
282
        });
×
283

284
        $this->app->singleton(PropertyNameCollectionFactoryInterface::class, function (Application $app) {
×
285
            /** @var ConfigRepository $config */
286
            $config = $app['config'];
×
287

288
            return new CachePropertyNameCollectionMetadataFactory(
×
289
                new ClassLevelAttributePropertyNameCollectionFactory(
×
290
                    new ConcernsPropertyNameCollectionMetadataFactory(
×
291
                        new EloquentPropertyNameCollectionMetadataFactory(
×
292
                            $app->make(ModelMetadata::class),
×
293
                            new PropertyInfoPropertyNameCollectionFactory($app->make(PropertyInfoExtractorInterface::class)),
×
294
                            $app->make(ResourceClassResolverInterface::class)
×
295
                        )
×
296
                    )
×
297
                ),
×
298
                true === $config->get('app.debug') ? 'array' : $config->get('api-platform.cache', 'file')
×
299
            );
×
300
        });
×
301

302
        $this->app->singleton(LinkFactoryInterface::class, function (Application $app) {
×
303
            return new LinkFactory(
×
304
                $app->make(PropertyNameCollectionFactoryInterface::class),
×
305
                $app->make(PropertyMetadataFactoryInterface::class),
×
306
                $app->make(ResourceClassResolverInterface::class),
×
307
            );
×
308
        });
×
309

310
        $this->app->bind(PropertyAccessorInterface::class, function () {
×
311
            return new EloquentPropertyAccessor();
×
312
        });
×
313

314
        $this->app->bind(NameConverterInterface::class, function (Application $app) {
×
315
            $config = $app['config'];
×
NEW
316
            $nameConverter = $config->get('api-platform.name_converter', SnakeCaseToCamelCaseNameConverter::class);
×
NEW
317
            if ($nameConverter && class_exists($nameConverter)) {
×
NEW
318
                $nameConverter = $app->make($nameConverter);
×
319
            }
320

UNCOV
321
            $defaultContext = $config->get('api-platform.serializer', []);
×
322

NEW
323
            return new HydraPrefixNameConverter(new MetadataAwareNameConverter($app->make(ClassMetadataFactoryInterface::class), $nameConverter), $defaultContext);
×
324
        });
×
325

326
        $this->app->singleton(OperationMetadataFactory::class, function (Application $app) {
×
327
            return new OperationMetadataFactory($app->make(ResourceNameCollectionFactoryInterface::class), $app->make(ResourceMetadataCollectionFactoryInterface::class));
×
328
        });
×
329

330
        $this->app->bind(OperationMetadataFactoryInterface::class, OperationMetadataFactory::class);
×
331

332
        $this->app->singleton(ReadProvider::class, function (Application $app) {
×
333
            return new ReadProvider($app->make(CallableProvider::class));
×
334
        });
×
335

336
        $this->app->singleton(SwaggerUiProvider::class, function (Application $app) {
×
337
            /** @var ConfigRepository */
338
            $config = $app['config'];
×
339

340
            return new SwaggerUiProvider($app->make(ReadProvider::class), $app->make(OpenApiFactoryInterface::class), $config->get('api-platform.swagger_ui.enabled', false));
×
341
        });
×
342

NEW
343
        $this->app->singleton(DeserializeProvider::class, function (Application $app) {
×
NEW
344
            return new DeserializeProvider($app->make(SwaggerUiProvider::class), $app->make(SerializerInterface::class), $app->make(SerializerContextBuilderInterface::class));
×
UNCOV
345
        });
×
346

NEW
347
        $this->app->singleton(ValidateProvider::class, function (Application $app) {
×
NEW
348
            $config = $app['config'];
×
NEW
349
            $nameConverter = $config->get('api-platform.name_converter', SnakeCaseToCamelCaseNameConverter::class);
×
NEW
350
            if ($nameConverter && class_exists($nameConverter)) {
×
NEW
351
                $nameConverter = $app->make($nameConverter);
×
352
            }
353

NEW
354
            return new ValidateProvider($app->make(DeserializeProvider::class), $app, $app->make(ObjectNormalizer::class), $nameConverter);
×
UNCOV
355
        });
×
356

357
        if (class_exists(JsonApiProvider::class)) {
×
358
            $this->app->extend(DeserializeProvider::class, function (ProviderInterface $inner, Application $app) {
×
359
                return new JsonApiProvider($inner);
×
360
            });
×
361
        }
362

363
        $this->app->singleton(SortFilterParameterProvider::class, function (Application $app) {
×
364
            return new SortFilterParameterProvider();
×
365
        });
×
366

367
        $this->app->singleton(AccessCheckerProvider::class, function (Application $app) {
×
368
            return new AccessCheckerProvider($app->make(ParameterProvider::class), $app->make(ResourceAccessCheckerInterface::class));
×
369
        });
×
370

371
        $this->app->singleton(Negotiator::class, function (Application $app) {
×
372
            return new Negotiator();
×
373
        });
×
374
        $this->app->singleton(ContentNegotiationProvider::class, function (Application $app) {
×
375
            /** @var ConfigRepository */
376
            $config = $app['config'];
×
377

378
            return new ContentNegotiationProvider($app->make(AccessCheckerProvider::class), $app->make(Negotiator::class), $config->get('api-platform.formats'), $config->get('api-platform.error_formats'));
×
379
        });
×
380

381
        $this->app->bind(ProviderInterface::class, ContentNegotiationProvider::class);
×
382

383
        $this->app->singleton(RespondProcessor::class, function () {
×
384
            return new AddLinkHeaderProcessor(new RespondProcessor(), new HttpHeaderSerializer());
×
385
        });
×
386

387
        $this->app->singleton(SerializeProcessor::class, function (Application $app) {
×
388
            return new SerializeProcessor($app->make(RespondProcessor::class), $app->make(Serializer::class), $app->make(SerializerContextBuilderInterface::class));
×
389
        });
×
390

391
        $this->app->singleton(WriteProcessor::class, function (Application $app) {
×
392
            return new WriteProcessor($app->make(SerializeProcessor::class), $app->make(CallableProcessor::class));
×
393
        });
×
394

395
        $this->app->singleton(SerializerContextBuilder::class, function (Application $app) {
×
396
            /** @var ConfigRepository */
397
            $config = $app['config'];
×
398

399
            return new SerializerContextBuilder($app->make(ResourceMetadataCollectionFactoryInterface::class), $config->get('app.debug'));
×
400
        });
×
401
        $this->app->bind(SerializerContextBuilderInterface::class, EloquentSerializerContextBuilder::class);
×
402
        $this->app->singleton(EloquentSerializerContextBuilder::class, function (Application $app) {
×
403
            return new EloquentSerializerContextBuilder(
×
404
                $app->make(SerializerContextBuilder::class),
×
405
                $app->make(PropertyNameCollectionFactoryInterface::class)
×
406
            );
×
407
        });
×
408

409
        $this->app->singleton(HydraLinkProcessor::class, function (Application $app) {
×
410
            return new HydraLinkProcessor($app->make(WriteProcessor::class), $app->make(UrlGeneratorInterface::class));
×
411
        });
×
412

413
        $this->app->bind(ProcessorInterface::class, function (Application $app) {
×
414
            $config = $app['config'];
×
415
            if ($config->has('api-platform.formats.jsonld')) {
×
416
                return $app->make(HydraLinkProcessor::class);
×
417
            }
418

419
            return $app->make(WriteProcessor::class);
×
420
        });
×
421

422
        $this->app->singleton(ObjectNormalizer::class, function (Application $app) {
×
423
            $config = $app['config'];
×
424
            $defaultContext = $config->get('api-platform.serializer', []);
×
425

426
            return new ObjectNormalizer(defaultContext: $defaultContext);
×
427
        });
×
428

429
        $this->app->singleton(DateTimeNormalizer::class, function (Application $app) {
×
430
            $config = $app['config'];
×
431
            $defaultContext = $config->get('api-platform.serializer', []);
×
432

433
            return new DateTimeNormalizer(defaultContext: $defaultContext);
×
434
        });
×
435

436
        $this->app->singleton(DateTimeZoneNormalizer::class, function () {
×
437
            return new DateTimeZoneNormalizer();
×
438
        });
×
439

440
        $this->app->singleton(DateIntervalNormalizer::class, function (Application $app) {
×
441
            $config = $app['config'];
×
442
            $defaultContext = $config->get('api-platform.serializer', []);
×
443

444
            return new DateIntervalNormalizer(defaultContext: $defaultContext);
×
445
        });
×
446

447
        $this->app->singleton(JsonEncoder::class, function () {
×
448
            return new JsonEncoder('jsonld');
×
449
        });
×
450

451
        $this->app->bind(IriConverterInterface::class, IriConverter::class);
×
452
        $this->app->singleton(IriConverter::class, function (Application $app) {
×
453
            return new IriConverter($app->make(CallableProvider::class), $app->make(OperationMetadataFactoryInterface::class), $app->make(UrlGeneratorRouter::class), $app->make(IdentifiersExtractorInterface::class), $app->make(ResourceClassResolverInterface::class), $app->make(ResourceMetadataCollectionFactoryInterface::class), $app->make(SkolemIriConverter::class));
×
454
        });
×
455

456
        $this->app->singleton(SkolemIriConverter::class, function (Application $app) {
×
457
            return new SkolemIriConverter($app->make(UrlGeneratorRouter::class));
×
458
        });
×
459

460
        $this->app->bind(IdentifiersExtractorInterface::class, IdentifiersExtractor::class);
×
461
        $this->app->singleton(IdentifiersExtractor::class, function (Application $app) {
×
462
            return new EloquentIdentifiersExtractor(
×
463
                new IdentifiersExtractor(
×
464
                    $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
465
                    $app->make(ResourceClassResolverInterface::class),
×
466
                    $app->make(PropertyNameCollectionFactoryInterface::class),
×
467
                    $app->make(PropertyMetadataFactoryInterface::class),
×
468
                    $app->make(PropertyAccessorInterface::class)
×
469
                )
×
470
            );
×
471
        });
×
472

473
        $this->app->bind(UrlGeneratorInterface::class, UrlGeneratorRouter::class);
×
474
        $this->app->singleton(UrlGeneratorRouter::class, function (Application $app) {
×
475
            $request = $app->make('request');
×
476
            // https://github.com/laravel/framework/blob/2bfb70bca53e24227a6f921f39d84ba452efd8e0/src/Illuminate/Routing/CompiledRouteCollection.php#L112
477
            $trimmedRequest = $request->duplicate();
×
478
            $parts = explode('?', $request->server->get('REQUEST_URI'), 2);
×
479
            $trimmedRequest->server->set(
×
480
                'REQUEST_URI',
×
481
                rtrim($parts[0], '/').(isset($parts[1]) ? '?'.$parts[1] : '')
×
482
            );
×
483

484
            $urlGenerator = new UrlGeneratorRouter($app->make(Router::class));
×
485
            $urlGenerator->setContext((new RequestContext())->fromRequest($trimmedRequest));
×
486

487
            return $urlGenerator;
×
488
        });
×
489

490
        $this->app->bind(ContextBuilderInterface::class, JsonLdContextBuilder::class);
×
491
        $this->app->singleton(JsonLdContextBuilder::class, function (Application $app) {
×
492
            $config = $app['config'];
×
493
            $defaultContext = $config->get('api-platform.serializer', []);
×
494

495
            return new JsonLdContextBuilder(
×
496
                $app->make(ResourceNameCollectionFactoryInterface::class),
×
497
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
498
                $app->make(PropertyNameCollectionFactoryInterface::class),
×
499
                $app->make(PropertyMetadataFactoryInterface::class),
×
500
                $app->make(UrlGeneratorInterface::class),
×
501
                $app->make(IriConverterInterface::class),
×
502
                $app->make(NameConverterInterface::class),
×
503
                $defaultContext
×
504
            );
×
505
        });
×
506

507
        $this->app->singleton(HydraEntrypointNormalizer::class, function (Application $app) {
×
508
            return new HydraEntrypointNormalizer($app->make(ResourceMetadataCollectionFactoryInterface::class), $app->make(IriConverterInterface::class), $app->make(UrlGeneratorInterface::class));
×
509
        });
×
510

511
        $this->app->singleton(ResourceAccessCheckerInterface::class, function () {
×
512
            return new ResourceAccessChecker();
×
513
        });
×
514

515
        $this->app->singleton(ItemNormalizer::class, function (Application $app) {
×
516
            /** @var ConfigRepository */
517
            $config = $app['config'];
×
518
            $defaultContext = $config->get('api-platform.serializer', []);
×
519

520
            return new ItemNormalizer(
×
521
                $app->make(PropertyNameCollectionFactoryInterface::class),
×
522
                $app->make(PropertyMetadataFactoryInterface::class),
×
523
                $app->make(IriConverterInterface::class),
×
524
                $app->make(ResourceClassResolverInterface::class),
×
525
                $app->make(PropertyAccessorInterface::class),
×
526
                $app->make(NameConverterInterface::class),
×
527
                $app->make(ClassMetadataFactoryInterface::class),
×
528
                $app->make(LoggerInterface::class),
×
529
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
530
                $app->make(ResourceAccessCheckerInterface::class),
×
531
                $defaultContext
×
532
            );
×
533
        });
×
534

535
        $this->app->bind(AnonymousContextBuilderInterface::class, JsonLdContextBuilder::class);
×
536

537
        $this->app->singleton(JsonLdObjectNormalizer::class, function (Application $app) {
×
538
            return new JsonLdObjectNormalizer(
×
539
                $app->make(ObjectNormalizer::class),
×
540
                $app->make(IriConverterInterface::class),
×
541
                $app->make(AnonymousContextBuilderInterface::class)
×
542
            );
×
543
        });
×
544

545
        $this->app->singleton(HalCollectionNormalizer::class, function (Application $app) {
×
546
            /** @var ConfigRepository */
547
            $config = $app['config'];
×
548

549
            return new HalCollectionNormalizer(
×
550
                $app->make(ResourceClassResolverInterface::class),
×
551
                $config->get('api-platform.pagination.page_parameter_name'),
×
552
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
553
            );
×
554
        });
×
555

556
        $this->app->singleton(HalObjectNormalizer::class, function (Application $app) {
×
557
            return new HalObjectNormalizer(
×
558
                $app->make(ObjectNormalizer::class),
×
559
                $app->make(IriConverterInterface::class)
×
560
            );
×
561
        });
×
562

563
        $this->app->singleton(HalItemNormalizer::class, function (Application $app) {
×
564
            /** @var ConfigRepository */
565
            $config = $app['config'];
×
566
            $defaultContext = $config->get('api-platform.serializer', []);
×
567

568
            return new HalItemNormalizer(
×
569
                $app->make(PropertyNameCollectionFactoryInterface::class),
×
570
                $app->make(PropertyMetadataFactoryInterface::class),
×
571
                $app->make(IriConverterInterface::class),
×
572
                $app->make(ResourceClassResolverInterface::class),
×
573
                $app->make(PropertyAccessorInterface::class),
×
574
                $app->make(NameConverterInterface::class),
×
575
                $app->make(ClassMetadataFactoryInterface::class),
×
576
                $defaultContext,
×
577
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
578
                $app->make(ResourceAccessCheckerInterface::class),
×
579
            );
×
580
        });
×
581

582
        $this->app->singleton(Options::class, function (Application $app) {
×
583
            /** @var ConfigRepository */
584
            $config = $app['config'];
×
585

586
            return new Options(
×
587
                title: $config->get('api-platform.title', ''),
×
588
                description: $config->get('api-platform.description', ''),
×
589
                version: $config->get('api-platform.version', ''),
×
590
                oAuthEnabled: $config->get('api-platform.swagger_ui.oauth.enabled', false),
×
591
                oAuthType: $config->get('api-platform.swagger_ui.oauth.type', null),
×
592
                oAuthFlow: $config->get('api-platform.swagger_ui.oauth.flow', null),
×
593
                oAuthTokenUrl: $config->get('api-platform.swagger_ui.oauth.tokenUrl', null),
×
594
                oAuthAuthorizationUrl: $config->get('api-platform.swagger_ui.oauth.authorizationUrl', null),
×
595
                oAuthRefreshUrl: $config->get('api-platform.swagger_ui.oauth.refreshUrl', null),
×
596
                oAuthScopes: $config->get('api-platform.swagger_ui.oauth.scopes', []),
×
597
                apiKeys: $config->get('api-platform.swagger_ui.apiKeys', []),
×
598
                contactName: $config->get('api-platform.swagger_ui.contact.name', ''),
×
599
                contactUrl: $config->get('api-platform.swagger_ui.contact.url', ''),
×
600
                contactEmail: $config->get('api-platform.swagger_ui.contact.email', ''),
×
601
                licenseName: $config->get('api-platform.swagger_ui.license.name', ''),
×
602
                licenseUrl: $config->get('api-platform.swagger_ui.license.url', ''),
×
603
                persistAuthorization: $config->get('api-platform.swagger_ui.persist_authorization', false),
×
604
                httpAuth: $config->get('api-platform.swagger_ui.http_auth', []),
×
605
                tags: $config->get('api-platform.openapi.tags', []),
×
606
                errorResourceClass: Error::class,
×
607
                validationErrorResourceClass: ValidationError::class
×
608
            );
×
609
        });
×
610

611
        $this->app->singleton(SwaggerUiProcessor::class, function (Application $app) {
×
612
            /** @var ConfigRepository */
613
            $config = $app['config'];
×
614

615
            return new SwaggerUiProcessor(
×
616
                urlGenerator: $app->make(UrlGeneratorInterface::class),
×
617
                normalizer: $app->make(NormalizerInterface::class),
×
618
                openApiOptions: $app->make(Options::class),
×
619
                oauthClientId: $config->get('api-platform.swagger_ui.oauth.clientId'),
×
620
                oauthClientSecret: $config->get('api-platform.swagger_ui.oauth.clientSecret'),
×
621
                oauthPkce: $config->get('api-platform.swagger_ui.oauth.pkce', false),
×
622
            );
×
623
        });
×
624

625
        $this->app->singleton(DocumentationController::class, function (Application $app) {
×
626
            /** @var ConfigRepository */
627
            $config = $app['config'];
×
628

629
            return new DocumentationController($app->make(ResourceNameCollectionFactoryInterface::class), $config->get('api-platform.title') ?? '', $config->get('api-platform.description') ?? '', $config->get('api-platform.version') ?? '', $app->make(OpenApiFactoryInterface::class), $app->make(ProviderInterface::class), $app->make(ProcessorInterface::class), $app->make(Negotiator::class), $config->get('api-platform.docs_formats'), $config->get('api-platform.swagger_ui.enabled', false));
×
630
        });
×
631

632
        $this->app->singleton(EntrypointController::class, function (Application $app) {
×
633
            /** @var ConfigRepository */
634
            $config = $app['config'];
×
635

636
            return new EntrypointController($app->make(ResourceNameCollectionFactoryInterface::class), $app->make(ProviderInterface::class), $app->make(ProcessorInterface::class), $config->get('api-platform.docs_formats'));
×
637
        });
×
638

639
        $this->app->singleton(Pagination::class, function (Application $app) {
×
640
            /** @var ConfigRepository */
641
            $config = $app['config'];
×
642

643
            return new Pagination($config->get('api-platform.pagination'), []);
×
644
        });
×
645

646
        $this->app->singleton(PaginationOptions::class, function (Application $app) {
×
647
            /** @var ConfigRepository */
648
            $config = $app['config'];
×
649
            $defaults = $config->get('api-platform.defaults');
×
650
            $pagination = $config->get('api-platform.pagination');
×
651

652
            return new PaginationOptions(
×
653
                $defaults['pagination_enabled'] ?? true,
×
654
                $pagination['page_parameter_name'] ?? 'page',
×
655
                $defaults['pagination_client_items_per_page'] ?? false,
×
656
                $pagination['items_per_page_parameter_name'] ?? 'itemsPerPage',
×
657
                $defaults['pagination_client_enabled'] ?? false,
×
658
                $pagination['enabled_parameter_name'] ?? 'pagination',
×
659
                $defaults['pagination_items_per_page'] ?? 30,
×
660
                $defaults['pagination_maximum_items_per_page'] ?? 30,
×
661
                $defaults['pagination_partial'] ?? false,
×
662
                $defaults['pagination_client_partial'] ?? false,
×
663
                $pagination['partial_parameter_name'] ?? 'partial',
×
664
            );
×
665
        });
×
666

667
        $this->app->bind(OpenApiFactoryInterface::class, OpenApiFactory::class);
×
668
        $this->app->singleton(OpenApiFactory::class, function (Application $app) {
×
669
            /** @var ConfigRepository */
670
            $config = $app['config'];
×
671

672
            return new OpenApiFactory(
×
673
                $app->make(ResourceNameCollectionFactoryInterface::class),
×
674
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
675
                $app->make(PropertyNameCollectionFactoryInterface::class),
×
676
                $app->make(PropertyMetadataFactoryInterface::class),
×
677
                $app->make(SchemaFactoryInterface::class),
×
678
                null,
×
679
                $config->get('api-platform.formats'),
×
680
                $app->make(Options::class),
×
681
                $app->make(PaginationOptions::class),
×
682
                null,
×
683
                $config->get('api-platform.error_formats'),
×
684
                // ?RouterInterface $router = null
×
685
            );
×
686
        });
×
687

688
        $this->app->singleton(OpenApiCommand::class, function (Application $app) {
×
689
            return new OpenApiCommand($app->make(OpenApiFactory::class), $app->make(Serializer::class));
×
690
        });
×
691

692
        $this->app->bind(DefinitionNameFactoryInterface::class, DefinitionNameFactory::class);
×
693
        $this->app->singleton(DefinitionNameFactory::class, function (Application $app) {
×
694
            /** @var ConfigRepository */
695
            $config = $app['config'];
×
696

697
            return new DefinitionNameFactory($config->get('api-platform.formats'));
×
698
        });
×
699

700
        $this->app->singleton(SchemaFactory::class, function (Application $app) {
×
701
            /** @var ConfigRepository */
702
            $config = $app['config'];
×
703

704
            return new SchemaFactory(
×
705
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
706
                $app->make(PropertyNameCollectionFactoryInterface::class),
×
707
                $app->make(PropertyMetadataFactoryInterface::class),
×
708
                $app->make(NameConverterInterface::class),
×
709
                $app->make(ResourceClassResolverInterface::class),
×
710
                $config->get('api-platform.formats'),
×
711
                $app->make(DefinitionNameFactoryInterface::class),
×
712
            );
×
713
        });
×
714
        $this->app->singleton(JsonApiSchemaFactory::class, function (Application $app) {
×
715
            return new JsonApiSchemaFactory(
×
716
                $app->make(SchemaFactory::class),
×
717
                $app->make(PropertyMetadataFactoryInterface::class),
×
718
                $app->make(ResourceClassResolverInterface::class),
×
719
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
720
                $app->make(DefinitionNameFactoryInterface::class),
×
721
            );
×
722
        });
×
723
        $this->app->singleton(HydraSchemaFactory::class, function (Application $app) {
×
724
            $config = $app['config'];
×
725
            $defaultContext = $config->get('api-platform.serializer', []);
×
726

727
            return new HydraSchemaFactory(
×
728
                $app->make(JsonApiSchemaFactory::class),
×
729
                $defaultContext
×
730
            );
×
731
        });
×
732

733
        $this->app->bind(SchemaFactoryInterface::class, HydraSchemaFactory::class);
×
734

735
        $this->app->singleton(OpenApiNormalizer::class, function (Application $app) {
×
736
            return new OpenApiNormalizer($app->make(ObjectNormalizer::class));
×
737
        });
×
738

739
        $this->app->singleton(HydraDocumentationNormalizer::class, function (Application $app) {
×
740
            $config = $app['config'];
×
741
            $defaultContext = $config->get('api-platform.serializer', []);
×
742
            $entrypointEnabled = $config->get('api-platform.enable_entrypoint', true);
×
743

744
            return new HydraDocumentationNormalizer(
×
745
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
746
                $app->make(PropertyNameCollectionFactoryInterface::class),
×
747
                $app->make(PropertyMetadataFactoryInterface::class),
×
748
                $app->make(ResourceClassResolverInterface::class),
×
749
                $app->make(UrlGeneratorInterface::class),
×
750
                $app->make(NameConverterInterface::class),
×
751
                $defaultContext,
×
752
                $entrypointEnabled
×
753
            );
×
754
        });
×
755

756
        $this->app->singleton(HydraPartialCollectionViewNormalizer::class, function (Application $app) {
×
757
            $config = $app['config'];
×
758
            $defaultContext = $config->get('api-platform.serializer', []);
×
759

760
            return new HydraPartialCollectionViewNormalizer(
×
761
                new HydraCollectionFiltersNormalizer(
×
762
                    new HydraCollectionNormalizer(
×
763
                        $app->make(ContextBuilderInterface::class),
×
764
                        $app->make(ResourceClassResolverInterface::class),
×
765
                        $app->make(IriConverterInterface::class),
×
766
                        $defaultContext
×
767
                    ),
×
768
                    $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
769
                    $app->make(ResourceClassResolverInterface::class),
×
770
                    null, // filterLocator, we use only Parameters with Laravel and we don't need to call filters there
×
771
                    $defaultContext
×
772
                ),
×
773
                'page',
×
774
                'pagination',
×
775
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
776
                $app->make(PropertyAccessorInterface::class),
×
777
                $config->get('api-platform.url_generation_strategy', UrlGeneratorInterface::ABS_PATH),
×
778
                $defaultContext,
×
779
            );
×
780
        });
×
781

782
        $this->app->singleton(ReservedAttributeNameConverter::class, function (Application $app) {
×
783
            return new ReservedAttributeNameConverter($app->make(NameConverterInterface::class));
×
784
        });
×
785

786
        if (interface_exists(FieldsBuilderEnumInterface::class)) {
×
787
            $this->registerGraphQl();
×
788
        }
789

790
        $this->app->singleton(JsonApiEntrypointNormalizer::class, function (Application $app) {
×
791
            return new JsonApiEntrypointNormalizer(
×
792
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
793
                $app->make(IriConverterInterface::class),
×
794
                $app->make(UrlGeneratorInterface::class),
×
795
            );
×
796
        });
×
797

798
        $this->app->singleton(JsonApiCollectionNormalizer::class, function (Application $app) {
×
799
            /** @var ConfigRepository */
800
            $config = $app['config'];
×
801

802
            return new JsonApiCollectionNormalizer(
×
803
                $app->make(ResourceClassResolverInterface::class),
×
804
                $config->get('api-platform.pagination.page_parameter_name'),
×
805
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
806
            );
×
807
        });
×
808

809
        $this->app->singleton(JsonApiItemNormalizer::class, function (Application $app) {
×
810
            $config = $app['config'];
×
811
            $defaultContext = $config->get('api-platform.serializer', []);
×
812

813
            return new JsonApiItemNormalizer(
×
814
                $app->make(PropertyNameCollectionFactoryInterface::class),
×
815
                $app->make(PropertyMetadataFactoryInterface::class),
×
816
                $app->make(IriConverterInterface::class),
×
817
                $app->make(ResourceClassResolverInterface::class),
×
818
                $app->make(PropertyAccessorInterface::class),
×
819
                $app->make(NameConverterInterface::class),
×
820
                $app->make(ClassMetadataFactoryInterface::class),
×
821
                $defaultContext,
×
822
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
823
                $app->make(ResourceAccessCheckerInterface::class),
×
824
                null
×
825
                // $app->make(TagCollectorInterface::class),
×
826
            );
×
827
        });
×
828

829
        $this->app->singleton(JsonApiErrorNormalizer::class, function (Application $app) {
×
830
            return new JsonApiErrorNormalizer(
×
831
                $app->make(JsonApiItemNormalizer::class),
×
832
            );
×
833
        });
×
834

835
        $this->app->singleton(JsonApiObjectNormalizer::class, function (Application $app) {
×
836
            return new JsonApiObjectNormalizer(
×
837
                $app->make(ObjectNormalizer::class),
×
838
                $app->make(IriConverterInterface::class),
×
839
                $app->make(ResourceClassResolverInterface::class),
×
840
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
841
            );
×
842
        });
×
843

844
        $this->app->singleton('api_platform_normalizer_list', function (Application $app) {
×
845
            $list = new \SplPriorityQueue();
×
846
            $list->insert($app->make(HydraEntrypointNormalizer::class), -800);
×
847
            $list->insert($app->make(HydraPartialCollectionViewNormalizer::class), -800);
×
848
            $list->insert($app->make(HalCollectionNormalizer::class), -800);
×
849
            $list->insert($app->make(HalEntrypointNormalizer::class), -985);
×
850
            $list->insert($app->make(HalObjectNormalizer::class), -995);
×
851
            $list->insert($app->make(HalItemNormalizer::class), -890);
×
852
            $list->insert($app->make(JsonLdItemNormalizer::class), -890);
×
853
            $list->insert($app->make(JsonLdObjectNormalizer::class), -995);
×
854
            $list->insert($app->make(ArrayDenormalizer::class), -990);
×
855
            $list->insert($app->make(DateTimeZoneNormalizer::class), -915);
×
856
            $list->insert($app->make(DateIntervalNormalizer::class), -915);
×
857
            $list->insert($app->make(DateTimeNormalizer::class), -910);
×
858
            $list->insert($app->make(BackedEnumNormalizer::class), -910);
×
859
            $list->insert($app->make(ObjectNormalizer::class), -1000);
×
860
            $list->insert($app->make(ItemNormalizer::class), -895);
×
861
            $list->insert($app->make(OpenApiNormalizer::class), -780);
×
862
            $list->insert($app->make(HydraDocumentationNormalizer::class), -790);
×
863

864
            $list->insert($app->make(JsonApiEntrypointNormalizer::class), -800);
×
865
            $list->insert($app->make(JsonApiCollectionNormalizer::class), -985);
×
866
            $list->insert($app->make(JsonApiItemNormalizer::class), -890);
×
867
            $list->insert($app->make(JsonApiErrorNormalizer::class), -790);
×
868
            $list->insert($app->make(JsonApiObjectNormalizer::class), -995);
×
869

870
            if (interface_exists(FieldsBuilderEnumInterface::class)) {
×
871
                $list->insert($app->make(GraphQlItemNormalizer::class), -890);
×
872
                $list->insert($app->make(GraphQlObjectNormalizer::class), -995);
×
873
                $list->insert($app->make(GraphQlErrorNormalizer::class), -790);
×
874
                $list->insert($app->make(GraphQlValidationExceptionNormalizer::class), -780);
×
875
                $list->insert($app->make(GraphQlHttpExceptionNormalizer::class), -780);
×
876
                $list->insert($app->make(GraphQlRuntimeExceptionNormalizer::class), -780);
×
877
            }
878

879
            return $list;
×
880
        });
×
881

882
        $this->app->bind(SerializerInterface::class, Serializer::class);
×
883
        $this->app->bind(NormalizerInterface::class, Serializer::class);
×
884
        $this->app->singleton(Serializer::class, function (Application $app) {
×
885
            // TODO: unused + implement hal/jsonapi ?
886
            // $list->insert($dataUriNormalizer, -920);
887
            // $list->insert($unwrappingDenormalizer, 1000);
888
            // $list->insert($jsonserializableNormalizer, -900);
889
            // $list->insert($uuidDenormalizer, -895); //Todo ramsey uuid support ?
890

891
            return new Serializer(
×
892
                iterator_to_array($app->make('api_platform_normalizer_list')),
×
893
                [
×
894
                    new JsonEncoder('json'),
×
895
                    $app->make(JsonEncoder::class),
×
896
                    new JsonEncoder('jsonopenapi'),
×
897
                    new JsonEncoder('jsonapi'),
×
898
                    new JsonEncoder('jsonhal'),
×
899
                    new CsvEncoder(),
×
900
                ]
×
901
            );
×
902
        });
×
903

904
        $this->app->singleton(JsonLdItemNormalizer::class, function (Application $app) {
×
905
            $config = $app['config'];
×
906
            $defaultContext = $config->get('api-platform.serializer', []);
×
907

908
            return new JsonLdItemNormalizer(
×
909
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
910
                $app->make(PropertyNameCollectionFactoryInterface::class),
×
911
                $app->make(PropertyMetadataFactoryInterface::class),
×
912
                $app->make(IriConverterInterface::class),
×
913
                $app->make(ResourceClassResolverInterface::class),
×
914
                $app->make(ContextBuilderInterface::class),
×
915
                $app->make(PropertyAccessorInterface::class),
×
916
                $app->make(NameConverterInterface::class),
×
917
                $app->make(ClassMetadataFactoryInterface::class),
×
918
                $defaultContext,
×
919
                $app->make(ResourceAccessCheckerInterface::class)
×
920
            );
×
921
        });
×
922

923
        $this->app->singleton(InflectorInterface::class, function (Application $app) {
×
924
            return new Inflector();
×
925
        });
×
926

927
        if ($this->app->runningInConsole()) {
×
928
            $this->commands([
×
929
                Console\InstallCommand::class,
×
930
                Console\Maker\MakeStateProcessorCommand::class,
×
931
                Console\Maker\MakeStateProviderCommand::class,
×
932
                OpenApiCommand::class,
×
933
            ]);
×
934
        }
935
    }
936

937
    private function registerGraphQl(): void
938
    {
939
        $this->app->singleton(GraphQlItemNormalizer::class, function (Application $app) {
×
940
            return new GraphQlItemNormalizer(
×
941
                $app->make(PropertyNameCollectionFactoryInterface::class),
×
942
                $app->make(PropertyMetadataFactoryInterface::class),
×
943
                $app->make(IriConverterInterface::class),
×
944
                $app->make(IdentifiersExtractorInterface::class),
×
945
                $app->make(ResourceClassResolverInterface::class),
×
946
                $app->make(PropertyAccessorInterface::class),
×
947
                $app->make(NameConverterInterface::class),
×
948
                $app->make(SerializerClassMetadataFactory::class),
×
949
                null,
×
950
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
951
                $app->make(ResourceAccessCheckerInterface::class)
×
952
            );
×
953
        });
×
954

955
        $this->app->singleton(GraphQlObjectNormalizer::class, function (Application $app) {
×
956
            return new GraphQlObjectNormalizer(
×
957
                $app->make(ObjectNormalizer::class),
×
958
                $app->make(IriConverterInterface::class),
×
959
                $app->make(IdentifiersExtractorInterface::class),
×
960
            );
×
961
        });
×
962

963
        $this->app->singleton(GraphQlErrorNormalizer::class, function () {
×
964
            return new GraphQlErrorNormalizer();
×
965
        });
×
966

967
        $this->app->singleton(GraphQlValidationExceptionNormalizer::class, function (Application $app) {
×
968
            /** @var ConfigRepository */
969
            $config = $app['config'];
×
970

971
            return new GraphQlValidationExceptionNormalizer($config->get('api-platform.exception_to_status'));
×
972
        });
×
973

974
        $this->app->singleton(GraphQlHttpExceptionNormalizer::class, function () {
×
975
            return new GraphQlHttpExceptionNormalizer();
×
976
        });
×
977

978
        $this->app->singleton(GraphQlRuntimeExceptionNormalizer::class, function () {
×
979
            return new GraphQlHttpExceptionNormalizer();
×
980
        });
×
981

982
        $this->app->singleton('api_platform.graphql.type_locator', function (Application $app) {
×
983
            $tagged = iterator_to_array($app->tagged('api_platform.graphql.type'));
×
984
            $services = [];
×
985
            foreach ($tagged as $service) {
×
986
                $services[$service->name] = $service;
×
987
            }
988

989
            return new ServiceLocator($services);
×
990
        });
×
991

992
        $this->app->singleton(TypesFactoryInterface::class, function (Application $app) {
×
993
            $tagged = iterator_to_array($app->tagged('api_platform.graphql.type'));
×
994

995
            return new TypesFactory($app->make('api_platform.graphql.type_locator'), array_column($tagged, 'name'));
×
996
        });
×
997

998
        $this->app->singleton(TypesContainerInterface::class, function () {
×
999
            return new TypesContainer();
×
1000
        });
×
1001

1002
        $this->app->singleton(ResourceFieldResolver::class, function (Application $app) {
×
1003
            return new ResourceFieldResolver($app->make(IriConverterInterface::class));
×
1004
        });
×
1005

1006
        $this->app->singleton(ContextAwareTypeBuilderInterface::class, function (Application $app) {
×
1007
            return new TypeBuilder(
×
1008
                $app->make(TypesContainerInterface::class),
×
1009
                $app->make(ResourceFieldResolver::class),
×
1010
                null,
×
1011
                $app->make(Pagination::class)
×
1012
            );
×
1013
        });
×
1014

1015
        $this->app->singleton(TypeConverterInterface::class, function (Application $app) {
×
1016
            return new TypeConverter(
×
1017
                $app->make(ContextAwareTypeBuilderInterface::class),
×
1018
                $app->make(TypesContainerInterface::class),
×
1019
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
1020
                $app->make(PropertyMetadataFactoryInterface::class),
×
1021
            );
×
1022
        });
×
1023

1024
        $this->app->singleton(GraphQlSerializerContextBuilder::class, function (Application $app) {
×
1025
            return new GraphQlSerializerContextBuilder($app->make(NameConverterInterface::class));
×
1026
        });
×
1027

1028
        $this->app->singleton(GraphQlReadProvider::class, function (Application $app) {
×
1029
            /** @var ConfigRepository */
1030
            $config = $app['config'];
×
1031

1032
            return new GraphQlReadProvider(
×
1033
                $this->app->make(CallableProvider::class),
×
1034
                $app->make(IriConverterInterface::class),
×
1035
                $app->make(GraphQlSerializerContextBuilder::class),
×
1036
                $config->get('api-platform.graphql.nesting_separator') ?? '__'
×
1037
            );
×
1038
        });
×
1039
        $this->app->alias(GraphQlReadProvider::class, 'api_platform.graphql.state_provider.read');
×
1040

1041
        $this->app->singleton(ErrorProvider::class, function (Application $app) {
×
1042
            /** @var ConfigRepository */
1043
            $config = $app['config'];
×
1044

1045
            return new ErrorProvider(
×
1046
                $config->get('app.debug'),
×
1047
                $app->make(ResourceClassResolver::class),
×
1048
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
1049
            );
×
1050
        });
×
1051

1052
        $this->app->singleton(ResolverProvider::class, function (Application $app) {
×
1053
            $resolvers = iterator_to_array($app->tagged('api_platform.graphql.resolver'));
×
1054
            $taggedItemResolvers = iterator_to_array($app->tagged(QueryItemResolverInterface::class));
×
1055
            $taggedCollectionResolvers = iterator_to_array($app->tagged(QueryCollectionResolverInterface::class));
×
1056

1057
            return new ResolverProvider(
×
1058
                $app->make(GraphQlReadProvider::class),
×
1059
                new ServiceLocator([...$resolvers, ...$taggedItemResolvers, ...$taggedCollectionResolvers]),
×
1060
            );
×
1061
        });
×
1062

1063
        $this->app->alias(ResolverProvider::class, 'api_platform.graphql.state_provider.resolver');
×
1064

1065
        $this->app->singleton(GraphQlDenormalizeProvider::class, function (Application $app) {
×
1066
            return new GraphQlDenormalizeProvider(
×
1067
                $this->app->make(ResolverProvider::class),
×
1068
                $app->make(SerializerInterface::class),
×
1069
                $app->make(GraphQlSerializerContextBuilder::class)
×
1070
            );
×
1071
        });
×
1072

1073
        $this->app->alias(GraphQlDenormalizeProvider::class, 'api_platform.graphql.state_provider.denormalize');
×
1074

1075
        $this->app->singleton('api_platform.graphql.state_provider.access_checker', function (Application $app) {
×
1076
            return new AccessCheckerProvider($app->make('api_platform.graphql.state_provider.parameter'), $app->make(ResourceAccessCheckerInterface::class));
×
1077
        });
×
1078

1079
        $this->app->singleton(NormalizeProcessor::class, function (Application $app) {
×
1080
            return new NormalizeProcessor(
×
1081
                $app->make(SerializerInterface::class),
×
1082
                $app->make(GraphQlSerializerContextBuilder::class),
×
1083
                $app->make(Pagination::class)
×
1084
            );
×
1085
        });
×
1086
        $this->app->alias(NormalizeProcessor::class, 'api_platform.graphql.state_processor.normalize');
×
1087

1088
        $this->app->singleton('api_platform.graphql.state_processor', function (Application $app) {
×
1089
            return new WriteProcessor(
×
1090
                $app->make('api_platform.graphql.state_processor.normalize'),
×
1091
                $app->make(CallableProcessor::class),
×
1092
            );
×
1093
        });
×
1094

1095
        $this->app->singleton(ResolverFactoryInterface::class, function (Application $app) {
×
1096
            return new ResolverFactory(
×
1097
                $app->make('api_platform.graphql.state_provider.access_checker'),
×
1098
                $app->make('api_platform.graphql.state_processor'),
×
1099
                $app->make('api_platform.graphql.runtime_operation_metadata_factory'),
×
1100
            );
×
1101
        });
×
1102

1103
        $this->app->singleton('api_platform.graphql.runtime_operation_metadata_factory', function (Application $app) {
×
1104
            return new RuntimeOperationMetadataFactory(
×
1105
                $app->make(ResourceMetadataCollectionFactoryInterface::class),
×
1106
                $app->make(UrlGeneratorRouter::class)
×
1107
            );
×
1108
        });
×
1109

1110
        $this->app->singleton(SchemaBuilderInterface::class, function (Application $app) {
×
1111
            return new SchemaBuilder($app->make(ResourceNameCollectionFactoryInterface::class), $app->make(ResourceMetadataCollectionFactoryInterface::class), $app->make(TypesFactoryInterface::class), $app->make(TypesContainerInterface::class), $app->make(FieldsBuilderEnumInterface::class));
×
1112
        });
×
1113

1114
        $this->app->singleton(ErrorHandlerInterface::class, function () {
×
1115
            return new GraphQlErrorHandler();
×
1116
        });
×
1117

1118
        $this->app->singleton(ExecutorInterface::class, function (Application $app) {
×
1119
            /** @var ConfigRepository */
1120
            $config = $app['config'];
×
1121

1122
            return new Executor($config->get('api-platform.graphql.introspection.enabled') ?? false, $config->get('api-platform.graphql.max_query_complexity') ?? 500, $config->get('api-platform.graphql.max_query_depth') ?? 200);
×
1123
        });
×
1124

1125
        $this->app->singleton(GraphiQlController::class, function (Application $app) {
×
1126
            /** @var ConfigRepository */
1127
            $config = $app['config'];
×
1128
            $prefix = $config->get('api-platform.defaults.route_prefix') ?? '';
×
1129

1130
            return new GraphiQlController($prefix);
×
1131
        });
×
1132

1133
        $this->app->singleton(GraphQlEntrypointController::class, function (Application $app) {
×
1134
            /** @var ConfigRepository */
1135
            $config = $app['config'];
×
1136

1137
            return new GraphQlEntrypointController(
×
1138
                $app->make(SchemaBuilderInterface::class),
×
1139
                $app->make(ExecutorInterface::class),
×
1140
                $app->make(GraphiQlController::class),
×
1141
                $app->make(SerializerInterface::class),
×
1142
                $app->make(ErrorHandlerInterface::class),
×
1143
                debug: $config->get('app.debug'),
×
1144
                negotiator: $app->make(Negotiator::class),
×
1145
                formats: $config->get('api-platform.formats')
×
1146
            );
×
1147
        });
×
1148
    }
1149

1150
    /**
1151
     * Bootstrap services.
1152
     */
1153
    public function boot(): void
1154
    {
1155
        if ($this->app->runningInConsole()) {
×
1156
            $this->publishes([
×
1157
                __DIR__.'/config/api-platform.php' => $this->app->configPath('api-platform.php'),
×
1158
            ], 'api-platform-config');
×
1159

1160
            $this->publishes([
×
1161
                __DIR__.'/public' => $this->app->publicPath('vendor/api-platform'),
×
1162
            ], ['api-platform-assets', 'public']);
×
1163
        }
1164

1165
        $this->loadViewsFrom(__DIR__.'/resources/views', 'api-platform');
×
1166

1167
        $config = $this->app['config'];
×
1168

1169
        if ($config->get('api-platform.graphql.enabled')) {
×
1170
            $fieldsBuilder = $this->app->make(FieldsBuilderEnumInterface::class);
×
1171
            $typeBuilder = $this->app->make(ContextAwareTypeBuilderInterface::class);
×
1172
            $typeBuilder->setFieldsBuilderLocator(new ServiceLocator(['api_platform.graphql.fields_builder' => $fieldsBuilder]));
×
1173
        }
1174

1175
        $this->loadRoutesFrom(__DIR__.'/routes/api.php');
×
1176
    }
1177
}
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

© 2025 Coveralls, Inc