mirror of
https://github.com/moodle/moodle.git
synced 2025-06-02 06:05:31 +02:00
MDL-28448 Assign: Add a new capability that lets teachers mess with student submissions.
This commit is contained in:
parent
b19608d682
commit
57fbd5f91f
@ -82,6 +82,12 @@ $capabilities = array(
|
||||
'clonepermissionsfrom' => 'moodle/course:manageactivities'
|
||||
),
|
||||
|
||||
'mod/assign:editothersubmission' => array(
|
||||
'riskbitmask' => RISK_MANAGETRUST|RISK_DATALOSS|RISK_PERSONAL,
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_MODULE
|
||||
),
|
||||
|
||||
'mod/assign:grantextension' => array(
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_MODULE,
|
||||
|
@ -1422,9 +1422,10 @@ class mod_assign_external extends external_api {
|
||||
$warnings = array();
|
||||
$data = new stdClass();
|
||||
$data->submissionstatement = $acceptsubmissionstatement;
|
||||
$notices = array();
|
||||
|
||||
if (!$assignment->submit_for_grading($data)) {
|
||||
$detail = 'User id: ' . $USER->id . ', Assignment id: ' . $assignmentid;
|
||||
if (!$assignment->submit_for_grading($data, $notices)) {
|
||||
$detail = 'User id: ' . $USER->id . ', Assignment id: ' . $assignmentid . ' Notices:' . implode(', ', $notices);
|
||||
$warnings[] = self::generate_warning($assignmentid,
|
||||
'couldnotsubmitforgrading',
|
||||
$detail);
|
||||
|
@ -962,6 +962,8 @@ class assign_grading_table extends table_sql implements renderable {
|
||||
* @return string
|
||||
*/
|
||||
public function col_userid(stdClass $row) {
|
||||
global $USER;
|
||||
|
||||
$edit = '';
|
||||
|
||||
$actions = array();
|
||||
@ -978,6 +980,9 @@ class assign_grading_table extends table_sql implements renderable {
|
||||
}
|
||||
$actions[$url->out(false)] = $description;
|
||||
|
||||
$submissionsopen = $this->assignment->submissions_open($row->id);
|
||||
$caneditsubmission = $this->assignment->can_edit_submission($row->id, $USER->id);
|
||||
|
||||
// Hide for offline assignments.
|
||||
if ($this->assignment->is_any_submission_plugin_enabled()) {
|
||||
if (!$row->status ||
|
||||
@ -1018,6 +1023,18 @@ class assign_grading_table extends table_sql implements renderable {
|
||||
$description = get_string('grantextension', 'assign');
|
||||
$actions[$url->out(false)] = $description;
|
||||
}
|
||||
if ($submissionsopen &&
|
||||
$USER->id != $row->id &&
|
||||
$caneditsubmission) {
|
||||
$urlparams = array('id' => $this->assignment->get_course_module()->id,
|
||||
'userid'=>$row->id,
|
||||
'action'=>'editsubmission',
|
||||
'sesskey'=>sesskey(),
|
||||
'page'=>$this->currpage);
|
||||
$url = new moodle_url('/mod/assign/view.php', $urlparams);
|
||||
$description = get_string('editsubmission', 'assign');
|
||||
$actions[$url->out(false)] = $description;
|
||||
}
|
||||
}
|
||||
if ($row->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED &&
|
||||
$this->assignment->get_instance()->submissiondrafts) {
|
||||
@ -1030,6 +1047,20 @@ class assign_grading_table extends table_sql implements renderable {
|
||||
$description = get_string('reverttodraftshort', 'assign');
|
||||
$actions[$url->out(false)] = $description;
|
||||
}
|
||||
if ($row->status == ASSIGN_SUBMISSION_STATUS_DRAFT &&
|
||||
$this->assignment->get_instance()->submissiondrafts &&
|
||||
$caneditsubmission &&
|
||||
$submissionsopen &&
|
||||
$row->id != $USER->id) {
|
||||
$urlparams = array('id' => $this->assignment->get_course_module()->id,
|
||||
'userid'=>$row->id,
|
||||
'action'=>'submitotherforgrading',
|
||||
'sesskey'=>sesskey(),
|
||||
'page'=>$this->currpage);
|
||||
$url = new moodle_url('/mod/assign/view.php', $urlparams);
|
||||
$description = get_string('submitforgrading', 'assign');
|
||||
$actions[$url->out(false)] = $description;
|
||||
}
|
||||
|
||||
$ismanual = $this->assignment->get_instance()->attemptreopenmethod == ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL;
|
||||
$hassubmission = !empty($row->status);
|
||||
|
@ -42,6 +42,7 @@ $string['alwaysshowdescription_help'] = 'If disabled, the Assignment Description
|
||||
$string['applytoteam'] = 'Apply grades and feedback to entire group';
|
||||
$string['assign:addinstance'] = 'Add a new assignment';
|
||||
$string['assign:exportownsubmission'] = 'Export own submission';
|
||||
$string['assign:editothersubmission'] = 'Edit another students submission';
|
||||
$string['assign:grade'] = 'Grade assignment';
|
||||
$string['assign:grantextension'] = 'Grant extension';
|
||||
$string['assign:manageallocations'] = 'Manage markers allocated to submissions';
|
||||
@ -135,6 +136,7 @@ $string['duedatevalidation'] = 'Due date must be after the allow submissions fro
|
||||
$string['editattemptfeedback'] = 'Edit the grade and feedback for attempt number {$a}.';
|
||||
$string['editingpreviousfeedbackwarning'] = 'You are editing the feedback for a previous attempt. This is attempt {$a->attemptnumber} out of {$a->totalattempts}.';
|
||||
$string['editsubmission'] = 'Edit submission';
|
||||
$string['editsubmissionother'] = 'Edit submission for {$a}';
|
||||
$string['editsubmission_help'] = 'Make changes to your submission';
|
||||
$string['editingstatus'] = 'Editing status';
|
||||
$string['editaction'] = 'Actions...';
|
||||
@ -350,6 +352,16 @@ $string['submissionnoteditable'] = 'Student cannot edit this submission';
|
||||
$string['submissionnotready'] = 'This assignment is not ready to submit:';
|
||||
$string['submissionplugins'] = 'Submission plugins';
|
||||
$string['submissionreceipts'] = 'Send submission receipts';
|
||||
$string['submissionreceiptothertext'] = 'Your assignment submission for
|
||||
\'{$a->assignment}\' has been submitted.
|
||||
|
||||
You can see the status of your assignment submission:
|
||||
|
||||
{$a->url}';
|
||||
$string['submissionreceiptotherhtml'] = 'Your assignment submission for
|
||||
\'<i>{$a->assignment}</i>\' has been submitted.<br /><br />
|
||||
You can see the status of your <a href="{$a->url}">assignment submission</a>.';
|
||||
$string['submissionreceiptothersmall'] = 'Your assignment submission for {$a->assignment} has been submitted.';
|
||||
$string['submissionreceipttext'] = 'You have submitted an
|
||||
assignment submission for \'{$a->assignment}\'
|
||||
|
||||
@ -381,6 +393,7 @@ $string['submissionsummary'] = '{$a->status}. Last modified on {$a->timemodified
|
||||
$string['submissionteam'] = 'Group';
|
||||
$string['submission'] = 'Submission';
|
||||
$string['submitaction'] = 'Submit';
|
||||
$string['submitforgrading'] = 'Submit for grading';
|
||||
$string['submitassignment_help'] = 'Once this assignment is submitted you will not be able to make any more changes.';
|
||||
$string['submitassignment'] = 'Submit assignment';
|
||||
$string['submittedearly'] = 'Assignment was submitted {$a} early';
|
||||
@ -426,3 +439,4 @@ $string['workflowfilter'] = 'Workflow filter';
|
||||
$string['submissiontypes'] = 'Submission types';
|
||||
$string['feedbacktypes'] = 'Feedback types';
|
||||
$string['groupsubmissionsettings'] = 'Group submission settings';
|
||||
$string['submissionlog'] = 'Student: {$a->fullname}, Status: {$a->status}';
|
||||
|
@ -417,9 +417,18 @@ class assign {
|
||||
$nextpageparams['action'] = 'grading';
|
||||
} else if ($action == 'confirmsubmit') {
|
||||
$action = 'submit';
|
||||
if ($this->process_submit_for_grading($mform)) {
|
||||
if ($this->process_submit_for_grading($mform, $notices)) {
|
||||
$action = 'redirect';
|
||||
$nextpageparams['action'] = 'view';
|
||||
} else if ($notices) {
|
||||
$action = 'viewsubmitforgradingerror';
|
||||
}
|
||||
} else if ($action == 'submitotherforgrading') {
|
||||
if ($this->process_submit_other_for_grading($mform, $notices)) {
|
||||
$action = 'redirect';
|
||||
$nextpageparams['action'] = 'grading';
|
||||
} else {
|
||||
$action = 'viewsubmitforgradingerror';
|
||||
}
|
||||
} else if ($action == 'gradingbatchoperation') {
|
||||
$action = $this->process_grading_batch_operation($mform);
|
||||
@ -521,6 +530,8 @@ class assign {
|
||||
$o .= $this->view_batch_set_workflow_state($mform);
|
||||
} else if ($action == 'viewbatchmarkingallocation') {
|
||||
$o .= $this->view_batch_markingallocation($mform);
|
||||
} else if ($action == 'viewsubmitforgradingerror') {
|
||||
$o .= $this->view_error_page(get_string('submitforgrading', 'assign'), $notices);
|
||||
} else {
|
||||
$o .= $this->view_submission_page();
|
||||
}
|
||||
@ -3187,28 +3198,47 @@ class assign {
|
||||
/**
|
||||
* Message for students when assignment submissions have been closed.
|
||||
*
|
||||
* @param string $title The page title
|
||||
* @param array $notices The array of notices to show.
|
||||
* @return string
|
||||
*/
|
||||
protected function view_student_error_message() {
|
||||
protected function view_notices($title, $notices) {
|
||||
global $CFG;
|
||||
|
||||
$o = '';
|
||||
// Need submit permission to submit an assignment.
|
||||
require_capability('mod/assign:submit', $this->context);
|
||||
|
||||
$header = new assign_header($this->get_instance(),
|
||||
$this->get_context(),
|
||||
$this->show_intro(),
|
||||
$this->get_course_module()->id,
|
||||
get_string('editsubmission', 'assign'));
|
||||
$title);
|
||||
$o .= $this->get_renderer()->render($header);
|
||||
|
||||
$o .= $this->get_renderer()->notification(get_string('submissionsclosed', 'assign'));
|
||||
foreach ($notices as $notice) {
|
||||
$o .= $this->get_renderer()->notification($notice);
|
||||
}
|
||||
|
||||
$url = new moodle_url('/mod/assign/view.php', array('id'=>$this->get_course_module()->id, 'action'=>'view'));
|
||||
$o .= $this->get_renderer()->continue_button($url);
|
||||
|
||||
$o .= $this->view_footer();
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name for a user - hiding their real name if blind marking is on.
|
||||
*
|
||||
* @param stdClass $user The user record as required by fullname()
|
||||
* @return string The name.
|
||||
*/
|
||||
protected function fullname($user) {
|
||||
if ($this->is_blind_marking()) {
|
||||
$uniqueid = $this->get_uniqueid_for_user($userid);
|
||||
return get_string('participant', 'assign') . ' ' . $uniqueid;
|
||||
} else {
|
||||
return fullname($user);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3220,24 +3250,44 @@ class assign {
|
||||
* @return string The page output.
|
||||
*/
|
||||
protected function view_edit_submission_page($mform, $notices) {
|
||||
global $CFG;
|
||||
global $CFG, $USER, $DB;
|
||||
|
||||
$o = '';
|
||||
require_once($CFG->dirroot . '/mod/assign/submission_form.php');
|
||||
// Need submit permission to submit an assignment.
|
||||
require_capability('mod/assign:submit', $this->context);
|
||||
$userid = optional_param('userid', $USER->id, PARAM_INT);
|
||||
$user = clone($USER);
|
||||
if ($userid == $USER->id) {
|
||||
// User is editing their own submission.
|
||||
require_capability('mod/assign:submit', $this->context);
|
||||
$title = get_string('editsubmission', 'assign');
|
||||
} else {
|
||||
// User is editing another user's submission.
|
||||
if (!$this->can_edit_submission($userid, $USER->id)) {
|
||||
print_error('nopermission');
|
||||
}
|
||||
|
||||
if (!$this->submissions_open()) {
|
||||
return $this->view_student_error_message();
|
||||
$user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
|
||||
$name = $this->fullname($user);
|
||||
$title = get_string('editsubmissionother', 'assign', $name);
|
||||
}
|
||||
|
||||
if (!$this->submissions_open($userid)) {
|
||||
$message = array(get_string('submissionsclosed', 'assign'));
|
||||
return $this->view_notices($title, $message);
|
||||
}
|
||||
|
||||
$o .= $this->get_renderer()->render(new assign_header($this->get_instance(),
|
||||
$this->get_context(),
|
||||
$this->show_intro(),
|
||||
$this->get_course_module()->id,
|
||||
get_string('editsubmission', 'assign')));
|
||||
$o .= $this->plagiarism_print_disclosure();
|
||||
$title));
|
||||
if ($userid == $USER->id) {
|
||||
// We only show this if it their submission.
|
||||
$o .= $this->plagiarism_print_disclosure();
|
||||
}
|
||||
$data = new stdClass();
|
||||
|
||||
$data->userid = $userid;
|
||||
if (!$mform) {
|
||||
$mform = new mod_assign_submission_form(null, array($this, $data));
|
||||
}
|
||||
@ -3249,7 +3299,7 @@ class assign {
|
||||
$o .= $this->get_renderer()->render(new assign_form('editsubmissionform', $mform));
|
||||
|
||||
$o .= $this->view_footer();
|
||||
$this->add_to_log('view submit assignment form', get_string('viewownsubmissionform', 'assign'));
|
||||
$this->add_to_log('view submit assignment form', $title);
|
||||
|
||||
return $o;
|
||||
}
|
||||
@ -4265,6 +4315,42 @@ class assign {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Capability check to make sure this grader can edit this submission.
|
||||
*
|
||||
* @param int $userid - The user whose submission is to be edited
|
||||
* @param int $graderid (optional) - The user who will do the editing (default to $USER->id).
|
||||
* @return bool
|
||||
*/
|
||||
public function can_edit_submission($userid, $graderid = 0) {
|
||||
global $USER;
|
||||
|
||||
if (empty($graderid)) {
|
||||
$graderid = $USER->id;
|
||||
}
|
||||
|
||||
if ($userid == $graderid &&
|
||||
$this->submissions_open($userid) &&
|
||||
has_capability('mod/assign:submit', $this->context, $graderid)) {
|
||||
// User can edit their own submission.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!has_capability('mod/assign:editothersubmission', $this->context, $graderid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cm = $this->get_course_module();
|
||||
if (groups_get_activity_groupmode($cm) == SEPARATEGROUPS) {
|
||||
// These arrays are indexed by groupid.
|
||||
$studentgroups = array_keys(groups_get_activity_allowed_groups($cm, $userid));
|
||||
$gradergroups = array_keys(groups_get_activity_allowed_groups($cm, $graderid));
|
||||
|
||||
return count(array_intersect($studentgroups, $gradergroups)) > 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of teachers that should be grading given submission.
|
||||
*
|
||||
@ -4536,11 +4622,19 @@ class assign {
|
||||
} else {
|
||||
$user = $USER;
|
||||
}
|
||||
$this->send_notification($user,
|
||||
$user,
|
||||
'submissionreceipt',
|
||||
'assign_notification',
|
||||
$submission->timemodified);
|
||||
if ($submission->userid == $USER->id) {
|
||||
$this->send_notification(core_user::get_noreply_user(),
|
||||
$user,
|
||||
'submissionreceipt',
|
||||
'assign_notification',
|
||||
$submission->timemodified);
|
||||
} else {
|
||||
$this->send_notification($USER,
|
||||
$user,
|
||||
'submissionreceiptother',
|
||||
'assign_notification',
|
||||
$submission->timemodified);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4580,27 +4674,40 @@ class assign {
|
||||
/**
|
||||
* Submit a submission for grading.
|
||||
*
|
||||
* @param stdClass $data - The form data
|
||||
* @param array $notices - List of error messages to display on an error condition.
|
||||
* @return bool Return false if the submission was not submitted.
|
||||
*/
|
||||
public function submit_for_grading($data) {
|
||||
public function submit_for_grading($data, $notices) {
|
||||
global $USER;
|
||||
|
||||
$userid = $USER->id;
|
||||
if (!empty($data->userid)) {
|
||||
$userid = $data->userid;
|
||||
}
|
||||
// Need submit permission to submit an assignment.
|
||||
require_capability('mod/assign:submit', $this->context);
|
||||
if ($userid == $USER->id) {
|
||||
require_capability('mod/assign:submit', $this->context);
|
||||
} else {
|
||||
if (!$this->can_edit_submission($userid, $USER->id)) {
|
||||
print_error('nopermission');
|
||||
}
|
||||
}
|
||||
|
||||
$instance = $this->get_instance();
|
||||
|
||||
if ($instance->teamsubmission) {
|
||||
$submission = $this->get_group_submission($USER->id, 0, true);
|
||||
$submission = $this->get_group_submission($userid, 0, true);
|
||||
} else {
|
||||
$submission = $this->get_user_submission($USER->id, true);
|
||||
$submission = $this->get_user_submission($userid, true);
|
||||
}
|
||||
|
||||
if (!$this->submissions_open($USER->id)) {
|
||||
if (!$this->submissions_open($userid)) {
|
||||
$notices[] = get_string('submissionsclosed', 'assign');
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($instance->requiresubmissionstatement && !$data->submissionstatement) {
|
||||
if ($instance->requiresubmissionstatement && empty($data->submissionstatement) && $USER->id == $userid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -4614,13 +4721,13 @@ class assign {
|
||||
}
|
||||
|
||||
$submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
|
||||
$this->update_submission($submission, $USER->id, true, $instance->teamsubmission);
|
||||
$this->update_submission($submission, $userid, true, $instance->teamsubmission);
|
||||
$completion = new completion_info($this->get_course());
|
||||
if ($completion->is_enabled($this->get_course_module()) && $instance->completionsubmit) {
|
||||
$completion->update_state($this->get_course_module(), COMPLETION_COMPLETE, $USER->id);
|
||||
$completion->update_state($this->get_course_module(), COMPLETION_COMPLETE, $userid);
|
||||
}
|
||||
|
||||
if (!empty($data->submissionstatement)) {
|
||||
if (!empty($data->submissionstatement) && $USER->id == $userid) {
|
||||
$logmessage = get_string('submissionstatementacceptedlog',
|
||||
'mod_assign',
|
||||
fullname($USER));
|
||||
@ -4643,9 +4750,31 @@ class assign {
|
||||
$event->trigger();
|
||||
return true;
|
||||
}
|
||||
$notices[] = get_string('submissionsclosed', 'assign');
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A students submission is submitted for grading by a teacher.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function process_submit_other_for_grading($mform, $notices) {
|
||||
global $USER, $CFG;
|
||||
|
||||
require_sesskey();
|
||||
|
||||
$userid = optional_param('userid', $USER->id, PARAM_INT);
|
||||
|
||||
if (!$this->submissions_open($userid)) {
|
||||
$notices[] = get_string('submissionsclosed', 'assign');
|
||||
return false;
|
||||
}
|
||||
$data = new stdClass();
|
||||
$data->userid = $userid;
|
||||
return $this->submit_for_grading($data, $notices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assignment submission is processed before grading.
|
||||
*
|
||||
@ -4653,14 +4782,15 @@ class assign {
|
||||
* It can be null.
|
||||
* @return bool Return false if the validation fails. This affects which page is displayed next.
|
||||
*/
|
||||
protected function process_submit_for_grading($mform) {
|
||||
global $USER, $CFG;
|
||||
protected function process_submit_for_grading($mform, $notices) {
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/mod/assign/submissionconfirmform.php');
|
||||
require_sesskey();
|
||||
|
||||
if (!$this->submissions_open()) {
|
||||
return $this->view_student_error_message();
|
||||
$notices[] = get_string('submissionsclosed', 'assign');
|
||||
return false;
|
||||
}
|
||||
$instance = $this->get_instance();
|
||||
$data = new stdClass();
|
||||
@ -4685,7 +4815,7 @@ class assign {
|
||||
if ($mform->get_data() == false) {
|
||||
return false;
|
||||
}
|
||||
return $this->submit_for_grading($data);
|
||||
return $this->submit_for_grading($data, $notices);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -5161,11 +5291,19 @@ class assign {
|
||||
* @return string
|
||||
*/
|
||||
protected function format_submission_for_log(stdClass $submission) {
|
||||
global $DB;
|
||||
|
||||
$info = '';
|
||||
$info .= get_string('submissionstatus', 'assign') .
|
||||
': ' .
|
||||
get_string('submissionstatus_' . $submission->status, 'assign') .
|
||||
'. <br>';
|
||||
if ($submission->userid) {
|
||||
$user = $DB->get_record('user', array('id' => $submission->userid), '*', MUST_EXIST);
|
||||
$name = fullname($user);
|
||||
} else {
|
||||
$group = $DB->get_record('groups', array('id' => $submission->groupid), '*', MUST_EXIST);
|
||||
$name = $group->name;
|
||||
}
|
||||
$status = get_string('submissionstatus_' . $submission->status, 'assign');
|
||||
$params = array('id'=>$submission->userid, 'fullname'=>$name, 'status'=>$status);
|
||||
$info .= get_string('submissionlog', 'assign', $params) . ' <br>';
|
||||
|
||||
foreach ($this->submissionplugins as $plugin) {
|
||||
if ($plugin->is_enabled() && $plugin->is_visible()) {
|
||||
@ -5319,15 +5457,28 @@ class assign {
|
||||
* @return bool
|
||||
*/
|
||||
public function save_submission(stdClass $data, & $notices) {
|
||||
global $CFG, $USER;
|
||||
global $CFG, $USER, $DB;
|
||||
|
||||
require_capability('mod/assign:submit', $this->context);
|
||||
$userid = $USER->id;
|
||||
if (!empty($data->userid)) {
|
||||
$userid = $data->userid;
|
||||
}
|
||||
|
||||
$user = clone($USER);
|
||||
if ($userid == $USER->id) {
|
||||
require_capability('mod/assign:submit', $this->context);
|
||||
} else {
|
||||
$user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
|
||||
if (!$this->can_edit_submission($userid, $USER->id)) {
|
||||
print_error('nopermission');
|
||||
}
|
||||
}
|
||||
$instance = $this->get_instance();
|
||||
|
||||
if ($instance->teamsubmission) {
|
||||
$submission = $this->get_group_submission($USER->id, 0, true);
|
||||
$submission = $this->get_group_submission($userid, 0, true);
|
||||
} else {
|
||||
$submission = $this->get_user_submission($USER->id, true);
|
||||
$submission = $this->get_user_submission($userid, true);
|
||||
}
|
||||
if ($instance->submissiondrafts) {
|
||||
$submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
|
||||
@ -5335,7 +5486,7 @@ class assign {
|
||||
$submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
|
||||
}
|
||||
|
||||
$flags = $this->get_user_flags($USER->id, false);
|
||||
$flags = $this->get_user_flags($userid, false);
|
||||
|
||||
// Get the flags to check if it is locked.
|
||||
if ($flags && $flags->locked) {
|
||||
@ -5360,10 +5511,10 @@ class assign {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->update_submission($submission, $USER->id, true, $instance->teamsubmission);
|
||||
$this->update_submission($submission, $userid, true, $instance->teamsubmission);
|
||||
|
||||
// Logging.
|
||||
if (isset($data->submissionstatement)) {
|
||||
if (isset($data->submissionstatement) && ($userid == $USER->id)) {
|
||||
$logmessage = get_string('submissionstatementacceptedlog',
|
||||
'mod_assign',
|
||||
fullname($USER));
|
||||
@ -5392,7 +5543,7 @@ class assign {
|
||||
}
|
||||
$completion = new completion_info($this->get_course());
|
||||
if ($completion->is_enabled($this->get_course_module()) && $instance->completionsubmit) {
|
||||
$completion->update_state($this->get_course_module(), $complete, $USER->id);
|
||||
$completion->update_state($this->get_course_module(), $complete, $userid);
|
||||
}
|
||||
|
||||
if (!$instance->submissiondrafts) {
|
||||
@ -5421,20 +5572,22 @@ class assign {
|
||||
* @return bool
|
||||
*/
|
||||
protected function process_save_submission(&$mform, &$notices) {
|
||||
global $CFG;
|
||||
global $CFG, $USER;
|
||||
|
||||
// Include submission form.
|
||||
require_once($CFG->dirroot . '/mod/assign/submission_form.php');
|
||||
|
||||
$userid = optional_param('userid', $USER->id, PARAM_INT);
|
||||
// Need submit permission to submit an assignment.
|
||||
require_sesskey();
|
||||
if (!$this->submissions_open()) {
|
||||
if (!$this->submissions_open($userid)) {
|
||||
$notices[] = get_string('duedatereached', 'assign');
|
||||
return false;
|
||||
}
|
||||
$instance = $this->get_instance();
|
||||
|
||||
$data = new stdClass();
|
||||
$data->userid = $userid;
|
||||
$mform = new mod_assign_submission_form(null, array($this, $data));
|
||||
if ($mform->is_cancelled()) {
|
||||
return true;
|
||||
@ -5839,11 +5992,12 @@ class assign {
|
||||
public function add_submission_form_elements(MoodleQuickForm $mform, stdClass $data) {
|
||||
global $USER;
|
||||
|
||||
$userid = $data->userid;
|
||||
// Team submissions.
|
||||
if ($this->get_instance()->teamsubmission) {
|
||||
$submission = $this->get_group_submission($USER->id, 0, false);
|
||||
$submission = $this->get_group_submission($userid, 0, false);
|
||||
} else {
|
||||
$submission = $this->get_user_submission($USER->id, false);
|
||||
$submission = $this->get_user_submission($userid, false);
|
||||
}
|
||||
|
||||
// Submission statement.
|
||||
@ -5854,7 +6008,8 @@ class assign {
|
||||
|
||||
$draftsenabled = $this->get_instance()->submissiondrafts;
|
||||
|
||||
if ($requiresubmissionstatement && !$draftsenabled) {
|
||||
// Only show submission statement if we are editing our own submission.
|
||||
if ($requiresubmissionstatement && !$draftsenabled && $userid == $USER->id) {
|
||||
|
||||
$submissionstatement = '';
|
||||
if (!empty($adminconfig->submissionstatement)) {
|
||||
@ -5864,12 +6019,15 @@ class assign {
|
||||
$mform->addRule('submissionstatement', get_string('required'), 'required', null, 'client');
|
||||
}
|
||||
|
||||
$this->add_plugin_submission_elements($submission, $mform, $data, $USER->id);
|
||||
$this->add_plugin_submission_elements($submission, $mform, $data, $userid);
|
||||
|
||||
// Hidden params.
|
||||
$mform->addElement('hidden', 'id', $this->get_course_module()->id);
|
||||
$mform->setType('id', PARAM_INT);
|
||||
|
||||
$mform->addElement('hidden', 'userid', $userid);
|
||||
$mform->setType('userid', PARAM_INT);
|
||||
|
||||
$mform->addElement('hidden', 'action', 'savesubmission');
|
||||
$mform->setType('action', PARAM_TEXT);
|
||||
}
|
||||
|
@ -1278,6 +1278,90 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
|
||||
$this->editingteachers[0]->ignoresesskey = false;
|
||||
}
|
||||
|
||||
public function test_teacher_submit_for_student() {
|
||||
global $PAGE;
|
||||
|
||||
$this->preventResetByRollback();
|
||||
$sink = $this->redirectMessages();
|
||||
|
||||
$this->setUser($this->editingteachers[0]);
|
||||
|
||||
$assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1, 'submissiondrafts'=>1));
|
||||
$PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
|
||||
|
||||
$this->setUser($this->students[0]);
|
||||
// Simulate a submission.
|
||||
$data = new stdClass();
|
||||
$data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
|
||||
'text'=>'Student submission text',
|
||||
'format'=>FORMAT_MOODLE);
|
||||
|
||||
$notices = array();
|
||||
$assign->save_submission($data, $notices);
|
||||
|
||||
// Check that the submission text was saved.
|
||||
$output = $assign->view_student_summary($this->students[0], true);
|
||||
$this->assertContains('Student submission text', $output, 'Contains student submission text');
|
||||
|
||||
// Check that a teacher teacher with the extra capability can edit a students submission.
|
||||
$this->setUser($this->teachers[0]);
|
||||
$data = new stdClass();
|
||||
$data->userid = $this->students[0]->id;
|
||||
$data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
|
||||
'text'=>'Teacher edited submission text',
|
||||
'format'=>FORMAT_MOODLE);
|
||||
|
||||
// Add the required capability.
|
||||
$roleid = create_role('Dummy role', 'dummyrole', 'dummy role description');
|
||||
assign_capability('mod/assign:editothersubmission', CAP_ALLOW, $roleid, $assign->get_context()->id);
|
||||
role_assign($roleid, $this->teachers[0]->id, $assign->get_context()->id);
|
||||
accesslib_clear_all_caches_for_unit_testing();
|
||||
|
||||
// Try to save the submission.
|
||||
$notices = array();
|
||||
$assign->save_submission($data, $notices);
|
||||
|
||||
// Check that the teacher can submit the students work.
|
||||
$data = new stdClass();
|
||||
$data->userid = $this->students[0]->id;
|
||||
$notices = array();
|
||||
$assign->submit_for_grading($data, $notices);
|
||||
|
||||
// Revert to draft so the student can edit it.
|
||||
$assign->revert_to_draft($this->students[0]->id);
|
||||
|
||||
$this->setUser($this->students[0]);
|
||||
|
||||
// Check that the submission text was saved.
|
||||
$output = $assign->view_student_summary($this->students[0], true);
|
||||
$this->assertContains('Teacher edited submission text', $output, 'Contains student submission text');
|
||||
|
||||
// Check that the student can submit their work.
|
||||
$data = new stdClass();
|
||||
$assign->submit_for_grading($data, $notices);
|
||||
|
||||
$output = $assign->view_student_summary($this->students[0], true);
|
||||
$this->assertNotContains(get_string('addsubmission', 'assign'), $output);
|
||||
|
||||
// Set to a default editing teacher who should not be able to edit this submission.
|
||||
$this->setUser($this->editingteachers[1]);
|
||||
|
||||
// Revert to draft so the submission is editable.
|
||||
$assign->revert_to_draft($this->students[0]->id);
|
||||
|
||||
$data = new stdClass();
|
||||
$data->userid = $this->students[0]->id;
|
||||
$data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
|
||||
'text'=>'Teacher 2 edited submission text',
|
||||
'format'=>FORMAT_MOODLE);
|
||||
|
||||
$notices = array();
|
||||
$this->setExpectedException('moodle_exception');
|
||||
$assign->save_submission($data, $notices);
|
||||
|
||||
$sink->close();
|
||||
}
|
||||
|
||||
public function test_marker_updated_event() {
|
||||
$this->editingteachers[0]->ignoresesskey = true;
|
||||
$this->setUser($this->editingteachers[0]);
|
||||
@ -1669,5 +1753,55 @@ Anchor link 2:<a title=\"bananas\" href=\"../logo-240x60.gif\">Link text</a>
|
||||
$plugin = $assign->get_feedback_plugin_by_type($gradebookplugintype);
|
||||
$this->assertEquals(0, $plugin->is_enabled('enabled'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing can_edit_submission
|
||||
*/
|
||||
public function test_can_edit_submission() {
|
||||
global $PAGE, $DB;
|
||||
$this->create_extra_users();
|
||||
|
||||
$this->setAdminUser();
|
||||
// Create assignment (onlinetext).
|
||||
$assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1, 'submissiondrafts'=>1));
|
||||
$PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
|
||||
|
||||
// Check student can edit their own submission.
|
||||
$this->assertTrue($assign->can_edit_submission($this->students[0]->id, $this->students[0]->id));
|
||||
// Check student cannot edit others submission.
|
||||
$this->assertFalse($assign->can_edit_submission($this->students[0]->id, $this->students[1]->id));
|
||||
|
||||
// Check teacher cannot (by default) edit a students submission.
|
||||
$this->assertFalse($assign->can_edit_submission($this->students[0]->id, $this->teachers[0]->id));
|
||||
|
||||
// Add the required capability to edit a student submission.
|
||||
$roleid = create_role('Dummy role', 'dummyrole', 'dummy role description');
|
||||
assign_capability('mod/assign:editothersubmission', CAP_ALLOW, $roleid, $assign->get_context()->id);
|
||||
role_assign($roleid, $this->teachers[0]->id, $assign->get_context()->id);
|
||||
accesslib_clear_all_caches_for_unit_testing();
|
||||
// Retest - should now have access.
|
||||
$this->assertTrue($assign->can_edit_submission($this->students[0]->id, $this->teachers[0]->id));
|
||||
|
||||
// Force create an assignment with SEPARATEGROUPS.
|
||||
$data = new stdClass();
|
||||
$data->courseid = $this->course->id;
|
||||
$data->name = 'Grouping';
|
||||
$groupingid = groups_create_grouping($data);
|
||||
groups_assign_grouping($groupingid, $this->groups[0]->id);
|
||||
groups_assign_grouping($groupingid, $this->groups[1]->id);
|
||||
$assign = $this->create_instance(array('groupingid' => $groupingid, 'groupmode' => SEPARATEGROUPS));
|
||||
|
||||
// Add the capability to the new assignment for extra students 0 and 1.
|
||||
assign_capability('mod/assign:editothersubmission', CAP_ALLOW, $roleid, $assign->get_context()->id);
|
||||
role_assign($roleid, $this->extrastudents[0]->id, $assign->get_context()->id);
|
||||
role_assign($roleid, $this->extrastudents[1]->id, $assign->get_context()->id);
|
||||
accesslib_clear_all_caches_for_unit_testing();
|
||||
|
||||
// Verify the extra student does not have the capability to edit a submission not in their group.
|
||||
$this->assertFalse($assign->can_edit_submission($this->students[0]->id, $this->extrastudents[1]->id));
|
||||
// Verify the extra student does have the capability to edit a submission in their group.
|
||||
$this->assertTrue($assign->can_edit_submission($this->students[0]->id, $this->extrastudents[0]->id));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$module->component = 'mod_assign'; // Full name of the plugin (used for diagnostics).
|
||||
$module->version = 2014010801; // The current module version (Date: YYYYMMDDXX).
|
||||
$module->version = 2014011500; // The current module version (Date: YYYYMMDDXX).
|
||||
$module->requires = 2013110500; // Requires this Moodle version.
|
||||
$module->cron = 60;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user