mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
API Add excludeAny() and tests for complicated excludes/filters (#7838)
This commit is contained in:
parent
ef6b03a35a
commit
860fa2a05a
@ -587,9 +587,8 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a copy of this list which does not contain any items with these charactaristics
|
* Return a copy of this list which does not contain any items that match all params
|
||||||
*
|
*
|
||||||
* @see SS_List::exclude()
|
|
||||||
* @example $list = $list->exclude('Name', 'bob'); // exclude bob from list
|
* @example $list = $list->exclude('Name', 'bob'); // exclude bob from list
|
||||||
* @example $list = $list->exclude('Name', array('aziz', 'bob'); // exclude aziz and bob from list
|
* @example $list = $list->exclude('Name', array('aziz', 'bob'); // exclude aziz and bob from list
|
||||||
* @example $list = $list->exclude(array('Name'=>'bob, 'Age'=>21)); // exclude bob that has Age 21
|
* @example $list = $list->exclude(array('Name'=>'bob, 'Age'=>21)); // exclude bob that has Age 21
|
||||||
@ -599,7 +598,9 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
|||||||
*
|
*
|
||||||
* @todo extract the sql from this method into a SQLGenerator class
|
* @todo extract the sql from this method into a SQLGenerator class
|
||||||
*
|
*
|
||||||
* @param string|array Escaped SQL statement. If passed as array, all keys and values will be escaped internally
|
* @param string|array
|
||||||
|
* @param string [optional]
|
||||||
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function exclude()
|
public function exclude()
|
||||||
@ -625,6 +626,43 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a copy of this list which does not contain any items with any of these params
|
||||||
|
*
|
||||||
|
* @example $list = $list->excludeAny('Name', 'bob'); // exclude bob from list
|
||||||
|
* @example $list = $list->excludeAny('Name', array('aziz', 'bob'); // exclude aziz and bob from list
|
||||||
|
* @example $list = $list->excludeAny(array('Name'=>'bob, 'Age'=>21)); // exclude bob or Age 21
|
||||||
|
* @example $list = $list->excludeAny(array('Name'=>'bob, 'Age'=>array(21, 43))); // exclude bob or Age 21 or 43
|
||||||
|
* @example $list = $list->excludeAny(array('Name'=>array('bob','phil'), 'Age'=>array(21, 43)));
|
||||||
|
* // bob, phil, 21 or 43 would be excluded
|
||||||
|
*
|
||||||
|
* @param string|array
|
||||||
|
* @param string [optional]
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function excludeAny()
|
||||||
|
{
|
||||||
|
$numberFuncArgs = count(func_get_args());
|
||||||
|
$whereArguments = array();
|
||||||
|
|
||||||
|
if ($numberFuncArgs == 1 && is_array(func_get_arg(0))) {
|
||||||
|
$whereArguments = func_get_arg(0);
|
||||||
|
} elseif ($numberFuncArgs == 2) {
|
||||||
|
$whereArguments[func_get_arg(0)] = func_get_arg(1);
|
||||||
|
} else {
|
||||||
|
throw new InvalidArgumentException('Incorrect number of arguments passed to excludeAny()');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->alterDataQuery(function (DataQuery $dataQuery) use ($whereArguments) {
|
||||||
|
foreach ($whereArguments as $field => $value) {
|
||||||
|
$filter = $this->createSearchFilter($field, $value);
|
||||||
|
$filter->exclude($dataQuery);
|
||||||
|
}
|
||||||
|
return $dataQuery;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns a copy of this list that does not contain any DataObjects that exists in $list
|
* This method returns a copy of this list that does not contain any DataObjects that exists in $list
|
||||||
*
|
*
|
||||||
|
@ -1509,14 +1509,61 @@ class DataListTest extends SapphireTest
|
|||||||
$this->assertEquals(2, $list->count());
|
$this->assertEquals(2, $list->count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test doesn't exclude if only matches one
|
||||||
|
* $list->exclude(array('Name'=>'bob, 'Age'=>21)); // exclude bob that has Age 21
|
||||||
|
*/
|
||||||
|
public function testMultipleExcludeMultipleMatches()
|
||||||
|
{
|
||||||
|
$list = TeamComment::get();
|
||||||
|
$list = $list->exclude(array('Name'=>'Bob', 'Comment'=>'Phil is a unique guy, and comments on team2'));
|
||||||
|
$this->assertCount(3, $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* // exclude only those that match both
|
||||||
|
*/
|
||||||
|
public function testMultipleExcludeArraysMultipleMatches()
|
||||||
|
{
|
||||||
|
$list = TeamComment::get();
|
||||||
|
$list = $list->exclude(array(
|
||||||
|
'Name'=> array('Bob', 'Phil'),
|
||||||
|
'Comment'=> array(
|
||||||
|
'This is a team comment by Bob',
|
||||||
|
'Phil is a unique guy, and comments on team2'
|
||||||
|
)
|
||||||
|
));
|
||||||
|
$this->assertListEquals([['Name' => 'Joe']], $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclude only which matches both params
|
||||||
|
*/
|
||||||
|
public function testMultipleExcludeArraysMultipleMatchesOneMiss()
|
||||||
|
{
|
||||||
|
$list = TeamComment::get();
|
||||||
|
$list = $list->exclude(array(
|
||||||
|
'Name' => array('Bob', 'Phil'),
|
||||||
|
'Comment' => array(
|
||||||
|
'Does not match any comments',
|
||||||
|
'Phil is a unique guy, and comments on team2'
|
||||||
|
)
|
||||||
|
));
|
||||||
|
$list = $list->sort('Name');
|
||||||
|
$this->assertListEquals(
|
||||||
|
[
|
||||||
|
['Name' => 'Bob'],
|
||||||
|
['Name' => 'Joe'],
|
||||||
|
],
|
||||||
|
$list
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that if an exclude() is applied to a filter(), the filter() is still preserved.
|
* Test that if an exclude() is applied to a filter(), the filter() is still preserved.
|
||||||
*/
|
*/
|
||||||
public function testExcludeOnFilter()
|
public function testExcludeOnFilter()
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var DataList $list
|
|
||||||
*/
|
|
||||||
$list = TeamComment::get();
|
$list = TeamComment::get();
|
||||||
$list = $list->filter('Comment', 'Phil is a unique guy, and comments on team2');
|
$list = $list->filter('Comment', 'Phil is a unique guy, and comments on team2');
|
||||||
$list = $list->exclude('Name', 'Bob');
|
$list = $list->exclude('Name', 'Bob');
|
||||||
@ -1528,6 +1575,58 @@ class DataListTest extends SapphireTest
|
|||||||
$sql
|
$sql
|
||||||
);
|
);
|
||||||
$this->assertEquals(array('Phil is a unique guy, and comments on team2', 'Bob'), $parameters);
|
$this->assertEquals(array('Phil is a unique guy, and comments on team2', 'Bob'), $parameters);
|
||||||
|
$this->assertListEquals([['Name' => 'Phil']], $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that if a complicated exclude() is applied to a filter(), the filter() is still preserved.
|
||||||
|
*/
|
||||||
|
public function testComplicatedExcludeOnFilter()
|
||||||
|
{
|
||||||
|
$list = TeamComment::get();
|
||||||
|
$list = $list->filter('Name', array('Phil', 'Bob'));
|
||||||
|
$list = $list->exclude('Name', array('Bob', 'Joe'));
|
||||||
|
|
||||||
|
$sql = $list->sql($parameters);
|
||||||
|
$this->assertSQLContains(
|
||||||
|
'WHERE ("DataObjectTest_TeamComment"."Name" IN (?, ?)) AND (("DataObjectTest_TeamComment"."Name" NOT IN (?, ?) '
|
||||||
|
. 'OR "DataObjectTest_TeamComment"."Name" IS NULL))',
|
||||||
|
$sql
|
||||||
|
);
|
||||||
|
$this->assertEquals(array('Phil', 'Bob', 'Bob', 'Joe'), $parameters);
|
||||||
|
$this->assertListEquals([['Name' => 'Phil']], $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that if a very complicated exclude() is applied to a filter(), the filter() is still preserved.
|
||||||
|
*/
|
||||||
|
public function testVeryComplicatedExcludeOnFilter()
|
||||||
|
{
|
||||||
|
$list = TeamComment::get();
|
||||||
|
$list = $list->filter('Name', array('Phil', 'Bob'));
|
||||||
|
$list = $list->exclude(array(
|
||||||
|
'Name' => array('Joe', 'Phil'),
|
||||||
|
'Comment' => array('Matches no comments', 'Not a matching comment')
|
||||||
|
));
|
||||||
|
|
||||||
|
$sql = $list->sql($parameters);
|
||||||
|
$this->assertSQLContains(
|
||||||
|
'WHERE ("DataObjectTest_TeamComment"."Name" IN (?, ?)) '
|
||||||
|
. 'AND (("DataObjectTest_TeamComment"."Name" NOT IN (?, ?) '
|
||||||
|
. 'OR "DataObjectTest_TeamComment"."Name" IS NULL) '
|
||||||
|
. 'OR ("DataObjectTest_TeamComment"."Comment" NOT IN (?, ?) '
|
||||||
|
. 'OR "DataObjectTest_TeamComment"."Comment" IS NULL))',
|
||||||
|
$sql
|
||||||
|
);
|
||||||
|
$this->assertEquals(array('Phil', 'Bob', 'Joe', 'Phil', 'Matches no comments', 'Not a matching comment'), $parameters);
|
||||||
|
$list = $list->sort('Name');
|
||||||
|
$this->assertListEquals(
|
||||||
|
[
|
||||||
|
['Name' => 'Bob'],
|
||||||
|
['Name' => 'Phil'],
|
||||||
|
],
|
||||||
|
$list
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testExcludeWithSearchFilter()
|
public function testExcludeWithSearchFilter()
|
||||||
@ -1540,6 +1639,45 @@ class DataListTest extends SapphireTest
|
|||||||
$this->assertEquals(array('Bob'), $parameters);
|
$this->assertEquals(array('Bob'), $parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that Bob and Phil are excluded (one match each)
|
||||||
|
*/
|
||||||
|
public function testExcludeAny()
|
||||||
|
{
|
||||||
|
$list = TeamComment::get();
|
||||||
|
$list = $list->excludeAny(array(
|
||||||
|
'Name' => 'Bob',
|
||||||
|
'Comment' => 'Phil is a unique guy, and comments on team2'
|
||||||
|
));
|
||||||
|
$this->assertListEquals([['Name' => 'Joe']], $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that Bob and Phil are excluded by Name
|
||||||
|
*/
|
||||||
|
public function testExcludeAnyArrays()
|
||||||
|
{
|
||||||
|
$list = TeamComment::get();
|
||||||
|
$list = $list->excludeAny(array(
|
||||||
|
'Name' => array('Bob', 'Phil'),
|
||||||
|
'Comment' => 'No matching comments'
|
||||||
|
));
|
||||||
|
$this->assertListEquals([['Name' => 'Joe']], $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that Bob is excluded by Name, Phil by comment
|
||||||
|
*/
|
||||||
|
public function testExcludeAnyMultiArrays()
|
||||||
|
{
|
||||||
|
$list = TeamComment::get();
|
||||||
|
$list = $list->excludeAny(array(
|
||||||
|
'Name' => array('Bob', 'Fred'),
|
||||||
|
'Comment' => array('No matching comments', 'Phil is a unique guy, and comments on team2')
|
||||||
|
));
|
||||||
|
$this->assertListEquals([['Name' => 'Joe']], $list);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test exact match filter with empty array items
|
* Test exact match filter with empty array items
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user