Skip to content

Commit 57bfefb

Browse files
committed
fix(metadata): convert composite uri variables w/ proper type
1 parent 354d84d commit 57bfefb

File tree

3 files changed

+21
-5
lines changed

3 files changed

+21
-5
lines changed

src/Api/UriVariablesConverter.php

+13-4
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ public function __construct(private readonly PropertyMetadataFactoryInterface $p
3535

3636
/**
3737
* {@inheritdoc}
38+
*
39+
* To handle the composite identifiers type correctly, use an `uri_variables_map` that maps uriVariables to their uriVariablesDefinition.
40+
* Indeed, a composite identifier will already be parsed, and their corresponding properties will be the parameterName and not the defined
41+
* identifiers.
3842
*/
3943
public function convert(array $uriVariables, string $class, array $context = []): array
4044
{
@@ -43,10 +47,15 @@ public function convert(array $uriVariables, string $class, array $context = [])
4347
$uriVariablesDefinitions = $operation->getUriVariables() ?? [];
4448

4549
foreach ($uriVariables as $parameterName => $value) {
46-
$uriVariableDefinition = $uriVariablesDefinitions[$parameterName] ?? $uriVariablesDefinitions['id'] ?? new Link();
50+
$uriVariableDefinition = $context['uri_variables_map'][$parameterName] ?? $uriVariablesDefinitions[$parameterName] ?? $uriVariablesDefinitions['id'] ?? new Link();
4751

48-
$identifierTypes = $this->getIdentifierTypes($uriVariableDefinition->getFromClass() ?? $class, $uriVariableDefinition->getIdentifiers() ?? [$parameterName]);
49-
if (!($types = $identifierTypes[$parameterName] ?? false)) {
52+
// When a composite identifier is used, we assume that the parameterName is the property to find our type
53+
$properties = $uriVariableDefinition->getIdentifiers() ?? [$parameterName];
54+
if ($uriVariableDefinition->getCompositeIdentifier()) {
55+
$properties = [$parameterName];
56+
}
57+
58+
if (!$types = $this->getIdentifierTypes($uriVariableDefinition->getFromClass() ?? $class, $properties)) {
5059
continue;
5160
}
5261

@@ -73,7 +82,7 @@ private function getIdentifierTypes(string $resourceClass, array $properties): a
7382
foreach ($properties as $property) {
7483
$propertyMetadata = $this->propertyMetadataFactory->create($resourceClass, $property);
7584
foreach ($propertyMetadata->getBuiltinTypes() as $type) {
76-
$types[$property][] = Type::BUILTIN_TYPE_OBJECT === ($builtinType = $type->getBuiltinType()) ? $type->getClassName() : $builtinType;
85+
$types[] = Type::BUILTIN_TYPE_OBJECT === ($builtinType = $type->getBuiltinType()) ? $type->getClassName() : $builtinType;
7786
}
7887
}
7988

src/State/UriVariablesResolverTrait.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ private function getOperationUriVariables(?HttpOperation $operation = null, arra
3333
return $identifiers;
3434
}
3535

36+
$uriVariablesMap = [];
3637
foreach ($operation->getUriVariables() ?? [] as $parameterName => $uriVariableDefinition) {
3738
if (!isset($parameters[$parameterName])) {
3839
if (!isset($parameters['id'])) {
@@ -51,16 +52,18 @@ private function getOperationUriVariables(?HttpOperation $operation = null, arra
5152

5253
foreach ($currentIdentifiers as $key => $value) {
5354
$identifiers[$key] = $value;
55+
$uriVariableMap[$key] = $uriVariableDefinition;
5456
}
5557

5658
continue;
5759
}
5860

5961
$identifiers[$parameterName] = $parameters[$parameterName];
62+
$uriVariableMap[$parameterName] = $uriVariableDefinition;
6063
}
6164

6265
if ($this->uriVariablesConverter) {
63-
$context = ['operation' => $operation];
66+
$context = ['operation' => $operation, 'uri_variables_map' => $uriVariablesMap];
6467
$identifiers = $this->uriVariablesConverter->convert($identifiers, $operation->getClass() ?? $resourceClass, $context);
6568
}
6669

tests/Fixtures/TestBundle/ApiResource/Issue5396/CompositeKeyWithDifferentType.php

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ class CompositeKeyWithDifferentType
2828

2929
public static function provide(Operation $operation, array $uriVariables = [], array $context = []): array
3030
{
31+
if (!\is_string($uriVariables['verificationKey'])) {
32+
throw new \RuntimeException('verificationKey should be a string.');
33+
}
34+
3135
return $context;
3236
}
3337
}

0 commit comments

Comments
 (0)