forked from silverstripe/silverstripe-framework
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
NEW Provide an easy way to filter arbitrary ViewableData in gridfields
- Loading branch information
1 parent
a29b079
commit 80048c3
Showing
3 changed files
with
147 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
<?php | ||
|
||
namespace SilverStripe\ORM\Search; | ||
|
||
use BadMethodCallException; | ||
use InvalidArgumentException; | ||
use SilverStripe\Core\Config\Configurable; | ||
use SilverStripe\Dev\Deprecation; | ||
use SilverStripe\ORM\Filterable; | ||
use SilverStripe\ORM\Limitable; | ||
use SilverStripe\ORM\Sortable; | ||
|
||
/** | ||
* A SearchContext that can be used with non-ORM data. | ||
*/ | ||
class BasicSearchContext extends SearchContext | ||
{ | ||
use Configurable; | ||
|
||
/** | ||
* Name of the field which, if included in search forms passed to this object, will be used | ||
* to search across all searchable fields. | ||
*/ | ||
private static $general_search_field_name = 'q'; | ||
|
||
/** | ||
* Returns a list which has been limited, sorted, and filtered by the given parameters. | ||
* | ||
* @param array $searchParams Map of search criteria, mostly taken from $_REQUEST. | ||
* If a filter is applied to a relationship in dot notation, | ||
* the parameter name should have the dots replaced with double underscores, | ||
* for example "Comments__Name" instead of the filter name "Comments.Name". | ||
* @param array|bool|string $sort Field to sort on. | ||
* @param array|null|string $limit | ||
* @param Filterable&Sortable&Limitable $existingQuery | ||
*/ | ||
public function getQuery($searchParams, $sort = false, $limit = false, $existingQuery = null): Filterable&Sortable&Limitable | ||
{ | ||
if (!$existingQuery || !($existingQuery instanceof Filterable) || !($existingQuery instanceof Sortable) || !($existingQuery instanceof Limitable)) { | ||
throw new InvalidArgumentException('getQuery requires a pre-existing filterable/sortable/limitable list (usually ArrayList) to be passed as $existingQuery.'); | ||
} | ||
|
||
if ((count(func_get_args()) >= 3) && (!in_array(gettype($limit), ['array', 'NULL', 'string']))) { | ||
Deprecation::notice( | ||
'5.1.0', | ||
'$limit should be type of array|string|null' | ||
); | ||
$limit = null; | ||
} | ||
|
||
$searchParams = $this->normaliseFieldNames($searchParams); | ||
$result = $this->applyGeneralSearchField($searchParams, $existingQuery); | ||
|
||
// Filter the list by the requested filters. | ||
if (!empty($searchParams)) { | ||
$result = $result->filter($searchParams); | ||
} | ||
|
||
// Only sort if a sort value is provided - sort by "false" just means use the existing sort. | ||
if ($sort) { | ||
$result = $result->sort($sort); | ||
} | ||
|
||
// Limit must be last so that ArrayList results don't have an applied limit before they can be filtered/sorted. | ||
$result = $result->limit($limit); | ||
|
||
return $result; | ||
} | ||
|
||
private function normaliseFieldNames(array $searchParams): array | ||
{ | ||
$normalised = []; | ||
foreach ($searchParams as $field => $searchTerm) { | ||
$normalised[str_replace('__', '.', $field)] = $searchTerm; | ||
} | ||
return $normalised; | ||
} | ||
|
||
private function applyGeneralSearchField(array &$searchParams, Filterable $existingQuery): Filterable | ||
{ | ||
$generalFieldName = static::config()->get('general_search_field_name'); | ||
if (array_key_exists($generalFieldName, $searchParams)) { | ||
$searchTerm = $searchParams[$generalFieldName]; | ||
$generalFilter = []; | ||
foreach ($this->getSearchFields()->dataFieldNames() as $fieldName) { | ||
if ($fieldName === $generalFieldName) { | ||
continue; | ||
} | ||
$generalFilter[$fieldName] = $searchTerm; | ||
} | ||
$result = $existingQuery->filterAny($generalFilter); | ||
unset($searchParams[$generalFieldName]); | ||
} | ||
|
||
return $result ?? $existingQuery; | ||
} | ||
|
||
/** | ||
* Throws an exception. SearchFilters aren't defined for this search context. Instead, | ||
* the field names should have search filter syntax directly (e.g. "Name:PartialMatch") | ||
* @throws BadMethodCallException | ||
*/ | ||
public function setFilters($filters) | ||
{ | ||
throw new BadMethodCallException('Not implemented'); | ||
} | ||
|
||
/** | ||
* Throws an exception. SearchFilters aren't defined for this search context. Instead, | ||
* the field names should have search filter syntax directly (e.g. "Name:PartialMatch") | ||
* @throws BadMethodCallException | ||
*/ | ||
public function addFilter($filter) | ||
{ | ||
throw new BadMethodCallException('Not implemented'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters