[graphql] custom field resolver, fixes #1089

This commit is contained in:
Shish 2024-02-25 19:29:33 +00:00 committed by Shish
parent d2df6fc50f
commit b9c7d632fd
3 changed files with 48 additions and 13 deletions

View file

@ -130,9 +130,7 @@ class Image implements \ArrayAccess
public function offsetExists(mixed $offset): bool public function offsetExists(mixed $offset): bool
{ {
assert(is_string($offset)); assert(is_string($offset));
// property_exists is a workaround for return array_key_exists($offset, static::$prop_types);
// https://github.com/webonyx/graphql-php/pull/1531
return array_key_exists($offset, static::$prop_types) || property_exists($this, $offset);
} }
public function offsetGet(mixed $offset): mixed public function offsetGet(mixed $offset): mixed
{ {
@ -141,9 +139,7 @@ class Image implements \ArrayAccess
$known = implode(", ", array_keys(static::$prop_types)); $known = implode(", ", array_keys(static::$prop_types));
throw new \OutOfBoundsException("Undefined dynamic property: $offset (Known: $known)"); throw new \OutOfBoundsException("Undefined dynamic property: $offset (Known: $known)");
} }
// property lookup is a workaround for return $this->dynamic_props[$offset] ?? null;
// https://github.com/webonyx/graphql-php/pull/1531
return $this->dynamic_props[$offset] ?? $this->$offset ?? null;
} }
public function offsetSet(mixed $offset, mixed $value): void public function offsetSet(mixed $offset, mixed $value): void
{ {

View file

@ -40,6 +40,37 @@ class MetadataInput
} }
} }
function shmFieldResolver(
mixed $objectValue,
mixed $args,
mixed $context,
\GraphQL\Type\Definition\ResolveInfo $info
): mixed {
$fieldName = $info->fieldName;
$property = null;
if (is_array($objectValue)) {
if (isset($objectValue[$fieldName])) {
$property = $objectValue[$fieldName];
}
} elseif ($objectValue instanceof \ArrayAccess) {
if (isset($objectValue->{$fieldName})) {
$property = $objectValue->{$fieldName};
} elseif (isset($objectValue[$fieldName])) {
$property = $objectValue[$fieldName];
}
} elseif (is_object($objectValue)) {
if (isset($objectValue->{$fieldName})) {
$property = $objectValue->{$fieldName};
}
}
return $property instanceof \Closure
? $property($objectValue, $args, $context, $info)
: $property;
}
class GraphQL extends Extension class GraphQL extends Extension
{ {
public static function get_schema(): Schema public static function get_schema(): Schema
@ -90,6 +121,7 @@ class GraphQL extends Extension
$t1 = ftime(); $t1 = ftime();
$server = new StandardServer([ $server = new StandardServer([
'schema' => $this->get_schema(), 'schema' => $this->get_schema(),
'fieldResolver' => "\Shimmie2\shmFieldResolver",
]); ]);
$t2 = ftime(); $t2 = ftime();
$resp = $server->executeRequest(); $resp = $server->executeRequest();
@ -197,7 +229,7 @@ class GraphQL extends Extension
$schema = $this->get_schema(); $schema = $this->get_schema();
$t2 = ftime(); $t2 = ftime();
$debug = DebugFlag::INCLUDE_DEBUG_MESSAGE | DebugFlag::RETHROW_INTERNAL_EXCEPTIONS; $debug = DebugFlag::INCLUDE_DEBUG_MESSAGE | DebugFlag::RETHROW_INTERNAL_EXCEPTIONS;
$body = GQL::executeQuery($schema, $query)->toArray($debug); $body = GQL::executeQuery($schema, $query, fieldResolver: "\Shimmie2\shmFieldResolver")->toArray($debug);
$t3 = ftime(); $t3 = ftime();
$body['stats'] = get_debug_info_arr(); $body['stats'] = get_debug_info_arr();
$body['stats']['graphql_schema_time'] = round($t2 - $t1, 2); $body['stats']['graphql_schema_time'] = round($t2 - $t1, 2);

View file

@ -16,13 +16,23 @@ class GraphQLTest extends ShimmiePHPUnitTestCase
$this->assertTrue(true); $this->assertTrue(true);
} }
/**
* @return array<string, mixed>
*/
protected function graphql(string $query): array
{
$schema = GraphQL::get_schema();
$debug = DebugFlag::INCLUDE_DEBUG_MESSAGE | DebugFlag::RETHROW_INTERNAL_EXCEPTIONS;
return GQL::executeQuery($schema, $query, fieldResolver: "\Shimmie2\shmFieldResolver")->toArray($debug);
}
public function testQuery(): void public function testQuery(): void
{ {
$this->log_in_as_user(); $this->log_in_as_user();
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "test"); $image_id = $this->post_image("tests/pbx_screenshot.jpg", "test");
$image = Image::by_id_ex($image_id); $image = Image::by_id($image_id);
$query = '{ $result = $this->graphql('{
posts(limit: 3, offset: 0) { posts(limit: 3, offset: 0) {
id id
post_id post_id
@ -33,10 +43,7 @@ class GraphQLTest extends ShimmiePHPUnitTestCase
name name
} }
} }
}'; }');
$schema = GraphQL::get_schema();
$debug = DebugFlag::INCLUDE_DEBUG_MESSAGE | DebugFlag::RETHROW_INTERNAL_EXCEPTIONS;
$result = GQL::executeQuery($schema, $query)->toArray($debug);
$this->assertEquals([ $this->assertEquals([
'data' => [ 'data' => [