BUG Fix issue with SS_List as datasource for dropdown field

BUG Fix validation issue with CheckboxSetField
Fixes #6166
This commit is contained in:
Damian Mooyman 2016-10-11 14:56:32 +13:00
parent 5580100ade
commit 7368deca8f
No known key found for this signature in database
GPG Key ID: 78B823A10DE27D1A
4 changed files with 95 additions and 23 deletions

View File

@ -333,21 +333,22 @@ class CheckboxSetField extends OptionsetField {
return true; return true;
} }
$sourceArray = $this->getSourceAsArray(); $sourceArray = $this->getSourceAsArray();
$validValues = array_keys($sourceArray);
if (is_array($values)) { if (is_array($values)) {
if (!array_intersect_key($sourceArray, $values)) { if (!array_intersect($validValues, $values)) {
$validator->validationError( $validator->validationError(
$this->name, $this->name,
_t( _t(
'CheckboxSetField.SOURCE_VALIDATION', 'CheckboxSetField.SOURCE_VALIDATION',
"Please select a value within the list provided. '{value}' is not a valid option", "Please select a value within the list provided. '{value}' is not a valid option",
array('value' => implode(' and ', array_diff($sourceArray, $values))) array('value' => implode(' and ', $values))
), ),
"validation" "validation"
); );
return false; return false;
} }
} else { } else {
if (!in_array($this->value, $sourceArray)) { if (!in_array($this->value, $validValues)) {
$validator->validationError( $validator->validationError(
$this->name, $this->name,
_t( _t(

View File

@ -318,14 +318,23 @@ class DropdownField extends FormField {
public function getSourceAsArray() public function getSourceAsArray()
{ {
$source = $this->getSource(); $source = $this->getSource();
// Simplify source if presented as dataobject list
if ($source instanceof SS_List) {
$source = $source->map();
}
if ($source instanceof SS_Map) {
$source = $source->toArray();
}
if (is_array($source)) { if (is_array($source)) {
return $source; return $source;
} else { }
$sourceArray = array(); $sourceArray = array();
foreach ($source as $key => $value) { foreach ($source as $key => $value) {
$sourceArray[$key] = $value; $sourceArray[$key] = $value;
} }
}
return $sourceArray; return $sourceArray;
} }

View File

@ -177,28 +177,65 @@ class CheckboxSetFieldTest extends SapphireTest {
$tag1 = $this->objFromFixture('CheckboxSetFieldTest_Tag', 'tag1'); $tag1 = $this->objFromFixture('CheckboxSetFieldTest_Tag', 'tag1');
$tag2 = $this->objFromFixture('CheckboxSetFieldTest_Tag', 'tag2'); $tag2 = $this->objFromFixture('CheckboxSetFieldTest_Tag', 'tag2');
$tag3 = $this->objFromFixture('CheckboxSetFieldTest_Tag', 'tag3'); $tag3 = $this->objFromFixture('CheckboxSetFieldTest_Tag', 'tag3');
$field = CheckboxSetField::create('Test', 'Testing', $checkboxTestArticle->Tags() ->map()); $field = CheckboxSetField::create('Test', 'Testing', $checkboxTestArticle->Tags());
$validator = new RequiredFields(); $validator = new RequiredFields();
$field->setValue(array( $field->setValue(array( $tag1->ID, $tag2->ID ));
$tag1->ID => $tag1->ID, $isValid = $field->validate($validator);
$tag2->ID => $tag2->ID
));
$this->assertTrue( $this->assertTrue(
$field->validate($validator), $isValid,
'Validates values in source map' 'Validates values in source map'
); );
//invalid value should fail
// Invalid value should fail
$validator = new RequiredFields();
$fakeID = CheckboxSetFieldTest_Tag::get()->max('ID') + 1; $fakeID = CheckboxSetFieldTest_Tag::get()->max('ID') + 1;
$field->setValue(array($fakeID => $fakeID)); $field->setValue(array($fakeID));
$this->assertFalse( $this->assertFalse(
$field->validate($validator), $field->validate($validator),
'Field does not valid values outside of source map' 'Field does not valid values outside of source map'
); );
$errors = $validator->getErrors();
$error = reset($errors);
$this->assertEquals(
"Please select a value within the list provided. '$fakeID' is not a valid option",
$error['message']
);
// Multiple invalid values should fail
$validator = new RequiredFields();
$fakeID = CheckboxSetFieldTest_Tag::get()->max('ID') + 1;
$field->setValue(array($fakeID, $tag3->ID));
$this->assertFalse(
$field->validate($validator),
'Field does not valid values outside of source map'
);
$errors = $validator->getErrors();
$error = reset($errors);
$this->assertEquals(
"Please select a value within the list provided. '{$fakeID} and {$tag3->ID}' is not a valid option",
$error['message']
);
// Invalid value with non-array value
$validator = new RequiredFields();
$field->setValue($fakeID);
$this->assertFalse(
$field->validate($validator),
'Field does not valid values outside of source map'
);
$errors = $validator->getErrors();
$error = reset($errors);
$this->assertEquals(
"Please select a value within the list provided. '{$fakeID}' is not a valid option",
$error['message']
);
// non valid value included with valid options should succeed // non valid value included with valid options should succeed
$validator = new RequiredFields();
$field->setValue(array( $field->setValue(array(
$tag1->ID => $tag1->ID, $tag1->ID,
$tag2->ID => $tag2->ID, $tag2->ID,
$tag3->ID => $tag3->ID $tag3->ID
)); ));
$this->assertTrue( $this->assertTrue(
$field->validate($validator), $field->validate($validator),

View File

@ -6,12 +6,37 @@
class DropdownFieldTest extends SapphireTest { class DropdownFieldTest extends SapphireTest {
public function testGetSource() { public function testGetSource() {
$source = array(1=>'one'); $source = array(1=>'one', 2 => 'two');
$field = new DropdownField('Field', null, $source); $field = new DropdownField('Field', null, $source);
$this->assertEquals( $this->assertEquals(
$field->getSource(), $source,
$field->getSource()
);
$this->assertEquals(
$source,
$field->getSourceAsArray()
);
$items = new ArrayList([
[ 'ID' => 1, 'Title' => 'ichi', 'OtherField' => 'notone' ],
[ 'ID' => 2, 'Title' => 'ni', 'OtherField' => 'nottwo' ],
]);
$field->setSource($items);
$this->assertEquals(
$field->getSourceAsArray(),
array( array(
1 => 'one' 1 => 'ichi',
2 => 'ni',
)
);
$map = new SS_Map($items, 'ID', 'OtherField');
$field->setSource($map);
$this->assertEquals(
$field->getSourceAsArray(),
array(
1 => 'notone',
2 => 'nottwo',
) )
); );
} }