mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
FIX: CheckboxSetField can now save into DBMultiEnum
Fixes https://github.com/silverstripe/silverstripe-framework/issues/1489
This commit is contained in:
parent
6bd2281b83
commit
76255c9fb5
@ -4,6 +4,7 @@ namespace SilverStripe\Forms;
|
|||||||
|
|
||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
use SilverStripe\ORM\DataObjectInterface;
|
use SilverStripe\ORM\DataObjectInterface;
|
||||||
|
use SilverStripe\ORM\FieldType\DBMultiEnum;
|
||||||
use SilverStripe\ORM\Relation;
|
use SilverStripe\ORM\Relation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,7 +99,15 @@ abstract class MultiSelectField extends SelectField
|
|||||||
$value = array_values($relation->getIDList());
|
$value = array_values($relation->getIDList());
|
||||||
parent::setValue($value);
|
parent::setValue($value);
|
||||||
} elseif ($record->hasField($fieldName)) {
|
} elseif ($record->hasField($fieldName)) {
|
||||||
$value = $this->stringDecode($record->$fieldName);
|
// Load dataValue from field... a CSV for DBMultiEnum
|
||||||
|
if ($record->obj($fieldName) instanceof DBMultiEnum) {
|
||||||
|
$value = $this->csvDecode($record->$fieldName);
|
||||||
|
|
||||||
|
// ... JSON-encoded string for other fields
|
||||||
|
} else {
|
||||||
|
$value = $this->stringDecode($record->$fieldName);
|
||||||
|
}
|
||||||
|
|
||||||
parent::setValue($value);
|
parent::setValue($value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,8 +138,14 @@ abstract class MultiSelectField extends SelectField
|
|||||||
// Save ids into relation
|
// Save ids into relation
|
||||||
$relation->setByIDList($items);
|
$relation->setByIDList($items);
|
||||||
} elseif ($record->hasField($fieldName)) {
|
} elseif ($record->hasField($fieldName)) {
|
||||||
// Save dataValue into field
|
// Save dataValue into field... a CSV for DBMultiEnum
|
||||||
$record->$fieldName = $this->stringEncode($items);
|
if ($record->obj($fieldName) instanceof DBMultiEnum) {
|
||||||
|
$record->$fieldName = $this->csvEncode($items);
|
||||||
|
|
||||||
|
// ... JSON-encoded string for other fields
|
||||||
|
} else {
|
||||||
|
$record->$fieldName = $this->stringEncode($items);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +184,45 @@ abstract class MultiSelectField extends SelectField
|
|||||||
throw new \InvalidArgumentException("Invalid string encoded value for multi select field");
|
throw new \InvalidArgumentException("Invalid string encoded value for multi select field");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode a list of values into a string as a comma separated list.
|
||||||
|
* Commas will be stripped from the items passed in
|
||||||
|
*
|
||||||
|
* @param array $value
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
protected function csvEncode($value)
|
||||||
|
{
|
||||||
|
if (!$value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return implode(
|
||||||
|
',',
|
||||||
|
array_map(
|
||||||
|
function ($x) {
|
||||||
|
return str_replace(',', '', $x);
|
||||||
|
},
|
||||||
|
array_values($value)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a list of values from a comma separated string.
|
||||||
|
* Spaces are trimmed
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function csvDecode($value)
|
||||||
|
{
|
||||||
|
if (!$value) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return preg_split('/\s*,\s*/', trim($value));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate this field
|
* Validate this field
|
||||||
*
|
*
|
||||||
|
16
tests/php/Forms/CheckboxFieldtest/MutiEnumArticle.php
Normal file
16
tests/php/Forms/CheckboxFieldtest/MutiEnumArticle.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Forms\Tests\CheckboxSetFieldTest;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
|
||||||
|
class MultiEnumArticle extends DataObject implements TestOnly
|
||||||
|
{
|
||||||
|
private static $table_name = 'CheckboxSetFieldTest_MultiEnumArticle';
|
||||||
|
|
||||||
|
private static $db = array(
|
||||||
|
"Content" => "Text",
|
||||||
|
"Colours" => "MultiEnum('Red,Blue,Green')",
|
||||||
|
);
|
||||||
|
}
|
98
tests/php/Forms/CheckboxSetFieldMultiEnumTest.php
Normal file
98
tests/php/Forms/CheckboxSetFieldMultiEnumTest.php
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Forms\Tests;
|
||||||
|
|
||||||
|
use SilverStripe\Forms\Tests\CheckboxSetFieldTest\MultiEnumArticle;
|
||||||
|
use SilverStripe\ORM\DB;
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Forms\CheckboxSetField;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\Form;
|
||||||
|
use SilverStripe\ORM\Connect\MySQLDatabase;
|
||||||
|
|
||||||
|
class CheckboxSetFieldMulitEnumTest extends SapphireTest
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $usesDatabase = true;
|
||||||
|
|
||||||
|
public static function getExtraDataObjects()
|
||||||
|
{
|
||||||
|
// Don't add this for other database
|
||||||
|
if (DB::get_conn() instanceof MySQLDatabase) {
|
||||||
|
return [
|
||||||
|
MultiEnumArticle::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
if (!(DB::get_conn() instanceof MySQLDatabase)) {
|
||||||
|
$this->markTestSkipped('DBMultiEnum only supported by MySQL');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parent::setUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tearDown()
|
||||||
|
{
|
||||||
|
if (!(DB::get_conn() instanceof MySQLDatabase)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parent::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLoadDataFromMultiEnum()
|
||||||
|
{
|
||||||
|
$article = new MultiEnumArticle();
|
||||||
|
$article->Colours = 'Red,Green';
|
||||||
|
|
||||||
|
$field = new CheckboxSetField(
|
||||||
|
'Colours',
|
||||||
|
'Colours',
|
||||||
|
[
|
||||||
|
'Red' => 'Red',
|
||||||
|
'Blue' => 'Blue',
|
||||||
|
'Green' => 'Green',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$form = new Form(
|
||||||
|
Controller::curr(),
|
||||||
|
'Form',
|
||||||
|
new FieldList($field),
|
||||||
|
new FieldList()
|
||||||
|
);
|
||||||
|
$form->loadDataFrom($article);
|
||||||
|
$value = $field->Value();
|
||||||
|
$this->assertEquals(['Red', 'Green'], $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSavingIntoMultiEnum()
|
||||||
|
{
|
||||||
|
$field = new CheckboxSetField(
|
||||||
|
'Colours',
|
||||||
|
'Colours',
|
||||||
|
[
|
||||||
|
'Red' => 'Red',
|
||||||
|
'Blue' => 'Blue',
|
||||||
|
'Green' => 'Green',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$article = new MultiEnumArticle();
|
||||||
|
$field->setValue(array('Red' => 'Red', 'Blue' => 'Blue'));
|
||||||
|
$field->saveInto($article);
|
||||||
|
$article->write();
|
||||||
|
|
||||||
|
$dbValue = DB::query(
|
||||||
|
sprintf(
|
||||||
|
'SELECT "Colours" FROM "CheckboxSetFieldTest_MultiEnumArticle" WHERE "ID" = %s',
|
||||||
|
$article->ID
|
||||||
|
)
|
||||||
|
)->value();
|
||||||
|
|
||||||
|
// JSON encoded values
|
||||||
|
$this->assertEquals('Red,Blue', $dbValue);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user