Skip to content

Commit dc88545

Browse files
committed
chore: fixes
1 parent 02194e5 commit dc88545

13 files changed

+313
-407
lines changed

features/graphql/query.feature

+14-14
Original file line numberDiff line numberDiff line change
@@ -452,11 +452,11 @@ Feature: GraphQL query support
452452

453453
@createSchema
454454
Scenario: Execute a GraphQL query that includes a nested collection with different relations to same entity
455-
Given there are 3 sameRelationMultiUseDummy objects having a manyToOneRelation and each 2 manyToManyRelations and having each 3 oneToManyRelations
455+
Given there are 2 multiRelationsDummy objects having each a manyToOneRelation, 2 manyToManyRelations and 3 oneToManyRelations
456456
When I send the following GraphQL request:
457457
"""
458458
{
459-
sameRelationMultiUseDummy(id: "/same_relation_multi_use_dummies/2") {
459+
multiRelationsDummy(id: "/multi_relations_dummies/2") {
460460
id
461461
name
462462
manyToOneRelation {
@@ -485,15 +485,15 @@ Feature: GraphQL query support
485485
Then the response status code should be 200
486486
And the response should be in JSON
487487
And the header "Content-Type" should be equal to "application/json"
488-
And the JSON node "data.sameRelationMultiUseDummy.id" should be equal to "/same_relation_multi_use_dummies/2"
489-
And the JSON node "data.sameRelationMultiUseDummy.name" should be equal to "Dummy #2"
490-
And the JSON node "data.sameRelationMultiUseDummy.manyToOneRelation.id" should not be null
491-
And the JSON node "data.sameRelationMultiUseDummy.manyToOneRelation.name" should be equal to "RelatedMultiUsedDummy #2"
492-
And the JSON node "data.sameRelationMultiUseDummy.manyToManyRelations.edges" should have 2 element
493-
And the JSON node "data.sameRelationMultiUseDummy.manyToManyRelations.edges[1].node.id" should not be null
494-
And the JSON node "data.sameRelationMultiUseDummy.manyToManyRelations.edges[0].node.name" should be equal to "RelatedManyToManyDummy12"
495-
And the JSON node "data.sameRelationMultiUseDummy.manyToManyRelations.edges[1].node.name" should be equal to "RelatedManyToManyDummy22"
496-
And the JSON node "data.sameRelationMultiUseDummy.oneToManyRelations.edges" should have 3 element
497-
And the JSON node "data.sameRelationMultiUseDummy.oneToManyRelations.edges[1].node.id" should not be null
498-
And the JSON node "data.sameRelationMultiUseDummy.oneToManyRelations.edges[0].node.name" should be equal to "RelatedOneToManyDummy12"
499-
And the JSON node "data.sameRelationMultiUseDummy.oneToManyRelations.edges[2].node.name" should be equal to "RelatedOneToManyDummy32"
488+
And the JSON node "data.multiRelationsDummy.id" should be equal to "/multi_relations_dummies/2"
489+
And the JSON node "data.multiRelationsDummy.name" should be equal to "Dummy #2"
490+
And the JSON node "data.multiRelationsDummy.manyToOneRelation.id" should not be null
491+
And the JSON node "data.multiRelationsDummy.manyToOneRelation.name" should be equal to "RelatedManyToOneDummy #2"
492+
And the JSON node "data.multiRelationsDummy.manyToManyRelations.edges" should have 2 element
493+
And the JSON node "data.multiRelationsDummy.manyToManyRelations.edges[1].node.id" should not be null
494+
And the JSON node "data.multiRelationsDummy.manyToManyRelations.edges[0].node.name" should be equal to "RelatedManyToManyDummy12"
495+
And the JSON node "data.multiRelationsDummy.manyToManyRelations.edges[1].node.name" should be equal to "RelatedManyToManyDummy22"
496+
And the JSON node "data.multiRelationsDummy.oneToManyRelations.edges" should have 3 element
497+
And the JSON node "data.multiRelationsDummy.oneToManyRelations.edges[1].node.id" should not be null
498+
And the JSON node "data.multiRelationsDummy.oneToManyRelations.edges[0].node.name" should be equal to "RelatedOneToManyDummy12"
499+
And the JSON node "data.multiRelationsDummy.oneToManyRelations.edges[2].node.name" should be equal to "RelatedOneToManyDummy32"

src/Doctrine/Common/State/LinksHandlerTrait.php

+8-4
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,19 @@ private function getLinks(string $resourceClass, Operation $operation, array $co
3535
}
3636

3737
$newLink = null;
38-
$linkProperty = $context['linkProperty'];
38+
$linkProperty = $context['linkProperty'] ?? null;
3939

4040
foreach ($links as $link) {
41-
if (($linkClass === $link->getFromClass()) && ($linkProperty === $link->getFromProperty())) {
41+
if ($linkClass === $link->getFromClass() && $linkProperty === $link->getFromProperty()) {
4242
$newLink = $link;
4343
break;
4444
}
4545
}
4646

47+
if ($newLink) {
48+
return [$newLink];
49+
}
50+
4751
// Using GraphQL, it's possible that we won't find a GraphQL Operation of the same type (e.g. it is disabled).
4852
try {
4953
$resourceMetadataCollection = $this->resourceMetadataCollectionFactory->create($linkClass);
@@ -64,13 +68,13 @@ private function getLinks(string $resourceClass, Operation $operation, array $co
6468
}
6569

6670
foreach ($this->getOperationLinks($linkedOperation ?? null) as $link) {
67-
if (($resourceClass === $link->getToClass()) && ($linkProperty === $link->getFromProperty())) {
71+
if ($resourceClass === $link->getToClass() && $linkProperty === $link->getFromProperty()) {
6872
$newLink = $link;
6973
break;
7074
}
7175
}
7276

73-
if (null === $newLink) {
77+
if (!$newLink) {
7478
throw new RuntimeException(sprintf('The class "%s" cannot be retrieved from "%s".', $resourceClass, $linkClass));
7579
}
7680

src/Metadata/Resource/Factory/LinkResourceMetadataCollectionFactory.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,18 @@ private function mergeLinks(array $links, array $toMergeLinks): array
6868
{
6969
$classLinks = [];
7070
foreach ($links as $link) {
71-
$classLinks[$link->getToClass()][$link->getFromProperty()] = $link;
71+
$classLinks[$link->getToClass().'#'.$link->getFromProperty()] = $link;
7272
}
7373

7474
foreach ($toMergeLinks as $link) {
75-
if (null !== $prevLink = $classLinks[$link->getToClass()][$link->getFromProperty()] ?? null) {
76-
$classLinks[$link->getToClass()][$link->getFromProperty()] = $prevLink->withLink($link);
75+
if (null !== $prevLink = $classLinks[$link->getToClass().'#'.$link->getFromProperty()] ?? null) {
76+
$classLinks[$link->getToClass().'#'.$link->getFromProperty()] = $prevLink->withLink($link);
7777

7878
continue;
7979
}
80-
$classLinks[$link->getToClass()][$link->getFromProperty()] = $link;
80+
$classLinks[$link->getToClass().'#'.$link->getFromProperty()] = $link;
8181
}
8282

83-
return array_values(array_merge(...array_values($classLinks)));
83+
return array_values($classLinks);
8484
}
8585
}

tests/Behat/DoctrineContext.php

+18-19
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
use ApiPlatform\Tests\Fixtures\TestBundle\Document\InitializeInput as InitializeInputDocument;
6464
use ApiPlatform\Tests\Fixtures\TestBundle\Document\IriOnlyDummy as IriOnlyDummyDocument;
6565
use ApiPlatform\Tests\Fixtures\TestBundle\Document\MaxDepthDummy as MaxDepthDummyDocument;
66+
use ApiPlatform\Tests\Fixtures\TestBundle\Document\MultiRelationsDummy as MultiRelationsDummyDocument;
67+
use ApiPlatform\Tests\Fixtures\TestBundle\Document\MultiRelationsRelatedDummy as MultiRelationsRelatedDummyDocument;
6668
use ApiPlatform\Tests\Fixtures\TestBundle\Document\NetworkPathDummy as NetworkPathDummyDocument;
6769
use ApiPlatform\Tests\Fixtures\TestBundle\Document\NetworkPathRelationDummy as NetworkPathRelationDummyDocument;
6870
use ApiPlatform\Tests\Fixtures\TestBundle\Document\Order as OrderDocument;
@@ -78,10 +80,8 @@
7880
use ApiPlatform\Tests\Fixtures\TestBundle\Document\RelatedOwnedDummy as RelatedOwnedDummyDocument;
7981
use ApiPlatform\Tests\Fixtures\TestBundle\Document\RelatedOwningDummy as RelatedOwningDummyDocument;
8082
use ApiPlatform\Tests\Fixtures\TestBundle\Document\RelatedSecuredDummy as RelatedSecuredDummyDocument;
81-
use ApiPlatform\Tests\Fixtures\TestBundle\Document\RelatedMultiUsedDummy as RelatedMultiUsedDummyDocument;
8283
use ApiPlatform\Tests\Fixtures\TestBundle\Document\RelatedToDummyFriend as RelatedToDummyFriendDocument;
8384
use ApiPlatform\Tests\Fixtures\TestBundle\Document\RelationEmbedder as RelationEmbedderDocument;
84-
use ApiPlatform\Tests\Fixtures\TestBundle\Document\SameRelationMultiUseDummy as SameRelationMultiUseDummyDocument;
8585
use ApiPlatform\Tests\Fixtures\TestBundle\Document\SecuredDummy as SecuredDummyDocument;
8686
use ApiPlatform\Tests\Fixtures\TestBundle\Document\SoMany as SoManyDocument;
8787
use ApiPlatform\Tests\Fixtures\TestBundle\Document\Taxon as TaxonDocument;
@@ -140,6 +140,8 @@
140140
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\InternalUser;
141141
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\IriOnlyDummy;
142142
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\MaxDepthDummy;
143+
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\MultiRelationsDummy;
144+
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\MultiRelationsRelatedDummy;
143145
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\NetworkPathDummy;
144146
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\NetworkPathRelationDummy;
145147
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Order;
@@ -154,13 +156,11 @@
154156
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Question;
155157
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\RamseyUuidDummy;
156158
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\RelatedDummy;
157-
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\RelatedMultiUsedDummy;
158159
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\RelatedOwnedDummy;
159160
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\RelatedOwningDummy;
160161
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\RelatedSecuredDummy;
161162
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\RelatedToDummyFriend;
162163
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\RelationEmbedder;
163-
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\SameRelationMultiUseDummy;
164164
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\SecuredDummy;
165165
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Site;
166166
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\SoMany;
@@ -764,29 +764,29 @@ public function thereAreDummyObjectsWithRelatedDummies(int $nb, int $nbrelated):
764764
}
765765

766766
/**
767-
* @Given there are :nb sameRelationMultiUseDummy objects having a manyToOneRelation and each :nbmtmr manyToManyRelations and having each :nbotmr oneToManyRelations
767+
* @Given there are :nb multiRelationsDummy objects having each a manyToOneRelation, :nbmtmr manyToManyRelations and :nbotmr oneToManyRelations
768768
*/
769-
public function thereAreSameRelationMultiUseDummyObjectsHavingAManyToOneRelationAndEachManyToManyRelationsAndHavingEachOneToManyRelations(int $nb, int $nbmtmr, int $nbotmr): void
769+
public function thereAreMultiRelationsDummyObjectsHavingEachAManyToOneRelationManyToManyRelationsAndOneToManyRelations(int $nb, int $nbmtmr, int $nbotmr): void
770770
{
771771
for ($i = 1; $i <= $nb; ++$i) {
772-
$relatedDummy = $this->buildRelatedMultiUsedDummy();
773-
$relatedDummy->setName('RelatedMultiUsedDummy #'.$i);
772+
$relatedDummy = $this->buildMultiRelationsRelatedDummy();
773+
$relatedDummy->name = 'RelatedManyToOneDummy #'.$i;
774774

775-
$dummy = $this->buildSameRelationMultiUseDummy();
776-
$dummy->setName('Dummy #'.$i);
775+
$dummy = $this->buildMultiRelationsDummy();
776+
$dummy->name = 'Dummy #'.$i;
777777
$dummy->setManyToOneRelation($relatedDummy);
778778

779779
for ($j = 1; $j <= $nbmtmr; ++$j) {
780-
$manyToManyItem = $this->buildRelatedMultiUsedDummy();
781-
$manyToManyItem->setName('RelatedManyToManyDummy'.$j.$i);
780+
$manyToManyItem = $this->buildMultiRelationsRelatedDummy();
781+
$manyToManyItem->name = 'RelatedManyToManyDummy'.$j.$i;
782782
$this->manager->persist($manyToManyItem);
783783

784784
$dummy->addManyToManyRelation($manyToManyItem);
785785
}
786786

787787
for ($j = 1; $j <= $nbotmr; ++$j) {
788-
$oneToManyItem = $this->buildRelatedMultiUsedDummy();
789-
$oneToManyItem->setName('RelatedOneToManyDummy'.$j.$i);
788+
$oneToManyItem = $this->buildMultiRelationsRelatedDummy();
789+
$oneToManyItem->name = 'RelatedOneToManyDummy'.$j.$i;
790790
$oneToManyItem->setOneToManyRelation($dummy);
791791
$this->manager->persist($oneToManyItem);
792792

@@ -795,7 +795,6 @@ public function thereAreSameRelationMultiUseDummyObjectsHavingAManyToOneRelation
795795

796796
$this->manager->persist($relatedDummy);
797797
$this->manager->persist($dummy);
798-
799798
}
800799
$this->manager->flush();
801800
}
@@ -2342,13 +2341,13 @@ private function buildPayment(string $amount): Payment|PaymentDocument
23422341
return $this->isOrm() ? new Payment($amount) : new PaymentDocument($amount);
23432342
}
23442343

2345-
private function buildSameRelationMultiUseDummy(): SameRelationMultiUseDummy|SameRelationMultiUseDummyDocument
2344+
private function buildMultiRelationsDummy(): MultiRelationsDummy|MultiRelationsDummyDocument
23462345
{
2347-
return $this->isOrm() ? new SameRelationMultiUseDummy() : new SameRelationMultiUseDummyDocument();
2346+
return $this->isOrm() ? new MultiRelationsDummy() : new MultiRelationsDummyDocument();
23482347
}
23492348

2350-
private function buildRelatedMultiUsedDummy(): RelatedMultiUsedDummy|RelatedMultiUsedDummyDocument
2349+
private function buildMultiRelationsRelatedDummy(): MultiRelationsRelatedDummy|MultiRelationsRelatedDummyDocument
23512350
{
2352-
return $this->isOrm() ? new RelatedMultiUsedDummy() : new RelatedMultiUsedDummyDocument();
2351+
return $this->isOrm() ? new MultiRelationsRelatedDummy() : new MultiRelationsRelatedDummyDocument();
23532352
}
23542353
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Tests\Fixtures\TestBundle\Document;
15+
16+
use ApiPlatform\Metadata\ApiResource;
17+
use ApiPlatform\Metadata\GraphQl\Query;
18+
use ApiPlatform\Metadata\GraphQl\QueryCollection;
19+
use Doctrine\Common\Collections\ArrayCollection;
20+
use Doctrine\Common\Collections\Collection;
21+
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
22+
23+
/**
24+
* Dummy using different kind of relations to the same resource.
25+
*
26+
* @author Thomas Helmrich <[email protected]>
27+
*/
28+
#[ApiResource(graphQlOperations: [new QueryCollection(), new Query()])]
29+
#[ODM\Document]
30+
class MultiRelationsDummy
31+
{
32+
#[ODM\Id(strategy: 'INCREMENT', type: 'int')]
33+
private ?int $id = null;
34+
35+
#[ODM\Field(type: 'string')]
36+
public string $name;
37+
38+
#[ODM\ReferenceOne(targetDocument: MultiRelationsRelatedDummy::class, storeAs: 'id', nullable: true)]
39+
public ?MultiRelationsRelatedDummy $manyToOneRelation = null;
40+
41+
/** @var Collection<int, MultiRelationsRelatedDummy> */
42+
#[ODM\ReferenceMany(targetDocument: MultiRelationsRelatedDummy::class, storeAs: 'id', nullable: true)]
43+
public Collection $manyToManyRelations;
44+
45+
/** @var Collection<int, MultiRelationsRelatedDummy> */
46+
#[ODM\ReferenceMany(targetDocument: MultiRelationsRelatedDummy::class, mappedBy: 'oneToManyRelation', storeAs: 'id')]
47+
public Collection $oneToManyRelations;
48+
49+
public function __construct()
50+
{
51+
$this->manyToManyRelations = new ArrayCollection();
52+
$this->oneToManyRelations = new ArrayCollection();
53+
}
54+
55+
public function getId(): ?int
56+
{
57+
return $this->id;
58+
}
59+
60+
public function getManyToOneRelation(): ?MultiRelationsRelatedDummy
61+
{
62+
return $this->manyToOneRelation;
63+
}
64+
65+
public function setManyToOneRelation(?MultiRelationsRelatedDummy $relatedMultiUsedDummy): void
66+
{
67+
$this->manyToOneRelation = $relatedMultiUsedDummy;
68+
}
69+
70+
public function addManyToManyRelation(MultiRelationsRelatedDummy $relatedMultiUsedDummy): void
71+
{
72+
$this->manyToManyRelations->add($relatedMultiUsedDummy);
73+
}
74+
75+
public function addOneToManyRelation(MultiRelationsRelatedDummy $relatedMultiUsedDummy): void
76+
{
77+
$this->oneToManyRelations->add($relatedMultiUsedDummy);
78+
}
79+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Tests\Fixtures\TestBundle\Document;
15+
16+
use ApiPlatform\Metadata\ApiResource;
17+
use ApiPlatform\Metadata\GraphQl\Query;
18+
use ApiPlatform\Metadata\GraphQl\QueryCollection;
19+
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
20+
21+
/**
22+
* Dummy used in different kind of relations in the same resource.
23+
*
24+
* @author Thomas Helmrich <[email protected]>
25+
*/
26+
#[ApiResource(graphQlOperations: [new QueryCollection(), new Query()])]
27+
#[ODM\Document]
28+
class MultiRelationsRelatedDummy
29+
{
30+
#[ODM\Id(strategy: 'INCREMENT', type: 'int')]
31+
private ?int $id = null;
32+
33+
#[ODM\Field(type: 'string', nullable: true)]
34+
public ?string $name;
35+
36+
#[ODM\ReferenceOne(targetDocument: MultiRelationsDummy::class, inversedBy: 'oneToManyRelations', nullable: true, storeAs: 'id')]
37+
private ?MultiRelationsDummy $oneToManyRelation;
38+
39+
public function getId(): ?int
40+
{
41+
return $this->id;
42+
}
43+
44+
public function getOneToManyRelation(): ?MultiRelationsDummy
45+
{
46+
return $this->oneToManyRelation;
47+
}
48+
49+
public function setOneToManyRelation(?MultiRelationsDummy $oneToManyRelation): void
50+
{
51+
$this->oneToManyRelation = $oneToManyRelation;
52+
}
53+
}

0 commit comments

Comments
 (0)