Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(doctrine): denormalization of properties with embeds many that omit target document directive #4315

Merged
merged 6 commits into from
Jun 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
@mongodb
Feature: Embed many without target document deserializable
In order to create and update resources
As a developer
I need to be able to deserialize data into objects with embed many that omit target document directive

@createSchema
Scenario: Post a resource with embedded data
When I add "Content-Type" header equal to "application/ld+json"
And I send a "POST" request to "/dummy_with_embed_many_omitting_target_documents" with body:
"""
{
"embeddedDummies": [
{
"dummyName": "foo",
"dummyBoolean": true,
"dummyDate": "2020-01-01",
"dummyFloat": 0.1,
"dummyPrice": 10
},
{
"dummyName": "bar",
"dummyBoolean": false,
"dummyDate": "2021-01-01",
"dummyFloat": 0.2,
"dummyPrice": 20
}
]
}
"""
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 should be a superset of:
"""
{
"@context": "/contexts/DummyWithEmbedManyOmittingTargetDocument",
"@id": "/dummy_with_embed_many_omitting_target_documents/1",
"@type": "DummyWithEmbedManyOmittingTargetDocument",
"id": 1,
"embeddedDummies": [
{
"@type": "EmbeddableDummy",
"dummyName": "foo",
"dummyBoolean": true,
"dummyDate": "2020-01-01T00:00:00+00:00",
"dummyFloat": 0.1,
"dummyPrice": 10
},
{
"@type": "EmbeddableDummy",
"dummyName": "bar",
"dummyBoolean": false,
"dummyDate": "2021-01-01T00:00:00+00:00",
"dummyFloat": 0.2,
"dummyPrice": 20
}
]
}
"""
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,13 @@ public function getTypes($class, $property, array $context = [])
}

if ($metadata->hasAssociation($property)) {
/** @var ?string $class */
$class = $metadata->getAssociationTargetClass($property);

if (null === $class) {
return null;
}

if ($metadata->isSingleValuedAssociation($property)) {
$nullable = $metadata instanceof MongoDbClassMetadata && $metadata->isNullable($property);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public function testTestGetPropertiesWithEmbedded(): void
'id',
'embedOne',
'embedMany',
'embedManyOmittingTargetDocument',
],
$this->createExtractor()->getProperties(DoctrineWithEmbedded::class)
);
Expand Down Expand Up @@ -197,6 +198,16 @@ public function testGeneratedValueNotWritable()
$this->assertNull($extractor->isReadable(DoctrineGeneratedValue::class, 'foo'));
}

public function testGetTypesWithEmbedManyOmittingTargetDocument(): void
{
$actualTypes = $this->createExtractor()->getTypes(
DoctrineWithEmbedded::class,
'embedManyOmittingTargetDocument'
);

self::assertNull($actualTypes);
}

private function createExtractor(): DoctrineExtractor
{
$config = DoctrineMongoDbOdmSetup::createAnnotationMetadataConfiguration([__DIR__.\DIRECTORY_SEPARATOR.'Fixtures'], true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,9 @@ class DoctrineWithEmbedded
* @EmbedMany(targetDocument=DoctrineEmbeddable::class)
*/
protected $embedMany;

/**
* @EmbedMany
*/
protected $embedManyOmittingTargetDocument;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?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\Core\Tests\Fixtures\TestBundle\Document;

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/**
* @ApiResource
* @ODM\Document
*/
class DummyWithEmbedManyOmittingTargetDocument
{
/**
* @var int The id
*
* @ODM\Id(strategy="INCREMENT", type="int")
*/
private $id;

/**
* @var EmbeddableDummy[]|Collection
*
* @ODM\EmbedMany
*/
private $embeddedDummies;

public function __construct()
{
$this->embeddedDummies = new ArrayCollection();
}

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

public function getEmbeddedDummies(): Collection
{
return $this->embeddedDummies;
}

public function addEmbeddedDummy(EmbeddableDummy $dummy): void
{
$this->embeddedDummies->add($dummy);
}

public function removeEmbeddedDummy(EmbeddableDummy $dummy): void
{
$this->embeddedDummies->removeElement($dummy);
}
}