Skip to content

Commit

Permalink
Custom id fields for mutations and more (#412)
Browse files Browse the repository at this point in the history
* NEW: Allow id field to be customised on update, delete

* Ensure mutations get updated to interfaces

* Fix incorrect field on config

* Cast JSON blob as object
  • Loading branch information
Aaron Carlino committed Oct 26, 2021
1 parent 7915749 commit 64ee0ce
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 11 deletions.
16 changes: 12 additions & 4 deletions src/Schema/DataObject/DeleteCreator.php
Expand Up @@ -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;
Expand All @@ -52,6 +53,7 @@ public function createOperation(
->setResolver([static::class, 'resolve'])
->setResolverContext([
'dataClass' => $model->getSourceClass(),
'idField' => $idField,
])
->addArg('ids', '[ID]!');
}
Expand All @@ -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 */
Expand Down
7 changes: 7 additions & 0 deletions src/Schema/DataObject/Plugin/QueryCollector.php
Expand Up @@ -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;
Expand Down Expand Up @@ -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()) {
Expand Down
17 changes: 13 additions & 4 deletions src/Schema/DataObject/UpdateCreator.php
Expand Up @@ -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);
}
Expand All @@ -66,6 +67,7 @@ public function createOperation(
->setPlugins($plugins)
->setResolver([static::class, 'resolve'])
->addResolverContext('dataClass', $model->getSourceClass())
->addResolverContext('idField', $idField)
->addArg('input', "{$inputTypeName}!");
}

Expand All @@ -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['idField'] ?? 'id';
return function ($obj, array $args, array $context, ResolveInfo $info) use ($dataClass, $idField) {
if (!$dataClass) {
return null;
}
Expand All @@ -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',
Expand Down
6 changes: 3 additions & 3 deletions src/Schema/Resolver/JSONResolver.php
Expand Up @@ -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);
}

/**
Expand Down

0 comments on commit 64ee0ce

Please sign in to comment.