Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
71918e4
fix(jsonschema): respect readableLink for resource-typed properties o…
wuchen90 Jun 29, 2026
6682985
fix(doctrine): support filtering scalar enum columns by IRI (#8358)
soyuka Jun 29, 2026
f1f33ca
fix(ci): link monorepo root in laravel e2e so siblings resolve from w…
soyuka Jun 29, 2026
43e3b4c
fix(openapi): don't apply the global name converter to the generated …
soyuka Jun 30, 2026
fe84af2
fix(symfony): allow null $data in PlaceholderAction (#8359)
soyuka Jun 30, 2026
a9c1b53
fix: clone Parameters before mutation in security and validator provi…
ostrolucky Jul 2, 2026
f9d3706
fix(mcp): make tools/list resilient to an empty registry (#8371)
soyuka Jul 3, 2026
48e8f97
fix(doctrine): use PHP property name in DQL for modern filters with n…
soyuka Jul 3, 2026
798b4cc
fix(serializer): denormalize nullable collections of enums/objects (#…
soyuka Jul 3, 2026
340e982
fix(test): remove stale phpstan ignores in CollectionNormalizerTest (…
soyuka Jul 3, 2026
328cb67
fix(symfony): don't expose entrypoint in openapi format (#8383)
soyuka Jul 3, 2026
95dd023
doc: changelog 4.3.16
soyuka Jul 3, 2026
56de597
fix(doctrine): fetch_data=false reference for stateOptions resources …
bendavies Jul 8, 2026
079c746
fix(openapi): don't inherit name converter from a possibly-missing Sy…
soyuka Jul 8, 2026
b396ff9
fix(serializer): report enum backing type in denormalization violatio…
soyuka Jul 11, 2026
3d48a4a
fix(serializer): preserve denormalization errors for nullable object …
bendavies Jul 11, 2026
815f7f4
doc: changelog 4.3.17
soyuka Jul 12, 2026
400463f
chore(graphql): remove stray committed foo.diff patch file (#8395)
soyuka Jul 12, 2026
083dabe
Merge 4.3 into 4.4
soyuka Jul 12, 2026
722ed09
fix(validator): forward-port enum backing type into DenormalizationVi…
soyuka Jul 12, 2026
1cacc0b
fix(test): drop stale serializer 8.1 deprecation guard on ported enum…
soyuka Jul 12, 2026
af4e04b
Merge pull request #8396 from soyuka/mergeup-4.4-into
soyuka Jul 12, 2026
db5c7d8
chore: remove @experimental from stabilized APIs (#8398)
soyuka Jul 12, 2026
2d104d0
chore: require Symfony ^7.4 across all components (#8397)
soyuka Jul 12, 2026
432992e
Merge 4.4 into main
soyuka Jul 12, 2026
88f458a
fix(jsonschema): drop removed getBuiltinTypes path in SchemaPropertyM…
soyuka Jul 12, 2026
8360186
fix(serializer): remove dead native-type guards in AbstractItemNormal…
soyuka Jul 12, 2026
bc387cd
style: cs-fixer
soyuka Jul 12, 2026
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 .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1193,7 +1193,7 @@ jobs:
- name: Install api-platform/laravel
run: |
composer require laravel/framework:"^13.0" --no-update
composer global link ../src/Laravel --permanent
composer global link ../ --working-directory=$(pwd) --permanent
composer config minimum-stability dev
composer config prefer-stable true
composer require api-platform/laravel:"@dev" -W
Expand Down
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,31 @@
* [c9e5071d9](https://github.com/api-platform/core/commit/c9e5071d973caedeb9b554f885dedbc89743b93d) feat(symfony): deprecate Symfony Security AccessDeniedException (#8318)
* [cc0ae1254](https://github.com/api-platform/core/commit/cc0ae1254acaf9742c7f899dd24a14d46c89ca6e) feat: support dynamic HTTP response status code via request attribute (#7904)

## v4.3.17

### Bug fixes

* [079c7461f](https://github.com/api-platform/core/commit/079c7461f947714f15bb29b41fb143ed4bb171ea) fix(openapi): don't inherit name converter from a possibly-missing Symfony parent (#8386)
* [3d48a4aa4](https://github.com/api-platform/core/commit/3d48a4aa4d87f1fa80fe19361393d645d0d013c2) fix(serializer): preserve denormalization errors for nullable object properties (#8393)
* [56de59737](https://github.com/api-platform/core/commit/56de59737c53e18120ed0b9b6c40633c109d58c2) fix(doctrine): fetch_data=false reference for stateOptions resources (#8387)
* [b396ff938](https://github.com/api-platform/core/commit/b396ff938272280a26d38d89011970dcee56d721) fix(serializer): report enum backing type in denormalization violations (#8389)

## v4.3.16

### Bug fixes

* [328cb67ce](https://github.com/api-platform/core/commit/328cb67ceda3d934d8985fb0f7e08542f59fb38d) fix(symfony): don't expose entrypoint in openapi format (#8383)
* [340e982c2](https://github.com/api-platform/core/commit/340e982c22ebc6c4cf45a6f481151f668722eaf9) fix(test): remove stale phpstan ignores in CollectionNormalizerTest (#8384)
* [43e3b4cf7](https://github.com/api-platform/core/commit/43e3b4cf716ed7b0d3962b5e022d065a2bb746c9) fix(openapi): don't apply the global name converter to the generated document (#8360)
* [48e8f9781](https://github.com/api-platform/core/commit/48e8f97816a945d205b0cfaf4c76cc532c143312) fix(doctrine): use PHP property name in DQL for modern filters with name converter (#8382)
* [66829859f](https://github.com/api-platform/core/commit/66829859fac0fe0363b8a91fd338d3ab71877774) fix(doctrine): support filtering scalar enum columns by IRI (#8358)
* [71918e464](https://github.com/api-platform/core/commit/71918e4644ed2f6ce1ff8514b9ee87a57f074285) fix(jsonschema): respect readableLink for resource-typed properties on non-resource parents (#8362)
* [798b4cc53](https://github.com/api-platform/core/commit/798b4cc53dee7ef1e8dd8042668bbf9f8086b746) fix(serializer): denormalize nullable collections of enums/objects (#8381)
* [a9c1b538c](https://github.com/api-platform/core/commit/a9c1b538cb48ee5e629ed3909ce56653970c8889) fix: clone Parameters before mutation in security and validator providers (#8378)
* [f1f33cac9](https://github.com/api-platform/core/commit/f1f33cac9a15331bc940654d37bf9fd9828d0c28) fix(ci): link monorepo root in laravel e2e so siblings resolve from working tree (#8363)
* [f9d3706bb](https://github.com/api-platform/core/commit/f9d3706bb583f3a7dd74be1cc94729e49cc0611c) fix(mcp): make tools/list resilient to an empty registry (#8371)
* [fe84af236](https://github.com/api-platform/core/commit/fe84af2365244055737df73f888f7aa3888f462e) fix(symfony): allow null $data in PlaceholderAction (#8359)

## v4.3.15

### Bug fixes
Expand Down
70 changes: 35 additions & 35 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"dev-main": "5.0.x-dev"
},
"symfony": {
"require": "^6.4 || ^7.1 || ^8.0"
"require": "^7.4 || ^8.0"
},
"pmu": {
"projects": [
Expand Down Expand Up @@ -113,15 +113,15 @@
"psr/cache": "^1.0 || ^2.0 || ^3.0",
"psr/container": "^1.0 || ^2.0",
"symfony/deprecation-contracts": "^3.1",
"symfony/http-foundation": "^6.4.14 || ^7.0 || ^8.0",
"symfony/http-kernel": "^6.4.13 || ^7.0 || ^8.0",
"symfony/property-access": "^6.4 || ^7.0 || ^8.0",
"symfony/property-info": "^7.1 || ^8.0",
"symfony/serializer": "^6.4.37 || ^7.4.9 || ^8.0.9",
"symfony/http-foundation": "^7.4 || ^8.0",
"symfony/http-kernel": "^7.4 || ^8.0",
"symfony/property-access": "^7.4 || ^8.0",
"symfony/property-info": "^7.4 || ^8.0",
"symfony/serializer": "^7.4.9 || ^8.0.9",
"symfony/translation-contracts": "^3.3",
"symfony/type-info": "^7.4 || ^8.0",
"symfony/validator": "^6.4.11 || ^7.1 || ^8.0",
"symfony/web-link": "^6.4 || ^7.1 || ^8.0",
"symfony/validator": "^7.4 || ^8.0",
"symfony/web-link": "^7.4 || ^8.0",
"willdurand/negotiation": "^3.1"
},
"require-dev": {
Expand Down Expand Up @@ -157,39 +157,39 @@
"ramsey/uuid-doctrine": "^2.0",
"soyuka/pmu": "^0.2.0",
"soyuka/stubs-mongodb": "^1.0",
"symfony/asset": "^6.4 || ^7.0 || ^8.0",
"symfony/browser-kit": "^6.4 || ^7.0 || ^8.0",
"symfony/cache": "^6.4 || ^7.0 || ^8.0",
"symfony/config": "^6.4 || ^7.0 || ^8.0",
"symfony/console": "^6.4 || ^7.0 || ^8.0",
"symfony/css-selector": "^6.4 || ^7.0 || ^8.0",
"symfony/dependency-injection": "^6.4 || ^7.0 || ^8.0",
"symfony/doctrine-bridge": "^6.4.2 || ^7.1 || ^8.0",
"symfony/dom-crawler": "^6.4 || ^7.0 || ^8.0",
"symfony/error-handler": "^6.4 || ^7.0 || ^8.0",
"symfony/event-dispatcher": "^6.4 || ^7.0 || ^8.0",
"symfony/expression-language": "^6.4 || ^7.0 || ^8.0",
"symfony/finder": "^6.4 || ^7.0 || ^8.0",
"symfony/form": "^6.4 || ^7.0 || ^8.0",
"symfony/framework-bundle": "^6.4 || ^7.0 || ^8.0",
"symfony/http-client": "^6.4 || ^7.0 || ^8.0",
"symfony/intl": "^6.4 || ^7.0 || ^8.0",
"symfony/asset": "^7.4 || ^8.0",
"symfony/browser-kit": "^7.4 || ^8.0",
"symfony/cache": "^7.4 || ^8.0",
"symfony/config": "^7.4 || ^8.0",
"symfony/console": "^7.4 || ^8.0",
"symfony/css-selector": "^7.4 || ^8.0",
"symfony/dependency-injection": "^7.4 || ^8.0",
"symfony/doctrine-bridge": "^7.4 || ^8.0",
"symfony/dom-crawler": "^7.4 || ^8.0",
"symfony/error-handler": "^7.4 || ^8.0",
"symfony/event-dispatcher": "^7.4 || ^8.0",
"symfony/expression-language": "^7.4 || ^8.0",
"symfony/finder": "^7.4 || ^8.0",
"symfony/form": "^7.4 || ^8.0",
"symfony/framework-bundle": "^7.4 || ^8.0",
"symfony/http-client": "^7.4 || ^8.0",
"symfony/intl": "^7.4 || ^8.0",
"symfony/json-streamer": "^7.4 || ^8.0",
"symfony/maker-bundle": "^1.24",
"symfony/mcp-bundle": "dev-main",
"symfony/mercure-bundle": "*",
"symfony/messenger": "^6.4 || ^7.0 || ^8.0",
"symfony/messenger": "^7.4 || ^8.0",
"symfony/object-mapper": "^7.4 || ^8.0",
"symfony/routing": "^6.4 || ^7.0 || ^8.0",
"symfony/security-bundle": "^6.4 || ^7.0 || ^8.0",
"symfony/security-core": "^6.4 || ^7.0 || ^8.0",
"symfony/stopwatch": "^6.4 || ^7.0 || ^8.0",
"symfony/string": "^6.4 || ^7.0 || ^8.0",
"symfony/twig-bundle": "^6.4 || ^7.0 || ^8.0",
"symfony/uid": "^6.4 || ^7.0 || ^8.0",
"symfony/routing": "^7.4 || ^8.0",
"symfony/security-bundle": "^7.4 || ^8.0",
"symfony/security-core": "^7.4 || ^8.0",
"symfony/stopwatch": "^7.4 || ^8.0",
"symfony/string": "^7.4 || ^8.0",
"symfony/twig-bundle": "^7.4 || ^8.0",
"symfony/uid": "^7.4 || ^8.0",
"symfony/var-exporter": "^7.4 || ^8.0",
"symfony/web-profiler-bundle": "^6.4 || ^7.0 || ^8.0",
"symfony/yaml": "^6.4 || ^7.0 || ^8.0",
"symfony/web-profiler-bundle": "^7.4 || ^8.0",
"symfony/yaml": "^7.4 || ^8.0",
"twig/twig": "^1.42.3 || ^2.12 || ^3.0",
"webonyx/graphql-php": "^15.0"
},
Expand Down
4 changes: 2 additions & 2 deletions src/Doctrine/Common/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"doctrine/orm": "^2.17 || ^3.0",
"phpspec/prophecy-phpunit": "^2.2",
"phpunit/phpunit": "^11.5 || ^12.2",
"symfony/type-info": "^7.3 || ^8.0"
"symfony/type-info": "^7.4 || ^8.0"
},
"conflict": {
"doctrine/persistence": "<1.3"
Expand Down Expand Up @@ -67,7 +67,7 @@
"dev-4.1": "4.1.x-dev"
},
"symfony": {
"require": "^6.4 || ^7.0 || ^8.0"
"require": "^7.4 || ^8.0"
},
"thanks": {
"name": "api-platform/api-platform",
Expand Down
22 changes: 22 additions & 0 deletions src/Doctrine/Odm/Filter/IriFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use ApiPlatform\State\ParameterProvider\IriConverterParameterProvider;
use Doctrine\ODM\MongoDB\Aggregation\Builder;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
use Doctrine\ODM\MongoDB\Mapping\MappingException;

/**
Expand Down Expand Up @@ -68,7 +69,23 @@ public function apply(Builder $aggregationBuilder, string $resourceClass, ?Opera
$leafProperty = $nestedInfo['leaf_property'] ?? $property;
$classMetadata = $documentManager->getClassMetadata($leafClass);

// Backed enum exposed as a resource: match the scalar field against the resolved enum.
if (!$classMetadata->hasReference($leafProperty)) {
if (!$this->isEnumField($classMetadata, $leafProperty)) {
return;
}

$normalize = static fn (mixed $v): mixed => $v instanceof \BackedEnum ? $v->value : $v;

if (is_iterable($value)) {
$values = \is_array($value) ? $value : iterator_to_array($value);
$match->{$operator}($aggregationBuilder->matchExpr()->field($matchField)->in(array_map($normalize, $values)));

return;
}

$match->{$operator}($aggregationBuilder->matchExpr()->field($matchField)->equals($normalize($value)));

return;
}

Expand Down Expand Up @@ -113,4 +130,9 @@ public static function getParameterProvider(): string
{
return IriConverterParameterProvider::class;
}

private function isEnumField(ClassMetadata $classMetadata, string $field): bool
{
return $classMetadata->hasField($field) && null !== ($classMetadata->getFieldMapping($field)['enumType'] ?? null);
}
}
2 changes: 1 addition & 1 deletion src/Doctrine/Odm/NestedPropertyHelperTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ protected function addNestedParameterLookups(string $property, Builder $aggregat
$nestedInfo = ($extraProperties['nested_properties_info'] ?? []) ? reset($extraProperties['nested_properties_info']) : null;

if (!$nestedInfo) {
return $property;
return $extraProperties['query_property'] ?? $property;
}

$odmSegments = $nestedInfo['odm_segments'] ?? [];
Expand Down
20 changes: 10 additions & 10 deletions src/Doctrine/Odm/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,21 @@
"api-platform/serializer": "^5.0@alpha",
"api-platform/state": "^5.0@alpha",
"doctrine/mongodb-odm": "^2.10",
"symfony/property-info": "^7.1 || ^8.0",
"symfony/type-info": "^7.3 || ^8.0"
"symfony/property-info": "^7.4 || ^8.0",
"symfony/type-info": "^7.4 || ^8.0"
},
"require-dev": {
"doctrine/doctrine-bundle": "^2.11 || ^3.1",
"doctrine/mongodb-odm-bundle": "^5.0",
"phpspec/prophecy-phpunit": "^2.2",
"phpunit/phpunit": "^11.5 || ^12.2",
"symfony/cache": "^6.4 || ^7.0 || ^8.0",
"symfony/framework-bundle": "^6.4 || ^7.0 || ^8.0",
"symfony/property-access": "^6.4 || ^7.0 || ^8.0",
"symfony/serializer": "^6.4 || ^7.0 || ^8.0",
"symfony/uid": "^6.4 || ^7.0 || ^8.0",
"symfony/validator": "^6.4.11 || ^7.0 || ^8.0",
"symfony/yaml": "^6.4 || ^7.0 || ^8.0"
"symfony/cache": "^7.4 || ^8.0",
"symfony/framework-bundle": "^7.4 || ^8.0",
"symfony/property-access": "^7.4 || ^8.0",
"symfony/serializer": "^7.4 || ^8.0",
"symfony/uid": "^7.4 || ^8.0",
"symfony/validator": "^7.4 || ^8.0",
"symfony/yaml": "^7.4 || ^8.0"
},
"autoload": {
"psr-4": {
Expand All @@ -68,7 +68,7 @@
"dev-4.1": "4.1.x-dev"
},
"symfony": {
"require": "^6.4 || ^7.0 || ^8.0"
"require": "^7.4 || ^8.0"
},
"thanks": {
"name": "api-platform/api-platform",
Expand Down
54 changes: 52 additions & 2 deletions src/Doctrine/Orm/Filter/IriFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
use ApiPlatform\Metadata\Operation;
use ApiPlatform\Metadata\ParameterProviderFilterInterface;
use ApiPlatform\State\ParameterProvider\IriConverterParameterProvider;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\FieldMapping;
use Doctrine\ORM\QueryBuilder;

/**
Expand Down Expand Up @@ -57,6 +59,13 @@ public function apply(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $q
$ormLeafMetadata = $this->resolveLeafMetadataAtRuntime($queryBuilder, $resourceClass, $parameter->getProperty(), $property);
}

// Backed enum exposed as a resource: compare the scalar column to the resolved enum.
if (null === $ormLeafMetadata) {
$this->applyEnumComparison($queryBuilder, $alias, $property, $parameterName, $value, $context);

return;
}

// Collection associations (OneToMany/ManyToMany) require a JOIN to compare individual elements.
if ($ormLeafMetadata['is_collection_valued']) {
$queryBuilder->join(\sprintf('%s.%s', $alias, $property), $parameterName);
Expand Down Expand Up @@ -102,6 +111,25 @@ public static function getParameterProvider(): string
return IriConverterParameterProvider::class;
}

private function applyEnumComparison(QueryBuilder $queryBuilder, string $alias, string $property, string $parameterName, mixed $value, array $context): void
{
$propertyExpr = \sprintf('%s.%s', $alias, $property);
$normalize = static fn (mixed $v): mixed => $v instanceof \BackedEnum ? $v->value : $v;

if (is_iterable($value)) {
$values = \is_array($value) ? $value : iterator_to_array($value);
$queryBuilder
->{$context['whereClause'] ?? 'andWhere'}(\sprintf('%s IN (:%s)', $propertyExpr, $parameterName))
->setParameter($parameterName, array_map($normalize, $values));

return;
}

$queryBuilder
->{$context['whereClause'] ?? 'andWhere'}(\sprintf('%s = :%s', $propertyExpr, $parameterName))
->setParameter($parameterName, $normalize($value));
}

/**
* @return array{is_collection_valued: bool, association_target_class: string, identifier_type: ?string}|null
*/
Expand All @@ -122,9 +150,12 @@ private function getOrmLeafMetadata(mixed $parameter): ?array
* Resolves leaf metadata at runtime by walking the association chain.
* Used as fallback when precomputed orm_leaf_metadata is not available.
*
* @return array{is_collection_valued: bool, association_target_class: string, identifier_type: ?string}
* Returns null when the leaf is a backed enum column so the caller compares it directly;
* a non-association, non-enum leaf is left to raise a mapping error.
*
* @return array{is_collection_valued: bool, association_target_class: string, identifier_type: ?string}|null
*/
private function resolveLeafMetadataAtRuntime(QueryBuilder $queryBuilder, string $resourceClass, string $originalProperty, string $leafProperty): array
private function resolveLeafMetadataAtRuntime(QueryBuilder $queryBuilder, string $resourceClass, string $originalProperty, string $leafProperty): ?array
{
$em = $queryBuilder->getEntityManager();
$metadata = $em->getClassMetadata($resourceClass);
Expand All @@ -135,6 +166,10 @@ private function resolveLeafMetadataAtRuntime(QueryBuilder $queryBuilder, string
$metadata = $em->getClassMetadata($associationMapping['targetEntity']);
}

if (!$metadata->hasAssociation($leafProperty) && $this->isEnumField($metadata, $leafProperty)) {
return null;
}

$isCollectionValued = $metadata->isCollectionValuedAssociation($leafProperty);
$associationMapping = $metadata->getAssociationMapping($leafProperty);
$targetClass = $associationMapping['targetEntity'];
Expand All @@ -152,4 +187,19 @@ private function resolveLeafMetadataAtRuntime(QueryBuilder $queryBuilder, string
'identifier_type' => $identifierType,
];
}

private function isEnumField(ClassMetadata $metadata, string $field): bool
{
if (!isset($metadata->fieldMappings[$field])) {
return false;
}

$fieldMapping = $metadata->fieldMappings[$field];
// Doctrine ORM 2.x returns an array and Doctrine ORM 3.x returns a FieldMapping object.
if ($fieldMapping instanceof FieldMapping) {
$fieldMapping = (array) $fieldMapping;
}

return null !== ($fieldMapping['enumType'] ?? null);
}
}
2 changes: 1 addition & 1 deletion src/Doctrine/Orm/NestedPropertyHelperTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ protected function addNestedParameterJoins(
$nestedInfo = ($extraProperties['nested_properties_info'] ?? []) ? reset($extraProperties['nested_properties_info']) : null;

if (!$nestedInfo) {
return [$alias, $property];
return [$alias, $extraProperties['query_property'] ?? $property];
}

$relationClasses = $nestedInfo['relation_classes'] ?? [];
Expand Down
6 changes: 4 additions & 2 deletions src/Doctrine/Orm/State/ItemProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,10 @@ private function getReferenceIdentifiers(EntityManagerInterface $manager, string

$identifiers = [];
foreach ($this->getLinks($entityClass, $operation, $context) as $parameterName => $link) {
// Mirrors LinksHandlerTrait: the identifier-self link has no relation property and points to the entity itself.
if ($entityClass !== $link->getFromClass() || $link->getFromProperty() || $link->getToProperty()) {
// Mirrors LinksHandlerTrait: the identifier-self link has no relation property and points to the resource itself.
// Links are expressed in resource terms, so the identifier-self link's fromClass is the resource class
// ($operation->getClass()), which differs from $entityClass for a DTO/stateOptions resource.
if ($operation->getClass() !== $link->getFromClass() || $link->getFromProperty() || $link->getToProperty()) {
continue;
}

Expand Down
31 changes: 31 additions & 0 deletions src/Doctrine/Orm/Tests/Fixtures/Model/EmployeeApi.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?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\Doctrine\Orm\Tests\Fixtures\Model;

use ApiPlatform\Doctrine\Orm\State\Options;
use ApiPlatform\Doctrine\Orm\Tests\Fixtures\Entity\Employee;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;

/**
* DTO resource backed by the {@see Employee} entity through stateOptions: the resource
* class differs from the Doctrine entity class, which is what exercises the
* fetch_data=false getReference() fast-path for DTO/stateOptions resources.
*/
#[ApiResource(stateOptions: new Options(entityClass: Employee::class))]
#[Get]
class EmployeeApi
{
public ?int $id = null;
}
Loading
Loading