mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
FEATURE Added MoneyField as a form field to edit Money values
ENHANCEMENT Using MoneyField in Money->scaffoldFormField() BUGFIX Fixed Money->setValue() to respect $value parameter over $record to avoid wrongly updated values from stale $record values instead of new $value git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@77772 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
75ba6a1ab9
commit
b478c8be34
@ -101,16 +101,16 @@ class Money extends DBField implements CompositeDBField {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setValue($value,$record=null) {
|
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']) {
|
if($record[$this->name . 'Currency'] && $record[$this->name . 'Amount']) {
|
||||||
$this->setCurrency($record[$this->name . 'Currency']);
|
$this->setCurrency($record[$this->name . 'Currency']);
|
||||||
$this->setAmount($record[$this->name . 'Amount']);
|
$this->setAmount($record[$this->name . 'Amount']);
|
||||||
} else {
|
} else {
|
||||||
$this->value = $this->nullValue();
|
$this->value = $this->nullValue();
|
||||||
}
|
}
|
||||||
} elseif ($value instanceof Money) {
|
|
||||||
$this->setCurrency($value->getCurrency());
|
|
||||||
$this->setAmount($value->getAmount());
|
|
||||||
} else if (is_array($value)) {
|
} else if (is_array($value)) {
|
||||||
if (array_key_exists('Currency', $value)) {
|
if (array_key_exists('Currency', $value)) {
|
||||||
$this->setCurrency($value['Currency']);
|
$this->setCurrency($value['Currency']);
|
||||||
@ -266,25 +266,8 @@ class Money extends DBField implements CompositeDBField {
|
|||||||
* @return FormField
|
* @return FormField
|
||||||
*/
|
*/
|
||||||
public function scaffoldFormField($title = null) {
|
public function scaffoldFormField($title = null) {
|
||||||
$fieldAmount = new NumericField($this->name."Amount", 'Amount');
|
$field = new MoneyField($this->name);
|
||||||
|
$field->setAllowedCurrencies($this->getAllowedCurrencies());
|
||||||
$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);
|
|
||||||
|
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
139
forms/MoneyField.php
Normal file
139
forms/MoneyField.php
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Ingo Schommer, SilverStripe Ltd. (<firstname>@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 "<div class=\"fieldgroup\">" .
|
||||||
|
"<div class=\"fieldgroupField\">" . $this->fieldCurrency->SmallFieldHolder() . "</div>" .
|
||||||
|
"<div class=\"fieldgroupField\">" . $this->fieldAmount->SmallFieldHolder() . "</div>" .
|
||||||
|
"</div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
53
tests/forms/MoneyFieldTest.php
Normal file
53
tests/forms/MoneyFieldTest.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package sapphire
|
||||||
|
* @subpackage tests
|
||||||
|
*/
|
||||||
|
class MoneyFieldTest extends SapphireTest {
|
||||||
|
function testSaveInto() {
|
||||||
|
$o = new MoneyFieldTest_Object();
|
||||||
|
|
||||||
|
$m = new Money();
|
||||||
|
$m->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',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
?>
|
Loading…
x
Reference in New Issue
Block a user