[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 * Activity progress reports 19 * 20 * @package report 21 * @subpackage progress 22 * @copyright 2008 Sam Marshall 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 require('../../config.php'); 27 require_once($CFG->libdir . '/completionlib.php'); 28 29 define('COMPLETION_REPORT_PAGE', 25); 30 31 // Get course 32 $id = required_param('course',PARAM_INT); 33 $course = $DB->get_record('course',array('id'=>$id)); 34 if (!$course) { 35 print_error('invalidcourseid'); 36 } 37 $context = context_course::instance($course->id); 38 39 // Sort (default lastname, optionally firstname) 40 $sort = optional_param('sort','',PARAM_ALPHA); 41 $firstnamesort = $sort == 'firstname'; 42 43 // CSV format 44 $format = optional_param('format','',PARAM_ALPHA); 45 $excel = $format == 'excelcsv'; 46 $csv = $format == 'csv' || $excel; 47 48 // Paging 49 $start = optional_param('start', 0, PARAM_INT); 50 $sifirst = optional_param('sifirst', 'all', PARAM_NOTAGS); 51 $silast = optional_param('silast', 'all', PARAM_NOTAGS); 52 $start = optional_param('start', 0, PARAM_INT); 53 54 // Whether to show extra user identity information 55 $extrafields = get_extra_user_fields($context); 56 $leftcols = 1 + count($extrafields); 57 58 function csv_quote($value) { 59 global $excel; 60 if ($excel) { 61 return core_text::convert('"'.str_replace('"',"'",$value).'"','UTF-8','UTF-16LE'); 62 } else { 63 return '"'.str_replace('"',"'",$value).'"'; 64 } 65 } 66 67 $url = new moodle_url('/report/progress/index.php', array('course'=>$id)); 68 if ($sort !== '') { 69 $url->param('sort', $sort); 70 } 71 if ($format !== '') { 72 $url->param('format', $format); 73 } 74 if ($start !== 0) { 75 $url->param('start', $start); 76 } 77 $PAGE->set_url($url); 78 $PAGE->set_pagelayout('report'); 79 80 require_login($course); 81 82 // Check basic permission 83 require_capability('report/progress:view',$context); 84 85 // Get group mode 86 $group = groups_get_course_group($course,true); // Supposed to verify group 87 if ($group===0 && $course->groupmode==SEPARATEGROUPS) { 88 require_capability('moodle/site:accessallgroups',$context); 89 } 90 91 // Get data on activities and progress of all users, and give error if we've 92 // nothing to display (no users or no activities) 93 $reportsurl = $CFG->wwwroot.'/course/report.php?id='.$course->id; 94 $completion = new completion_info($course); 95 $activities = $completion->get_activities(); 96 97 // Generate where clause 98 $where = array(); 99 $where_params = array(); 100 101 if ($sifirst !== 'all') { 102 $where[] = $DB->sql_like('u.firstname', ':sifirst', false); 103 $where_params['sifirst'] = $sifirst.'%'; 104 } 105 106 if ($silast !== 'all') { 107 $where[] = $DB->sql_like('u.lastname', ':silast', false); 108 $where_params['silast'] = $silast.'%'; 109 } 110 111 // Get user match count 112 $total = $completion->get_num_tracked_users(implode(' AND ', $where), $where_params, $group); 113 114 // Total user count 115 $grandtotal = $completion->get_num_tracked_users('', array(), $group); 116 117 // Get user data 118 $progress = array(); 119 120 if ($total) { 121 $progress = $completion->get_progress_all( 122 implode(' AND ', $where), 123 $where_params, 124 $group, 125 $firstnamesort ? 'u.firstname ASC' : 'u.lastname ASC', 126 $csv ? 0 : COMPLETION_REPORT_PAGE, 127 $csv ? 0 : $start, 128 $context 129 ); 130 } 131 132 if ($csv && $grandtotal && count($activities)>0) { // Only show CSV if there are some users/actvs 133 134 $shortname = format_string($course->shortname, true, array('context' => $context)); 135 header('Content-Disposition: attachment; filename=progress.'. 136 preg_replace('/[^a-z0-9-]/','_',core_text::strtolower(strip_tags($shortname))).'.csv'); 137 // Unicode byte-order mark for Excel 138 if ($excel) { 139 header('Content-Type: text/csv; charset=UTF-16LE'); 140 print chr(0xFF).chr(0xFE); 141 $sep="\t".chr(0); 142 $line="\n".chr(0); 143 } else { 144 header('Content-Type: text/csv; charset=UTF-8'); 145 $sep=","; 146 $line="\n"; 147 } 148 } else { 149 150 // Navigation and header 151 $strreports = get_string("reports"); 152 $strcompletion = get_string('activitycompletion', 'completion'); 153 154 $PAGE->set_title($strcompletion); 155 $PAGE->set_heading($course->fullname); 156 echo $OUTPUT->header(); 157 $PAGE->requires->js('/report/progress/textrotate.js'); 158 $PAGE->requires->js_function_call('textrotate_init', null, true); 159 160 // Handle groups (if enabled) 161 groups_print_course_menu($course,$CFG->wwwroot.'/report/progress/?course='.$course->id); 162 } 163 164 if (count($activities)==0) { 165 echo $OUTPUT->container(get_string('err_noactivities', 'completion'), 'errorbox errorboxcontent'); 166 echo $OUTPUT->footer(); 167 exit; 168 } 169 170 // If no users in this course what-so-ever 171 if (!$grandtotal) { 172 echo $OUTPUT->container(get_string('err_nousers', 'completion'), 'errorbox errorboxcontent'); 173 echo $OUTPUT->footer(); 174 exit; 175 } 176 177 // Build link for paging 178 $link = $CFG->wwwroot.'/report/progress/?course='.$course->id; 179 if (strlen($sort)) { 180 $link .= '&sort='.$sort; 181 } 182 $link .= '&start='; 183 184 // Build the the page by Initial bar 185 $initials = array('first', 'last'); 186 $alphabet = explode(',', get_string('alphabet', 'langconfig')); 187 188 $pagingbar = ''; 189 foreach ($initials as $initial) { 190 $var = 'si'.$initial; 191 192 $othervar = $initial == 'first' ? 'silast' : 'sifirst'; 193 $othervar = $$othervar != 'all' ? "&{$othervar}={$$othervar}" : ''; 194 195 $pagingbar .= ' <div class="initialbar '.$initial.'initial">'; 196 $pagingbar .= get_string($initial.'name').': '; 197 198 if ($$var == 'all') { 199 $pagingbar .= '<strong>'.get_string('all').'</strong> '; 200 } 201 else { 202 $pagingbar .= "<a href=\"{$link}{$othervar}\">".get_string('all').'</a> '; 203 } 204 205 foreach ($alphabet as $letter) { 206 if ($$var === $letter) { 207 $pagingbar .= '<strong>'.$letter.'</strong> '; 208 } 209 else { 210 $pagingbar .= "<a href=\"$link&$var={$letter}{$othervar}\">$letter</a> "; 211 } 212 } 213 214 $pagingbar .= '</div>'; 215 } 216 217 // Do we need a paging bar? 218 if ($total > COMPLETION_REPORT_PAGE) { 219 220 // Paging bar 221 $pagingbar .= '<div class="paging">'; 222 $pagingbar .= get_string('page').': '; 223 224 $sistrings = array(); 225 if ($sifirst != 'all') { 226 $sistrings[] = "sifirst={$sifirst}"; 227 } 228 if ($silast != 'all') { 229 $sistrings[] = "silast={$silast}"; 230 } 231 $sistring = !empty($sistrings) ? '&'.implode('&', $sistrings) : ''; 232 233 // Display previous link 234 if ($start > 0) { 235 $pstart = max($start - COMPLETION_REPORT_PAGE, 0); 236 $pagingbar .= "(<a class=\"previous\" href=\"{$link}{$pstart}{$sistring}\">".get_string('previous').'</a>) '; 237 } 238 239 // Create page links 240 $curstart = 0; 241 $curpage = 0; 242 while ($curstart < $total) { 243 $curpage++; 244 245 if ($curstart == $start) { 246 $pagingbar .= ' '.$curpage.' '; 247 } else { 248 $pagingbar .= " <a href=\"{$link}{$curstart}{$sistring}\">$curpage</a> "; 249 } 250 251 $curstart += COMPLETION_REPORT_PAGE; 252 } 253 254 // Display next link 255 $nstart = $start + COMPLETION_REPORT_PAGE; 256 if ($nstart < $total) { 257 $pagingbar .= " (<a class=\"next\" href=\"{$link}{$nstart}{$sistring}\">".get_string('next').'</a>)'; 258 } 259 260 $pagingbar .= '</div>'; 261 } 262 263 // Okay, let's draw the table of progress info, 264 265 // Start of table 266 if (!$csv) { 267 print '<br class="clearer"/>'; // ugh 268 269 print $pagingbar; 270 271 if (!$total) { 272 echo $OUTPUT->heading(get_string('nothingtodisplay')); 273 echo $OUTPUT->footer(); 274 exit; 275 } 276 277 print '<div id="completion-progress-wrapper" class="no-overflow">'; 278 print '<table id="completion-progress" class="generaltable flexible boxaligncenter" style="text-align:left"><thead><tr style="vertical-align:top">'; 279 280 // User heading / sort option 281 print '<th scope="col" class="completion-sortchoice">'; 282 283 $sistring = "&silast={$silast}&sifirst={$sifirst}"; 284 285 if ($firstnamesort) { 286 print 287 get_string('firstname')." / <a href=\"./?course={$course->id}{$sistring}\">". 288 get_string('lastname').'</a>'; 289 } else { 290 print "<a href=\"./?course={$course->id}&sort=firstname{$sistring}\">". 291 get_string('firstname').'</a> / '. 292 get_string('lastname'); 293 } 294 print '</th>'; 295 296 // Print user identity columns 297 foreach ($extrafields as $field) { 298 echo '<th scope="col" class="completion-identifyfield">' . 299 get_user_field_name($field) . '</th>'; 300 } 301 } else { 302 foreach ($extrafields as $field) { 303 echo $sep . csv_quote(get_user_field_name($field)); 304 } 305 } 306 307 // Activities 308 $formattedactivities = array(); 309 foreach($activities as $activity) { 310 $datepassed = $activity->completionexpected && $activity->completionexpected <= time(); 311 $datepassedclass = $datepassed ? 'completion-expired' : ''; 312 313 if ($activity->completionexpected) { 314 $datetext=userdate($activity->completionexpected,get_string('strftimedate','langconfig')); 315 } else { 316 $datetext=''; 317 } 318 319 // Some names (labels) come URL-encoded and can be very long, so shorten them 320 $displayname = format_string($activity->name, true, array('context' => $activity->context)); 321 322 if ($csv) { 323 print $sep.csv_quote($displayname).$sep.csv_quote($datetext); 324 } else { 325 $shortenedname = shorten_text($displayname); 326 print '<th scope="col" class="'.$datepassedclass.'">'. 327 '<a href="'.$CFG->wwwroot.'/mod/'.$activity->modname. 328 '/view.php?id='.$activity->id.'" title="' . s($displayname) . '">'. 329 '<img src="'.$OUTPUT->pix_url('icon', $activity->modname).'" alt="'. 330 s(get_string('modulename', $activity->modname)). 331 '" /> <span class="completion-activityname">'. 332 $shortenedname.'</span></a>'; 333 if ($activity->completionexpected) { 334 print '<div class="completion-expected"><span>'.$datetext.'</span></div>'; 335 } 336 print '</th>'; 337 } 338 $formattedactivities[$activity->id] = (object)array( 339 'datepassedclass' => $datepassedclass, 340 'displayname' => $displayname, 341 ); 342 } 343 344 if ($csv) { 345 print $line; 346 } else { 347 print '</tr></thead><tbody>'; 348 } 349 350 // Row for each user 351 foreach($progress as $user) { 352 // User name 353 if ($csv) { 354 print csv_quote(fullname($user)); 355 foreach ($extrafields as $field) { 356 echo $sep . csv_quote($user->{$field}); 357 } 358 } else { 359 print '<tr><th scope="row"><a href="'.$CFG->wwwroot.'/user/view.php?id='. 360 $user->id.'&course='.$course->id.'">'.fullname($user).'</a></th>'; 361 foreach ($extrafields as $field) { 362 echo '<td>' . s($user->{$field}) . '</td>'; 363 } 364 } 365 366 // Progress for each activity 367 foreach($activities as $activity) { 368 369 // Get progress information and state 370 if (array_key_exists($activity->id,$user->progress)) { 371 $thisprogress=$user->progress[$activity->id]; 372 $state=$thisprogress->completionstate; 373 $date=userdate($thisprogress->timemodified); 374 } else { 375 $state=COMPLETION_INCOMPLETE; 376 $date=''; 377 } 378 379 // Work out how it corresponds to an icon 380 switch($state) { 381 case COMPLETION_INCOMPLETE : $completiontype='n'; break; 382 case COMPLETION_COMPLETE : $completiontype='y'; break; 383 case COMPLETION_COMPLETE_PASS : $completiontype='pass'; break; 384 case COMPLETION_COMPLETE_FAIL : $completiontype='fail'; break; 385 } 386 387 $completionicon='completion-'. 388 ($activity->completion==COMPLETION_TRACKING_AUTOMATIC ? 'auto' : 'manual'). 389 '-'.$completiontype; 390 391 $describe = get_string('completion-' . $completiontype, 'completion'); 392 $a=new StdClass; 393 $a->state=$describe; 394 $a->date=$date; 395 $a->user=fullname($user); 396 $a->activity = $formattedactivities[$activity->id]->displayname; 397 $fulldescribe=get_string('progress-title','completion',$a); 398 399 if ($csv) { 400 print $sep.csv_quote($describe).$sep.csv_quote($date); 401 } else { 402 print '<td class="completion-progresscell '.$formattedactivities[$activity->id]->datepassedclass.'">'. 403 '<img src="'.$OUTPUT->pix_url('i/'.$completionicon). 404 '" alt="'.s($describe).'" title="'.s($fulldescribe).'" /></td>'; 405 } 406 } 407 408 if ($csv) { 409 print $line; 410 } else { 411 print '</tr>'; 412 } 413 } 414 415 if ($csv) { 416 exit; 417 } 418 print '</tbody></table>'; 419 print '</div>'; 420 print $pagingbar; 421 422 print '<ul class="progress-actions"><li><a href="index.php?course='.$course->id. 423 '&format=csv">'.get_string('csvdownload','completion').'</a></li> 424 <li><a href="index.php?course='.$course->id.'&format=excelcsv">'. 425 get_string('excelcsvdownload','completion').'</a></li></ul>'; 426 427 echo $OUTPUT->footer(); 428
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |