MDL-75362 gradereport_user: Comments and type hinting

This commit is contained in:
Mathew May 2022-09-12 06:29:55 +02:00
parent 8539da6af7
commit fdeda7f222
5 changed files with 213 additions and 193 deletions

View File

@ -25,7 +25,10 @@ use external_multiple_structure;
use external_single_structure;
use external_value;
use external_warnings;
use grade_plugin_return;
use graded_users_iterator;
use moodle_exception;
use stdClass;
defined('MOODLE_INTERNAL') || die;
@ -50,16 +53,16 @@ class user extends external_api {
* @return array with the parameters cleaned and other required information
* @since Moodle 3.2
*/
protected static function check_report_access($courseid, $userid, $groupid = 0) {
protected static function check_report_access(int $courseid, int $userid, int $groupid = 0): array {
global $USER;
// Validate the parameter.
$params = self::validate_parameters(self::get_grades_table_parameters(),
array(
[
'courseid' => $courseid,
'userid' => $userid,
'groupid' => $groupid,
)
]
);
// Compact/extract functions are not recommended.
@ -95,7 +98,7 @@ class user extends external_api {
if (has_capability('moodle/grade:viewall', $context)) {
// Can view all course grades.
$access = true;
} else if ($userid == $USER->id and has_capability('moodle/grade:view', $context) and $course->showgrades) {
} else if ($userid == $USER->id && has_capability('moodle/grade:view', $context) && $course->showgrades) {
// View own grades.
$access = true;
}
@ -122,7 +125,7 @@ class user extends external_api {
}
}
return array($params, $course, $context, $user, $groupid);
return [$params, $course, $context, $user, $groupid];
}
/**
@ -136,10 +139,17 @@ class user extends external_api {
* @return array data and possible warnings
* @since Moodle 3.2
*/
protected static function get_report_data($course, $context, $user, $userid, $groupid, $tabledata = true) {
protected static function get_report_data(
stdClass $course,
stdClass $context,
stdClass $user,
int $userid,
int $groupid,
bool $tabledata = true
): array {
global $CFG;
$warnings = array();
$warnings = [];
// Require files here to save some memory in case validation fails.
require_once($CFG->dirroot . '/group/lib.php');
require_once($CFG->libdir . '/gradelib.php');
@ -150,29 +160,30 @@ class user extends external_api {
grade_regrade_final_grades($course->id);
$gpr = new grade_plugin_return(
array(
[
'type' => 'report',
'plugin' => 'user',
'courseid' => $course->id,
'courseidnumber' => $course->idnumber,
'userid' => $userid)
'userid' => $userid
]
);
$reportdata = array();
$reportdata = [];
// Just one user.
if ($user) {
$report = new gradereport_user\report\user($course->id, $gpr, $context, $userid);
$report->fill_table();
$gradeuserdata = array(
$gradeuserdata = [
'courseid' => $course->id,
'courseidnumber' => $course->idnumber,
'userid' => $user->id,
'userfullname' => fullname($user),
'useridnumber' => $user->idnumber,
'maxdepth' => $report->maxdepth,
);
];
if ($tabledata) {
$gradeuserdata['tabledata'] = $report->tabledata;
} else {
@ -193,14 +204,14 @@ class user extends external_api {
$report = new gradereport_user\report\user($course->id, $gpr, $context, $currentuser->id);
$report->fill_table();
$gradeuserdata = array(
$gradeuserdata = [
'courseid' => $course->id,
'courseidnumber' => $course->idnumber,
'userid' => $currentuser->id,
'userfullname' => fullname($currentuser),
'useridnumber' => $currentuser->idnumber,
'maxdepth' => $report->maxdepth,
);
];
if ($tabledata) {
$gradeuserdata['tabledata'] = $report->tabledata;
} else {
@ -210,7 +221,7 @@ class user extends external_api {
}
$gui->close();
}
return array($reportdata, $warnings);
return [$reportdata, $warnings];
}
/**
@ -219,13 +230,13 @@ class user extends external_api {
* @return external_function_parameters
* @since Moodle 2.9
*/
public static function get_grades_table_parameters() {
public static function get_grades_table_parameters(): external_function_parameters {
return new external_function_parameters (
array(
[
'courseid' => new external_value(PARAM_INT, 'Course Id', VALUE_REQUIRED),
'userid' => new external_value(PARAM_INT, 'Return grades only for this user (optional)', VALUE_DEFAULT, 0),
'groupid' => new external_value(PARAM_INT, 'Get users from this group only', VALUE_DEFAULT, 0)
)
]
);
}
@ -239,19 +250,18 @@ class user extends external_api {
* @return array the grades tables
* @since Moodle 2.9
*/
public static function get_grades_table($courseid, $userid = 0, $groupid = 0) {
global $CFG, $USER;
public static function get_grades_table(int $courseid, int $userid = 0, int $groupid = 0): array {
list($params, $course, $context, $user, $groupid) = self::check_report_access($courseid, $userid, $groupid);
$userid = $params['userid'];
$userid = $params['userid'];
// We pass userid because it can be still 0.
list($tables, $warnings) = self::get_report_data($course, $context, $user, $userid, $groupid);
$result = array();
$result['tables'] = $tables;
$result['warnings'] = $warnings;
return $result;
return [
'tables' => $tables,
'warnings' => $warnings
];
}
/**
@ -260,12 +270,12 @@ class user extends external_api {
* @return array
* @since Moodle 2.9
*/
private static function grades_table_column() {
return array (
private static function grades_table_column(): array {
return [
'class' => new external_value(PARAM_RAW, 'class'),
'content' => new external_value(PARAM_RAW, 'cell content'),
'headers' => new external_value(PARAM_RAW, 'headers')
);
];
}
/**
@ -274,33 +284,33 @@ class user extends external_api {
* @return external_single_structure
* @since Moodle 2.9
*/
public static function get_grades_table_returns() {
public static function get_grades_table_returns(): external_single_structure {
return new external_single_structure(
array(
[
'tables' => new external_multiple_structure(
new external_single_structure(
array(
[
'courseid' => new external_value(PARAM_INT, 'course id'),
'userid' => new external_value(PARAM_INT, 'user id'),
'userfullname' => new external_value(PARAM_TEXT, 'user fullname'),
'maxdepth' => new external_value(PARAM_INT, 'table max depth (needed for printing it)'),
'tabledata' => new external_multiple_structure(
new external_single_structure(
array(
[
'itemname' => new external_single_structure(
array (
[
'class' => new external_value(PARAM_RAW, 'class'),
'colspan' => new external_value(PARAM_INT, 'col span'),
'content' => new external_value(PARAM_RAW, 'cell content'),
'celltype' => new external_value(PARAM_RAW, 'cell type'),
'id' => new external_value(PARAM_ALPHANUMEXT, 'id')
), 'The item returned data', VALUE_OPTIONAL
], 'The item returned data', VALUE_OPTIONAL
),
'leader' => new external_single_structure(
array (
[
'class' => new external_value(PARAM_RAW, 'class'),
'rowspan' => new external_value(PARAM_INT, 'row span')
), 'The item returned data', VALUE_OPTIONAL
], 'The item returned data', VALUE_OPTIONAL
),
'weight' => new external_single_structure(
self::grades_table_column(), 'weight column', VALUE_OPTIONAL
@ -329,14 +339,14 @@ class user extends external_api {
'contributiontocoursetotal' => new external_single_structure(
self::grades_table_column(), 'contributiontocoursetotal column', VALUE_OPTIONAL
),
), 'table'
], 'table'
)
)
)
]
)
),
'warnings' => new external_warnings()
)
]
);
}
@ -346,12 +356,12 @@ class user extends external_api {
* @return external_function_parameters
* @since Moodle 2.9
*/
public static function view_grade_report_parameters() {
public static function view_grade_report_parameters(): external_function_parameters {
return new external_function_parameters(
array(
[
'courseid' => new external_value(PARAM_INT, 'id of the course'),
'userid' => new external_value(PARAM_INT, 'id of the user, 0 means current user', VALUE_DEFAULT, 0),
)
]
);
}
@ -364,18 +374,18 @@ class user extends external_api {
* @since Moodle 2.9
* @throws moodle_exception
*/
public static function view_grade_report($courseid, $userid = 0) {
public static function view_grade_report(int $courseid, int $userid = 0): array {
global $CFG, $USER;
require_once($CFG->dirroot . "/grade/lib.php");
require_once($CFG->dirroot . "/grade/report/user/lib.php");
$params = self::validate_parameters(self::view_grade_report_parameters(),
array(
[
'courseid' => $courseid,
'userid' => $userid
));
]);
$warnings = array();
$warnings = [];
$course = get_course($params['courseid']);
@ -395,7 +405,7 @@ class user extends external_api {
if (has_capability('moodle/grade:viewall', $context)) {
// Can view all course grades (any user).
$access = true;
} else if ($userid == $USER->id and has_capability('moodle/grade:view', $context) and $course->showgrades) {
} else if ($userid == $USER->id && has_capability('moodle/grade:view', $context) && $course->showgrades) {
// View own grades.
$access = true;
}
@ -408,10 +418,10 @@ class user extends external_api {
$report = new gradereport_user\report\user($course->id, null, $context, $userid);
$report->viewed();
$result = array();
$result['status'] = true;
$result['warnings'] = $warnings;
return $result;
return [
'status' => true,
'warnings' => $warnings
];
}
/**
@ -422,10 +432,10 @@ class user extends external_api {
*/
public static function view_grade_report_returns() {
return new external_single_structure(
array(
[
'status' => new external_value(PARAM_BOOL, 'status: true if success'),
'warnings' => new external_warnings()
)
]
);
}
@ -435,7 +445,7 @@ class user extends external_api {
* @return external_function_parameters
* @since Moodle 3.2
*/
public static function get_grade_items_parameters() {
public static function get_grade_items_parameters(): external_function_parameters {
return self::get_grades_table_parameters();
}
@ -449,26 +459,25 @@ class user extends external_api {
* @return array the grades tables
* @since Moodle 3.2
*/
public static function get_grade_items($courseid, $userid = 0, $groupid = 0) {
global $CFG, $USER;
public static function get_grade_items(int $courseid, int $userid = 0, int $groupid = 0): array {
list($params, $course, $context, $user, $groupid) = self::check_report_access($courseid, $userid, $groupid);
$userid = $params['userid'];
$userid = $params['userid'];
// We pass userid because it can be still 0.
list($gradeitems, $warnings) = self::get_report_data($course, $context, $user, $userid, $groupid, false);
foreach ($gradeitems as $gradeitem) {
if (isset($gradeitem['feedback']) and isset($gradeitem['feedbackformat'])) {
if (isset($gradeitem['feedback']) && isset($gradeitem['feedbackformat'])) {
list($gradeitem['feedback'], $gradeitem['feedbackformat']) =
external_format_text($gradeitem['feedback'], $gradeitem['feedbackformat'], $context->id);
}
}
$result = array();
$result['usergrades'] = $gradeitems;
$result['warnings'] = $warnings;
return $result;
return [
'usergrades' => $gradeitems,
'warnings' => $warnings
];
}
/**
@ -477,12 +486,12 @@ class user extends external_api {
* @return external_single_structure
* @since Moodle 3.2
*/
public static function get_grade_items_returns() {
public static function get_grade_items_returns(): external_single_structure {
return new external_single_structure(
array(
[
'usergrades' => new external_multiple_structure(
new external_single_structure(
array(
[
'courseid' => new external_value(PARAM_INT, 'course id'),
'courseidnumber' => new external_value(PARAM_TEXT, 'course idnumber'),
'userid' => new external_value(PARAM_INT, 'user id'),
@ -492,7 +501,7 @@ class user extends external_api {
'maxdepth' => new external_value(PARAM_INT, 'table max depth (needed for printing it)'),
'gradeitems' => new external_multiple_structure(
new external_single_structure(
array(
[
'id' => new external_value(PARAM_INT, 'Grade item id'),
'itemname' => new external_value(PARAM_TEXT, 'Grade item name'),
'itemtype' => new external_value(PARAM_ALPHA, 'Grade item type'),
@ -527,14 +536,14 @@ class user extends external_api {
'averageformatted' => new external_value(PARAM_NOTAGS, 'Grade average', VALUE_OPTIONAL),
'feedback' => new external_value(PARAM_RAW, 'Grade feedback', VALUE_OPTIONAL),
'feedbackformat' => new external_format_value('feedback', VALUE_OPTIONAL),
), 'Grade items'
], 'Grade items'
)
)
)
]
)
),
'warnings' => new external_warnings()
)
]
);
}
}

View File

@ -191,18 +191,22 @@ class user extends grade_report {
* Constructor. Sets local copies of user preferences and initialises grade_tree.
* @param int $courseid
* @param object $gpr grade plugin return tracking object
* @param string $context
* @param object $context
* @param int $userid The id of the user
* @param bool $viewasuser Set this to true when the current user is a mentor/parent of the targetted user.
*/
public function __construct($courseid, $gpr, $context, $userid, $viewasuser = null) {
public function __construct(int $courseid, object $gpr, object $context, int $userid, bool $viewasuser = null) {
global $DB, $CFG;
parent::__construct($courseid, $gpr, $context);
$this->showrank = grade_get_setting($this->courseid, 'report_user_showrank', $CFG->grade_report_user_showrank);
$this->showpercentage = grade_get_setting($this->courseid, 'report_user_showpercentage', $CFG->grade_report_user_showpercentage);
$this->showhiddenitems = grade_get_setting($this->courseid, 'report_user_showhiddenitems', $CFG->grade_report_user_showhiddenitems);
$this->showtotalsifcontainhidden = array($this->courseid => grade_get_setting($this->courseid, 'report_user_showtotalsifcontainhidden', $CFG->grade_report_user_showtotalsifcontainhidden));
$this->showtotalsifcontainhidden = [$this->courseid => grade_get_setting(
$this->courseid,
'report_user_showtotalsifcontainhidden',
$CFG->grade_report_user_showtotalsifcontainhidden
)];
$this->showgrade = grade_get_setting($this->courseid, 'report_user_showgrade', !empty($CFG->grade_report_user_showgrade));
$this->showrange = grade_get_setting($this->courseid, 'report_user_showrange', !empty($CFG->grade_report_user_showrange));
@ -235,7 +239,7 @@ class user extends grade_report {
$this->switch = grade_get_setting($this->courseid, 'aggregationposition', $CFG->grade_aggregationposition);
// Grab the grade_tree for this course
// Grab the grade_tree for this course.
$this->gtree = new grade_tree($this->courseid, false, $this->switch, null, !$CFG->enableoutcomes);
// Get the user (for full name).
@ -261,24 +265,24 @@ class user extends grade_report {
$this->tabledata = array();
// base url for sorting by first/last name
// The base url for sorting by first/last name.
$this->baseurl = $CFG->wwwroot.'/grade/report?id='.$courseid.'&userid='.$userid;
$this->pbarurl = $this->baseurl;
// no groups on this report - rank is from all course users
// There no groups on this report - rank is from all course users.
$this->setup_table();
//optionally calculate grade item averages
// Optionally calculate grade item averages.
$this->calculate_averages();
}
/**
* Recurses through a tree of elements setting the rowspan property on each element
* Recurse through a tree of elements setting the rowspan property on each element
*
* @param array $element Either the top element or, during recursion, the current element
* @return int The number of elements processed
*/
function inject_rowspans(&$element) {
function inject_rowspans(array &$element): int {
if ($element['depth'] > $this->maxdepth) {
$this->maxdepth = $element['depth'];
@ -314,7 +318,7 @@ class user extends grade_report {
*| All columns except for itemname/description are optional
*/
// setting up table headers
// Setting up table headers.
$this->tablecolumns = array('itemname');
$this->tableheaders = array($this->get_lang_string('gradeitem', 'grades'));
@ -366,11 +370,7 @@ class user extends grade_report {
}
function fill_table() {
//print "<pre>";
//print_r($this->gtree->top_element);
$this->fill_table_recursive($this->gtree->top_element);
//print_r($this->tabledata);
//print "</pre>";
return true;
}
@ -379,7 +379,7 @@ class user extends grade_report {
*
* @param $element - An array containing the table data for the current row.
*/
private function fill_table_recursive(&$element) {
private function fill_table_recursive(array &$element) {
global $DB, $CFG, $OUTPUT;
$type = $element['type'];
@ -388,15 +388,15 @@ class user extends grade_report {
$eid = $grade_object->id;
$element['userid'] = $this->user->id;
$fullname = $this->gtree->get_element_header($element, true, true, true, true, true);
$data = array();
$gradeitemdata = array();
$data = [];
$gradeitemdata = [];
$hidden = '';
$excluded = '';
$itemlevel = ($type == 'categoryitem' || $type == 'category' || $type == 'courseitem') ? $depth : ($depth + 1);
$class = 'level' . $itemlevel . ' level' . ($itemlevel % 2 ? 'odd' : 'even');
$classfeedback = '';
// If this is a hidden grade category, hide it completely from the user
// If this is a hidden grade category, hide it completely from the user.
if ($type == 'category' && $grade_object->is_hidden() && !$this->canviewhidden && (
$this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN ||
($this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_object->is_hiddenuntil()))) {
@ -408,12 +408,12 @@ class user extends grade_report {
}
$alter = ($this->evenodd[$depth] == 0) ? 'even' : 'odd';
/// Process those items that have scores associated
// Process those items that have scores associated.
if ($type == 'item' or $type == 'categoryitem' or $type == 'courseitem') {
$header_row = "row_{$eid}_{$this->user->id}";
$header_cat = "cat_{$grade_object->categoryid}_{$this->user->id}";
if (! $grade_grade = grade_grade::fetch(array('itemid'=>$grade_object->id,'userid'=>$this->user->id))) {
if (! $grade_grade = grade_grade::fetch(['itemid'=>$grade_object->id,'userid'=>$this->user->id])) {
$grade_grade = new grade_grade();
$grade_grade->userid = $this->user->id;
$grade_grade->itemid = $grade_object->id;
@ -421,7 +421,7 @@ class user extends grade_report {
$grade_grade->load_grade_item();
/// Hidden Items
// Hidden Items.
if ($grade_grade->grade_item->is_hidden()) {
$hidden = ' dimmed_text';
}
@ -454,7 +454,7 @@ class user extends grade_report {
$gradeval = $grade_grade->finalgrade;
$hint = $grade_grade->get_aggregation_hint();
if (!$this->canviewhidden) {
/// Virtual Grade (may be calculated excluding hidden items etc).
// Virtual Grade (may be calculated excluding hidden items etc).
$adjustedgrade = $this->blank_hidden_total_and_adjust_bounds($this->courseid,
$grade_grade->grade_item,
$gradeval);
@ -477,15 +477,8 @@ class user extends grade_report {
if (!$hide) {
/// Excluded Item
/**
if ($grade_grade->is_excluded()) {
$fullname .= ' ['.get_string('excluded', 'grades').']';
$excluded = ' excluded';
}
**/
$canviewall = has_capability('moodle/grade:viewall', $this->context);
/// Other class information
// Other class information.
$class .= $hidden . $excluded;
if ($this->switch) { // alter style based on whether aggregation is first or last
$class .= ($type == 'categoryitem' or $type == 'courseitem') ? " ".$alter."d$depth baggt b2b" : " item b1b";
@ -496,7 +489,7 @@ class user extends grade_report {
$header_cat = "cat_{$grade_object->iteminstance}_{$this->user->id}";
}
/// Name
// Name.
$data['itemname']['content'] = $fullname;
$data['itemname']['class'] = $class;
$data['itemname']['colspan'] = ($this->maxdepth - $depth);
@ -517,7 +510,7 @@ class user extends grade_report {
$gradeitemdata['locked'] = $canviewall ? $grade_grade->grade_item->is_locked() : null;
if ($this->showfeedback) {
// Copy $class before appending itemcenter as feedback should not be centered
// Copy $class before appending itemcenter as feedback should not be centered.
$classfeedback = $class;
}
$class .= " itemcenter ";
@ -525,7 +518,7 @@ class user extends grade_report {
$data['weight']['class'] = $class;
$data['weight']['content'] = '-';
$data['weight']['headers'] = "$header_cat $header_row weight";
// has a weight assigned, might be extra credit
// Has a weight assigned, might be extra credit.
// This obliterates the weight because it provides a more informative description.
if (is_numeric($hint['weight'])) {
@ -554,7 +547,7 @@ class user extends grade_report {
$data['grade']['content'] = get_string('error');
} else if (!empty($CFG->grade_hiddenasdate) and $grade_grade->get_datesubmitted() and !$this->canviewhidden and $grade_grade->is_hidden()
and !$grade_grade->grade_item->is_category_item() and !$grade_grade->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
// 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.
$class .= ' datesubmitted';
$data['grade']['class'] = $class;
$data['grade']['content'] = get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort')));
@ -593,7 +586,7 @@ class user extends grade_report {
$gradeitemdata['gradeformatted'] = $data['grade']['content'];
}
// Range
// Range.
if ($this->showrange) {
$data['range']['class'] = $class;
$data['range']['content'] = $grade_grade->grade_item->get_formatted_range(GRADE_DISPLAY_TYPE_REAL, $this->rangedecimals);
@ -604,7 +597,7 @@ class user extends grade_report {
$gradeitemdata['grademax'] = $grade_grade->grade_item->grademax;
}
// Percentage
// Percentage.
if ($this->showpercentage) {
if ($grade_grade->grade_item->needsupdate) {
$data['percentage']['class'] = $class.' gradingerror';
@ -623,7 +616,7 @@ class user extends grade_report {
$gradeitemdata['percentageformatted'] = $data['percentage']['content'];
}
// Lettergrade
// Lettergrade.
if ($this->showlettergrade) {
if ($grade_grade->grade_item->needsupdate) {
$data['lettergrade']['class'] = $class.' gradingerror';
@ -643,7 +636,7 @@ class user extends grade_report {
$gradeitemdata['lettergradeformatted'] = $data['lettergrade']['content'];
}
// Rank
// Rank.
if ($this->showrank) {
$gradeitemdata['rank'] = 0;
if ($grade_grade->grade_item->needsupdate) {
@ -658,7 +651,7 @@ class user extends grade_report {
$data['rank']['content'] = '-';
} else {
/// find the number of users with a higher grade
// Find the number of users with a higher grade.
$sql = "SELECT COUNT(DISTINCT(userid))
FROM {grade_grades}
WHERE finalgrade > ?
@ -676,7 +669,7 @@ class user extends grade_report {
$data['rank']['headers'] = "$header_cat $header_row rank";
}
// Average
// Average.
if ($this->showaverage) {
$gradeitemdata['averageformatted'] = '';
@ -690,7 +683,7 @@ class user extends grade_report {
$data['average']['headers'] = "$header_cat $header_row average";
}
// Feedback
// Feedback.
if ($this->showfeedback) {
$gradeitemdata['feedback'] = '';
$gradeitemdata['feedbackformat'] = $grade_grade->feedbackformat;
@ -746,12 +739,13 @@ class user extends grade_report {
}
}
/// Category
// Category.
if ($type == 'category') {
$data['leader']['class'] = $class.' '.$alter."d$depth b1t b2b b1l";
$data['leader']['rowspan'] = $element['rowspan'];
if ($this->switch) { // alter style based on whether aggregation is first or last
// Alter style based on whether aggregation is first or last.
if ($this->switch) {
$data['itemname']['class'] = $class.' '.$alter."d$depth b1b b1t";
} else {
$data['itemname']['class'] = $class.' '.$alter."d$depth b2t";
@ -762,13 +756,13 @@ class user extends grade_report {
$data['itemname']['id'] = "cat_{$grade_object->id}_{$this->user->id}";
}
/// Add this row to the overall system
// Add this row to the overall system.
foreach ($data as $key => $celldata) {
$data[$key]['class'] .= ' column-' . $key;
}
$this->tabledata[] = $data;
/// Recursively iterate through all child elements
// Recursively iterate through all child elements.
if (isset($element['children'])) {
foreach ($element['children'] as $key=>$child) {
$this->fill_table_recursive($element['children'][$key]);
@ -779,7 +773,6 @@ class user extends grade_report {
// This should be the very last thing this fill_table_recursive function does.
if ($this->showcontributiontocoursetotal && ($type == 'category' && $depth == 1)) {
// We should have collected all the hints by now - walk the tree again and build the contributions column.
$this->fill_contributions_column($element);
}
}
@ -791,7 +784,7 @@ class user extends grade_report {
*
* @param $element - An array containing the table data for the current row.
*/
public function fill_contributions_column($element) {
public function fill_contributions_column(array $element) {
// Recursively iterate through all child elements.
if (isset($element['children'])) {
@ -876,10 +869,10 @@ class user extends grade_report {
* @param bool $return Whether or not to return the data instead of printing it directly.
* @return string
*/
public function print_table($return=false) {
public function print_table(bool $return = false): string {
$maxspan = $this->maxdepth;
/// Build table structure
// Build table structure.
$html = "
<table cellspacing='0'
cellpadding='0'
@ -898,7 +891,7 @@ class user extends grade_report {
</thead>
<tbody>\n";
/// Print out the table data
// Print out the table data.
for ($i = 0; $i < count($this->tabledata); $i++) {
$html .= "<tr>\n";
if (isset($this->tabledata[$i]['leader'])) {
@ -976,7 +969,7 @@ class user extends grade_report {
$params = array_merge($this->groupwheresql_params, $gradebookrolesparams, $enrolledparams, $relatedctxparams);
$params['courseid'] = $this->courseid;
// find sums of all grade items in course
// Find the sums of all grade items in course.
$sql = "SELECT gg.itemid, SUM(gg.finalgrade) AS sum
FROM {grade_items} gi
JOIN {grade_grades} gg ON gg.itemid = gi.id
@ -1005,10 +998,10 @@ class user extends grade_report {
$columncount=0;
// Empty grades must be evaluated as grademin, NOT always 0
// This query returns a count of ungraded grades (NULL finalgrade OR no matching record in grade_grades table)
// No join condition when joining grade_items and user to get a grade item row for every user
// Then left join with grade_grades and look for rows with null final grade (which includes grade items with no grade_grade)
// Empty grades must be evaluated as grademin, NOT always 0.
// This query returns a count of ungraded grades (NULL finalgrade OR no matching record in grade_grades table).
// No join condition when joining grade_items and user to get a grade item row for every user.
// Then left join with grade_grades and look for rows with null final grade (which includes grade items with no grade_grade).
$sql = "SELECT gi.id, COUNT(u.id) AS count
FROM {grade_items} gi
JOIN {user} u ON u.deleted = 0
@ -1050,26 +1043,28 @@ class user extends grade_report {
$ungraded_count = $ungraded_counts[$itemid]->count;
}
//do they want the averages to include all grade items
// Do they want the averages to include all grade items.
if ($meanselection == GRADE_REPORT_MEAN_GRADED) {
$mean_count = $totalcount - $ungraded_count;
} else { // Bump up the sum by the number of ungraded items * grademin
} else {
// Bump up the sum by the number of ungraded items * grademin.
$sum_array[$item->id] += ($ungraded_count * $item->grademin);
$mean_count = $totalcount;
}
// Determine which display type to use for this average
// Determine which display type to use for this average.
if (isset($USER->editing) && $USER->editing) {
$displaytype = GRADE_DISPLAY_TYPE_REAL;
} else if ($averagesdisplaytype == GRADE_REPORT_PREFERENCE_INHERIT) { // no ==0 here, please resave the report and user preferences
} else if ($averagesdisplaytype == GRADE_REPORT_PREFERENCE_INHERIT) {
// No ==0 here, please resave the report and user preferences.
$displaytype = $item->get_displaytype();
} else {
$displaytype = $averagesdisplaytype;
}
// Override grade_item setting if a display preference (not inherit) was set for the averages
// Override grade_item setting if a display preference (not inherit) was set for the averages.
if ($averagesdecimalpoints == GRADE_REPORT_PREFERENCE_INHERIT) {
$decimalpoints = $item->get_decimals();
} else {

View File

@ -21,31 +21,29 @@
* @copyright 2015 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$functions = array(
'gradereport_user_get_grades_table' => array(
$functions = [
'gradereport_user_get_grades_table' => [
'classname' => 'gradereport_user\\external\\user',
'methodname' => 'get_grades_table',
'description' => 'Get the user/s report grades table for a course',
'type' => 'read',
'capabilities' => 'gradereport/user:view',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
'gradereport_user_view_grade_report' => array(
'services' => [MOODLE_OFFICIAL_MOBILE_SERVICE],
],
'gradereport_user_view_grade_report' => [
'classname' => 'gradereport_user\\external\\user',
'methodname' => 'view_grade_report',
'description' => 'Trigger the report view event',
'type' => 'write',
'capabilities' => 'gradereport/user:view',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
'gradereport_user_get_grade_items' => array(
'services' => [MOODLE_OFFICIAL_MOBILE_SERVICE],
],
'gradereport_user_get_grade_items' => [
'classname' => 'gradereport_user\\external\\user',
'methodname' => 'get_grade_items',
'description' => 'Returns the complete list of grade items for users in a course',
'type' => 'read',
'capabilities' => 'gradereport/user:view',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
)
);
'services' => [MOODLE_OFFICIAL_MOBILE_SERVICE],
]
];

View File

@ -31,7 +31,7 @@ $courseid = required_param('id', PARAM_INT);
$userid = optional_param('userid', $USER->id, PARAM_INT);
$userview = optional_param('userview', 0, PARAM_INT);
$PAGE->set_url(new moodle_url('/grade/report/user/index.php', array('id'=>$courseid)));
$PAGE->set_url(new moodle_url('/grade/report/user/index.php', ['id'=>$courseid]));
if ($userview == 0) {
$userview = get_user_preferences('gradereport_user_view_user', GRADE_REPORT_USER_VIEW_USER);
@ -39,8 +39,8 @@ if ($userview == 0) {
set_user_preference('gradereport_user_view_user', $userview);
}
/// basic access checks
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
// Basic access checks.
if (!$course = $DB->get_record('course', ['id' => $courseid])) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
@ -53,54 +53,57 @@ if (empty($userid)) {
require_capability('moodle/grade:viewall', $context);
} else {
if (!$DB->get_record('user', array('id'=>$userid, 'deleted'=>0)) or isguestuser($userid)) {
if (!$DB->get_record('user', ['id'=>$userid, 'deleted'=>0]) or isguestuser($userid)) {
throw new \moodle_exception('invaliduser');
}
}
$access = false;
if (has_capability('moodle/grade:viewall', $context)) {
//ok - can view all course grades
// User can view all course grades.
$access = true;
} else if ($userid == $USER->id and has_capability('moodle/grade:view', $context) and $course->showgrades) {
//ok - can view own grades
// User can view own grades.
$access = true;
} else if (has_capability('moodle/grade:viewall', context_user::instance($userid)) and $course->showgrades) {
// ok - can view grades of this user- parent most probably
// User can view grades of this user, The user is an parent most probably.
$access = true;
}
if (!$access) {
// no access to grades!
// The user has no access to grades.
throw new \moodle_exception('nopermissiontoviewgrades', 'error', $CFG->wwwroot.'/course/view.php?id='.$courseid);
}
/// return tracking object
$gpr = new grade_plugin_return(array('type'=>'report', 'plugin'=>'user', 'courseid'=>$courseid, 'userid'=>$userid));
// Initialise the grade tracking object.
$gpr = new grade_plugin_return(['type'=>'report', 'plugin'=>'user', 'courseid'=>$courseid, 'userid'=>$userid]);
/// last selected report session tracking
// Infer the users previously selected report via session tracking.
if (!isset($USER->grade_last_report)) {
$USER->grade_last_report = array();
$USER->grade_last_report = [];
}
$USER->grade_last_report[$course->id] = 'user';
// First make sure we have proper final grades.
grade_regrade_final_grades_if_required($course);
if (has_capability('moodle/grade:viewall', $context)) { //Teachers will see all student reports
$groupmode = groups_get_course_groupmode($course); // Groups are being used
// Teachers will see all student reports.
if (has_capability('moodle/grade:viewall', $context)) {
// Verify if we are using groups or not.
$groupmode = groups_get_course_groupmode($course);
$currentgroup = $gpr->groupid;
if (!$currentgroup) { // To make some other functions work better later
// To make some other functions work better later.
if (!$currentgroup) {
$currentgroup = NULL;
}
$isseparategroups = ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context));
if ($isseparategroups and (!$currentgroup)) {
// no separate group access, can view only self
// No separate group access, The user can view only themselves.
$userid = $USER->id;
$user_selector = false;
} else {
@ -123,9 +126,9 @@ if (has_capability('moodle/grade:viewall', $context)) { //Teachers will see all
$gui = new graded_users_iterator($course, null, $currentgroup);
$gui->require_active_enrolment($showonlyactiveenrol);
$gui->init();
// Add tabs
// Add tabs.
print_grade_page_head($courseid, 'report', 'user');
groups_print_course_menu($course, $gpr->get_return_url('index.php?id='.$courseid, array('userid'=>0)));
groups_print_course_menu($course, $gpr->get_return_url('index.php?id='.$courseid, ['userid'=>0]));
if ($user_selector) {
echo $renderer->graded_users_selector('user', $course, $userid, $currentgroup, true);
@ -137,7 +140,7 @@ if (has_capability('moodle/grade:viewall', $context)) { //Teachers will see all
$user = $userdata->user;
$report = new gradereport_user\report\user($courseid, $gpr, $context, $user->id, $viewasuser);
$studentnamelink = html_writer::link(new moodle_url('/user/view.php', array('id' => $report->user->id, 'course' => $courseid)), fullname($report->user));
$studentnamelink = html_writer::link(new moodle_url('/user/view.php', ['id' => $report->user->id, 'course' => $courseid]), fullname($report->user));
echo $OUTPUT->heading($studentnamelink);
if ($report->fill_table()) {
@ -146,14 +149,15 @@ if (has_capability('moodle/grade:viewall', $context)) { //Teachers will see all
echo "<p style = 'page-break-after: always;'></p>";
}
$gui->close();
} else { // Only show one user's report
} else {
// Only show one user's report.
$report = new gradereport_user\report\user($courseid, $gpr, $context, $userid, $viewasuser);
$studentnamelink = html_writer::link(new moodle_url('/user/view.php', array('id' => $report->user->id, 'course' => $courseid)), fullname($report->user));
$studentnamelink = html_writer::link(new moodle_url('/user/view.php', ['id' => $report->user->id, 'course' => $courseid]), fullname($report->user));
print_grade_page_head($courseid, 'report', 'user', get_string('pluginname', 'gradereport_user') . ' - ' . $studentnamelink,
false, false, true, null, null, $report->user);
groups_print_course_menu($course, $gpr->get_return_url('index.php?id='.$courseid, array('userid'=>0)));
groups_print_course_menu($course, $gpr->get_return_url('index.php?id='.$courseid, ['userid'=>0]));
if ($user_selector) {
$showallusersoptions = true;
@ -170,12 +174,13 @@ if (has_capability('moodle/grade:viewall', $context)) { //Teachers will see all
}
}
}
} else { //Students will see just their own report
} else {
//Students will see just their own report.
// Create a report instance
// Create a report instance.
$report = new gradereport_user\report\user($courseid, $gpr, $context, $userid);
// print the page
// Print the page.
print_grade_page_head($courseid, 'report', 'user', get_string('pluginname', 'gradereport_user'). ' - '.fullname($report->user));
if ($report->fill_table()) {
@ -187,7 +192,7 @@ if (isset($report)) {
// Trigger report viewed event.
$report->viewed();
} else {
echo html_writer::tag('div', '', array('class' => 'clearfix'));
echo html_writer::tag('div', '', ['class' => 'clearfix']);
echo $OUTPUT->notification(get_string('nostudentsyet'));
}

View File

@ -22,10 +22,11 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use core_user\output\myprofile\tree;
require_once($CFG->dirroot . '/grade/report/lib.php');
require_once($CFG->libdir.'/tablelib.php');
//showhiddenitems values
define("GRADE_REPORT_USER_HIDE_HIDDEN", 0);
define("GRADE_REPORT_USER_HIDE_UNTIL", 1);
define("GRADE_REPORT_USER_SHOW_HIDDEN", 2);
@ -36,9 +37,11 @@ define("GRADE_REPORT_USER_VIEW_USER", 2);
function grade_report_user_settings_definition(&$mform) {
global $CFG;
$options = array(-1 => get_string('default', 'grades'),
0 => get_string('hide'),
1 => get_string('show'));
$options = [
-1 => get_string('default', 'grades'),
0 => get_string('hide'),
1 => get_string('show')
];
if (empty($CFG->grade_report_user_showrank)) {
$options[-1] = get_string('defaultprev', 'grades', $options[0]);
@ -115,16 +118,26 @@ function grade_report_user_settings_definition(&$mform) {
$mform->addElement('select', 'report_user_showrange', get_string('showrange', 'grades'), $options);
$options = array(0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5);
if (! empty($CFG->grade_report_user_rangedecimals)) {
$options = [
0=>0,
1=>1,
2=>2,
3=>3,
4=>4,
5=>5
];
if (!empty($CFG->grade_report_user_rangedecimals)) {
$options[-1] = $options[$CFG->grade_report_user_rangedecimals];
}
$mform->addElement('select', 'report_user_rangedecimals', get_string('rangedecimals', 'grades'), $options);
$options = array(-1 => get_string('default', 'grades'),
0 => get_string('shownohidden', 'grades'),
1 => get_string('showhiddenuntilonly', 'grades'),
2 => get_string('showallhidden', 'grades'));
$options = [
-1 => get_string('default', 'grades'),
0 => get_string('shownohidden', 'grades'),
1 => get_string('showhiddenuntilonly', 'grades'),
2 => get_string('showallhidden', 'grades')
];
if (empty($CFG->grade_report_user_showhiddenitems)) {
$options[-1] = get_string('defaultprev', 'grades', $options[0]);
@ -135,11 +148,12 @@ function grade_report_user_settings_definition(&$mform) {
$mform->addElement('select', 'report_user_showhiddenitems', get_string('showhiddenitems', 'grades'), $options);
$mform->addHelpButton('report_user_showhiddenitems', 'showhiddenitems', 'grades');
//showtotalsifcontainhidden
$options = array(-1 => get_string('default', 'grades'),
GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN => get_string('hide'),
GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowexhiddenitems', 'grades'),
GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowinchiddenitems', 'grades') );
$options = [
-1 => get_string('default', 'grades'),
GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN => get_string('hide'),
GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowexhiddenitems', 'grades'),
GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowinchiddenitems', 'grades')
];
if (empty($CFG->grade_report_user_showtotalsifcontainhidden)) {
$options[-1] = get_string('defaultprev', 'grades', $options[0]);
@ -159,19 +173,19 @@ function grade_report_user_settings_definition(&$mform) {
* @param object $user The user.
* @param boolean $viewasuser True when we are viewing this as the targetted user sees it.
*/
function grade_report_user_profilereport($course, $user, $viewasuser = false) {
global $OUTPUT;
function grade_report_user_profilereport(object $course, object $user, bool $viewasuser = false) {
if (!empty($course->showgrades)) {
$context = context_course::instance($course->id);
/// return tracking object
// Fetch the return tracking object.
$gpr = new grade_plugin_return(array('type'=>'report', 'plugin'=>'user', 'courseid'=>$course->id, 'userid'=>$user->id));
// Create a report instance
// Create a report instance.
$report = new gradereport_user\report\user($course->id, $gpr, $context, $user->id, $viewasuser);
// print the page
echo '<div class="grade-report-user">'; // css fix to share styles with real report page
// Print the page.
// A css fix to share styles with real report page.
echo '<div class="grade-report-user">';
if ($report->fill_table()) {
echo $report->print_table(true);
}
@ -182,13 +196,12 @@ function grade_report_user_profilereport($course, $user, $viewasuser = false) {
/**
* Add nodes to myprofile page.
*
* @param \core_user\output\myprofile\tree $tree Tree object
* @param tree $tree Tree object
* @param stdClass $user user object
* @param bool $iscurrentuser
* @param stdClass $course Course object
* @param null|stdClass $course Course object
*/
function gradereport_user_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) {
global $CFG, $USER;
function gradereport_user_myprofile_navigation(tree $tree, stdClass $user, bool $iscurrentuser, ?stdClass $course) {
if (empty($course)) {
// We want to display these reports under the site context.
$course = get_fast_modinfo(SITEID)->get_course();