Permalink
Browse files

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.
  • Loading branch information...
1 parent 9b3aebd commit 22efd3848e20b60cdc4173225ee84b2d86ab0be2 @stojg stojg committed with stojg Dec 19, 2012
Showing with 21 additions and 12 deletions.
  1. +18 −12 model/DataObject.php
  2. +3 −0 tests/model/DataObjectTest.php
View
30 model/DataObject.php
@@ -2619,27 +2619,33 @@ public function relObject($fieldPath) {
* 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
3 tests/model/DataObjectTest.php
@@ -1091,6 +1091,9 @@ public function testRelField() {
$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() {

0 comments on commit 22efd38

Please sign in to comment.