mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
ENHANCEMENT Relationship saving in ListboxField (preparing for chosen.js usage), escaping commas in payload when serialising multiple values into a single field
This commit is contained in:
parent
eab8401c7d
commit
6e3ceefbb8
@ -144,17 +144,63 @@ class ListboxField extends DropdownField {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return String
|
* Return the CheckboxSetField value as a string
|
||||||
|
* selected item keys.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
function dataValue() {
|
function dataValue() {
|
||||||
if($this->value && $this->multiple && is_array($this->value)) {
|
if($this->value && is_array($this->value) && $this->multiple) {
|
||||||
return implode(',', $this->value);
|
$filtered = array();
|
||||||
|
foreach($this->value as $item) {
|
||||||
|
if($item) {
|
||||||
|
$filtered[] = str_replace(",", "{comma}", $item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return implode(',', $filtered);
|
||||||
} else {
|
} else {
|
||||||
return parent::dataValue();
|
return parent::dataValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setValue($val) {
|
/**
|
||||||
|
* Save the current value of this field into a DataObject.
|
||||||
|
* If the field it is saving to is a has_many or many_many relationship,
|
||||||
|
* it is saved by setByIDList(), otherwise it creates a comma separated
|
||||||
|
* list for a standard DB text/varchar field.
|
||||||
|
*
|
||||||
|
* @param DataObject $record The record to save into
|
||||||
|
*/
|
||||||
|
function saveInto(DataObject $record) {
|
||||||
|
if($this->multiple) {
|
||||||
|
$fieldname = $this->name;
|
||||||
|
if($fieldname && $record && ($record->has_many($fieldname) || $record->many_many($fieldname))) {
|
||||||
|
$idList = (is_array($this->value)) ? array_values($this->value) : array();
|
||||||
|
$record->$fieldname()->setByIDList($idList);
|
||||||
|
} elseif($fieldname && $record) {
|
||||||
|
if($this->value) {
|
||||||
|
$this->value = str_replace(',', '{comma}', $this->value);
|
||||||
|
$record->$fieldname = implode(",", $this->value);
|
||||||
|
} else {
|
||||||
|
$record->$fieldname = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
parent::saveInto($record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a value into this CheckboxSetField
|
||||||
|
*/
|
||||||
|
function setValue($val, $obj = null) {
|
||||||
|
// If we're not passed a value directly,
|
||||||
|
// we can look for it in a relation method on the object passed as a second arg
|
||||||
|
if(!$val && $obj && $obj instanceof DataObject && $obj->hasMethod($this->name)) {
|
||||||
|
$funcName = $this->name;
|
||||||
|
$val = array_values($obj->$funcName()->getIDList());
|
||||||
|
}
|
||||||
|
|
||||||
if($val) {
|
if($val) {
|
||||||
if(!$this->multiple && is_array($val)) {
|
if(!$this->multiple && is_array($val)) {
|
||||||
throw new InvalidArgumentException('No array values allowed with multiple=false');
|
throw new InvalidArgumentException('No array values allowed with multiple=false');
|
||||||
|
@ -6,7 +6,27 @@
|
|||||||
|
|
||||||
class ListboxFieldTest extends SapphireTest {
|
class ListboxFieldTest extends SapphireTest {
|
||||||
|
|
||||||
protected $extraDataObjects = array('ListboxFieldTest_DataObject');
|
static $fixture_file = 'ListboxFieldTest.yml';
|
||||||
|
|
||||||
|
protected $extraDataObjects = array('ListboxFieldTest_DataObject', 'ListboxFieldTest_Article', 'ListboxFieldTest_Tag');
|
||||||
|
|
||||||
|
function testFieldWithManyManyRelationship() {
|
||||||
|
$articleWithTags = $this->objFromFixture('ListboxFieldTest_Article', 'articlewithtags');
|
||||||
|
$tag1 = $this->objFromFixture('ListboxFieldTest_Tag', 'tag1');
|
||||||
|
$tag2 = $this->objFromFixture('ListboxFieldTest_Tag', 'tag2');
|
||||||
|
$tag3 = $this->objFromFixture('ListboxFieldTest_Tag', 'tag3');
|
||||||
|
$field = new ListboxField("Tags", "Test field", DataObject::get("ListboxFieldTest_Tag")->map()->toArray());
|
||||||
|
$field->setMultiple(true);
|
||||||
|
$field->setValue(null, $articleWithTags);
|
||||||
|
|
||||||
|
$p = new CSSContentParser($field->Field());
|
||||||
|
$tag1xml = $p->getByXpath('//option[@value=' . $tag1->ID . ']');
|
||||||
|
$tag2xml = $p->getByXpath('//option[@value=' . $tag2->ID . ']');
|
||||||
|
$tag3xml = $p->getByXpath('//option[@value=' . $tag3->ID . ']');
|
||||||
|
$this->assertEquals('selected', (string)$tag1xml[0]['selected']);
|
||||||
|
$this->assertEquals('selected', (string)$tag2xml[0]['selected']);
|
||||||
|
$this->assertNull($tag3xml[0]['selected']);
|
||||||
|
}
|
||||||
|
|
||||||
function testSaveIntoNullValueWithMultipleOff() {
|
function testSaveIntoNullValueWithMultipleOff() {
|
||||||
$choices = array('a' => 'a value', 'b' => 'b value','c' => 'c value');
|
$choices = array('a' => 'a value', 'b' => 'b value','c' => 'c value');
|
||||||
@ -63,6 +83,33 @@ class ListboxFieldTest extends SapphireTest {
|
|||||||
$this->assertEquals('a,c', $obj2->Choices);
|
$this->assertEquals('a,c', $obj2->Choices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testSaveIntoManyManyRelation() {
|
||||||
|
$article = $this->objFromFixture('ListboxFieldTest_Article', 'articlewithouttags');
|
||||||
|
$articleWithTags = $this->objFromFixture('ListboxFieldTest_Article', 'articlewithtags');
|
||||||
|
$tag1 = $this->objFromFixture('ListboxFieldTest_Tag', 'tag1');
|
||||||
|
$tag2 = $this->objFromFixture('ListboxFieldTest_Tag', 'tag2');
|
||||||
|
$field = new ListboxField("Tags", "Test field", DataObject::get("ListboxFieldTest_Tag")->map()->toArray());
|
||||||
|
$field->setMultiple(true);
|
||||||
|
|
||||||
|
// Save new relations
|
||||||
|
$field->setValue(array($tag1->ID,$tag2->ID));
|
||||||
|
$field->saveInto($article);
|
||||||
|
$article = Dataobject::get_by_id('ListboxFieldTest_Article', $article->ID, false);
|
||||||
|
$this->assertEquals(array($tag1->ID, $tag2->ID), $article->Tags()->column('ID'));
|
||||||
|
|
||||||
|
// Remove existing relation
|
||||||
|
$field->setValue(array($tag1->ID));
|
||||||
|
$field->saveInto($article);
|
||||||
|
$article = Dataobject::get_by_id('ListboxFieldTest_Article', $article->ID, false);
|
||||||
|
$this->assertEquals(array($tag1->ID), $article->Tags()->column('ID'));
|
||||||
|
|
||||||
|
// Set NULL value
|
||||||
|
$field->setValue(null);
|
||||||
|
$field->saveInto($article);
|
||||||
|
$article = Dataobject::get_by_id('ListboxFieldTest_Article', $article->ID, false);
|
||||||
|
$this->assertEquals(array(), $article->Tags()->column('ID'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException InvalidArgumentException
|
* @expectedException InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
@ -131,3 +178,20 @@ class ListboxFieldTest_DataObject extends DataObject implements TestOnly {
|
|||||||
'Choices' => 'Text'
|
'Choices' => 'Text'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ListboxFieldTest_Article extends DataObject implements TestOnly {
|
||||||
|
static $db = array(
|
||||||
|
"Content" => "Text",
|
||||||
|
);
|
||||||
|
|
||||||
|
static $many_many = array(
|
||||||
|
"Tags" => "ListboxFieldTest_Tag",
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ListboxFieldTest_Tag extends DataObject implements TestOnly {
|
||||||
|
static $belongs_many_many = array(
|
||||||
|
'Articles' => 'ListboxFieldTest_Article'
|
||||||
|
);
|
||||||
|
}
|
13
tests/forms/ListboxFieldTest.yml
Normal file
13
tests/forms/ListboxFieldTest.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
ListboxFieldTest_Tag:
|
||||||
|
tag1:
|
||||||
|
Title: Tag 1
|
||||||
|
tag2:
|
||||||
|
Title: Tag 2
|
||||||
|
tag3:
|
||||||
|
Title: Tag 3
|
||||||
|
ListboxFieldTest_Article:
|
||||||
|
articlewithouttags:
|
||||||
|
Content: Article 1
|
||||||
|
articlewithtags:
|
||||||
|
Content: Article 2
|
||||||
|
Tags: =>ListboxFieldTest_Tag.tag1,=>ListboxFieldTest_Tag.tag2
|
Loading…
x
Reference in New Issue
Block a user