mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
ENHANCEMENT: add "InnerJoin" clause for an has_many component's ancestry classes for SearchFilter::applyRelation() so that an searchfliter could filter on that component's ancestry's field. add unit tests for this enhancement and r83500
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@84113 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
788b435821
commit
95a8939c7e
@ -129,11 +129,8 @@ abstract class SearchFilter extends Object {
|
|||||||
$query->leftJoin($component, "\"$component\".\"ID\" = \"{$this->model}\".\"{$foreignKey}ID\"");
|
$query->leftJoin($component, "\"$component\".\"ID\" = \"{$this->model}\".\"{$foreignKey}ID\"");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add join clause to the component's parent class so that the search filter could search on its
|
* add join clause to the component's ancestry classes so that the search filter could search on its
|
||||||
* parent fields.
|
* ancester fields.
|
||||||
* todo: add UT for this. Also add the clause for other relations like has_many, many_many in other
|
|
||||||
* elseif branch and their UTs.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
$ancestry = ClassInfo::ancestry($component, true);
|
$ancestry = ClassInfo::ancestry($component, true);
|
||||||
if(!empty($ancestry)){
|
if(!empty($ancestry)){
|
||||||
@ -152,6 +149,20 @@ abstract class SearchFilter extends Object {
|
|||||||
$ancestry = $model->getClassAncestry();
|
$ancestry = $model->getClassAncestry();
|
||||||
$foreignKey = $model->getComponentJoinField($rel);
|
$foreignKey = $model->getComponentJoinField($rel);
|
||||||
$query->leftJoin($component, "\"$component\".\"{$foreignKey}\" = \"{$ancestry[0]}\".\"ID\"");
|
$query->leftJoin($component, "\"$component\".\"{$foreignKey}\" = \"{$ancestry[0]}\".\"ID\"");
|
||||||
|
/**
|
||||||
|
* add join clause to the component's ancestry classes so that the search filter could search on its
|
||||||
|
* ancestor fields.
|
||||||
|
*/
|
||||||
|
$ancestry = ClassInfo::ancestry($component, true);
|
||||||
|
if(!empty($ancestry)){
|
||||||
|
$ancestry = array_reverse($ancestry);
|
||||||
|
foreach($ancestry as $ancestor){
|
||||||
|
if($ancestor != $component){
|
||||||
|
$query->innerJoin($ancestor, "\"$component\".\"ID\" = \"$ancestor\".ID");
|
||||||
|
$component=$ancestor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$this->model = $component;
|
$this->model = $component;
|
||||||
} elseif ($component = $model->many_many($rel)) {
|
} elseif ($component = $model->many_many($rel)) {
|
||||||
|
164
tests/search/SearchFilterApplyRelationTest.php
Normal file
164
tests/search/SearchFilterApplyRelationTest.php
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This test class will focus on the when an search filter contains relational component,
|
||||||
|
* such as has_one, has_many, many_many, the SearchFilter::applyRelation($query) will add
|
||||||
|
* the right "join" clauses to $query without the component parent class missing from
|
||||||
|
* "join" chain.
|
||||||
|
*
|
||||||
|
* @package sapphire
|
||||||
|
* @subpackage testing
|
||||||
|
*/
|
||||||
|
class SearchFilterApplyRelationTest extends SapphireTest{
|
||||||
|
static $fixture_file = 'sapphire/tests/search/SearchFilterApplyRelationTest.yml';
|
||||||
|
|
||||||
|
|
||||||
|
function testApplyRelationHasOne(){
|
||||||
|
|
||||||
|
$all = singleton("SearchFilterApplyRelationTest_DO");
|
||||||
|
$context = $all->getDefaultSearchContext();
|
||||||
|
|
||||||
|
$filter = new ExactMatchFilter("SearchFilterApplyRelationTest_HasOneGrantChild.Title");
|
||||||
|
$context->setFilters(null);
|
||||||
|
$context->addFilter($filter);
|
||||||
|
$params = array(
|
||||||
|
"Title" => "I am has_one object",
|
||||||
|
);
|
||||||
|
$results = $context->getResults($params);
|
||||||
|
$this->assertEquals(2, $results->count());
|
||||||
|
}
|
||||||
|
|
||||||
|
function testApplyRelationHasMany(){
|
||||||
|
$all = singleton("SearchFilterApplyRelationTest_DO");
|
||||||
|
$context = $all->getDefaultSearchContext();
|
||||||
|
|
||||||
|
$filter = new PartialMatchFilter("SearchFilterApplyRelationTest_HasManyGrantChildren.Title");
|
||||||
|
$context->setFilters(null);
|
||||||
|
$context->addFilter($filter);
|
||||||
|
$params = array(
|
||||||
|
"Title" => "I am has_many object1",
|
||||||
|
);
|
||||||
|
$results = $context->getResults($params);
|
||||||
|
$this->assertEquals(1, $results->count());
|
||||||
|
$this->assertEquals(1, $results->First()->ID);
|
||||||
|
|
||||||
|
$params = array(
|
||||||
|
"Title" => "I am has_many object3",
|
||||||
|
);
|
||||||
|
$results = $context->getResults($params);
|
||||||
|
$this->assertEquals(1, $results->count());
|
||||||
|
$this->assertEquals(2, $results->First()->ID);
|
||||||
|
|
||||||
|
$params = array(
|
||||||
|
"Title" => "I am has_many object",
|
||||||
|
);
|
||||||
|
$results = $context->getResults($params);
|
||||||
|
$this->assertEquals(2, $results->count());
|
||||||
|
|
||||||
|
$params = array(
|
||||||
|
"Title" => "not exist",
|
||||||
|
);
|
||||||
|
$results = $context->getResults($params);
|
||||||
|
$this->assertEquals(0, $results->count());
|
||||||
|
}
|
||||||
|
|
||||||
|
function testApplyRelationManyMany(){
|
||||||
|
$all = singleton("SearchFilterApplyRelationTest_DO");
|
||||||
|
$context = $all->getDefaultSearchContext();
|
||||||
|
|
||||||
|
$filter = new PartialMatchFilter("SearchFilterApplyRelationTest_ManyManyGrantChildren.Title");
|
||||||
|
$context->setFilters(null);
|
||||||
|
$context->addFilter($filter);
|
||||||
|
$params = array(
|
||||||
|
"Title" => "I am many_many object1",
|
||||||
|
);
|
||||||
|
$results = $context->getResults($params);
|
||||||
|
$this->assertEquals(2, $results->count());
|
||||||
|
|
||||||
|
$params = array(
|
||||||
|
"Title" => "I am many_many object2",
|
||||||
|
);
|
||||||
|
$results = $context->getResults($params);
|
||||||
|
$this->assertEquals(2, $results->count());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchFilterApplyRelationTest_DO extends DataObject implements TestOnly{
|
||||||
|
static $has_one = array(
|
||||||
|
'SearchFilterApplyRelationTest_HasOneGrantChild' => 'SearchFilterApplyRelationTest_HasOneGrantChild'
|
||||||
|
);
|
||||||
|
|
||||||
|
static $has_many = array(
|
||||||
|
'SearchFilterApplyRelationTest_HasManyGrantChildren' => 'SearchFilterApplyRelationTest_HasManyGrantChild'
|
||||||
|
);
|
||||||
|
|
||||||
|
static $many_many = array(
|
||||||
|
'SearchFilterApplyRelationTest_ManyManyGrantChildren' => 'SearchFilterApplyRelationTest_ManyManyGrantChild'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchFilterApplyRelationTest_HasOneParent extends DataObject implements TestOnly{
|
||||||
|
static $db = array(
|
||||||
|
"Title" => "Varchar"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchFilterApplyRelationTest_HasOneChild extends SearchFilterApplyRelationTest_HasOneParent{
|
||||||
|
// This is to create an seperate Table only.
|
||||||
|
static $db = array(
|
||||||
|
"ChildField" => "Varchar"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchFilterApplyRelationTest_HasOneGrantChild extends SearchFilterApplyRelationTest_HasOneChild{
|
||||||
|
// This is to create an seperate Table only.
|
||||||
|
static $db = array(
|
||||||
|
"GrantChildField" => "Varchar"
|
||||||
|
);
|
||||||
|
static $has_many = array(
|
||||||
|
"SearchFilterApplyRelationTest_DOs" => "SearchFilterApplyRelationTest_DO"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchFilterApplyRelationTest_HasManyParent extends DataObject implements TestOnly{
|
||||||
|
static $db = array(
|
||||||
|
"Title" => "Varchar"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchFilterApplyRelationTest_HasManyChild extends SearchFilterApplyRelationTest_HasManyParent{
|
||||||
|
// This is to create an seperate Table only.
|
||||||
|
static $db = array(
|
||||||
|
"ChildField" => "Varchar"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchFilterApplyRelationTest_HasManyGrantChild extends SearchFilterApplyRelationTest_HasManyChild{
|
||||||
|
static $has_one = array(
|
||||||
|
"SearchFilterApplyRelationTest_DO" => "SearchFilterApplyRelationTest_DO"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchFilterApplyRelationTest_ManyManyParent extends DataObject implements TestOnly{
|
||||||
|
static $db = array(
|
||||||
|
"Title" => "Varchar"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchFilterApplyRelationTest_ManyManyChild extends SearchFilterApplyRelationTest_ManyManyParent{
|
||||||
|
// This is to create an seperate Table only.
|
||||||
|
static $db = array(
|
||||||
|
"ChildField" => "Varchar"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchFilterApplyRelationTest_ManyManyGrantChild extends SearchFilterApplyRelationTest_ManyManyChild{
|
||||||
|
// This is to create an seperate Table only.
|
||||||
|
static $db = array(
|
||||||
|
"GrantChildField" => "Varchar"
|
||||||
|
);
|
||||||
|
static $belongs_many_many = array(
|
||||||
|
"SearchFilterApplyRelationTest_DOs" => "SearchFilterApplyRelationTest_DO"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
29
tests/search/SearchFilterApplyRelationTest.yml
Normal file
29
tests/search/SearchFilterApplyRelationTest.yml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
SearchFilterApplyRelationTest_HasOneGrantChild:
|
||||||
|
grant_child:
|
||||||
|
Title: I am has_one object
|
||||||
|
|
||||||
|
SearchFilterApplyRelationTest_HasManyGrantChild:
|
||||||
|
grant_child1:
|
||||||
|
Title: I am has_many object1
|
||||||
|
grant_child2:
|
||||||
|
Title: I am has_many object2
|
||||||
|
grant_child3:
|
||||||
|
Title: I am has_many object3
|
||||||
|
grant_child4:
|
||||||
|
Title: I am has_many object4
|
||||||
|
|
||||||
|
SearchFilterApplyRelationTest_ManyManyGrantChild:
|
||||||
|
grant_child1:
|
||||||
|
Title: I am many_many object1
|
||||||
|
grant_child2:
|
||||||
|
Title: I am many_many object2
|
||||||
|
|
||||||
|
SearchFilterApplyRelationTest_DO:
|
||||||
|
do1:
|
||||||
|
SearchFilterApplyRelationTest_HasOneGrantChild: =>SearchFilterApplyRelationTest_HasOneGrantChild.grant_child
|
||||||
|
SearchFilterApplyRelationTest_HasManyGrantChildren: =>SearchFilterApplyRelationTest_HasManyGrantChild.grant_child1,=>SearchFilterApplyRelationTest_HasManyGrantChild.grant_child2
|
||||||
|
SearchFilterApplyRelationTest_ManyManyGrantChildren: =>SearchFilterApplyRelationTest_ManyManyGrantChild.grant_child1,=>SearchFilterApplyRelationTest_ManyManyGrantChild.grant_child2
|
||||||
|
do2:
|
||||||
|
SearchFilterApplyRelationTest_HasOneGrantChild: =>SearchFilterApplyRelationTest_HasOneGrantChild.grant_child
|
||||||
|
SearchFilterApplyRelationTest_HasManyGrantChildren: =>SearchFilterApplyRelationTest_HasManyGrantChild.grant_child3,=>SearchFilterApplyRelationTest_HasManyGrantChild.grant_child4
|
||||||
|
SearchFilterApplyRelationTest_ManyManyGrantChildren: =>SearchFilterApplyRelationTest_ManyManyGrantChild.grant_child1, =>SearchFilterApplyRelationTest_ManyManyGrantChild.grant_child2
|
Loading…
Reference in New Issue
Block a user