diff --git a/mod/assign/classes/output/user_submission_actionmenu.php b/mod/assign/classes/output/user_submission_actionmenu.php index d8a52a0e6b8..4d939cb6fb3 100644 --- a/mod/assign/classes/output/user_submission_actionmenu.php +++ b/mod/assign/classes/output/user_submission_actionmenu.php @@ -89,6 +89,16 @@ class user_submission_actionmenu implements templatable, renderable { } } + /** + * Has the submission started. + * + * @return bool The status of the submission; true if started, otherwise false. + */ + protected function is_submission_started(): bool { + return (is_object($this->teamsubmission) && isset($this->teamsubmission->timestarted)) + || (is_object($this->submission) && isset($this->submission->timestarted)); + } + /** * Export the submission buttons for the page. * @@ -130,20 +140,20 @@ class user_submission_actionmenu implements templatable, renderable { $data['edit']['help'] = $newattempthelp->export_for_template($output); } if ($status === ASSIGN_SUBMISSION_STATUS_NEW) { - $timelimitenabled = get_config('assign', 'enabletimelimit'); - if ($timelimitenabled && $this->timelimit && empty($this->submission->timestarted)) { + if ($timelimitenabled && $this->timelimit && !$this->is_submission_started()) { $confirmation = new \confirm_action( get_string('confirmstart', 'assign', format_time($this->timelimit)), null, get_string('beginassignment', 'assign') ); - $urlparams = array('id' => $this->cmid, 'action' => 'editsubmission'); + // The 'begin' flag indicates that the user is starting a timed assignment. + $urlparams = ['id' => $this->cmid, 'action' => 'editsubmission', 'begin' => 1]; $beginbutton = new \action_link( new moodle_url('/mod/assign/view.php', $urlparams), - get_string('beginassignment', 'assign'), - $confirmation, - ['class' => 'btn btn-primary'] + get_string('beginassignment', 'assign'), + $confirmation, + ['class' => 'btn btn-primary'] ); $data['edit']['button'] = $beginbutton->export_for_template($output); $data['edit']['begin'] = true; diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index 545100bbe58..2c3d2051e27 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -3211,7 +3211,9 @@ class assign { if ($create) { $action = optional_param('action', '', PARAM_TEXT); if ($action == 'editsubmission') { - if (empty($submission->timestarted) && $this->get_instance()->timelimit) { + $starttimer = optional_param('begin', 0, PARAM_INT); + // Only start the timer if the user has clicked the 'Begin assignment' button. + if (empty($submission->timestarted) && $this->get_instance()->timelimit && $starttimer) { $submission->timestarted = time(); $DB->update_record('assign_submission', $submission); } @@ -3822,7 +3824,9 @@ class assign { if ($create) { $action = optional_param('action', '', PARAM_TEXT); if ($action == 'editsubmission') { - if (empty($submission->timestarted) && $this->get_instance()->timelimit) { + $starttimer = optional_param('begin', 0, PARAM_INT); + // Only start the timer if the user has clicked the 'Begin assignment' button. + if (empty($submission->timestarted) && $this->get_instance()->timelimit && $starttimer) { $submission->timestarted = time(); $DB->update_record('assign_submission', $submission); } @@ -4832,7 +4836,7 @@ class assign { * @return string The page output. */ protected function view_edit_submission_page($mform, $notices) { - global $CFG, $USER, $DB, $PAGE; + global $CFG, $USER, $DB, $PAGE, $OUTPUT; $o = ''; require_once($CFG->dirroot . '/mod/assign/submission_form.php'); @@ -4917,7 +4921,30 @@ class assign { $o .= $this->get_renderer()->notification($notice); } - $o .= $this->get_renderer()->render(new assign_form('editsubmissionform', $mform)); + if ( + $submission->status == ASSIGN_SUBMISSION_STATUS_NEW && $this->get_instance()->timelimit && + empty($submission->timestarted) + ) { + // Timed assignment should always get a confirmation that the user wants to start it. + $confirmation = new \confirm_action( + get_string('confirmstart', 'assign', format_time($this->get_instance()->timelimit)), + null, + get_string('beginassignment', 'assign') + ); + // The 'begin' flag indicates that the user is starting a timed assignment. + $urlparams = ['id' => $this->get_course_module()->id, 'action' => 'editsubmission', 'begin' => 1]; + $beginbutton = new \action_link( + new moodle_url('/mod/assign/view.php', $urlparams), + get_string('beginassignment', 'assign'), + $confirmation, + ['class' => 'btn btn-primary'] + ); + + $o .= $OUTPUT->render($beginbutton); + } else { + $o .= $this->get_renderer()->render(new assign_form('editsubmissionform', $mform)); + } + $o .= $this->view_footer(); \mod_assign\event\submission_form_viewed::create_from_user($this, $user)->trigger(); diff --git a/mod/assign/tests/behat/timed_assignment.feature b/mod/assign/tests/behat/timed_assignment.feature new file mode 100644 index 00000000000..f84bc2c1a88 --- /dev/null +++ b/mod/assign/tests/behat/timed_assignment.feature @@ -0,0 +1,84 @@ +@mod @mod_assign +Feature: In a timed assignment, students should confirm before starting the timer + In order to submit a timed assignment + As a student + I need to confirm to begin the assignment before the timer starts + + Background: + Given the following config values are set as admin: + | config | value | plugin | + | enabletimelimit | 1 | assign | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "users" exist: + | username | firstname | lastname | email | + | student1 | Student | 1 | student1@example.com | + | student2 | Student | 2 | student2@example.com | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | student2 | C1 | student | + And the following "activities" exist: + | activity | course | name | assignsubmission_file_enabled | assignsubmission_file_maxfiles | assignsubmission_file_maxsizebytes | teamsubmission | duedate | timelimit | + | assign | C1 | Timed assignment 1 | 1 | 1 | 2097152 | 0 | ##+1 hours 30 minutes## | 60 | + | assign | C1 | Group assignment 2 | 1 | 1 | 2097152 | 1 | ##+1 hours 30 minutes## | 60 | + + Scenario: Access a timed assignment from the course page + Given I am on the "Timed assignment 1" Activity page logged in as student1 + And "Begin assignment" "link" should exist + When I reload the page + Then "Begin assignment" "link" should exist + And "#mod_assign_timelimit_block" "css_element" should not exist + + @javascript + Scenario: Access a timed assignment from the Dashboard + Given I am logged in as student1 + When I click on "Timed assignment 1" "link" in the "Calendar" "block" + And I click on "Add submission" "link" in the ".modal-footer" "css_element" + Then "Begin assignment" "link" should exist + And I reload the page + And "Begin assignment" "link" should exist + And "#mod_assign_timelimit_block" "css_element" should not exist + # Repeat the steps to confirm timer doesn't start automatically. + And I select "Dashboard" from primary navigation + And I click on "Timed assignment 1" "link" in the "Calendar" "block" + And I click on "Add submission" "link" in the ".modal-footer" "css_element" + And "Begin assignment" "link" should exist + And "#mod_assign_timelimit_block" "css_element" should not exist + # Now start the timer. + And I click on "Begin assignment" "link" + And I click on "Begin assignment" "button" in the ".modal-footer" "css_element" + And "#mod_assign_timelimit_block" "css_element" should exist + + @javascript + Scenario: Access a timed group assignment from the Dashboard + Given the following "groups" exist: + | name | course | idnumber | + | Group 1 | C1 | CG1 | + And the following "group members" exist: + | user | group | + | student1 | CG1 | + | student2 | CG1 | + And I am logged in as student1 + When I click on "Group assignment 2" "link" in the "Calendar" "block" + And I click on "Add submission" "link" in the ".modal-footer" "css_element" + Then "Begin assignment" "link" should exist + And I reload the page + And "Begin assignment" "link" should exist + And "#mod_assign_timelimit_block" "css_element" should not exist + # Repeat the steps to confirm timer doesn't start automatically. + And I select "Dashboard" from primary navigation + And I click on "Group assignment 2" "link" in the "Calendar" "block" + And I click on "Add submission" "link" in the ".modal-footer" "css_element" + And "Begin assignment" "link" should exist + And "#mod_assign_timelimit_block" "css_element" should not exist + # Now start the timer. + And I click on "Begin assignment" "link" + And I click on "Begin assignment" "button" in the ".modal-footer" "css_element" + And "#mod_assign_timelimit_block" "css_element" should exist + And I log out + # Now check the submission has started for the other group member too. + And I am on the "Group assignment 2" "assign activity" page logged in as student2 + And "Begin assignment" "link" should not exist + And "Add submission" "button" should exist