Skip to content

Commit

Permalink
fix(jsonschema): restore type factory usage (#5897)
Browse files Browse the repository at this point in the history
fixes #5896
  • Loading branch information
soyuka authored Oct 23, 2023
1 parent 3d0dfc1 commit c2824c1
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 5 deletions.
2 changes: 1 addition & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ parameters:
- src/Symfony/Bundle/DependencyInjection/Configuration.php
# Templates for Maker
- src/Symfony/Maker/Resources/skeleton
- src/*/vendor
- **vendor**
earlyTerminatingMethodCalls:
PHPUnit\Framework\Constraint\Constraint:
- fail
Expand Down
10 changes: 8 additions & 2 deletions src/JsonSchema/SchemaFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ final class SchemaFactory implements SchemaFactoryInterface
{
use ResourceClassInfoTrait;
private array $distinctFormats = [];

private ?TypeFactoryInterface $typeFactory = null;
// Edge case where the related resource is not readable (for example: NotExposed) but we have groups to read the whole related object
public const FORCE_SUBSCHEMA = '_api_subschema_force_readable_link';
public const OPENAPI_DEFINITION_NAME = 'openapi_definition_name';

public function __construct(?TypeFactoryInterface $typeFactory, ResourceMetadataCollectionFactoryInterface $resourceMetadataFactory, private readonly PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, private readonly PropertyMetadataFactoryInterface $propertyMetadataFactory, private readonly ?NameConverterInterface $nameConverter = null, ResourceClassResolverInterface $resourceClassResolver = null)
{
if ($typeFactory) {
trigger_deprecation('api-platform/core', '3.2', sprintf('The "%s" is not needed anymore and will not be used anymore.', TypeFactoryInterface::class));
$this->typeFactory = $typeFactory;
}

$this->resourceMetadataFactory = $resourceMetadataFactory;
Expand Down Expand Up @@ -198,6 +198,12 @@ private function buildPropertySchema(Schema $schema, string $definitionName, str
$subSchema->setDefinitions($schema->getDefinitions()); // Populate definitions of the main schema

foreach ($types as $type) {
// TODO: in 3.3 add trigger_deprecation() as type factories are not used anymore, we moved this logic to SchemaPropertyMetadataFactory so that it gets cached
if ($typeFromFactory = $this->typeFactory?->getType($type, 'jsonschema', $propertyMetadata->isReadableLink(), $serializerContext)) {
$propertySchema = $typeFromFactory;
break;
}

$isCollection = $type->isCollection();
if ($isCollection) {
$valueType = $type->getCollectionValueTypes()[0] ?? null;
Expand Down
7 changes: 7 additions & 0 deletions src/JsonSchema/TypeFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
/**
* {@inheritdoc}
*
* @deprecated since 3.3 https://github.com/api-platform/core/pull/5470
*
* @author Kévin Dunglas <[email protected]>
*/
final class TypeFactory implements TypeFactoryInterface
Expand All @@ -46,6 +48,11 @@ public function setSchemaFactory(SchemaFactoryInterface $schemaFactory): void
*/
public function getType(Type $type, string $format = 'json', bool $readableLink = null, array $serializerContext = null, Schema $schema = null): array
{
if ('jsonschema' === $format) {
return [];
}

// TODO: OpenApiFactory uses this to compute filter types
if ($type->isCollection()) {
$keyType = $type->getCollectionKeyTypes()[0] ?? null;
$subType = ($type->getCollectionValueTypes()[0] ?? null) ?? new Type($type->getBuiltinType(), false, $type->getClassName(), false);
Expand Down
2 changes: 1 addition & 1 deletion src/OpenApi/Factory/OpenApiFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ private function getFiltersParameters(CollectionOperationInterface|HttpOperation
}

foreach ($filter->getDescription($entityClass) as $name => $data) {
$schema = $data['schema'] ?? (\in_array($data['type'], Type::$builtinTypes, true) ? $this->jsonSchemaTypeFactory->getType(new Type($data['type'], false, null, $data['is_collection'] ?? false)) : ['type' => 'string']);
$schema = $data['schema'] ?? (\in_array($data['type'], Type::$builtinTypes, true) ? $this->jsonSchemaTypeFactory->getType(new Type($data['type'], false, null, $data['is_collection'] ?? false), 'openapi') : ['type' => 'string']);

$parameters[] = new Parameter(
$name,
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Bundle/Resources/config/json_schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<service id="ApiPlatform\JsonSchema\TypeFactoryInterface" alias="api_platform.json_schema.type_factory" />

<service id="api_platform.json_schema.schema_factory" class="ApiPlatform\JsonSchema\SchemaFactory">
<argument>null</argument>
<argument type="service" id="api_platform.json_schema.type_factory" on-invalid="ignore"></argument>
<argument type="service" id="api_platform.metadata.resource.metadata_collection_factory" />
<argument type="service" id="api_platform.metadata.property.name_collection_factory" />
<argument type="service" id="api_platform.metadata.property.metadata_factory" />
Expand Down
25 changes: 25 additions & 0 deletions tests/Fixtures/TestBundle/ApiResource/Issue5896/Foo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue5896;

use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\Get;

#[Get]
class Foo
{
#[ApiProperty(readable: false, writable: false, identifier: true)]
public ?int $id = null;
public ?LocalDate $expiration;
}
18 changes: 18 additions & 0 deletions tests/Fixtures/TestBundle/ApiResource/Issue5896/LocalDate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue5896;

class LocalDate
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue5896;

use ApiPlatform\JsonSchema\Schema;
use ApiPlatform\JsonSchema\TypeFactoryInterface;
use Symfony\Component\PropertyInfo\Type;

class TypeFactoryDecorator implements TypeFactoryInterface
{
public function __construct(
private readonly TypeFactoryInterface $decorated,
) {
}

public function getType(Type $type, string $format = 'json', bool $readableLink = null, array $serializerContext = null, Schema $schema = null): array
{
if (is_a($type->getClassName(), LocalDate::class, true)) {
return [
'type' => 'string',
'format' => 'date',
];
}

return $this->decorated->getType($type, $format, $readableLink, $serializerContext, $schema);
}
}
5 changes: 5 additions & 0 deletions tests/Fixtures/app/config/config_common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -457,3 +457,8 @@ services:
ApiPlatform\Tests\Fixtures\TestBundle\State\ODMLinkHandledDummyLinksHandler:
tags:
- {name: 'api_platform.doctrine.odm.links_handler'}

ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue5896\TypeFactoryDecorator:
decorates: 'api_platform.json_schema.type_factory'
arguments:
$decorated: '@.inner'
14 changes: 14 additions & 0 deletions tests/JsonSchema/Command/JsonSchemaGenerateCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,18 @@ public function testArraySchemaWithReference(): void
'$ref' => '#/definitions/TestEntity.jsonld-write',
]);
}

/**
* TODO: add deprecation (TypeFactory will be deprecated in api platform 3.3).
*
* @group legacy
*/
public function testArraySchemaWithTypeFactory(): void
{
$this->tester->run(['command' => 'api:json-schema:generate', 'resource' => 'ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue5896\Foo', '--type' => 'output']);
$result = $this->tester->getDisplay();
$json = json_decode($result, associative: true);

$this->assertEquals($json['definitions']['Foo.jsonld']['properties']['expiration'], ['type' => 'string', 'format' => 'date']);
}
}

0 comments on commit c2824c1

Please sign in to comment.