Skip to content

Commit 0f89161

Browse files
authored
fix(metadata): route prefix in the operation name (#5208)
1 parent aeeaea9 commit 0f89161

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

src/Metadata/Operations.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ public function __construct(array $operations = [])
2626
// When we use an int-indexed array in the constructor, compute priorities
2727
if (\is_int($operationName)) {
2828
$operation = $operation->withPriority($operationName);
29+
$operationName = (string) $operationName;
30+
}
31+
32+
if ($operation->getName()) {
33+
$operationName = $operation->getName();
2934
}
3035

3136
$this->operations[] = [$operationName, $operation];

src/Metadata/Resource/Factory/OperationNameResourceMetadataCollectionFactory.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ public function create(string $resourceClass): ResourceMetadataCollection
5252
continue;
5353
}
5454

55-
$newOperationName = sprintf('_api_%s_%s%s', $operation->getUriTemplate() ?: $operation->getShortName(), strtolower($operation->getMethod() ?? HttpOperation::METHOD_GET), $operation instanceof CollectionOperationInterface ? '_collection' : '');
55+
$path = ($operation->getRoutePrefix() ?? '').($operation->getUriTemplate() ?? '');
56+
$newOperationName = sprintf('_api_%s_%s%s', $path ?: ($operation->getShortName() ?? $this->getDefaultShortname($resourceClass)), strtolower($operation->getMethod() ?? HttpOperation::METHOD_GET), $operation instanceof CollectionOperationInterface ? '_collection' : '');
5657
$operations->remove($operationName)->add($newOperationName, $operation->withName($newOperationName));
5758
}
5859

@@ -61,4 +62,9 @@ public function create(string $resourceClass): ResourceMetadataCollection
6162

6263
return $resourceMetadataCollection;
6364
}
65+
66+
private function getDefaultShortname(string $resourceClass): string
67+
{
68+
return (false !== $pos = strrpos($resourceClass, '\\')) ? substr($resourceClass, $pos + 1) : $resourceClass;
69+
}
6470
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
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\Metadata\Resource\Factory;
15+
16+
use ApiPlatform\Metadata\ApiResource;
17+
use ApiPlatform\Metadata\Get;
18+
use ApiPlatform\Metadata\Operation;
19+
use ApiPlatform\Metadata\Resource\Factory\OperationNameResourceMetadataCollectionFactory;
20+
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
21+
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
22+
use PHPUnit\Framework\TestCase;
23+
use Prophecy\PhpUnit\ProphecyTrait;
24+
25+
class OperationNameResourceMetadataFactoryTest extends TestCase
26+
{
27+
use ProphecyTrait;
28+
29+
/**
30+
* @dataProvider operationProvider
31+
*/
32+
public function testGeneratesName(Operation $operation, string $expectedOperationName): void
33+
{
34+
$decorated = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
35+
$decorated->create('a')->willReturn(new ResourceMetadataCollection('a', [
36+
new ApiResource(operations: [$operation]),
37+
]));
38+
39+
$operationNameResourceMetadataFactory = new OperationNameResourceMetadataCollectionFactory($decorated->reveal());
40+
$result = $operationNameResourceMetadataFactory->create('a');
41+
42+
$this->assertEquals($operation->withName($expectedOperationName), $result->getOperation($expectedOperationName));
43+
}
44+
45+
public function operationProvider(): array
46+
{
47+
return [
48+
[new Get(), '_api_a_get'],
49+
[new Get(shortName: 'Foo'), '_api_Foo_get'],
50+
[new Get(name: 'test'), 'test'],
51+
[new Get(routePrefix: 'foo'), '_api_foo_get'],
52+
[new Get(uriTemplate: '/foo'), '_api_/foo_get'],
53+
[new Get(routePrefix: '/admin', uriTemplate: '/foo'), '_api_/admin/foo_get'],
54+
];
55+
}
56+
}

0 commit comments

Comments
 (0)