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 311 and 401]

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