Skip to content

Commit d34cd7b

Browse files
fix: use stateOptions when retrieving a Parameter filter (#6728)
Co-authored-by: soyuka <[email protected]>
1 parent 5503478 commit d34cd7b

File tree

5 files changed

+382
-5
lines changed

5 files changed

+382
-5
lines changed

src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313

1414
namespace ApiPlatform\Metadata\Resource\Factory;
1515

16+
use ApiPlatform\Doctrine\Odm\State\Options as DoctrineOdmOptions;
17+
use ApiPlatform\Doctrine\Orm\State\Options as DoctrineOrmOptions;
1618
use ApiPlatform\Metadata\FilterInterface;
1719
use ApiPlatform\Metadata\HeaderParameterInterface;
1820
use ApiPlatform\Metadata\HttpOperation;
21+
use ApiPlatform\Metadata\Operation;
1922
use ApiPlatform\Metadata\Parameter;
2023
use ApiPlatform\Metadata\Parameters;
2124
use ApiPlatform\Metadata\QueryParameter;
@@ -54,14 +57,15 @@ public function create(string $resourceClass): ResourceMetadataCollection
5457
$resourceMetadataCollection = $this->decorated?->create($resourceClass) ?? new ResourceMetadataCollection($resourceClass);
5558

5659
foreach ($resourceMetadataCollection as $i => $resource) {
60+
$resourceClass = $resource->getClass();
5761
$operations = $resource->getOperations();
5862

5963
$internalPriority = -1;
6064
foreach ($operations as $operationName => $operation) {
6165
$parameters = $operation->getParameters() ?? new Parameters();
6266
foreach ($parameters as $key => $parameter) {
6367
$key = $parameter->getKey() ?? $key;
64-
$parameter = $this->setDefaults($key, $parameter, $resourceClass);
68+
$parameter = $this->setDefaults($key, $parameter, $resourceClass, $operation);
6569
$priority = $parameter->getPriority() ?? $internalPriority--;
6670
$parameters->add($key, $parameter->withPriority($priority));
6771
}
@@ -87,7 +91,7 @@ public function create(string $resourceClass): ResourceMetadataCollection
8791
$parameters = $operation->getParameters() ?? new Parameters();
8892
foreach ($operation->getParameters() ?? [] as $key => $parameter) {
8993
$key = $parameter->getKey() ?? $key;
90-
$parameter = $this->setDefaults($key, $parameter, $resourceClass);
94+
$parameter = $this->setDefaults($key, $parameter, $resourceClass, $operation);
9195
$priority = $parameter->getPriority() ?? $internalPriority--;
9296
$parameters->add($key, $parameter->withPriority($priority));
9397
}
@@ -101,7 +105,7 @@ public function create(string $resourceClass): ResourceMetadataCollection
101105
return $resourceMetadataCollection;
102106
}
103107

104-
private function setDefaults(string $key, Parameter $parameter, string $resourceClass): Parameter
108+
private function setDefaults(string $key, Parameter $parameter, string $resourceClass, Operation $operation): Parameter
105109
{
106110
if (null === $parameter->getKey()) {
107111
$parameter = $parameter->withKey($key);
@@ -117,7 +121,7 @@ private function setDefaults(string $key, Parameter $parameter, string $resource
117121
}
118122

119123
// Read filter description to populate the Parameter
120-
$description = $filter instanceof FilterInterface ? $filter->getDescription($resourceClass) : [];
124+
$description = $filter instanceof FilterInterface ? $filter->getDescription($this->getFilterClass($operation)) : [];
121125
if (($schema = $description[$key]['schema'] ?? null) && null === $parameter->getSchema()) {
122126
$parameter = $parameter->withSchema($schema);
123127
}
@@ -242,7 +246,7 @@ private function addFilterValidation(HttpOperation $operation): Parameters
242246
}
243247

244248
$filter = $this->filterLocator->get($filter);
245-
foreach ($filter->getDescription($operation->getClass()) as $parameterName => $definition) {
249+
foreach ($filter->getDescription($this->getFilterClass($operation)) as $parameterName => $definition) {
246250
$key = $parameterName;
247251
$required = $definition['required'] ?? false;
248252
$schema = $definition['schema'] ?? null;
@@ -296,4 +300,19 @@ private function addFilterValidation(HttpOperation $operation): Parameters
296300

297301
return $parameters;
298302
}
303+
304+
private function getFilterClass(Operation $operation): ?string
305+
{
306+
$stateOptions = $operation->getStateOptions();
307+
308+
if ($stateOptions instanceof DoctrineOrmOptions) {
309+
return $stateOptions->getEntityClass();
310+
}
311+
312+
if ($stateOptions instanceof DoctrineOdmOptions) {
313+
return $stateOptions->getDocumentClass();
314+
}
315+
316+
return $operation->getClass();
317+
}
299318
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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\ApiResource;
15+
16+
use ApiPlatform\Doctrine\Odm\Filter\DateFilter as OdmDateFilter;
17+
use ApiPlatform\Doctrine\Odm\State\Options as OdmOptions;
18+
use ApiPlatform\Doctrine\Orm\Filter\DateFilter;
19+
use ApiPlatform\Doctrine\Orm\State\Options;
20+
use ApiPlatform\Metadata\ApiFilter;
21+
use ApiPlatform\Metadata\ApiResource;
22+
use ApiPlatform\Metadata\GetCollection;
23+
use ApiPlatform\Metadata\QueryParameter;
24+
use ApiPlatform\Tests\Fixtures\TestBundle\Document\AgentDocument;
25+
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Agent;
26+
27+
#[ApiFilter(DateFilter::class, properties: ['birthday'], alias: 'app_filter_date')]
28+
#[ApiResource(
29+
shortName: 'Agent',
30+
operations: [
31+
new GetCollection(parameters: [
32+
'birthday' => new QueryParameter(filter: 'app_filter_date'),
33+
]),
34+
],
35+
stateOptions: new Options(entityClass: Agent::class)
36+
)]
37+
#[ApiFilter(OdmDateFilter::class, properties: ['birthday'], alias: 'app_filter_date_odm')]
38+
#[ApiResource(
39+
shortName: 'AgentDocument',
40+
operations: [
41+
new GetCollection(parameters: [
42+
'birthday' => new QueryParameter(filter: 'app_filter_date_odm'),
43+
]),
44+
],
45+
stateOptions: new OdmOptions(documentClass: AgentDocument::class)
46+
)]
47+
class AgentApi
48+
{
49+
private ?int $id = null;
50+
51+
private ?string $name = null;
52+
53+
private ?\DateTimeInterface $birthday = null;
54+
55+
public function getId(): ?int
56+
{
57+
return $this->id;
58+
}
59+
60+
public function setId(?int $id): self
61+
{
62+
$this->id = $id;
63+
64+
return $this;
65+
}
66+
67+
public function getName(): ?string
68+
{
69+
return $this->name;
70+
}
71+
72+
public function setName(?string $name): self
73+
{
74+
$this->name = $name;
75+
76+
return $this;
77+
}
78+
79+
public function getBirthday(): ?\DateTimeInterface
80+
{
81+
return $this->birthday;
82+
}
83+
84+
public function setBirthday(?\DateTimeInterface $birthday): self
85+
{
86+
$this->birthday = $birthday;
87+
88+
return $this;
89+
}
90+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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 Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
17+
18+
#[ODM\Document]
19+
class AgentDocument
20+
{
21+
#[ODM\Id(strategy: 'INCREMENT', type: 'int')]
22+
public ?int $id = null;
23+
24+
#[ODM\Field]
25+
public ?string $name = null;
26+
27+
#[ODM\Field]
28+
public ?string $apiKey = null;
29+
30+
#[ODM\Field]
31+
public ?\DateTimeImmutable $createdAt = null;
32+
33+
#[ODM\Field]
34+
public ?\DateTimeImmutable $birthday = null;
35+
36+
public function getId(): ?int
37+
{
38+
return $this->id;
39+
}
40+
41+
public function setId(int $id): static
42+
{
43+
$this->id = $id;
44+
45+
return $this;
46+
}
47+
48+
public function getName(): ?string
49+
{
50+
return $this->name;
51+
}
52+
53+
public function setName(string $name): static
54+
{
55+
$this->name = $name;
56+
57+
return $this;
58+
}
59+
60+
public function getApiKey(): ?string
61+
{
62+
return $this->apiKey;
63+
}
64+
65+
public function setApiKey(string $apiKey): static
66+
{
67+
$this->apiKey = $apiKey;
68+
69+
return $this;
70+
}
71+
72+
public function getCreatedAt(): ?\DateTimeImmutable
73+
{
74+
return $this->createdAt;
75+
}
76+
77+
public function setCreatedAt(\DateTimeImmutable $createdAt): static
78+
{
79+
$this->createdAt = $createdAt;
80+
81+
return $this;
82+
}
83+
84+
public function getBirthday(): ?\DateTimeImmutable
85+
{
86+
return $this->birthday;
87+
}
88+
89+
public function setBirthday(\DateTimeImmutable $birthday): static
90+
{
91+
$this->birthday = $birthday;
92+
93+
return $this;
94+
}
95+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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\Entity;
15+
16+
use Doctrine\ORM\Mapping as ORM;
17+
18+
#[ORM\Entity]
19+
class Agent
20+
{
21+
#[ORM\Id]
22+
#[ORM\GeneratedValue]
23+
#[ORM\Column]
24+
public ?int $id = null;
25+
26+
#[ORM\Column(length: 255)]
27+
public ?string $name = null;
28+
29+
#[ORM\Column]
30+
public ?\DateTimeImmutable $createdAt = null;
31+
32+
#[ORM\Column]
33+
public ?\DateTimeImmutable $birthday = null;
34+
35+
public function getId(): ?int
36+
{
37+
return $this->id;
38+
}
39+
40+
public function setId(int $id): static
41+
{
42+
$this->id = $id;
43+
44+
return $this;
45+
}
46+
47+
public function getName(): ?string
48+
{
49+
return $this->name;
50+
}
51+
52+
public function setName(string $name): static
53+
{
54+
$this->name = $name;
55+
56+
return $this;
57+
}
58+
59+
public function getCreatedAt(): ?\DateTimeImmutable
60+
{
61+
return $this->createdAt;
62+
}
63+
64+
public function setCreatedAt(\DateTimeImmutable $createdAt): static
65+
{
66+
$this->createdAt = $createdAt;
67+
68+
return $this;
69+
}
70+
71+
public function getBirthday(): ?\DateTimeImmutable
72+
{
73+
return $this->birthday;
74+
}
75+
76+
public function setBirthday(\DateTimeImmutable $birthday): static
77+
{
78+
$this->birthday = $birthday;
79+
80+
return $this;
81+
}
82+
}

0 commit comments

Comments
 (0)