Merge branch 'MDL-78858' of https://github.com/paulholden/moodle
[moodle.git] / completion / classes / activity_custom_completion.php
blobb7f95a421362c361640a42fe2a7f974e3c28c487
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.
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/>.
17 declare(strict_types = 1);
19 namespace core_completion;
21 use cm_info;
22 use coding_exception;
23 use moodle_exception;
25 /**
26 * Base class for defining an activity module's custom completion rules.
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.
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
35 abstract class activity_custom_completion {
37 /** @var cm_info The course module information object. */
38 protected $cm;
40 /** @var int The user's ID. */
41 protected $userid;
43 /** @var array The current state of core completion */
44 protected $completionstate;
46 /**
47 * activity_custom_completion constructor.
49 * @param cm_info $cm
50 * @param int $userid
51 * @param array|null $completionstate The current state of the core completion criteria
53 public function __construct(cm_info $cm, int $userid, ?array $completionstate = null) {
54 $this->cm = $cm;
55 $this->userid = $userid;
56 $this->completionstate = $completionstate;
59 /**
60 * Validates that the custom rule is defined by this plugin and is enabled for this activity instance.
62 * @param string $rule The custom completion rule.
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'");
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.");
76 /**
77 * Whether this module defines this custom rule.
79 * @param string $rule The custom completion rule.
80 * @return bool
82 public function is_defined(string $rule): bool {
83 return in_array($rule, static::get_defined_custom_rules());
86 /**
87 * Checks whether the custom completion rule is being used by the activity module instance.
89 * @param string $rule The custom completion rule.
90 * @return bool
92 public function is_available(string $rule): bool {
93 return in_array($rule, $this->get_available_custom_rules());
96 /**
97 * Fetches the list of custom completion rules that are being used by this activity module instance.
99 * @return array
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;
111 return $availablerules;
115 * Fetches the overall completion status of this activity instance for a user based on its available custom completion rules.
117 * @return int The completion state (e.g. COMPLETION_COMPLETE, COMPLETION_INCOMPLETE).
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;
127 // If this was reached, then all custom rules have been marked complete.
128 return COMPLETION_COMPLETE;
132 * Fetches the description for a given custom completion rule.
134 * @param string $rule The custom completion rule.
135 * @return string
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;
143 return $descriptions[$rule];
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.
151 * @return bool
153 public function manual_completion_always_shown(): bool {
154 return false;
158 * Fetches the module's custom completion class implementation if it's available.
160 * @param string $modname The activity module name. Usually from cm_info::modname.
161 * @return string|null
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;
168 return null;
172 * Fetches the completion state for a given completion rule.
174 * @param string $rule The completion rule.
175 * @return int The completion state.
177 abstract public function get_state(string $rule): int;
180 * Fetch the list of custom completion rules that this module defines.
182 * @return array
184 abstract public static function get_defined_custom_rules(): array;
187 * Returns an associative array of the descriptions of custom completion rules.
189 * @return array
191 abstract public function get_custom_rule_descriptions(): array;
194 * Returns an array of all completion rules, in the order they should be displayed to users.
196 * @return array
198 abstract public function get_sort_order(): array;