Skip to content

Commit bfab314

Browse files
committed
refactor: merge DefaultParametersResourceMetadataCollectionFactory into ParameterValidationResourceMetadataCollectionFactory
1 parent 88619ac commit bfab314

6 files changed

Lines changed: 143 additions & 185 deletions

File tree

src/Metadata/Resource/Factory/DefaultParametersResourceMetadataCollectionFactory.php

Lines changed: 0 additions & 166 deletions
This file was deleted.

src/Symfony/Bundle/Resources/config/metadata/resource.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
use ApiPlatform\Metadata\Resource\Factory\BackedEnumResourceMetadataCollectionFactory;
1919
use ApiPlatform\Metadata\Resource\Factory\CachedResourceMetadataCollectionFactory;
2020
use ApiPlatform\Metadata\Resource\Factory\ConcernsResourceMetadataCollectionFactory;
21-
use ApiPlatform\Metadata\Resource\Factory\DefaultParametersResourceMetadataCollectionFactory;
2221
use ApiPlatform\Metadata\Resource\Factory\ExtractorResourceMetadataCollectionFactory;
2322
use ApiPlatform\Metadata\Resource\Factory\FiltersResourceMetadataCollectionFactory;
2423
use ApiPlatform\Metadata\Resource\Factory\FormatsResourceMetadataCollectionFactory;
@@ -154,13 +153,6 @@
154153
service('logger')->ignoreOnInvalid(),
155154
]);
156155

157-
$services->set('api_platform.metadata.resource.metadata_collection_factory.default_parameters', DefaultParametersResourceMetadataCollectionFactory::class)
158-
->decorate('api_platform.metadata.resource.metadata_collection_factory', null, 1001)
159-
->args([
160-
'%api_platform.defaults.parameters%',
161-
service('api_platform.metadata.resource.metadata_collection_factory.default_parameters.inner'),
162-
]);
163-
164156
$services->set('api_platform.metadata.resource.metadata_collection_factory.cached', CachedResourceMetadataCollectionFactory::class)
165157
->decorate('api_platform.metadata.resource.metadata_collection_factory', null, -10)
166158
->args([

src/Symfony/Bundle/Resources/config/validator/validator.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,6 @@
3737
->args([
3838
service('api_platform.validator.metadata.resource.metadata_collection_factory.parameter.inner'),
3939
service('api_platform.filter_locator'),
40+
'%api_platform.defaults.parameters%',
4041
]);
4142
};

src/Validator/Metadata/Resource/Factory/ParameterValidationResourceMetadataCollectionFactory.php

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace ApiPlatform\Validator\Metadata\Resource\Factory;
1515

16+
use ApiPlatform\Metadata\ApiResource;
1617
use ApiPlatform\Metadata\HttpOperation;
1718
use ApiPlatform\Metadata\Parameter;
1819
use ApiPlatform\Metadata\Parameters;
@@ -30,14 +31,19 @@ final class ParameterValidationResourceMetadataCollectionFactory implements Reso
3031
public function __construct(
3132
private readonly ?ResourceMetadataCollectionFactoryInterface $decorated = null,
3233
private readonly ?ContainerInterface $filterLocator = null,
34+
private readonly array $defaultParameters = [],
3335
) {
3436
}
3537

3638
public function create(string $resourceClass): ResourceMetadataCollection
3739
{
3840
$resourceMetadataCollection = $this->decorated?->create($resourceClass) ?? new ResourceMetadataCollection($resourceClass);
3941

42+
$defaultParams = $this->buildDefaultParameters();
43+
4044
foreach ($resourceMetadataCollection as $i => $resource) {
45+
$resource = $this->applyDefaults($resource, $defaultParams);
46+
4147
$operations = $resource->getOperations();
4248

4349
foreach ($operations as $operationName => $operation) {
@@ -135,4 +141,121 @@ private function addFilterValidation(HttpOperation $operation): Parameters
135141

136142
return $parameters;
137143
}
144+
145+
/**
146+
* Builds Parameter objects from the default configuration array.
147+
*
148+
* @return array<string, Parameter> Array of Parameter objects indexed by their key
149+
*/
150+
private function buildDefaultParameters(): array
151+
{
152+
$parameters = [];
153+
154+
foreach ($this->defaultParameters as $parameterClass => $config) {
155+
if (!is_subclass_of($parameterClass, Parameter::class)) {
156+
continue;
157+
}
158+
159+
$key = $config['key'] ?? null;
160+
if (!$key) {
161+
$key = (new \ReflectionClass($parameterClass))->getShortName();
162+
}
163+
164+
$identifier = $key;
165+
166+
$parameter = $this->createParameterFromConfig($parameterClass, $config);
167+
$parameters[$identifier] = $parameter;
168+
}
169+
170+
return $parameters;
171+
}
172+
173+
/**
174+
* Creates a Parameter instance from configuration.
175+
*
176+
* @param class-string<Parameter> $parameterClass The parameter class name
177+
* @param array<string, mixed> $config The configuration array
178+
*
179+
* @return Parameter The created parameter instance
180+
*/
181+
private function createParameterFromConfig(string $parameterClass, array $config): Parameter
182+
{
183+
return new $parameterClass(
184+
key: $config['key'] ?? null,
185+
schema: $config['schema'] ?? null,
186+
openApi: null,
187+
provider: null,
188+
filter: $config['filter'] ?? null,
189+
property: $config['property'] ?? null,
190+
description: $config['description'] ?? null,
191+
properties: null,
192+
required: $config['required'] ?? false,
193+
priority: $config['priority'] ?? null,
194+
hydra: $config['hydra'] ?? null,
195+
constraints: $config['constraints'] ?? null,
196+
security: $config['security'] ?? null,
197+
securityMessage: $config['security_message'] ?? null,
198+
extraProperties: $config['extra_properties'] ?? [],
199+
filterContext: null,
200+
nativeType: null,
201+
castToArray: null,
202+
castToNativeType: null,
203+
castFn: null,
204+
default: $config['default'] ?? null,
205+
filterClass: $config['filter_class'] ?? null,
206+
);
207+
}
208+
209+
/**
210+
* Applies default parameters to the resource.
211+
*
212+
* @param array<string, Parameter> $defaultParams The default parameters to apply
213+
*/
214+
private function applyDefaults(ApiResource $resource, array $defaultParams): ApiResource
215+
{
216+
$resourceParameters = $resource->getParameters() ?? new Parameters();
217+
$mergedResourceParameters = $this->mergeParameters($resourceParameters, $defaultParams);
218+
$resource = $resource->withParameters($mergedResourceParameters);
219+
220+
foreach ($operations = $resource->getOperations() ?? [] as $operationName => $operation) {
221+
$operationParameters = $operation->getParameters() ?? new Parameters();
222+
$mergedOperationParameters = $this->mergeParameters($operationParameters, $defaultParams);
223+
$operations->add((string) $operationName, $operation->withParameters($mergedOperationParameters));
224+
}
225+
226+
if ($operations) {
227+
$resource = $resource->withOperations($operations);
228+
}
229+
230+
foreach ($graphQlOperations = $resource->getGraphQlOperations() ?? [] as $operationName => $operation) {
231+
$operationParameters = $operation->getParameters() ?? new Parameters();
232+
$mergedOperationParameters = $this->mergeParameters($operationParameters, $defaultParams);
233+
$graphQlOperations[$operationName] = $operation->withParameters($mergedOperationParameters);
234+
}
235+
236+
if ($graphQlOperations) {
237+
$resource = $resource->withGraphQlOperations($graphQlOperations);
238+
}
239+
240+
return $resource;
241+
}
242+
243+
/**
244+
* Merges default parameters with operation-specific parameters.
245+
*
246+
* @param Parameters $operationParameters The parameters already defined on the operation
247+
* @param array<string, Parameter> $defaultParams The default parameters to merge
248+
*
249+
* @return Parameters The merged parameters
250+
*/
251+
private function mergeParameters(Parameters $operationParameters, array $defaultParams): Parameters
252+
{
253+
$merged = new Parameters($defaultParams);
254+
255+
foreach ($operationParameters as $key => $param) {
256+
$merged->add($key, $param);
257+
}
258+
259+
return $merged;
260+
}
138261
}

tests/Symfony/Bundle/DependencyInjection/ConfigurationDefaultParametersTest.php renamed to src/Validator/Tests/Metadata/Resource/Factory/ParameterValidationConfigurationTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@
1111

1212
declare(strict_types=1);
1313

14-
namespace ApiPlatform\Tests\Symfony\Bundle\DependencyInjection;
14+
namespace ApiPlatform\Tests\Validator\Metadata\Resource\Factory;
1515

1616
use ApiPlatform\Symfony\Bundle\DependencyInjection\Configuration;
1717
use PHPUnit\Framework\TestCase;
1818
use Symfony\Component\Config\Definition\Processor;
1919

2020
/**
21-
* Tests the defaults.parameters configuration option.
21+
* Tests the defaults.parameters configuration option used by ParameterValidationResourceMetadataCollectionFactory.
2222
*
2323
* @author Maxence Castel <maxence.castel59@gmail.com>
2424
*/
25-
final class ConfigurationDefaultParametersTest extends TestCase
25+
final class ParameterValidationConfigurationTest extends TestCase
2626
{
2727
private Configuration $configuration;
2828

0 commit comments

Comments
 (0)