From b628e4fe6b35ff5ff2eb3704c9b152aa944420ee Mon Sep 17 00:00:00 2001 From: Vincent Chalamon <407859+vincentchalamon@users.noreply.github.com> Date: Fri, 1 Dec 2023 13:10:48 +0100 Subject: [PATCH 1/2] fix: item_uri_template conflict with context on relation --- src/Serializer/AbstractItemNormalizer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Serializer/AbstractItemNormalizer.php b/src/Serializer/AbstractItemNormalizer.php index d0ab05c528c..af563b7e082 100644 --- a/src/Serializer/AbstractItemNormalizer.php +++ b/src/Serializer/AbstractItemNormalizer.php @@ -678,7 +678,7 @@ protected function getAttributeValue(object $object, string $attribute, string $ && $this->resourceClassResolver->isResourceClass($className) ) { $childContext = $this->createChildContext($this->createOperationContext($context, $className), $attribute, $format); - unset($childContext['iri'], $childContext['uri_variables']); + unset($childContext['iri'], $childContext['uri_variables'], $childContext['item_uri_template']); if ('jsonld' === $format && $uriTemplate = $propertyMetadata->getUriTemplate()) { $operation = $this->resourceMetadataCollectionFactory->create($className)->getOperation( From 7d56fcd9f6207e27126c4ebf49ca6ee706fe9dd5 Mon Sep 17 00:00:00 2001 From: soyuka Date: Tue, 19 Dec 2023 10:00:28 +0100 Subject: [PATCH 2/2] test --- features/hydra/item_uri_template.feature | 13 ++++++++++++ .../TestBundle/Entity/Issue5662/Review.php | 20 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/features/hydra/item_uri_template.feature b/features/hydra/item_uri_template.feature index 2cb5a57443b..c32da0283ae 100644 --- a/features/hydra/item_uri_template.feature +++ b/features/hydra/item_uri_template.feature @@ -220,3 +220,16 @@ Feature: Exposing a collection of objects should use the specified operation to ] } """ + + Scenario: Create an object with an itemUriTemplate should generate the IRI according to the specified itemUriTemplate + When I add "Content-Type" header equal to "application/ld+json" + And I send a "POST" request to "/issue5662/books/a/reviews" with body: + """ + { + "body": "Good book" + } + """ + Then the response status code should be 201 + And the response should be in JSON + And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8" + And the JSON node "@id" should be equal to "/issue5662/books/a/reviews/0" diff --git a/tests/Fixtures/TestBundle/Entity/Issue5662/Review.php b/tests/Fixtures/TestBundle/Entity/Issue5662/Review.php index 6d37f2bad6a..ff29d33eae0 100644 --- a/tests/Fixtures/TestBundle/Entity/Issue5662/Review.php +++ b/tests/Fixtures/TestBundle/Entity/Issue5662/Review.php @@ -17,6 +17,8 @@ use ApiPlatform\Metadata\GetCollection; use ApiPlatform\Metadata\Link; use ApiPlatform\Metadata\Operation; +use ApiPlatform\Metadata\Post; +use ApiPlatform\State\CreateProvider; #[GetCollection( uriTemplate: '/issue5662/admin/reviews{._format}', @@ -43,12 +45,28 @@ 'id' => new Link(fromClass: Review::class), ] )] +#[Post( + itemUriTemplate: '/issue5662/books/{bookId}/reviews/{id}{._format}', + uriTemplate: '/issue5662/books/{id}/reviews{._format}', + uriVariables: [ + 'id' => new Link(toProperty: 'book', fromClass: Book::class), + ], + provider: CreateProvider::class, + processor: [Review::class, 'process'] +)] class Review { - public function __construct(public Book $book, public int $id, public string $body) + public function __construct(public ?Book $book = null, public ?int $id = null, public ?string $body = null) { } + public static function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []) + { + $data->id = 0; + + return $data; + } + public static function getData(Operation $operation, array $uriVariables = [], array $context = []): object|array|null { return [