2009-05-26 00:21:02 +02:00
|
|
|
<?php
|
2015-08-30 07:02:55 +02:00
|
|
|
|
2016-06-15 06:03:16 +02:00
|
|
|
|
|
|
|
|
|
|
|
use SilverStripe\ORM\FieldType\DBField;
|
|
|
|
use SilverStripe\ORM\FieldType\DBMoney;
|
|
|
|
use SilverStripe\ORM\DataObjectInterface;
|
|
|
|
|
2015-08-30 07:02:55 +02:00
|
|
|
|
2009-05-26 00:21:02 +02:00
|
|
|
/**
|
2010-11-13 03:05:34 +01:00
|
|
|
* A form field that can save into a {@link Money} database field.
|
2014-08-15 08:53:05 +02:00
|
|
|
* See {@link CurrencyField} for a similiar implementation
|
2010-11-13 03:05:34 +01:00
|
|
|
* that can save into a single float database field without indicating the currency.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2009-05-26 00:21:02 +02:00
|
|
|
* @author Ingo Schommer, SilverStripe Ltd. (<firstname>@silverstripe.com)
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2013-11-29 05:12:47 +01:00
|
|
|
* @package forms
|
2009-05-26 00:21:02 +02:00
|
|
|
* @subpackage fields-formattedinput
|
|
|
|
*/
|
|
|
|
class MoneyField extends FormField {
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2016-03-21 11:12:23 +01:00
|
|
|
protected $schemaDataType = FormField::SCHEMA_DATA_TYPE_TEXT;
|
|
|
|
|
2009-05-26 00:21:02 +02:00
|
|
|
/**
|
|
|
|
* @var string $_locale
|
|
|
|
*/
|
|
|
|
protected $_locale;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-05-26 00:21:02 +02:00
|
|
|
/**
|
|
|
|
* Limit the currencies
|
|
|
|
* @var array $allowedCurrencies
|
|
|
|
*/
|
|
|
|
protected $allowedCurrencies;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-05-26 00:21:02 +02:00
|
|
|
/**
|
2016-07-25 07:24:26 +02:00
|
|
|
* @var NumericField
|
2009-05-26 00:21:02 +02:00
|
|
|
*/
|
|
|
|
protected $fieldAmount = null;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-05-26 00:21:02 +02:00
|
|
|
/**
|
|
|
|
* @var FormField
|
|
|
|
*/
|
|
|
|
protected $fieldCurrency = null;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2016-07-25 07:24:26 +02:00
|
|
|
/**
|
|
|
|
* Gets field for the currency selector
|
|
|
|
*
|
|
|
|
* @return FormField
|
|
|
|
*/
|
|
|
|
public function getCurrencyField() {
|
|
|
|
return $this->fieldCurrency;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets field for the amount input
|
|
|
|
*
|
|
|
|
* @return NumericField
|
|
|
|
*/
|
|
|
|
public function getAmountField() {
|
|
|
|
return $this->fieldAmount;
|
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function __construct($name, $title = null, $value = "") {
|
2016-07-25 07:24:26 +02:00
|
|
|
$this->setName($name);
|
|
|
|
|
2009-05-26 00:21:02 +02:00
|
|
|
// naming with underscores to prevent values from actually being saved somewhere
|
|
|
|
$this->fieldAmount = new NumericField("{$name}[Amount]", _t('MoneyField.FIELDLABELAMOUNT', 'Amount'));
|
2016-07-25 07:24:26 +02:00
|
|
|
$this->fieldCurrency = $this->buildCurrencyField();
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-01-02 17:09:30 +01:00
|
|
|
parent::__construct($name, $title, $value);
|
2009-05-26 00:21:02 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2016-07-25 07:24:26 +02:00
|
|
|
public function __clone()
|
|
|
|
{
|
|
|
|
$this->fieldAmount = clone $this->fieldAmount;
|
|
|
|
$this->fieldCurrency = clone $this->fieldCurrency;
|
2009-05-26 00:21:02 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-05-26 00:21:02 +02:00
|
|
|
/**
|
2016-07-25 07:24:26 +02:00
|
|
|
* Builds a new currency field based on the allowed currencies configured
|
|
|
|
*
|
2009-05-26 00:21:02 +02:00
|
|
|
* @return FormField
|
|
|
|
*/
|
2016-07-25 07:24:26 +02:00
|
|
|
protected function buildCurrencyField() {
|
|
|
|
$name = $this->getName();
|
2009-05-26 00:21:02 +02:00
|
|
|
$allowedCurrencies = $this->getAllowedCurrencies();
|
|
|
|
if($allowedCurrencies) {
|
|
|
|
$field = new DropdownField(
|
2014-08-15 08:53:05 +02:00
|
|
|
"{$name}[Currency]",
|
2009-05-26 00:21:02 +02:00
|
|
|
_t('MoneyField.FIELDLABELCURRENCY', 'Currency'),
|
2012-09-26 23:34:00 +02:00
|
|
|
ArrayLib::is_associative($allowedCurrencies)
|
|
|
|
? $allowedCurrencies
|
|
|
|
: array_combine($allowedCurrencies,$allowedCurrencies)
|
2009-05-26 00:21:02 +02:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
$field = new TextField(
|
2014-08-15 08:53:05 +02:00
|
|
|
"{$name}[Currency]",
|
2009-05-26 00:21:02 +02:00
|
|
|
_t('MoneyField.FIELDLABELCURRENCY', 'Currency')
|
|
|
|
);
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2016-07-25 07:24:26 +02:00
|
|
|
$field->setReadonly($this->isReadonly());
|
|
|
|
$field->setDisabled($this->isDisabled());
|
2009-05-26 00:21:02 +02:00
|
|
|
return $field;
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function setValue($val) {
|
2009-05-26 00:21:02 +02:00
|
|
|
$this->value = $val;
|
|
|
|
|
|
|
|
if(is_array($val)) {
|
2009-05-27 02:59:07 +02:00
|
|
|
$this->fieldCurrency->setValue($val['Currency']);
|
|
|
|
$this->fieldAmount->setValue($val['Amount']);
|
2015-08-30 07:02:55 +02:00
|
|
|
} elseif($val instanceof DBMoney) {
|
2009-05-27 02:59:07 +02:00
|
|
|
$this->fieldCurrency->setValue($val->getCurrency());
|
|
|
|
$this->fieldAmount->setValue($val->getAmount());
|
2009-05-26 00:21:02 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-05-26 03:08:47 +02:00
|
|
|
// @todo Format numbers according to current locale, incl.
|
|
|
|
// decimal and thousands signs, while respecting the stored
|
|
|
|
// precision in the database without truncating it during display
|
|
|
|
// and subsequent save operations
|
2012-02-17 13:35:26 +01:00
|
|
|
|
|
|
|
return $this;
|
2009-05-26 00:21:02 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-06-30 05:16:28 +02:00
|
|
|
/**
|
2014-08-15 08:53:05 +02:00
|
|
|
* 30/06/2009 - Enhancement:
|
|
|
|
* SaveInto checks if set-methods are available and use them
|
2009-06-30 05:16:28 +02:00
|
|
|
* instead of setting the values in the money class directly. saveInto
|
|
|
|
* initiates a new Money class object to pass through the values to the setter
|
|
|
|
* method.
|
|
|
|
*
|
|
|
|
* (see @link MoneyFieldTest_CustomSetter_Object for more information)
|
2016-07-25 07:24:26 +02:00
|
|
|
*
|
|
|
|
* @param DataObjectInterface|Object $dataObject
|
2009-06-30 05:16:28 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function saveInto(DataObjectInterface $dataObject) {
|
2015-09-04 05:49:22 +02:00
|
|
|
$fieldName = $this->getName();
|
2009-06-30 05:16:28 +02:00
|
|
|
if($dataObject->hasMethod("set$fieldName")) {
|
2012-03-27 06:57:42 +02:00
|
|
|
$dataObject->$fieldName = DBField::create_field('Money', array(
|
2015-05-20 13:18:34 +02:00
|
|
|
"Currency" => $this->fieldCurrency->dataValue(),
|
|
|
|
"Amount" => $this->fieldAmount->dataValue()
|
2009-06-30 05:16:28 +02:00
|
|
|
));
|
|
|
|
} else {
|
2015-09-04 05:49:22 +02:00
|
|
|
$currencyField = "{$fieldName}Currency";
|
|
|
|
$amountField = "{$fieldName}Amount";
|
|
|
|
|
|
|
|
$dataObject->$currencyField = $this->fieldCurrency->dataValue();
|
|
|
|
$dataObject->$amountField = $this->fieldAmount->dataValue();
|
2009-06-30 05:16:28 +02:00
|
|
|
}
|
2009-05-26 00:21:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a readonly version of this field.
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function performReadonlyTransformation() {
|
2009-05-26 00:21:02 +02:00
|
|
|
$clone = clone $this;
|
2014-01-13 09:35:40 +01:00
|
|
|
$clone->fieldAmount = $clone->fieldAmount->performReadonlyTransformation();
|
2014-01-22 10:07:15 +01:00
|
|
|
$clone->fieldCurrency = $clone->fieldCurrency->performReadonlyTransformation();
|
2009-05-26 00:21:02 +02:00
|
|
|
$clone->setReadonly(true);
|
|
|
|
return $clone;
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function setReadonly($bool) {
|
2009-05-26 00:21:02 +02:00
|
|
|
parent::setReadonly($bool);
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-01-02 16:19:22 +01:00
|
|
|
$this->fieldAmount->setReadonly($bool);
|
|
|
|
$this->fieldCurrency->setReadonly($bool);
|
2012-02-17 13:35:26 +01:00
|
|
|
|
|
|
|
return $this;
|
2012-01-02 16:19:22 +01:00
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function setDisabled($bool) {
|
2012-01-02 16:19:22 +01:00
|
|
|
parent::setDisabled($bool);
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-01-02 16:19:22 +01:00
|
|
|
$this->fieldAmount->setDisabled($bool);
|
|
|
|
$this->fieldCurrency->setDisabled($bool);
|
2012-02-17 13:35:26 +01:00
|
|
|
|
|
|
|
return $this;
|
2009-05-26 00:21:02 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-05-26 00:21:02 +02:00
|
|
|
/**
|
|
|
|
* @param array $arr
|
2016-07-25 07:24:26 +02:00
|
|
|
* @return $this
|
2009-05-26 00:21:02 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function setAllowedCurrencies($arr) {
|
2009-05-26 00:21:02 +02:00
|
|
|
$this->allowedCurrencies = $arr;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-05-26 00:21:02 +02:00
|
|
|
// @todo Has to be done twice in case allowed currencies changed since construction
|
2015-05-20 13:18:34 +02:00
|
|
|
$oldVal = $this->fieldCurrency->dataValue();
|
2016-07-25 07:24:26 +02:00
|
|
|
$this->fieldCurrency = $this->buildCurrencyField();
|
2009-05-26 00:21:02 +02:00
|
|
|
$this->fieldCurrency->setValue($oldVal);
|
2012-02-17 13:35:26 +01:00
|
|
|
|
|
|
|
return $this;
|
2009-05-26 00:21:02 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-05-26 00:21:02 +02:00
|
|
|
/**
|
|
|
|
* @return array
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function getAllowedCurrencies() {
|
2009-05-26 00:21:02 +02:00
|
|
|
return $this->allowedCurrencies;
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function setLocale($locale) {
|
2009-05-26 00:21:02 +02:00
|
|
|
$this->_locale = $locale;
|
2012-02-17 13:35:26 +01:00
|
|
|
return $this;
|
2009-05-26 00:21:02 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function getLocale() {
|
2009-05-26 00:21:02 +02:00
|
|
|
return $this->_locale;
|
|
|
|
}
|
2014-11-12 03:19:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Validate this field
|
|
|
|
*
|
|
|
|
* @param Validator $validator
|
|
|
|
* @return bool
|
|
|
|
*/
|
2015-05-11 02:32:00 +02:00
|
|
|
public function validate($validator) {
|
2014-11-12 03:19:12 +01:00
|
|
|
return !(is_null($this->fieldAmount) || is_null($this->fieldCurrency));
|
|
|
|
}
|
2016-07-25 07:24:26 +02:00
|
|
|
|
|
|
|
public function setForm($form) {
|
|
|
|
$this->fieldCurrency->setForm($form);
|
|
|
|
$this->fieldAmount->setForm($form);
|
|
|
|
return parent::setForm($form);
|
|
|
|
}
|
2009-05-26 00:21:02 +02:00
|
|
|
}
|