From 5bbf568c2ffa07b15ab756460d36618ed55490c5 Mon Sep 17 00:00:00 2001 From: sam marshall Date: Thu, 5 Jun 2025 11:51:41 +0100 Subject: [PATCH] MDL-85679 mod_assign: Use core DI clock to make testing easier --- .upgradenotes/MDL-85679-2025060910570756.yml | 8 +++++ .../moodle2/restore_assign_stepslib.php | 5 +-- mod/assign/classes/dates.php | 2 +- .../classes/external/start_submission.php | 2 +- mod/assign/classes/output/grading_app.php | 2 +- mod/assign/classes/output/renderer.php | 6 ++-- mod/assign/classes/output/timelimit_panel.php | 2 +- mod/assign/extensionform.php | 2 +- .../comments/tests/privacy/provider_test.php | 2 +- .../editpdf/classes/document_services.php | 2 +- .../classes/task/convert_submission.php | 2 +- mod/assign/gradingtable.php | 5 +-- mod/assign/lib.php | 8 +++-- mod/assign/locallib.php | 36 ++++++++++--------- 14 files changed, 49 insertions(+), 35 deletions(-) create mode 100644 .upgradenotes/MDL-85679-2025060910570756.yml diff --git a/.upgradenotes/MDL-85679-2025060910570756.yml b/.upgradenotes/MDL-85679-2025060910570756.yml new file mode 100644 index 00000000000..a88d599d598 --- /dev/null +++ b/.upgradenotes/MDL-85679-2025060910570756.yml @@ -0,0 +1,8 @@ +issueNumber: MDL-85679 +notes: + mod_assign: + - message: >- + Within mod_assign, time() calls have been changed to use the core clock + class; this means Behat and PHPunit tests that mock the time will now + work as expected in mod_assign. + type: improved diff --git a/mod/assign/backup/moodle2/restore_assign_stepslib.php b/mod/assign/backup/moodle2/restore_assign_stepslib.php index 8f458d06107..02fa71a7034 100644 --- a/mod/assign/backup/moodle2/restore_assign_stepslib.php +++ b/mod/assign/backup/moodle2/restore_assign_stepslib.php @@ -315,8 +315,9 @@ class restore_assign_activity_structure_step extends restore_activity_structure_ $submission->status = ASSIGN_SUBMISSION_STATUS_NEW; $submission->groupid = 0; $submission->latest = 0; - $submission->timecreated = time(); - $submission->timemodified = time(); + $now = \core\di::get(\core\clock::class)->time(); + $submission->timecreated = $now; + $submission->timemodified = $now; array_push($submissions, $submission); } diff --git a/mod/assign/classes/dates.php b/mod/assign/classes/dates.php index 31d4ce63b43..d700649476c 100644 --- a/mod/assign/classes/dates.php +++ b/mod/assign/classes/dates.php @@ -71,7 +71,7 @@ class dates extends activity_dates { } } - $now = time(); + $now = \core\di::get(\core\clock::class)->time(); $dates = []; if ($timeopen) { diff --git a/mod/assign/classes/external/start_submission.php b/mod/assign/classes/external/start_submission.php index 35424a94f79..4a9fb88667e 100644 --- a/mod/assign/classes/external/start_submission.php +++ b/mod/assign/classes/external/start_submission.php @@ -94,7 +94,7 @@ class start_submission extends external_api { } // Set the start time of the submission. - $submission->timestarted = time(); + $submission->timestarted = \core\di::get(\core\clock::class)->time(); $DB->update_record('assign_submission', $submission); } diff --git a/mod/assign/classes/output/grading_app.php b/mod/assign/classes/output/grading_app.php index 647f1a81a0a..23978bbba88 100644 --- a/mod/assign/classes/output/grading_app.php +++ b/mod/assign/classes/output/grading_app.php @@ -137,7 +137,7 @@ class grading_app implements templatable, renderable { $export->showreview = $showreview; - $time = time(); + $time = \core\di::get(\core\clock::class)->time(); $export->count = count($export->participants); $export->coursename = $this->assignment->get_course_context()->get_context_name(true, false, false); $export->caneditsettings = has_capability('mod/assign:addinstance', $this->assignment->get_context()); diff --git a/mod/assign/classes/output/renderer.php b/mod/assign/classes/output/renderer.php index dfc510cc0dc..95a99d2cbea 100644 --- a/mod/assign/classes/output/renderer.php +++ b/mod/assign/classes/output/renderer.php @@ -345,7 +345,7 @@ class renderer extends \plugin_renderer_base { } } - $time = time(); + $time = \core\di::get(\core\clock::class)->time(); if ($summary->duedate) { // Time remaining. $duedate = $summary->duedate; @@ -644,7 +644,7 @@ class renderer extends \plugin_renderer_base { $o = ''; $o .= $this->output->container_start('submissionstatustable'); $o .= $this->output->heading(get_string('submissionstatusheading', 'assign'), 3); - $time = time(); + $time = \core\di::get(\core\clock::class)->time(); $o .= $this->output->box_start('boxaligncenter submissionsummarytable'); @@ -1300,7 +1300,7 @@ class renderer extends \plugin_renderer_base { * string and the second is a CSS class. */ protected function get_time_remaining(\mod_assign\output\assign_submission_status $status): array { - $time = time(); + $time = \core\di::get(\core\clock::class)->time(); $submission = $status->teamsubmission ? $status->teamsubmission : $status->submission; $submissionstarted = $submission && property_exists($submission, 'timestarted') && $submission->timestarted; $timelimitenabled = get_config('assign', 'enabletimelimit') && $status->timelimit > 0 && $submissionstarted; diff --git a/mod/assign/classes/output/timelimit_panel.php b/mod/assign/classes/output/timelimit_panel.php index 33025588b04..24ad62bb746 100644 --- a/mod/assign/classes/output/timelimit_panel.php +++ b/mod/assign/classes/output/timelimit_panel.php @@ -59,7 +59,7 @@ class timelimit_panel implements templatable, renderable { * @return stdClass - Flat list of exported data. */ public function export_for_template(renderer_base $output): stdClass { - return (object)['timerstartvalue' => $this->end_time() - time()]; + return (object)['timerstartvalue' => $this->end_time() - \core\di::get(\core\clock::class)->time()]; } /** diff --git a/mod/assign/extensionform.php b/mod/assign/extensionform.php index 790ced882c3..961f21d9659 100644 --- a/mod/assign/extensionform.php +++ b/mod/assign/extensionform.php @@ -157,7 +157,7 @@ class mod_assign_extension_form extends moodleform { $defaultdate = $lateststextension; } else { // Otherwise take the later of the deadline and one minute before midnight tonight (server time). - $endoftoday = new DateTimeImmutable('today 23:59', core_date::get_server_timezone_object()); + $endoftoday = \core\di::get(\core\clock::class)->now()->setTime(23, 59); $defaultdate = max($finaldate, $endoftoday->getTimestamp()); } $mform->addElement('date_time_selector', 'extensionduedate', diff --git a/mod/assign/feedback/comments/tests/privacy/provider_test.php b/mod/assign/feedback/comments/tests/privacy/provider_test.php index 6bfedb1482b..e4083e81139 100644 --- a/mod/assign/feedback/comments/tests/privacy/provider_test.php +++ b/mod/assign/feedback/comments/tests/privacy/provider_test.php @@ -43,7 +43,7 @@ final class provider_test extends provider_testcase { $submission = new \stdClass(); $submission->assignment = $assign->get_instance()->id; $submission->userid = $student->id; - $submission->timecreated = time(); + $submission->timecreated = \core\di::get(\core\clock::class)->time(); $submission->onlinetext_editor = ['text' => $submissiontext, 'format' => FORMAT_MOODLE]; diff --git a/mod/assign/feedback/editpdf/classes/document_services.php b/mod/assign/feedback/editpdf/classes/document_services.php index 193a6b6b51b..c6bb0ba40ad 100644 --- a/mod/assign/feedback/editpdf/classes/document_services.php +++ b/mod/assign/feedback/editpdf/classes/document_services.php @@ -1005,7 +1005,7 @@ EOD; } $filename = $matches[0].'png'; $tmpdir = make_request_directory(); - $tempfile = $tmpdir . '/' . time() . '_' . $filename; + $tempfile = $tmpdir . '/' . \core\di::get(\core\clock::class)->time() . '_' . $filename; imagepng($content, $tempfile); $filearea = self::PAGE_IMAGE_FILEAREA; diff --git a/mod/assign/feedback/editpdf/classes/task/convert_submission.php b/mod/assign/feedback/editpdf/classes/task/convert_submission.php index 9ca2c3887d3..ac379d58089 100644 --- a/mod/assign/feedback/editpdf/classes/task/convert_submission.php +++ b/mod/assign/feedback/editpdf/classes/task/convert_submission.php @@ -127,7 +127,7 @@ class convert_submission extends adhoc_task { mtrace('Conversion still in progress. Requeueing self to check again.'); $task = new self; $task->set_custom_data($data); - $task->set_next_run_time(time() + MINSECS); + $task->set_next_run_time(\core\di::get(\core\clock::class)->time() + MINSECS); manager::queue_adhoc_task($task); } else { mtrace('The document has been successfully converted'); diff --git a/mod/assign/gradingtable.php b/mod/assign/gradingtable.php index b81ee619e01..8bdc7d26b80 100644 --- a/mod/assign/gradingtable.php +++ b/mod/assign/gradingtable.php @@ -1269,7 +1269,7 @@ class assign_grading_table extends table_sql implements renderable { $submissioninfo .= $this->output->container(get_string('graded', 'assign'), 'submissiongraded'); } } else if (!$timesubmitted || $status == ASSIGN_SUBMISSION_STATUS_NEW) { - $now = time(); + $now = \core\di::get(\core\clock::class)->time(); if ($due && ($now > $due)) { $overduestr = get_string('overdue', 'assign', format_time($now - $due)); $submissioninfo .= $this->output->container($overduestr, 'overduesubmission'); @@ -1787,8 +1787,9 @@ class assign_grading_table extends table_sql implements renderable { if (empty($assignment->blindmarking)) { $result = array_merge($result, array('userid' => SORT_ASC)); } else { + $now = \core\di::get(\core\clock::class)->time(); $result = array_merge($result, [ - 'COALESCE(s.timecreated, ' . time() . ')' => SORT_ASC, + 'COALESCE(s.timecreated, ' . $now . ')' => SORT_ASC, 'COALESCE(s.id, ' . PHP_INT_MAX . ')' => SORT_ASC, 'um.id' => SORT_ASC, ]); diff --git a/mod/assign/lib.php b/mod/assign/lib.php index 72b0d7d2353..075cc7ba88c 100644 --- a/mod/assign/lib.php +++ b/mod/assign/lib.php @@ -503,7 +503,8 @@ function assign_get_coursemodule_info($coursemodule) { $result = new cached_cm_info(); $result->name = $assignment->name; if ($coursemodule->showdescription) { - if ($assignment->alwaysshowdescription || time() > $assignment->allowsubmissionsfromdate) { + $now = \core\di::get(\core\clock::class)->time(); + if ($assignment->alwaysshowdescription || $now > $assignment->allowsubmissionsfromdate) { // Convert intro to html. Do not filter cached version, filters run at display time. $result->content = format_module_intro('assign', $assignment, $coursemodule->id, false); } @@ -1624,7 +1625,8 @@ function mod_assign_core_calendar_provide_event_action(calendar_event $event, 'id' => $cm->id, 'action' => 'grader' ]); - $actionable = $assign->can_grade($userid) && (time() >= $assign->get_instance()->allowsubmissionsfromdate); + $now = \core\di::get(\core\clock::class)->time(); + $actionable = $assign->can_grade($userid) && ($now >= $assign->get_instance()->allowsubmissionsfromdate); $itemcount = $actionable ? $assign->count_submissions_need_grading() : 0; } else { $usersubmission = $assign->get_user_submission($userid, false); @@ -1790,7 +1792,7 @@ function mod_assign_core_calendar_event_timestart_updated(\calendar_event $event } if ($modified) { - $instance->timemodified = time(); + $instance->timemodified = \core\di::get(\core\clock::class)->time(); // Persist the assign instance changes. $DB->update_record('assign', $instance); $assign->update_calendar($coursemodule->id); diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index f460910367e..24eda454075 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -292,7 +292,7 @@ class assign { */ public function show_intro() { if ($this->get_instance()->alwaysshowdescription || - time() > $this->get_instance()->allowsubmissionsfromdate) { + \core\di::get(\core\clock::class)->time() > $this->get_instance()->allowsubmissionsfromdate) { return true; } return false; @@ -733,8 +733,9 @@ class assign { // Add the database record. $update = new stdClass(); $update->name = $formdata->name; - $update->timemodified = time(); - $update->timecreated = time(); + $now = \core\di::get(\core\clock::class)->time(); + $update->timemodified = $now; + $update->timecreated = $now; $update->course = $formdata->course; $update->courseid = $formdata->course; $update->intro = $formdata->intro; @@ -1528,7 +1529,7 @@ class assign { $update = new stdClass(); $update->id = $formdata->instance; $update->name = $formdata->name; - $update->timemodified = time(); + $update->timemodified = \core\di::get(\core\clock::class)->time(); $update->course = $formdata->course; $update->intro = $formdata->intro; $update->introformat = $formdata->introformat; @@ -2358,8 +2359,9 @@ class assign { // Note, different DBs have different ordering of NULL values. // Therefore we coalesce the current time into the timecreated field, and the max possible integer into // the ID field. + $now = \core\di::get(\core\clock::class)->time(); if (empty($tablesort)) { - $orderby = "COALESCE(s.timecreated, " . time() . ") ASC, COALESCE(s.id, " . PHP_INT_MAX . ") ASC, um.id ASC"; + $orderby = "COALESCE(s.timecreated, " . $now . ") ASC, COALESCE(s.id, " . PHP_INT_MAX . ") ASC, um.id ASC"; } } @@ -2773,8 +2775,8 @@ class assign { global $DB; // Only ever send a max of one days worth of updates. - $yesterday = time() - (24 * 3600); - $timenow = time(); + $timenow = \core\di::get(\core\clock::class)->time(); + $yesterday = $timenow - (24 * 3600); $task = \core\task\manager::get_scheduled_task(mod_assign\task\cron_task::class); $lastruntime = $task->get_last_run_time(); @@ -3008,7 +3010,7 @@ class assign { public function update_grade($grade, $reopenattempt = false) { global $DB; - $grade->timemodified = time(); + $grade->timemodified = \core\di::get(\core\clock::class)->time(); if (!empty($grade->workflowstate)) { $validstates = $this->get_marking_workflow_states_for_current_user(); @@ -3254,7 +3256,7 @@ class assign { $action = optional_param('action', '', PARAM_TEXT); if ($action == 'editsubmission') { if (empty($submission->timestarted) && $this->get_instance()->timelimit) { - $submission->timestarted = time(); + $submission->timestarted = \core\di::get(\core\clock::class)->time(); $DB->update_record('assign_submission', $submission); } } @@ -3266,7 +3268,7 @@ class assign { $submission->assignment = $this->get_instance()->id; $submission->userid = 0; $submission->groupid = $groupid; - $submission->timecreated = time(); + $submission->timecreated = \core\di::get(\core\clock::class)->time(); $submission->timemodified = $submission->timecreated; if ($attemptnumber >= 0) { $submission->attemptnumber = $attemptnumber; @@ -3767,7 +3769,7 @@ class assign { $action = optional_param('action', '', PARAM_TEXT); if ($action == 'editsubmission') { if (empty($submission->timestarted) && $this->get_instance()->timelimit) { - $submission->timestarted = time(); + $submission->timestarted = \core\di::get(\core\clock::class)->time(); $DB->update_record('assign_submission', $submission); } } @@ -3778,7 +3780,7 @@ class assign { $submission = new stdClass(); $submission->assignment = $this->get_instance()->id; $submission->userid = $userid; - $submission->timecreated = time(); + $submission->timecreated = \core\di::get(\core\clock::class)->time(); $submission->timemodified = $submission->timecreated; $submission->status = ASSIGN_SUBMISSION_STATUS_NEW; if ($attemptnumber >= 0) { @@ -3914,7 +3916,7 @@ class assign { $grade = new stdClass(); $grade->assignment = $this->get_instance()->id; $grade->userid = $userid; - $grade->timecreated = time(); + $grade->timecreated = \core\di::get(\core\clock::class)->time(); // If we are "auto-creating" a grade - and there is a submission // the new grade should not have a more recent timemodified value // than the submission. @@ -6092,7 +6094,7 @@ class assign { global $DB; if ($updatetime) { - $submission->timemodified = time(); + $submission->timemodified = \core\di::get(\core\clock::class)->time(); } // First update the submission for the current user. @@ -6168,7 +6170,7 @@ class assign { } if ($updatetime) { - $submission->timemodified = time(); + $submission->timemodified = \core\di::get(\core\clock::class)->time(); } $result= $DB->update_record('assign_submission', $submission); if ($result) { @@ -6203,7 +6205,7 @@ class assign { $userid = $USER->id; } - $time = time(); + $time = \core\di::get(\core\clock::class)->time(); $dateopen = true; $finaldate = false; if ($this->get_instance()->cutoffdate) { @@ -6743,7 +6745,7 @@ class assign { $instance = $this->get_instance(); - $late = $instance->duedate && ($instance->duedate < time()); + $late = $instance->duedate && ($instance->duedate < \core\di::get(\core\clock::class)->time()); if (!$instance->sendnotifications && !($late && $instance->sendlatenotifications)) { // No need to do anything.