From 0d4c71f393a9d73981b9cf25287e3213ffddeb1a Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Mon, 2 May 2016 16:41:30 +1200 Subject: [PATCH] API Filtering on invalid relation is no longer a silent error Fixes #5331 --- model/DataList.php | 2 +- model/DataQuery.php | 14 ++++++++++---- tests/model/DataListTest.php | 11 +++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/model/DataList.php b/model/DataList.php index 7fc8d6549..d4072437f 100644 --- a/model/DataList.php +++ b/model/DataList.php @@ -503,7 +503,7 @@ class DataList extends ViewableData implements SS_List, SS_Filterable, SS_Sortab $fieldName = array_pop($relations); // Apply - $relationModelName = $query->applyRelation($field, $linearOnly); + $relationModelName = $query->applyRelation($relations, $linearOnly); // Find the db field the relation belongs to $className = ClassInfo::table_for_object_field($relationModelName, $fieldName); diff --git a/model/DataQuery.php b/model/DataQuery.php index 77913baeb..f3b14294c 100644 --- a/model/DataQuery.php +++ b/model/DataQuery.php @@ -641,16 +641,20 @@ class DataQuery { * mappings to the query object state. This has to be called * in any overloaded {@link SearchFilter->apply()} methods manually. * - * @param String|array $relation The array/dot-syntax relation to follow + * @param string|array $relation The array/dot-syntax relation to follow * @param bool $linearOnly Set to true to restrict to linear relations only. Set this * if this relation will be used for sorting, and should not include duplicate rows. - * @return The model class of the related item + * @return string The model class of the related item */ public function applyRelation($relation, $linearOnly = false) { // NO-OP - if(!$relation) return $this->dataClass; + if(!$relation) { + return $this->dataClass; + } - if(is_string($relation)) $relation = explode(".", $relation); + if(is_string($relation)) { + $relation = explode(".", $relation); + } $modelClass = $this->dataClass; @@ -682,6 +686,8 @@ class DataQuery { ); $modelClass = $componentClass; + } else { + throw new InvalidArgumentException("$rel is not a relation on model $modelClass"); } } diff --git a/tests/model/DataListTest.php b/tests/model/DataListTest.php index dcf709f05..a0d84f4ae 100755 --- a/tests/model/DataListTest.php +++ b/tests/model/DataListTest.php @@ -833,6 +833,17 @@ class DataListTest extends SapphireTest { $this->assertEquals('007', $list->first()->ShirtNumber); } + public function testFilterOnInvalidRelation() { + $this->setExpectedException( + 'InvalidArgumentException', + "MascotAnimal is not a relation on model DataObjectTest_Team" + ); + // Filter on missing relation 'MascotAnimal' + DataObjectTest_Team::get() + ->filter('MascotAnimal.Name', 'Richard') + ->toArray(); + } + public function testFilterAndExcludeById() { $id = $this->idFromFixture('DataObjectTest_SubTeam', 'subteam1'); $list = DataObjectTest_SubTeam::get()->filter('ID', $id);