FIX Support search filters with match_any searchable_fields

This commit is contained in:
Guy Sartorelli 2022-06-30 10:54:20 +12:00
parent 4e53c35b53
commit 6c01661512

View File

@ -17,6 +17,7 @@ use SilverStripe\Forms\SelectField;
use SilverStripe\Forms\CheckboxField; use SilverStripe\Forms\CheckboxField;
use InvalidArgumentException; use InvalidArgumentException;
use Exception; use Exception;
use SilverStripe\ORM\DataQuery;
/** /**
* Manages searching of properties on one or more {@link DataObject} * Manages searching of properties on one or more {@link DataObject}
@ -179,28 +180,25 @@ class SearchContext
$query = $query->sort($sort); $query = $query->sort($sort);
$this->setSearchParams($searchParams); $this->setSearchParams($searchParams);
$modelObj = Injector::inst()->create($this->modelClass);
$searchableFields = $modelObj->searchableFields();
foreach ($this->searchParams as $key => $value) { foreach ($this->searchParams as $key => $value) {
$key = str_replace('__', '.', $key ?? ''); $key = str_replace('__', '.', $key ?? '');
if ($filter = $this->getFilter($key)) { if ($filter = $this->getFilter($key)) {
$filter->setModel($this->modelClass); $filter->setModel($this->modelClass);
$filter->setValue($value); $filter->setValue($value);
if (!$filter->isEmpty()) { if (!$filter->isEmpty()) {
$modelObj = Injector::inst()->create($this->modelClass); if (isset($searchableFields[$key]['match_any'])) {
if (isset($modelObj->searchableFields()[$key]['match_any'])) { $searchFields = $searchableFields[$key]['match_any'];
$query = $query->alterDataQuery(function ($dataQuery) use ($modelObj, $key, $value) { $filterClass = get_class($filter);
$searchFields = $modelObj->searchableFields()[$key]['match_any']; $modifiers = $filter->getModifiers();
$sqlSearchFields = []; $query = $query->alterDataQuery(function (DataQuery $dataQuery) use ($searchFields, $filterClass, $modifiers, $value) {
foreach ($searchFields as $dottedRelation) { $subGroup = $dataQuery->disjunctiveGroup();
$relation = substr($dottedRelation ?? '', 0, strpos($dottedRelation ?? '', '.')); foreach ($searchFields as $matchField) {
$relations = explode('.', $dottedRelation ?? ''); /** @var SearchFilter $filterClass */
$fieldName = array_pop($relations); $filter = new $filterClass($matchField, $value, $modifiers);
$relationModelName = $dataQuery->applyRelation($relation); $filter->apply($subGroup);
$relationPrefix = $dataQuery->applyRelationPrefix($relation);
$columnName = $modelObj->getSchema()
->sqlColumnForField($relationModelName, $fieldName, $relationPrefix);
$sqlSearchFields[$columnName] = $value;
} }
$dataQuery = $dataQuery->whereAny($sqlSearchFields);
}); });
} else { } else {
$query = $query->alterDataQuery([$filter, 'apply']); $query = $query->alterDataQuery([$filter, 'apply']);