Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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