Permalink
Browse files

ENHANCEMENT Relationship saving in ListboxField (preparing for chosen…

….js usage), escaping commas in payload when serialising multiple values into a single field
  • Loading branch information...
1 parent eab8401 commit 6e3ceefbb86b048bb9b12b414103fa578a8f2504 @chillu chillu committed Mar 5, 2012
Showing with 130 additions and 7 deletions.
  1. +52 −6 forms/ListboxField.php
  2. +65 −1 tests/forms/ListboxFieldTest.php
  3. +13 −0 tests/forms/ListboxFieldTest.yml
View
@@ -142,19 +142,65 @@ function setSource($source) {
return $this;
}
-
+
/**
- * @return String
+ * Return the CheckboxSetField value as a string
+ * selected item keys.
+ *
+ * @return string
*/
function dataValue() {
- if($this->value && $this->multiple && is_array($this->value)) {
- return implode(',', $this->value);
+ if($this->value && is_array($this->value) && $this->multiple) {
+ $filtered = array();
+ foreach($this->value as $item) {
+ if($item) {
+ $filtered[] = str_replace(",", "{comma}", $item);
+ }
+ }
+ return implode(',', $filtered);
} else {
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(!$this->multiple && is_array($val)) {
throw new InvalidArgumentException('No array values allowed with multiple=false');
@@ -187,4 +233,4 @@ function setValue($val) {
return $this;
}
-}
+}
@@ -5,8 +5,28 @@
*/
class ListboxFieldTest extends SapphireTest {
+
+ static $fixture_file = 'ListboxFieldTest.yml';
- protected $extraDataObjects = array('ListboxFieldTest_DataObject');
+ 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() {
$choices = array('a' => 'a value', 'b' => 'b value','c' => 'c value');
@@ -62,6 +82,33 @@ function testSaveIntoMultiple() {
$field->saveInto($obj2);
$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
@@ -130,4 +177,21 @@ class ListboxFieldTest_DataObject extends DataObject implements TestOnly {
static $db = array(
'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'
+ );
}
@@ -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

0 comments on commit 6e3ceef

Please sign in to comment.