diff --git a/core/model/fieldtypes/Money.php b/core/model/fieldtypes/Money.php
index 1097985c1..9f0b4aea8 100644
--- a/core/model/fieldtypes/Money.php
+++ b/core/model/fieldtypes/Money.php
@@ -101,16 +101,16 @@ class Money extends DBField implements CompositeDBField {
}
function setValue($value,$record=null) {
- if($record && isset($record[$this->name . 'Currency']) && isset($record[$this->name . 'Amount'])) {
+ if ($value instanceof Money) {
+ $this->setCurrency($value->getCurrency());
+ $this->setAmount($value->getAmount());
+ } else if($record && isset($record[$this->name . 'Currency']) && isset($record[$this->name . 'Amount'])) {
if($record[$this->name . 'Currency'] && $record[$this->name . 'Amount']) {
$this->setCurrency($record[$this->name . 'Currency']);
$this->setAmount($record[$this->name . 'Amount']);
} else {
$this->value = $this->nullValue();
}
- } elseif ($value instanceof Money) {
- $this->setCurrency($value->getCurrency());
- $this->setAmount($value->getAmount());
} else if (is_array($value)) {
if (array_key_exists('Currency', $value)) {
$this->setCurrency($value['Currency']);
@@ -266,25 +266,8 @@ class Money extends DBField implements CompositeDBField {
* @return FormField
*/
public function scaffoldFormField($title = null) {
- $fieldAmount = new NumericField($this->name."Amount", 'Amount');
-
- $allowedCurrencies = $this->getAllowedCurrencies();
- if($allowedCurrencies) {
- $fieldCurrency = new DropdownField(
- $this->name."Currency",
- 'Currency',
- array_combine($allowedCurrencies,$allowedCurrencies)
- );
- } else {
- $fieldCurrency = new TextField($this->name."Currency", 'Currency');
- }
-
- $field = new FieldGroup(
- $fieldAmount,
- $fieldCurrency
- );
-
- $field->setID ($this->name);
+ $field = new MoneyField($this->name);
+ $field->setAllowedCurrencies($this->getAllowedCurrencies());
return $field;
}
diff --git a/forms/MoneyField.php b/forms/MoneyField.php
new file mode 100644
index 000000000..88df1fab5
--- /dev/null
+++ b/forms/MoneyField.php
@@ -0,0 +1,139 @@
+@silverstripe.com)
+ *
+ * @package sapphire
+ * @subpackage fields-formattedinput
+ */
+class MoneyField extends FormField {
+
+ /**
+ * @var string $_locale
+ */
+ protected $_locale;
+
+ /**
+ * Limit the currencies
+ * @var array $allowedCurrencies
+ */
+ protected $allowedCurrencies;
+
+ /**
+ * @var FormField
+ */
+ protected $fieldAmount = null;
+
+ /**
+ * @var FormField
+ */
+ protected $fieldCurrency = null;
+
+ function __construct($name, $title = null, $value = "", $form = null) {
+ parent::__construct($name, $title, $value, $form);
+
+ // naming with underscores to prevent values from actually being saved somewhere
+ $this->fieldAmount = new NumericField("{$name}[Amount]", _t('MoneyField.FIELDLABELAMOUNT', 'Amount'));
+ $this->fieldCurrency = $this->FieldCurrency();
+ $this->setValue($value);
+ }
+
+ /**
+ * @return string
+ */
+ function Field() {
+ return "
" .
+ "
" . $this->fieldCurrency->SmallFieldHolder() . "
" .
+ "
" . $this->fieldAmount->SmallFieldHolder() . "
" .
+ "
";
+ }
+
+ /**
+ * @return FormField
+ */
+ protected function FieldCurrency() {
+ $allowedCurrencies = $this->getAllowedCurrencies();
+ if($allowedCurrencies) {
+ $field = new DropdownField(
+ "{$this->name}[Currency]",
+ _t('MoneyField.FIELDLABELCURRENCY', 'Currency'),
+ array_combine($allowedCurrencies,$allowedCurrencies)
+ );
+ } else {
+ $field = new TextField(
+ "{$this->name}[Currency]",
+ _t('MoneyField.FIELDLABELCURRENCY', 'Currency')
+ );
+ }
+
+ return $field;
+ }
+
+ function setValue($val) {
+ $this->value = $val;
+
+ if(is_array($val)) {
+ $this->fieldCurrency->setValue($val['Currency']);
+ $this->fieldAmount->setValue($val['Amount']);
+ } elseif($val instanceof Money) {
+ $this->fieldCurrency->setValue($val->getCurrency());
+ $this->fieldAmount->setValue($val->getAmount());
+ }
+ }
+
+ function saveInto($dataObject) {
+ $fieldName = $this->name;
+ $dataObject->$fieldName->setCurrency($this->fieldCurrency->Value());
+ $dataObject->$fieldName->setAmount($this->fieldAmount->Value());
+ }
+
+ /**
+ * Returns a readonly version of this field.
+ */
+ function performReadonlyTransformation() {
+ $clone = clone $this;
+ $clone->setReadonly(true);
+ return $clone;
+ }
+
+ /**
+ * @todo Implement removal of readonly state with $bool=false
+ * @todo Set readonly state whenever field is recreated, e.g. in setAllowedCurrencies()
+ */
+ function setReadonly($bool) {
+ parent::setReadonly($bool);
+
+ if($bool) {
+ $this->fieldAmount = $this->fieldAmount->performReadonlyTransformation();
+ $this->fieldCurrency = $this->fieldCurrency->performReadonlyTransformation();
+ }
+ }
+
+ /**
+ * @param array $arr
+ */
+ function setAllowedCurrencies($arr) {
+ $this->allowedCurrencies = $arr;
+
+ // @todo Has to be done twice in case allowed currencies changed since construction
+ $oldVal = $this->fieldCurrency->Value();
+ $this->fieldCurrency = $this->FieldCurrency();
+ $this->fieldCurrency->setValue($oldVal);
+ }
+
+ /**
+ * @return array
+ */
+ function getAllowedCurrencies() {
+ return $this->allowedCurrencies;
+ }
+
+ function setLocale($locale) {
+ $this->_locale = $locale;
+ $this->fieldAmount->setLocale($locale);
+ }
+
+ function getLocale() {
+ return $this->_locale;
+ }
+}
+?>
\ No newline at end of file
diff --git a/tests/forms/MoneyFieldTest.php b/tests/forms/MoneyFieldTest.php
new file mode 100644
index 000000000..87f2391de
--- /dev/null
+++ b/tests/forms/MoneyFieldTest.php
@@ -0,0 +1,53 @@
+setAmount(1.23);
+ $m->setCurrency('EUR');
+ $f = new MoneyField('MyMoney', 'MyMoney', $m);
+
+ $f->saveInto($o);
+ $this->assertEquals($o->MyMoney->getAmount(), 1.23);
+ $this->assertEquals($o->MyMoney->getCurrency(), 'EUR');
+ }
+
+ function testSetValueAsMoney() {
+ $o = new MoneyFieldTest_Object();
+
+ $f = new MoneyField('MyMoney', 'MyMoney');
+
+ $m = new Money();
+ $m->setAmount(1.23);
+ $m->setCurrency('EUR');
+ $f->setValue($m);
+
+ $f->saveInto($o);
+ $this->assertEquals($o->MyMoney->getAmount(), 1.23);
+ $this->assertEquals($o->MyMoney->getCurrency(), 'EUR');
+ }
+
+ function testSetValueAsArray() {
+ $o = new MoneyFieldTest_Object();
+
+ $f = new MoneyField('MyMoney', 'MyMoney');
+
+ $f->setValue(array('Currency'=>'EUR','Amount'=>1.23));
+
+ $f->saveInto($o);
+ $this->assertEquals($o->MyMoney->getAmount(), 1.23);
+ $this->assertEquals($o->MyMoney->getCurrency(), 'EUR');
+ }
+}
+
+class MoneyFieldTest_Object extends DataObject implements TestOnly {
+ static $db = array(
+ 'MyMoney' => 'Money',
+ );
+}
+?>
\ No newline at end of file