mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
BUGFIX Excluding names of CompositeDBFields from DataObject::custom_database_fields() and including the actually generated columns in CompositeDBField->compositeDatabaseFields(). This is necessary for DataObject->hasField() to work correctly and avoid generated queries with wrong column identifiers
BUGFIX Querying db() in DataObject->hasField() in addition to hasDatabaseField(), as the two might differ when CompositeDBFields are used MINOR Added DataObjectTest->hasDatabaseField() git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@78235 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
e1e9295fb5
commit
634ff10c89
@ -182,15 +182,37 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all database fields explicitly defined on a class in {@link DataObject::$db} and {@link DataObject::$has_one}
|
||||
* Get all database columns explicitly defined on a class in {@link DataObject::$db}
|
||||
* and {@link DataObject::$has_one}. Resolves instances of {@link CompositeDBField}
|
||||
* into the actual database fields, rather than the name of the field which
|
||||
* might not equate a database column.
|
||||
*
|
||||
* @uses CompositeDBField->compositeDatabaseFields()
|
||||
*
|
||||
* @param string $class
|
||||
* @return array
|
||||
* @return array Map of fieldname to specification, similiar to {@link DataObject::$db}.
|
||||
*/
|
||||
public static function custom_database_fields($class) {
|
||||
$fields = Object::uninherited_static($class, 'db');
|
||||
|
||||
// Remove CompositeDBField instances, and replace with the actually used fields
|
||||
if($fields) foreach($fields as $fieldName => $fieldSpec) {
|
||||
$fieldClass = singleton($class)->db($fieldName);
|
||||
// Strip off any parameters
|
||||
if(strpos('(', $fieldClass) !== FALSE) $fieldClass = substr(0,strpos('(', $fieldClass), $fieldClass);
|
||||
if(ClassInfo::classImplements($fieldClass, 'CompositeDBField')) {
|
||||
// Remove the original fieldname, its not an actual database column
|
||||
unset($fields[$fieldName]);
|
||||
// Add all composite columns
|
||||
$compositeFields = singleton($fieldClass)->compositeDatabaseFields();
|
||||
if($compositeFields) foreach($compositeFields as $compositeName => $spec) {
|
||||
$fields["{$fieldName}{$compositeName}"] = $spec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add has_one relationships
|
||||
$hasOne = Object::uninherited_static($class, 'has_one');
|
||||
|
||||
if($hasOne) foreach(array_keys($hasOne) as $field) {
|
||||
$fields[$field . 'ID'] = 'ForeignKey';
|
||||
}
|
||||
@ -1964,7 +1986,12 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
* @return boolean True if the given field exists
|
||||
*/
|
||||
public function hasField($field) {
|
||||
return array_key_exists($field, $this->record) || $this->hasDatabaseField($field) || $this->hasMethod("get{$field}");
|
||||
return (
|
||||
array_key_exists($field, $this->record)
|
||||
|| $this->hasDatabaseField($field)
|
||||
|| array_key_exists($field, $this->db())
|
||||
|| $this->hasMethod("get{$field}")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -692,6 +692,38 @@ class DataObjectTest extends SapphireTest {
|
||||
}
|
||||
}
|
||||
|
||||
function hasDatabaseField() {
|
||||
$team = singleton('DataObjectTest_Team');
|
||||
$subteam = singleton('DataObjectTest_SubTeam');
|
||||
|
||||
$this->assertTrue(
|
||||
$team->hasDatabaseField('Title'),
|
||||
"hasOwnDatabaseField() works with \$db fields"
|
||||
);
|
||||
$this->assertTrue(
|
||||
$team->hasDatabaseField('CaptainID'),
|
||||
"hasOwnDatabaseField() works with \$has_one fields"
|
||||
);
|
||||
$this->assertFalse(
|
||||
$team->hasDatabaseField('NonExistentField'),
|
||||
"hasOwnDatabaseField() doesn't detect non-existend fields"
|
||||
);
|
||||
$this->assertTrue(
|
||||
$team->hasDatabaseField('DecoratedDatabaseField'),
|
||||
"hasOwnDatabaseField() works with decorated fields"
|
||||
);
|
||||
$this->assertFalse(
|
||||
$team->hasDatabaseField('SubclassDatabaseField'),
|
||||
"hasOwnDatabaseField() doesn't pick up fields in subclasses on parent class"
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$subteam->hasDatabaseField('SubclassDatabaseField'),
|
||||
"hasOwnDatabaseField() picks up fields in subclasses"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DataObjectTest_Player extends Member implements TestOnly {
|
||||
|
Loading…
x
Reference in New Issue
Block a user