Skip to content

Commit

Permalink
feat(graphql): parameter graphql arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
soyuka committed Mar 27, 2024
1 parent 8cfefb9 commit 566fce2
Showing 1 changed file with 113 additions and 5 deletions.
118 changes: 113 additions & 5 deletions src/GraphQl/Type/FieldsBuilder.php
Expand Up @@ -290,9 +290,108 @@ public function resolveResourceArgs(array $args, Operation $operation): array
$args[$id]['type'] = $this->typeConverter->resolveType($arg['type']);
}

foreach ($operation->getParameters() ?? [] as $parameter) {
$key = $parameter->getKey();

Check warning on line 294 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L293-L294

Added lines #L293 - L294 were not covered by tests

if (str_contains($key, ':property')) {
if (!($filterId = $parameter->getFilter()) || !$this->filterLocator->has($filterId)) {
continue;

Check warning on line 298 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L296-L298

Added lines #L296 - L298 were not covered by tests
}

$parsedKey = explode('[:property]', $key);
$flattenFields = [];
foreach ($this->filterLocator->get($filterId)->getDescription($operation->getClass()) as $key => $value) {
$values = [];
parse_str($key, $values);
if (isset($values[$parsedKey[0]])) {
$values = $values[$parsedKey[0]];

Check warning on line 307 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L301-L307

Added lines #L301 - L307 were not covered by tests
}

$name = key($values);
$flattenFields[] = ['name' => $name, 'required' => $value['required'] ?? null, 'description' => $value['description'] ?? null, 'leafs' => $values[$name], 'type' => $value['type'] ?? 'string'];

Check warning on line 311 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L310-L311

Added lines #L310 - L311 were not covered by tests
}

$args[$parsedKey[0]] = $this->parameterToObjectType($flattenFields, $parsedKey[0]);
continue;

Check warning on line 315 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L314-L315

Added lines #L314 - L315 were not covered by tests
}

$args[$key] = ['type' => GraphQLType::string()];

Check warning on line 318 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L318

Added line #L318 was not covered by tests

if ($parameter->getRequired()) {
$args[$key]['type'] = GraphQLType::nonNull($args[$key]['type']);

Check warning on line 321 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L320-L321

Added lines #L320 - L321 were not covered by tests
}
}

return $args;
}

/**
* Transform the result of a parse_str to a GraphQL object type.
* We should consider merging getFilterArgs and this, `getFilterArgs` uses `convertType` whereas we assume that parameters have only scalar types.
* Note that this method has a lower complexity then the `getFilterArgs` one.
* TODO: Is there a use case with an argument being a complex type (eg: a Resource, Enum etc.)?
*
* @param array<array{name: string, required: bool|null, description: string|null, leafs: string|array, type: string}> $flattenFields
*/
private function parameterToObjectType(array $flattenFields, string $name): InputObjectType

Check warning on line 336 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L336

Added line #L336 was not covered by tests
{
$fields = [];
foreach ($flattenFields as $field) {
$key = $field['name'];
$type = $this->getParameterType(\in_array($field['type'], Type::$builtinTypes, true) ? new Type($field['type'], !$field['required']) : new Type('object', !$field['required'], $field['type']));

Check warning on line 341 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L338-L341

Added lines #L338 - L341 were not covered by tests

if (\is_array($l = $field['leafs'])) {
if (0 === key($l)) {
$key = $key;
$type = GraphQLType::listOf($type);

Check warning on line 346 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L343-L346

Added lines #L343 - L346 were not covered by tests
} else {
$n = [];
foreach ($field['leafs'] as $l => $value) {
$n[] = ['required' => null, 'name' => $l, 'leafs' => $value, 'type' => 'string', 'description' => null];

Check warning on line 350 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L348-L350

Added lines #L348 - L350 were not covered by tests
}

$type = $this->parameterToObjectType($n, $key);
if (isset($fields[$key]) && ($t = $fields[$key]['type']) instanceof InputObjectType) {
$t = $fields[$key]['type'];
$t->config['fields'] = array_merge($t->config['fields'], $type->config['fields']);
$type = $t;

Check warning on line 357 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L353-L357

Added lines #L353 - L357 were not covered by tests
}
}
}

if ($field['required']) {
$type = GraphQLType::nonNull($type);

Check warning on line 363 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L362-L363

Added lines #L362 - L363 were not covered by tests
}

if (isset($fields[$key])) {
if ($type instanceof ListOfType) {
$key .= '_list';

Check warning on line 368 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L366-L368

Added lines #L366 - L368 were not covered by tests
}
}

$fields[$key] = ['type' => $type, 'name' => $key];

Check warning on line 372 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L372

Added line #L372 was not covered by tests
}

return new InputObjectType(['name' => $name, 'fields' => $fields]);

Check warning on line 375 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L375

Added line #L375 was not covered by tests
}

/**
* A simplified version of convert type that does not support resources.
*/
private function getParameterType(Type $type): GraphQLType

Check warning on line 381 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L381

Added line #L381 was not covered by tests
{
return match ($type->getBuiltinType()) {
Type::BUILTIN_TYPE_BOOL => GraphQLType::boolean(),
Type::BUILTIN_TYPE_INT => GraphQLType::int(),
Type::BUILTIN_TYPE_FLOAT => GraphQLType::float(),
Type::BUILTIN_TYPE_STRING => GraphQLType::string(),
Type::BUILTIN_TYPE_ARRAY => GraphQLType::listOf($this->getParameterType($type->getCollectionValueTypes()[0])),
Type::BUILTIN_TYPE_ITERABLE => GraphQLType::listOf($this->getParameterType($type->getCollectionValueTypes()[0])),
Type::BUILTIN_TYPE_OBJECT => GraphQLType::string(),
default => GraphQLType::string(),
};

Check warning on line 392 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L383-L392

Added lines #L383 - L392 were not covered by tests
}

/**
* Get the field configuration of a resource.
*
Expand Down Expand Up @@ -433,6 +532,7 @@ private function getFilterArgs(array $args, ?string $resourceClass, string $root
if (null === $resourceClass) {
return $args;
}
$d = false;

Check warning on line 535 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L535

Added line #L535 was not covered by tests

foreach ($resourceOperation->getFilters() ?? [] as $filterId) {
if (!$this->filterLocator->has($filterId)) {
Expand All @@ -450,9 +550,9 @@ private function getFilterArgs(array $args, ?string $resourceClass, string $root
}
}

foreach ($this->filterLocator->get($filterId)->getDescription($entityClass) as $key => $value) {
$nullable = isset($value['required']) ? !$value['required'] : true;
$filterType = \in_array($value['type'], Type::$builtinTypes, true) ? new Type($value['type'], $nullable) : new Type('object', $nullable, $value['type']);
foreach ($this->filterLocator->get($filterId)->getDescription($entityClass) as $key => $description) {
$nullable = isset($description['required']) ? !$description['required'] : true;
$filterType = \in_array($description['type'], Type::$builtinTypes, true) ? new Type($description['type'], $nullable) : new Type('object', $nullable, $description['type']);

Check warning on line 555 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L553-L555

Added lines #L553 - L555 were not covered by tests
$graphqlFilterType = $this->convertType($filterType, false, $resourceOperation, $rootOperation, $resourceClass, $rootResource, $property, $depth);

if (str_ends_with($key, '[]')) {
Expand All @@ -467,13 +567,21 @@ private function getFilterArgs(array $args, ?string $resourceClass, string $root
if (\array_key_exists($key, $parsed) && \is_array($parsed[$key])) {
$parsed = [$key => ''];
}
array_walk_recursive($parsed, static function (&$value) use ($graphqlFilterType): void {
$value = $graphqlFilterType;
array_walk_recursive($parsed, static function (&$v) use ($graphqlFilterType): void {
$v = $graphqlFilterType;

Check warning on line 571 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L570-L571

Added lines #L570 - L571 were not covered by tests
});
$args = $this->mergeFilterArgs($args, $parsed, $resourceOperation, $key);

if (str_contains($filterId, 'order')) {
$d = true;

Check warning on line 576 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L575-L576

Added lines #L575 - L576 were not covered by tests
}
}
}

if (true === $d) {

Check warning on line 581 in src/GraphQl/Type/FieldsBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/GraphQl/Type/FieldsBuilder.php#L581

Added line #L581 was not covered by tests
// dd($this->convertFilterArgsToTypes($args));
}

return $this->convertFilterArgsToTypes($args);
}

Expand Down

0 comments on commit 566fce2

Please sign in to comment.