Browse files

Make Validation::decimal accept integers

Fix #2800
Force locale of ValidationTests with en_US to ensure decimal dot separator
  • Loading branch information...
1 parent afbd582 commit 28bd6880df2f4a6bd182bcb0f3a04dd5a1b64fad @CauanCabral CauanCabral committed with markstory Apr 17, 2012
Showing with 11 additions and 5 deletions.
  1. +9 −3 lib/Cake/Test/Case/Utility/ValidationTest.php
  2. +2 −2 lib/Cake/Utility/Validation.php
12 lib/Cake/Test/Case/Utility/ValidationTest.php
@@ -103,6 +103,8 @@ class ValidationTest extends CakeTestCase {
public function setUp() {
$this->_appEncoding = Configure::read('App.encoding');
+ $this->_appLocale = setlocale(LC_ALL, "0");
+ setlocale(LC_ALL, 'en_US');
@@ -113,6 +115,7 @@ public function setUp() {
public function tearDown() {
Configure::write('App.encoding', $this->_appEncoding);
+ setlocale(LC_ALL, $this->_appLocale);
@@ -1490,10 +1493,13 @@ public function testDecimal() {
+ $this->assertTrue(Validation::decimal('1234'));
+ $this->assertTrue(Validation::decimal('-1234'));
+ $this->assertTrue(Validation::decimal('+1234'));
+ $this->assertTrue(Validation::decimal(1234.56));
+ $this->assertTrue(Validation::decimal(1234.00));
- $this->assertFalse(Validation::decimal('1234'));
- $this->assertFalse(Validation::decimal('-1234'));
- $this->assertFalse(Validation::decimal('+1234'));
4 lib/Cake/Utility/Validation.php
@@ -382,9 +382,9 @@ public static function boolean($check) {
public static function decimal($check, $places = null, $regex = null) {
if (is_null($regex)) {
if (is_null($places)) {
- $regex = '/^[-+]?[0-9]*\\.{1}[0-9]+(?:[eE][-+]?[0-9]+)?$/';
+ $regex = '/^[-+]?[0-9]*(\\.{1}[0-9]+(?:[eE][-+]?[0-9]+)?)?$/';
} else {
- $regex = '/^[-+]?[0-9]*\\.{1}[0-9]{' . $places . '}$/';
+ $regex = '/^[-+]?[0-9]*(\\.{1}[0-9]{' . $places . '})?$/';
return self::_check($check, $regex);

11 comments on commit 28bd688


Why is Validator::decimal() nos validation decimal point anymore?¿
Even the docs says it should:

Checks that a value is a valid decimal. If $places is null, the $check is allowed to be a scientific float
If no decimal point is found a false will be returned. Both the sign and exponent are optional.




CakePHP member

Well 1234 is a valid decimal value, as it has implicit 00's


I know, but the whoie point of testing against decimal(), and not numeric() or naturalNumber() is to detect a decimal point (again, as the documentation says). It can't be right that (int)1234 passes the test...

CakePHP member

The original issue that created this change was The wikipedia article on decimal values says

Trailing zeros after the decimal point are not necessary

Which seems reasonable considering decimal values generally come from user input, and requiring trailing zero's seems a bit excessive. Both '10' and '10.000' have the same representation in both PHP and Javascript. Additionally databases like MySQL and SQLite treat these values as interchangeable as does Postgres from what I remember.


Yes, because of PHP type juggling feature and being loosely typed, it removes trailing zeroes and automatically types the value to float, so when you type 13.00 ends being (float) 13, but when you type '13.00', it does not change but correctly passes the tests.

The solution to that can be undoing what PHP does when a float number is detected, a working proof of concept with old tests and new ones should be:



Updating the commit with a clearly invalid test wich fails here because of the ()? regex grouping




I agree with bar. I would only use the decimal validation rule if I wanted to validate a number with a decimal place: 10.23, 45323.33 and even 4343.00. Numbers without a decimal shouldn't pass IMO.

CakePHP member

@bar a59548a5e951f433dc24e3040c708941ca37de50 seems like a reasonable change as '' passing as a decimal is wrong like you said.


@markstory yes, it seemed odd...

CakePHP member

Thanks for the change @bar, merged in b75a6b4


Sure, being able to contribute to the core is always a pleasure!

Please sign in to comment.