Skip to content

Commit 9f672b0

Browse files
committed
temp
1 parent 0e657d1 commit 9f672b0

File tree

1 file changed

+93
-96
lines changed

1 file changed

+93
-96
lines changed

src/GraphQl/Type/FieldsBuilder.php

Lines changed: 93 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,60 @@ public function resolveResourceArgs(array $args, Operation $operation): array
311311
return $args;
312312
}
313313

314+
/**
315+
* Transform the result of a parse_str to a GraphQL object type.
316+
* We should consider merging getFilterArgs and this, `getFilterArgs` uses `convertType` whereas we assume that parameters have only scalar types.
317+
* Note that this method has a lower complexity then the `getFilterArgs` one.
318+
* TODO: Is there a use case with an argument being a complex type (eg: a Resource, Enum etc.)?
319+
*
320+
* @param array<array{name: string, required: bool|null, description: string|null, leafs: string|array, type: string}> $flattenFields
321+
*/
322+
private function parameterToObjectType(array $flattenFields, string $name): InputObjectType
323+
{
324+
$fields = [];
325+
foreach ($flattenFields as $field) {
326+
$key = $field['name'];
327+
$type = \in_array($field['type'], TypeIdentifier::values(), true) ? Type::builtin($field['type']) : Type::object($field['type']);
328+
if (!$field['required']) {
329+
$type = Type::nullable($type);
330+
}
331+
332+
$type = $this->getParameterType($type);
333+
if (\is_array($l = $field['leafs'])) {
334+
if (0 === key($l)) {
335+
$key = $key;
336+
$type = GraphQLType::listOf($type);
337+
} else {
338+
$n = [];
339+
foreach ($field['leafs'] as $l => $value) {
340+
$n[] = ['required' => null, 'name' => $l, 'leafs' => $value, 'type' => 'string', 'description' => null];
341+
}
342+
343+
$type = $this->parameterToObjectType($n, $key);
344+
if (isset($fields[$key]) && ($t = $fields[$key]['type']) instanceof InputObjectType) {
345+
$t = $fields[$key]['type'];
346+
$t->config['fields'] = array_merge($t->config['fields'], $type->config['fields']);
347+
$type = $t;
348+
}
349+
}
350+
}
351+
352+
if ($field['required']) {
353+
$type = GraphQLType::nonNull($type);
354+
}
355+
356+
if (isset($fields[$key])) {
357+
if ($type instanceof ListOfType) {
358+
$key .= '_list';
359+
}
360+
}
361+
362+
$fields[$key] = ['type' => $type, 'name' => $key];
363+
}
364+
365+
return new InputObjectType(['name' => $name, 'fields' => $fields]);
366+
}
367+
314368
/**
315369
* A simplified version of convert type that does not support resources.
316370
*/
@@ -445,92 +499,57 @@ private function getParameterArgs(Operation $operation, array $args = []): array
445499
{
446500
foreach ($operation->getParameters() ?? [] as $parameter) {
447501
$key = $parameter->getKey();
448-
$property = $parameter->getProperty();
449-
450-
$matchFound = false;
451-
452-
if ($filter = $this->getFilterInstance($parameter->getFilter())) {
453-
foreach ($filter->getDescription($operation->getClass()) as $name => $value) {
454-
// Check if this description entry matches the current parameter's property
455-
if ($property && ($value['property'] ?? null) === $property) {
456-
$matchFound = true;
457-
458-
$suffix = '';
459-
if (str_starts_with($name, $property)) {
460-
$suffix = substr($name, \strlen($property));
461-
}
462-
463-
$argName = $key.$suffix;
464502

465-
$type = \in_array($value['type'] ?? 'string', TypeIdentifier::values(), true) ? Type::builtin($value['type'] ?? 'string') : Type::object($value['type'] ?? 'string');
503+
if (!str_contains($key, ':property')) {
504+
$args[$key] = ['type' => GraphQLType::string()];
466505

467-
if (!($value['required'] ?? false)) {
468-
$type = Type::nullable($type);
469-
}
470-
471-
$graphQlType = $this->getParameterType($type);
506+
if ($parameter->getRequired()) {
507+
$args[$key]['type'] = GraphQLType::nonNull($args[$key]['type']);
508+
}
472509

473-
parse_str($argName, $parsed);
474-
array_walk_recursive($parsed, static function (&$v) use ($graphQlType): void {
475-
$v = $graphQlType;
476-
});
510+
continue;
511+
}
477512

478-
$args = $this->mergeFilterArgs($args, $parsed, $operation, $key);
479-
}
480-
}
513+
if (!($filterId = $parameter->getFilter()) || !$this->filterLocator->has($filterId)) {
514+
continue;
515+
}
481516

482-
if ($filter instanceof OpenApiParameterFilterInterface) {
483-
foreach ($filter->getOpenApiParameters($parameter) as $value) {
484-
$matchFound = true;
485-
$suffix = '';
486-
if ($property && str_starts_with($value->getName(), $property)) {
487-
$suffix = substr($value->getName(), \strlen($property));
488-
}
517+
$filter = $this->filterLocator->get($filterId);
518+
$parsedKey = explode('[:property]', $key);
519+
$flattenFields = [];
489520

490-
$argName = $key.$suffix;
491-
$type = \in_array($value->getSchema()['type'] ?? 'string', TypeIdentifier::values(), true) ? Type::builtin($value->getSchema()['type'] ?? 'string') : Type::object($value->getSchema()['type'] ?? 'string');
492-
if (!$value->getRequired()) {
493-
$type = Type::nullable($type);
494-
}
495-
$graphQlType = $this->getParameterType($type);
496-
parse_str($argName, $parsed);
497-
array_walk_recursive($parsed, static function (&$v) use ($graphQlType): void {
498-
$v = $graphQlType;
499-
});
500-
$args = $this->mergeFilterArgs($args, $parsed, $operation, $key);
521+
if ($filter instanceof FilterInterface) {
522+
foreach ($filter->getDescription($operation->getClass()) as $name => $value) {
523+
$values = [];
524+
parse_str($name, $values);
525+
if (isset($values[$parsedKey[0]])) {
526+
$values = $values[$parsedKey[0]];
501527
}
502-
}
503-
}
504528

505-
if (!$matchFound) {
506-
$type = GraphQLType::string();
507-
if ($parameter->getNativeType()) {
508-
$type = $this->getParameterType($parameter->getNativeType());
529+
$name = key($values);
530+
$flattenFields[] = ['name' => $name, 'required' => $value['required'] ?? null, 'description' => $value['description'] ?? null, 'leafs' => $values[$name], 'type' => $value['type'] ?? 'string'];
509531
}
510532

511-
$arg = ['type' => $type];
533+
$args[$parsedKey[0]] = $this->parameterToObjectType($flattenFields, $parsedKey[0]);
534+
}
512535

513-
if ($parameter->getRequired()) {
514-
$arg['type'] = GraphQLType::nonNull($arg['type']);
515-
}
536+
if ($filter instanceof OpenApiParameterFilterInterface) {
537+
foreach ($filter->getOpenApiParameters($parameter) as $value) {
538+
$values = [];
539+
parse_str($value->getName(), $values);
540+
if (isset($values[$parsedKey[0]])) {
541+
$values = $values[$parsedKey[0]];
542+
}
516543

517-
if ($parameter->getDescription()) {
518-
$arg['description'] = $parameter->getDescription();
544+
$name = key($values);
545+
$flattenFields[] = ['name' => $name, 'required' => $value->getRequired(), 'description' => $value->getDescription(), 'leafs' => $values[$name], 'type' => $value->getSchema()['type'] ?? 'string'];
519546
}
520547

521-
if (str_contains($key, '[')) {
522-
parse_str($key, $parsed);
523-
array_walk_recursive($parsed, static function (&$v) use ($arg): void {
524-
$v = $arg['type'];
525-
});
526-
$args = $this->mergeFilterArgs($args, $parsed, $operation, $key);
527-
} else {
528-
$args[$key] = $arg;
529-
}
548+
$args[$parsedKey[0]] = $this->parameterToObjectType($flattenFields, $parsedKey[0].$operation->getShortName().$operation->getName());
530549
}
531550
}
532551

533-
return $this->convertFilterArgsToTypes($args);
552+
return $args;
534553
}
535554

536555
private function getGraphQlPaginationArgs(Operation $queryOperation): array
@@ -627,10 +646,10 @@ private function mergeFilterArgs(array $args, array $parsed, ?Operation $operati
627646
}
628647

629648
if (\is_array($value)) {
630-
$value = $this->mergeFilterArgs($args[$key] ?? [], $value, $operation, $original);
649+
$value = $this->mergeFilterArgs($args[$key] ?? [], $value);
631650
if (!isset($value['#name'])) {
632651
$name = (false === $pos = strrpos($original, '[')) ? $original : substr($original, 0, (int) $pos);
633-
$value['#name'] = $name.($operation ? $operation->getShortName().$operation->getName() : '');
652+
$value['#name'] = ($operation ? $operation->getShortName() : '').'Filter_'.strtr($name, ['[' => '_', ']' => '', '.' => '__']);
634653
}
635654
}
636655

@@ -664,10 +683,10 @@ private function convertFilterArgsToTypes(array $args): array
664683

665684
unset($value['#name']);
666685

667-
$filterArgType = new InputObjectType([
686+
$filterArgType = GraphQLType::listOf(new InputObjectType([
668687
'name' => $name,
669688
'fields' => $this->convertFilterArgsToTypes($value),
670-
]);
689+
]));
671690

672691
$this->typesContainer->set($name, $filterArgType);
673692

@@ -723,27 +742,5 @@ private function normalizePropertyName(string $property, string $resourceClass):
723742

724743
return $this->nameConverter->normalize($property, $resourceClass);
725744
}
726-
727-
private function getFilterInstance(object|string|null $filter): ?FilterInterface
728-
{
729-
if (!$filter) {
730-
return null;
731-
}
732-
733-
if (\is_object($filter)) {
734-
return $filter instanceof FilterInterface ? $filter : null;
735-
}
736-
737-
if (!$this->filterLocator->has($filter)) {
738-
return null;
739-
}
740-
741-
$filter = $this->filterLocator->get($filter);
742-
743-
if (!$filter instanceof FilterInterface) {
744-
return null;
745-
}
746-
747-
return $filter;
748-
}
749745
}
746+

0 commit comments

Comments
 (0)