From ed07bfadb3ddf53c118a3a65bb11db67cc8091a8 Mon Sep 17 00:00:00 2001 From: Loz Calver Date: Mon, 19 Jan 2015 20:55:38 +0000 Subject: [PATCH] FIX: DataObject::db returned fields in incorrect order, with incorrect data types --- model/DataObject.php | 51 ++++++++++++++++++++++++---------- tests/model/DataObjectTest.php | 10 +++++++ 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/model/DataObject.php b/model/DataObject.php index 0bd7b19dde8..3d2ac805789 100644 --- a/model/DataObject.php +++ b/model/DataObject.php @@ -1665,10 +1665,15 @@ public function belongs_to($component = null, $classOnly = true) { * @return array The database fields */ public function db($fieldName = null) { + if($fieldName) { + $dataType = $this->dbField($fieldName); + return $dataType ? $dataType : array(); + } + $classes = ClassInfo::ancestry($this, true); $items = array(); - foreach(array_reverse($classes) as $class) { + foreach($classes as $class) { if(isset(self::$_cache_db[$class])) { $dbItems = self::$_cache_db[$class]; } else { @@ -1676,27 +1681,43 @@ public function db($fieldName = null) { self::$_cache_db[$class] = $dbItems; } - if($fieldName) { - if(isset($dbItems[$fieldName])) { - return $dbItems[$fieldName]; - } - } else { - // Validate the data - foreach($dbItems as $k => $v) { - if(!is_string($k) || is_numeric($k) || !is_string($v)) { - user_error("$class::\$db has a bad entry: " - . var_export($k,true). " => " . var_export($v,true) . ". Each map key should be a" - . " property name, and the map value should be the property type.", E_USER_ERROR); - } + // Validate the data + foreach($dbItems as $k => $v) { + if(!is_string($k) || is_numeric($k) || !is_string($v)) { + user_error("$class::\$db has a bad entry: " + . var_export($k,true). " => " . var_export($v,true) . ". Each map key should be a" + . " property name, and the map value should be the property type.", E_USER_ERROR); } - - $items = isset($items) ? array_merge((array) $items, $dbItems) : $dbItems; } + + $items = isset($items) ? array_merge((array) $items, $dbItems) : $dbItems; } return $items; } + /** + * Return the data type for the given database field + * @param string fieldName + * @return string|null + */ + public function dbField($fieldName) { + $classes = ClassInfo::ancestry($this, true); + + foreach(array_reverse($classes) as $class) { + if(isset(self::$_cache_db[$class])) { + $dbItems = self::$_cache_db[$class]; + } else { + $dbItems = (array) Config::inst()->get($class, 'db', Config::UNINHERITED); + self::$_cache_db[$class] = $dbItems; + } + + if(isset($dbItems[$fieldName])) { + return $dbItems[$fieldName]; + } + } + } + /** * Gets the class of a one-to-many relationship. If no $component is specified then an array of all the one-to-many * relationships and their classes will be returned. diff --git a/tests/model/DataObjectTest.php b/tests/model/DataObjectTest.php index 275e643d6d3..8daffecce8f 100644 --- a/tests/model/DataObjectTest.php +++ b/tests/model/DataObjectTest.php @@ -38,9 +38,19 @@ public function testDb() { $this->assertEquals('Text', $obj->db('Comment')); $obj = new DataObjectTest_ExtendedTeamComment(); + $dbFields = $obj->db(); // Assert overloaded fields have correct data type $this->assertEquals('HTMLText', $obj->db('Comment')); + $this->assertEquals('HTMLText', $dbFields['Comment'], + 'Calls to DataObject::db without a field specified return correct data types'); + + // assertEquals doesn't verify the order of array elements, so access keys manually to check order: + // expected: array('Name' => 'Varchar', 'Comment' => 'HTMLText') + reset($dbFields); + $this->assertEquals('Name', key($dbFields), 'DataObject::db returns fields in correct order'); + next($dbFields); + $this->assertEquals('Comment', key($dbFields), 'DataObject::db returns fields in correct order'); } public function testValidObjectsForBaseFields() {