Harts
Harts

Reputation: 4103

Cakephp date validation still save and no error even though wrong input

I'm using cakephp validation for a field called birthdate.

my model is

'birthdate' => array(
    'rule'       => 'date',
    'message'    => 'Enter a valid date',
    'allowEmpty' => true    
),  

my question is how come it's still save correctly even though it's invalid input. e.g:

March 27, 1988 so, if I put it like this, and the array result like this

//this will work
'birthdate' => array(
    'month' => '3#',
    'day' => '27',
    'year' => '1988'
)

//this will NOT work
'birthdate' => array(
    'month' => '#3',
    'day' => '27',
    'year' => '1988'
)

why the first one still validate it (still save correctly. e.g: the end result still march 27, 1988)? but I would like to have consistency. is there anyway to report an error?

Upvotes: 0

Views: 245

Answers (1)

ndm
ndm

Reputation: 60503

Complex data type deconstruction

Dates are being passed as arrays, so they need to be formatted to a string first. In case the column in the database is of type date*, the value is being formatted automatically so that it fits the proper column type format.

Ultimately this is done in Model::deconstruct() (it ends up there when calling Model::set(), which normally happens before validation), where the individual values are being passed through sprintf():

$date[$index] = sprintf('%02d', $date[$index]);

https://github.com/cakephp/cakephp/blob/2.4.5/lib/Cake/Model/Model.php#L1336

Integer casting

And that's the answer to your first question, it's that formatting directive that is responsible for this behavior, it casts the individual date values to integers, where 3# evaluates to a number, while #3 fails (and ends up as 00), that's how string conversion in PHP works.

See http://php.net/manual/language.types.string.php#language.types.string.conversion

Use custom validation/formatting

So in order to be able to trigger an error on such input you'll either have to use a custom validation rule, which would require to for example pass the data using a different fieldname so that it's not being formatted in Model::set(), or use custom formatting (for example by overwriting Model::set() or Model::deconstruct()) to flatten the complex value in a way that the individual values are not being casted.

Upvotes: 1

Related Questions