Skip to content

Commit c9692b5

Browse files
authored
fix(state): transform uri variable using ReadLinkParameterProvider (#7375)
1 parent 5a8d4d2 commit c9692b5

File tree

4 files changed

+82
-3
lines changed

4 files changed

+82
-3
lines changed

src/State/ParameterProvider/ReadLinkParameterProvider.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ public function provide(Parameter $parameter, array $parameters = [], array $con
8989

9090
$context['request']?->attributes->set($securityObjectName, $relation);
9191

92+
if ($parameter instanceof Link) {
93+
$uriVariables = $operation->getUriVariables();
94+
$uriVariables[$parameter->getKey()] = $parameter;
95+
$operation = $operation->withUriVariables($uriVariables);
96+
}
97+
9298
return $operation;
9399
}
94100

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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\Metadata\Get;
17+
use ApiPlatform\Metadata\HttpOperation;
18+
use ApiPlatform\Metadata\Link;
19+
use ApiPlatform\Metadata\Operation;
20+
use ApiPlatform\State\ParameterProvider\ReadLinkParameterProvider;
21+
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Dummy;
22+
23+
#[Get(
24+
uriTemplate: '/link_parameter_provider_resources/{id}',
25+
uriVariables: [
26+
'id' => new Link(
27+
provider: ReadLinkParameterProvider::class,
28+
fromClass: Dummy::class
29+
),
30+
],
31+
provider: [self::class, 'provide']
32+
)]
33+
class LinkParameterProviderResource
34+
{
35+
public string $id;
36+
public Dummy $dummy;
37+
38+
/**
39+
* @param HttpOperation $operation
40+
*/
41+
public static function provide(Operation $operation, array $uriVariables = [])
42+
{
43+
$d = new self();
44+
$d->id = '1';
45+
$d->dummy = $operation->getUriVariables()['id']->getValue();
46+
47+
return $d;
48+
}
49+
}

tests/Fixtures/TestBundle/Entity/Employee.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
use ApiPlatform\Metadata\Post;
2121
use Doctrine\ORM\Mapping as ORM;
2222
use Symfony\Component\Serializer\Annotation\Groups;
23-
use Symfony\Component\Validator\Constraints\IdenticalTo;
23+
use Symfony\Component\Validator\Constraints\Expression;
2424

2525
#[ApiResource]
2626
#[Post]
@@ -49,7 +49,11 @@
4949
toProperty: 'company',
5050
security: 'company.name == "Test" or company.name == "NotTest"',
5151
extraProperties: ['uri_template' => '/company-by-name/{name}'],
52-
constraints: [new IdenticalTo('Test')]
52+
constraints: [
53+
new Expression(
54+
'value.getName() == "Test"',
55+
),
56+
]
5357
),
5458
],
5559
)]

tests/Functional/Parameters/LinkProviderParameterTest.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\Tests\Functional\Parameters;
1515

1616
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
17+
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\LinkParameterProviderResource;
1718
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\WithParameter;
1819
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Company;
1920
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Dummy;
@@ -35,7 +36,7 @@ final class LinkProviderParameterTest extends ApiTestCase
3536
*/
3637
public static function getResources(): array
3738
{
38-
return [WithParameter::class, Dummy::class, Employee::class, Company::class];
39+
return [WithParameter::class, Dummy::class, Employee::class, Company::class, LinkParameterProviderResource::class];
3940
}
4041

4142
/**
@@ -162,4 +163,23 @@ public function testLinkSecurityWithConstraint(): void
162163
$response = self::createClient()->request('GET', '/companies-by-name/NotTest/employees');
163164
self::assertEquals(422, $response->getStatusCode());
164165
}
166+
167+
public function testUriVariableHasDummy(): void
168+
{
169+
if ('mongodb' === $container->getParameter('kernel.environment')) {
170+
$this->markTestSkipped();
171+
}
172+
173+
$manager = $this->getManager();
174+
$dummy = new Dummy();
175+
$dummy->setName('hi');
176+
$manager->persist($dummy);
177+
$manager->flush();
178+
179+
self::createClient()->request('GET', '/link_parameter_provider_resources/'.$dummy->getId());
180+
181+
$this->assertJsonContains([
182+
'dummy' => '/dummies/1',
183+
]);
184+
}
165185
}

0 commit comments

Comments
 (0)