Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOCS: custom graphql filter fields #10192

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,82 @@ MyProject\Models\ProductCategory:
title: true
```

[info]
You can add all fields with `'*': true`, just like with standard model definitions.
[/info]

##### Adding non-native filter fields

Sometimes you may want to add a filter field that may stem from a custom getter, or a complex computation that
isn't easily addressed by simple field comparisons. For cases like this, you can add the custom field as long
as you provide instructions on how to resolve it.

*app/_graphql/models.yml*
```yaml
MyProject\Models\Product:
fields:
title: true
price: true
operations:
read:
plugins:
filter:
fields:
title: true
hasReviews: true
resolve:
hasReviews:
type: Boolean
resolver: ['MyApp\Resolvers\Resolver', 'resolveHasReviewsFilter']
```

We've added the custom field `hasReviews` as a custom field in the `fields` section of the plugin config. A custom field
like this that does not exist on the `Product` dataobject will cause the plugin to throw unless you've provided
a `resolve` directive for it.

In the `resolve` section, we need to provide two vital pieces of information:

* What data type will the filter value be? (boolean in this case)
* Where is the code that will apply this filter? (A static function in our `Resolver` class)

The code to resolve the filter will get two relevant pieces of information in its `$context` parameter:

* `filterComparator`: e.g. "eq", "ne", "gt", etc.
* `filterValue`: What value we're comparing (true or false, in this case, since it's a boolean)

Here's how we can resolve this custom filter:

*app/src/Resolvers/Resolver.php*
```php
namespace MyApp\Resolvers;

class Resolver
{
public static function resolveHasReviewsFilter($list, $args, $context)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should put in param types in e.g. array $context

{
$onlyWithReviews = $context['filterValue'];
$comparator = $context['filterComparator'];

if (!in_array($comparator, ['eq','ne'])) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!in_array($comparator, ['eq','ne'])) {
if (!in_array($comparator, ['eq', 'ne'])) {

throw new \Exception('Invalid comparator for hasReviews: ' . $comparator);
}
if ($comparator === 'ne') {
$onlyWithReviews = !$onlyWithReviews;
}

return $onlyWithReviews
? $list->filter('Reviews.Count():GreaterThan', 0)
: $list->filter('Reviews.Count()', 0);
}
}
```

[info]
Custom filter fields are also a good opportunity to implement something like `filterByCallback` on your list for
particularly complex computations that cannot be done at the database level.
[/info]


#### Disabling the filter plugin

Just set it to `false` in the configuration.
Expand Down