Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

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

   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   * This file contains the activity completion criteria type class and any
  20   * supporting functions it may require.
  21   *
  22   * @package core_completion
  23   * @category completion
  24   * @copyright 2009 Catalyst IT Ltd
  25   * @author Aaron Barnes <aaronb@catalyst.net.nz>
  26   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  27   */
  28  
  29  defined('MOODLE_INTERNAL') || die();
  30  
  31  /**
  32   * Course completion critieria - completion on activity completion
  33   *
  34   * @package core_completion
  35   * @category completion
  36   * @copyright 2009 Catalyst IT Ltd
  37   * @author Aaron Barnes <aaronb@catalyst.net.nz>
  38   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  39   */
  40  class completion_criteria_activity extends completion_criteria {
  41  
  42      /* @var int Criteria [COMPLETION_CRITERIA_TYPE_ACTIVITY] */
  43      public $criteriatype = COMPLETION_CRITERIA_TYPE_ACTIVITY;
  44  
  45      /**
  46       * Finds and returns a data_object instance based on params.
  47       *
  48       * @param array $params associative arrays varname=>value
  49       * @return completion_criteria_activity data_object instance or false if none found.
  50       */
  51      public static function fetch($params) {
  52          $params['criteriatype'] = COMPLETION_CRITERIA_TYPE_ACTIVITY;
  53          return self::fetch_helper('course_completion_criteria', __CLASS__, $params);
  54      }
  55  
  56      /**
  57       * Add appropriate form elements to the critieria form
  58       *
  59       * @param moodleform $mform  Moodle forms object
  60       * @param stdClass $data details of various modules
  61       */
  62      public function config_form_display(&$mform, $data = null) {
  63          $modnames = get_module_types_names();
  64          $mform->addElement('advcheckbox',
  65                  'criteria_activity['.$data->id.']',
  66                  $modnames[self::get_mod_name($data->module)] . ' - ' . format_string($data->name),
  67                  null,
  68                  array('group' => 1));
  69  
  70          if ($this->id) {
  71              $mform->setDefault('criteria_activity['.$data->id.']', 1);
  72          }
  73      }
  74  
  75      /**
  76       * Update the criteria information stored in the database
  77       *
  78       * @param stdClass $data Form data
  79       */
  80      public function update_config(&$data) {
  81          global $DB;
  82  
  83          if (!empty($data->criteria_activity) && is_array($data->criteria_activity)) {
  84  
  85              $this->course = $data->id;
  86  
  87              // Data comes from advcheckbox, so contains keys for all activities.
  88              // A value of 0 is 'not checked' whereas 1 is 'checked'.
  89              foreach ($data->criteria_activity as $activity => $val) {
  90                  // Only update those which are checked.
  91                  if (!empty($val)) {
  92                      $module = $DB->get_record('course_modules', array('id' => $activity));
  93                      $this->module = self::get_mod_name($module->module);
  94                      $this->moduleinstance = $activity;
  95                      $this->id = null;
  96                      $this->insert();
  97                  }
  98              }
  99          }
 100      }
 101  
 102      /**
 103       * Get module instance module type
 104       *
 105       * @param int $type Module type id
 106       * @return string
 107       */
 108      public static function get_mod_name($type) {
 109          static $types;
 110  
 111          if (!is_array($types)) {
 112              global $DB;
 113              $types = $DB->get_records('modules');
 114          }
 115  
 116          return $types[$type]->name;
 117      }
 118  
 119      /**
 120       * Gets the module instance from the database and returns it.
 121       * If no module instance exists this function returns false.
 122       *
 123       * @return stdClass|bool
 124       */
 125      public function get_mod_instance() {
 126          global $DB;
 127  
 128          return $DB->get_record_sql(
 129              "
 130                  SELECT
 131                      m.*
 132                  FROM
 133                      {{$this->module}} m
 134                  INNER JOIN
 135                      {course_modules} cm
 136                   ON cm.id = {$this->moduleinstance}
 137                  AND m.id = cm.instance
 138              "
 139          );
 140      }
 141  
 142      /**
 143       * Review this criteria and decide if the user has completed
 144       *
 145       * @param completion_completion $completion     The user's completion record
 146       * @param bool $mark Optionally set false to not save changes to database
 147       * @return bool
 148       */
 149      public function review($completion, $mark = true) {
 150          global $DB;
 151  
 152          $course = $DB->get_record('course', array('id' => $completion->course));
 153          $cm = $DB->get_record('course_modules', array('id' => $this->moduleinstance));
 154          $info = new completion_info($course);
 155  
 156          $data = $info->get_data($cm, false, $completion->userid);
 157  
 158          // If the activity is complete.
 159          if (in_array($data->completionstate, [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS])) {
 160              if ($mark) {
 161                  $completion->mark_complete();
 162              }
 163  
 164              return true;
 165          }
 166  
 167          return false;
 168      }
 169  
 170      /**
 171       * Return criteria title for display in reports
 172       *
 173       * @return string
 174       */
 175      public function get_title() {
 176          return get_string('activitiescompleted', 'completion');
 177      }
 178  
 179      /**
 180       * Return a more detailed criteria title for display in reports
 181       *
 182       * @return  string
 183       */
 184      public function get_title_detailed() {
 185          global $DB;
 186          $module = $DB->get_record('course_modules', array('id' => $this->moduleinstance));
 187          $activity = $DB->get_record($this->module, array('id' => $module->instance));
 188  
 189          return shorten_text(format_string($activity->name, true,
 190                  array('context' => context_module::instance($module->id))));
 191      }
 192  
 193      /**
 194       * Return criteria type title for display in reports
 195       *
 196       * @return  string
 197       */
 198      public function get_type_title() {
 199          return get_string('activities', 'completion');
 200      }
 201  
 202      /**
 203       * Find users who have completed this criteria and mark them accordingly
 204       */
 205      public function cron() {
 206          \core_completion\api::mark_course_completions_activity_criteria();
 207      }
 208  
 209      /**
 210       * Return criteria progress details for display in reports
 211       *
 212       * @param completion_completion $completion The user's completion record
 213       * @return array An array with the following keys:
 214       *     type, criteria, requirement, status
 215       */
 216      public function get_details($completion) {
 217          // Get completion info
 218          $modinfo = get_fast_modinfo($completion->course);
 219          $cm = $modinfo->get_cm($this->moduleinstance);
 220  
 221          $details = array();
 222          $details['type'] = $this->get_title();
 223          if ($cm->has_view()) {
 224              $details['criteria'] = html_writer::link($cm->url, $cm->get_formatted_name());
 225          } else {
 226              $details['criteria'] = $cm->get_formatted_name();
 227          }
 228  
 229          // Build requirements
 230          $details['requirement'] = array();
 231  
 232          if ($cm->completion == COMPLETION_TRACKING_MANUAL) {
 233              $details['requirement'][] = get_string('markingyourselfcomplete', 'completion');
 234          } elseif ($cm->completion == COMPLETION_TRACKING_AUTOMATIC) {
 235              if ($cm->completionview) {
 236                  $modulename = core_text::strtolower(get_string('modulename', $this->module));
 237                  $details['requirement'][] = get_string('viewingactivity', 'completion', $modulename);
 238              }
 239  
 240              if (!is_null($cm->completiongradeitemnumber)) {
 241                  $details['requirement'][] = get_string('achievinggrade', 'completion');
 242              }
 243  
 244              if ($cm->completionpassgrade) {
 245                  $details['requirement'][] = get_string('achievingpassinggrade', 'completion');
 246              }
 247          }
 248  
 249          $details['requirement'] = implode(', ', $details['requirement']);
 250  
 251          $details['status'] = '';
 252  
 253          return $details;
 254      }
 255  
 256      /**
 257       * Return pix_icon for display in reports.
 258       *
 259       * @param string $alt The alt text to use for the icon
 260       * @param array $attributes html attributes
 261       * @return pix_icon
 262       */
 263      public function get_icon($alt, array $attributes = null) {
 264          return new pix_icon('monologo', $alt, "mod_{$this->module}", $attributes);
 265      }
 266  }