BUG Calling DataObject::relField() on a object with an empty relation list

This causes a 'Fatal error: Call to a member function hasMethod() on a non-object'.

This can happen when displaying a field in a gridfield on a belongs_to relationship.
This commit is contained in:
Stig Lindqvist 2012-12-19 16:40:13 +13:00 committed by Stig Lindqvist
parent 9b3aebd310
commit 22efd3848e
2 changed files with 21 additions and 12 deletions

View File

@ -2619,27 +2619,33 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
* The path to the related field is specified with dot separated syntax (eg: Parent.Child.Child.FieldName)
*
* @param $fieldPath string
* @return string
* @return string | null - will return null on a missing value
*/
public function relField($fieldName) {
$component = $this;
// We're dealing with relations here so we traverse the dot syntax
if(strpos($fieldName, '.') !== false) {
$parts = explode('.', $fieldName);
$fieldName = array_pop($parts);
// Traverse dot syntax
foreach($parts as $relation) {
if($component instanceof SS_List) {
if(method_exists($component,$relation)) $component = $component->$relation();
else $component = $component->relation($relation);
} else {
$relations = explode('.', $fieldName);
$fieldName = array_pop($relations);
foreach($relations as $relation) {
// Bail if any of the below sets a $component to a null object
if($component instanceof SS_List && !method_exists($component, $relation)) {
$component = $component->relation($relation);
// Just call the method and hope for the best
} else {
$component = $component->$relation();
}
}
}
if ($component->hasMethod($fieldName)) return $component->$fieldName();
// Bail if the component is null
if(!$component) {
return null;
}
if($component->hasMethod($fieldName)) {
return $component->$fieldName();
}
return $component->$fieldName;
}

View File

@ -1091,6 +1091,9 @@ class DataObjectTest extends SapphireTest {
$player = $this->objFromFixture('DataObjectTest_Player', 'player2');
// Test that we can traverse more than once, and that arbitrary methods are okay
$this->assertEquals("Team 1", $player->relField('Teams.First.Title'));
$newPlayer = new DataObjectTest_Player();
$this->assertNull($newPlayer->relField('Teams.First.Title'));
}
public function testRelObject() {