mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 05:58:34 +01:00
completion: MDL-2631 Improve queries, reports and fix problems checking for tracked users
This commit is contained in:
parent
465a9b4f06
commit
24a3b34131
@ -62,9 +62,7 @@ class block_completionstatus extends block_base {
|
||||
}
|
||||
|
||||
// Check this user is enroled
|
||||
$users = $info->internal_get_tracked_users(true);
|
||||
if (!in_array($USER->id, array_keys($users))) {
|
||||
|
||||
if (!$info->is_tracked_user($USER->id)) {
|
||||
// If not enrolled, but are can view the report:
|
||||
if (has_capability('coursereport/completion:view', get_context_instance(CONTEXT_COURSE, $COURSE->id))) {
|
||||
$this->content->text = '<a href="'.$CFG->wwwroot.'/course/report/completion/index.php?course='.$COURSE->id.
|
||||
|
@ -93,8 +93,7 @@ if (empty($completions)) {
|
||||
}
|
||||
|
||||
// Check this user is enroled
|
||||
$users = $info->internal_get_tracked_users(true);
|
||||
if (!in_array($user->id, array_keys($users))) {
|
||||
if (!$info->is_tracked_user($user->id)) {
|
||||
error(get_string('notenroled', 'completion'));
|
||||
}
|
||||
|
||||
|
@ -72,8 +72,7 @@ class block_selfcompletion extends block_base {
|
||||
}
|
||||
|
||||
// Check this user is enroled
|
||||
$users = $info->internal_get_tracked_users(true);
|
||||
if (!in_array($USER->id, array_keys($users))) {
|
||||
if (!$info->is_tracked_user($USER->id)) {
|
||||
$this->content->text = get_string('notenroled', 'completion');
|
||||
return $this->content;
|
||||
}
|
||||
|
@ -54,8 +54,10 @@ $firstnamesort = ($sort == 'firstname');
|
||||
$excel = ($format == 'excelcsv');
|
||||
$csv = ($format == 'csv' || $excel);
|
||||
|
||||
// Whether to start at a particular position
|
||||
$start = optional_param('start',0,PARAM_INT);
|
||||
// Paging
|
||||
$start = optional_param('start', 0, PARAM_INT);
|
||||
$sifirst = optional_param('sifirst', 'all', PARAM_ALPHA);
|
||||
$silast = optional_param('silast', 'all', PARAM_ALPHA);
|
||||
|
||||
// Whether to show idnumber
|
||||
$idnumbers = $CFG->grade_report_showuseridnumber;
|
||||
@ -137,13 +139,6 @@ if (!$csv) {
|
||||
}
|
||||
}
|
||||
|
||||
// Get user data
|
||||
$progress = $completion->get_progress_all(
|
||||
$firstnamesort, $group,
|
||||
$csv ? 0 : COMPLETION_REPORT_PAGE,
|
||||
$csv ? 0 : $start);
|
||||
|
||||
|
||||
/**
|
||||
* Setup page header
|
||||
*/
|
||||
@ -168,7 +163,7 @@ if ($csv) {
|
||||
|
||||
$PAGE->set_title($strcompletion);
|
||||
$PAGE->set_heading($course->fullname);
|
||||
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
$PAGE->requires->yui2_lib(
|
||||
@ -183,36 +178,122 @@ if ($csv) {
|
||||
$PAGE->requires->js('/course/report/completion/textrotate.js');
|
||||
|
||||
// Handle groups (if enabled)
|
||||
groups_print_course_menu($course, $CFG->wwwroot.'/course/report/progress/?course='.$course->id);
|
||||
groups_print_course_menu($course, $CFG->wwwroot.'/course/report/completion/?course='.$course->id);
|
||||
}
|
||||
|
||||
|
||||
// Generate where clause
|
||||
$where = array();
|
||||
$ilike = $DB->sql_ilike();
|
||||
|
||||
if ($sifirst !== 'all') {
|
||||
$where[] = "u.firstname $ilike '$sifirst%'";
|
||||
}
|
||||
|
||||
if ($silast !== 'all') {
|
||||
$where[] = "u.lastname $ilike '$silast%'";
|
||||
}
|
||||
|
||||
// Get user match count
|
||||
$total = $completion->get_num_tracked_users(implode(' AND ', $where), $group);
|
||||
|
||||
// Total user count
|
||||
$grandtotal = $completion->get_num_tracked_users('', $group);
|
||||
|
||||
// If no users in this course what-so-ever
|
||||
if (!$grandtotal) {
|
||||
echo $OUTPUT->container(get_string('err_nousers', 'completion'), 'errorbox errorboxcontent');
|
||||
echo $OUTPUT->footer();
|
||||
exit;
|
||||
}
|
||||
|
||||
// Get user data
|
||||
$progress = array();
|
||||
|
||||
if ($total) {
|
||||
$progress = $completion->get_progress_all(
|
||||
implode(' AND ', $where),
|
||||
$group,
|
||||
$firstnamesort ? 'u.firstname ASC' : 'u.lastname ASC',
|
||||
$csv ? 0 : COMPLETION_REPORT_PAGE,
|
||||
$csv ? 0 : $start
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Build link for paging
|
||||
$link = $CFG->wwwroot.'/course/report/completion/?course='.$course->id;
|
||||
if (strlen($sort)) {
|
||||
$link .= '&sort='.$sort;
|
||||
}
|
||||
$link .= '&start=';
|
||||
|
||||
// Build the the page by Initial bar
|
||||
$initials = array('first', 'last');
|
||||
$alphabet = explode(',', get_string('alphabet', 'langconfig'));
|
||||
|
||||
$pagingbar = '';
|
||||
foreach ($initials as $initial) {
|
||||
$var = 'si'.$initial;
|
||||
|
||||
$pagingbar .= ' <div class="initialbar '.$initial.'initial">';
|
||||
$pagingbar .= get_string($initial.'name').': ';
|
||||
|
||||
if ($$var == 'all') {
|
||||
$pagingbar .= '<strong>'.get_string('all').'</strong> ';
|
||||
}
|
||||
else {
|
||||
$pagingbar .= '<a href="'.$link.'">'.get_string('all').'</a> ';
|
||||
}
|
||||
|
||||
foreach ($alphabet as $letter) {
|
||||
if ($$var === $letter) {
|
||||
$pagingbar .= '<strong>'.$letter.'</strong> ';
|
||||
}
|
||||
else {
|
||||
$pagingbar .= '<a href="'.$link.'&'.$var.'='.$letter.'">'.$letter.'</a> ';
|
||||
}
|
||||
}
|
||||
|
||||
$pagingbar .= '</div>';
|
||||
}
|
||||
|
||||
// Do we need a paging bar?
|
||||
if($progress->total > COMPLETION_REPORT_PAGE) {
|
||||
$pagingbar='<div class="completion_pagingbar">';
|
||||
if($total > COMPLETION_REPORT_PAGE) {
|
||||
|
||||
if($start>0) {
|
||||
$newstart=$start-COMPLETION_REPORT_PAGE;
|
||||
if($newstart<0) {
|
||||
$newstart=0;
|
||||
// Paging bar
|
||||
$pagingbar .= '<div class="paging">';
|
||||
$pagingbar .= get_string('page').': ';
|
||||
|
||||
// Display previous link
|
||||
if ($start > 0) {
|
||||
$pstart = max($start - COMPLETION_REPORT_PAGE, 0);
|
||||
$pagingbar .= '(<a class="previous" href="'.$link.$pstart.'">'.get_string('previous').'</a>) ';
|
||||
}
|
||||
|
||||
// Create page links
|
||||
$curstart = 0;
|
||||
$curpage = 0;
|
||||
while ($curstart < $total) {
|
||||
$curpage++;
|
||||
|
||||
if ($curstart == $start) {
|
||||
$pagingbar .= ' '.$curpage.' ';
|
||||
}
|
||||
$pagingbar.=link_arrow_left(get_string('previous'),'./?course='.$course->id.
|
||||
($newstart ? '&start='.$newstart : ''),false,'completion_prev');
|
||||
else {
|
||||
$pagingbar .= ' <a href="'.$link.$curstart.'">'.$curpage.'</a> ';
|
||||
}
|
||||
|
||||
$curstart += COMPLETION_REPORT_PAGE;
|
||||
}
|
||||
|
||||
$a=new StdClass;
|
||||
$a->from=$start+1;
|
||||
$a->to=$start+COMPLETION_REPORT_PAGE;
|
||||
$a->total=$progress->total;
|
||||
$pagingbar.='<p>'.get_string('reportpage','completion',$a).'</p>';
|
||||
|
||||
if($start+COMPLETION_REPORT_PAGE < $progress->total) {
|
||||
$pagingbar.=link_arrow_right(get_string('next'),'./?course='.$course->id.
|
||||
'&start='.($start+COMPLETION_REPORT_PAGE),false,'completion_next');
|
||||
// Display next link
|
||||
$nstart = $start + COMPLETION_REPORT_PAGE;
|
||||
if ($nstart < $total) {
|
||||
$pagingbar .= ' (<a class="next" href="'.$link.$nstart.'">'.get_string('next').'</a>)';
|
||||
}
|
||||
|
||||
$pagingbar.='</div>';
|
||||
} else {
|
||||
$pagingbar='';
|
||||
$pagingbar .= '</div>';
|
||||
}
|
||||
|
||||
|
||||
@ -224,16 +305,17 @@ if($progress->total > COMPLETION_REPORT_PAGE) {
|
||||
if(!$csv) {
|
||||
print '<br class="clearer"/>'; // ugh
|
||||
|
||||
if(count($progress->users)==0) {
|
||||
echo $OUTPUT->box_start('errorbox errorboxcontent boxaligncenter boxwidthnormal');
|
||||
print '<p class="nousers">'.get_string('err_nousers','completion').'</p>';
|
||||
print '<p><a href="'.$CFG->wwwroot.'/course/report.php?id='.$course->id.'">'.get_string('continue').'</a></p>';
|
||||
echo $OUTPUT->box_end();
|
||||
echo $OUTPUT->footer($course);
|
||||
$total_header = ($total == $grandtotal) ? $total : "{$total}/{$grandtotal}";
|
||||
echo $OUTPUT->heading(get_string('allparticipants').": {$total_header}", 3);
|
||||
|
||||
print $pagingbar;
|
||||
|
||||
if (!$total) {
|
||||
echo $OUTPUT->heading(get_string('nothingtodisplay'), 2);
|
||||
echo $OUTPUT->footer();
|
||||
exit;
|
||||
}
|
||||
|
||||
print $pagingbar;
|
||||
print '<table id="completion-progress" class="generaltable flexible boxaligncenter completionreport" style="text-align: left" cellpadding="5" border="1">';
|
||||
|
||||
// Print criteria group names
|
||||
@ -447,7 +529,7 @@ if(!$csv) {
|
||||
///
|
||||
/// Display a row for each user
|
||||
///
|
||||
foreach($progress->users as $user) {
|
||||
foreach ($progress as $user) {
|
||||
|
||||
// User name
|
||||
if($csv) {
|
||||
|
@ -2,7 +2,7 @@
|
||||
require_once('../../../config.php');
|
||||
require_once($CFG->libdir . '/completionlib.php');
|
||||
|
||||
define('COMPLETION_REPORT_PAGE',50);
|
||||
define('COMPLETION_REPORT_PAGE', 25);
|
||||
|
||||
// Get course
|
||||
$id = required_param('course',PARAM_INT);
|
||||
@ -12,22 +12,25 @@ if(!$course) {
|
||||
}
|
||||
|
||||
// Sort (default lastname, optionally firstname)
|
||||
$sort=optional_param('sort','',PARAM_ALPHA);
|
||||
$firstnamesort=$sort=='firstname';
|
||||
$sort = optional_param('sort','',PARAM_ALPHA);
|
||||
$firstnamesort = $sort == 'firstname';
|
||||
|
||||
// CSV format
|
||||
$format=optional_param('format','',PARAM_ALPHA);
|
||||
$excel=$format=='excelcsv';
|
||||
$csv=$format=='csv' || $excel;
|
||||
$format = optional_param('format','',PARAM_ALPHA);
|
||||
$excel = $format == 'excelcsv';
|
||||
$csv = $format == 'csv' || $excel;
|
||||
|
||||
// Whether to start at a particular position
|
||||
$start=optional_param('start',0,PARAM_INT);
|
||||
// Paging
|
||||
$start = optional_param('start', 0, PARAM_INT);
|
||||
$sifirst = optional_param('sifirst', 'all', PARAM_ALPHA);
|
||||
$silast = optional_param('silast', 'all', PARAM_ALPHA);
|
||||
$start = optional_param('start',0,PARAM_INT);
|
||||
|
||||
// Whether to show idnumber
|
||||
// TODO: This should really not be using a config option 'intended' for
|
||||
// gradebook, but that option is also used in quiz reports as well. There ought
|
||||
// to be a generic option somewhere.
|
||||
$idnumbers=$CFG->grade_report_showuseridnumber;
|
||||
$idnumbers = $CFG->grade_report_showuseridnumber;
|
||||
|
||||
function csv_quote($value) {
|
||||
global $excel;
|
||||
@ -73,8 +76,46 @@ if(count($activities)==0) {
|
||||
print_error('err_noactivities','completion',$reportsurl);
|
||||
}
|
||||
|
||||
$progress=$completion->get_progress_all($firstnamesort,$group,
|
||||
$csv ? 0 :COMPLETION_REPORT_PAGE,$csv ? 0 : $start);
|
||||
// Generate where clause
|
||||
$where = array();
|
||||
$ilike = $DB->sql_ilike();
|
||||
|
||||
if ($sifirst !== 'all') {
|
||||
$where[] = "u.firstname $ilike '$sifirst%'";
|
||||
}
|
||||
|
||||
if ($silast !== 'all') {
|
||||
$where[] = "u.lastname $ilike '$silast%'";
|
||||
}
|
||||
|
||||
// Get user match count
|
||||
$total = $completion->get_num_tracked_users(implode(' AND ', $where), $group);
|
||||
|
||||
// Total user count
|
||||
$grandtotal = $completion->get_num_tracked_users('', $group);
|
||||
|
||||
// If no users in this course what-so-ever
|
||||
if (!$grandtotal) {
|
||||
print_box_start('errorbox errorboxcontent boxaligncenter boxwidthnormal');
|
||||
print '<p class="nousers">'.get_string('err_nousers','completion').'</p>';
|
||||
print '<p><a href="'.$CFG->wwwroot.'/course/report.php?id='.$course->id.'">'.get_string('continue').'</a></p>';
|
||||
print_box_end();
|
||||
print_footer($course);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Get user data
|
||||
$progress = array();
|
||||
|
||||
if ($total) {
|
||||
$progress = $completion->get_progress_all(
|
||||
implode(' AND ', $where),
|
||||
$group,
|
||||
$firstnamesort ? 'u.firstname ASC' : 'u.lastname ASC',
|
||||
$csv ? 0 : COMPLETION_REPORT_PAGE,
|
||||
$csv ? 0 : $start
|
||||
);
|
||||
}
|
||||
|
||||
if($csv) {
|
||||
header('Content-Disposition: attachment; filename=progress.'.
|
||||
@ -111,33 +152,79 @@ if($csv) {
|
||||
groups_print_course_menu($course,$CFG->wwwroot.'/course/report/progress/?course='.$course->id);
|
||||
}
|
||||
|
||||
// Do we need a paging bar?
|
||||
if($progress->total > COMPLETION_REPORT_PAGE) {
|
||||
$pagingbar='<div class="completion_pagingbar">';
|
||||
// Build link for paging
|
||||
$link = $CFG->wwwroot.'/course/report/progress/?course='.$course->id;
|
||||
if (strlen($sort)) {
|
||||
$link .= '&sort='.$sort;
|
||||
}
|
||||
$link .= '&start=';
|
||||
|
||||
if($start>0) {
|
||||
$newstart=$start-COMPLETION_REPORT_PAGE;
|
||||
if($newstart<0) {
|
||||
$newstart=0;
|
||||
// Build the the page by Initial bar
|
||||
$initials = array('first', 'last');
|
||||
$alphabet = explode(',', get_string('alphabet', 'langconfig'));
|
||||
|
||||
$pagingbar = '';
|
||||
foreach ($initials as $initial) {
|
||||
$var = 'si'.$initial;
|
||||
|
||||
$pagingbar .= ' <div class="initialbar '.$initial.'initial">';
|
||||
$pagingbar .= get_string($initial.'name').': ';
|
||||
|
||||
if ($$var == 'all') {
|
||||
$pagingbar .= '<strong>'.get_string('all').'</strong> ';
|
||||
}
|
||||
else {
|
||||
$pagingbar .= '<a href="'.$link.'">'.get_string('all').'</a> ';
|
||||
}
|
||||
|
||||
foreach ($alphabet as $letter) {
|
||||
if ($$var === $letter) {
|
||||
$pagingbar .= '<strong>'.$letter.'</strong> ';
|
||||
}
|
||||
else {
|
||||
$pagingbar .= '<a href="'.$link.'&'.$var.'='.$letter.'">'.$letter.'</a> ';
|
||||
}
|
||||
$pagingbar.=link_arrow_left(get_string('previous'),'./?course='.$course->id.
|
||||
($newstart ? '&start='.$newstart : ''),false,'completion_prev');
|
||||
}
|
||||
|
||||
$a=new StdClass;
|
||||
$a->from=$start+1;
|
||||
$a->to=$start+COMPLETION_REPORT_PAGE;
|
||||
$a->total=$progress->total;
|
||||
$pagingbar.='<p>'.get_string('reportpage','completion',$a).'</p>';
|
||||
$pagingbar .= '</div>';
|
||||
}
|
||||
|
||||
if($start+COMPLETION_REPORT_PAGE < $progress->total) {
|
||||
$pagingbar.=link_arrow_right(get_string('next'),'./?course='.$course->id.
|
||||
'&start='.($start+COMPLETION_REPORT_PAGE),false,'completion_next');
|
||||
// Do we need a paging bar?
|
||||
if($total > COMPLETION_REPORT_PAGE) {
|
||||
|
||||
// Paging bar
|
||||
$pagingbar .= '<div class="paging">';
|
||||
$pagingbar .= get_string('page').': ';
|
||||
|
||||
// Display previous link
|
||||
if ($start > 0) {
|
||||
$pstart = max($start - COMPLETION_REPORT_PAGE, 0);
|
||||
$pagingbar .= '(<a class="previous" href="'.$link.$pstart.'">'.get_string('previous').'</a>) ';
|
||||
}
|
||||
|
||||
$pagingbar.='</div>';
|
||||
} else {
|
||||
$pagingbar='';
|
||||
// Create page links
|
||||
$curstart = 0;
|
||||
$curpage = 0;
|
||||
while ($curstart < $total) {
|
||||
$curpage++;
|
||||
|
||||
if ($curstart == $start) {
|
||||
$pagingbar .= ' '.$curpage.' ';
|
||||
}
|
||||
else {
|
||||
$pagingbar .= ' <a href="'.$link.$curstart.'">'.$curpage.'</a> ';
|
||||
}
|
||||
|
||||
$curstart += COMPLETION_REPORT_PAGE;
|
||||
}
|
||||
|
||||
// Display next link
|
||||
$nstart = $start + COMPLETION_REPORT_PAGE;
|
||||
if ($nstart < $total) {
|
||||
$pagingbar .= ' (<a class="next" href="'.$link.$nstart.'">'.get_string('next').'</a>)';
|
||||
}
|
||||
|
||||
$pagingbar .= '</div>';
|
||||
}
|
||||
|
||||
// Okay, let's draw the table of progress info,
|
||||
@ -145,13 +232,15 @@ if($progress->total > COMPLETION_REPORT_PAGE) {
|
||||
// Start of table
|
||||
if(!$csv) {
|
||||
print '<br class="clearer"/>'; // ugh
|
||||
if(count($progress->users)==0) {
|
||||
print '<p class="nousers">'.get_string('err_nousers','completion').'</p>';
|
||||
print '<p><a href="'.$reportsurl.'">'.get_string('continue').'</a></p>';
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
print $pagingbar;
|
||||
|
||||
if (!$total) {
|
||||
print_heading(get_string('nothingtodisplay'));
|
||||
print_footer($course);
|
||||
exit;
|
||||
}
|
||||
print $pagingbar;
|
||||
|
||||
print '<table id="completion-progress" class="generaltable flexible boxaligncenter" style="text-align:left"><tr style="vertical-align:top">';
|
||||
|
||||
// User heading / sort option
|
||||
@ -214,7 +303,7 @@ if($csv) {
|
||||
}
|
||||
|
||||
// Row for each user
|
||||
foreach($progress->users as $user) {
|
||||
foreach($progress as $user) {
|
||||
// User name
|
||||
if($csv) {
|
||||
print csv_quote(fullname($user));
|
||||
|
@ -57,6 +57,13 @@ function completion_cron_mark_started() {
|
||||
mtrace('Marking users as started');
|
||||
}
|
||||
|
||||
if (!empty($CFG->progresstrackedroles)) {
|
||||
$roles = ' AND ra.roleid IN ('.$CFG->progresstrackedroles.')';
|
||||
} else {
|
||||
// This causes it to default to everyone (if there is no student role)
|
||||
$roles = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* A quick explaination of this horrible looking query
|
||||
*
|
||||
@ -77,8 +84,8 @@ function completion_cron_mark_started() {
|
||||
c.id AS course,
|
||||
u.id AS userid,
|
||||
crc.id AS completionid,
|
||||
ue.timestart,
|
||||
ue.timecreated AS timeenrolled
|
||||
ue.timestart AS timeenrolled,
|
||||
ue.timecreated
|
||||
FROM
|
||||
{user} u
|
||||
INNER JOIN
|
||||
@ -90,6 +97,9 @@ function completion_cron_mark_started() {
|
||||
INNER JOIN
|
||||
{course} c
|
||||
ON c.id = e.courseid
|
||||
INNER JOIN
|
||||
{role_assignments} ra
|
||||
ON ra.userid = u.id
|
||||
LEFT JOIN
|
||||
{course_completions} crc
|
||||
ON crc.course = c.id
|
||||
@ -102,8 +112,7 @@ function completion_cron_mark_started() {
|
||||
AND u.deleted = 0
|
||||
AND ue.timestart < ?
|
||||
AND (ue.timeend > ? OR ue.timeend = 0)
|
||||
AND ue.timecreated < ?
|
||||
AND (ue.timecreated > ? OR ue.timecreated = 0)
|
||||
$roles
|
||||
ORDER BY
|
||||
course,
|
||||
userid
|
||||
@ -140,7 +149,7 @@ function completion_cron_mark_started() {
|
||||
else {
|
||||
// Not all enrol plugins fill out timestart correctly, so use whichever
|
||||
// is non-zero
|
||||
$current->timeenrolled = max($current->timestart, $current->timeenrolled);
|
||||
$current->timeenrolled = max($current->timecreated, $current->timeenrolled);
|
||||
}
|
||||
|
||||
// If we are at the last record,
|
||||
@ -154,6 +163,7 @@ function completion_cron_mark_started() {
|
||||
$completion->course = $prev->course;
|
||||
$completion->timeenrolled = (string) $prev->timeenrolled;
|
||||
$completion->timestarted = 0;
|
||||
$completion->reaggregate = time();
|
||||
|
||||
if ($prev->completionid) {
|
||||
$completion->id = $prev->completionid;
|
||||
@ -232,7 +242,7 @@ function completion_cron_completions() {
|
||||
SELECT DISTINCT
|
||||
c.id AS course,
|
||||
cr.id AS criteriaid,
|
||||
cc.userid AS userid,
|
||||
crc.userid AS userid,
|
||||
cr.criteriatype AS criteriatype,
|
||||
cc.timecompleted AS timecompleted
|
||||
FROM
|
||||
@ -251,13 +261,14 @@ function completion_cron_completions() {
|
||||
c.enablecompletion = 1
|
||||
AND crc.timecompleted IS NULL
|
||||
AND crc.reaggregate > 0
|
||||
AND crc.reaggregate < :timestarted
|
||||
ORDER BY
|
||||
course,
|
||||
userid
|
||||
';
|
||||
|
||||
// Check if result is empty
|
||||
if (!$rs = $DB->get_recordset_sql($sql)) {
|
||||
if (!$rs = $DB->get_recordset_sql($sql, array('timestarted' => $timestarted))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -758,7 +758,7 @@ class completion_info {
|
||||
$this->delete_all_state($cm);
|
||||
|
||||
// Merge this with list of planned users (according to roles)
|
||||
$trackedusers = $this->internal_get_tracked_users(false);
|
||||
$trackedusers = $this->get_tracked_users();
|
||||
foreach ($trackedusers as $trackeduser) {
|
||||
$keepusers[] = $trackeduser->id;
|
||||
}
|
||||
@ -962,31 +962,154 @@ class completion_info {
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets list of users in a course whose progress is tracked for display on the
|
||||
* progress report.
|
||||
* Checks to see if the userid supplied has a tracked role in
|
||||
* this course
|
||||
*
|
||||
* @global object
|
||||
* @global object
|
||||
* @uses CONTEXT_COURSE
|
||||
* @param bool $sortfirstname Optional True to sort with firstname
|
||||
* @param int $groupid Optionally restrict to groupid
|
||||
* @return array Array of user objects containing id, firstname, lastname (empty if none)
|
||||
* @param $userid User id
|
||||
* @return bool
|
||||
*/
|
||||
function internal_get_tracked_users($sortfirstname = false, $groupid = 0) {
|
||||
global $CFG, $DB;
|
||||
function is_tracked_user($userid) {
|
||||
global $DB;
|
||||
|
||||
$sql = "SELECT u.id ";
|
||||
$sql .= $this->generate_tracked_user_sql();
|
||||
$sql .= ' AND u.id = :user';
|
||||
return $DB->record_exists_sql($sql, array('user' => (int)$userid));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return number of users whose progress is tracked in this course
|
||||
*
|
||||
* Optionally supply a search's where clause, or a group id
|
||||
*
|
||||
* @param string $where Where clause
|
||||
* @param int $groupid Group id
|
||||
* @return int
|
||||
*/
|
||||
function get_num_tracked_users($where = '', $groupid = 0) {
|
||||
global $DB;
|
||||
|
||||
$sql = "SELECT COUNT(u.id) ";
|
||||
$sql .= $this->generate_tracked_user_sql($groupid);
|
||||
|
||||
if ($where) {
|
||||
$sql .= " AND $where";
|
||||
}
|
||||
|
||||
return $DB->count_records_sql($sql);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return array of users whose progress is tracked in this course
|
||||
*
|
||||
* Optionally supply a search's where caluse, group id, sorting, paging
|
||||
*
|
||||
* @param string $where Where clause (optional)
|
||||
* @param integer $groupid Group ID to restrict to (optional)
|
||||
* @param string $sort Order by clause (optional)
|
||||
* @param integer $limitfrom Result start (optional)
|
||||
* @param integer $limitnum Result max size (optional)
|
||||
* @return array
|
||||
*/
|
||||
function get_tracked_users($where = '', $groupid = 0, $sort = '',
|
||||
$limitfrom = '', $limitnum = '') {
|
||||
|
||||
global $DB;
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
u.id,
|
||||
u.firstname,
|
||||
u.lastname,
|
||||
u.idnumber
|
||||
";
|
||||
|
||||
$sql .= $this->generate_tracked_user_sql($groupid);
|
||||
|
||||
if ($where) {
|
||||
$sql .= " AND $where";
|
||||
}
|
||||
|
||||
if ($sort) {
|
||||
$sql .= " ORDER BY $sort";
|
||||
}
|
||||
|
||||
$users = $DB->get_records_sql($sql, null, $limitfrom, $limitnum);
|
||||
return $users ? $users : array(); // In case it returns false
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate the SQL for finding tracked users in this course
|
||||
*
|
||||
* Optionally supply a group id
|
||||
*
|
||||
* @param integer $groupid
|
||||
* @return string
|
||||
*/
|
||||
function generate_tracked_user_sql($groupid = 0) {
|
||||
global $CFG;
|
||||
|
||||
if (!empty($CFG->progresstrackedroles)) {
|
||||
$roles = explode(', ', $CFG->progresstrackedroles);
|
||||
$roles = ' AND ra.roleid IN ('.$CFG->progresstrackedroles.')';
|
||||
} else {
|
||||
// This causes it to default to everyone (if there is no student role)
|
||||
$roles = array();
|
||||
$roles = '';
|
||||
}
|
||||
$users = get_role_users($roles, get_context_instance(CONTEXT_COURSE, $this->course->id), true,
|
||||
'u.id, u.firstname, u.lastname, u.idnumber',
|
||||
$sortfirstname ? 'u.firstname ASC' : 'u.lastname ASC', true, $groupid);
|
||||
$users = $users ? $users : array(); // In case it returns false
|
||||
return $users;
|
||||
|
||||
// Build context sql
|
||||
$context = get_context_instance(CONTEXT_COURSE, $this->course->id);
|
||||
$parentcontexts = substr($context->path, 1); // kill leading slash
|
||||
$parentcontexts = str_replace('/', ',', $parentcontexts);
|
||||
if ($parentcontexts !== '') {
|
||||
$parentcontexts = ' OR ra.contextid IN ('.$parentcontexts.' )';
|
||||
}
|
||||
|
||||
$groupjoin = '';
|
||||
$groupselect = '';
|
||||
if ($groupid) {
|
||||
$groupjoin = "JOIN {groups_members} gm
|
||||
ON gm.userid = u.id";
|
||||
$groupselect = " AND gm.groupid = $groupid ";
|
||||
}
|
||||
|
||||
$now = time();
|
||||
|
||||
$sql = "
|
||||
FROM
|
||||
{user} u
|
||||
INNER JOIN
|
||||
{role_assignments} ra
|
||||
ON ra.userid = u.id
|
||||
INNER JOIN
|
||||
{role} r
|
||||
ON r.id = ra.roleid
|
||||
INNER JOIN
|
||||
{user_enrolments} ue
|
||||
ON ue.userid = u.id
|
||||
INNER JOIN
|
||||
{enrol} e
|
||||
ON e.id = ue.enrolid
|
||||
INNER JOIN
|
||||
{course} c
|
||||
ON c.id = e.courseid
|
||||
$groupjoin
|
||||
WHERE
|
||||
(ra.contextid = {$context->id} $parentcontexts)
|
||||
AND c.id = {$this->course->id}
|
||||
AND ue.status = 0
|
||||
AND e.status = 0
|
||||
AND ue.timestart < $now
|
||||
AND (ue.timeend > $now OR ue.timeend = 0)
|
||||
$groupselect
|
||||
$roles
|
||||
";
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1004,31 +1127,26 @@ class completion_info {
|
||||
* @param bool $sortfirstname If true, sort by first name, otherwise sort by
|
||||
* last name
|
||||
* @param int $groupid Group ID or 0 (default)/false for all groups
|
||||
* @param int $pagesize Number of users to actually return (0 = unlimited)
|
||||
* @param int $start User to start at if paging (0 = first set)
|
||||
* @param int $pagesize Number of users to actually return (optional)
|
||||
* @param int $start User to start at if paging (optional)
|
||||
* @return Object with ->total and ->start (same as $start) and ->users;
|
||||
* an array of user objects (like mdl_user id, firstname, lastname)
|
||||
* containing an additional ->progress array of coursemoduleid => completionstate
|
||||
*/
|
||||
public function get_progress_all($sortfirstname=false, $groupid=0,
|
||||
$pagesize=0,$start=0) {
|
||||
public function get_progress_all($where = '', $groupid = 0, $sort = '', $pagesize = '', $start = '') {
|
||||
global $CFG, $DB;
|
||||
$resultobject=new StdClass;
|
||||
|
||||
// Get list of applicable users
|
||||
$users = $this->internal_get_tracked_users($sortfirstname, $groupid);
|
||||
$resultobject->start=$start;
|
||||
$resultobject->total=count($users);
|
||||
$users=array_slice($users,$start,$pagesize==0 ? count($users)-$start : $pagesize);
|
||||
$users = $this->get_tracked_users($where, $groupid, $sort, $start, $pagesize);
|
||||
|
||||
// Get progress information for these users in groups of 1, 000 (if needed)
|
||||
// to avoid making the SQL IN too long
|
||||
$resultobject->users=array();
|
||||
$results = array();
|
||||
$userids = array();
|
||||
foreach ($users as $user) {
|
||||
$userids[] = $user->id;
|
||||
$resultobject->users[$user->id]=$user;
|
||||
$resultobject->users[$user->id]->progress=array();
|
||||
$results[$user->id] = $user;
|
||||
$results[$user->id]->progress = array();
|
||||
}
|
||||
|
||||
for($i=0; $i<count($userids); $i+=1000) {
|
||||
@ -1037,21 +1155,22 @@ class completion_info {
|
||||
list($insql, $params) = $DB->get_in_or_equal(array_slice($userids, $i, $blocksize));
|
||||
array_splice($params, 0, 0, array($this->course->id));
|
||||
$rs = $DB->get_recordset_sql("
|
||||
SELECT
|
||||
cmc.*
|
||||
FROM
|
||||
{course_modules} cm
|
||||
INNER JOIN {course_modules_completion} cmc ON cm.id=cmc.coursemoduleid
|
||||
WHERE
|
||||
cm.course=? AND cmc.userid $insql
|
||||
SELECT
|
||||
cmc.*
|
||||
FROM
|
||||
{course_modules} cm
|
||||
INNER JOIN {course_modules_completion} cmc ON cm.id=cmc.coursemoduleid
|
||||
WHERE
|
||||
cm.course=? AND cmc.userid $insql
|
||||
", $params);
|
||||
foreach ($rs as $progress) {
|
||||
$resultobject->users[$progress->userid]->progress[$progress->coursemoduleid]=$progress;
|
||||
$progress = (object)$progress;
|
||||
$results[$progress->userid]->progress[$progress->coursemoduleid] = $progress;
|
||||
}
|
||||
$rs->close();
|
||||
}
|
||||
|
||||
return $resultobject;
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user