Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 <dunglas@gmail.com>
*/
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 <dunglas@gmail.com>
*
* 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 <dunglas@gmail.com>
*
* 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 <dunglas@gmail.com>
*
* 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']);
}
}