I'm developing an application with CakePHP that handles monetary values. The client wants the numbers to have a custom format like 1.275,34
, i.e. a dot as the delimiter in the integer part and a comma as the delimiter of the decimal part.
I'm wondering what's the best approach to manage this, since i need to do two basic things:
- Validate values written in forms according to that custom format.
- Transform those values according to the format expected by MySQL's column data type (
decimal(18,2)
in this case,1275.34
in the example above).
I think I have these options but I'm not completely happy with any because several mode开发者_如何学JAVAls work with that custom format and that means replicating some code:
- Validate and transform the value in the controller before calling
$this->Model->save()
, maybe using a Component. - Validate the data using custom rules in model (
var $validate
array) and transforming them, maybe using a Behavior.
What do you recommend? Is there any other approach to handle this?
Thanks!
You can use PHPs number_format()
to format it any way you like : http://php.net/manual/en/function.number-format.php
As for hooking it in, you can use the beforeSave()
and afterFind()
callbacks to do the transformation, if you want do it in the model.
http://book.cakephp.org/view/1048/Callback-Methods
I would suggest you keep an extra field that is populated in the model model after a find operation using the callbacks above so it's always available to you and doesn't mess up if you accidentally try to save it.
ALSO You could use virtualFields (available from cakePHP 1.3) to create a field that is populated by the DB on every find. You could use MySQLs string formatting to achieve this.
Virtual Field : http://book.cakephp.org/view/1608/Virtual-fields
MySQL string : http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_format
An example would be
var $virtualFields = array(
'formatted' => 'FORMAT(12332.1,2)' // would output 12,332.10
);
The "1.234,56" format is the European money format, so you're probably better off making the entire app use this format. What you need to do is set the monetary locale of your app, using setlocale(LC_MONETARY,$locale)
. So, for example:
setlocale(LC_MONETARY, 'it_IT');
Then, you use money_format
to format your currency strings appropriately, and use a Model::beforeValidate()
callback to massage any currency input before validation, so you can validate against standard decimal format. This related question may be useful.
精彩评论