From 72d134dc984be6c833db1f1f5bdd4b8274b28a96 Mon Sep 17 00:00:00 2001 From: Andrew Welch Date: Sat, 25 Jan 2025 17:13:58 -0500 Subject: [PATCH] feat: Add the ability to have multiple **and** `where` queries by accepting an array of arguments, closes ([#25](https://github.com/lsst-epo/canto-dam-assets/issues/25)) --- README.md | 12 ++--- src/fields/CantoDamAsset.php | 24 ++++----- src/gql/resolvers/CantoDamAssetResolver.php | 55 ++++++++++++++++----- 3 files changed, 60 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 5edeeae..b37672f 100644 --- a/README.md +++ b/README.md @@ -334,7 +334,7 @@ So for example, this query: { entry(section: "homepage") { ... on homepage_homepage_Entry { - someDamAsset(where: {key: "default.Author", value: "Hernan Stockebrand"}, sortByDesc: { field: "default.Size" }) { + someDamAsset(where: {key: "default.Author", value: "Hernan Stockebrand"}, sortByDesc: { field: "default.Size", flags: SORT_NUMERIC }) { id, url { directUrlOriginal @@ -385,20 +385,20 @@ Here's a list of the available arguments, and the types they expect as parameter * [`forPage`](https://laravel.com/docs/10.x/collections#method-forpage): `ForPageInput` - Paginate the items by page number and items per page. -* [`where`](https://laravel.com/docs/10.x/collections#method-where): `WhereFiltersInput` - Get all items by the given key value pair, using the optional operator for comparison. +* [`where`](https://laravel.com/docs/10.x/collections#method-where): `[WhereFiltersInput]` - Get all items by the given key value pair, using the optional operator for comparison. -* [`whereBetween`](https://laravel.com/docs/10.x/collections#method-wherebetween): `WhereBetweenFiltersInput` +* [`whereBetween`](https://laravel.com/docs/10.x/collections#method-wherebetween): `[WhereBetweenFiltersInput]` Filter items such that the value of the given key is between the given values. -* [`whereIn`](https://laravel.com/docs/10.x/collections#method-wherein): `WhereInFiltersInput` - Filter items such that the value of the given key is in the array of values provided. +* [`whereIn`](https://laravel.com/docs/10.x/collections#method-wherein): `[WhereInFiltersInput]` - Filter items such that the value of the given key is in the array of values provided. -* [`whereNotBetween`](https://laravel.com/docs/10.x/collections#method-wherenotbetween): `WhereNotBetweenFiltersInput` - Filter items such that the value of the given key is NOT between the given values. This argument expects exactly three values in an array. You can use the field.subField syntax for nested fields. +* [`whereNotBetween`](https://laravel.com/docs/10.x/collections#method-wherenotbetween): `[WhereNotBetweenFiltersInput]` - Filter items such that the value of the given key is NOT between the given values. This argument expects exactly three values in an array. You can use the field.subField syntax for nested fields. -* [`whereNotIn`](https://laravel.com/docs/10.x/collections#method-wherenotin): `WhereNotInFiltersInput` - Filter items by the given key value pair, making sure the value is not in the array. +* [`whereNotIn`](https://laravel.com/docs/10.x/collections#method-wherenotin): `[WhereNotInFiltersInput]` - Filter items by the given key value pair, making sure the value is not in the array. * [`whereNotNull`](https://laravel.com/docs/10.x/collections#method-wherenotnull): `String` - Return items from the collection where the given key is not null. You can use the `field.subField` syntax for nested fields. diff --git a/src/fields/CantoDamAsset.php b/src/fields/CantoDamAsset.php index b01c210..208faff 100644 --- a/src/fields/CantoDamAsset.php +++ b/src/fields/CantoDamAsset.php @@ -390,7 +390,7 @@ protected function getGqlArguments(): array 'whereContainsIn' => [ 'name' => 'whereContainsIn', 'description' => 'Look across the given key-values and return fuzzy match on a single search term', - 'type' => new InputObjectType([ + 'type' => Type::listOf(new InputObjectType([ 'name' => 'WhereContainsInFilterInput', 'fields' => [ 'keys' => [ @@ -402,12 +402,12 @@ protected function getGqlArguments(): array 'description' => 'The value that should be fuzzy matched in the key-values' ], ] - ]), + ])), ], 'where' => [ 'name' => 'where', 'description' => 'Get all items by the given key value pair, using the optional operator for comparison. (See https://laravel.com/docs/10.x/collections#method-where).', - 'type' => new InputObjectType([ + 'type' => Type::listOf(new InputObjectType([ 'name' => 'WhereFiltersInput', 'fields' => [ 'key' => [ @@ -423,7 +423,7 @@ protected function getGqlArguments(): array 'description' => 'The comparison operator to use, e.g.: `=`, `>`, `<=`, etc. The default is `=`', ], ], - ]), + ])), ], 'whereNull' => [ 'name' => 'whereNull', @@ -438,7 +438,7 @@ protected function getGqlArguments(): array 'whereIn' => [ 'name' => 'whereIn', 'description' => 'Filter items such that the value of the given key is in the array of values provided. (See https://laravel.com/docs/10.x/collections#method-wherein).', - 'type' => new InputObjectType([ + 'type' => Type::listOf(new InputObjectType([ 'name' => 'WhereInFiltersInput', 'fields' => [ 'key' => [ @@ -450,12 +450,12 @@ protected function getGqlArguments(): array 'description' => 'The values that should be in the key', ], ], - ]), + ])), ], 'whereNotIn' => [ 'name' => 'whereNotIn', 'description' => 'Filter items by the given key value pair, making sure the value is NOT in the array. (See https://laravel.com/docs/10.x/collections#method-wherenotin).', - 'type' => new InputObjectType([ + 'type' => Type::listOf(new InputObjectType([ 'name' => 'WhereNotInFiltersInput', 'fields' => [ 'key' => [ @@ -467,12 +467,12 @@ protected function getGqlArguments(): array 'description' => 'The the values that should not be in the key', ], ], - ]), + ])), ], 'whereBetween' => [ 'name' => 'whereBetween', 'description' => 'Filter items such that the value of the given key is between the given values. (See https://laravel.com/docs/10.x/collections#method-wherebetween).', - 'type' => new InputObjectType([ + 'type' => Type::listOf(new InputObjectType([ 'name' => 'WhereBetweenFiltersInput', 'fields' => [ 'key' => [ @@ -484,12 +484,12 @@ protected function getGqlArguments(): array 'description' => 'The values that the key should be between', ], ], - ]), + ])), ], 'whereNotBetween' => [ 'name' => 'whereNotBetween', 'description' => 'Filter items such that the value of the given key is not between the given values. (See https://laravel.com/docs/10.x/collections#method-wherenotbetween).', - 'type' => new InputObjectType([ + 'type' => Type::listOf(new InputObjectType([ 'name' => 'WhereNotBetweenFiltersInput', 'fields' => [ 'key' => [ @@ -501,7 +501,7 @@ protected function getGqlArguments(): array 'description' => 'The values the key should not be between', ], ], - ]), + ])), ], ], 'CantoDamAssetQueryType'); } diff --git a/src/gql/resolvers/CantoDamAssetResolver.php b/src/gql/resolvers/CantoDamAssetResolver.php index b9cae53..97ac43d 100644 --- a/src/gql/resolvers/CantoDamAssetResolver.php +++ b/src/gql/resolvers/CantoDamAssetResolver.php @@ -88,11 +88,17 @@ protected static function forPageArgs(Collection $collection, array $arguments, protected static function whereArgs(Collection $collection, array $arguments, string $arg): Collection { - return $collection->$arg( - $arguments[$arg]['key'] ?? null, - $arguments[$arg]['operator'] ?? null, - $arguments[$arg]['value'] ?? null - ); + // Allow for an array of where arguments to be passed in + $argValues = self::isArrayList($arguments[$arg]) ? $arguments[$arg] : [$arguments[$arg]]; + foreach ($argValues as $argValue) { + $collection = $collection->$arg( + $argValue['key'] ?? null, + $argValue['operator'] ?? null, + $argValue['value'] ?? null + ); + } + + return $collection; } protected static function sortArgs(Collection $collection, array $arguments, string $arg): Collection @@ -106,18 +112,30 @@ protected static function sortArgs(Collection $collection, array $arguments, str protected static function whereContainsInArgs(Collection $collection, array $arguments, string $arg): Collection { - return $collection->$arg( - $arguments[$arg]['keys'] ?? null, - $arguments[$arg]['value'] ?? null - ); + // Allow for an array of where arguments to be passed in + $argValues = self::isArrayList($arguments[$arg]) ? $arguments[$arg] : [$arguments[$arg]]; + foreach ($argValues as $argValue) { + $collection = $collection->$arg( + $argValue['keys'] ?? null, + $argValue['value'] ?? null + ); + } + + return $collection; } protected static function whereArrayArgs(Collection $collection, array $arguments, string $arg): Collection { - return $collection->$arg( - $arguments[$arg]['key'] ?? null, - $arguments[$arg]['values'] ?? null - ); + // Allow for an array of where arguments to be passed in + $argValues = self::isArrayList($arguments[$arg]) ? $arguments[$arg] : [$arguments[$arg]]; + foreach ($argValues as $argValue) { + $collection = $collection->$arg( + $argValue['key'] ?? null, + $argValue['values'] ?? null + ); + } + + return $collection; } protected static function simpleArgs(Collection $collection, array $arguments, string $arg): Collection @@ -129,4 +147,15 @@ protected static function noArgs(Collection $collection, array $arguments, strin { return new Collection([$collection->$arg(null)]); } + + protected static function isArrayList(mixed $arr) + { + if (!is_array($arr)) { + return false; + } + if ($arr === []) { + return true; + } + return array_keys($arr) === range(0, count($arr) - 1); + } }