Skip to content

Commit f296976

Browse files
committed
yes
1 parent c16dccd commit f296976

25 files changed

+284
-201
lines changed

features/openapi/docs.feature

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ Feature: Documentation support
1010
And the response should be in JSON
1111
And the header "Content-Type" should be equal to "application/json; charset=utf-8"
1212
# Context
13-
And the JSON node "openapi" should be equal to "3.1.0"
13+
# And the JSON node "openapi" should be equal to "3.1.0"
14+
And the JSON node "openapi" should be equal to "3.0.0"
1415
# Root properties
1516
And the JSON node "info.title" should be equal to "My Dummy API"
1617
And the JSON node "info.description" should contain "This is a test API."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Core\GraphQl\Resolver;
15+
16+
use ApiPlatform\Core\Api\IriConverterInterface;
17+
use ApiPlatform\Core\GraphQl\Serializer\ItemNormalizer;
18+
use ApiPlatform\Core\Util\ClassInfoTrait;
19+
use GraphQL\Type\Definition\ResolveInfo;
20+
21+
/**
22+
* A field resolver that resolves IDs to IRIs and allow to access to the raw ID using the "#id" field.
23+
*
24+
* @experimental
25+
*
26+
* @author Kévin Dunglas <[email protected]>
27+
*/
28+
final class ResourceFieldResolver
29+
{
30+
use ClassInfoTrait;
31+
32+
private $iriConverter;
33+
34+
public function __construct(IriConverterInterface $iriConverter)
35+
{
36+
$this->iriConverter = $iriConverter;
37+
}
38+
39+
public function __invoke(?array $source, array $args, $context, ResolveInfo $info)
40+
{
41+
$property = null;
42+
if ('id' === $info->fieldName && !isset($source['_id']) && isset($source[ItemNormalizer::ITEM_RESOURCE_CLASS_KEY], $source[ItemNormalizer::ITEM_IDENTIFIERS_KEY])) {
43+
return $this->iriConverter->getItemIriFromResourceClass($source[ItemNormalizer::ITEM_RESOURCE_CLASS_KEY], $source[ItemNormalizer::ITEM_IDENTIFIERS_KEY]);
44+
}
45+
46+
if ('_id' === $info->fieldName && !isset($source['_id']) && isset($source['id'])) {
47+
$property = $source['id'];
48+
} elseif (\is_array($source) && isset($source[$info->fieldName])) {
49+
$property = $source[$info->fieldName];
50+
} elseif (isset($source->{$info->fieldName})) {
51+
$property = $source->{$info->fieldName};
52+
}
53+
54+
return $property instanceof \Closure ? $property($source, $args, $context) : $property;
55+
}
56+
}

src/Core/Metadata/Property/Factory/AnnotationPropertyMetadataFactory.php

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use ApiPlatform\Core\Annotation\ApiProperty;
1717
use ApiPlatform\Core\Exception\PropertyNotFoundException;
1818
use ApiPlatform\Core\Metadata\Property\PropertyMetadata;
19+
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\SecuredDummy;
1920
use ApiPlatform\Util\Reflection;
2021
use Doctrine\Common\Annotations\Reader;
2122

src/JsonLd/ContextBuilder.php

+7-2
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,13 @@ private function getResourceContextWithShortname(string $resourceClass, int $ref
217217
}
218218

219219
$convertedName = $this->nameConverter ? $this->nameConverter->normalize($propertyName, $resourceClass, self::FORMAT) : $propertyName;
220-
$jsonldContext = ($propertyMetadata instanceof PropertyMetadata ? $propertyMetadata->getAttributes()['jsonld_context'] : $propertyMetadata->getJsonldContext()) ?? [];
221-
$id = $propertyMetadata instanceof PropertyMetadata ? $propertyMetadata->getIri() : ($propertyMetadata->getTypes()[0] ?? null);
220+
if ($propertyMetadata instanceof PropertyMetadata) {
221+
$jsonldContext = ($propertyMetadata->getAttributes() ?? [])['jsonld_context'] ?? [];
222+
$id = $propertyMetadata->getIri();
223+
} else {
224+
$jsonldContext = $propertyMetadata->getJsonldContext() ?? [];
225+
$id = $propertyMetadata->getTypes()[0] ?? null;
226+
}
222227

223228
if (!$id) {
224229
$id = sprintf('%s/%s', $shortName, $convertedName);

src/Metadata/Property/Factory/AttributePropertyMetadataFactory.php

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use ApiPlatform\Core\Metadata\Property\PropertyMetadata;
1717
use ApiPlatform\Exception\PropertyNotFoundException;
1818
use ApiPlatform\Metadata\ApiProperty;
19+
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\OperationResource;
1920
use ApiPlatform\Util\Reflection;
2021

2122
/**

src/Metadata/Resource/Factory/LinkFactory.php

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
1919
use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
2020
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\AttributeResource;
21+
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\OperationResource;
2122
use Symfony\Component\PropertyInfo\Type;
2223

2324
/**

src/OpenApi/OpenApi.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ final class OpenApi implements DocumentationInterface
2323
{
2424
use ExtensionTrait;
2525

26-
public const VERSION = '3.1.0';
26+
// We're actually supporting 3.1 but swagger ui has a version constraint
27+
// public const VERSION = '3.1.0';
28+
public const VERSION = '3.0.0';
2729

2830
private $openapi;
2931
private $info;

src/Serializer/AbstractItemNormalizer.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,8 @@ public function denormalize($data, $class, $format = null, array $context = [])
296296
if (null !== $previousObject) {
297297
$this->setValue($object, $attribute, $this->propertyAccessor->getValue($previousObject, $attribute));
298298
} else {
299-
$propertyMetaData = $this->propertyMetadataFactory->create($resourceClass, $attribute, $this->getFactoryOptions($context));
300-
$this->setValue($object, $attribute, $propertyMetaData->getDefault());
299+
$propertyMetadata = $this->propertyMetadataFactory->create($resourceClass, $attribute, $this->getFactoryOptions($context));
300+
$this->setValue($object, $attribute, $propertyMetadata->getDefault());
301301
}
302302
}
303303
}

src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php

+35-88
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,13 @@ private function registerCommonConfiguration(ContainerBuilder $container, array
159159
$loader->load('legacy/backward_compatibility.xml');
160160
} else {
161161
$loader->load('v3/api.xml');
162+
$loader->load('legacy/data_provider.xml');
163+
$loader->load('v3/state.xml');
164+
$loader->load('v3/backward_compatibility.xml');
162165
}
163166

164167
$loader->load('data_persister.xml');
165168
$loader->load('data_provider.xml');
166-
$loader->load('state.xml');
167169
$loader->load('filter.xml');
168170

169171
if ($container->hasDefinition('api_platform.operation_method_resolver')) {
@@ -307,25 +309,24 @@ private function registerMetadataConfiguration(ContainerBuilder $container, arra
307309
$container->getDefinition('api_platform.metadata.resource_extractor.xml')->replaceArgument(0, $xmlResources);
308310
$container->getDefinition('api_platform.metadata.property_extractor.xml')->replaceArgument(0, $xmlResources);
309311

310-
if ($config['metadata_backward_compatibility_layer']) {
311-
$loader->load('legacy/metadata.xml');
312-
$container->getDefinition('api_platform.metadata.extractor.xml.legacy')->replaceArgument(0, $xmlResources);
312+
$loader->load('legacy/metadata.xml');
313+
$container->getDefinition('api_platform.metadata.extractor.xml.legacy')->replaceArgument(0, $xmlResources);
313314

314-
if (class_exists(Annotation::class)) {
315-
$loader->load('legacy/metadata_annotation.xml');
316-
}
315+
if (class_exists(Annotation::class)) {
316+
$loader->load('legacy/metadata_annotation.xml');
317+
}
317318

318-
if (interface_exists(DocBlockFactoryInterface::class)) {
319-
$loader->load('legacy/metadata_php_doc.xml');
320-
}
319+
if (interface_exists(DocBlockFactoryInterface::class)) {
320+
$loader->load('legacy/metadata_php_doc.xml');
321+
}
321322

322-
if (class_exists(Yaml::class)) {
323-
$loader->load('legacy/metadata_yaml.xml');
324-
$container->getDefinition('api_platform.metadata.extractor.yaml.legacy')->replaceArgument(0, $yamlResources);
325-
}
326-
} else {
327-
// Load the legacy metadata as well
323+
if (class_exists(Yaml::class)) {
324+
$loader->load('legacy/metadata_yaml.xml');
325+
$container->getDefinition('api_platform.metadata.extractor.yaml.legacy')->replaceArgument(0, $yamlResources);
326+
}
328327

328+
// Load the legacy metadata as well
329+
if (!$config['metadata_backward_compatibility_layer']) {
329330
$loader->load('metadata/links.xml');
330331
$loader->load('metadata/property.xml');
331332
$loader->load('metadata/property_name.xml');
@@ -339,14 +340,8 @@ private function registerMetadataConfiguration(ContainerBuilder $container, arra
339340
$loader->load('metadata/yaml.xml');
340341
$container->getDefinition('api_platform.metadata.resource_extractor.yaml')->replaceArgument(0, $yamlResources);
341342
$container->getDefinition('api_platform.metadata.property_extractor.yaml')->replaceArgument(0, $yamlResources);
343+
$loader->load('metadata/backward_compatibility.xml');
342344
}
343-
344-
// TODO: remove in 3.0 legacy metadata
345-
// if ($config['metadata_backward_compatibility_layer']) {
346-
// $container->removeDefinition('api_platform.metadata.property.metadata_factory');
347-
// $container->setAlias('api_platform.metadata.property.metadata_factory', 'api_platform.metadata.property.metadata_factory.legacy');
348-
// }
349-
350345
}
351346

352347
private function getBundlesResourcesPaths(ContainerBuilder $container, array $config): array
@@ -453,7 +448,7 @@ private function registerSwaggerConfiguration(ContainerBuilder $container, array
453448
}
454449

455450
$loader->load('openapi.xml');
456-
$loader->load('swagger-ui.xml');
451+
$loader->load('swagger_ui.xml');
457452

458453
if (!$config['enable_swagger_ui'] && !$config['enable_re_doc']) {
459454
// Remove the listener but keep the controller to allow customizing the path of the UI
@@ -480,6 +475,7 @@ private function registerSwaggerConfiguration(ContainerBuilder $container, array
480475
}
481476

482477
$loader->load('v3/openapi.xml');
478+
$loader->load('v3/swagger_ui.xml');
483479
}
484480

485481
private function registerJsonApiConfiguration(array $formats, XmlFileLoader $loader): void
@@ -621,10 +617,7 @@ private function registerDoctrineOrmConfiguration(ContainerBuilder $container, a
621617
->setBindings(['$requestStack' => null]);
622618

623619
$loader->load('doctrine_orm.xml');
624-
625-
if ($config['metadata_backward_compatibility_layer']) {
626-
$loader->load('legacy/doctrine_orm.xml');
627-
}
620+
$loader->load('legacy/doctrine_orm.xml');
628621

629622
if ($this->isConfigEnabled($container, $config['eager_loading'])) {
630623
return;
@@ -650,10 +643,7 @@ private function registerDoctrineMongoDbOdmConfiguration(ContainerBuilder $conta
650643
->setBindings(['$managerRegistry' => new Reference('doctrine_mongodb')]);
651644

652645
$loader->load('doctrine_mongodb_odm.xml');
653-
654-
if ($config['metadata_backward_compatibility_layer']) {
655-
$loader->load('legacy/doctrine_odm.xml');
656-
}
646+
$loader->load('legacy/doctrine_odm.xml');
657647
}
658648

659649
private function registerHttpCacheConfiguration(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
@@ -693,12 +683,6 @@ private function registerHttpCacheConfiguration(ContainerBuilder $container, arr
693683
$config['http_cache']['invalidation']['max_header_length'], ]);
694684
$container->setAlias('api_platform.http_cache.purger.xkey', 'api_platform.http_cache.purger.varnish.xkey');
695685
}
696-
697-
if ($config['metadata_backward_compatibility_layer']) {
698-
// $definition = $container->getDefinition('api_platform.http_cache.listener.response.add_tags');
699-
// $definition->setArgument(0, new Reference('api_platform.iri_converter.legacy'));
700-
// $definition->setArgument(1, null);
701-
}
702686
}
703687

704688
/**
@@ -760,6 +744,12 @@ private function registerDataCollectorConfiguration(ContainerBuilder $container,
760744

761745
if ($container->hasParameter('kernel.debug') && $container->getParameter('kernel.debug')) {
762746
$loader->load('debug.xml');
747+
748+
if ($config['metadata_backward_compatibility_layer']) {
749+
$loader->load('legacy/debug.xml');
750+
} else {
751+
$loader->load('v3/debug.xml');
752+
}
763753
}
764754
}
765755

@@ -797,7 +787,11 @@ private function registerMercureConfiguration(ContainerBuilder $container, array
797787
}
798788

799789
if ($this->isConfigEnabled($container, $config['graphql'])) {
800-
$loader->load('graphql_mercure.xml');
790+
if ($config['metadata_backward_compatibility_layer']) {
791+
$loader->load('legacy/graphql_mercure.xml');
792+
} else {
793+
$loader->load('v3/graphql_mercure.xml');
794+
}
801795
if (class_exists(HubRegistry::class)) {
802796
$container->getDefinition('api_platform.graphql.subscription.mercure_iri_generator')->addArgument(new Reference(HubRegistry::class));
803797
} else {
@@ -888,68 +882,21 @@ private function registerArgumentResolverConfiguration(ContainerBuilder $contain
888882
return;
889883
}
890884

891-
die('wtf');
892885
$loader->load('argument_resolver.xml');
893886
}
894887

895888
private function registerLegacyServices(ContainerBuilder $container, array $config, XmlFileLoader $loader): void
896889
{
897890
$container->setParameter('api_platform.metadata_backward_compatibility_layer', $config['metadata_backward_compatibility_layer']);
898891

892+
$loader->load('legacy/identifiers.xml');
893+
899894
if (!$config['metadata_backward_compatibility_layer']) {
900895
$loader->load('symfony.xml');
901896
return;
902897
}
903898

904-
$loader->load('legacy/identifiers.xml');
905899
$loader->load('legacy/api.xml');
906-
907-
// $container->removeDefinition('api_platform.iri_converter');
908-
// $container->setAlias('api_platform.iri_converter', 'api_platform.iri_converter.legacy');
909-
// $container->removeDefinition('api_platform.route_loader');
910-
// $container->setAlias('api_platform.route_loader', 'api_platform.route_loader.legacy');
911-
// $container->removeDefinition('api_platform.operation_path_resolver');
912-
//
913-
// $container->removeAlias('api_platform.identifiers_extractor');
914-
// $container->setAlias('api_platform.identifiers_extractor', 'api_platform.identifiers_extractor.legacy');
915-
//
916-
// $container->removeAlias('api_platform.iri_converter');
917-
// $container->setAlias('api_platform.iri_converter', 'api_platform.iri_converter.legacy');
918-
//
919-
// $container->removeAlias('api_platform.openapi.factory');
920-
// $container->setAlias('api_platform.openapi.factory', 'api_platform.openapi.factory.legacy');
921-
//
922-
// $container->removeAlias('api_platform.graphql.resolver.stage.read');
923-
// $container->setAlias('api_platform.graphql.resolver.stage.read', 'api_platform.graphql.resolver.stage.read.legacy');
924-
//
925-
// $container->removeAlias('api_platform.graphql.resolver.stage.write');
926-
// $container->setAlias('api_platform.graphql.resolver.stage.write', 'api_platform.graphql.resolver.stage.write.legacy');
927-
//
928-
// $container->removeAlias('api_platform.graphql.type_converter');
929-
// $container->setAlias('api_platform.graphql.type_converter', 'api_platform.graphql.type_converter.legacy');
930-
//
931-
// $container->removeAlias('api_platform.graphql.type_builder');
932-
// $container->setAlias('api_platform.graphql.type_builder', 'api_platform.graphql.type_builder.legacy');
933-
//
934-
// $container->removeAlias('api_platform.graphql.fields_builder');
935-
// $container->setAlias('api_platform.graphql.fields_builder', 'api_platform.graphql.fields_builder.legacy');
936-
//
937-
// $container->removeAlias('api_platform.graphql.schema_builder');
938-
// $container->setAlias('api_platform.graphql.schema_builder', 'api_platform.graphql.schema_builder.legacy');
939-
//
940-
// $container->removeAlias('api_platform.pagination');
941-
// $container->setAlias('api_platform.pagination', 'api_platform.pagination.legacy');
942-
//
943-
// $container->removeDefinition('api_platform.metadata.resource.name_collection_factory.attributes');
944-
// $container->removeDefinition('api_platform.metadata.resource.name_collection_factory.xml');
945-
// $container->setAlias('api_platform.metadata.resource.name_collection_factory.xml', 'api_platform.metadata.resource.name_collection_factory.xml.legacy');
946-
//
947-
// $container->removeDefinition('api_platform.metadata.resource.name_collection_factory.yaml');
948-
// $container->setAlias('api_platform.metadata.resource.name_collection_factory.yaml', 'api_platform.metadata.resource.name_collection_factory.yaml.legacy');
949-
//
950-
// $container->getDefinition('api_platform.hal.normalizer.item')->setArgument(11, null);
951-
// $container->getDefinition('api_platform.graphql.normalizer.item')->setArgument(12, null);
952-
// $container->getDefinition('api_platform.http_cache.listener.response.add_tags')->setArgument(1, null);
953900
}
954901

955902
private function registerRectorConfiguration(ContainerBuilder $container, XmlFileLoader $loader, array $config): void

src/Symfony/Bundle/Resources/config/debug.xml

-27
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,8 @@
55
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
66

77
<services>
8-
<service id="debug.api_platform.collection_data_provider" class="ApiPlatform\Core\Bridge\Symfony\Bundle\DataProvider\TraceableChainCollectionDataProvider" decorates="api_platform.collection_data_provider">
9-
<argument type="service" id="debug.api_platform.collection_data_provider.inner" />
10-
</service>
11-
12-
<service id="debug.api_platform.item_data_provider" class="ApiPlatform\Core\Bridge\Symfony\Bundle\DataProvider\TraceableChainItemDataProvider" decorates="api_platform.item_data_provider">
13-
<argument type="service" id="debug.api_platform.item_data_provider.inner" />
14-
</service>
15-
16-
<service id="debug.api_platform.subresource_data_provider" class="ApiPlatform\Core\Bridge\Symfony\Bundle\DataProvider\TraceableChainSubresourceDataProvider" decorates="api_platform.subresource_data_provider">
17-
<argument type="service" id="debug.api_platform.subresource_data_provider.inner" />
18-
</service>
19-
20-
<service id="debug.api_platform.data_persister" class="ApiPlatform\Core\Bridge\Symfony\Bundle\DataPersister\TraceableChainDataPersister" decorates="api_platform.data_persister">
21-
<argument type="service" id="debug.api_platform.data_persister.inner" />
22-
</service>
23-
248
<service id="debug.var_dumper.cloner" class="Symfony\Component\VarDumper\Cloner\VarCloner" />
259

2610
<service id="debug.var_dumper.cli_dumper" class="Symfony\Component\VarDumper\Dumper\CliDumper" />
27-
28-
<service id="debug.api_platform.debug_resource.command" class="ApiPlatform\Symfony\Bundle\Command\DebugResourceCommand">
29-
<tag name="console.command" />
30-
<argument type="service" id="api_platform.metadata.resource.metadata_collection_factory" />
31-
<argument type="service" id="debug.var_dumper.cloner" />
32-
<argument type="service" id="debug.var_dumper.cli_dumper" />
33-
</service>
34-
35-
<service id="debug.api_platform.processor" class="ApiPlatform\Symfony\Bundle\Processor\TraceableChainProcessor" decorates="api_platform.state_processor">
36-
<argument type="service" id="debug.api_platform.processor.inner" />
37-
</service>
3811
</services>
3912
</container>

src/Symfony/Bundle/Resources/config/legacy/api.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989

9090
<service id="api_platform.listener.view.respond" class="ApiPlatform\Symfony\EventListener\RespondListener">
9191
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
92-
<argument type="service" id="api_platform.iri_converter" />
92+
<argument>null</argument>
9393
<tag name="kernel.event_listener" event="kernel.view" method="onKernelView" priority="8" />
9494
</service>
9595

0 commit comments

Comments
 (0)