Version 5 supported

SearchFilter Modifiers

The filter() and exclude() methods on DataList specify exact matches by default. However, when filtering a DataList, there are a number of suffixes that you can put on field names to change this behavior. These are represented as SearchFilter subclasses and include:

See SilverStripe\ORM\Filters in the API docs for a full list of SearchFilter classes available in silverstripe/framework.

An example of a SearchFilter in use:

// fetch any player whose first name starts with the letter 'S' and has a PlayerNumber greater than 10
$players = Player::get()->filter([
    'FirstName:StartsWith' => 'S',
    'PlayerNumber:GreaterThan' => '10'
]);

// fetch any player whose name contains the letter 'z'
$players = Player::get()->filterAny([
    'FirstName:PartialMatch' => 'z',
    'LastName:PartialMatch' => 'z'
]);
Notice the syntax - to invoke a SearchFilter in a DataList's filter()/filterAny()/filterByCallback() or exclude()/excludeAny() methods, you add a colon after the field name, followed by the name of the filter (excluding the actual word "filter"). e.g. for a StartsWithFilter: 'FieldName:StartsWith' [hint]

Developers can define their own SearchFilter if needing to extend the ORM filter and exclude behaviors.

Modifiers

SearchFilters can also take modifiers. The modifiers currently supported are ":not", ":nocase", and ":case" (though you can implement custom modifiers on your own SearchFilter implementations). These negate the filter, make it case-insensitive and make it case-sensitive, respectively. The default comparison uses the database's default. For MySQL and MSSQL, this is case-insensitive. For PostgreSQL, this is case-sensitive.

// Fetch players that their FirstName is exactly 'Sam'
// Caution: This might be case in-sensitive if MySQL or MSSQL is used
$players = Player::get()->filter([
    'FirstName:ExactMatch' => 'Sam'
]);

// Fetch players that their FirstName is exactly 'Sam' (force case-sensitive)
$players = Player::get()->filter([
    'FirstName:ExactMatch:case' => 'Sam'
]);

// Fetch players that their FirstName is exactly 'Sam' (force NOT case-sensitive)
$players = Player::get()->filter([
    'FirstName:ExactMatch:nocase' => 'Sam'
]);

By default the :ExactMatch filter is applied, so we can shorthand the above to:

$players = Player::get()->filter('FirstName', 'Sam'); // Default DB engine behaviour
$players = Player::get()->filter('FirstName:case', 'Sam'); // case-sensitive
$players = Player::get()->filter('FirstName:nocase', 'Sam'); // NOT case-sensitive

Note that all search filters (e.g. :PartialMatch) refer to services registered with Injector within the DataListFilter. prefixed namespace. New filters can be registered using the below yml config:

SilverStripe\Core\Injector\Injector:
  DataListFilter.CustomMatch:
    class: MyVendor\Search\CustomMatchFilter

The following is a query which will return everyone whose first name starts with "S", either lowercase or uppercase:

$players = Player::get()->filter([
    'FirstName:StartsWith:nocase' => 'S'
]);

// use :not to get everyone whose first name does NOT start with "S"
$players = Player::get()->filter([
    'FirstName:StartsWith:not' => 'S'
]);

[hint] You can combine :not and either :nocase or :case. Note that the order doesn't matter - these two calls are equivalent:

$players = Player::get()->filter([
    'FirstName:StartsWith:nocase:not' => 'S'
]);
$players = Player::get()->filter([
    'FirstName:StartsWith:not:nocase' => 'S'
]);

Related Lessons

API Documentation