This commit is contained in:
skodak 2007-10-19 08:51:52 +00:00
parent deb2988f39
commit d297269d79
13 changed files with 284 additions and 162 deletions

View file

@ -10,8 +10,6 @@ $temp = new admin_settingpage('gradessettings', get_string('gradessettings', 'gr
// enable outcomes checkbox // enable outcomes checkbox
$temp->add(new admin_setting_configcheckbox('enableoutcomes', get_string('enableoutcomes', 'grades'), get_string('configenableoutcomes', 'grades'), 0, PARAM_INT)); $temp->add(new admin_setting_configcheckbox('enableoutcomes', get_string('enableoutcomes', 'grades'), get_string('configenableoutcomes', 'grades'), 0, PARAM_INT));
// enable publishing in exports/imports
$temp->add(new admin_setting_configcheckbox('gradepublishing', get_string('gradepublishing', 'grades'), get_string('configgradepublishing', 'grades'), 0, PARAM_INT));
$temp->add(new admin_setting_configselect('grade_aggregationposition', get_string('aggregationposition', 'grades'), $temp->add(new admin_setting_configselect('grade_aggregationposition', get_string('aggregationposition', 'grades'),
get_string('configaggregationposition', 'grades'), GRADE_REPORT_AGGREGATION_POSITION_LAST, get_string('configaggregationposition', 'grades'), GRADE_REPORT_AGGREGATION_POSITION_LAST,
@ -33,6 +31,11 @@ $temp->add(new admin_setting_configselect('grade_decimalpoints', get_string('dec
'4' => '4', '4' => '4',
'5' => '5'))); '5' => '5')));
$temp->add(new admin_setting_configcheckbox('grade_hiddenasdate', get_string('hiddenasdate', 'grades'), get_string('confighiddenasdate', 'grades'), 0, PARAM_INT));
// enable publishing in exports/imports
$temp->add(new admin_setting_configcheckbox('gradepublishing', get_string('gradepublishing', 'grades'), get_string('configgradepublishing', 'grades'), 0, PARAM_INT));
$temp->add(new admin_setting_configselect('grade_export_displaytype', get_string('gradeexportdisplaytype', 'grades'), $temp->add(new admin_setting_configselect('grade_export_displaytype', get_string('gradeexportdisplaytype', 'grades'),
get_string('configgradeexportdisplaytype', 'grades'), GRADE_DISPLAY_TYPE_REAL, get_string('configgradeexportdisplaytype', 'grades'), GRADE_DISPLAY_TYPE_REAL,
array(GRADE_DISPLAY_TYPE_REAL => get_string('real', 'grades'), array(GRADE_DISPLAY_TYPE_REAL => get_string('real', 'grades'),
@ -46,20 +49,11 @@ $temp->add(new admin_setting_configselect('grade_export_decimalpoints', get_stri
'2' => '2', '2' => '2',
'3' => '3', '3' => '3',
'4' => '4', '4' => '4',
'5' => '5'))); '5' => '5')));
$temp->add(new admin_setting_special_gradeexport()); $temp->add(new admin_setting_special_gradeexport());
$ADMIN->add('grades', $temp); $ADMIN->add('grades', $temp);
/// Scales and outcomes
$scales = new admin_externalpage('scales', get_string('scales'), $CFG->wwwroot.'/grade/edit/scale/index.php', 'moodle/grade:manage');
$ADMIN->add('grades', $scales);
$outcomes = new admin_externalpage('outcomes', get_string('outcomes', 'grades'), $CFG->wwwroot.'/grade/edit/outcome/index.php', 'moodle/grade:manage');
$ADMIN->add('grades', $outcomes);
$letters = new admin_externalpage('letters', get_string('letters', 'grades'), $CFG->wwwroot.'/grade/edit/letter/edit.php', 'moodle/grade:manageletters');
$ADMIN->add('grades', $letters);
/// Grade category settings /// Grade category settings
$temp = new admin_settingpage('gradecategorysettings', get_string('gradecategorysettings', 'grades')); $temp = new admin_settingpage('gradecategorysettings', get_string('gradecategorysettings', 'grades'));
@ -96,6 +90,15 @@ $temp->add(new admin_setting_configselect('grade_droplow', get_string('droplow',
$ADMIN->add('grades', $temp); $ADMIN->add('grades', $temp);
/// Scales and outcomes
$scales = new admin_externalpage('scales', get_string('scales'), $CFG->wwwroot.'/grade/edit/scale/index.php', 'moodle/grade:manage');
$ADMIN->add('grades', $scales);
$outcomes = new admin_externalpage('outcomes', get_string('outcomes', 'grades'), $CFG->wwwroot.'/grade/edit/outcome/index.php', 'moodle/grade:manage');
$ADMIN->add('grades', $outcomes);
$letters = new admin_externalpage('letters', get_string('letters', 'grades'), $CFG->wwwroot.'/grade/edit/letter/edit.php', 'moodle/grade:manageletters');
$ADMIN->add('grades', $letters);
// The plugins must implement a settings.php file that adds their admin settings to the $settings object // The plugins must implement a settings.php file that adds their admin settings to the $settings object
// Reports // Reports

View file

@ -187,35 +187,9 @@ function get_grade_tree(&$gtree, $element, $current_itemid=null, $errors=null) {
} }
} }
$icon = '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="icon" alt=""/>' . "\n"; $icon = $gtree->get_element_icon($element);
$last = ''; $last = '';
$catcourseitem = false; $catcourseitem = ($element['type'] == 'courseitem' or $element['type'] == 'categoryitem');
switch ($type) {
case 'item':
if ($object->itemtype == 'mod') {
$icon = '<img src="'.$CFG->modpixpath.'/'.$object->itemmodule.'/icon.gif" class="icon" alt="'
. get_string('modulename', $object->itemmodule).'"/>' . "\n";
} else if ($object->itemtype == 'manual') {
//TODO: add manual grading icon
if (empty($object->outcomeid)) {
$icon = '<img src="'.$CFG->pixpath.'/t/edit.gif" class="icon" alt="'
. get_string('manualgrade', 'grades').'"/>' . "\n"; // TODO: localize
} else {
$icon = '<img src="'.$CFG->pixpath.'/i/outcomes.gif" class="icon" alt="'
. get_string('outcome', 'grades').'"/>' . "\n";
}
}
break;
case 'courseitem':
case 'categoryitem':
$icon = '<img src="'.$CFG->pixpath.'/i/category_grade.gif" class="icon" alt="'.get_string('categorygrade').'"/>' . "\n"; // TODO: localize
$catcourseitem = true;
break;
case 'category':
$icon = '<img src="'.$CFG->pixpath.'/f/folder.gif" class="icon" alt="'.get_string('category').'"/>' . "\n";
break;
}
if ($type != 'category') { if ($type != 'category') {
$return_string .= '<li class="'.$type.'">'.$icon.$name.'</li>' . "\n"; $return_string .= '<li class="'.$type.'">'.$icon.$name.'</li>' . "\n";

View file

@ -42,7 +42,7 @@ class edit_category_form extends moodleform {
GRADE_AGGREGATE_EXTRACREDIT_MEAN=>get_string('aggregateextracreditmean', 'grades')); GRADE_AGGREGATE_EXTRACREDIT_MEAN=>get_string('aggregateextracreditmean', 'grades'));
// visible elements // visible elements
$mform->addElement('header', 'general', get_string('gradecategory', 'grades')); $mform->addElement('header', 'gradecat', get_string('gradecategory', 'grades'));
$mform->addElement('text', 'fullname', get_string('categoryname', 'grades')); $mform->addElement('text', 'fullname', get_string('categoryname', 'grades'));
if ($CFG->grade_aggregation == -1) { if ($CFG->grade_aggregation == -1) {
@ -62,12 +62,14 @@ class edit_category_form extends moodleform {
$mform->addElement('static', 'aggregateonlygraded', get_string('aggregateonlygraded', 'grades')); $mform->addElement('static', 'aggregateonlygraded', get_string('aggregateonlygraded', 'grades'));
} }
if (!empty($CFG->enableoutcomes) && $CFG->grade_aggregateoutcomes == -1) { if (!empty($CFG->enableoutcomes)) {
$mform->addElement('advcheckbox', 'aggregateoutcomes', get_string('aggregateoutcomes', 'grades')); if($CFG->grade_aggregateoutcomes == -1) {
$mform->setHelpButton('aggregateoutcomes', array(false, get_string('aggregateoutcomes', 'grades'), $mform->addElement('advcheckbox', 'aggregateoutcomes', get_string('aggregateoutcomes', 'grades'));
false, true, false, get_string('aggregateoutcomeshelp', 'grades'))); $mform->setHelpButton('aggregateoutcomes', array(false, get_string('aggregateoutcomes', 'grades'),
} else { false, true, false, get_string('aggregateoutcomeshelp', 'grades')));
$mform->addElement('static', 'aggregateoutcomes', get_string('aggregateoutcomes', 'grades')); } else {
$mform->addElement('static', 'aggregateoutcomes', get_string('aggregateoutcomes', 'grades'));
}
} }
if ($CFG->grade_aggregatesubcats == -1) { if ($CFG->grade_aggregatesubcats == -1) {
@ -111,7 +113,7 @@ class edit_category_form extends moodleform {
} }
// user preferences // user preferences
$mform->addElement('header', 'general', get_string('userpreferences', 'grades')); $mform->addElement('header', 'userpref', get_string('myreportpreferences', 'grades'));
$options = array(GRADE_REPORT_PREFERENCE_DEFAULT => get_string('default', 'grades'), $options = array(GRADE_REPORT_PREFERENCE_DEFAULT => get_string('default', 'grades'),
GRADE_REPORT_AGGREGATION_VIEW_FULL => get_string('fullmode', 'grades'), GRADE_REPORT_AGGREGATION_VIEW_FULL => get_string('fullmode', 'grades'),
GRADE_REPORT_AGGREGATION_VIEW_AGGREGATES_ONLY => get_string('aggregatesonly', 'grades'), GRADE_REPORT_AGGREGATION_VIEW_AGGREGATES_ONLY => get_string('aggregatesonly', 'grades'),
@ -158,9 +160,11 @@ class edit_category_form extends moodleform {
$agg_el->setValue($checkbox_values[$CFG->grade_aggregateonlygraded]); $agg_el->setValue($checkbox_values[$CFG->grade_aggregateonlygraded]);
} }
if ($CFG->grade_aggregateoutcomes != -1) { if (!empty($CFG->enableoutcomes)) {
$agg_el =& $mform->getElement('aggregateoutcomes'); if ($CFG->grade_aggregateoutcomes != -1) {
$agg_el->setValue($checkbox_values[$CFG->grade_aggregateoutcomes]); $agg_el =& $mform->getElement('aggregateoutcomes');
$agg_el->setValue($checkbox_values[$CFG->grade_aggregateoutcomes]);
}
} }
if ($CFG->grade_aggregatesubcats != -1) { if ($CFG->grade_aggregatesubcats != -1) {

View file

@ -201,35 +201,9 @@ function print_grade_tree(&$gtree, $element, $moving, &$gpr, $switch, $switchedl
$actions .= $gtree->get_hiding_icon($element, $gpr); $actions .= $gtree->get_hiding_icon($element, $gpr);
/// prepare icon /// prepare icon
$icon = '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="icon" alt=""/>'; $icon = $gtree->get_element_icon($element);
$last = ''; $last = '';
$catcourseitem = false; $catcourseitem = ($element['type'] == 'courseitem' or $element['type'] == 'categoryitem');
switch ($element['type']) {
case 'item':
if ($object->itemtype == 'mod') {
$icon = '<img src="'.$CFG->modpixpath.'/'.$object->itemmodule.'/icon.gif" class="icon" alt="'
. get_string('modulename', $object->itemmodule).'"/>';
} else if ($object->itemtype == 'manual') {
//TODO: add manual grading icon
if (empty($object->outcomeid)) {
$icon = '<img src="'.$CFG->pixpath.'/t/edit.gif" class="icon" alt="'
. get_string('manualgrade', 'grades').'"/>'; // TODO: localize
} else {
$icon = '<img src="'.$CFG->pixpath.'/i/outcomes.gif" class="icon" alt="'
. get_string('outcome', 'grades').'"/>';
}
}
break;
case 'courseitem':
case 'categoryitem':
$icon = '<img src="'.$CFG->pixpath.'/i/category_grade.gif" class="icon" alt="'.get_string('categorygrade').'"/>'; // TODO: localize
$catcourseitem = true;
break;
case 'category':
$icon = '<img src="'.$CFG->pixpath.'/f/folder.gif" class="icon" alt="'.get_string('category').'"/>';
break;
}
/// prepare move target if needed /// prepare move target if needed
$moveto = ''; $moveto = '';

View file

@ -839,7 +839,6 @@ class grade_seq {
return 'g'.$grade_grade->id; return 'g'.$grade_grade->id;
} }
} }
} }
/** /**
@ -919,6 +918,7 @@ class grade_tree {
} }
grade_tree::fill_levels($this->levels, $this->top_element, 0); grade_tree::fill_levels($this->levels, $this->top_element, 0);
} }
/** /**
@ -1344,6 +1344,61 @@ class grade_tree {
return $calculation_icon; return $calculation_icon;
} }
/**
* Returns icon of element
* @param object $element
* @param bool $spacerifnone return spacer if no icon found
* @return string icon or spacer
*/
function get_element_icon(&$element, $spacerifnone=true) {
global $CFG;
switch ($element['type']) {
case 'item':
case 'courseitem':
case 'categoryitem':
if ($element['object']->is_calculated()) {
return '<img src="'.$CFG->pixpath.'/i/calc.gif" class="icon" alt="'.get_string('calculation', 'grades').'"/>';
} else if (($element['object']->is_course_item() or $element['object']->is_category_item())
and ($element['object']->gradetype == GRADE_TYPE_SCALE or $element['object']->gradetype == GRADE_TYPE_VALUE)) {
if ($category = $element['object']->get_item_category()) {
switch ($category->aggregation) {
case GRADE_AGGREGATE_MEAN:
case GRADE_AGGREGATE_MEDIAN:
case GRADE_AGGREGATE_WEIGHTED_MEAN:
case GRADE_AGGREGATE_EXTRACREDIT_MEAN:
return '<img src="'.$CFG->pixpath.'/i/agg_mean.gif" class="icon" alt="'.get_string('aggregation', 'grades').'"/>';
//case GRADE_AGGREGATE_SUM:
//return '<img src="'.$CFG->pixpath.'/i/agg_sum.gif" class="icon" alt="'.get_string('aggregation', 'grades').'"/>';
}
}
} else if ($element['object']->itemtype == 'mod') {
return '<img src="'.$CFG->modpixpath.'/'.$element['object']->itemmodule.'/icon.gif" class="icon" alt="'
.get_string('modulename', $element['object']->itemmodule).'"/>';
} else if ($element['object']->itemtype == 'manual') {
if ($element['object']->is_outcome_item()) {
return '<img src="'.$CFG->pixpath.'/i/outcomes.gif" class="icon" alt="'.get_string('outcome', 'grades').'"/>';
} else {
//TODO: add better icon
return '<img src="'.$CFG->pixpath.'/t/edit.gif" class="icon" alt="'.get_string('manualitem', 'grades').'"/>';
}
}
break;
case 'category':
return '<img src="'.$CFG->pixpath.'/f/folder.gif" class="icon" alt="'.get_string('category', 'grades').'"/>';
}
if ($spacerifnone) {
return '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="icon" alt=""/>';
} else {
return '';
}
}
} }
?> ?>

View file

@ -132,6 +132,8 @@ if ($perpageurl) {
} }
$report->load_users(); $report->load_users();
$numusers = $report->get_numusers(); $numusers = $report->get_numusers();
$report->load_final_grades(); $report->load_final_grades();

View file

@ -342,9 +342,10 @@ class grade_report_grader extends grade_report {
$userids = array_keys($this->users); $userids = array_keys($this->users);
if ($grades = get_records_sql($sql)) { if ($grades = get_records_sql($sql)) {
foreach ($grades as $graderec) { foreach ($grades as $graderec) {
if (in_array($graderec->userid, $userids)) { if (in_array($graderec->userid, $userids) and array_key_exists($graderec->itemid, $this->gtree->items)) { // some items may not be present!!
$this->grades[$graderec->userid][$graderec->itemid] = new grade_grade($graderec, false); $this->grades[$graderec->userid][$graderec->itemid] = new grade_grade($graderec, false);
$this->grades[$graderec->userid][$graderec->itemid]->grade_item =& $this->gtree->items[$graderec->itemid]; // db caching $this->grades[$graderec->userid][$graderec->itemid]->grade_item =& $this->gtree->items[$graderec->itemid]; // db caching
} }
@ -603,20 +604,23 @@ class grade_report_grader extends grade_report {
*/ */
function get_studentshtml() { function get_studentshtml() {
global $CFG, $USER; global $CFG, $USER;
$studentshtml = ''; $studentshtml = '';
$strfeedback = $this->get_lang_string("feedback"); $strfeedback = $this->get_lang_string("feedback");
$strgrade = $this->get_lang_string('grade'); $strgrade = $this->get_lang_string('grade');
$gradetabindex = 1; $gradetabindex = 1;
$showuserimage = $this->get_pref('showuserimage'); $showuserimage = $this->get_pref('showuserimage');
$numusers = count($this->users); $numusers = count($this->users);
// Preload scale objects for items with a scaleid // Preload scale objects for items with a scaleid
$scales_list = ''; $scales_list = '';
$tabindices = array(); $tabindices = array();
foreach ($this->gtree->items as $item) { foreach ($this->gtree->items as $item) {
if (!empty($item->scaleid)) { if (!empty($item->scaleid)) {
$scales_list .= "$item->scaleid,"; $scales_list .= "$item->scaleid,";
} }
$tabindices[$item->id]['grade'] = $gradetabindex; $tabindices[$item->id]['grade'] = $gradetabindex;
$tabindices[$item->id]['feedback'] = $gradetabindex + $numusers; $tabindices[$item->id]['feedback'] = $gradetabindex + $numusers;
$gradetabindex += $numusers * 2; $gradetabindex += $numusers * 2;
@ -633,9 +637,13 @@ class grade_report_grader extends grade_report {
foreach ($this->users as $userid => $user) { foreach ($this->users as $userid => $user) {
if ($canviewhidden) { if ($canviewhidden) {
$hiding_affected = array(); $altered = array();
$unknown = array();
} else { } else {
$hiding_affected = grade_grade::get_hiding_affected($this->grades[$userid], $this->gtree->items); $hiding_affected = grade_grade::get_hiding_affected($this->grades[$userid], $this->gtree->items);
$altered = $hiding_affected['altered'];
$unknown = $hiding_affected['unknown'];
unset($hiding_affected);
} }
$columncount = 0; $columncount = 0;
@ -651,17 +659,24 @@ class grade_report_grader extends grade_report {
foreach ($this->gtree->items as $itemid=>$unused) { foreach ($this->gtree->items as $itemid=>$unused) {
$item =& $this->gtree->items[$itemid]; $item =& $this->gtree->items[$itemid];
$grade = $this->grades[$userid][$item->id];
// Get the decimal points preference for this item // Get the decimal points preference for this item
$decimalpoints = $item->get_decimals(); $decimalpoints = $item->get_decimals();
$grade = $this->grades[$userid][$item->id]; if (in_array($itemid, $unknown)) {
$gradeval = $grade->finalgrade; $gradeval = null;
} else if (array_key_exists($itemid, $altered)) {
$gradeval = $altered[$itemid];
} else {
$gradeval = $grade->finalgrade;
}
// MDL-11274 // MDL-11274
// Hide grades in the grader report if the current grader doesn't have 'moodle/grade:viewhidden' // Hide grades in the grader report if the current grader doesn't have 'moodle/grade:viewhidden'
if (!$canviewhidden and ($grade->is_hidden() or in_array($itemid, $hiding_affected))) { if (!$canviewhidden and $grade->is_hidden()) {
if (!is_null($gradeval) and $grade->is_hidden()) { if (!empty($CFG->grade_hiddenasdate) and !is_null($grade->finalgrade) and !$item->is_category_item() and !$item->is_course_item()) {
// the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records
$studentshtml .= '<td class="cell c'.$columncount++.'">'.userdate($grade->timecreated,get_string('strftimedatetimeshort')).'</td>'; $studentshtml .= '<td class="cell c'.$columncount++.'">'.userdate($grade->timecreated,get_string('strftimedatetimeshort')).'</td>';
} else { } else {
$studentshtml .= '<td class="cell c'.$columncount++.'">-</td>'; $studentshtml .= '<td class="cell c'.$columncount++.'">-</td>';

View file

@ -137,14 +137,26 @@ class grade_report_user extends grade_report {
} }
if ($canviewhidden) { if ($canviewhidden) {
$hiding_affected = array(); $altered = array();
$unknown = array();
} else { } else {
$hiding_affected = grade_grade::get_hiding_affected($grades, $items); $hiding_affected = grade_grade::get_hiding_affected($grades, $items);
$altered = $hiding_affected['altered'];
$unknown = $hiding_affected['unknown'];
unset($hiding_affected);
} }
foreach ($items as $key=>$unused) { foreach ($items as $itemid=>$unused) {
$grade_item =& $items[$key]; $grade_item =& $items[$itemid];
$grade_grade =& $grades[$key]; $grade_grade =& $grades[$itemid];
if (in_array($itemid, $unknown)) {
$gradeval = null;
} else if (array_key_exists($itemid, $altered)) {
$gradeval = $altered[$itemid];
} else {
$gradeval = $grade_grade->finalgrade;
}
$data = array(); $data = array();
@ -169,47 +181,31 @@ class grade_report_user extends grade_report {
if ($grade_item->needsupdate) { if ($grade_item->needsupdate) {
$data[] = '<span class="gradingerror">'.get_string('error').'</span>'; $data[] = '<span class="gradingerror">'.get_string('error').'</span>';
} else if (is_null($grade_grade->finalgrade)) { } else if (!empty($CFG->grade_hiddenasdate) and !is_null($grade_grade->finalgrade) and !$canviewhidden and $grade_grade->is_hidden()
$data[] = $excluded . '-'; and !$grade_item->is_category_item() and !$grade_item->is_course_item()) {
// the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records
} else if (!$canviewhidden and ($grade_grade->is_hidden() or in_array($grade_item->id, $hiding_affected))) { $data[] = $excluded . '<div class="gradeddate">'.get_string('gradedon', 'grades', userdate($grade_grade->timemodified, get_string('strftimedatetimeshort'))).'</div>';
// TODO: optinally do not show anything for hidden grades
// $data[] = '-';
if ($grade_grade->is_hidden()) {
$data[] = $excluded . '<div class="gradeddate">'.get_string('gradedon', 'grades', userdate($grade_grade->timemodified, get_string('strftimedatetimeshort'))).'</div>';
} else {
$data[] = $excluded . '-';
}
} else { } else {
$data[] = $excluded . grade_format_gradevalue($grade_grade->finalgrade, $grade_item, true); $data[] = $excluded . grade_format_gradevalue($gradeval, $grade_item, true);
} }
/// prints percentage /// prints percentage
if ($grade_item->needsupdate) { if ($grade_item->needsupdate) {
$data[] = '<span class="gradingerror">'.get_string('error').'</span>'; $data[] = '<span class="gradingerror">'.get_string('error').'</span>';
} else if (is_null($grade_grade->finalgrade)) {
$data[] = '-';
} else if (!$canviewhidden and ($grade_grade->is_hidden() or in_array($grade_item->id, $hiding_affected))) {
$data[] = '-';
} else { } else {
$data[] = grade_format_gradevalue($grade_grade->finalgrade, $grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE); $data[] = grade_format_gradevalue($gradeval, $grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE);
} }
/// prints rank /// prints rank
if ($grade_item->needsupdate) { if ($grade_item->needsupdate) {
$data[] = '<span class="gradingerror">'.get_string('error').'</span>'; $data[] = '<span class="gradingerror">'.get_string('error').'</span>';
} else if (is_null($grade_grade->finalgrade)) { } else if (is_null($gradeval)) {
// no grade, no rank // no grade, no rank
$data[] = '-'; $data[] = '-';
} else if (!$canviewhidden and ($grade_grade->is_hidden() or in_array($grade_item->id, $hiding_affected))) {
$data[] = '-';
} else { } else {
/// find the number of users with a higher grade /// find the number of users with a higher grade
$sql = "SELECT COUNT(DISTINCT(userid)) $sql = "SELECT COUNT(DISTINCT(userid))
@ -225,7 +221,7 @@ class grade_report_user extends grade_report {
if (empty($grade_grade->feedback)) { if (empty($grade_grade->feedback)) {
$data[] = '&nbsp;'; $data[] = '&nbsp;';
} else if (!$canviewhidden and ($grade_grade->is_hidden() or in_array($grade_item->id, $hiding_affected))) { } else if (!$canviewhidden and $grade_grade->is_hidden()) {
$data[] = '&nbsp;'; $data[] = '&nbsp;';
} else { } else {

View file

@ -74,6 +74,7 @@ $string['configexportdecimalpoints'] = 'The number of decimal points to display
$string['configgradeletter'] = 'A letter or other symbol used to represent a range of grades.'; $string['configgradeletter'] = 'A letter or other symbol used to represent a range of grades.';
$string['configgradeletterdefault'] = 'A letter or other symbol used to represent a range of grades. Leave this field empty to use the site default (currently $a).'; $string['configgradeletterdefault'] = 'A letter or other symbol used to represent a range of grades. Leave this field empty to use the site default (currently $a).';
$string['configgradepublishing'] = 'Enable publishing in exports and imports: Exported grades can be accessed by accessing a URL, without having to log on to a Moodle site. Grades can be imported by accessing such a URL (which means that a moodle site can import grades published by another site). By default only administrators may use this feature, please educate users before adding required capabilities to other roles (dangers of bookmark sharing and download accelerators, IP restrictions, etc.).'; $string['configgradepublishing'] = 'Enable publishing in exports and imports: Exported grades can be accessed by accessing a URL, without having to log on to a Moodle site. Grades can be imported by accessing such a URL (which means that a moodle site can import grades published by another site). By default only administrators may use this feature, please educate users before adding required capabilities to other roles (dangers of bookmark sharing and download accelerators, IP restrictions, etc.).';
$string['confighiddenasdate'] = 'If user can not see hidden grades show date instead of \'-\'.';
$string['configmeanselection'] = 'Select which types of grades will be included in the column averages. Cells with no grade can be ignored, or counted as 0 (default setting).'; $string['configmeanselection'] = 'Select which types of grades will be included in the column averages. Cells with no grade can be ignored, or counted as 0 (default setting).';
$string['configquickfeedback'] = 'Quick Feedback adds a text input element in each grade cell on the grader report, allowing you to edit many grades at once. You can then click the Update button to perform all these changes at once, instead of one at a time.'; $string['configquickfeedback'] = 'Quick Feedback adds a text input element in each grade cell on the grader report, allowing you to edit many grades at once. You can then click the Update button to perform all these changes at once, instead of one at a time.';
$string['configquickgrading'] = 'Quick Grading adds a text input element in each grade cell on the grader report, allowing you to edit the feedback for many grades at once. You can then click the Update button to perform all these changes at once, instead of one at a time.'; $string['configquickgrading'] = 'Quick Grading adds a text input element in each grade cell on the grader report, allowing you to edit the feedback for many grades at once. You can then click the Update button to perform all these changes at once, instead of one at a time.';
@ -163,7 +164,7 @@ $string['gradeboundary'] = 'Letter grade boundary';
$string['gradecategories'] = 'Grade categories'; $string['gradecategories'] = 'Grade categories';
$string['gradecategory'] = 'Grade Category'; $string['gradecategory'] = 'Grade Category';
$string['gradecategoryhelp'] = 'Grade Category Help'; $string['gradecategoryhelp'] = 'Grade Category Help';
$string['gradecategorysettings'] = 'Grade Category Settings'; $string['gradecategorysettings'] = 'Grade category settings';
$string['gradedon'] = 'Graded $a'; $string['gradedon'] = 'Graded $a';
$string['gradedisplay'] = 'Grade display'; $string['gradedisplay'] = 'Grade display';
$string['gradedisplaytype'] = 'Grade display type'; $string['gradedisplaytype'] = 'Grade display type';
@ -205,6 +206,7 @@ $string['gradeview'] = 'View Grade';
$string['gradeweighthelp'] = 'Grade Weight Help'; $string['gradeweighthelp'] = 'Grade Weight Help';
$string['groupavg'] = 'Group average'; $string['groupavg'] = 'Group average';
$string['hidden'] = 'Hidden'; $string['hidden'] = 'Hidden';
$string['hiddenasdate'] = 'Show date for hidden grades';
$string['hiddenuntil'] = 'Hidden until'; $string['hiddenuntil'] = 'Hidden until';
$string['hiddenuntildate'] = 'Hidden until: $a'; $string['hiddenuntildate'] = 'Hidden until: $a';
$string['hideadvanced'] = 'Hide Advanced Features'; $string['hideadvanced'] = 'Hide Advanced Features';
@ -256,6 +258,7 @@ $string['locktime'] = 'Lock after';
$string['locktimedate'] = 'Locked after: $a'; $string['locktimedate'] = 'Locked after: $a';
$string['lowest'] = 'Lowest'; $string['lowest'] = 'Lowest';
$string['lowgradeletter'] = 'Low'; $string['lowgradeletter'] = 'Low';
$string['manualitem'] = 'Manual item';
$string['mapfrom'] = 'Map from'; $string['mapfrom'] = 'Map from';
$string['mapto'] = 'Map to'; $string['mapto'] = 'Map to';
$string['max'] = 'Highest'; $string['max'] = 'Highest';

View file

@ -521,7 +521,38 @@ class grade_category extends grade_object {
return; return;
} }
/// start the aggregation // do the maths
$agg_grade = $this->aggregate_values($grade_values, $items);
/// prepare update of new raw grade
$grade->rawgrademin = $this->grade_item->grademin;
$grade->rawgrademax = $this->grade_item->grademax;
$grade->rawscaleid = $this->grade_item->scaleid;
$grade->rawgrade = null; // categories do not use raw grades
// recalculate the rawgrade back to requested range
$finalgrade = grade_grade::standardise_score($agg_grade, 0, 1, $this->grade_item->grademin, $this->grade_item->grademax);
if (!is_null($finalgrade)) {
$grade->finalgrade = bounded_number($this->grade_item->grademin, $finalgrade, $this->grade_item->grademax);
} else {
$grade->finalgrade = $finalgrade;
}
// update in db if changed
if ( $grade->finalgrade !== $oldgrade->finalgrade
or $grade->rawgrade !== $oldgrade->rawgrade
or $grade->rawgrademin !== $oldgrade->rawgrademin
or $grade->rawgrademax !== $oldgrade->rawgrademax
or $grade->rawscaleid !== $oldgrade->rawscaleid) {
$grade->update('system');
}
return;
}
function aggregate_values($grade_values, $items) {
switch ($this->aggregation) { switch ($this->aggregation) {
case GRADE_AGGREGATE_MEDIAN: // Middle point value in the set: ignores frequencies case GRADE_AGGREGATE_MEDIAN: // Middle point value in the set: ignores frequencies
$num = count($grade_values); $num = count($grade_values);
@ -593,34 +624,8 @@ class grade_category extends grade_object {
break; break;
} }
/// prepare update of new raw grade return $agg_grade;
$grade->rawgrademin = $this->grade_item->grademin;
$grade->rawgrademax = $this->grade_item->grademax;
$grade->rawscaleid = $this->grade_item->scaleid;
$grade->rawgrade = null; // categories do not use raw grades
// recalculate the rawgrade back to requested range
$finalgrade = grade_grade::standardise_score($agg_grade, 0, 1, $this->grade_item->grademin, $this->grade_item->grademax);
if (!is_null($finalgrade)) {
$grade->finalgrade = bounded_number($this->grade_item->grademin, $finalgrade, $this->grade_item->grademax);
} else {
$grade->finalgrade = $finalgrade;
}
// update in db if changed
if ( $grade->finalgrade !== $oldgrade->finalgrade
or $grade->rawgrade !== $oldgrade->rawgrade
or $grade->rawgrademin !== $oldgrade->rawgrademin
or $grade->rawgrademax !== $oldgrade->rawgrademax
or $grade->rawscaleid !== $oldgrade->rawscaleid) {
$grade->update('system');
}
return;
} }
/** /**
* Given an array of grade values (numerical indices), applies droplow or keephigh * Given an array of grade values (numerical indices), applies droplow or keephigh
* rules to limit the final array. * rules to limit the final array.

View file

@ -142,7 +142,7 @@ class grade_grade extends grade_object {
* Returns array of grades for given grade_item+users. * Returns array of grades for given grade_item+users.
* @param object $grade_item * @param object $grade_item
* @param array $userids * @param array $userids
* @param bool $include_missing include grades taht do not exist yet * @param bool $include_missing include grades that do not exist yet
* @return array userid=>grade_grade array * @return array userid=>grade_grade array
*/ */
function fetch_users_grades($grade_item, $userids, $include_missing=true) { function fetch_users_grades($grade_item, $userids, $include_missing=true) {
@ -475,45 +475,136 @@ class grade_grade extends grade_object {
/** /**
* Return array of grade item ids that are either hidden or indirectly depend * Return array of grade item ids that are either hidden or indirectly depend
* on hidden grades, excluded grades are not returned. * on hidden grades, excluded grades are not returned.
* THIS IS A REALLY BIG HACK! to be replaced by conditional aggregation of hidden grades in 2.0
*
* @static * @static
* @param array $grades all course grades of one user, & used for better internal caching * @param array $grades all course grades of one user, & used for better internal caching
* @param array $items $grade_items array of grade items, & used for better internal caching * @param array $items $grade_items array of grade items, & used for better internal caching
* @return array * @return array
*/ */
function get_hiding_affected(&$grade_grades, &$grade_items) { function get_hiding_affected(&$grade_grades, &$grade_items) {
global $CFG;
if (count($grade_grades) !== count($grade_items)) { if (count($grade_grades) !== count($grade_items)) {
error("Incorrent size of arrays in params of grade_grade::get_hiding_affected()!"); error("Incorrent size of arrays in params of grade_grade::get_hiding_affected()!");
} }
$dependson = array(); $dependson = array();
$todo = array();
$unknown = array(); // can not find altered
$altered = array(); // altered grades
foreach($grade_items as $key=>$unused) { foreach($grade_items as $key=>$unused) {
$grade_item =& $grade_items[$key]; // reference for improved caching inside grade_item $grade_item =& $grade_items[$key]; // reference for improved caching inside grade_item
$dependson[$grade_item->id] = $grade_item->depends_on(); $dependson[$grade_items[$key]->id] = $grade_items[$key]->depends_on();
} }
$todo = array(); $hiddenfound = false;
$hiding = array();
foreach($grade_grades as $grade_grade) { foreach($grade_grades as $grade_grade) {
if ($grade_grade->is_hidden() and !$grade_grade->is_excluded() and !is_null($grade_grade->finalgrade)) { if ($grade_grade->is_excluded()) {
$hiding[] = $grade_grade->itemid; //nothing to do, aggregation is ok
} else { } else if ($grade_grade->is_hidden()) {
$hiddenfound = true;
// hidden null grade does not affect the aggregation
if (!is_null($grade_grade->finalgrade)) {
$altered[$grade_grade->itemid] = null;
}
} else if (!empty($dependson[$grade_grade->itemid])) {
$todo[] = $grade_grade->itemid; $todo[] = $grade_grade->itemid;
} }
} }
if (!$hiddenfound) {
return array('unknown'=>array(), 'altered'=>array());
}
$max = count($grade_items); $max = count($todo);
for($i=0; $i<$max; $i++) { for($i=0; $i<$max; $i++) {
$found = false; $found = false;
foreach($todo as $key=>$do) { foreach($todo as $key=>$do) {
if (empty($dependson[$do])) { if (array_intersect($dependson[$do], $unknown)) {
unset($todo[$key]);
continue;
} else if (array_intersect($dependson[$do], $hiding)) {
// this item depends on hidden grade indirectly // this item depends on hidden grade indirectly
$hiding[] = $do; $unknown[$do] = $do;
unset($todo[$key]); unset($todo[$key]);
$found = true; $found = true;
continue;
} else if (!array_intersect($dependson[$do], $todo)) {
if (!array_intersect($dependson[$do], array_keys($altered))) {
// hiding does not affect this grade
unset($todo[$key]);
$found = true;
continue;
} else {
// depends on altered grades - we should try to recalculate if possible
if ($grade_items[$do]->is_calculated() or (!$grade_items[$do]->is_category_item() and !$grade_items[$do]->is_course_item())) {
$unknown[$do] = $do;
unset($todo[$key]);
$found = true;
continue;
} else {
$grade_category = $grade_items[$do]->load_item_category();
$values = array();
foreach ($dependson[$do] as $itemid) {
if (array_key_exists($itemid, $altered)) {
$values[$itemid] = $altered[$itemid];
} else {
$values[$itemid] = $grade_grades[$itemid]->finalgrade;
}
}
if ($CFG->grade_aggregateonlygraded != -1) {
$grade_category->aggregateonlygraded = $CFG->grade_aggregateonlygraded;
}
if ($grade_category->aggregateonlygraded) {
foreach ($values as $itemid=>$value) {
if (is_null($value)) {
unset($values[$itemid]);
}
}
} else {
foreach ($values as $itemid=>$value) {
if (is_null($value)) {
$values[$itemid] = $grade_items[$itemid]->grademin;
}
}
}
foreach ($values as $itemid=>$value) {
if ($grade_grades[$itemid]->is_excluded()) {
unset($values[$itemid]);
continue;
}
$values[$itemid] = grade_grade::standardise_score($value, $grade_items[$itemid]->grademin, $grade_items[$itemid]->grademax, 0, 1);
}
// limit and sort
$grade_category->apply_limit_rules($values);
asort($values, SORT_NUMERIC);
// let's see we have still enough grades to do any statistics
if (count($values) == 0) {
// not enough attempts yet
$altered[$do] = null;
unset($todo[$key]);
$found = true;
continue;
}
$agg_grade = $grade_category->aggregate_values($values, $grade_items);
// recalculate the rawgrade back to requested range
$finalgrade = grade_grade::standardise_score($agg_grade, 0, 1, $grade_items[$itemid]->grademin, $grade_items[$itemid]->grademax);
if (!is_null($finalgrade)) {
$finalgrade = bounded_number($grade_items[$itemid]->grademin, $finalgrade, $grade_items[$itemid]->grademax);
}
$altered[$do] = $finalgrade;
unset($todo[$key]);
$found = true;
continue;
}
}
} }
} }
if (!$found) { if (!$found) {
@ -521,7 +612,7 @@ class grade_grade extends grade_object {
} }
} }
return $hiding; return array('unknown'=>$unknown, 'altered'=>$altered);
} }
} }
?> ?>

BIN
pix/i/agg_mean.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

View file

Before

Width:  |  Height:  |  Size: 267 B

After

Width:  |  Height:  |  Size: 267 B

Before After
Before After