From d8a1cf696e815b7b06fadf7afd146c286056cf06 Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Mon, 26 Apr 2021 10:41:29 +1000 Subject: [PATCH] MDL-71163 core: support relative dates in activity dates AMOS BEGIN CPY [relativedatessubmissionduedateafter,mod_assign],[relativedatessubmissionduedateafter,core_course] CPY [relativedatessubmissionduedatebefore,mod_assign],[relativedatessubmissionduedatebefore,core_course] AMOS END --- .../classes/output/activity_information.php | 25 ++++++++++++++++++- course/templates/activity_date.mustache | 4 +-- lang/en/course.php | 2 ++ mod/assign/classes/dates.php | 20 +++++++++++++-- mod/assign/lang/en/assign.php | 6 +++-- mod/assign/lang/en/deprecated.txt | 2 ++ mod/assign/lib.php | 10 ++++++++ mod/assign/renderer.php | 4 +-- mod/assign/tests/behat/relative_dates.feature | 23 +++++++++++++++++ 9 files changed, 87 insertions(+), 9 deletions(-) diff --git a/course/classes/output/activity_information.php b/course/classes/output/activity_information.php index deaa39c2a2d..56b763bce0c 100644 --- a/course/classes/output/activity_information.php +++ b/course/classes/output/activity_information.php @@ -80,12 +80,35 @@ class activity_information implements renderable, templatable { $data->cmid = $this->cminfo->id; $data->activityname = $this->cminfo->name; - $data->activitydates = $this->activitydates; + $this->build_dates_data($data); $data->hasdates = !empty($this->activitydates); return $data; } + /** + * Builds the dates data for export. + * + * @param stdClass $data + */ + protected function build_dates_data(stdClass $data): void { + foreach ($this->activitydates as $date) { + if (empty($date['relativeto'])) { + $date['datestring'] = userdate($date['timestamp'], get_string('strftimedatetime', 'core_langconfig')); + } else { + $diffstr = get_time_interval_string($date['timestamp'], $date['relativeto']); + if ($date['timestamp'] >= $date['relativeto']) { + $date['datestring'] = get_string('relativedatessubmissionduedateafter', 'core_course', + ['datediffstr' => $diffstr]); + } else { + $date['datestring'] = get_string('relativedatessubmissionduedatebefore', 'core_course', + ['datediffstr' => $diffstr]); + } + } + $data->activitydates[] = $date; + } + } + /** * Builds the completion data for export. * diff --git a/course/templates/activity_date.mustache b/course/templates/activity_date.mustache index c50e292d6dc..a2013d6a20d 100644 --- a/course/templates/activity_date.mustache +++ b/course/templates/activity_date.mustache @@ -22,9 +22,9 @@ Example context (json): { "label": "Opens:", - "timestamp": 1293876000 + "datestring": "6 April 2021, 6:46 PM" } }}
- {{label}} {{#userdate}} {{timestamp}}, {{#str}} strftimedatetime, core_langconfig {{/str}} {{/userdate}} + {{label}} {{datestring}}
diff --git a/lang/en/course.php b/lang/en/course.php index 2a080b0ce2a..50649324ab7 100644 --- a/lang/en/course.php +++ b/lang/en/course.php @@ -97,6 +97,8 @@ $string['privacy:metadata:completionsummary'] = 'The course contains completion $string['privacy:metadata:favouritessummary'] = 'The course contains information relating to the course being starred by the user.'; $string['recommend'] = 'Recommend'; $string['recommendcheckbox'] = 'Recommend activity: {$a}'; +$string['relativedatessubmissionduedateafter'] = '{$a->datediffstr} after course start'; +$string['relativedatessubmissionduedatebefore'] = '{$a->datediffstr} before course start'; $string['searchactivitiesbyname'] = 'Search for activities by name'; $string['searchresults'] = 'Search results: {$a}'; $string['submitsearch'] = 'Submit search'; diff --git a/mod/assign/classes/dates.php b/mod/assign/classes/dates.php index f2a4c9177de..9de15e8a86c 100644 --- a/mod/assign/classes/dates.php +++ b/mod/assign/classes/dates.php @@ -42,6 +42,14 @@ class dates extends activity_dates { * @return array */ protected function get_dates(): array { + global $CFG; + + require_once($CFG->dirroot . '/mod/assign/locallib.php'); + + $course = get_course($this->cm->course); + $context = \context_module::instance($this->cm->id); + $assign = new \assign($context, $this->cm, $course); + $timeopen = $this->cm->customdata['allowsubmissionsfromdate'] ?? null; $timedue = $this->cm->customdata['duedate'] ?? null; $now = time(); @@ -49,17 +57,25 @@ class dates extends activity_dates { if ($timeopen) { $openlabelid = $timeopen > $now ? 'activitydate:submissionsopen' : 'activitydate:submissionsopened'; - $dates[] = [ + $date = [ 'label' => get_string($openlabelid, 'mod_assign'), 'timestamp' => (int) $timeopen, ]; + if ($course->relativedatesmode && $assign->can_view_grades()) { + $date['relativeto'] = $course->startdate; + } + $dates[] = $date; } if ($timedue) { - $dates[] = [ + $date = [ 'label' => get_string('activitydate:submissionsdue', 'mod_assign'), 'timestamp' => (int) $timedue, ]; + if ($course->relativedatesmode && $assign->can_view_grades()) { + $date['relativeto'] = $course->startdate; + } + $dates[] = $date; } return $dates; diff --git a/mod/assign/lang/en/assign.php b/mod/assign/lang/en/assign.php index b68423d0c91..27ba57beb75 100644 --- a/mod/assign/lang/en/assign.php +++ b/mod/assign/lang/en/assign.php @@ -450,8 +450,6 @@ $string['quickgradingresult'] = 'Quick grading'; $string['quickgradingchangessaved'] = 'The grade changes were saved'; $string['quickgrading_help'] = 'Quick grading allows you to assign grades (and outcomes) directly in the submissions table. Quick grading is not compatible with advanced grading and is not recommended when there are multiple markers.'; $string['relativedatessubmissiontimeleft'] = 'Calculated for each student'; -$string['relativedatessubmissionduedateafter'] = '{$a->datediffstr} after course start'; -$string['relativedatessubmissionduedatebefore'] = '{$a->datediffstr} before course start'; $string['removeallgroupoverrides'] = 'Delete all group overrides'; $string['removealluseroverrides'] = 'Delete all user overrides'; $string['reopenuntilpassincompatiblewithblindmarking'] = 'Reopen until pass option is incompatible with anonymous submissions, because the grades are not released to the gradebook until the student identities are revealed.'; @@ -640,3 +638,7 @@ $string['nolatesubmissions'] = 'No late submissions accepted. '; $string['nosubmissionsacceptedafter'] = 'No submissions accepted after '; $string['notsubmittedyet'] = 'Not submitted yet'; $string['submissionsnotgraded'] = 'Submissions not graded: {$a}'; + +// Deprecated since Moodle 3.11. +$string['relativedatessubmissionduedateafter'] = '{$a->datediffstr} after course start'; +$string['relativedatessubmissionduedatebefore'] = '{$a->datediffstr} before course start'; diff --git a/mod/assign/lang/en/deprecated.txt b/mod/assign/lang/en/deprecated.txt index 41f5cf7846e..f2d7c5df466 100644 --- a/mod/assign/lang/en/deprecated.txt +++ b/mod/assign/lang/en/deprecated.txt @@ -3,4 +3,6 @@ mysubmission,mod_assign nolatesubmissions,mod_assign nosubmissionsacceptedafter,mod_assign notsubmittedyet,mod_assign +relativedatessubmissionduedateafter,mod_assign +relativedatessubmissionduedatebefore,mod_assign submissionsnotgraded,mod_assign \ No newline at end of file diff --git a/mod/assign/lib.php b/mod/assign/lib.php index 45a9708ee2d..eaf7203b843 100644 --- a/mod/assign/lib.php +++ b/mod/assign/lib.php @@ -572,6 +572,16 @@ function mod_assign_cm_info_dynamic(cm_info $cm) { } } + // Calculate relative dates. The assignment module calculates relative date only for duedate. + // A user or group override always has higher priority over any relative date calculation. + if (empty($override->duedate) && !empty($cm->customdata['duedate'])) { + $course = get_course($cm->course); + $usercoursedates = course_get_course_dates_for_user_id($course, $USER->id); + if ($usercoursedates['start']) { + $override->duedate = $cm->customdata['duedate'] + $usercoursedates['startoffset']; + } + } + // Populate some other values that can be used in calendar or on dashboard. if (!is_null($override->allowsubmissionsfromdate)) { $cm->override_customdata('allowsubmissionsfromdate', $override->allowsubmissionsfromdate); diff --git a/mod/assign/renderer.php b/mod/assign/renderer.php index 1af000027a5..ddc45cde30d 100644 --- a/mod/assign/renderer.php +++ b/mod/assign/renderer.php @@ -342,10 +342,10 @@ class mod_assign_renderer extends plugin_renderer_base { // Returns a formatted string, in the format '10d 10h 45m'. $diffstr = get_time_interval_string($duedate, $summary->coursestartdate); if ($duedate >= $summary->coursestartdate) { - $cell2content = get_string('relativedatessubmissionduedateafter', 'mod_assign', + $cell2content = get_string('relativedatessubmissionduedateafter', 'core_course', ['datediffstr' => $diffstr]); } else { - $cell2content = get_string('relativedatessubmissionduedatebefore', 'mod_assign', + $cell2content = get_string('relativedatessubmissionduedatebefore', 'core_course', ['datediffstr' => $diffstr]); } } else { diff --git a/mod/assign/tests/behat/relative_dates.feature b/mod/assign/tests/behat/relative_dates.feature index d1204f3115e..b835a640531 100644 --- a/mod/assign/tests/behat/relative_dates.feature +++ b/mod/assign/tests/behat/relative_dates.feature @@ -35,6 +35,29 @@ I should be able to create an assignment with a due date relative to the course And I follow "Test assignment name" And I should not see "Assignment is overdue by:" in the "Time remaining" "table_row" + Scenario: As a student the due date I see for submitting my assignment is relative to my course start date + Given the following config values are set as admin: + | enablecourserelativedates | 1 | + And the following "courses" exist: + # A course with start date set to 1 Jan 2021. + | fullname | shortname | category | groupmode | relativedatesmode | startdate | + | Course 1 | C1 | 0 | 1 | 1 | 1609459200 | + And the following "users" exist: + | username | firstname | lastname | email | + | student1 | Student | 1 | student1@example.com | + And the following "course enrolments" exist: + # User's enrolment starts from 5 Jan 2021. + | user | course | role | timestart | + | student1 | C1 | student | 1609804800 | + And the following "activities" exist: + # The assignment's due date is 3 Jan 2021. + | activity | name | intro | course | idnumber | assignsubmission_onlinetext_enabled | duedate | + | assign | Test assignment name | Test assignment description | C1 | assign0 | 1 | 1609632000 | + When I log in as "student1" + And I am on "Course 1" course homepage + And I follow "Test assignment name" + Then the activity date in "Test assignment name" should contain "Due: 7 January 2021, 8:00 AM" + Scenario: As a teacher, I should see the relative dates when reviewing assignment submissions Given the following config values are set as admin: | enablecourserelativedates | 1 |