1 <?php
2 3 4 5 6 7 8
9
10 require_once 'Zend/Currency.php';
11
12 13 14 15 16 17 18 19 20 21 22 23 24
25 class Money extends DBField implements CompositeDBField {
26
27 28 29
30 protected $currency;
31
32 33 34
35 protected $amount;
36
37 38 39
40 protected $isChanged = false;
41
42 43 44
45 protected $locale = null;
46
47 48 49
50 protected $currencyLib;
51
52 53 54 55
56 protected $allowedCurrencies;
57
58 59 60
61 static $composite_db = array(
62 "Currency" => "Varchar(3)",
63 "Amount" => 'Decimal(19,4)'
64 );
65
66 function __construct($name = null) {
67 $this->currencyLib = new Zend_Currency(null, i18n::default_locale());
68
69 parent::__construct($name);
70 }
71
72 function compositeDatabaseFields() {
73 return self::$composite_db;
74 }
75
76 function requireField() {
77 $fields = $this->compositeDatabaseFields();
78 if($fields) foreach($fields as $name => $type){
79 DB::requireField($this->tableName, $this->name.$name, $type);
80 }
81 }
82
83 function writeToManipulation(&$manipulation) {
84 if($this->getCurrency()) {
85 $manipulation['fields'][$this->name.'Currency'] = $this->prepValueForDB($this->getCurrency());
86 } else {
87 $manipulation['fields'][$this->name.'Currency'] = DBField::create('Varchar', $this->getCurrency())->nullValue();
88 }
89
90 if($this->getAmount()) {
91 $manipulation['fields'][$this->name.'Amount'] = $this->getAmount();
92 } else {
93 $manipulation['fields'][$this->name.'Amount'] = DBField::create('Decimal', $this->getAmount())->nullValue();
94 }
95 }
96
97 function addToQuery(&$query) {
98 parent::addToQuery($query);
99 $query->select[] = sprintf('"%sAmount"', $this->name);
100 $query->select[] = sprintf('"%sCurrency"', $this->name);
101 }
102
103 function setValue($value, $record = null, $markChanged = true) {
104
105 if ($value instanceof Money && $value->hasValue()) {
106 $this->setCurrency($value->getCurrency(), $markChanged);
107 $this->setAmount($value->getAmount(), $markChanged);
108 if($markChanged) $this->isChanged = true;
109 } else if($record && isset($record[$this->name . 'Currency']) && isset($record[$this->name . 'Amount'])) {
110 if($record[$this->name . 'Currency'] && $record[$this->name . 'Amount']) {
111 $this->setCurrency($record[$this->name . 'Currency'], $markChanged);
112 $this->setAmount($record[$this->name . 'Amount'], $markChanged);
113 } else {
114 $this->value = $this->nullValue();
115 }
116 if($markChanged) $this->isChanged = true;
117 } else if (is_array($value)) {
118 if (array_key_exists('Currency', $value)) {
119 $this->setCurrency($value['Currency'], $markChanged);
120 }
121 if (array_key_exists('Amount', $value)) {
122 $this->setAmount($value['Amount'], $markChanged);
123 }
124 if($markChanged) $this->isChanged = true;
125 } else {
126
127
128 }
129 }
130
131 132 133
134 function Nice($options = array()) {
135 $amount = $this->getAmount();
136 if(!isset($options['display'])) $options['display'] = Zend_Currency::USE_SYMBOL;
137 if(!isset($options['currency'])) $options['currency'] = $this->getCurrency();
138 if(!isset($options['symbol'])) $options['symbol'] = $this->currencyLib->getSymbol($this->getCurrency(), $this->getLocale());
139 return (is_numeric($amount)) ? $this->currencyLib->toCurrency($amount, $options) : '';
140 }
141
142 143 144
145 function NiceWithShortname($options = array()){
146 $options['display'] = Zend_Currency::USE_SHORTNAME;
147 return $this->Nice($options);
148 }
149
150 151 152
153 function NiceWithName($options = array()){
154 $options['display'] = Zend_Currency::USE_NAME;
155 return $this->Nice($options);
156 }
157
158 159 160
161 function getCurrency() {
162 return $this->currency;
163 }
164
165 166 167
168 function setCurrency($currency, $markChanged = true) {
169 $this->currency = $currency;
170 if($markChanged) $this->isChanged = true;
171 }
172
173 174 175 176 177
178 function getAmount() {
179 return $this->amount;
180 }
181
182 183 184
185 function setAmount($amount, $markChanged = true) {
186 $this->amount = (float)$amount;
187 if($markChanged) $this->isChanged = true;
188 }
189
190 191 192
193 function hasValue() {
194 return ($this->getCurrency() && is_numeric($this->getAmount()));
195 }
196
197 198 199
200 function hasAmount() {
201 return (int)$this->getAmount() != '0';
202 }
203
204 function isChanged() {
205 return $this->isChanged;
206 }
207
208 209 210
211 function setLocale($locale) {
212 $this->locale = $locale;
213 $this->currencyLib->setLocale($locale);
214 }
215
216 217 218
219 function getLocale() {
220 return ($this->locale) ? $this->locale : i18n::get_locale();
221 }
222
223 224 225
226 function getSymbol($currency = null, $locale = null) {
227
228 if($locale === null) $locale = $this->getLocale();
229 if($currency === null) $currency = $this->getCurrency();
230
231 return $this->currencyLib->getSymbol($currency, $locale);
232 }
233
234 235 236
237 function getShortName($currency = null, $locale = null) {
238 if($locale === null) $locale = $this->getLocale();
239 if($currency === null) $currency = $this->getCurrency();
240
241 return $this->currencyLib->getShortName($currency, $locale);
242 }
243
244 245 246
247 function getName($currency = null, $locale = null) {
248 if($locale === null) $locale = $this->getLocale();
249 if($currency === null) $currency = $this->getCurrency();
250
251 return $this->currencyLib->getName($currency, $locale);
252 }
253
254 255 256
257 function setAllowedCurrencies($arr) {
258 $this->allowedCurrencies = $arr;
259 }
260
261 262 263
264 function getAllowedCurrencies() {
265 return $this->allowedCurrencies;
266 }
267
268 269 270 271 272 273 274 275 276
277 public function scaffoldFormField($title = null) {
278 $field = new MoneyField($this->name);
279 $field->setAllowedCurrencies($this->getAllowedCurrencies());
280 $field->setLocale($this->getLocale());
281
282 return $field;
283 }
284
285 286 287 288 289 290
291 function __toString() {
292 return (string)$this->getAmount();
293 }
294 }
295 ?>
[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.
-