mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
New getSummary() API for SearchContext
This commit is contained in:
parent
18863f0916
commit
74873096bd
@ -10,6 +10,10 @@ use SilverStripe\Forms\FormField;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\DataList;
|
||||
use SilverStripe\ORM\Filters\SearchFilter;
|
||||
use SilverStripe\ORM\ArrayList;
|
||||
use SilverStripe\View\ArrayData;
|
||||
use SilverStripe\Forms\SelectField;
|
||||
use SilverStripe\Forms\CheckboxField;
|
||||
use InvalidArgumentException;
|
||||
use Exception;
|
||||
|
||||
@ -61,6 +65,13 @@ class SearchContext
|
||||
*/
|
||||
protected $filters;
|
||||
|
||||
/**
|
||||
* Key/value pairs of search fields to search terms
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $searchParams = [];
|
||||
|
||||
/**
|
||||
* The logical connective used to join WHERE clauses. Defaults to AND.
|
||||
* @var string
|
||||
@ -121,7 +132,7 @@ class SearchContext
|
||||
* Returns a SQL object representing the search context for the given
|
||||
* list of query parameters.
|
||||
*
|
||||
* @param array $searchParams Map of search criteria, mostly taked from $_REQUEST.
|
||||
* @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".
|
||||
@ -160,15 +171,9 @@ class SearchContext
|
||||
|
||||
/** @var DataList $query */
|
||||
$query = $query->sort($sort);
|
||||
$this->setSearchParams($searchParams);
|
||||
|
||||
// hack to work with $searchParems when it's an Object
|
||||
if ($searchParams instanceof HTTPRequest) {
|
||||
$searchParamArray = $searchParams->getVars();
|
||||
} else {
|
||||
$searchParamArray = $searchParams;
|
||||
}
|
||||
|
||||
foreach ($searchParamArray as $key => $value) {
|
||||
foreach ($this->searchParams as $key => $value) {
|
||||
$key = str_replace('__', '.', $key);
|
||||
if ($filter = $this->getFilter($key)) {
|
||||
$filter->setModel($this->modelClass);
|
||||
@ -311,4 +316,72 @@ class SearchContext
|
||||
{
|
||||
$this->fields->removeByName($fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $searchParams
|
||||
*/
|
||||
public function setSearchParams($searchParams)
|
||||
{
|
||||
// hack to work with $searchParams when it's an Object
|
||||
if ($searchParams instanceof HTTPRequest) {
|
||||
$this->searchParams = $searchParams->getVars();
|
||||
} else {
|
||||
$this->searchParams = $searchParams;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSearchParams()
|
||||
{
|
||||
return $this->searchParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of what fields were searched and the values provided
|
||||
* for each field. Returns an ArrayList of ArrayData, suitable for
|
||||
* rendering on a template.
|
||||
*
|
||||
* @return ArrayList
|
||||
*/
|
||||
public function getSummary()
|
||||
{
|
||||
$list = ArrayList::create();
|
||||
foreach ($this->searchParams as $searchField => $searchValue) {
|
||||
if (empty($searchValue)) {
|
||||
continue;
|
||||
}
|
||||
$filter = $this->getFilter($searchField);
|
||||
if (!$filter) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$field = $this->fields->fieldByName($filter->getFullName());
|
||||
if (!$field) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// For dropdowns, checkboxes, etc, get the value that was presented to the user
|
||||
// e.g. not an ID
|
||||
if ($field instanceof SelectField) {
|
||||
$source = $field->getSource();
|
||||
if (isset($source[$searchValue])) {
|
||||
$searchValue = $source[$searchValue];
|
||||
}
|
||||
} else {
|
||||
// For checkboxes, it suffices to simply include the field in the list, since it's binary
|
||||
if ($field instanceof CheckboxField) {
|
||||
$searchValue = null;
|
||||
}
|
||||
}
|
||||
|
||||
$list->push(ArrayData::create([
|
||||
'Field' => $field->Title(),
|
||||
'Value' => $searchValue,
|
||||
]));
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,11 @@ use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\Forms\TextField;
|
||||
use SilverStripe\Forms\TextareaField;
|
||||
use SilverStripe\Forms\NumericField;
|
||||
use SilverStripe\Forms\DropdownField;
|
||||
use SilverStripe\Forms\CheckboxField;
|
||||
use SilverStripe\Forms\FieldList;
|
||||
use SilverStripe\ORM\Filters\PartialMatchFilter;
|
||||
use SilverStripe\ORM\Search\SearchContext;
|
||||
|
||||
class SearchContextTest extends SapphireTest
|
||||
{
|
||||
@ -184,4 +187,67 @@ class SearchContextTest extends SapphireTest
|
||||
$this->assertEquals(1, $results->Count());
|
||||
$this->assertEquals("Filtered value", $results->First()->HiddenValue);
|
||||
}
|
||||
|
||||
public function testSearchContextSummary()
|
||||
{
|
||||
$filters = [
|
||||
'KeywordSearch' => PartialMatchFilter::create('KeywordSearch'),
|
||||
'Country' => PartialMatchFilter::create('Country'),
|
||||
'CategoryID' => PartialMatchFilter::create('CategoryID'),
|
||||
'Featured' => PartialMatchFilter::create('Featured'),
|
||||
'Nothing' => PartialMatchFilter::create('Nothing'),
|
||||
];
|
||||
|
||||
$fields = FieldList::create(
|
||||
TextField::create('KeywordSearch', 'Keywords'),
|
||||
TextField::create('Country', 'Country'),
|
||||
DropdownField::create('CategoryID', 'Category', [
|
||||
1 => 'Category one',
|
||||
2 => 'Category two',
|
||||
]),
|
||||
CheckboxField::create('Featured', 'Featured')
|
||||
);
|
||||
|
||||
$context = SearchContext::create(
|
||||
SearchContextTest\Person::class,
|
||||
$fields,
|
||||
$filters
|
||||
);
|
||||
|
||||
$context->setSearchParams([
|
||||
'KeywordSearch' => 'tester',
|
||||
'Country' => null,
|
||||
'CategoryID' => 2,
|
||||
'Featured' => 1,
|
||||
'Nothing' => 'empty',
|
||||
]);
|
||||
|
||||
$list = $context->getSummary();
|
||||
|
||||
$this->assertEquals(3, $list->count());
|
||||
// KeywordSearch should be in the summary
|
||||
$keyword = $list->find('Field', 'Keywords');
|
||||
$this->assertNotNull($keyword);
|
||||
$this->assertEquals('tester', $keyword->Value);
|
||||
|
||||
// Country should be skipped over
|
||||
$country = $list->find('Field', 'Country');
|
||||
$this->assertNull($country);
|
||||
|
||||
// Category should be expressed as the label
|
||||
$category = $list->find('Field', 'Category');
|
||||
$this->assertNotNull($category);
|
||||
$this->assertEquals('Category two', $category->Value);
|
||||
|
||||
// Featured should have no value, since it's binary
|
||||
$featured = $list->find('Field', 'Featured');
|
||||
$this->assertNotNull($featured);
|
||||
$this->assertNull($featured->Value);
|
||||
|
||||
// "Nothing" should come back null since there's no field for it
|
||||
$nothing = $list->find('Field', 'Nothing');
|
||||
$this->assertNull($nothing);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user