// Special value means allow unlimited attempts.
define('ASSIGN_UNLIMITED_ATTEMPTS', -1);
+// Marking workflow states.
+define('ASSIGN_MARKING_WORKFLOW_STATE_NOTMARKED', 'notmarked');
+define('ASSIGN_MARKING_WORKFLOW_STATE_INMARKING', 'inmarking');
+define('ASSIGN_MARKING_WORKFLOW_STATE_READYFORREVIEW', 'readyforreview');
+define('ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW', 'inreview');
+define('ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE', 'readyforrelease');
+define('ASSIGN_MARKING_WORKFLOW_STATE_RELEASED', 'released');
+
require_once($CFG->libdir . '/accesslib.php');
require_once($CFG->libdir . '/formslib.php');
require_once($CFG->dirroot . '/repository/lib.php');
/** @var string modulenameplural prevents excessive calls to get_string */
private static $modulenameplural = null;
+ /** @var array of marking workflow states for the current user */
+ private $markingworkflowstates = null;
+
+ /** @var bool whether to exclude users with inactive enrolment */
+ private $showonlyactiveenrol = null;
+
+ /** @var array list of suspended user IDs in form of ([id1] => id1) */
+ public $susers = null;
+
/**
* Constructor for the base assign class.
*
* otherwise this class will load one from the context as required.
*/
public function __construct($coursemodulecontext, $coursemodule, $course) {
- global $PAGE;
-
$this->context = $coursemodulecontext;
$this->coursemodule = $coursemodule;
$this->course = $course;
global $CFG;
$result = array();
- $names = get_plugin_list($subtype);
+ $names = core_component::get_plugin_list($subtype);
foreach ($names as $name => $path) {
if (file_exists($path . '/locallib.php')) {
$this->process_unlock();
$action = 'redirect';
$nextpageparams['action'] = 'grading';
+ } else if ($action == 'setbatchmarkingworkflowstate') {
+ $this->process_set_batch_marking_workflow_state();
+ $action = 'redirect';
+ $nextpageparams['action'] = 'grading';
+ } else if ($action == 'setbatchmarkingallocation') {
+ $this->process_set_batch_marking_allocation();
+ $action = 'redirect';
+ $nextpageparams['action'] = 'grading';
} else if ($action == 'confirmsubmit') {
$action = 'submit';
if ($this->process_submit_for_grading($mform)) {
$o .= $this->view_plugin_page();
} else if ($action == 'viewcourseindex') {
$o .= $this->view_course_index();
+ } else if ($action == 'viewbatchsetmarkingworkflowstate') {
+ $o .= $this->view_batch_set_workflow_state($mform);
+ } else if ($action == 'viewbatchmarkingallocation') {
+ $o .= $this->view_batch_markingallocation($mform);
} else {
$o .= $this->view_submission_page();
}
$update->completionsubmit = !empty($formdata->completionsubmit);
$update->teamsubmission = $formdata->teamsubmission;
$update->requireallteammemberssubmit = $formdata->requireallteammemberssubmit;
- $update->teamsubmissiongroupingid = $formdata->teamsubmissiongroupingid;
+ if (isset($formdata->teamsubmissiongroupingid)) {
+ $update->teamsubmissiongroupingid = $formdata->teamsubmissiongroupingid;
+ }
$update->blindmarking = $formdata->blindmarking;
$update->attemptreopenmethod = ASSIGN_ATTEMPT_REOPEN_METHOD_NONE;
if (!empty($formdata->attemptreopenmethod)) {
if (!empty($formdata->maxattempts)) {
$update->maxattempts = $formdata->maxattempts;
}
+ $update->markingworkflow = $formdata->markingworkflow;
+ $update->markingallocation = $formdata->markingallocation;
$returnid = $DB->insert_record('assign', $update);
$this->instance = $DB->get_record('assign', array('id'=>$returnid), '*', MUST_EXIST);
}
$update->teamsubmission = $formdata->teamsubmission;
$update->requireallteammemberssubmit = $formdata->requireallteammemberssubmit;
- $update->teamsubmissiongroupingid = $formdata->teamsubmissiongroupingid;
+ if (isset($formdata->teamsubmissiongroupingid)) {
+ $update->teamsubmissiongroupingid = $formdata->teamsubmissiongroupingid;
+ }
$update->blindmarking = $formdata->blindmarking;
$update->attemptreopenmethod = ASSIGN_ATTEMPT_REOPEN_METHOD_NONE;
if (!empty($formdata->attemptreopenmethod)) {
if (!empty($formdata->maxattempts)) {
$update->maxattempts = $formdata->maxattempts;
}
+ $update->markingworkflow = $formdata->markingworkflow;
+ $update->markingallocation = $formdata->markingallocation;
$result = $DB->update_record('assign', $update);
$this->instance = $DB->get_record('assign', array('id'=>$update->id), '*', MUST_EXIST);
if ($grade < 0) {
$displaygrade = '';
} else {
- $displaygrade = format_float($grade);
+ $displaygrade = format_float($grade, 2);
}
$o .= '<label class="accesshide" for="quickgrade_' . $userid . '">' .
get_string('usergrade', 'assign') .
*/
public function list_participants($currentgroup, $idsonly) {
if ($idsonly) {
- return get_enrolled_users($this->context, 'mod/assign:submit', $currentgroup, 'u.id');
+ return get_enrolled_users($this->context, 'mod/assign:submit', $currentgroup, 'u.id', null, null, null,
+ $this->show_only_active_users());
} else {
- return get_enrolled_users($this->context, 'mod/assign:submit', $currentgroup);
+ return get_enrolled_users($this->context, 'mod/assign:submit', $currentgroup, 'u.*', null, null, null,
+ $this->show_only_active_users());
}
}
}
/**
- * Load a count of users enrolled in the current course with the specified permission and group.
+ * Load a count of active users enrolled in the current course with the specified permission and group.
* 0 for no group.
*
* @param int $currentgroup
* @return int number of matching users
*/
public function count_participants($currentgroup) {
- return count_enrolled_users($this->context, 'mod/assign:submit', $currentgroup);
+ return count_enrolled_users($this->context, 'mod/assign:submit', $currentgroup, true);
}
/**
- * Load a count of users submissions in the current module that require grading
+ * Load a count of active users submissions in the current module that require grading
* This means the submission modification time is more recent than the
* grading modification time and the status is SUBMITTED.
*
}
$currentgroup = groups_get_activity_group($this->get_course_module(), true);
- list($esql, $params) = get_enrolled_sql($this->get_context(), 'mod/assign:submit', $currentgroup, false);
+ list($esql, $params) = get_enrolled_sql($this->get_context(), 'mod/assign:submit', $currentgroup, true);
$submissionmaxattempt = 'SELECT mxs.userid, MAX(mxs.attemptnumber) AS maxattempt
FROM {assign_submission} mxs
}
$currentgroup = groups_get_activity_group($this->get_course_module(), true);
- list($esql, $params) = get_enrolled_sql($this->get_context(), 'mod/assign:submit', $currentgroup, false);
+ list($esql, $params) = get_enrolled_sql($this->get_context(), 'mod/assign:submit', $currentgroup, true);
$params['assignid'] = $this->get_instance()->id;
$params['groupuserid'] = 0;
} else {
$currentgroup = groups_get_activity_group($this->get_course_module(), true);
- list($esql, $params) = get_enrolled_sql($this->get_context(), 'mod/assign:submit', $currentgroup, false);
+ list($esql, $params) = get_enrolled_sql($this->get_context(), 'mod/assign:submit', $currentgroup, true);
$params['assignid'] = $this->get_instance()->id;
WHERE
s.assignment = :assignid AND
s.timemodified IS NOT NULL';
+
}
return $DB->count_records_sql($sql, $params);
global $DB;
$currentgroup = groups_get_activity_group($this->get_course_module(), true);
- list($esql, $params) = get_enrolled_sql($this->get_context(), 'mod/assign:submit', $currentgroup, false);
+ list($esql, $params) = get_enrolled_sql($this->get_context(), 'mod/assign:submit', $currentgroup, true);
$params['assignid'] = $this->get_instance()->id;
$params['assignid2'] = $this->get_instance()->id;
s.assignment = :assignid AND
s.timemodified IS NOT NULL AND
s.status = :submissionstatus';
+
}
return $DB->count_records_sql($sql, $params);
$grade->timemodified = time();
+ if (!empty($grade->workflowstate)) {
+ $validstates = $this->get_marking_workflow_states_for_current_user();
+ if (!array_key_exists($grade->workflowstate, $validstates)) {
+ return false;
+ }
+ }
+
if ($grade->grade && $grade->grade != -1) {
if ($this->get_instance()->grade > 0) {
if (!is_numeric($grade->grade)) {
}
}
}
+ // Exclude suspended users, if user can't see them.
+ if (!has_capability('moodle/course:viewsuspendedusers', $this->context)) {
+ foreach ($members as $key => $member) {
+ if (!$this->is_active_user($member->id)) {
+ unset($members[$key]);
+ }
+ }
+ }
return $members;
}
require_capability('mod/assign:grade', $this->context);
// Load all users with submit.
- $students = get_enrolled_users($this->context, "mod/assign:submit");
+ $students = get_enrolled_users($this->context, "mod/assign:submit", null, 'u.*', null, null, null,
+ $this->show_only_active_users());
// Build a list of files to zip.
$filesforzipping = array();
$result .= $this->get_renderer()->continue_button($url);
$result .= $this->view_footer();
} else if ($zipfile = $this->pack_files($filesforzipping)) {
- $this->add_to_log('download all submissions', get_string('downloadall', 'assign'));
+ $addtolog = $this->add_to_log('download all submissions', get_string('downloadall', 'assign'), '', true);
+ $params = array(
+ 'context' => $this->context,
+ 'objectid' => $this->get_instance()->id
+ );
+ $event = \mod_assign\event\all_submissions_downloaded::create($params);
+ $event->set_legacy_logdata($addtolog);
+ $event->trigger();
// Send file and delete after sending.
send_temp_file($zipfile, $filename);
// We will not get here - send_temp_file calls exit.
* @param string $action The current action
* @param string $info A detailed description of the change. But no more than 255 characters.
* @param string $url The url to the assign module instance.
- * @return void
+ * @param bool $return If true, returns the arguments, else adds to log. The purpose of this is to
+ * retrieve the arguments to use them with the new event system (Event 2).
+ * @return void|array
*/
- public function add_to_log($action = '', $info = '', $url='') {
+ public function add_to_log($action = '', $info = '', $url='', $return = false) {
global $USER;
$fullurl = 'view.php?id=' . $this->get_course_module()->id;
$fullurl .= '&' . $url;
}
- add_to_log($this->get_course()->id,
- 'assign',
- $action,
- $fullurl,
- $info,
- $this->get_course_module()->id,
- $USER->id);
+ $args = array(
+ $this->get_course()->id,
+ 'assign',
+ $action,
+ $fullurl,
+ $info,
+ $this->get_course_module()->id,
+ $USER->id
+ );
+
+ if ($return) {
+ return $args;
+ }
+ call_user_func_array('add_to_log', $args);
}
/**
$flags->userid = $userid;
$flags->locked = 0;
$flags->extensionduedate = 0;
+ $flags->workflowstate = '';
+ $flags->allocatedmarker = 0;
// The mailed flag can be one of 3 values: 0 is unsent, 1 is sent and 2 is do not send yet.
// This is because students only want to be notified about certain types of update (grades and feedback).
$viewfullnames,
$this->is_blind_marking(),
$this->get_uniqueid_for_user($user->id),
- get_extra_user_fields($this->get_context()));
+ get_extra_user_fields($this->get_context()),
+ !$this->is_active_user($userid));
$o .= $this->get_renderer()->render($usersummary);
}
$submission = $this->get_user_submission($userid, false, $attemptnumber);
$submissiongroup = null;
- $submissiongroupmemberswhohavenotsubmitted = array();
$teamsubmission = null;
$notsubmitted = array();
if ($instance->teamsubmission) {
if ($grade->grade !== null && $grade->grade >= 0) {
$data->grade = format_float($grade->grade, 2);
}
+ if (!empty($flags->workflowstate)) {
+ $data->workflowstate = $flags->workflowstate;
+ }
+ if (!empty($flags->allocatedmarker)) {
+ $data->allocatedmarker = $flags->allocatedmarker;
+ }
} else {
$data = new stdClass();
$data->grade = '';
$perpage = get_user_preferences('assign_perpage', 10);
$filter = get_user_preferences('assign_filter', '');
+ $markerfilter = get_user_preferences('assign_markerfilter', '');
+ $workflowfilter = get_user_preferences('assign_workflowfilter', '');
$controller = $gradingmanager->get_active_controller();
$showquickgrading = empty($controller);
$quickgrading = get_user_preferences('assign_quickgrading', false);
+ $showonlyactiveenrolopt = has_capability('moodle/course:viewsuspendedusers', $this->context);
+
+ $markingallocation = $this->get_instance()->markingallocation &&
+ has_capability('mod/assign:manageallocations', $this->context);
+ // Get markers to use in drop lists.
+ $markingallocationoptions = array();
+ if ($markingallocation) {
+ $markers = get_users_by_capability($this->context, 'mod/assign:grade');
+ $markingallocationoptions[''] = get_string('filternone', 'assign');
+ foreach ($markers as $marker) {
+ $markingallocationoptions[$marker->id] = fullname($marker);
+ }
+ }
+
+ $markingworkflow = $this->get_instance()->markingworkflow;
+ // Get marking states to show in form.
+ $markingworkflowoptions = array();
+ if ($markingworkflow) {
+ $notmarked = get_string('markingworkflowstatenotmarked', 'assign');
+ $markingworkflowoptions[''] = get_string('filternone', 'assign');
+ $markingworkflowoptions[ASSIGN_MARKING_WORKFLOW_STATE_NOTMARKED] = $notmarked;
+ $markingworkflowoptions = array_merge($markingworkflowoptions, $this->get_marking_workflow_states_for_current_user());
+ }
// Print options for changing the filter and changing the number of results per page.
$gradingoptionsformparams = array('cm'=>$cmid,
'userid'=>$USER->id,
'submissionsenabled'=>$this->is_any_submission_plugin_enabled(),
'showquickgrading'=>$showquickgrading,
- 'quickgrading'=>$quickgrading);
+ 'quickgrading'=>$quickgrading,
+ 'markingworkflowopt'=>$markingworkflowoptions,
+ 'markingallocationopt'=>$markingallocationoptions,
+ 'showonlyactiveenrolopt'=>$showonlyactiveenrolopt,
+ 'showonlyactiveenrol'=>$this->show_only_active_users());
$classoptions = array('class'=>'gradingoptionsform');
$gradingoptionsform = new mod_assign_grading_options_form(null,
'submissiondrafts'=>$this->get_instance()->submissiondrafts,
'duedate'=>$this->get_instance()->duedate,
'attemptreopenmethod'=>$this->get_instance()->attemptreopenmethod,
- 'feedbackplugins'=>$this->get_feedback_plugins());
+ 'feedbackplugins'=>$this->get_feedback_plugins(),
+ 'context'=>$this->get_context(),
+ 'markingworkflow'=>$markingworkflow,
+ 'markingallocation'=>$markingallocation);
$classoptions = array('class'=>'gradingbatchoperationsform');
$gradingbatchoperationsform = new mod_assign_grading_batch_operations_form(null,
$gradingoptionsdata = new stdClass();
$gradingoptionsdata->perpage = $perpage;
$gradingoptionsdata->filter = $filter;
+ $gradingoptionsdata->markerfilter = $markerfilter;
+ $gradingoptionsdata->workflowfilter = $workflowfilter;
$gradingoptionsform->set_data($gradingoptionsdata);
$actionformtext = $this->get_renderer()->render($gradingactions);
if ($userid == $USER->id && has_capability('mod/assign:submit', $this->context)) {
return true;
}
+ if (!$this->is_active_user($userid) && !has_capability('moodle/course:viewsuspendedusers', $this->context)) {
+ return false;
+ }
if (has_capability('mod/assign:grade', $this->context)) {
return true;
}
require_once($CFG->dirroot . '/mod/assign/gradingbatchoperationsform.php');
require_sesskey();
+ $markingallocation = $this->get_instance()->markingallocation &&
+ has_capability('mod/assign:manageallocations', $this->context);
+
$batchformparams = array('cm'=>$this->get_course_module()->id,
'submissiondrafts'=>$this->get_instance()->submissiondrafts,
'duedate'=>$this->get_instance()->duedate,
'attemptreopenmethod'=>$this->get_instance()->attemptreopenmethod,
- 'feedbackplugins'=>$this->get_feedback_plugins());
+ 'feedbackplugins'=>$this->get_feedback_plugins(),
+ 'context'=>$this->get_context(),
+ 'markingworkflow'=>$this->get_instance()->markingworkflow,
+ 'markingallocation'=>$markingallocation);
$formclasses = array('class'=>'gradingbatchoperationsform');
$mform = new mod_assign_grading_batch_operations_form(null,
$batchformparams,
// Reset the form so the grant extension page will create the extension form.
$mform = null;
return 'grantextension';
+ } else if ($data->operation == 'setmarkingworkflowstate') {
+ return 'viewbatchsetmarkingworkflowstate';
+ } else if ($data->operation == 'setmarkingallocation') {
+ return 'viewbatchmarkingallocation';
} else if (strpos($data->operation, $prefix) === 0) {
$tail = substr($data->operation, strlen($prefix));
list($plugintype, $action) = explode('_', $tail, 2);
return 'grading';
}
+ /**
+ * Shows a form that allows the workflow state for selected submissions to be changed.
+ *
+ * @param moodleform $mform Set to a grading batch operations form
+ * @return string - the page to view after processing these actions
+ */
+ private function view_batch_set_workflow_state($mform) {
+ global $CFG, $DB;
+
+ require_once($CFG->dirroot . '/mod/assign/batchsetmarkingworkflowstateform.php');
+
+ $o = '';
+
+ $submitteddata = $mform->get_data();
+ $users = $submitteddata->selectedusers;
+ $userlist = explode(',', $users);
+
+ $formparams = array('cm'=>$this->get_course_module()->id,
+ 'users'=>$userlist,
+ 'context'=>$this->get_context());
+
+ $usershtml = '';
+
+ $usercount = 0;
+ $extrauserfields = get_extra_user_fields($this->get_context());
+ foreach ($userlist as $userid) {
+ if ($usercount >= 5) {
+ $usershtml .= get_string('moreusers', 'assign', count($userlist) - 5);
+ break;
+ }
+ $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
+
+ $usershtml .= $this->get_renderer()->render(new assign_user_summary($user,
+ $this->get_course()->id,
+ has_capability('moodle/site:viewfullnames',
+ $this->get_course_context()),
+ $this->is_blind_marking(),
+ $this->get_uniqueid_for_user($user->id),
+ $extrauserfields,
+ !$this->is_active_user($userid)));
+ $usercount += 1;
+ }
+
+ $formparams['usershtml'] = $usershtml;
+ $formparams['markingworkflowstates'] = $this->get_marking_workflow_states_for_current_user();
+
+ $mform = new mod_assign_batch_set_marking_workflow_state_form(null, $formparams);
+ $o .= $this->get_renderer()->header();
+ $o .= $this->get_renderer()->render(new assign_form('setworkflowstate', $mform));
+ $o .= $this->view_footer();
+
+ $this->add_to_log('view batch set marking workflow state', get_string('viewbatchsetmarkingworkflowstate', 'assign'));
+ return $o;
+ }
+
+ /**
+ * Shows a form that allows the allocated marker for selected submissions to be changed.
+ *
+ * @param moodleform $mform Set to a grading batch operations form
+ * @return string - the page to view after processing these actions
+ */
+ private function view_batch_markingallocation($mform) {
+ global $CFG, $DB;
+
+ require_once($CFG->dirroot . '/mod/assign/batchsetallocatedmarkerform.php');
+
+ $o = '';
+
+ $submitteddata = $mform->get_data();
+ $users = $submitteddata->selectedusers;
+ $userlist = explode(',', $users);
+
+ $formparams = array('cm'=>$this->get_course_module()->id,
+ 'users'=>$userlist,
+ 'context'=>$this->get_context());
+
+ $usershtml = '';
+
+ $usercount = 0;
+ $extrauserfields = get_extra_user_fields($this->get_context());
+ foreach ($userlist as $userid) {
+ if ($usercount >= 5) {
+ $usershtml .= get_string('moreusers', 'assign', count($userlist) - 5);
+ break;
+ }
+ $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
+
+ $usershtml .= $this->get_renderer()->render(new assign_user_summary($user,
+ $this->get_course()->id,
+ has_capability('moodle/site:viewfullnames',
+ $this->get_course_context()),
+ $this->is_blind_marking(),
+ $this->get_uniqueid_for_user($user->id),
+ $extrauserfields,
+ !$this->is_active_user($userid)));
+ $usercount += 1;
+ }
+
+ $formparams['usershtml'] = $usershtml;
+ $markers = get_users_by_capability($this->get_context(), 'mod/assign:grade');
+ $markerlist = array();
+ foreach ($markers as $marker) {
+ $markerlist[$marker->id] = fullname($marker);
+ }
+
+ $formparams['markers'] = $markerlist;
+
+ $mform = new mod_assign_batch_set_allocatedmarker_form(null, $formparams);
+ $o .= $this->get_renderer()->header();
+ $o .= $this->get_renderer()->render(new assign_form('setworkflowstate', $mform));
+ $o .= $this->view_footer();
+
+ $this->add_to_log('view batch set marker allocation', get_string('viewbatchmarkingallocation', 'assign'));
+ return $o;
+ }
+
/**
* Ask the user to confirm they want to submit their work for grading.
*
$data = new stdClass();
$adminconfig = $this->get_admin_config();
- $requiresubmissionstatement = (!empty($adminconfig->requiresubmissionstatement) ||
- $this->get_instance()->requiresubmissionstatement) &&
+ $requiresubmissionstatement = $this->get_instance()->requiresubmissionstatement &&
!empty($adminconfig->submissionstatement);
$submissionstatement = '';
($this->is_any_submission_plugin_enabled()) &&
$showlinks;
- $gradelocked = ($flags && $flags->locked) || $this->grading_disabled($user->id);
+ $gradelocked = ($flags && $flags->locked) || $this->grading_disabled($user->id, false);
// Grading criteria preview.
$gradingmanager = get_grading_manager($this->context, 'mod_assign', 'submissions');
}
}
+ $gradereleased = true;
+ if ($this->get_instance()->markingworkflow &&
+ (empty($grade) || $flags->workflowstate != ASSIGN_MARKING_WORKFLOW_STATE_RELEASED)) {
+ $gradereleased = false;
+ $emptyplugins = true; // Don't show feedback plugins until released either.
+ }
+
$cangrade = has_capability('mod/assign:grade', $this->get_context());
- // If there is feedback or a visible grade, show the summary.
- if ((!empty($gradebookgrade->grade) && ($cangrade || !$gradebookgrade->hidden)) ||
- !$emptyplugins) {
+ // If there is a visible grade, show the summary.
+ if ((!empty($gradebookgrade->grade) || !$emptyplugins)
+ && ($cangrade || !$gradebookgrade->hidden)) {
$gradefordisplay = null;
$gradeddate = null;
// Only show the grade if it is not hidden in gradebook.
if (!empty($gradebookgrade->grade) && ($cangrade || !$gradebookgrade->hidden)) {
if ($controller = $gradingmanager->get_active_controller()) {
- $controller->set_grade_range(make_grades_menu($this->get_instance()->grade));
+ $controller->set_grade_range(make_grades_menu($this->get_instance()->grade), $this->get_instance()->grade > 0);
$gradefordisplay = $controller->render_grade($PAGE,
$grade->id,
$gradingitem,
// Now get the gradefordisplay.
if ($controller) {
- $controller->set_grade_range(make_grades_menu($this->get_instance()->grade));
+ $controller->set_grade_range(make_grades_menu($this->get_instance()->grade), $this->get_instance()->grade > 0);
$grade->gradefordisplay = $controller->render_grade($PAGE,
$grade->id,
$gradingitem,
if ($this->is_blind_marking()) {
return false;
}
+ // If marking workflow is enabled and grade is not released then don't send to gradebook yet.
+ if ($this->get_instance()->markingworkflow && !empty($grade)) {
+ $flags = $this->get_user_flags($grade->userid, false);
+ if (empty($flags->workflowstate) || $flags->workflowstate != ASSIGN_MARKING_WORKFLOW_STATE_RELEASED) {
+ return false;
+ }
+ }
+
if ($submission != null) {
if ($submission->userid == 0) {
// This is a group submission update.
$team = groups_get_members($submission->groupid, 'u.id');
foreach ($team as $member) {
- $submission->groupid = 0;
- $submission->userid = $member->id;
- $this->gradebook_item_update($submission, null);
+ $membersubmission = clone $submission;
+ $membersubmission->groupid = 0;
+ $membersubmission->userid = $member->id;
+ $this->gradebook_item_update($membersubmission, null);
}
return;
}
return false;
}
$assign = clone $this->get_instance();
- $assign->cmidnumber = $this->get_course_module()->id;
+ $assign->cmidnumber = $this->get_course_module()->idnumber;
return assign_grade_item_update($assign, $gradebookgrade);
}
foreach ($team as $member) {
$membersubmission = $this->get_user_submission($member->id, false, $submission->attemptnumber);
- if (!$membersubmission || $membersubmission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) {
+ // If no submission found for team member and member is active then everyone has not submitted.
+ if (!$membersubmission || $membersubmission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED
+ && ($this->is_active_user($member->id))) {
$allsubmitted = false;
if ($anysubmitted) {
break;
}
}
- if ($this->grading_disabled($userid)) {
+ // See if this user grade is locked in the gradebook.
+ $gradinginfo = grade_get_grades($this->get_course()->id,
+ 'mod',
+ 'assign',
+ $this->get_instance()->id,
+ array($userid));
+ if ($gradinginfo &&
+ isset($gradinginfo->items[0]->grades[$userid]) &&
+ $gradinginfo->items[0]->grades[$userid]->locked) {
return false;
}
* @return array
*/
protected function get_graders($userid) {
- $potentialgraders = get_enrolled_users($this->context, 'mod/assign:grade');
+ // Potential graders should be active users only.
+ $potentialgraders = get_enrolled_users($this->context, "mod/assign:grade", null, 'u.*', null, null, null, true);
$graders = array();
if (groups_get_activity_groupmode($this->get_course_module()) == SEPARATEGROUPS) {
$instance = $this->get_instance();
$data = new stdClass();
$adminconfig = $this->get_admin_config();
- $requiresubmissionstatement = (!empty($adminconfig->requiresubmissionstatement) ||
- $instance->requiresubmissionstatement) &&
+ $requiresubmissionstatement = $instance->requiresubmissionstatement &&
!empty($adminconfig->submissionstatement);
$submissionstatement = '';
// Give each submission plugin a chance to process the submission.
$plugins = $this->get_submission_plugins();
foreach ($plugins as $plugin) {
- $plugin->submit_for_grading($submission);
+ if ($plugin->is_enabled() && $plugin->is_visible()) {
+ $plugin->submit_for_grading($submission);
+ }
}
$submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
$logmessage = get_string('submissionstatementacceptedlog',
'mod_assign',
fullname($USER));
- $this->add_to_log('submission statement accepted', $logmessage);
+ $addtolog = $this->add_to_log('submission statement accepted', $logmessage, '', true);
+ $params = array(
+ 'context' => $this->context,
+ 'objectid' => $submission->id
+ );
+ $event = \mod_assign\event\statement_accepted::create($params);
+ $event->set_legacy_logdata($addtolog);
+ $event->trigger();
}
- $this->add_to_log('submit for grading', $this->format_submission_for_log($submission));
+ $logdata = $this->add_to_log('submit for grading', $this->format_submission_for_log($submission), '', true);
$this->notify_graders($submission);
$this->notify_student_submission_receipt($submission);
// Trigger assessable_submitted event on submission.
- $eventdata = new stdClass();
- $eventdata->modulename = 'assign';
- $eventdata->cmid = $this->get_course_module()->id;
- $eventdata->itemid = $submission->id;
- $eventdata->courseid = $this->get_course()->id;
- $eventdata->userid = $USER->id;
- $eventdata->params = array( 'submission_editable' => false);
- events_trigger('assessable_submitted', $eventdata);
+ $params = array(
+ 'context' => context_module::instance($this->get_course_module()->id),
+ 'objectid' => $submission->id,
+ 'other' => array(
+ 'submission_editable' => false
+ )
+ );
+ $event = \mod_assign\event\assessable_submitted::create($params);
+ $event->set_legacy_logdata($logdata);
+ $event->trigger();
}
}
return true;
$result = $this->update_user_flags($flags);
if ($result) {
- $this->add_to_log('grant extension', $userid);
+ $addtolog = $this->add_to_log('grant extension', $userid, '', true);
+ $params = array(
+ 'context' => $this->context,
+ 'objectid' => $flags->assignment,
+ 'relateduserid' => $userid
+ );
+ $event = \mod_assign\event\extension_granted::create($params);
+ $event->set_legacy_logdata($addtolog);
+ $event->trigger();
}
return $result;
}
$record->userid = $userid;
if ($modified >= 0) {
$record->grade = unformat_float(optional_param('quickgrade_' . $record->userid, -1, PARAM_TEXT));
+ $record->workflowstate = optional_param('quickgrade_' . $record->userid.'_workflowstate', '', PARAM_TEXT);
+ $record->allocatedmarker = optional_param('quickgrade_' . $record->userid.'_allocatedmarker', '', PARAM_INT);
} else {
// This user was not in the grading table.
continue;
FROM {assign_grades} mxg
WHERE mxg.assignment = :assignid1 GROUP BY mxg.userid';
- $sql = 'SELECT u.id as userid, g.grade as grade, g.timemodified as lastmodified
+ $sql = 'SELECT u.id as userid, g.grade as grade, g.timemodified as lastmodified, uf.workflowstate, uf.allocatedmarker
FROM {user} u
LEFT JOIN ( ' . $grademaxattempt . ' ) gmx ON u.id = gmx.userid
LEFT JOIN {assign_grades} g ON
u.id = g.userid AND
g.assignment = :assignid2 AND
g.attemptnumber = gmx.maxattempt
+ LEFT JOIN {assign_user_flags} uf ON uf.assignment = g.assignment AND uf.userid = g.userid
WHERE u.id ' . $userids;
$currentgrades = $DB->get_recordset_sql($sql, $params);
if (($current->grade < 0 || $current->grade === null) &&
($modified->grade < 0 || $modified->grade === null)) {
// Different ways to indicate no grade.
- continue;
+ $modified->grade = $current->grade; // Keep existing grade.
}
// Treat 0 and null as different values.
if ($current->grade !== null) {
$current->grade = floatval($current->grade);
}
- if ($current->grade !== $modified->grade) {
+ if ($current->grade !== $modified->grade ||
+ ($this->get_instance()->markingallocation && $current->allocatedmarker != $modified->allocatedmarker ) ||
+ ($this->get_instance()->markingworkflow && $current->workflowstate !== $modified->workflowstate )) {
+
// Grade changed.
if ($this->grading_disabled($modified->userid)) {
continue;
// Ok - ready to process the updates.
foreach ($modifiedusers as $userid => $modified) {
$grade = $this->get_user_grade($userid, true);
+ $flags = $this->get_user_flags($userid, true);
$grade->grade= grade_floatval(unformat_float($modified->grade));
$grade->grader= $USER->id;
}
}
+ if ($flags->workflowstate != $modified->workflowstate ||
+ $flags->allocatedmarker != $modified->allocatedmarker) {
+
+ $flags->workflowstate = $modified->workflowstate;
+ $flags->allocatedmarker = $modified->allocatedmarker;
+ $this->update_user_flags($flags);
+ }
$this->update_grade($grade);
$this->notify_grade_modified($grade);
}
}
- $this->add_to_log('grade submission', $this->format_grade_for_log($grade));
+ $addtolog = $this->add_to_log('grade submission', $this->format_grade_for_log($grade), '', true);
+ $params = array(
+ 'context' => $this->context,
+ 'objectid' => $grade->id,
+ 'relateduserid' => $userid
+ );
+ $event = \mod_assign\event\submission_graded::create($params);
+ $event->set_legacy_logdata($addtolog);
+ $event->trigger();
}
return get_string('quickgradingchangessaved', 'assign');
$this->gradebook_item_update(null, $grade);
}
- $this->add_to_log('reveal identities', get_string('revealidentities', 'assign'));
+ $addtolog = $this->add_to_log('reveal identities', get_string('revealidentities', 'assign'), '', true);
+ $params = array(
+ 'context' => $this->context,
+ 'objectid' => $update->id
+ );
+ $event = \mod_assign\event\identities_revealed::create($params);
+ $event->set_legacy_logdata($addtolog);
+ $event->trigger();
}
$gradingmanager = get_grading_manager($this->get_context(), 'mod_assign', 'submissions');
$controller = $gradingmanager->get_active_controller();
$showquickgrading = empty($controller);
+ if (!is_null($this->context)) {
+ $showonlyactiveenrolopt = has_capability('moodle/course:viewsuspendedusers', $this->context);
+ } else {
+ $showonlyactiveenrolopt = false;
+ }
+
+ $markingallocation = $this->get_instance()->markingallocation &&
+ has_capability('mod/assign:manageallocations', $this->context);
+ // Get markers to use in drop lists.
+ $markingallocationoptions = array();
+ if ($markingallocation) {
+ $markingallocationoptions[''] = get_string('filternone', 'assign');
+ $markers = get_users_by_capability($this->context, 'mod/assign:grade');
+ foreach ($markers as $marker) {
+ $markingallocationoptions[$marker->id] = fullname($marker);
+ }
+ }
+
+ // Get marking states to show in form.
+ $markingworkflowoptions = array();
+ if ($this->get_instance()->markingworkflow) {
+ $notmarked = get_string('markingworkflowstatenotmarked', 'assign');
+ $markingworkflowoptions[''] = get_string('filternone', 'assign');
+ $markingworkflowoptions[ASSIGN_MARKING_WORKFLOW_STATE_NOTMARKED] = $notmarked;
+ $markingworkflowoptions = array_merge($markingworkflowoptions, $this->get_marking_workflow_states_for_current_user());
+ }
$gradingoptionsparams = array('cm'=>$this->get_course_module()->id,
'contextid'=>$this->context->id,
'userid'=>$USER->id,
'submissionsenabled'=>$this->is_any_submission_plugin_enabled(),
'showquickgrading'=>$showquickgrading,
- 'quickgrading'=>false);
+ 'quickgrading'=>false,
+ 'markingworkflowopt' => $markingworkflowoptions,
+ 'markingallocationopt' => $markingallocationoptions,
+ 'showonlyactiveenrolopt'=>$showonlyactiveenrolopt,
+ 'showonlyactiveenrol'=>$this->show_only_active_users());
$mform = new mod_assign_grading_options_form(null, $gradingoptionsparams);
if ($formdata = $mform->get_data()) {
if (isset($formdata->filter)) {
set_user_preference('assign_filter', $formdata->filter);
}
+ if (isset($formdata->markerfilter)) {
+ set_user_preference('assign_markerfilter', $formdata->markerfilter);
+ }
+ if (isset($formdata->workflowfilter)) {
+ set_user_preference('assign_workflowfilter', $formdata->workflowfilter);
+ }
if ($showquickgrading) {
set_user_preference('assign_quickgrading', isset($formdata->quickgrading));
}
+ if (!empty($showonlyactiveenrolopt)) {
+ $showonlyactiveenrol = isset($formdata->showonlyactiveenrol);
+ set_user_preference('grade_report_showonlyactiveenrol', $showonlyactiveenrol);
+ $this->showonlyactiveenrol = $showonlyactiveenrol;
+ }
}
}
return false;
}
- $this->add_to_log('submissioncopied', $this->format_submission_for_log($submission));
+ $addtolog = $this->add_to_log('submissioncopied', $this->format_submission_for_log($submission), '', true);
+ $params = array(
+ 'context' => $this->context,
+ 'objectid' => $submission->id
+ );
+ $event = \mod_assign\event\submission_duplicated::create($params);
+ $event->set_legacy_logdata($addtolog);
+ $event->trigger();
$complete = COMPLETION_INCOMPLETE;
if ($submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED) {
// The same logic applies here - we could not notify teachers,
// but then they would wonder why there are submitted assignments
// and they haven't been notified.
- $eventdata = new stdClass();
- $eventdata->modulename = 'assign';
- $eventdata->cmid = $this->get_course_module()->id;
- $eventdata->itemid = $submission->id;
- $eventdata->courseid = $this->get_course()->id;
- $eventdata->userid = $USER->id;
- $eventdata->params = array(
- 'submission_editable' => true,
+ $params = array(
+ 'context' => context_module::instance($this->get_course_module()->id),
+ 'objectid' => $submission->id,
+ 'other' => array(
+ 'submission_editable' => true
+ )
);
- events_trigger('assessable_submitted', $eventdata);
+ $event = \mod_assign\event\assessable_submitted::create($params);
+ $event->trigger();
}
return true;
}
return true;
}
if ($data = $mform->get_data()) {
+ if (!$this->submissions_open()) {
+ $notices[] = get_string('duedatereached', 'assign');
+ return false;
+ }
if ($instance->teamsubmission) {
$submission = $this->get_group_submission($USER->id, 0, true);
} else {
$allempty = true;
$pluginerror = false;
foreach ($this->submissionplugins as $plugin) {
- if ($plugin->is_enabled()) {
+ if ($plugin->is_enabled() && $plugin->is_visible()) {
if (!$plugin->save($submission, $data)) {
$notices[] = $plugin->get_error();
$pluginerror = true;
$logmessage = get_string('submissionstatementacceptedlog',
'mod_assign',
fullname($USER));
- $this->add_to_log('submission statement accepted', $logmessage);
+ $addtolog = $this->add_to_log('submission statement accepted', $logmessage, '', true);
+ $params = array(
+ 'context' => $this->context,
+ 'objectid' => $submission->id
+ );
+ $event = \mod_assign\event\statement_accepted::create($params);
+ $event->set_legacy_logdata($addtolog);
+ $event->trigger();
}
- $this->add_to_log('submit', $this->format_submission_for_log($submission));
+
+ $addtolog = $this->add_to_log('submit', $this->format_submission_for_log($submission), '', true);
+ $params = array(
+ 'context' => $this->context,
+ 'objectid' => $submission->id
+ );
+ $event = \mod_assign\event\submission_updated::create($params);
+ $event->set_legacy_logdata($addtolog);
+ $event->trigger();
$complete = COMPLETION_INCOMPLETE;
if ($submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED) {
$this->notify_student_submission_receipt($submission);
$this->notify_graders($submission);
// Trigger assessable_submitted event on submission.
- $eventdata = new stdClass();
- $eventdata->modulename = 'assign';
- $eventdata->cmid = $this->get_course_module()->id;
- $eventdata->itemid = $submission->id;
- $eventdata->courseid = $this->get_course()->id;
- $eventdata->userid = $USER->id;
- $eventdata->params = array(
- 'submission_editable' => true,
+ $params = array(
+ 'context' => context_module::instance($this->get_course_module()->id),
+ 'objectid' => $submission->id,
+ 'other' => array(
+ 'submission_editable' => true
+ )
);
- events_trigger('assessable_submitted', $eventdata);
+ $event = \mod_assign\event\assessable_submitted::create($params);
+ $event->trigger();
}
return true;
}
/**
- * Determine if this users grade is locked or overridden.
+ * Determine if this users grade can be edited.
*
* @param int $userid - The student userid
+ * @param bool $checkworkflow - whether to include a check for the workflow state.
* @return bool $gradingdisabled
*/
- public function grading_disabled($userid) {
+ public function grading_disabled($userid, $checkworkflow=true) {
global $CFG;
-
+ if ($checkworkflow && $this->get_instance()->markingworkflow) {
+ $grade = $this->get_user_grade($userid, false);
+ $validstates = $this->get_marking_workflow_states_for_current_user();
+ if (!empty($grade) && !empty($grade->workflowstate) && !array_key_exists($grade->workflowstate, $validstates)) {
+ return true;
+ }
+ }
$gradinginfo = grade_get_grades($this->get_course()->id,
'mod',
'assign',
global $CFG, $USER;
$grademenu = make_grades_menu($this->get_instance()->grade);
+ $allowgradedecimals = $this->get_instance()->grade > 0;
$advancedgradingwarning = false;
$gradingmanager = get_grading_manager($this->context, 'mod_assign', 'submissions');
}
}
if ($gradinginstance) {
- $gradinginstance->get_controller()->set_grade_range($grademenu);
+ $gradinginstance->get_controller()->set_grade_range($grademenu, $allowgradedecimals);
}
return $gradinginstance;
}
$gradingelement->freeze();
} else {
$mform->addElement('hidden', 'advancedgradinginstanceid', $gradinginstance->get_id());
+ $mform->setType('advancedgradinginstanceid', PARAM_INT);
}
} else {
// Use simple direct grading.
if ($this->get_instance()->grade > 0) {
$name = get_string('gradeoutof', 'assign', $this->get_instance()->grade);
- $gradingelement = $mform->addElement('text', 'grade', $name);
- $mform->addHelpButton('grade', 'gradeoutofhelp', 'assign');
- $mform->setType('grade', PARAM_TEXT);
- if ($gradingdisabled) {
- $gradingelement->freeze();
+ if (!$gradingdisabled) {
+ $gradingelement = $mform->addElement('text', 'grade', $name);
+ $mform->addHelpButton('grade', 'gradeoutofhelp', 'assign');
+ $mform->setType('grade', PARAM_RAW);
+ } else {
+ $mform->addElement('hidden', 'grade', $name);
+ $mform->hardFreeze('grade');
+ $mform->setType('grade', PARAM_RAW);
+ $strgradelocked = get_string('gradelocked', 'assign');
+ $mform->addElement('static', 'gradedisabled', $name, $strgradelocked);
+ $mform->addHelpButton('gradedisabled', 'gradeoutofhelp', 'assign');
}
} else {
$grademenu = make_grades_menu($this->get_instance()->grade);
}
$gradestring = $usergrade;
}
+
+ if ($this->get_instance()->markingworkflow) {
+ $states = $this->get_marking_workflow_states_for_current_user();
+ $options = array('' => get_string('markingworkflowstatenotmarked', 'assign')) + $states;
+ $mform->addElement('select', 'workflowstate', get_string('markingworkflowstate', 'assign'), $options);
+ $mform->addHelpButton('workflowstate', 'markingworkflowstate', 'assign');
+ }
+
+ if ($this->get_instance()->markingallocation && has_capability('mod/assign:manageallocations', $this->context)) {
+ $markers = get_users_by_capability($this->context, 'mod/assign:grade');
+ $markerlist = array('' => get_string('choosemarker', 'assign'));
+ foreach ($markers as $marker) {
+ $markerlist[$marker->id] = fullname($marker);
+ }
+ $mform->addElement('select', 'allocatedmarker', get_string('allocatedmarker', 'assign'), $markerlist);
+ $mform->addHelpButton('allocatedmarker', 'allocatedmarker', 'assign');
+ $mform->disabledIf('allocatedmarker', 'workflowstate', 'eq', ASSIGN_MARKING_WORKFLOW_STATE_READYFORREVIEW);
+ $mform->disabledIf('allocatedmarker', 'workflowstate', 'eq', ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW);
+ $mform->disabledIf('allocatedmarker', 'workflowstate', 'eq', ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE);
+ $mform->disabledIf('allocatedmarker', 'workflowstate', 'eq', ASSIGN_MARKING_WORKFLOW_STATE_RELEASED);
+ }
+
$mform->addElement('static', 'currentgrade', get_string('currentgrade', 'assign'), $gradestring);
if (count($useridlist) > 1) {
// Submission statement.
$adminconfig = $this->get_admin_config();
- $requiresubmissionstatement = (!empty($adminconfig->requiresubmissionstatement) ||
- $this->get_instance()->requiresubmissionstatement) &&
+ $requiresubmissionstatement = $this->get_instance()->requiresubmissionstatement &&
!empty($adminconfig->submissionstatement);
$draftsenabled = $this->get_instance()->submissiondrafts;
$submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
$this->update_submission($submission, $userid, true, $this->get_instance()->teamsubmission);
+ // Give each submission plugin a chance to process the reverting to draft.
+ $plugins = $this->get_submission_plugins();
+ foreach ($plugins as $plugin) {
+ if ($plugin->is_enabled() && $plugin->is_visible()) {
+ $plugin->revert_to_draft($submission);
+ }
+ }
// Update the modified time on the grade (grader modified).
$grade = $this->get_user_grade($userid, true);
$grade->grader = $USER->id;
$logmessage = get_string('reverttodraftforstudent',
'assign',
array('id'=>$user->id, 'fullname'=>fullname($user)));
- $this->add_to_log('revert submission to draft', $logmessage);
+ $addtolog = $this->add_to_log('revert submission to draft', $logmessage, '', true);
+ $params = array(
+ 'context' => $this->context,
+ 'objectid' => $submission->id,
+ 'relateduserid' => ($this->get_instance()->teamsubmission) ? null : $userid,
+ 'other' => array(
+ 'newstatus' => $submission->status
+ )
+ );
+ $event = \mod_assign\event\submission_status_updated::create($params);
+ $event->set_legacy_logdata($addtolog);
+ $event->trigger();
}
/**
$userid = required_param('userid', PARAM_INT);
}
+ // Give each submission plugin a chance to process the locking.
+ $plugins = $this->get_submission_plugins();
+ $submission = $this->get_user_submission($userid, false);
+ foreach ($plugins as $plugin) {
+ if ($plugin->is_enabled() && $plugin->is_visible()) {
+ $plugin->lock($submission);
+ }
+ }
+
$flags = $this->get_user_flags($userid, true);
$flags->locked = 1;
$this->update_user_flags($flags);
$logmessage = get_string('locksubmissionforstudent',
'assign',
array('id'=>$user->id, 'fullname'=>fullname($user)));
- $this->add_to_log('lock submission', $logmessage);
+ $addtolog = $this->add_to_log('lock submission', $logmessage, '', true);
+ $params = array(
+ 'context' => $this->context,
+ 'objectid' => $flags->assignment,
+ 'relateduserid' => $user->id
+ );
+ $event = \mod_assign\event\submission_locked::create($params);
+ $event->set_legacy_logdata($addtolog);
+ $event->trigger();
+ }
+
+
+ /**
+ * Set the workflow state for multiple users
+ *
+ * @return void
+ */
+ protected function process_set_batch_marking_workflow_state() {
+ global $DB;
+
+ require_sesskey();
+
+ $batchusers = required_param('selectedusers', PARAM_TEXT);
+ $state = required_param('markingworkflowstate', PARAM_ALPHA);
+ $useridlist = explode(',', $batchusers);
+
+ foreach ($useridlist as $userid) {
+ $flags = $this->get_user_flags($userid, true);
+
+ $flags->workflowstate = $state;
+
+ $gradingdisabled = $this->grading_disabled($userid);
+
+ // Will not apply update if user does not have permission to assign this workflow state.
+ if (!$gradingdisabled && $this->update_user_flags($flags)) {
+ if ($state == ASSIGN_MARKING_WORKFLOW_STATE_RELEASED) {
+ // Update Gradebook.
+ $assign = clone $this->get_instance();
+ $assign->cmidnumber = $this->get_course_module()->idnumber;
+ assign_update_grades($assign, $userid);
+ }
+
+ $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
+
+ $params = array('id'=>$user->id,
+ 'fullname'=>fullname($user),
+ 'state'=>$state);
+ $message = get_string('setmarkingworkflowstateforlog', 'assign', $params);
+ $addtolog = $this->add_to_log('set marking workflow state', $message, '', true);
+ $params = array(
+ 'context' => $this->context,
+ 'objectid' => $this->get_instance()->id,
+ 'relateduserid' => $userid,
+ 'other' => array(
+ 'newstate' => $state
+ )
+ );
+ $event = \mod_assign\event\workflow_state_updated::create($params);
+ $event->set_legacy_logdata($addtolog);
+ $event->trigger();
+ }
+ }
+ }
+
+ /**
+ * Set the marking allocation for multiple users
+ *
+ * @return void
+ */
+ protected function process_set_batch_marking_allocation() {
+ global $DB;
+
+ require_sesskey();
+ require_capability('mod/assign:manageallocations', $this->context);
+
+ $batchusers = required_param('selectedusers', PARAM_TEXT);
+ $markerid = required_param('allocatedmarker', PARAM_INT);
+ $marker = $DB->get_record('user', array('id' => $markerid), '*', MUST_EXIST);
+
+ $useridlist = explode(',', $batchusers);
+
+ foreach ($useridlist as $userid) {
+ $flags = $this->get_user_flags($userid, true);
+ if ($flags->workflowstate == ASSIGN_MARKING_WORKFLOW_STATE_READYFORREVIEW ||
+ $flags->workflowstate == ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW ||
+ $flags->workflowstate == ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE ||
+ $flags->workflowstate == ASSIGN_MARKING_WORKFLOW_STATE_RELEASED) {
+
+ continue; // Allocated marker can only be changed in certain workflow states.
+ }
+
+ $flags->allocatedmarker = $marker->id;
+
+ if ($this->update_user_flags($flags)) {
+
+ $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
+
+ $params = array('id'=>$user->id,
+ 'fullname'=>fullname($user),
+ 'marker'=>fullname($marker));
+ $message = get_string('setmarkerallocationforlog', 'assign', $params);
+ $addtolog = $this->add_to_log('set marking allocation', $message, '', true);
+ $params = array(
+ 'context' => $this->context,
+ 'objectid' => $this->get_instance()->id,
+ 'relateduserid' => $userid,
+ 'other' => array(
+ 'markerid' => $marker->id
+ )
+ );
+ $event = \mod_assign\event\marker_updated::create($params);
+ $event->set_legacy_logdata($addtolog);
+ $event->trigger();
+ }
+ }
}
+
/**
* Unlock the process.
*
if (!$userid) {
$userid = required_param('userid', PARAM_INT);
}
+ // Give each submission plugin a chance to process the unlocking.
+ $plugins = $this->get_submission_plugins();
+ $submission = $this->get_user_submission($userid, false);
+ foreach ($plugins as $plugin) {
+ if ($plugin->is_enabled() && $plugin->is_visible()) {
+ $plugin->unlock($submission);
+ }
+ }
$flags = $this->get_user_flags($userid, true);
$flags->locked = 0;
$logmessage = get_string('unlocksubmissionforstudent',
'assign',
array('id'=>$user->id, 'fullname'=>fullname($user)));
- $this->add_to_log('unlock submission', $logmessage);
+ $addtolog = $this->add_to_log('unlock submission', $logmessage, '', true);
+ $params = array(
+ 'context' => $this->context,
+ 'objectid' => $flags->assignment,
+ 'relateduserid' => $user->id
+ );
+ $event = \mod_assign\event\submission_unlocked::create($params);
+ $event->set_legacy_logdata($addtolog);
+ $event->trigger();
}
/**
$grade->grade = grade_floatval(unformat_float($formdata->grade));
}
}
+ if (isset($formdata->workflowstate) || isset($formdata->allocatedmarker)) {
+ $flags = $this->get_user_flags($userid, true);
+ $flags->workflowstate = isset($formdata->workflowstate) ? $formdata->workflowstate : $flags->workflowstate;
+ $flags->allocatedmarker = isset($formdata->allocatedmarker) ? $formdata->allocatedmarker : $flags->allocatedmarker;
+ $this->update_user_flags($flags);
+ }
}
$grade->grader= $USER->id;
}
$this->update_grade($grade);
$this->notify_grade_modified($grade);
- $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
- $this->add_to_log('grade submission', $this->format_grade_for_log($grade));
+ $addtolog = $this->add_to_log('grade submission', $this->format_grade_for_log($grade), '', true);
+ $params = array(
+ 'context' => $this->context,
+ 'objectid' => $grade->id,
+ 'relateduserid' => $userid
+ );
+ $event = \mod_assign\event\submission_graded::create($params);
+ $event->set_legacy_logdata($addtolog);
+ $event->trigger();
}
return false;
}
+ /**
+ * Get the list of marking_workflow states the current user has permission to transition a grade to.
+ *
+ * @return array of state => description
+ */
+ public function get_marking_workflow_states_for_current_user() {
+ if (!empty($this->markingworkflowstates)) {
+ return $this->markingworkflowstates;
+ }
+ $states = array();
+ if (has_capability('mod/assign:grade', $this->context)) {
+ $states[ASSIGN_MARKING_WORKFLOW_STATE_INMARKING] = get_string('markingworkflowstateinmarking', 'assign');
+ $states[ASSIGN_MARKING_WORKFLOW_STATE_READYFORREVIEW] = get_string('markingworkflowstatereadyforreview', 'assign');
+ }
+ if (has_any_capability(array('mod/assign:reviewgrades',
+ 'mod/assign:managegrades'), $this->context)) {
+ $states[ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW] = get_string('markingworkflowstateinreview', 'assign');
+ $states[ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE] = get_string('markingworkflowstatereadyforrelease', 'assign');
+ }
+ if (has_any_capability(array('mod/assign:releasegrades',
+ 'mod/assign:managegrades'), $this->context)) {
+ $states[ASSIGN_MARKING_WORKFLOW_STATE_RELEASED] = get_string('markingworkflowstatereleased', 'assign');
+ }
+ $this->markingworkflowstates = $states;
+ return $this->markingworkflowstates;
+ }
+
+ /**
+ * Check is only active users in course should be shown.
+ *
+ * @return bool true if only active users should be shown.
+ */
+ public function show_only_active_users() {
+ global $CFG;
+
+ if (is_null($this->showonlyactiveenrol)) {
+ $defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol);
+ $this->showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol);
+
+ if (!is_null($this->context)) {
+ $this->showonlyactiveenrol = $this->showonlyactiveenrol ||
+ !has_capability('moodle/course:viewsuspendedusers', $this->context);
+ }
+ }
+ return $this->showonlyactiveenrol;
+ }
+
+ /**
+ * Return true is user is active user in course else false
+ *
+ * @param int $userid
+ * @return bool true is user is active in course.
+ */
+ public function is_active_user($userid) {
+ if (is_null($this->susers) && !is_null($this->context)) {
+ $this->susers = get_suspended_userids($this->context);
+ }
+ return !in_array($userid, $this->susers);
+ }
}
/**
} else if ($this->exporter->get('formatclass') == PORTFOLIO_FORMAT_LEAP2A) {
$leapwriter = $this->exporter->get('format')->leap2a_writer();
$entry = new portfolio_format_leap2a_entry($this->area . $this->cmid,
- print_context_name($context),
+ $context->get_context_name(),
'resource',
$html);
// If we have multiple files, they should be grouped together into a folder.
$entry = new portfolio_format_leap2a_entry($baseid . 'group',
- print_context_name($context),
+ $context->get_context_name(),
'selection');
$leapwriter->add_entry($entry);
$leapwriter->make_selection($entry, $entryids, 'Folder');