Search moodle.org's
Developer Documentation

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

Search This Site: