mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
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:
parent
9b3aebd310
commit
22efd3848e
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user