ENHANCEMENT Allow selecting a single field from ComponentSet::getExtraData()

MINOR Removed redundant code from ComplexTableField
MINOR Added more test cases for extra data on ComplexTableFieldTest


git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/2.3@75759 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sean Harvey 2009-04-30 21:14:34 +00:00 committed by Sam Minnee
parent 0cafc79346
commit 7a4b18090c
3 changed files with 60 additions and 52 deletions

View File

@ -63,30 +63,36 @@ class ComponentSet extends DataObjectSet {
/**
* Find the extra field data for a single row of the relationship
* join table, given the known child ID.
*
* @todo This should return casted fields, like Enum, Varchar, Date
* instead of just the raw value of the field.
*
* @param string $componentName The name of the component
* @param int $childID The ID of the child for the relationship
* @return array Map of fieldName => fieldValue
* @param string|null $fieldName To get a specific extra data field, specify it here
* @return array|string Array of field => value or single string of value
*/
function getExtraData($componentName, $childID) {
function getExtraData($componentName, $childID, $fieldName = null) {
$ownerObj = $this->ownerObj;
$parentField = $this->ownerClass . 'ID';
$childField = ($this->childClass == $this->ownerClass) ? 'ChildID' : ($this->childClass . 'ID');
$result = array();
if(!$componentName) return false;
// @todo Optimize into a single query instead of one per extra field
$extraFields = $ownerObj->many_many_extraFields($componentName);
if($extraFields) {
foreach($extraFields as $fieldName => $dbFieldSpec) {
$query = DB::query("SELECT $fieldName FROM {$this->tableName} WHERE $parentField = '{$this->ownerObj->ID}' AND $childField = '{$childID}'");
$value = $query->value();
$result[$fieldName] = $value;
}
}
if(!$extraFields) return false;
return $result;
if($fieldName && !empty($extraFields[$fieldName])) {
$query = DB::query("SELECT $fieldName FROM {$this->tableName} WHERE $parentField = '{$this->ownerObj->ID}' AND $childField = '{$childID}'");
return $query->value();
} else {
$fields = array();
foreach($extraFields as $fieldName => $fieldSpec) {
$query = DB::query("SELECT $fieldName FROM {$this->tableName} WHERE $parentField = '{$this->ownerObj->ID}' AND $childField = '{$childID}'");
$fields[$fieldName] = $query->value();
}
return $fields;
}
}
/**

View File

@ -455,42 +455,22 @@ JS;
* this method.
*/
function getCustomFieldsFor($childData) {
if($this->detailFormFields instanceof Fieldset) {
if($this->detailFormFields instanceof FieldSet) {
return $this->detailFormFields;
} else {
$fieldsMethod = $this->detailFormFields;
}
$fieldsMethod = $this->detailFormFields;
if(!is_string($fieldsMethod)) {
$this->detailFormFields = 'getCMSFields';
$fieldsMethod = 'getCMSFields';
}
if(!$childData->hasMethod($fieldsMethod)) {
$fieldsMethod = 'getCMSFields';
}
$fields = $childData->$fieldsMethod();
if(!is_string($fieldsMethod)) {
$this->detailFormFields = 'getCMSFields';
$fieldsMethod = 'getCMSFields';
}
if(!$this->relationAutoSetting) {
return $fields;
if(!$childData->hasMethod($fieldsMethod)) {
$fieldsMethod = 'getCMSFields';
}
if($this->sourceID()) {
$parentClass = DataObject::get_by_id($this->getParentClass(), $this->sourceID());
} else {
$parentClass = singleton($this->getParentClass());
}
$manyManyExtraFields = $parentClass->many_many_extraFields($this->name);
if($manyManyExtraFields) {
foreach($manyManyExtraFields as $fieldName => $fieldSpec) {
$dbField = new Varchar('ctf[extraFields][' . $fieldName . ']');
$fields->addFieldToTab('Root.Main', $dbField->scaffoldFormField($fieldName));
}
}
return $fields;
return $childData->$fieldsMethod();
}
function getFieldsFor($childData) {
@ -531,13 +511,24 @@ JS;
$detailFields = $this->getCustomFieldsFor($childData);
// Loading of extra field values for editing an existing record
if($manyManyRelationName && $childData->ID) {
if($manyManyRelationName) {
$manyManyComponentSet = $parentClass->getManyManyComponents($manyManyRelationName);
$extraData = $manyManyComponentSet->getExtraData($manyManyRelationName, $childData->ID);
$extraFieldsSpec = $parentClass->many_many_extraFields($this->name);
if($extraData) foreach($extraData as $fieldName => $fieldValue) {
$field = $detailFields->dataFieldByName('ctf[extraFields][' . $fieldName . ']');
$field->setValue($fieldValue);
$extraData = null;
if($childData && $childData->ID) {
$extraData = $manyManyComponentSet->getExtraData($manyManyRelationName, $childData->ID);
}
if($extraFieldsSpec) foreach($extraFieldsSpec as $fieldName => $fieldSpec) {
// @todo Create the proper DBField type instead of hardcoding Varchar
$fieldObj = new Varchar($fieldName);
if(isset($extraData[$fieldName])) {
$fieldObj->setValue($extraData[$fieldName]);
}
$detailFields->addFieldToTab('Root.Main', $fieldObj->scaffoldFormField($fieldName));
}
}

View File

@ -47,10 +47,10 @@ class ComplexTableFieldTest extends FunctionalTest {
$parser = new CSSContentParser($detailForm);
/* There is a field called "Name", which is a text input */
$this->assertNotNull($parser->getBySelector('#Name input'), 'There is a field called "Name", which is a text input');
$this->assertEquals(count($parser->getBySelector('#Name input')), 1, 'There is a field called "Name", which is a text input');
/* There is a field called "Role" - this field is the extra field for $many_many_extraFields */
$this->assertNotNull($parser->getBySelector('#Role input'), 'There is a field called "Role" - this field is the extra field for $many_many_extraFields');
$this->assertEquals(count($parser->getBySelector('#Role input')), 1, 'There is a field called "Role" - this field is the extra field for $many_many_extraFields');
}
function testAddingManyManyNewPlayerWithExtraData() {
@ -60,7 +60,9 @@ class ComplexTableFieldTest extends FunctionalTest {
'Name' => 'Bobby Joe',
'ctf' => array(
'extraFields' => array(
'Role' => 'Goalie'
'Role' => 'Goalie',
'Position' => 'Player',
'DateJoined' => '2008-10-10'
),
'ClassName' => 'ComplexTableFieldTest_Player',
'manyManyRelation' => 'Players',
@ -83,7 +85,14 @@ class ComplexTableFieldTest extends FunctionalTest {
/* The extra fields have the correct value */
$extraFields = $teams->getExtraData('Teams', $team->ID);
$this->assertEquals($extraFields['Role'], 'Goalie', 'The extra fields have the correct value');
/* There are 3 extra fields */
$this->assertEquals(count($extraFields), 3, 'There are 3 extra fields');
/* The three extra fields have the correct values */
$this->assertEquals($extraFields['Role'], 'Goalie', 'The extra field "Role" has the correct value');
$this->assertEquals($extraFields['Position'], 'Player', 'The extra field "Position" has the correct value');
$this->assertEquals($extraFields['DateJoined'], '2008-10-10', 'The extra field "DateJoined" has the correct value');
}
function testAddingHasManyData() {
@ -201,7 +210,9 @@ class ComplexTableFieldTest_Player extends DataObject implements TestOnly {
public static $many_many_extraFields = array(
'Teams' => array(
'Role' => 'Varchar(100)'
'Role' => 'Varchar(100)',
'Position' => "Enum('Admin,Player,Coach','Admin')",
'DateJoined' => 'Date'
)
);