Skip to content

Commit 7766881

Browse files
author
Thibaut Cholley
committed
refactor: introduce inputClass & outputClass
1 parent 61c6dee commit 7766881

19 files changed

Lines changed: 160 additions & 53 deletions

src/GraphQl/Serializer/SerializerContextBuilder.php

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@ public function create(?string $resourceClass, Operation $operation, array $reso
4040
}
4141

4242
$context['operation'] = $operation;
43-
if ($operation->getInput()) {
44-
$context['input'] = $operation->getInput();
45-
}
46-
if ($operation->getOutput()) {
47-
$context['output'] = $operation->getOutput();
48-
}
43+
$context['input'] = $operation->getInputClass() === $operation->getClass() ? null : ['class' => $operation->getInputClass()];
44+
$context['output'] = $operation->getOutputClass() === $operation->getClass() ? null : ['class' => $operation->getOutputClass()];
45+
// if (($inputClass = $operation->getInputClass()) !== $operation->getClass()) {
46+
// $context['input'] = ['class' => $inputClass];
47+
// }
48+
// if (($outputClass = $operation->getOutputClass()) !== $operation->getClass()) {
49+
// $context['output'] = ['class' => $outputClass];
50+
// }
4951
$context = $normalization ? array_merge($operation->getNormalizationContext() ?? [], $context) : array_merge($operation->getDenormalizationContext() ?? [], $context);
5052

5153
if ($normalization) {
@@ -99,7 +101,7 @@ private function replaceIdKeys(array $fields, ?string $resourceClass, array $con
99101
continue;
100102
}
101103

102-
$denormalizedFields[$this->denormalizePropertyName((string) $key, $resourceClass, $context)] = \is_array($value) ? $this->replaceIdKeys($value, $resourceClass, $context) : $value;
104+
$denormalizedFields[$this->denormalizePropertyName((string)$key, $resourceClass, $context)] = \is_array($value) ? $this->replaceIdKeys($value, $resourceClass, $context) : $value;
103105
}
104106

105107
return $denormalizedFields;

src/GraphQl/Type/TypeBuilder.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -311,15 +311,12 @@ private function getQueryOperation(ResourceMetadataCollection $resourceMetadataC
311311
private function getResourceObjectTypeConfiguration(string $shortName, ResourceMetadataCollection $resourceMetadataCollection, Operation $operation, array $context = []): InputObjectType|ObjectType
312312
{
313313
$operationName = $operation->getName();
314-
$resourceClass = $operation->getClass();
315314
$input = $context['input'];
316315
$depth = $context['depth'] ?? 0;
317316
$wrapped = $context['wrapped'] ?? false;
318317

319-
$ioMetadata = $input ? $operation->getInput() : $operation->getOutput();
320-
if (null !== $ioMetadata && \array_key_exists('class', $ioMetadata) && null !== $ioMetadata['class']) {
321-
$resourceClass = $ioMetadata['class'];
322-
}
318+
$resourceClass = $input ? $operation->getInputClass() : $operation->getOutputClass();
319+
$ioMetadata = $resourceClass ? ['class' => $resourceClass] : null;
323320

324321
$wrapData = !$wrapped && ($operation instanceof Mutation || $operation instanceof Subscription) && !$input && $depth < 1;
325322

src/Hydra/Serializer/DocumentationNormalizer.php

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,11 @@ private function getHydraProperties(string $resourceClass, ApiResource $resource
216216
continue;
217217
}
218218

219-
$inputMetadata = $operation->getInput();
220-
if (null !== $inputClass = $inputMetadata['class'] ?? null) {
219+
if (null !== ($inputClass = $operation->getInputClass())) {
221220
$classes[$inputClass] = true;
222221
}
223222

224-
$outputMetadata = $operation->getOutput();
225-
if (null !== $outputClass = $outputMetadata['class'] ?? null) {
223+
if (null !== ($outputClass = $operation->getOutputClass())) {
226224
$classes[$outputClass] = true;
227225
}
228226
}
@@ -288,11 +286,8 @@ private function getHydraOperation(HttpOperation $operation, string $prefixedSho
288286
}
289287

290288
$shortName = $operation->getShortName();
291-
$inputMetadata = $operation->getInput() ?? [];
292-
$outputMetadata = $operation->getOutput() ?? [];
293-
294-
$inputClass = \array_key_exists('class', $inputMetadata) ? $inputMetadata['class'] : false;
295-
$outputClass = \array_key_exists('class', $outputMetadata) ? $outputMetadata['class'] : false;
289+
$inputClass = $operation->getInputClass();
290+
$outputClass = $operation->getOutputClass();
296291

297292
if ('GET' === $method && $operation instanceof CollectionOperationInterface) {
298293
$hydraOperation += [

src/JsonSchema/ResourceMetadataTrait.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,10 @@ trait ResourceMetadataTrait
2929

3030
private function findOutputClass(string $className, string $type, Operation $operation, ?array $serializerContext): ?string
3131
{
32-
$inputOrOutput = ['class' => $className];
33-
$inputOrOutput = Schema::TYPE_OUTPUT === $type ? ($operation->getOutput() ?? $inputOrOutput) : ($operation->getInput() ?? $inputOrOutput);
32+
$resourceClass = (Schema::TYPE_OUTPUT === $type ? $operation->getOutputClass() : $operation->getInputClass()) ?? $className;
3433
$forceSubschema = $serializerContext[SchemaFactory::FORCE_SUBSCHEMA] ?? false;
3534

36-
return $forceSubschema ? ($inputOrOutput['class'] ?? $inputOrOutput->class ?? $operation->getClass()) : ($inputOrOutput['class'] ?? $inputOrOutput->class ?? null);
35+
return $forceSubschema ? ($resourceClass ?? $operation->getClass()) : $resourceClass;
3736
}
3837

3938
private function findOperation(string $className, string $type, ?Operation $operation, ?array $serializerContext, ?string $format = null): Operation

src/Mcp/Capability/Registry/Loader.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ public function load(RegistryInterface $registry): void
4949
foreach ($metadata as $resource) {
5050
foreach ($resource->getMcp() ?? [] as $mcp) {
5151
if ($mcp instanceof McpTool) {
52-
$inputClass = $mcp->getInput()['class'] ?? $mcp->getClass();
52+
$inputClass = $mcp->getInputClass();
5353
$inputFormat = array_key_first($mcp->getInputFormats() ?? ['json' => ['application/json']]);
5454
$inputSchema = $this->schemaFactory->buildSchema($inputClass, $inputFormat, Schema::TYPE_INPUT, $mcp, null, [SchemaFactory::FORCE_SUBSCHEMA => true]);
5555

5656
$outputSchema = null;
5757
if (false !== $mcp->getStructuredContent()) {
58-
$outputClass = $mcp->getOutput()['class'] ?? $mcp->getClass();
58+
$outputClass = $mcp->getOutputClass();
5959
$outputFormat = array_key_first($mcp->getOutputFormats() ?? ['json' => ['application/json']]);
6060
$outputSchema = $this->schemaFactory->buildSchema($outputClass, $outputFormat, Schema::TYPE_OUTPUT, $mcp, null, [SchemaFactory::FORCE_SUBSCHEMA => true])->getArrayCopy();
6161
}

src/Mcp/State/ToolProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
3535
}
3636

3737
$data = (object) $context['mcp_data'];
38-
$class = $operation->getInput()['class'] ?? $operation->getClass();
38+
$class = $operation->getInputClass();
3939

4040
return $this->objectMapper->map($data, $class);
4141
}

src/Metadata/ApiResource.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ class ApiResource extends Metadata
4848
* @param mixed|null $mercure
4949
* @param mixed|null $messenger
5050
* @param mixed|null $input
51+
* @param string|null $inputClass
5152
* @param mixed|null $output
53+
* @param string|null $outputClass
5254
* @param array<string, McpResource|McpTool>|null $mcp A list of Mcp resources or tools
5355
*/
5456
public function __construct(
@@ -430,8 +432,16 @@ public function __construct(
430432
* @var string|bool|null
431433
*/
432434
protected $messenger = null,
435+
/**
436+
* @deprecated use inputClass instead
437+
*/
433438
protected $input = null,
439+
protected ?string $inputClass = null,
440+
/**
441+
* @deprecated use outputClass instead
442+
*/
434443
protected $output = null,
444+
protected ?string $outputClass = null,
435445
/**
436446
* Override the default order of items in your collection. Note that this is handled by our doctrine filters such as
437447
* the [OrderFilter](/docs/reference/Doctrine/Orm/Filter/OrderFilter).
@@ -988,7 +998,9 @@ class: $class,
988998
mercure: $mercure,
989999
messenger: $messenger,
9901000
input: $input,
1001+
inputClass: $inputClass,
9911002
output: $output,
1003+
outputClass: $outputClass,
9921004
order: $order,
9931005
fetchPartial: $fetchPartial,
9941006
forceEager: $forceEager,

src/Metadata/Metadata.php

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ abstract class Metadata
2929
* @param string|\Stringable|null $securityPostDenormalize https://api-platform.com/docs/core/security/#executing-access-control-rules-after-denormalization
3030
* @param mixed|null $mercure
3131
* @param mixed|null $messenger
32-
* @param mixed|null $input
33-
* @param mixed|null $output
32+
* @param mixed|null $input @deprecated use inputClass instead
33+
* @param mixed|null $inputClass
34+
* @param mixed|null $output @deprecated use outputClass instead
35+
* @param mixed|null $outputClass
3436
* @param mixed|null $provider
3537
* @param mixed|null $processor
3638
* @param Parameters|array<string, Parameter> $parameters
@@ -50,7 +52,9 @@ public function __construct(
5052
protected $mercure = null,
5153
protected $messenger = null,
5254
protected $input = null,
55+
protected ?string $inputClass = null,
5356
protected $output = null,
57+
protected ?string $outputClass = null,
5458
protected ?array $order = null,
5559
protected ?bool $fetchPartial = null,
5660
protected ?bool $forceEager = null,
@@ -272,26 +276,108 @@ public function withMessenger(mixed $messenger): static
272276
return $self;
273277
}
274278

279+
/**
280+
* @deprecated use getInputClass() instead
281+
*/
275282
public function getInput(): mixed
276283
{
284+
trigger_deprecation('api-platform/metadata', '4.3', 'The method "getInput()" is deprecated, use "getInputClass()" instead.');
285+
277286
return $this->input;
278287
}
279288

289+
/**
290+
* @deprecated use withInputClass() instead
291+
*/
280292
public function withInput(mixed $input): static
281293
{
294+
trigger_deprecation('api-platform/metadata', '4.3', 'The method "withInput()" is deprecated, use "withInputClass()" instead.');
295+
282296
$self = clone $this;
283297
$self->input = $input;
284298

285299
return $self;
286300
}
287301

302+
public function getInputClass(): ?string
303+
{
304+
if (null !== $this->inputClass) {
305+
return $this->inputClass;
306+
}
307+
308+
if (false === $this->input) {
309+
return null;
310+
}
311+
312+
if (\is_array($this->input) && \is_string($this->input['class'] ?? null)) {
313+
return $this->input['class'];
314+
}
315+
316+
if (null === $this->input) {
317+
return $this->getClass();
318+
}
319+
320+
return null;
321+
}
322+
323+
/**
324+
* @param class-string|null $inputClass
325+
* @return $this
326+
*/
327+
public function withInputClass(?string $inputClass): static
328+
{
329+
$self = clone $this;
330+
$self->inputClass = $inputClass;
331+
332+
return $self;
333+
}
334+
335+
public function getOutputClass(): ?string
336+
{
337+
if (null !== $this->outputClass) {
338+
return $this->outputClass;
339+
}
340+
341+
if (false === $this->output) {
342+
return null;
343+
}
344+
345+
if (\is_array($this->output) && \is_string($this->output['class'] ?? null)) {
346+
return $this->output['class'];
347+
}
348+
349+
if (null === $this->output) {
350+
return $this->getClass();
351+
}
352+
353+
return null;
354+
}
355+
356+
public function withOutputClass(?string $outputClass): static
357+
{
358+
$self = clone $this;
359+
$self->outputClass = $outputClass;
360+
361+
return $self;
362+
}
363+
364+
/**
365+
* @deprecated use getOutputClass() instead
366+
*/
288367
public function getOutput(): mixed
289368
{
369+
trigger_deprecation('api-platform/metadata', '4.3', 'The method "getOutput()" is deprecated, use "getOutputClass()" instead.');
370+
290371
return $this->output;
291372
}
292373

374+
/**
375+
* @deprecated use withOutputClass() instead
376+
*/
293377
public function withOutput(mixed $output): static
294378
{
379+
trigger_deprecation('api-platform/metadata', '4.3', 'The method "withOutput()" is deprecated, use "withOutputClass()" instead.');
380+
295381
$self = clone $this;
296382
$self->output = $output;
297383

src/Metadata/Operation.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,8 +729,16 @@ public function __construct(
729729
* For more examples, read our guide on [validation](/guides/validation).
730730
*/
731731
protected ?array $validationContext = null,
732+
/**
733+
* @deprecated use inputClass instead
734+
*/
732735
protected $input = null,
736+
protected ?string $inputClass = null,
737+
/**
738+
* @deprecated use outputClass instead
739+
*/
733740
protected $output = null,
741+
protected ?string $outputClass = null,
734742
protected $mercure = null,
735743
/**
736744
* The `messenger` option dispatches the current resource through the Message Bus.
@@ -831,7 +839,9 @@ class: $class,
831839
mercure: $mercure,
832840
messenger: $messenger,
833841
input: $input,
842+
inputClass: $inputClass,
834843
output: $output,
844+
outputClass: $outputClass,
835845
order: $order,
836846
fetchPartial: $fetchPartial,
837847
forceEager: $forceEager,

src/Metadata/Resource/Factory/InputOutputResourceMetadataCollectionFactory.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ public function create(string $resourceClass): ResourceMetadataCollection
3737
$resourceMetadataCollection = $this->decorated->create($resourceClass);
3838

3939
foreach ($resourceMetadataCollection as $key => $resourceMetadata) {
40-
$resourceMetadata = $resourceMetadata->withInput($this->transformInputOutput($resourceMetadata->getInput()));
41-
$resourceMetadata = $resourceMetadata->withOutput($this->transformInputOutput($resourceMetadata->getOutput()));
40+
$resourceMetadata = $resourceMetadata->withInputClass($this->transformInputOutput($resourceMetadata->getInput())['class'] ?? null);
41+
$resourceMetadata = $resourceMetadata->withOutputClass($this->transformInputOutput($resourceMetadata->getOutput())['class'] ?? null);
4242

4343
if ($resourceMetadata->getOperations()) {
4444
$resourceMetadata = $resourceMetadata->withOperations($this->getTransformedOperations($resourceMetadata->getOperations(), $resourceMetadata));
@@ -61,23 +61,19 @@ public function create(string $resourceClass): ResourceMetadataCollection
6161
private function getTransformedOperations(Operations|array $operations, ApiResource $resourceMetadata): Operations|array
6262
{
6363
foreach ($operations as $key => $operation) {
64-
$operation = $operation->withInput(null !== $operation->getInput() ? $this->transformInputOutput($operation->getInput()) : $resourceMetadata->getInput());
65-
$operation = $operation->withOutput(null !== $operation->getOutput() ? $this->transformInputOutput($operation->getOutput()) : $resourceMetadata->getOutput());
64+
$operation = $operation->withInputClass(null !== $operation->getInput() ? ($this->transformInputOutput($operation->getInput())['class'] ?? null) : $resourceMetadata->getInputClass());
65+
$operation = $operation->withOutputClass(null !== $operation->getOutput() ? ($this->transformInputOutput($operation->getOutput())['class'] ?? null) : $resourceMetadata->getOutputClass());
6666

6767
if (
68-
$operation->getInput()
69-
&& \array_key_exists('class', $operation->getInput())
70-
&& null === $operation->getInput()['class']
68+
null === $operation->getInputClass()
7169
) {
7270
$operation = $operation->withDeserialize(null === $operation->canDeserialize() ? false : $operation->canDeserialize());
7371
$operation = $operation->withValidate(null === $operation->canValidate() ? false : $operation->canValidate());
7472
}
7573

7674
if (
7775
$operation instanceof HttpOperation
78-
&& $operation->getOutput()
79-
&& \array_key_exists('class', $operation->getOutput())
80-
&& null === $operation->getOutput()['class']
76+
&& null === $operation->getOutputClass()
8177
&& null === $operation->getStatus()
8278
) {
8379
$operation = $operation->withStatus(204);

0 commit comments

Comments
 (0)