MDL-86006 mod_assign: Display markers on grading table
This commit is contained in:
committed by
David Woloszyn
parent
a47646f775
commit
eaf4a6d425
@@ -456,14 +456,21 @@ class assign_grading_table extends table_sql implements renderable {
|
||||
$columns[] = 'team';
|
||||
$headers[] = get_string('submissionteam', 'assign');
|
||||
}
|
||||
// Allocated marker.
|
||||
|
||||
// Multiple markers.
|
||||
if ($this->assignment->get_instance()->markingworkflow &&
|
||||
$this->assignment->get_instance()->markingallocation &&
|
||||
has_capability('mod/assign:manageallocations', $this->assignment->get_context())) {
|
||||
// Add a column for the allocated marker.
|
||||
$columns[] = 'allocatedmarker';
|
||||
$headers[] = get_string('marker', 'assign');
|
||||
property_exists(
|
||||
$assignment->get_instance(),
|
||||
'markercount',
|
||||
)
|
||||
) {
|
||||
for ($i = 1; $i <= $assignment->get_instance()->markercount; $i++) {
|
||||
$columns[] = "marker$i";
|
||||
$headers[] = get_string('markernumber', 'assign', $i);
|
||||
}
|
||||
}
|
||||
|
||||
// Grade.
|
||||
$columns[] = 'grade';
|
||||
$headers[] = get_string('gradenoun');
|
||||
@@ -668,15 +675,6 @@ class assign_grading_table extends table_sql implements renderable {
|
||||
$o .= html_writer::div($allworkflowstates[$workflowstate]);
|
||||
} else {
|
||||
$o .= html_writer::select($workflowstates, $name, $workflowstate, ['' => $notmarked]);
|
||||
// Check if this user is a marker that can't manage allocations and doesn't have the marker column added.
|
||||
if ($this->assignment->get_instance()->markingworkflow &&
|
||||
$this->assignment->get_instance()->markingallocation &&
|
||||
!has_capability('mod/assign:manageallocations', $this->assignment->get_context())) {
|
||||
|
||||
$name = 'quickgrade_' . $row->id . '_allocatedmarker';
|
||||
$o .= html_writer::empty_tag('input', ['type' => 'hidden', 'name' => $name,
|
||||
'value' => $row->allocatedmarker]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$o .= $this->output->container(get_string('markingworkflowstate' . $workflowstate, 'assign'), $workflowstate);
|
||||
@@ -699,56 +697,102 @@ class assign_grading_table extends table_sql implements renderable {
|
||||
return get_string('markingworkflowstate' . $state, 'assign');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user object for the marker of a given student and marker number.
|
||||
*
|
||||
* @param int $studentid ID of the student.
|
||||
* @param int $number Marker index number.
|
||||
* @return stdClass|false User object or false if not found.
|
||||
*/
|
||||
protected function get_marker_number(int $studentid, int $number): stdClass|false {
|
||||
global $DB;
|
||||
$multimarkers = $DB->get_fieldset('assign_allocated_marker', 'marker', [
|
||||
'student' => $studentid, 'assignment' => $this->assignment->get_instance()->id,
|
||||
]);
|
||||
if (!empty($multimarkers) && count($multimarkers) >= $number) {
|
||||
// Then get the name of the one at the column position requested, e.g. marker1, marker2, etc...
|
||||
$index = $number - 1;
|
||||
return \core_user::get_user($multimarkers[$index]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* list current marker
|
||||
*
|
||||
* @param stdClass $row - The row of data
|
||||
* @return id the user->id of the marker.
|
||||
* @param int $markerpos - Marker position number - related to the markercount
|
||||
* @return string The name of the allocated marker
|
||||
*/
|
||||
public function col_allocatedmarker(stdClass $row) {
|
||||
public function col_allocatedmarker(stdClass $row, int $markerpos = 1) {
|
||||
static $markers = null;
|
||||
static $markerlist = array();
|
||||
if ($markers === null) {
|
||||
list($sort, $params) = users_order_by_sql('u');
|
||||
// Only enrolled users could be assigned as potential markers.
|
||||
$markers = get_enrolled_users($this->assignment->get_context(), 'mod/assign:grade', 0, 'u.*', $sort);
|
||||
$markerlist[0] = get_string('choosemarker', 'assign');
|
||||
$viewfullnames = has_capability('moodle/site:viewfullnames', $this->assignment->get_context());
|
||||
foreach ($markers as $marker) {
|
||||
$markerlist[$marker->id] = fullname($marker, $viewfullnames);
|
||||
|
||||
// Get the allocated markers that have been assigned to this student, if we are using multi-marking.
|
||||
$allocatedmarker = $this->get_marker_number($row->userid, $markerpos);
|
||||
|
||||
if ($this->is_downloading()) {
|
||||
if ($allocatedmarker) {
|
||||
return fullname(
|
||||
$allocatedmarker,
|
||||
has_capability('moodle/site:viewfullnames', $this->assignment->get_context())
|
||||
);
|
||||
}
|
||||
}
|
||||
if (empty($markerlist)) {
|
||||
// TODO: add some form of notification here that no markers are available.
|
||||
return '';
|
||||
}
|
||||
if ($this->is_downloading()) {
|
||||
if (isset($markers[$row->allocatedmarker])) {
|
||||
return fullname($markers[$row->allocatedmarker],
|
||||
has_capability('moodle/site:viewfullnames', $this->assignment->get_context()));
|
||||
} else {
|
||||
|
||||
if (
|
||||
$this->quickgrading &&
|
||||
has_capability('mod/assign:manageallocations', $this->assignment->get_context()) &&
|
||||
(
|
||||
empty($row->workflowstate) ||
|
||||
$row->workflowstate == ASSIGN_MARKING_WORKFLOW_STATE_INMARKING ||
|
||||
$row->workflowstate == ASSIGN_MARKING_WORKFLOW_STATE_NOTMARKED
|
||||
)
|
||||
) {
|
||||
// Get the potential users who could be assigned as an allocated marker.
|
||||
if ($markers === null) {
|
||||
[$sort, $params] = users_order_by_sql('u');
|
||||
// Only enrolled users could be assigned as potential markers.
|
||||
$markers = get_enrolled_users($this->assignment->get_context(), 'mod/assign:grade', 0, 'u.*', $sort);
|
||||
$markerlist[0] = get_string('choosemarker', 'assign');
|
||||
$viewfullnames = has_capability('moodle/site:viewfullnames', $this->assignment->get_context());
|
||||
foreach ($markers as $marker) {
|
||||
$markerlist[$marker->id] = fullname($marker, $viewfullnames);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($markerlist)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (count($markers) > 1) {
|
||||
$label = get_string('allocatedmarker', 'assign') . ' ' . $markerpos;
|
||||
} else {
|
||||
$label = get_string('allocatedmarker', 'assign');
|
||||
}
|
||||
|
||||
$name = 'quickgrade_' . $row->id . '_allocatedmarker_' . $markerpos;
|
||||
return html_writer::label(
|
||||
$label,
|
||||
'menu' . $name
|
||||
) . html_writer::select($markerlist, $name, ($allocatedmarker) ? $allocatedmarker->id : '', false);
|
||||
}
|
||||
|
||||
if ($this->quickgrading && has_capability('mod/assign:manageallocations', $this->assignment->get_context()) &&
|
||||
(empty($row->workflowstate) ||
|
||||
$row->workflowstate == ASSIGN_MARKING_WORKFLOW_STATE_INMARKING ||
|
||||
$row->workflowstate == ASSIGN_MARKING_WORKFLOW_STATE_NOTMARKED)) {
|
||||
|
||||
$name = 'quickgrade_' . $row->id . '_allocatedmarker';
|
||||
return html_writer::select($markerlist, $name, $row->allocatedmarker, false);
|
||||
} else if (!empty($row->allocatedmarker)) {
|
||||
if ($allocatedmarker) {
|
||||
$output = '';
|
||||
if ($this->quickgrading) { // Add hidden field for quickgrading page.
|
||||
$name = 'quickgrade_' . $row->id . '_allocatedmarker';
|
||||
$attributes = ['type' => 'hidden', 'name' => $name, 'value' => $row->allocatedmarker];
|
||||
$name = 'quickgrade_' . $row->id . '_allocatedmarker_' . $markerpos;
|
||||
$attributes = ['type' => 'hidden', 'name' => $name, 'value' => $allocatedmarker->id];
|
||||
$output .= html_writer::empty_tag('input', $attributes);
|
||||
}
|
||||
$output .= $markerlist[$row->allocatedmarker];
|
||||
$output .= html_writer::tag('strong', fullname($allocatedmarker));
|
||||
return $output;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* For download only - list all the valid options for this custom scale.
|
||||
*
|
||||
@@ -1048,6 +1092,128 @@ class assign_grading_table extends table_sql implements renderable {
|
||||
return $displaygrade;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the marker column's data for display.
|
||||
*
|
||||
* @param stdClass $row Row object.
|
||||
* @param int $col Marker number column.
|
||||
* @return string
|
||||
*/
|
||||
public function col_marker(stdClass $row, int $col): string {
|
||||
global $USER, $DB;
|
||||
$allocatedmarker = "";
|
||||
$index = $col - 1;
|
||||
|
||||
if (
|
||||
$this->assignment->get_instance()->markingworkflow &&
|
||||
$this->assignment->get_instance()->markingallocation
|
||||
) {
|
||||
$allocatedmarker = $this->col_allocatedmarker($row, $col);
|
||||
}
|
||||
|
||||
$gradingdisabled = $this->assignment->grading_disabled($row->id, true, $this->gradinginfo);
|
||||
$displaymark = "";
|
||||
|
||||
if (!$this->is_downloading() && $this->hasgrade) {
|
||||
if (
|
||||
$this->assignment->get_instance()->markingworkflow &&
|
||||
$this->assignment->get_instance()->markingallocation
|
||||
) {
|
||||
// Allocated markers are enabled: get the mark corresponding to
|
||||
// the marker for this column.
|
||||
$markers = array_values($DB->get_records('assign_allocated_marker', [
|
||||
'student' => $row->userid,
|
||||
'assignment' => $this->assignment->get_instance()->id,
|
||||
], 'id'));
|
||||
if (count($markers) > $index) {
|
||||
$mark = $DB->get_record('assign_mark', ['gradeid' => $row->gradeid, 'marker' => $markers[$index]->marker]);
|
||||
// Mark is only editable if we are quick grading, grading is not disabled, and if we are either
|
||||
// the marker for this column, or we have manageallocations permissions.
|
||||
$editable = (
|
||||
($this->quickgrading) &&
|
||||
(!$gradingdisabled) &&
|
||||
($USER->id == $markers[$index]->marker)
|
||||
);
|
||||
$displaymark = $this->display_grade(
|
||||
$mark->mark ?? null,
|
||||
$editable,
|
||||
$row->userid,
|
||||
$row->timemarked,
|
||||
0,
|
||||
$markers[$index]->marker,
|
||||
);
|
||||
// Display the workflow state for this mark.
|
||||
if ($markers[$index]->marker > 0) {
|
||||
$displaymark .= html_writer::div(
|
||||
get_string('markingworkflowstate' . ($mark->workflowstate ?? 'notmarked'), 'assign'),
|
||||
'badge bg-info d-block'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$urlparams = [
|
||||
'id' => $this->assignment->get_course_module()->id,
|
||||
'rownum' => 0,
|
||||
'action' => 'marker',
|
||||
];
|
||||
|
||||
if ($this->assignment->is_blind_marking()) {
|
||||
if (empty($row->recordid)) {
|
||||
$row->recordid = $this->assignment->get_uniqueid_for_user($row->userid);
|
||||
}
|
||||
$urlparams['blindid'] = $row->recordid;
|
||||
} else {
|
||||
$urlparams['userid'] = $row->userid;
|
||||
}
|
||||
$url = new moodle_url('/mod/assign/view.php', $urlparams);
|
||||
|
||||
// The container with the grade information.
|
||||
$gradecontainer = $this->output->container($displaymark, 'w-100');
|
||||
|
||||
// Should this user get the 'Mark' action menu item?
|
||||
$isallocatedmarker = false;
|
||||
|
||||
if (
|
||||
$this->assignment->get_instance()->markingworkflow &&
|
||||
$this->assignment->get_instance()->markingallocation
|
||||
) {
|
||||
// If allocated marking is enabled is this user the marker for this column?
|
||||
if (
|
||||
$markers = $DB->get_fieldset('assign_allocated_marker', 'marker', [
|
||||
'student' => $row->userid,
|
||||
'assignment' => $this->assignment->get_instance()->id,
|
||||
])
|
||||
) {
|
||||
$isallocatedmarker = (array_key_exists($index, $markers) && $markers[$index] == $USER->id);
|
||||
}
|
||||
}
|
||||
|
||||
if ($isallocatedmarker) {
|
||||
$menu = new action_menu();
|
||||
$menu->set_owner_selector('.gradingtable-actionmenu');
|
||||
$menu->set_boundary('window');
|
||||
$menu->set_kebab_trigger(get_string('markactions', 'assign'));
|
||||
$menu->set_additional_classes('ps-2 ms-auto');
|
||||
// Prioritise the menu ahead of all other actions.
|
||||
$menu->prioritise = true;
|
||||
// Add the 'Mark' action item to the contextual menu.
|
||||
$menu->add(new action_menu_link_secondary($url, null, get_string('markverb', 'assign')));
|
||||
// The contextual menu container.
|
||||
$contextualmenucontainer = $this->output->container($this->output->render($menu), 'd-flex');
|
||||
return $allocatedmarker .
|
||||
$this->output->container($gradecontainer . $contextualmenucontainer, ['class' => 'd-flex']);
|
||||
}
|
||||
}
|
||||
// The table data is being downloaded, or the user cannot grade; therefore, only the formatted grade for display
|
||||
// is returned.
|
||||
if ($this->is_downloading()) {
|
||||
return $displaymark;
|
||||
} else {
|
||||
return $allocatedmarker . $this->output->container($gradecontainer, ['class' => 'd-flex']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a column of data for display.
|
||||
*
|
||||
@@ -1644,6 +1810,12 @@ class assign_grading_table extends table_sql implements renderable {
|
||||
* @return mixed string or NULL
|
||||
*/
|
||||
public function other_cols($colname, $row) {
|
||||
// If the column name is formatted as "marker" and a number, e.g. "marker1", this is a Marker column
|
||||
// and so we need to call col_marker() instead with the marker number provided in the name. In this case "1".
|
||||
if (str_starts_with($colname, 'marker') && ($col = substr($colname, 6)) && ctype_digit($col)) {
|
||||
return $this->col_marker($row, $col);
|
||||
}
|
||||
|
||||
// For extra user fields the result is already in $row.
|
||||
if (empty($this->plugincache[$colname])) {
|
||||
return parent::other_cols($colname, $row);
|
||||
|
||||
@@ -384,11 +384,13 @@ $string['locksubmissionforstudent'] = 'Prevent any more submissions for student:
|
||||
$string['locksubmissions'] = 'Lock submissions';
|
||||
$string['manageassignfeedbackplugins'] = 'Manage assignment feedback plugins';
|
||||
$string['manageassignsubmissionplugins'] = 'Manage assignment submission plugins';
|
||||
$string['markactions'] = 'Mark actions';
|
||||
$string['marker'] = 'Marker';
|
||||
$string['markercount'] = 'Markers';
|
||||
$string['markercount_help'] = 'Number of markers for the assignment.';
|
||||
$string['markerfilter'] = 'Marker filter';
|
||||
$string['markerfilternomarker'] = 'No marker';
|
||||
$string['markernumber'] = 'Marker {$a}';
|
||||
$string['markgradeaverage'] = 'Average mark';
|
||||
$string['markgradeaverage_help'] = 'Grade will be calculated as the average of all marks given.';
|
||||
$string['markgrademanual'] = 'Manual';
|
||||
@@ -417,6 +419,7 @@ $string['markingworkflowstatenotmarked'] = 'Not marked';
|
||||
$string['markingworkflowstatereadyforreview'] = 'Marking completed';
|
||||
$string['markingworkflowstatereadyforrelease'] = 'Ready for release';
|
||||
$string['markingworkflowstatereleased'] = 'Released';
|
||||
$string['markverb'] = 'Mark';
|
||||
$string['multimarkmethod'] = 'Calculate grade';
|
||||
$string['multimarkmethod_help'] = 'How the grade will be calculated when there are multiple markers';
|
||||
$string['multimarkrounding'] = 'Rounding';
|
||||
|
||||
Reference in New Issue
Block a user