|
13 | 13 |
|
14 | 14 | namespace ApiPlatform\Laravel;
|
15 | 15 |
|
| 16 | +use ApiPlatform\GraphQl\Resolver\Factory\ResolverFactoryInterface; |
| 17 | +use ApiPlatform\GraphQl\State\Provider\DenormalizeProvider as GraphQlDenormalizeProvider; |
| 18 | +use ApiPlatform\GraphQl\Type\ContextAwareTypeBuilderInterface; |
| 19 | +use ApiPlatform\GraphQl\Type\FieldsBuilder; |
| 20 | +use ApiPlatform\GraphQl\Type\FieldsBuilderEnumInterface; |
| 21 | +use ApiPlatform\GraphQl\Type\TypeConverterInterface; |
| 22 | +use ApiPlatform\GraphQl\Type\TypesContainerInterface; |
16 | 23 | use ApiPlatform\JsonApi\Filter\SparseFieldset;
|
17 | 24 | use ApiPlatform\JsonApi\Filter\SparseFieldsetParameterProvider;
|
| 25 | +use ApiPlatform\Laravel\Controller\ApiPlatformController; |
18 | 26 | use ApiPlatform\Laravel\Eloquent\Extension\FilterQueryExtension;
|
19 | 27 | use ApiPlatform\Laravel\Eloquent\Extension\QueryExtensionInterface;
|
20 | 28 | use ApiPlatform\Laravel\Eloquent\Filter\BooleanFilter;
|
|
26 | 34 | use ApiPlatform\Laravel\Eloquent\Filter\OrderFilter;
|
27 | 35 | use ApiPlatform\Laravel\Eloquent\Filter\PartialSearchFilter;
|
28 | 36 | use ApiPlatform\Laravel\Eloquent\Filter\RangeFilter;
|
| 37 | +use ApiPlatform\Laravel\Eloquent\Metadata\Factory\Resource\EloquentResourceCollectionMetadataFactory; |
29 | 38 | use ApiPlatform\Laravel\Eloquent\State\CollectionProvider;
|
30 | 39 | use ApiPlatform\Laravel\Eloquent\State\ItemProvider;
|
31 | 40 | use ApiPlatform\Laravel\Eloquent\State\LinksHandler;
|
32 | 41 | use ApiPlatform\Laravel\Eloquent\State\LinksHandlerInterface;
|
33 | 42 | use ApiPlatform\Laravel\Eloquent\State\PersistProcessor;
|
34 | 43 | use ApiPlatform\Laravel\Eloquent\State\RemoveProcessor;
|
| 44 | +use ApiPlatform\Laravel\Exception\ErrorHandler; |
| 45 | +use ApiPlatform\Laravel\Metadata\CacheResourceCollectionMetadataFactory; |
| 46 | +use ApiPlatform\Laravel\Metadata\ParameterValidationResourceMetadataCollectionFactory; |
35 | 47 | use ApiPlatform\Laravel\State\ParameterValidatorProvider;
|
36 | 48 | use ApiPlatform\Laravel\State\SwaggerUiProcessor;
|
| 49 | +use ApiPlatform\Metadata\IdentifiersExtractorInterface; |
| 50 | +use ApiPlatform\Metadata\InflectorInterface; |
| 51 | +use ApiPlatform\Metadata\Operation\PathSegmentNameGeneratorInterface; |
| 52 | +use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface; |
| 53 | +use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface; |
| 54 | +use ApiPlatform\Metadata\Resource\Factory\AlternateUriResourceMetadataCollectionFactory; |
| 55 | +use ApiPlatform\Metadata\Resource\Factory\AttributesResourceMetadataCollectionFactory; |
| 56 | +use ApiPlatform\Metadata\Resource\Factory\ConcernsResourceMetadataCollectionFactory; |
| 57 | +use ApiPlatform\Metadata\Resource\Factory\FiltersResourceMetadataCollectionFactory; |
| 58 | +use ApiPlatform\Metadata\Resource\Factory\FormatsResourceMetadataCollectionFactory; |
| 59 | +use ApiPlatform\Metadata\Resource\Factory\InputOutputResourceMetadataCollectionFactory; |
| 60 | +use ApiPlatform\Metadata\Resource\Factory\LinkFactoryInterface; |
| 61 | +use ApiPlatform\Metadata\Resource\Factory\LinkResourceMetadataCollectionFactory; |
| 62 | +use ApiPlatform\Metadata\Resource\Factory\NotExposedOperationResourceMetadataCollectionFactory; |
| 63 | +use ApiPlatform\Metadata\Resource\Factory\OperationNameResourceMetadataCollectionFactory; |
| 64 | +use ApiPlatform\Metadata\Resource\Factory\ParameterResourceMetadataCollectionFactory; |
| 65 | +use ApiPlatform\Metadata\Resource\Factory\PhpDocResourceMetadataCollectionFactory; |
37 | 66 | use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
|
| 67 | +use ApiPlatform\Metadata\Resource\Factory\UriTemplateResourceMetadataCollectionFactory; |
38 | 68 | use ApiPlatform\Metadata\ResourceAccessCheckerInterface;
|
| 69 | +use ApiPlatform\Metadata\ResourceClassResolverInterface; |
39 | 70 | use ApiPlatform\Metadata\Util\ReflectionClassRecursiveIterator;
|
40 | 71 | use ApiPlatform\Serializer\Filter\FilterInterface as SerializerFilterInterface;
|
41 | 72 | use ApiPlatform\Serializer\Filter\PropertyFilter;
|
|
50 | 81 | use ApiPlatform\State\Provider\ParameterProvider;
|
51 | 82 | use ApiPlatform\State\Provider\SecurityParameterProvider;
|
52 | 83 | use ApiPlatform\State\ProviderInterface;
|
| 84 | +use Illuminate\Contracts\Debug\ExceptionHandler as ExceptionHandlerInterface; |
53 | 85 | use Illuminate\Contracts\Foundation\Application;
|
54 | 86 | use Illuminate\Contracts\Support\DeferrableProvider;
|
55 | 87 | use Illuminate\Support\ServiceProvider;
|
| 88 | +use Negotiation\Negotiator; |
| 89 | +use Psr\Log\LoggerInterface; |
| 90 | +use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter; |
| 91 | +use Symfony\Component\Serializer\NameConverter\NameConverterInterface; |
56 | 92 |
|
57 | 93 | class ApiPlatformDeferredProvider extends ServiceProvider implements DeferrableProvider
|
58 | 94 | {
|
@@ -149,6 +185,130 @@ public function register(): void
|
149 | 185 | });
|
150 | 186 |
|
151 | 187 | $this->autoconfigure($classes, ProviderInterface::class, [ItemProvider::class, CollectionProvider::class, ErrorProvider::class]);
|
| 188 | + |
| 189 | + $this->app->singleton(ResourceMetadataCollectionFactoryInterface::class, function (Application $app) { |
| 190 | + /** @var ConfigRepository $config */ |
| 191 | + $config = $app['config']; |
| 192 | + $formats = $config->get('api-platform.formats'); |
| 193 | + |
| 194 | + if ($config->get('api-platform.swagger_ui.enabled', false) && !isset($formats['html'])) { |
| 195 | + $formats['html'] = ['text/html']; |
| 196 | + } |
| 197 | + |
| 198 | + return new CacheResourceCollectionMetadataFactory( |
| 199 | + new EloquentResourceCollectionMetadataFactory( |
| 200 | + new ParameterValidationResourceMetadataCollectionFactory( |
| 201 | + new ParameterResourceMetadataCollectionFactory( |
| 202 | + $this->app->make(PropertyNameCollectionFactoryInterface::class), |
| 203 | + $this->app->make(PropertyMetadataFactoryInterface::class), |
| 204 | + new AlternateUriResourceMetadataCollectionFactory( |
| 205 | + new FiltersResourceMetadataCollectionFactory( |
| 206 | + new FormatsResourceMetadataCollectionFactory( |
| 207 | + new InputOutputResourceMetadataCollectionFactory( |
| 208 | + new PhpDocResourceMetadataCollectionFactory( |
| 209 | + new OperationNameResourceMetadataCollectionFactory( |
| 210 | + new LinkResourceMetadataCollectionFactory( |
| 211 | + $app->make(LinkFactoryInterface::class), |
| 212 | + new UriTemplateResourceMetadataCollectionFactory( |
| 213 | + $app->make(LinkFactoryInterface::class), |
| 214 | + $app->make(PathSegmentNameGeneratorInterface::class), |
| 215 | + new NotExposedOperationResourceMetadataCollectionFactory( |
| 216 | + $app->make(LinkFactoryInterface::class), |
| 217 | + new AttributesResourceMetadataCollectionFactory( |
| 218 | + new ConcernsResourceMetadataCollectionFactory( |
| 219 | + null, |
| 220 | + $app->make(LoggerInterface::class), |
| 221 | + $config->get('api-platform.defaults', []), |
| 222 | + $config->get('api-platform.graphql.enabled'), |
| 223 | + ), |
| 224 | + $app->make(LoggerInterface::class), |
| 225 | + $config->get('api-platform.defaults', []), |
| 226 | + $config->get('api-platform.graphql.enabled'), |
| 227 | + ), |
| 228 | + ) |
| 229 | + ), |
| 230 | + $config->get('api-platform.graphql.enabled') |
| 231 | + ) |
| 232 | + ) |
| 233 | + ) |
| 234 | + ), |
| 235 | + $formats, |
| 236 | + $config->get('api-platform.patch_formats'), |
| 237 | + ) |
| 238 | + ) |
| 239 | + ), |
| 240 | + $app->make('filters'), |
| 241 | + $app->make(CamelCaseToSnakeCaseNameConverter::class), |
| 242 | + $this->app->make(LoggerInterface::class) |
| 243 | + ), |
| 244 | + $app->make('filters') |
| 245 | + ) |
| 246 | + ), |
| 247 | + true === $config->get('app.debug') ? 'array' : $config->get('api-platform.cache', 'file') |
| 248 | + ); |
| 249 | + }); |
| 250 | + |
| 251 | + $this->app->singleton( |
| 252 | + ExceptionHandlerInterface::class, |
| 253 | + function (Application $app) { |
| 254 | + /** @var ConfigRepository */ |
| 255 | + $config = $app['config']; |
| 256 | + |
| 257 | + return new ErrorHandler( |
| 258 | + $app, |
| 259 | + $app->make(ResourceMetadataCollectionFactoryInterface::class), |
| 260 | + $app->make(ApiPlatformController::class), |
| 261 | + $app->make(IdentifiersExtractorInterface::class), |
| 262 | + $app->make(ResourceClassResolverInterface::class), |
| 263 | + $app->make(Negotiator::class), |
| 264 | + $config->get('api-platform.exception_to_status'), |
| 265 | + $config->get('app.debug') |
| 266 | + ); |
| 267 | + } |
| 268 | + ); |
| 269 | + |
| 270 | + if (interface_exists(FieldsBuilderEnumInterface::class)) { |
| 271 | + $this->registerGraphQl(); |
| 272 | + } |
| 273 | + } |
| 274 | + |
| 275 | + private function registerGraphQl(): void |
| 276 | + { |
| 277 | + $this->app->singleton('api_platform.graphql.state_provider.parameter', function (Application $app) { |
| 278 | + $tagged = iterator_to_array($app->tagged(ParameterProviderInterface::class)); |
| 279 | + $tagged['api_platform.serializer.filter_parameter_provider'] = $app->make(SerializerFilterParameterProvider::class); |
| 280 | + |
| 281 | + return new ParameterProvider( |
| 282 | + new ParameterValidatorProvider( |
| 283 | + new SecurityParameterProvider( |
| 284 | + $app->make(GraphQlDenormalizeProvider::class), |
| 285 | + $app->make(ResourceAccessCheckerInterface::class) |
| 286 | + ), |
| 287 | + ), |
| 288 | + new ServiceLocator($tagged) |
| 289 | + ); |
| 290 | + }); |
| 291 | + |
| 292 | + $this->app->singleton(FieldsBuilderEnumInterface::class, function (Application $app) { |
| 293 | + /** @var ConfigRepository */ |
| 294 | + $config = $app['config']; |
| 295 | + |
| 296 | + return new FieldsBuilder( |
| 297 | + $app->make(PropertyNameCollectionFactoryInterface::class), |
| 298 | + $app->make(PropertyMetadataFactoryInterface::class), |
| 299 | + $app->make(ResourceMetadataCollectionFactoryInterface::class), |
| 300 | + $app->make(ResourceClassResolverInterface::class), |
| 301 | + $app->make(TypesContainerInterface::class), |
| 302 | + $app->make(ContextAwareTypeBuilderInterface::class), |
| 303 | + $app->make(TypeConverterInterface::class), |
| 304 | + $app->make(ResolverFactoryInterface::class), |
| 305 | + $app->make('filters'), |
| 306 | + $app->make(Pagination::class), |
| 307 | + $app->make(NameConverterInterface::class), |
| 308 | + $config->get('api-platform.graphql.nesting_separator') ?? '__', |
| 309 | + $app->make(InflectorInterface::class) |
| 310 | + ); |
| 311 | + }); |
152 | 312 | }
|
153 | 313 |
|
154 | 314 | /**
|
@@ -186,6 +346,9 @@ public function provides(): array
|
186 | 346 | ParameterProvider::class,
|
187 | 347 | FilterQueryExtension::class,
|
188 | 348 | 'filters',
|
| 349 | + ResourceMetadataCollectionFactoryInterface::class, |
| 350 | + 'api_platform.graphql.state_provider.parameter', |
| 351 | + FieldsBuilderEnumInterface::class, |
189 | 352 | ];
|
190 | 353 | }
|
191 | 354 | }
|
0 commit comments