From b46badb1308c862ecf99a48c4cbf1cbe585fbebf Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Wed, 17 Feb 2021 12:41:12 +0100 Subject: [PATCH] MDL-70926 core: getuserdate() shoud show debugging if null was passed passing null to getdate() has different results in PHP7 and PHP8 --- .../local/event/factories/event_abstract_factory.php | 2 +- calendar/tests/helpers.php | 2 +- lib/excellib.class.php | 2 +- lib/form/defaultcustom.php | 2 +- lib/moodlelib.php | 8 ++++++++ lib/tests/moodlelib_test.php | 6 ++++++ 6 files changed, 18 insertions(+), 4 deletions(-) diff --git a/calendar/classes/local/event/factories/event_abstract_factory.php b/calendar/classes/local/event/factories/event_abstract_factory.php index b964673cf35..dccd2dc831b 100644 --- a/calendar/classes/local/event/factories/event_abstract_factory.php +++ b/calendar/classes/local/event/factories/event_abstract_factory.php @@ -192,7 +192,7 @@ abstract class event_abstract_factory implements event_factory_interface { (new \DateTimeImmutable())->setTimestamp($dbrow->timestart + $dbrow->timeduration), (new \DateTimeImmutable())->setTimestamp($dbrow->timesort ? $dbrow->timesort : $dbrow->timestart), (new \DateTimeImmutable())->setTimestamp($dbrow->timemodified), - (new \DateTimeImmutable())->setTimestamp(usergetmidnight($dbrow->timesort)) + (new \DateTimeImmutable())->setTimestamp($dbrow->timesort ? usergetmidnight($dbrow->timesort) : 0) ), !empty($dbrow->visible), $subscription, diff --git a/calendar/tests/helpers.php b/calendar/tests/helpers.php index 5c373dc0a2e..46eaff79f01 100644 --- a/calendar/tests/helpers.php +++ b/calendar/tests/helpers.php @@ -230,7 +230,7 @@ class action_event_test_factory implements event_factory_interface { (new \DateTimeImmutable())->setTimestamp($record->timestart + $record->timeduration), (new \DateTimeImmutable())->setTimestamp($record->timesort ? $record->timesort : $record->timestart), (new \DateTimeImmutable())->setTimestamp($record->timemodified), - (new \DateTimeImmutable())->setTimestamp(usergetmidnight($record->timesort)) + (new \DateTimeImmutable())->setTimestamp($record->timesort ? usergetmidnight($record->timesort) : 0) ), !empty($record->visible), $subscription, diff --git a/lib/excellib.class.php b/lib/excellib.class.php index 2bd4a0f8eed..6950fbbdc44 100644 --- a/lib/excellib.class.php +++ b/lib/excellib.class.php @@ -246,7 +246,7 @@ class MoodleExcelWorksheet { * Write one date somewhere in the worksheet. * @param integer $row Zero indexed row * @param integer $col Zero indexed column - * @param string $date The date to write in UNIX timestamp format + * @param int $date The date to write in UNIX timestamp format * @param mixed $format The XF format for the cell */ public function write_date($row, $col, $date, $format = null) { diff --git a/lib/form/defaultcustom.php b/lib/form/defaultcustom.php index 16a263d1399..300f2d837bb 100644 --- a/lib/form/defaultcustom.php +++ b/lib/form/defaultcustom.php @@ -103,7 +103,7 @@ class MoodleQuickForm_defaultcustom extends MoodleQuickForm_group { */ protected function timestamp_to_date_array($value) { $calendartype = \core_calendar\type_factory::get_calendar_instance(); - $currentdate = $calendartype->timestamp_to_date_array($value, $this->_options['timezone']); + $currentdate = $calendartype->timestamp_to_date_array((int)$value, $this->_options['timezone']); return array( 'minute' => $currentdate['minutes'], 'hour' => $currentdate['hours'], diff --git a/lib/moodlelib.php b/lib/moodlelib.php index b6e9e2f2e63..bfbfaaedea4 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -2354,6 +2354,14 @@ function date_format_string($date, $format, $tz = 99) { * @return array An array that represents the date in user time */ function usergetdate($time, $timezone=99) { + if ($time === null) { + // PHP8 and PHP7 return different results when getdate(null) is called. + // Display warning and cast to 0 to make sure the usergetdate() behaves consistently on all versions of PHP. + // In the future versions of Moodle we may consider adding a strict typehint. + debugging('usergetdate() expects parameter $time to be int, null given', DEBUG_DEVELOPER); + $time = 0; + } + date_default_timezone_set(core_date::get_user_timezone($timezone)); $result = getdate($time); core_date::set_default_server_timezone(); diff --git a/lib/tests/moodlelib_test.php b/lib/tests/moodlelib_test.php index 34f2f1c0a7d..4357f5a2825 100644 --- a/lib/tests/moodlelib_test.php +++ b/lib/tests/moodlelib_test.php @@ -1317,6 +1317,12 @@ class core_moodlelib_testcase extends advanced_testcase { $this->assertSame(356, $yday); $this->assertSame('Wednesday', $weekday); $this->assertSame('December', $month); + + // Edge cases - 0 and null - they all mean 1st Jan 1970. Null shows debugging message. + $this->assertSame(1970, usergetdate(0)['year']); + $this->assertDebuggingNotCalled(); + $this->assertSame(1970, usergetdate(null)['year']); + $this->assertDebuggingCalled(null, DEBUG_DEVELOPER); } public function test_mark_user_preferences_changed() {