diff --git a/model/DataObject.php b/model/DataObject.php index 773c91b4889..ea10a745cab 100644 --- a/model/DataObject.php +++ b/model/DataObject.php @@ -1342,7 +1342,38 @@ public function getComponentsQuery($componentName, $filter = "", $sort = "", $jo return singleton($componentClass)->extendedSQL($combinedFilter, $sort, $limit, $join); } - + + /** + * Find the foreign class of a relation on this DataObject, regardless of the relation type. + * + * @param $relationName Relation name. + * @return string Class name, or null if not found. + */ + public function getRelationClass($relationName) { + // Go through all relationship configuration fields. + $candidates = array_merge( + ($relations = Config::inst()->get($this->class, 'has_one')) ? $relations : array(), + ($relations = Config::inst()->get($this->class, 'has_many')) ? $relations : array(), + ($relations = Config::inst()->get($this->class, 'many_many')) ? $relations : array(), + ($relations = Config::inst()->get($this->class, 'belongs_many_many')) ? $relations : array(), + ($relations = Config::inst()->get($this->class, 'belongs_to')) ? $relations : array() + ); + + if (isset($candidates[$relationName])) { + $remoteClass = $candidates[$relationName]; + + // If dot notation is present, extract just the first part that contains the class. + if(($fieldPos = strpos($remoteClass, '.'))!==false) { + return substr($remoteClass, 0, $fieldPos); + } + + // Otherwise just return the class + return $remoteClass; + } + + return null; + } + /** * Tries to find the database key on another object that is used to store a relationship to this class. If no join * field can be found it defaults to 'ParentID'. diff --git a/tests/model/DataObjectTest.php b/tests/model/DataObjectTest.php index 2c2f8072eb1..87f6bccba9c 100644 --- a/tests/model/DataObjectTest.php +++ b/tests/model/DataObjectTest.php @@ -183,6 +183,15 @@ function testGetSubclassFields() { $this->assertEquals($this->idFromFixture('DataObjectTest_Team', 'team1'), $captain1->FavouriteTeamID); } + function testGetRelationClass() { + $obj = new DataObjectTest_Player(); + $this->assertEquals(singleton('DataObjectTest_Player')->getRelationClass('FavouriteTeam'), 'DataObjectTest_Team', 'has_one is properly inspected'); + $this->assertEquals(singleton('DataObjectTest_Company')->getRelationClass('CurrentStaff'), 'DataObjectTest_Staff', 'has_many is properly inspected'); + $this->assertEquals(singleton('DataObjectTest_Team')->getRelationClass('Players'), 'DataObjectTest_Player', 'many_many is properly inspected'); + $this->assertEquals(singleton('DataObjectTest_Player')->getRelationClass('Teams'), 'DataObjectTest_Team', 'belongs_many_many is properly inspected'); + $this->assertEquals(singleton('DataObjectTest_CEO')->getRelationClass('Company'), 'DataObjectTest_Company', 'belongs_to is properly inspected'); + } + function testGetHasOneRelations() { $captain1 = $this->objFromFixture("DataObjectTest_Player", "captain1"); /* There will be a field called (relname)ID that contains the ID of the object linked to via the has_one relation */