From af00a4ee516fb8896a28d95b02600d7a1fe4b95a Mon Sep 17 00:00:00 2001 From: Aaron Carlino Date: Mon, 25 Oct 2021 20:36:52 +1300 Subject: [PATCH 1/4] NEW: Allow id field to be customised on update, delete --- src/Schema/DataObject/DeleteCreator.php | 16 ++++++++++++---- src/Schema/DataObject/UpdateCreator.php | 17 +++++++++++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/Schema/DataObject/DeleteCreator.php b/src/Schema/DataObject/DeleteCreator.php index cdf30920d..1ba6222ff 100644 --- a/src/Schema/DataObject/DeleteCreator.php +++ b/src/Schema/DataObject/DeleteCreator.php @@ -40,6 +40,7 @@ public function createOperation( ): ?ModelOperation { $plugins = $config['plugins'] ?? []; $mutationName = $config['name'] ?? null; + $idField = $config['idField'] ?? 'id'; if (!$mutationName) { $pluraliser = $model->getSchemaConfig()->getPluraliser(); $suffix = $pluraliser ? $pluraliser($typeName) : $typeName; @@ -52,6 +53,7 @@ public function createOperation( ->setResolver([static::class, 'resolve']) ->setResolverContext([ 'dataClass' => $model->getSourceClass(), + 'idField' => $idField, ]) ->addArg('ids', '[ID]!'); } @@ -63,15 +65,21 @@ public function createOperation( public static function resolve(array $resolverContext = []): Closure { $dataClass = $resolverContext['dataClass'] ?? null; - return function ($obj, array $args, array $context, ResolveInfo $info) use ($dataClass) { + $idField = $resolverContext['idField'] ?? 'id'; + return function ($obj, array $args, array $context, ResolveInfo $info) use ($dataClass, $idField) { if (!$dataClass) { return null; } $ids = []; - DB::get_conn()->withTransaction(function () use ($args, $context, $info, $dataClass, $ids) { + DB::get_conn()->withTransaction(function () use ($args, $context, $info, $dataClass, $ids, $idField) { // Build list to filter - $results = DataList::create($dataClass) - ->byIDs($args['ids']); + if (strtolower($idField) === 'id') { + $results = DataList::create($dataClass) + ->byIDs($args['ids']); + } else { + $results = DataList::create($dataClass) + ->filter($idField, $args['ids']); + } // Before deleting, check if any items fail canDelete() /** @var DataObject[] $resultsList */ diff --git a/src/Schema/DataObject/UpdateCreator.php b/src/Schema/DataObject/UpdateCreator.php index d9f7a5537..4527e633a 100644 --- a/src/Schema/DataObject/UpdateCreator.php +++ b/src/Schema/DataObject/UpdateCreator.php @@ -56,6 +56,7 @@ public function createOperation( ): ?ModelOperation { $plugins = $config['plugins'] ?? []; $mutationName = $config['name'] ?? null; + $idField = $config['idField'] ?? 'id'; if (!$mutationName) { $mutationName = 'update' . ucfirst($typeName); } @@ -66,6 +67,7 @@ public function createOperation( ->setPlugins($plugins) ->setResolver([static::class, 'resolve']) ->addResolverContext('dataClass', $model->getSourceClass()) + ->addResolverContext('idField', $idField) ->addArg('input', "{$inputTypeName}!"); } @@ -76,7 +78,8 @@ public function createOperation( public static function resolve(array $resolverContext = []): Closure { $dataClass = $resolverContext['dataClass'] ?? null; - return function ($obj, array $args, array $context, ResolveInfo $info) use ($dataClass) { + $idField = $resolverContext['identifier'] ?? 'id'; + return function ($obj, array $args, array $context, ResolveInfo $info) use ($dataClass, $idField) { if (!$dataClass) { return null; } @@ -87,10 +90,16 @@ public static function resolve(array $resolverContext = []): Closure __CLASS__, SchemaConfigProvider::class ); - $fieldName = FieldAccessor::formatField('ID'); + $fieldName = FieldAccessor::formatField($idField); $input = $args['input']; - $obj = DataList::create($dataClass) - ->byID($input[$fieldName]); + if (strtolower($fieldName) === 'id') { + $obj = DataList::create($dataClass) + ->byID($input[$fieldName]); + } else { + $obj = DataList::create($dataClass) + ->filter($idField, $input[$fieldName]) + ->first(); + } if (!$obj) { throw new MutationException(sprintf( '%s with ID %s not found', From 5dd3295f73ce4e6863233a1ce765fbd6cf048014 Mon Sep 17 00:00:00 2001 From: Aaron Carlino Date: Tue, 26 Oct 2021 17:23:31 +1300 Subject: [PATCH 2/4] Ensure mutations get updated to interfaces --- src/Schema/DataObject/Plugin/QueryCollector.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Schema/DataObject/Plugin/QueryCollector.php b/src/Schema/DataObject/Plugin/QueryCollector.php index 53b2250e0..d3ba24c68 100644 --- a/src/Schema/DataObject/Plugin/QueryCollector.php +++ b/src/Schema/DataObject/Plugin/QueryCollector.php @@ -7,6 +7,7 @@ use SilverStripe\GraphQL\Schema\Exception\SchemaBuilderException; use SilverStripe\GraphQL\Schema\Field\Field; use SilverStripe\GraphQL\Schema\Field\ModelField; +use SilverStripe\GraphQL\Schema\Field\ModelMutation; use SilverStripe\GraphQL\Schema\Field\ModelQuery; use SilverStripe\GraphQL\Schema\Schema; use SilverStripe\GraphQL\Schema\Type\ModelInterfaceType; @@ -43,6 +44,12 @@ public function collectQueries(): array $queries[] = $field; } } + foreach ($this->schema->getMutationType()->getFields() as $field) { + if ($field instanceof ModelMutation) { + $queries[] = $field; + } + } + foreach (array_merge($this->schema->getModels(), $this->schema->getTypes()) as $type) { foreach ($type->getFields() as $field) { if ($field instanceof ModelField && $field->getModelType()) { From 03f5394c380eaba59bf8403d0c44fbb4dd1f548b Mon Sep 17 00:00:00 2001 From: Aaron Carlino Date: Tue, 26 Oct 2021 17:23:55 +1300 Subject: [PATCH 3/4] Fix incorrect field on config --- src/Schema/DataObject/UpdateCreator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Schema/DataObject/UpdateCreator.php b/src/Schema/DataObject/UpdateCreator.php index 4527e633a..00df83dcf 100644 --- a/src/Schema/DataObject/UpdateCreator.php +++ b/src/Schema/DataObject/UpdateCreator.php @@ -78,7 +78,7 @@ public function createOperation( public static function resolve(array $resolverContext = []): Closure { $dataClass = $resolverContext['dataClass'] ?? null; - $idField = $resolverContext['identifier'] ?? 'id'; + $idField = $resolverContext['idField'] ?? 'id'; return function ($obj, array $args, array $context, ResolveInfo $info) use ($dataClass, $idField) { if (!$dataClass) { return null; From e24e4ae7d7cff4e8dd7866c2c522bb64ac3ad7e5 Mon Sep 17 00:00:00 2001 From: Aaron Carlino Date: Tue, 26 Oct 2021 17:24:09 +1300 Subject: [PATCH 4/4] Cast JSON blob as object --- src/Schema/Resolver/JSONResolver.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Schema/Resolver/JSONResolver.php b/src/Schema/Resolver/JSONResolver.php index 67c9865b9..5d8ccb2ee 100644 --- a/src/Schema/Resolver/JSONResolver.php +++ b/src/Schema/Resolver/JSONResolver.php @@ -7,11 +7,11 @@ class JSONResolver { /** * @param $value - * @return object + * @return array */ - public static function serialise($value): object + public static function serialise($value): array { - return (object) $value; + return json_decode($value, true); } /**