Problem: Too many paging links and incorrect participant count in courses that have multiple enrol records returned per user. (Crosslisted courses in our case sometimes return 3 records per user, tripling the count).
Cause: The function query_db() in /classes/table/overview.php that uses the parent::query_db() function from /moodle/lib/tablelib.php and relies on an sql of 'SELECT COUNT(1)' for returning how many rows to return.
Solution: In my case, I used the existing plugin function for query_db(), removing the if (array_keys($sortcols)[0] === 'progress') from the top of the function, and putting in around other appropriate parts. (As shown below) I didn't re-arrange anything so as to keep the changes to a minimum.
public function query_db($pagesize, $useinitialsbar=true) {
global $DB;
$sortcols = $this->get_sort_columns();
// Kludge to sort by the runtime-computed percentage column.
if ($useinitialsbar && !$this->is_downloading()) {
$this->initialbars(true);
}
list($wsql, $wparams) = $this->get_sql_where();
if ($wsql) {
$this->sql->where .= ' AND '.$wsql;
$this->sql->params = array_merge($this->sql->params, $wparams);
}
if (($sort = $this->get_sql_sort())) {
$sort = "ORDER BY $sort";
}
$sql = "SELECT {$this->sql->fields}
FROM {$this->sql->from}
WHERE {$this->sql->where}
{$sort}";
$rawdata = $DB->get_recordset_sql($sql, $this->sql->params);
// Compute the percentage for each record and sort.
$data = [];
$percents = [];
foreach ($rawdata as $key => $row) {
$this->progress->for_user($row);
$percents[$key] = $this->progress->get_percentage() ?? -1;
$data[$key] = $row;
}
if (array_keys($sortcols)[0] === 'progress') {
$sortfunc = $sortcols['progress'] === SORT_ASC ? 'asort' : 'arsort';
$sortfunc($percents);
}
$rawdata->close();
if (!$this->is_downloading()) {
$pagestart = $this->currpage * $pagesize;
$percents = array_slice($percents, $pagestart, $pagesize, true);
$this->pagesize($pagesize, count($data));
}
if (array_keys($sortcols)[0] === 'progress') {
$this->rawdata = [];
foreach (array_keys($percents) as $key) {
$this->rawdata[] = $data[$key];
}
} else if (!$this->is_downloading()) {
$this->rawdata = $DB->get_records_sql($sql, $this->sql->params, $this->get_page_start(), $this->get_page_size());
} else {
$this->rawdata = $DB->get_records_sql($sql, $this->sql->params);
}
return;
}
Problem: Too many paging links and incorrect participant count in courses that have multiple enrol records returned per user. (Crosslisted courses in our case sometimes return 3 records per user, tripling the count).
Cause: The function query_db() in /classes/table/overview.php that uses the parent::query_db() function from /moodle/lib/tablelib.php and relies on an sql of 'SELECT COUNT(1)' for returning how many rows to return.
Solution: In my case, I used the existing plugin function for query_db(), removing the if (array_keys($sortcols)[0] === 'progress') from the top of the function, and putting in around other appropriate parts. (As shown below) I didn't re-arrange anything so as to keep the changes to a minimum.