Skip to content

Commit

Permalink
Merge pull request #5228 from soyuka/merge-2.7
Browse files Browse the repository at this point in the history
Merge 2.7
  • Loading branch information
soyuka authored Nov 25, 2022
2 parents 84a7e56 + fa2cf88 commit 7861f97
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 20 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ Breaking changes:
* Serializer: `skip_null_values` now defaults to `true`
* Metadata: `Patch` is added to the automatic CRUD

## v2.7.5

### Bug fixes

* [096ac119a](https://github.com/api-platform/core/commit/096ac119a5126bdc5e7877172a033d7cdaa28983) fix(metadata): keep configured uri variables (#5217)
* [2b2d468f0](https://github.com/api-platform/core/commit/2b2d468f06a63ecfa4928d5d631953acb624c181) fix(metadata): operations must inherit from resource and defaults
* [2cb3b4272](https://github.com/api-platform/core/commit/2cb3b42725105aaf34dc9d71d2c03e156acd5833) fix(serializer): use iri from $context if defined (#5201)
* [39398579e](https://github.com/api-platform/core/commit/39398579e32976b5b4b0219da98fdb35629a35ad) fix(symfony): definition when mercure is not installed (#5206)
* [e9c7e4abb](https://github.com/api-platform/core/commit/e9c7e4abb683bb830a61712a8b63b8063e015b13) fix(serializer): avoid call to legacy iri converter with non-resource class (#5219)
* [ebaad51b2](https://github.com/api-platform/core/commit/ebaad51b2ce173b6c59582dcc6fb311f1f4b7fa9) fix(serializer): read groups off the root operation (#5196)

## v2.7.4

### Bug fixes
Expand Down
23 changes: 11 additions & 12 deletions features/main/attribute_resource.feature
Original file line number Diff line number Diff line change
@@ -1,11 +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
@!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 @@ -35,9 +36,6 @@ Feature: Resource attributes
}
"""

@php8
@!mysql
@!mongodb
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"
Expand All @@ -55,9 +53,6 @@ Feature: Resource attributes
}
"""

@php8
@!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 @@ -77,9 +72,6 @@ Feature: Resource attributes
}
"""

@php8
@!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 @@ -101,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"'
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 @@ -137,7 +137,9 @@ private function configureUriVariables(ApiResource|HttpOperation $operation): Ap
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 @@ -164,6 +166,10 @@ private function configureUriVariables(ApiResource|HttpOperation $operation): Ap
$variables = $route->getPathVariables();

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 @@ -189,6 +189,10 @@ private function collectPaths(ApiResource $resource, ResourceMetadataCollection

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

$parameter = new Parameter($parameterName, 'path', (new \ReflectionClass($uriVariable->getFromClass()))->getShortName().' identifier', true, false, false, ['type' => 'string']);
if ($this->hasParameter($parameter, $parameters)) {
continue;
Expand Down
8 changes: 1 addition & 7 deletions tests/Fixtures/TestBundle/Entity/Company.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,7 @@
#[GetCollection]
#[Get]
#[Post]
#[Get(
uriTemplate: '/employees/{employeeId}/rooms/{roomId}/company/{companyId}',
uriVariables: [
'employeeId' => ['from_class' => Employee::class, 'from_property' => 'company'],
],
)]
#[Get(
#[ApiResource(
uriTemplate: '/employees/{employeeId}/company',
uriVariables: [
'employeeId' => ['from_class' => Employee::class, 'from_property' => 'company'],
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']);
}
}
39 changes: 39 additions & 0 deletions tests/Serializer/ItemNormalizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,45 @@ public function testDenormalizeWithIdAndUpdateNotAllowed(): void
$normalizer->denormalize(['id' => '12', 'name' => 'hello'], Dummy::class, null, $context);
}

public function testDenormalizeWithDefinedIri(): void
{
$dummy = new Dummy();
$dummy->setName('hello');

$propertyNameCollection = new PropertyNameCollection(['name']);
$propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
$propertyNameCollectionFactoryProphecy->create(Dummy::class, [])->willReturn($propertyNameCollection);

$resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
$resourceClassResolverProphecy->isResourceClass(Dummy::class)->willReturn(true);

$propertyMetadata = (new ApiProperty())->withReadable(true);
$propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
$propertyMetadataFactoryProphecy->create(Dummy::class, 'name', [])->willReturn($propertyMetadata);

$iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
$iriConverterProphecy->getIriFromResource($dummy)->shouldNotBeCalled();

$resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
$resourceClassResolverProphecy->getResourceClass($dummy, null)->willReturn(Dummy::class);
$resourceClassResolverProphecy->getResourceClass(null, Dummy::class)->willReturn(Dummy::class);
$resourceClassResolverProphecy->isResourceClass(Dummy::class)->willReturn(true);

$serializerProphecy = $this->prophesize(SerializerInterface::class);
$serializerProphecy->willImplement(NormalizerInterface::class);
$serializerProphecy->normalize('hello', null, Argument::type('array'))->willReturn('hello');

$normalizer = new ItemNormalizer(
$propertyNameCollectionFactoryProphecy->reveal(),
$propertyMetadataFactoryProphecy->reveal(),
$iriConverterProphecy->reveal(),
$resourceClassResolverProphecy->reveal()
);
$normalizer->setSerializer($serializerProphecy->reveal());

$this->assertEquals(['name' => 'hello'], $normalizer->normalize($dummy, null, ['resources' => [], 'iri' => '/custom']));
}

public function testDenormalizeWithIdAndNoResourceClass(): void
{
$context = [];
Expand Down

0 comments on commit 7861f97

Please sign in to comment.