Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403]

   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  declare(strict_types = 1);
  18  
  19  namespace core_completion;
  20  
  21  use cm_info;
  22  use coding_exception;
  23  use moodle_exception;
  24  
  25  /**
  26   * Base class for defining an activity module's custom completion rules.
  27   *
  28   * Class for defining an activity module's custom completion rules and fetching the completion statuses
  29   * of the custom completion rules for a given module instance and a user.
  30   *
  31   * @package   core_completion
  32   * @copyright 2021 Jun Pataleta <jun@moodle.com>
  33   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  34   */
  35  abstract class activity_custom_completion {
  36  
  37      /** @var cm_info The course module information object. */
  38      protected $cm;
  39  
  40      /** @var int The user's ID. */
  41      protected $userid;
  42  
  43      /**
  44       * activity_custom_completion constructor.
  45       *
  46       * @param cm_info $cm
  47       * @param int $userid
  48       */
  49      public function __construct(cm_info $cm, int $userid) {
  50          $this->cm = $cm;
  51          $this->userid = $userid;
  52      }
  53  
  54      /**
  55       * Validates that the custom rule is defined by this plugin and is enabled for this activity instance.
  56       *
  57       * @param string $rule The custom completion rule.
  58       */
  59      public function validate_rule(string $rule): void {
  60          // Check that this custom completion rule is defined.
  61          if (!$this->is_defined($rule)) {
  62              throw new coding_exception("Undefined custom completion rule '$rule'");
  63          }
  64  
  65          // Check that this custom rule is included in the course module's custom completion rules.
  66          if (!$this->is_available($rule)) {
  67              throw new moodle_exception("Custom completion rule '$rule' is not used by this activity.");
  68          }
  69      }
  70  
  71      /**
  72       * Whether this module defines this custom rule.
  73       *
  74       * @param string $rule The custom completion rule.
  75       * @return bool
  76       */
  77      public function is_defined(string $rule): bool {
  78          return in_array($rule, static::get_defined_custom_rules());
  79      }
  80  
  81      /**
  82       * Checks whether the custom completion rule is being used by the activity module instance.
  83       *
  84       * @param string $rule The custom completion rule.
  85       * @return bool
  86       */
  87      public function is_available(string $rule): bool {
  88          return in_array($rule, $this->get_available_custom_rules());
  89      }
  90  
  91      /**
  92       * Fetches the list of custom completion rules that are being used by this activity module instance.
  93       *
  94       * @return array
  95       */
  96      public function get_available_custom_rules(): array {
  97          $rules = static::get_defined_custom_rules();
  98          $availablerules = [];
  99          $customdata = (array)$this->cm->customdata;
 100          foreach ($rules as $rule) {
 101              $customrule = $customdata['customcompletionrules'][$rule] ?? false;
 102              if (!empty($customrule)) {
 103                  $availablerules[] = $rule;
 104              }
 105          }
 106          return $availablerules;
 107      }
 108  
 109      /**
 110       * Fetches the overall completion status of this activity instance for a user based on its available custom completion rules.
 111       *
 112       * @return int The completion state (e.g. COMPLETION_COMPLETE, COMPLETION_INCOMPLETE).
 113       */
 114      public function get_overall_completion_state(): int {
 115          foreach ($this->get_available_custom_rules() as $rule) {
 116              $state = $this->get_state($rule);
 117              // Return early if one of the custom completion rules is not yet complete.
 118              if ($state == COMPLETION_INCOMPLETE) {
 119                  return $state;
 120              }
 121          }
 122          // If this was reached, then all custom rules have been marked complete.
 123          return COMPLETION_COMPLETE;
 124      }
 125  
 126      /**
 127       * Fetches the description for a given custom completion rule.
 128       *
 129       * @param string $rule The custom completion rule.
 130       * @return string
 131       */
 132      public function get_custom_rule_description(string $rule): string {
 133          $descriptions = $this->get_custom_rule_descriptions();
 134          if (!isset($descriptions[$rule])) {
 135              // Lang string not found for this custom completion rule. Just return it.
 136              return $rule;
 137          }
 138          return $descriptions[$rule];
 139      }
 140  
 141      /**
 142       * Show the manual completion or not regardless of the course's showcompletionconditions setting.
 143       * Returns false by default for plugins that don't need to override the course's showcompletionconditions setting.
 144       * Activity plugins that need to always show manual completion need to override this function.
 145       *
 146       * @return bool
 147       */
 148      public function manual_completion_always_shown(): bool {
 149          return false;
 150      }
 151  
 152      /**
 153       * Fetches the module's custom completion class implementation if it's available.
 154       *
 155       * @param string $modname The activity module name. Usually from cm_info::modname.
 156       * @return string|null
 157       */
 158      public static function get_cm_completion_class(string $modname): ?string {
 159          $cmcompletionclass = "mod_{$modname}\\completion\\custom_completion";
 160          if (class_exists($cmcompletionclass) && is_subclass_of($cmcompletionclass, self::class)) {
 161              return $cmcompletionclass;
 162          }
 163          return null;
 164      }
 165  
 166      /**
 167       * Fetches the completion state for a given completion rule.
 168       *
 169       * @param string $rule The completion rule.
 170       * @return int The completion state.
 171       */
 172      abstract public function get_state(string $rule): int;
 173  
 174      /**
 175       * Fetch the list of custom completion rules that this module defines.
 176       *
 177       * @return array
 178       */
 179      abstract public static function get_defined_custom_rules(): array;
 180  
 181      /**
 182       * Returns an associative array of the descriptions of custom completion rules.
 183       *
 184       * @return array
 185       */
 186      abstract public function get_custom_rule_descriptions(): array;
 187  
 188      /**
 189       * Returns an array of all completion rules, in the order they should be displayed to users.
 190       *
 191       * @return array
 192       */
 193      abstract public function get_sort_order(): array;
 194  }