Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

Differences Between: [Versions 310 and 400] [Versions 311 and 400] [Versions 39 and 400]

   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   * Block for displayed logged in user's course completion status.
  19   * Displays overall, and individual criteria status for logged in user.
  20   *
  21   * @package    block_completionstatus
  22   * @copyright  2009-2012 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  class block_completionstatus extends block_base {
  27  
  28      public function init() {
  29          global $CFG;
  30  
  31          require_once("{$CFG->libdir}/completionlib.php");
  32  
  33          $this->title = get_string('pluginname', 'block_completionstatus');
  34      }
  35  
  36      public function applicable_formats() {
  37          return array('course' => true);
  38      }
  39  
  40      public function get_content() {
  41          global $USER;
  42  
  43          $rows = array();
  44          $srows = array();
  45          $prows = array();
  46          // If content is cached.
  47          if ($this->content !== null) {
  48              return $this->content;
  49          }
  50  
  51          $course = $this->page->course;
  52          $context = context_course::instance($course->id);
  53  
  54          // Create empty content.
  55          $this->content = new stdClass();
  56          $this->content->text = '';
  57          $this->content->footer = '';
  58  
  59          // Can edit settings?
  60          $can_edit = has_capability('moodle/course:update', $context);
  61  
  62          // Get course completion data.
  63          $info = new completion_info($course);
  64  
  65          // Don't display if completion isn't enabled!
  66          if (!completion_info::is_enabled_for_site()) {
  67              if ($can_edit) {
  68                  $this->content->text .= get_string('completionnotenabledforsite', 'completion');
  69              }
  70              return $this->content;
  71  
  72          } else if (!$info->is_enabled()) {
  73              if ($can_edit) {
  74                  $this->content->text .= get_string('completionnotenabledforcourse', 'completion');
  75              }
  76              return $this->content;
  77          }
  78  
  79          // Load criteria to display.
  80          $completions = $info->get_completions($USER->id);
  81  
  82          // Check if this course has any criteria.
  83          if (empty($completions)) {
  84              if ($can_edit) {
  85                  $this->content->text .= get_string('nocriteriaset', 'completion');
  86              }
  87              return $this->content;
  88          }
  89  
  90          // Check this user is enroled.
  91          if ($info->is_tracked_user($USER->id)) {
  92  
  93              // Generate markup for criteria statuses.
  94              $data = '';
  95  
  96              // For aggregating activity completion.
  97              $activities = array();
  98              $activities_complete = 0;
  99  
 100              // For aggregating course prerequisites.
 101              $prerequisites = array();
 102              $prerequisites_complete = 0;
 103  
 104              // Flag to set if current completion data is inconsistent with what is stored in the database.
 105              $pending_update = false;
 106  
 107              // Loop through course criteria.
 108              foreach ($completions as $completion) {
 109                  $criteria = $completion->get_criteria();
 110                  $complete = $completion->is_complete();
 111  
 112                  if (!$pending_update && $criteria->is_pending($completion)) {
 113                      $pending_update = true;
 114                  }
 115  
 116                  // Activities are a special case, so cache them and leave them till last.
 117                  if ($criteria->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
 118                      $activities[$criteria->moduleinstance] = $complete;
 119  
 120                      if ($complete) {
 121                          $activities_complete++;
 122                      }
 123  
 124                      continue;
 125                  }
 126  
 127                  // Prerequisites are also a special case, so cache them and leave them till last.
 128                  if ($criteria->criteriatype == COMPLETION_CRITERIA_TYPE_COURSE) {
 129                      $prerequisites[$criteria->courseinstance] = $complete;
 130  
 131                      if ($complete) {
 132                          $prerequisites_complete++;
 133                      }
 134  
 135                      continue;
 136                  }
 137                  $row = new html_table_row();
 138                  $row->cells[0] = new html_table_cell($criteria->get_title());
 139                  $row->cells[1] = new html_table_cell($completion->get_status());
 140                  $row->cells[1]->style = 'text-align: right;';
 141                  $srows[] = $row;
 142              }
 143  
 144              // Aggregate activities.
 145              if (!empty($activities)) {
 146                  $a = new stdClass();
 147                  $a->first = $activities_complete;
 148                  $a->second = count($activities);
 149  
 150                  $row = new html_table_row();
 151                  $row->cells[0] = new html_table_cell(get_string('activitiescompleted', 'completion'));
 152                  $row->cells[1] = new html_table_cell(get_string('firstofsecond', 'block_completionstatus', $a));
 153                  $row->cells[1]->style = 'text-align: right;';
 154                  $srows[] = $row;
 155              }
 156  
 157              // Aggregate prerequisites.
 158              if (!empty($prerequisites)) {
 159                  $a = new stdClass();
 160                  $a->first = $prerequisites_complete;
 161                  $a->second = count($prerequisites);
 162  
 163                  $row = new html_table_row();
 164                  $row->cells[0] = new html_table_cell(get_string('dependenciescompleted', 'completion'));
 165                  $row->cells[1] = new html_table_cell(get_string('firstofsecond', 'block_completionstatus', $a));
 166                  $row->cells[1]->style = 'text-align: right;';
 167                  $prows[] = $row;
 168  
 169                  $srows = array_merge($prows, $srows);
 170              }
 171  
 172              // Display completion status.
 173              $table = new html_table();
 174              $table->width = '100%';
 175              $table->attributes = array('style'=>'font-size: 90%;', 'class'=>'');
 176  
 177              $row = new html_table_row();
 178              $content = html_writer::tag('b', get_string('status').': ');
 179  
 180              // Is course complete?
 181              $coursecomplete = $info->is_course_complete($USER->id);
 182  
 183              // Load course completion.
 184              $params = array(
 185                  'userid' => $USER->id,
 186                  'course' => $course->id
 187              );
 188              $ccompletion = new completion_completion($params);
 189  
 190              // Has this user completed any criteria?
 191              $criteriacomplete = $info->count_course_user_data($USER->id);
 192  
 193              if ($pending_update) {
 194                  $content .= html_writer::tag('i', get_string('pending', 'completion'));
 195              } else if ($coursecomplete) {
 196                  $content .= get_string('complete');
 197              } else if (!$criteriacomplete && !$ccompletion->timestarted) {
 198                  $content .= html_writer::tag('i', get_string('notyetstarted', 'completion'));
 199              } else {
 200                  $content .= html_writer::tag('i', get_string('inprogress', 'completion'));
 201              }
 202  
 203              $row->cells[0] = new html_table_cell($content);
 204              $row->cells[0]->colspan = '2';
 205  
 206              $rows[] = $row;
 207              $row = new html_table_row();
 208              $content = "";
 209              // Get overall aggregation method.
 210              $overall = $info->get_aggregation_method();
 211              if ($overall == COMPLETION_AGGREGATION_ALL) {
 212                  $content .= get_string('criteriarequiredall', 'completion');
 213              } else {
 214                  $content .= get_string('criteriarequiredany', 'completion');
 215              }
 216              $content .= ':';
 217              $row->cells[0] = new html_table_cell($content);
 218              $row->cells[0]->colspan = '2';
 219              $rows[] = $row;
 220  
 221              $row = new html_table_row();
 222              $row->cells[0] = new html_table_cell(html_writer::tag('b', get_string('requiredcriteria', 'completion')));
 223              $row->cells[1] = new html_table_cell(html_writer::tag('b', get_string('status')));
 224              $row->cells[1]->style = 'text-align: right;';
 225              $rows[] = $row;
 226  
 227              // Array merge $rows and $data here.
 228              $rows = array_merge($rows, $srows);
 229  
 230              $table->data = $rows;
 231              $this->content->text .= html_writer::table($table);
 232  
 233              // Display link to detailed view.
 234              $details = new moodle_url('/blocks/completionstatus/details.php', array('course' => $course->id));
 235              $this->content->footer .= html_writer::link($details, get_string('moredetails', 'completion'));
 236          } else {
 237              // If user is not enrolled, show error.
 238              $this->content->text = get_string('nottracked', 'completion');
 239          }
 240  
 241          if (has_capability('report/completion:view', $context)) {
 242              $report = new moodle_url('/report/completion/index.php', array('course' => $course->id));
 243              if (empty($this->content->footer)) {
 244                  $this->content->footer = '';
 245              }
 246              $this->content->footer .= html_writer::empty_tag('br');
 247              $this->content->footer .= html_writer::link($report, get_string('viewcoursereport', 'completion'));
 248          }
 249  
 250          return $this->content;
 251      }
 252  
 253      /**
 254       * This block shouldn't be added to a page if the completion tracking advanced feature is disabled.
 255       *
 256       * @param moodle_page $page
 257       * @return bool
 258       */
 259      public function can_block_be_added(moodle_page $page): bool {
 260          global $CFG;
 261  
 262          return $CFG->enablecompletion;
 263      }
 264  }