Skip to content

Commit

Permalink
fix(metadata): keep configured uri variables (#5217)
Browse files Browse the repository at this point in the history
fixes #5184
  • Loading branch information
soyuka authored Nov 24, 2022
1 parent e9c7e4a commit 096ac11
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 26 deletions.
31 changes: 13 additions & 18 deletions features/main/attribute_resource.feature
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
@php8
@v3
@!mysql
@!mongodb
Feature: Resource attributes
In order to use the Resource attribute
As a developer
I should be able to fetch data from a state provider

@php8
@v3
@!mysql
@!mongodb

Scenario: Retrieve a Resource collection
When I add "Content-Type" header equal to "application/ld+json"
And I send a "GET" request to "/attribute_resources"
Expand Down Expand Up @@ -36,11 +36,7 @@ Feature: Resource attributes
}
"""

@php8
@v3
@!mysql
@!mongodb
Scenario: Retrieve the first resource
Scenario: Retrieve the first resource
When I add "Content-Type" header equal to "application/ld+json"
And I send a "GET" request to "/attribute_resources/1"
Then the response status code should be 200
Expand All @@ -57,10 +53,6 @@ Feature: Resource attributes
}
"""

@php8
@v3
@!mysql
@!mongodb
Scenario: Retrieve the aliased resource
When I add "Content-Type" header equal to "application/ld+json"
And I send a "GET" request to "/dummy/1/attribute_resources/2"
Expand All @@ -80,10 +72,6 @@ Feature: Resource attributes
}
"""

@php8
@v3
@!mysql
@!mongodb
Scenario: Patch the aliased resource
When I add "Content-Type" header equal to "application/merge-patch+json"
And I send a "PATCH" request to "/dummy/1/attribute_resources/2" with body:
Expand All @@ -105,3 +93,10 @@ Feature: Resource attributes
"name": "Patched"
}
"""

Scenario: Uri variables should be configured properly
When I send a "GET" request to "/photos/1/resize/300/100"
Then the response status code should be 400
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 "hydra:description" should be equal to 'Unable to generate an IRI for the item of type "ApiPlatform\Tests\Fixtures\TestBundle\Entity\IncompleteUriVariableConfigured"'
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ private function transformUriVariablesToIdentifiers(array $arrayOperation): arra

$arrayOperation['identifiers'] = [];
foreach ($arrayOperation['uri_variables'] as $parameterName => $identifiedBy) {
if ($identifiedBy->getExpandedValue() ?? false) {
continue;
}

if (1 === \count($identifiedBy->getIdentifiers() ?? ['id'])) {
$arrayOperation['identifiers'][$parameterName] = [$identifiedBy->getFromClass(), $identifiedBy->getIdentifiers()[0] ?? ['id']];
continue;
Expand Down
4 changes: 4 additions & 0 deletions src/Core/Swagger/Serializer/DocumentationNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,10 @@ private function addPaths(bool $v3, \ArrayObject $paths, \ArrayObject $definitio
}

foreach ($operations as $operationName => $operation) {
if (false === ($operation['openapi'] ?? null)) {
continue;
}

// Skolem IRI
if ('api_genid' === ($operation['route_name'] ?? null)) {
continue;
Expand Down
6 changes: 6 additions & 0 deletions src/Doctrine/Odm/State/LinksHandlerTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ private function handleLinks(Builder $aggregationBuilder, array $identifiers, ar
return;
}

foreach ($links as $i => $link) {
if (null !== $link->getExpandedValue()) {
unset($links[$i]);
}
}

$executeOptions = $operation->getExtraProperties()['doctrine_mongodb']['execute_options'] ?? [];

$this->buildAggregation($resourceClass, array_reverse($links), array_reverse($identifiers), $context, $executeOptions, $resourceClass, $aggregationBuilder);
Expand Down
2 changes: 1 addition & 1 deletion src/Doctrine/Orm/State/LinksHandlerTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private function handleLinks(QueryBuilder $queryBuilder, array $identifiers, Que
$identifiers = array_reverse($identifiers);

foreach (array_reverse($links) as $link) {
if ($link->getExpandedValue() || !$link->getFromClass()) {
if (null !== $link->getExpandedValue() || !$link->getFromClass()) {
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,9 @@ private function configureUriVariables($operation)
return $this->normalizeUriVariables($operation);
}

$hasUserConfiguredUriVariables = !($operation->getExtraProperties['is_legacy_resource_metadata'] ?? false);
if (!$operation->getUriVariables()) {
$hasUserConfiguredUriVariables = false;
$operation = $operation->withUriVariables($this->transformLinksToUriVariables($this->linkFactory->createLinksFromIdentifiers($operation)));
}

Expand All @@ -157,6 +159,10 @@ private function configureUriVariables($operation)
});

if (\count($variables) !== \count($uriVariables)) {
if ($hasUserConfiguredUriVariables) {
return $operation;
}

$newUriVariables = [];
foreach ($variables as $variable) {
if (isset($uriVariables[$variable])) {
Expand Down
4 changes: 4 additions & 0 deletions src/OpenApi/Factory/OpenApiFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ private function collectPaths(ApiResource $resource, ResourceMetadataCollection

// Set up parameters
foreach ($uriVariables ?? [] as $parameterName => $uriVariable) {
if ($uriVariable->getExpandedValue() ?? false) {
continue;
}

$parameter = new Model\Parameter($parameterName, 'path', (new \ReflectionClass($uriVariable->getFromClass()))->getShortName().' identifier', true, false, false, ['type' => 'string']);
if ($this->hasParameter($parameter, $parameters)) {
continue;
Expand Down
7 changes: 0 additions & 7 deletions tests/Fixtures/TestBundle/Entity/Company.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,6 @@
#[GetCollection]
#[Get]
#[Post]
#[ApiResource(
uriTemplate: '/employees/{employeeId}/rooms/{roomId}/company/{companyId}',
uriVariables: [
'employeeId' => ['from_class' => Employee::class, 'from_property' => 'company'],
],
)]
#[Get]
#[ApiResource(
uriTemplate: '/employees/{employeeId}/company',
uriVariables: [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?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\Entity;

use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\Operation;

#[Get(uriTemplate: '/photos/{id}/resize/{width}/{height}', uriVariables: ['id'], provider: [IncompleteUriVariableConfigured::class, 'provide'], openapi: false)]
final class IncompleteUriVariableConfigured
{
public function __construct(public string $id)
{
}

public static function provide(Operation $operation, array $uriVariables = [], array $context = []): self
{
if (isset($uriVariables['width'])) {
throw new \LogicException('URI variable "width" should not exist');
}

return new self($uriVariables['id']);
}
}

0 comments on commit 096ac11

Please sign in to comment.