Filters

What are filters

Part of what makes the SDK and the portal so flexible is logic groups. These are dynamic groups of users/groups/roles who meet a set of conditions, such as being tagged, being in a given group, having a position etc. Since these are used everywhere, from assigning permissions to being used as module settings, it is useful to be able to create your own filters.

A filter is one condition based around a user, group or role, which can be used in a logic group. For example, you may have a filter called 'Group Name Is'. This filter would accept a group and a name, and return true if the group’s name is the same as the given name, or false otherwise. By creating any number of filters we can control exactly what individuals can see and do on the portal.

Admins can put these filters together however they need to create logic groups, leaving them with a powerful set of groups to personalise the portal for every user.

How to make a filter

A filter must extend one of \BristolSU\Support\Filters\Contracts\Filters\UserFilter, \BristolSU\Support\Filters\Contracts\FiltersGroupFilter or \BristolSU\Support\Filters\Contracts\RoleFilter. It must then implement all the abstract methods.

  • Alias: The alias for the filter. Must be unique to the portal. This should start with your module alias.

  • Name: A name for the filter

  • Description: A description for the filter

  • Options. This should return a \FormSchema\Schema\Form, with information the filter needs to work.

  • Evaluate. This function does the hard work of checking whether the filter has passed or not.

Evaluating a filter

The evaluate function receives an array of completed settings as specified by the options function. It may do whatever it needs to, including making API requests, to check whether the filter passes.

To access information about the model being tested, you may use the model method (e.g. $this->model()). In each filter, you can also use the method specific to the filter type. For a user filter, you may use $this->user(), a group filter may use $this->group() and a role filter may use $this->role().

All the method needs to do is return the result of the evaluation.

Checking if a group name is the same as the settings

public function evaluate($settings): bool
{
    return strtoupper($this->group()->data()->name()) === strtoupper($settings['Group Name']);
}

How to register a filter

When created, a filter should be registered in the service provider. This may be done by putting the class name in the $filters array, with the filter alias as the key, or by using the contract directly.

protected $filters = [
    'mymodule-group-name-is' => \My\Namespace\GroupNameIs::class,
    'mymodule-group-id-is' => \My\Namespace\GroupIdIs::class,
];

public function boot()
{
    parent::boot
    // Manual Registration
    $this->app->make(\BristolSU\Support\Filters\Contracts\FilterManager::class)
        ->register('mymodule-group-tagged', \My\Namespace\GroupTagged::class);
}

We use filter alias and the class name of the filter to register a filter. The portal will then know about your filter and how to use it, and admins of the portal will be able to use your filter in any logic groups.

What kind of filters should be made

Don’t create inversions

Logic groups allow for filters to be tested differently. For example, we can add everyone to a logic group if a filter is false. Therefore, we don’t need to create the inverse of each filter. If we have a 'Group Name Is' filter, we by default can now test for 'Group Name Is Not'.

They should not need a module instance

Say we had a file upload module, and a filter to test if a file has been uploaded. Since we need a module instance for this to work, if the module instance is changed or deleted the filter will stop working. It’s a much better idea, in this case, to tag a user when they upload a file, then use the 'User Tagged' filter instead. In this way, the data will persist even if the module is changed.

This means that, for any filter you think of making, you should first ask 'Will this need a module instance?'. If the answer is yes, there may be a better way.

Examples

  • Has committed on github in the last week

  • Group is tagged

  • Does the user have a google account