MDL-28945 course_reports: Fixed up pagination issue
[moodle.git] / course / report / completion / index.php
CommitLineData
2be4d090
MD
1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18
19/**
20 * Course completion progress report
21 *
22 * @package moodlecore
23 * @copyright 2009 Catalyst IT Ltd
24 * @author Aaron Barnes <aaronb@catalyst.net.nz>
25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 */
27require_once('../../../config.php');
28require_once($CFG->libdir.'/completionlib.php');
29
2be4d090
MD
30/**
31 * Configuration
32 */
33define('COMPLETION_REPORT_PAGE', 25);
34define('COMPLETION_REPORT_COL_TITLES', true);
35
2be4d090
MD
36/**
37 * Setup page, check permissions
38 */
39
40// Get course
e67e026f
SH
41$courseid = required_param('course', PARAM_INT);
42$format = optional_param('format','',PARAM_ALPHA);
43$sort = optional_param('sort','',PARAM_ALPHA);
2be4d090
MD
44$edituser = optional_param('edituser', 0, PARAM_INT);
45
2be4d090 46
e67e026f
SH
47$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
48
49$url = new moodle_url('/course/report/completion/index.php', array('course'=>$course->id));
50$PAGE->set_url($url);
cf5a0dbd 51$PAGE->set_pagelayout('report');
e67e026f
SH
52
53$firstnamesort = ($sort == 'firstname');
54$excel = ($format == 'excelcsv');
55$csv = ($format == 'csv' || $excel);
2be4d090 56
24a3b341
AB
57// Paging
58$start = optional_param('start', 0, PARAM_INT);
59$sifirst = optional_param('sifirst', 'all', PARAM_ALPHA);
60$silast = optional_param('silast', 'all', PARAM_ALPHA);
2be4d090
MD
61
62// Whether to show idnumber
63$idnumbers = $CFG->grade_report_showuseridnumber;
64
65// Function for quoting csv cell values
66function csv_quote($value) {
67 global $excel;
68 if($excel) {
69 $tl=textlib_get_instance();
70 return $tl->convert('"'.str_replace('"',"'",$value).'"','UTF-8','UTF-16LE');
71 } else {
72 return '"'.str_replace('"',"'",$value).'"';
73 }
74}
75
76
77// Check permissions
78require_login($course);
79
80$context=get_context_instance(CONTEXT_COURSE, $course->id);
81require_capability('coursereport/completion:view', $context);
82
83// Get group mode
84$group = groups_get_course_group($course, true); // Supposed to verify group
85if($group === 0 && $course->groupmode == SEPARATEGROUPS) {
86 require_capability('moodle/site:accessallgroups',$context);
87}
88
2be4d090
MD
89/**
90 * Load data
91 */
92
93// Get criteria for course
94$completion = new completion_info($course);
95
96if (!$completion->has_criteria()) {
97 print_error('err_nocriteria', 'completion', $CFG->wwwroot.'/course/report.php?id='.$course->id);
98}
99
100// Get criteria and put in correct order
101$criteria = array();
102
103foreach ($completion->get_criteria(COMPLETION_CRITERIA_TYPE_COURSE) as $criterion) {
104 $criteria[] = $criterion;
105}
106
107foreach ($completion->get_criteria(COMPLETION_CRITERIA_TYPE_ACTIVITY) as $criterion) {
108 $criteria[] = $criterion;
109}
110
111foreach ($completion->get_criteria() as $criterion) {
112 if (!in_array($criterion->criteriatype, array(
113 COMPLETION_CRITERIA_TYPE_COURSE, COMPLETION_CRITERIA_TYPE_ACTIVITY))) {
114 $criteria[] = $criterion;
115 }
116}
117
118// Can logged in user mark users as complete?
119// (if the logged in user has a role defined in the role criteria)
120$allow_marking = false;
121$allow_marking_criteria = null;
122
123if (!$csv) {
124 // Get role criteria
125 $rcriteria = $completion->get_criteria(COMPLETION_CRITERIA_TYPE_ROLE);
126
127 if (!empty($rcriteria)) {
128
129 foreach ($rcriteria as $rcriterion) {
130 $users = get_role_users($rcriterion->role, $context, true);
131
132 // If logged in user has this role, allow marking complete
133 if ($users && in_array($USER->id, array_keys($users))) {
134 $allow_marking = true;
135 $allow_marking_criteria = $rcriterion->id;
136 break;
137 }
138 }
139 }
140}
141
2be4d090
MD
142/**
143 * Setup page header
144 */
145if ($csv) {
8ebbb06a
SH
146 $shortname = format_string($course->shortname, true, array('context' => $context));
147 $textlib = textlib_get_instance();
2be4d090 148 header('Content-Disposition: attachment; filename=progress.'.
8ebbb06a 149 preg_replace('/[^a-z0-9-]/','_',$textlib->strtolower(strip_tags($shortname))).'.csv');
2be4d090
MD
150 // Unicode byte-order mark for Excel
151 if($excel) {
152 header('Content-Type: text/csv; charset=UTF-16LE');
153 print chr(0xFF).chr(0xFE);
154 $sep="\t".chr(0);
155 $line="\n".chr(0);
156 } else {
157 header('Content-Type: text/csv; charset=UTF-8');
158 $sep=",";
159 $line="\n";
160 }
161
162} else {
163 // Navigation and header
cfc33925 164 $strcompletion = get_string('coursecompletion');
2be4d090
MD
165
166 $PAGE->set_title($strcompletion);
167 $PAGE->set_heading($course->fullname);
24a3b341 168
2be4d090
MD
169 echo $OUTPUT->header();
170
171 $PAGE->requires->yui2_lib(
172 array(
173 'yahoo',
174 'dom',
175 'element',
176 'event',
177 )
178 );
179
180 $PAGE->requires->js('/course/report/completion/textrotate.js');
181
182 // Handle groups (if enabled)
24a3b341 183 groups_print_course_menu($course, $CFG->wwwroot.'/course/report/completion/?course='.$course->id);
2be4d090
MD
184}
185
2be4d090 186
24a3b341
AB
187// Generate where clause
188$where = array();
5642a8e5 189$where_params = array();
24a3b341
AB
190
191if ($sifirst !== 'all') {
5642a8e5
AB
192 $where[] = $DB->sql_like('u.firstname', ':sifirst', false);
193 $where_params['sifirst'] = $sifirst.'%';
24a3b341
AB
194}
195
196if ($silast !== 'all') {
5642a8e5
AB
197 $where[] = $DB->sql_like('u.lastname', ':silast', false);
198 $where_params['silast'] = $silast.'%';
24a3b341
AB
199}
200
201// Get user match count
5642a8e5 202$total = $completion->get_num_tracked_users(implode(' AND ', $where), $where_params, $group);
24a3b341
AB
203
204// Total user count
5642a8e5 205$grandtotal = $completion->get_num_tracked_users('', array(), $group);
24a3b341
AB
206
207// If no users in this course what-so-ever
208if (!$grandtotal) {
209 echo $OUTPUT->container(get_string('err_nousers', 'completion'), 'errorbox errorboxcontent');
210 echo $OUTPUT->footer();
211 exit;
212}
213
214// Get user data
215$progress = array();
216
217if ($total) {
218 $progress = $completion->get_progress_all(
219 implode(' AND ', $where),
5642a8e5 220 $where_params,
24a3b341
AB
221 $group,
222 $firstnamesort ? 'u.firstname ASC' : 'u.lastname ASC',
223 $csv ? 0 : COMPLETION_REPORT_PAGE,
224 $csv ? 0 : $start
225 );
226}
227
228
229// Build link for paging
230$link = $CFG->wwwroot.'/course/report/completion/?course='.$course->id;
231if (strlen($sort)) {
232 $link .= '&amp;sort='.$sort;
233}
234$link .= '&amp;start=';
235
236// Build the the page by Initial bar
237$initials = array('first', 'last');
238$alphabet = explode(',', get_string('alphabet', 'langconfig'));
239
240$pagingbar = '';
241foreach ($initials as $initial) {
242 $var = 'si'.$initial;
243
1f186372
TL
244 $othervar = $initial == 'first' ? 'silast' : 'sifirst';
245 $othervar = $$othervar != 'all' ? "&amp;{$othervar}={$$othervar}" : '';
246
24a3b341
AB
247 $pagingbar .= ' <div class="initialbar '.$initial.'initial">';
248 $pagingbar .= get_string($initial.'name').':&nbsp;';
249
250 if ($$var == 'all') {
251 $pagingbar .= '<strong>'.get_string('all').'</strong> ';
252 }
253 else {
1f186372 254 $pagingbar .= "<a href=\"{$link}{$othervar}\">".get_string('all').'</a> ';
24a3b341
AB
255 }
256
257 foreach ($alphabet as $letter) {
258 if ($$var === $letter) {
259 $pagingbar .= '<strong>'.$letter.'</strong> ';
260 }
261 else {
1f186372 262 $pagingbar .= "<a href=\"$link&amp;$var={$letter}{$othervar}\">$letter</a> ";
2be4d090 263 }
2be4d090
MD
264 }
265
24a3b341
AB
266 $pagingbar .= '</div>';
267}
2be4d090 268
24a3b341
AB
269// Do we need a paging bar?
270if($total > COMPLETION_REPORT_PAGE) {
271
272 // Paging bar
273 $pagingbar .= '<div class="paging">';
274 $pagingbar .= get_string('page').': ';
275
1f186372 276 $sistrings = array();
7229f239
SH
277 if ($sifirst != 'all') {
278 $sistrings[] = "sifirst={$sifirst}";
279 }
280 if ($silast != 'all') {
281 $sistrings[] = "silast={$silast}";
282 }
283 $sistring = !empty($sistrings) ? '&amp;'.implode('&amp;', $sistrings) : '';
1f186372 284
24a3b341
AB
285 // Display previous link
286 if ($start > 0) {
287 $pstart = max($start - COMPLETION_REPORT_PAGE, 0);
1f186372 288 $pagingbar .= "(<a class=\"previous\" href=\"{$link}{$pstart}{$sistring}\">".get_string('previous').'</a>)&nbsp;';
2be4d090
MD
289 }
290
24a3b341
AB
291 // Create page links
292 $curstart = 0;
293 $curpage = 0;
294 while ($curstart < $total) {
295 $curpage++;
296
297 if ($curstart == $start) {
298 $pagingbar .= '&nbsp;'.$curpage.'&nbsp;';
299 }
300 else {
1f186372 301 $pagingbar .= "&nbsp;<a href=\"{$link}{$curstart}{$sistring}\">$curpage</a>&nbsp;";
24a3b341
AB
302 }
303
304 $curstart += COMPLETION_REPORT_PAGE;
305 }
306
307 // Display next link
308 $nstart = $start + COMPLETION_REPORT_PAGE;
309 if ($nstart < $total) {
1f186372 310 $pagingbar .= "&nbsp;(<a class=\"next\" href=\"{$link}{$nstart}{$sistring}\">".get_string('next').'</a>)';
24a3b341
AB
311 }
312
313 $pagingbar .= '</div>';
2be4d090
MD
314}
315
316
317/**
318 * Draw table header
319 */
320
321// Start of table
322if(!$csv) {
323 print '<br class="clearer"/>'; // ugh
324
24a3b341
AB
325 $total_header = ($total == $grandtotal) ? $total : "{$total}/{$grandtotal}";
326 echo $OUTPUT->heading(get_string('allparticipants').": {$total_header}", 3);
327
328 print $pagingbar;
329
330 if (!$total) {
331 echo $OUTPUT->heading(get_string('nothingtodisplay'), 2);
332 echo $OUTPUT->footer();
2be4d090
MD
333 exit;
334 }
335
2be4d090
MD
336 print '<table id="completion-progress" class="generaltable flexible boxaligncenter completionreport" style="text-align: left" cellpadding="5" border="1">';
337
338 // Print criteria group names
339 print PHP_EOL.'<tr style="vertical-align: top">';
340 print '<th scope="row" class="rowheader">'.get_string('criteriagroup', 'completion').'</th>';
341
342 $current_group = false;
343 $col_count = 0;
344 for ($i = 0; $i <= count($criteria); $i++) {
345
346 if (isset($criteria[$i])) {
347 $criterion = $criteria[$i];
348
349 if ($current_group && $criterion->criteriatype === $current_group->criteriatype) {
350 ++$col_count;
351 continue;
352 }
353 }
354
355 // Print header cell
356 if ($col_count) {
357 print '<th scope="col" colspan="'.$col_count.'" class="colheader criteriagroup">'.$current_group->get_type_title().'</th>';
358 }
359
360 if (isset($criteria[$i])) {
361 // Move to next criteria type
362 $current_group = $criterion;
363 $col_count = 1;
364 }
365 }
366
367 // Overall course completion status
368 print '<th style="text-align: center;">'.get_string('course').'</th>';
369
370 print '</tr>';
371
372 // Print aggregation methods
373 print PHP_EOL.'<tr style="vertical-align: top">';
374 print '<th scope="row" class="rowheader">'.get_string('aggregationmethod', 'completion').'</th>';
375
376 $current_group = false;
377 $col_count = 0;
378 for ($i = 0; $i <= count($criteria); $i++) {
379
380 if (isset($criteria[$i])) {
381 $criterion = $criteria[$i];
382
383 if ($current_group && $criterion->criteriatype === $current_group->criteriatype) {
384 ++$col_count;
385 continue;
386 }
387 }
388
389 // Print header cell
390 if ($col_count) {
391 $has_agg = array(
392 COMPLETION_CRITERIA_TYPE_COURSE,
393 COMPLETION_CRITERIA_TYPE_ACTIVITY,
394 COMPLETION_CRITERIA_TYPE_ROLE,
395 );
396
397 if (in_array($current_group->criteriatype, $has_agg)) {
398 // Try load a aggregation method
399 $method = $completion->get_aggregation_method($current_group->criteriatype);
400
5227344a 401 $method = $method == 1 ? get_string('all') : get_string('any');
2be4d090
MD
402
403 } else {
404 $method = '-';
405 }
406
407 print '<th scope="col" colspan="'.$col_count.'" class="colheader aggheader">'.$method.'</th>';
408 }
409
410 if (isset($criteria[$i])) {
411 // Move to next criteria type
412 $current_group = $criterion;
413 $col_count = 1;
414 }
415 }
416
417 // Overall course aggregation method
418 print '<th scope="col" class="colheader aggheader aggcriteriacourse">';
419
420 // Get course aggregation
421 $method = $completion->get_aggregation_method();
422
5227344a 423 print $method == 1 ? get_string('all') : get_string('any');
2be4d090
MD
424 print '</th>';
425
426 print '</tr>';
427
428
429 // Print criteria titles
430 if (COMPLETION_REPORT_COL_TITLES) {
431
432 print PHP_EOL.'<tr>';
433 print '<th scope="row" class="rowheader">'.get_string('criteria', 'completion').'</th>';
434
435 foreach ($criteria as $criterion) {
436 // Get criteria details
437 $details = $criterion->get_title_detailed();
438 print '<th scope="col" class="colheader criterianame">';
439 print '<span class="completion-criterianame">'.$details.'</span>';
440 print '</th>';
441 }
442
443 // Overall course completion status
444 print '<th scope="col" class="colheader criterianame">';
445
446 print '<span class="completion-criterianame">'.get_string('coursecomplete', 'completion').'</span>';
447
448 print '</th></tr>';
449 }
450
451 // Print user heading and icons
452 print '<tr>';
453
454 // User heading / sort option
455 print '<th scope="col" class="completion-sortchoice" style="clear: both;">';
1f186372
TL
456
457 $sistring = "&amp;silast={$silast}&amp;sifirst={$sifirst}";
458
2be4d090
MD
459 if($firstnamesort) {
460 print
1f186372 461 get_string('firstname')." / <a href=\"./?course={$course->id}{$sistring}\">".
2be4d090
MD
462 get_string('lastname').'</a>';
463 } else {
1f186372 464 print "<a href=\"./?course={$course->id}&amp;sort=firstname{$sistring}\">".
2be4d090
MD
465 get_string('firstname').'</a> / '.
466 get_string('lastname');
467 }
468 print '</th>';
469
470
471 // Print user id number column
472 if($idnumbers) {
473 print '<th>'.get_string('idnumber').'</th>';
474 }
475
476 ///
477 /// Print criteria icons
478 ///
479 foreach ($criteria as $criterion) {
480
481 // Generate icon details
482 $icon = '';
483 $iconlink = '';
484 $icontitle = ''; // Required if $iconlink set
485 $iconalt = ''; // Required
486 switch ($criterion->criteriatype) {
487
488 case COMPLETION_CRITERIA_TYPE_ACTIVITY:
489 // Load activity
490 $activity = $criterion->get_mod_instance();
491
492 // Display icon
f8e9c93a 493 $icon = $OUTPUT->pix_url('icon', $criterion->module);
2e98a747 494 $iconlink = $CFG->wwwroot.'/mod/'.$criterion->module.'/view.php?id='.$criterion->moduleinstance;
2be4d090
MD
495 $icontitle = $activity->name;
496 $iconalt = get_string('modulename', $criterion->module);
497 break;
498
499 case COMPLETION_CRITERIA_TYPE_COURSE:
500 // Load course
ffe50258 501 $crs = $DB->get_record('course', array('id' => $criterion->courseinstance));
2be4d090
MD
502
503 // Display icon
504 $iconlink = $CFG->wwwroot.'/course/view.php?id='.$criterion->courseinstance;
91d284c1 505 $icontitle = format_string($crs->fullname, true, array('context' => get_context_instance(CONTEXT_COURSE, $crs->id, MUST_EXIST)));
8ebbb06a 506 $iconalt = format_string($crs->shortname, true, array('context' => get_context_instance(CONTEXT_COURSE, $crs->id)));
2be4d090
MD
507 break;
508
509 case COMPLETION_CRITERIA_TYPE_ROLE:
510 // Load role
511 $role = $DB->get_record('role', array('id' => $criterion->role));
512
513 // Display icon
514 $iconalt = $role->name;
515 break;
516 }
517
518 // Print icon and cell
519 print '<th class="criteriaicon">';
520
521 // Create icon if not supplied
522 if (!$icon) {
f8e9c93a 523 $icon = $OUTPUT->pix_url('i/'.$COMPLETION_CRITERIA_TYPES[$criterion->criteriatype]);
2be4d090
MD
524 }
525
526 print ($iconlink ? '<a href="'.$iconlink.'" title="'.$icontitle.'">' : '');
527 print '<img src="'.$icon.'" class="icon" alt="'.$iconalt.'" '.(!$iconlink ? 'title="'.$iconalt.'"' : '').' />';
528 print ($iconlink ? '</a>' : '');
529
530 print '</th>';
531 }
532
533 // Overall course completion status
534 print '<th class="criteriaicon">';
5227344a 535 print '<img src="'.$OUTPUT->pix_url('i/course').'" class="icon" alt="'.get_string('course').'" title="'.get_string('coursecomplete', 'completion').'" />';
2be4d090
MD
536 print '</th>';
537
538 print '</tr>';
539
540
541} else {
542 // TODO
543 if($idnumbers) {
544 print $sep;
545 }
546}
547
548
549///
550/// Display a row for each user
551///
24a3b341 552foreach ($progress as $user) {
2be4d090
MD
553
554 // User name
555 if($csv) {
556 print csv_quote(fullname($user));
557 if($idnumbers) {
558 print $sep.csv_quote($user->idnumber);
559 }
560 } else {
561 print PHP_EOL.'<tr id="user-'.$user->id.'">';
562
563 print '<th scope="row"><a href="'.$CFG->wwwroot.'/user/view.php?id='.
564 $user->id.'&amp;course='.$course->id.'">'.fullname($user).'</a></th>';
565 if($idnumbers) {
566 print '<td>'.htmlspecialchars($user->idnumber).'</td>';
567 }
568 }
569
570 // Progress for each course completion criteria
571 foreach ($criteria as $criterion) {
572
573 // Handle activity completion differently
574 if ($criterion->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
575
576 // Load activity
577 $mod = $criterion->get_mod_instance();
578 $activity = $DB->get_record('course_modules', array('id' => $criterion->moduleinstance));
579 $activity->name = $mod->name;
580
581
582 // Get progress information and state
583 if(array_key_exists($activity->id,$user->progress)) {
584 $thisprogress=$user->progress[$activity->id];
585 $state=$thisprogress->completionstate;
586 $date=userdate($thisprogress->timemodified);
587 } else {
588 $state=COMPLETION_INCOMPLETE;
589 $date='';
590 }
591
592 $criteria_completion = $completion->get_user_completion($user->id, $criterion);
593
594 // Work out how it corresponds to an icon
595 switch($state) {
596 case COMPLETION_INCOMPLETE : $completiontype='n'; break;
597 case COMPLETION_COMPLETE : $completiontype='y'; break;
598 case COMPLETION_COMPLETE_PASS : $completiontype='pass'; break;
599 case COMPLETION_COMPLETE_FAIL : $completiontype='fail'; break;
600 }
601
602 $completionicon='completion-'.
603 ($activity->completion==COMPLETION_TRACKING_AUTOMATIC ? 'auto' : 'manual').
604 '-'.$completiontype;
605
606 $describe=get_string('completion-alt-auto-'.$completiontype,'completion');
607 $a=new StdClass;
608 $a->state=$describe;
609 $a->date=$date;
610 $a->user=fullname($user);
611 $a->activity=strip_tags($activity->name);
612 $fulldescribe=get_string('progress-title','completion',$a);
613
614 if($csv) {
615 print $sep.csv_quote($describe).$sep.csv_quote($date);
616 } else {
617 print '<td class="completion-progresscell">';
618
619 print '<img src="'.$OUTPUT->pix_url('i/'.$completionicon).
620 '" alt="'.$describe.'" class="icon" title="'.$fulldescribe.'" />';
621
622 print '</td>';
623 }
624
625 continue;
626 }
627
628 // Handle all other criteria
629 $criteria_completion = $completion->get_user_completion($user->id, $criterion);
630 $is_complete = $criteria_completion->is_complete();
631
632 $completiontype = $is_complete ? 'y' : 'n';
633 $completionicon = 'completion-auto-'.$completiontype;
634
635 $describe = get_string('completion-alt-auto-'.$completiontype, 'completion');
636
fbaea88f 637 $a = new stdClass();
2be4d090
MD
638 $a->state = $describe;
639 $a->date = $is_complete ? userdate($criteria_completion->timecompleted) : '';
640 $a->user = fullname($user);
641 $a->activity = strip_tags($criterion->get_title());
642 $fulldescribe = get_string('progress-title', 'completion', $a);
643
644 if ($csv) {
645 print $sep.csv_quote($describe);
646 } else {
647
648 if ($allow_marking_criteria === $criterion->id) {
649 $describe = get_string('completion-alt-auto-'.$completiontype,'completion');
650
651 print '<td class="completion-progresscell">'.
9cedb80c 652 '<a href="'.$CFG->wwwroot.'/course/togglecompletion.php?user='.$user->id.'&amp;course='.$course->id.'&amp;rolec='.$allow_marking_criteria.'&amp;sesskey='.sesskey().'">'.
2be4d090 653 '<img src="'.$OUTPUT->pix_url('i/completion-manual-'.($is_complete ? 'y' : 'n')).
5227344a 654 '" alt="'.$describe.'" class="icon" title="'.get_string('markcomplete', 'completion').'" /></a></td>';
2be4d090
MD
655 } else {
656 print '<td class="completion-progresscell">'.
657 '<img src="'.$OUTPUT->pix_url('i/'.$completionicon).
658 '" alt="'.$describe.'" class="icon" title="'.$fulldescribe.'" /></td>';
659 }
660 }
661 }
662
663 // Handle overall course completion
664
665 // Load course completion
666 $params = array(
667 'userid' => $user->id,
668 'course' => $course->id
669 );
670
671 $ccompletion = new completion_completion($params);
672 $completiontype = $ccompletion->is_complete() ? 'y' : 'n';
673
674 $describe = get_string('completion-alt-auto-'.$completiontype, 'completion');
675
676 $a = new StdClass;
677 $a->state = $describe;
678 $a->date = '';
679 $a->user = fullname($user);
680 $a->activity = strip_tags(get_string('coursecomplete', 'completion'));
681 $fulldescribe = get_string('progress-title', 'completion', $a);
682
683 if ($csv) {
684 print $sep.csv_quote($describe);
685 } else {
686
687 print '<td class="completion-progresscell">';
688
689 // Display course completion status icon
690 print '<img src="'.$OUTPUT->pix_url('i/completion-auto-'.$completiontype).
691 '" alt="'.$describe.'" class="icon" title="'.$fulldescribe.'" />';
692
693 print '</td>';
694 }
695
696 if($csv) {
697 print $line;
698 } else {
699 print '</tr>';
700 }
701}
702
703if($csv) {
704 exit;
705}
706print '</table>';
707print $pagingbar;
708
709print '<ul class="progress-actions"><li><a href="index.php?course='.$course->id.
710 '&amp;format=csv">'.get_string('csvdownload','completion').'</a></li>
711 <li><a href="index.php?course='.$course->id.'&amp;format=excelcsv">'.
712 get_string('excelcsvdownload','completion').'</a></li></ul>';
713
714echo $OUTPUT->footer($course);