Version: current

      1 <?php
      2 /**
      3  * @author Ingo Schommer, SilverStripe Ltd. (<firstname>@silverstripe.com)
      4  *
      5  * @package sapphire
      6  * @subpackage fields-formattedinput
      7  */
      8 class MoneyField extends FormField {
      9
     10     /**
     11      * @var string $_locale
     12      */
     13     protected $_locale;
     14
     15     /**
     16      * Limit the currencies
     17      * @var array $allowedCurrencies
     18      */
     19     protected $allowedCurrencies;
     20
     21     /**
     22      * @var FormField
     23      */
     24     protected $fieldAmount = null;
     25
     26     /**
     27      * @var FormField
     28      */
     29     protected $fieldCurrency = null;
     30
     31     function __construct($name, $title = null, $value = "", $form = null) {
     32         // naming with underscores to prevent values from actually being saved somewhere
     33         $this->fieldAmount = new NumericField("{$name}[Amount]", _t('MoneyField.FIELDLABELAMOUNT', 'Amount'));
     34         $this->fieldCurrency = $this->FieldCurrency();
     35
     36         parent::__construct($name, $title, $value, $form);
     37     }
     38
     39     /**
     40      * @return string
     41      */
     42     function Field() {
     43         return "<div class=\"fieldgroup\">" .
     44             "<div class=\"fieldgroupField\">" . $this->fieldCurrency->SmallFieldHolder() . "</div>" .
     45             "<div class=\"fieldgroupField\">" . $this->fieldAmount->SmallFieldHolder() . "</div>" .
     46         "</div>";
     47     }
     48
     49     /**
     50      * @return FormField
     51      */
     52     protected function FieldCurrency() {
     53         $allowedCurrencies = $this->getAllowedCurrencies();
     54         if($allowedCurrencies) {
     55             $field = new DropdownField(
     56                 "{$this->name}[Currency]",
     57                 _t('MoneyField.FIELDLABELCURRENCY', 'Currency'),
     58                 ArrayLib::is_associative($allowedCurrencies) ? $allowedCurrencies : array_combine($allowedCurrencies,$allowedCurrencies)
     59             );
     60         } else {
     61             $field = new TextField(
     62                 "{$this->name}[Currency]",
     63                 _t('MoneyField.FIELDLABELCURRENCY', 'Currency')
     64             );
     65         }
     66
     67         return $field;
     68     }
     69
     70     function setValue($val) {
     71         $this->value = $val;
     72
     73         if(is_array($val)) {
     74             $this->fieldCurrency->setValue($val['Currency']);
     75             $this->fieldAmount->setValue($val['Amount']);
     76         } elseif($val instanceof Money) {
     77             $this->fieldCurrency->setValue($val->getCurrency());
     78             $this->fieldAmount->setValue($val->getAmount());
     79         }
     80
     81         // @todo Format numbers according to current locale, incl.
     82         //  decimal and thousands signs, while respecting the stored
     83         //  precision in the database without truncating it during display
     84         //  and subsequent save operations
     85     }
     86
     87     /**
     88      * 30/06/2009 - Enhancement:
     89      * SaveInto checks if set-methods are available and use them
     90      * instead of setting the values in the money class directly. saveInto
     91      * initiates a new Money class object to pass through the values to the setter
     92      * method.
     93      *
     94      * (see @link MoneyFieldTest_CustomSetter_Object for more information)
     95      */
     96     function saveInto($dataObject) {
     97         $fieldName = $this->name;
     98         if($dataObject->hasMethod("set$fieldName")) {
     99             $dataObject->$fieldName = DBField::create('Money', array(
    100                 "Currency" => $this->fieldCurrency->Value(),
    101                 "Amount" => $this->fieldAmount->Value()
    102             ));
    103         } else {
    104             $dataObject->$fieldName->setCurrency($this->fieldCurrency->Value());
    105             $dataObject->$fieldName->setAmount($this->fieldAmount->Value());
    106         }
    107     }
    108
    109     /**
    110      * Returns a readonly version of this field.
    111      */
    112     function performReadonlyTransformation() {
    113         $clone = clone $this;
    114         $clone->setReadonly(true);
    115         return $clone;
    116     }
    117
    118     /**
    119      * @todo Implement removal of readonly state with $bool=false
    120      * @todo Set readonly state whenever field is recreated, e.g. in setAllowedCurrencies()
    121      */
    122     function setReadonly($bool) {
    123         parent::setReadonly($bool);
    124
    125         if($bool) {
    126             $this->fieldAmount = $this->fieldAmount->performReadonlyTransformation();
    127             $this->fieldCurrency = $this->fieldCurrency->performReadonlyTransformation();
    128         }
    129     }
    130
    131     /**
    132      * @param array $arr
    133      */
    134     function setAllowedCurrencies($arr) {
    135         $this->allowedCurrencies = $arr;
    136
    137         // @todo Has to be done twice in case allowed currencies changed since construction
    138         $oldVal = $this->fieldCurrency->Value();
    139         $this->fieldCurrency = $this->FieldCurrency();
    140         $this->fieldCurrency->setValue($oldVal);
    141     }
    142
    143     /**
    144      * @return array
    145      */
    146     function getAllowedCurrencies() {
    147         return $this->allowedCurrencies;
    148     }
    149
    150     function setLocale($locale) {
    151         $this->_locale = $locale;
    152     }
    153
    154     function getLocale() {
    155         return $this->_locale;
    156     }
    157 }
    158 ?>

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -