MDL-28448 Assign: Add a new capability that lets teachers mess with student submissions.

This commit is contained in:
Damyon Wiese 2013-12-11 16:59:23 +08:00
parent b19608d682
commit 57fbd5f91f
7 changed files with 397 additions and 53 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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}';

View File

@ -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);
}

View File

@ -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));
}
}

View File

@ -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;