Skip to content

Commit

Permalink
fix(serializer): json non-resource intermitent class (api-platform#5937)
Browse files Browse the repository at this point in the history
  • Loading branch information
soyuka authored Oct 30, 2023
1 parent 0f01521 commit 495f75f
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 4 deletions.
12 changes: 12 additions & 0 deletions features/issues/5926.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Feature: Issue 5926
In order to reproduce the issue at https://github.com/api-platform/core/issues/5926
As a client software developer
I need to be able to use every operation on a resource with non-resources embed objects

@!mongodb
Scenario: Create and retrieve a WriteResource
When I add "Accept" header equal to "application/json"
And I send a "GET" request to "/test_issue5926s/1"
Then the response status code should be 200
And the response should be in JSON
And the header "Content-Type" should be equal to "application/json; charset=utf-8"
4 changes: 2 additions & 2 deletions src/JsonLd/Serializer/ItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ public function normalize(mixed $object, string $format = null, array $context =
// TODO: we should not remove the resource_class in the normalizeRawCollection as we would find out anyway that it's not the same as the requested one
$previousResourceClass = $context['resource_class'] ?? null;
$metadata = [];
if ($isResourceClass = $this->resourceClassResolver->isResourceClass($resourceClass)) {
$resourceClass = $this->resourceClassResolver->getResourceClass($object, $context['resource_class'] ?? null);
if ($isResourceClass = $this->resourceClassResolver->isResourceClass($resourceClass) && (null === $previousResourceClass || $this->resourceClassResolver->isResourceClass($previousResourceClass))) {
$resourceClass = $this->resourceClassResolver->getResourceClass($object, $previousResourceClass);
$context = $this->initContext($resourceClass, $context);
$metadata = $this->addJsonLdContext($this->contextBuilder, $resourceClass, $context);
} elseif ($this->contextBuilder instanceof AnonymousContextBuilderInterface) {
Expand Down
4 changes: 2 additions & 2 deletions src/Serializer/AbstractItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -710,8 +710,8 @@ protected function getAttributeValue(object $object, string $attribute, string $
);

// Anonymous resources
if ($type->getClassName()) {
$childContext = $this->createChildContext($this->createOperationContext($context, null), $attribute, $format);
if ($className) {
$childContext = $this->createChildContext($this->createOperationContext($context, $className), $attribute, $format);
$childContext['output']['gen_id'] = $propertyMetadata->getGenId() ?? true;

$attributeValue = $this->propertyAccessor->getValue($object, $attribute);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?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\Issue5926;

class ContentItemCollection implements \IteratorAggregate
{
private array $items;

public function __construct(ContentItemInterface ...$items)
{
$this->items = $items;
}

public function getIterator(): \Traversable
{
return new \ArrayIterator($this->items);
}
}
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 <[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\Issue5926;

interface ContentItemInterface
{
}
36 changes: 36 additions & 0 deletions tests/Fixtures/TestBundle/Entity/Issue5926/Media.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?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\Issue5926;

use ApiPlatform\Metadata\ApiResource;

#[ApiResource]
class Media
{
public function __construct(
private readonly string $id,
private readonly string $title,
) {
}

public function getId(): string
{
return $this->id;
}

public function getTitle(): string
{
return $this->title;
}
}
27 changes: 27 additions & 0 deletions tests/Fixtures/TestBundle/Entity/Issue5926/MediaContentItem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?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\Issue5926;

class MediaContentItem implements ContentItemInterface
{
public function __construct(
private readonly Media $media,
) {
}

public function getMedia(): Media
{
return $this->media;
}
}
56 changes: 56 additions & 0 deletions tests/Fixtures/TestBundle/Entity/Issue5926/TestIssue5926.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?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\Issue5926;

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

#[ApiResource(
operations: [
new Get(
provider: [TestIssue5926::class, 'provide']
),
]
)]
class TestIssue5926
{
public function __construct(
private readonly string $id,
private readonly ?ContentItemCollection $content,
) {
}

public function getId(): string
{
return $this->id;
}

public function getContent(): ?ContentItemCollection
{
return $this->content;
}

public static function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
$media = new Media('1', 'My media');
$contentItem1 = new MediaContentItem($media);
$media = new Media('2', 'My media 2');
$contentItem2 = new MediaContentItem($media);

$collection = new ContentItemCollection($contentItem1, $contentItem2);

return new self('1', $collection);
}
}

0 comments on commit 495f75f

Please sign in to comment.