Date object treats 0 as a valid day, month or year. For example:
$date = new DateObject('00/00/2013', NULL, 'd/m/Y');
var_export($date->errors);
// Outputs an empty array.
I've set this issue to critical as this seems like quite a large hole in the date validation rules.
The problem comes from DateObject::arrayErrors(), specifically line 875 (http://drupalcode.org/project/date.git/blame/refs/heads/7.x-2.x:/date_ap...):
foreach ($arr as $part => $value) {
// Explicitly set the granularity to the values in the input array.
if (is_numeric($value)) {
$this->addGranularity($part);
}
// Avoid false errors when a numeric value is input as a string by casting
// as an integer.
$value = intval($value);
if (!empty($value) && $this->forceValid($part, $value, 'now', $default_month, $default_year) != $value) {
The problem is empty(0) evaluates to true so we never check if that value is valid. That's fine for times but is obviously a problem for dates. It looks like this bug has been here from the beginning (http://drupalcode.org/project/date.git/commit/135af56e2723b56d972fdf888d...). Removing the empty() check fixes the issue with no side effects as far as I can see. I'll attach a patch in the comments. With the patch applied we get:
$date = new DateObject('00/00/2013', NULL, 'd/m/Y');
var_export($date->errors);
// Outputs:
// array (
// 'month' => 'The month is invalid.',
// 'day' => 'The day is invalid.',
// )
It's probably worth adding some unit tests around this as well.
Comment | File | Size | Author |
---|---|---|---|
#35 | date-n2101397-34-test-only.patch | 1.78 KB | DamienMcKenna |
#34 | interdiff-31-34.txt | 433 bytes | solideogloria |
#34 | date-2101397-34.patch | 4.41 KB | solideogloria |
| |||
#31 | 2101397-31.patch | 4.42 KB | guilhermevp |
| |||
#26 | 2101397-0-date-25.patch | 4.36 KB | scottm316 |
Comments
Comment #1
Dean Reilly CreditAttribution: Dean Reilly commentedPatch attached.
Comment #2
Dean Reilly CreditAttribution: Dean Reilly commentedIgnore. Double post.
Comment #4
Dean Reilly CreditAttribution: Dean Reilly commentedHmm so it looks like the tests are failing because the date part is throwing an error so DateObject::parse never sets the correct time and we default to what the time is now in the default timezone (I guess the testbots are running in UTC).
I thought initially we could fix this up with something like:
i.e. removing the date parts but that doesn't work either. The problem seems to be dateobject doesn't distinguish between no date being provided and 0000-00-00 being provided. So this is going to need some more work.
Comment #5
Dean Reilly CreditAttribution: Dean Reilly commentedSo here's an attempt at differentiating between dates being left out when instantiating a DateObject and dates being set to zero.
Comment #6
Dean Reilly CreditAttribution: Dean Reilly commentedComment #8
Paul B CreditAttribution: Paul B commentedIf I enter a date '0000-00-00' into a date textfield, it is recorded as today's date (even if 'No default value' is given, see
#1995864: Date field not obey 'No default value' (defaults to current date) when within Field Collection or Paragraph.
If I apply only the last hunk of the patch in #5, this problem seems to be fixed and it still passes the date API tests.
Comment #9
Paul B CreditAttribution: Paul B commentedForget my last comment, the tests pass but my problem was not fixed.
Comment #10
Paul B CreditAttribution: Paul B commentedI should add that I'm using a d-m-Y day format (so in my case it's "00-00-0000", not "0000-00-00").
I didn't think that would matter, but it does:
This is wrong, it should be "0000-00-00 00:00:00".
This is also wrong.
Comment #11
Paul B CreditAttribution: Paul B commentedOK, maybe the -0001-11-30 value makes some sense since month 0 would be the month prior to month 1, etcetera. The date_api module says
But on https://bugs.php.net/bug.php?id=42971 it says that this is not a bug.
Anyway, I think
and
should return the same value. The patch should fix it I believe.
Comment #12
Dean Reilly CreditAttribution: Dean Reilly commentedYep, I've been thinking about this too and maybe it is valid to have 0 as a day, month and year value.
However, let me explain where I ran into this use case. We had a date field on a node using a text field widget. Users would sometimes enter something like 00/00/2014 into the field and the node would submit without any validation issues because the date api module treats this as a valid date but in every case it's not the date the user intended!
So if we are going to support this in the date format module we should probably have a think if we want this functionality to be user facing too.
Comment #13
vijaycs85Lets focus on this issue and get it in ASAP
Comment #14
vijaycs85Let's add some test...
Comment #16
vijaycs85Ok, lets get this in. Keeping it RTBC and assigning to @podarok for final review and commit.
Comment #17
Dean Reilly CreditAttribution: Dean Reilly commentedThe latest patch is not going to work as we now don't correctly recognise time-only inputs (see the attached patch with more tests).
It seems to me we have at least three problems in this thread:
1) Should an input like 0000-00-00T16:17:38 be treated as a time-only input or as a date.
2) Should 0000-00-00 be considered valid input for a date.
3) If 0000-00-00 is a valid input, should we allow end users to enter these kind of dates through date widgets?
And we need to make a decision about how we want to fix these before we can code a good solution.
Personally, I'm of the opinion that we should drop support for zero-dates. They don't gain us very much as we already have good support for date arithmetic elsewhere which is much more flexible and explicit in its intent. Also including and trying to support it could lead to some very complex code. Finally I'd argue that because we already have validation in place that tries to prevent zero-dates (it just doesn't work at the minute because of the empty() bug) it looks like this was already the decision made previously.
This then settles the other two questions: the first would be a time input and the widgets would not allow users to do things like 2014-00-25.
Comment #18
Dean Reilly CreditAttribution: Dean Reilly commentedComment #20
steinmb CreditAttribution: steinmb as a volunteer commentedComment #21
manishsaharan CreditAttribution: manishsaharan commentedComment #22
scottm316 CreditAttribution: scottm316 as a volunteer and commentedRe-rolled!
Comment #24
manishsaharan CreditAttribution: manishsaharan as a volunteer and commentedThis Patch will solve the issue
Comment #26
scottm316 CreditAttribution: scottm316 as a volunteer and commentedAs has been explored in many other issues, date-only and time-only values are not a reality when saving things in the database. There does exist dateOnly and timeOnly flags in the code, but they don't do much.
This patch needed a little more than a re-roll to work properly but I think I've got it as far as preventing zero month and zero day entries. Any changes or suggestions or questions would be welcomed. This is basically one of the most used modules in D7 so I understand the implications of what's been changed here.
Comment #27
DamienMcKennaThank you scottm316 for the patch.
Would someone mind testing the patch in #26 to see if it resolves your problems? Thanks.
Comment #28
DamienMcKennaThe test files have been renamed, so this needs a reroll.
Comment #29
guilhermevp CreditAttribution: guilhermevp at CI&T commentedI tried to re-roll the patch acommodating the changes in the module, but the problem remains.
Comment #30
DamienMcKennaIf you could please upload the patch it'd be a step forwards. Thank you.
Comment #31
guilhermevp CreditAttribution: guilhermevp at CI&T commentedSubmitting patch. I hope it may help!
Comment #32
DamienMcKennaThank you, I appreciate it!
I think there might be a typo here:
Comment #33
guilhermevp CreditAttribution: guilhermevp at CI&T commentedSorry! indeed I notice this mistake and corrected it, but forgot to update the patch!
Comment #34
solideogloria CreditAttribution: solideogloria commentedI fixed the typo.
Comment #35
DamienMcKennaTests only.
Comment #37
DamienMcKennaTests-only patch fails, full patch passes, this is great!
Comment #38
steinmb CreditAttribution: steinmb as a volunteer commentedI see no problems with the patch, makes the test pass. RTBC from me.
Comment #40
DamienMcKennaCommitted. Thank you all!