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
@@ -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'));
@@ -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

bar commented on 28bd688 Aug 24, 2012

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.





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

bar replied Aug 24, 2012

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...


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.

bar replied Aug 24, 2012

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:


bar replied Aug 24, 2012

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.


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

bar replied Aug 24, 2012

@markstory yes, it seemed odd...


Thanks for the change @bar, merged in b75a6b4

bar replied Aug 25, 2012

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

Please sign in to comment.