2 // This file is part of Moodle - http://moodle.org/
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.
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
;
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. */
40 /** @var int The user's ID. */
43 /** @var array The current state of core completion */
44 protected $completionstate;
47 * activity_custom_completion constructor.
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) {
55 $this->userid
= $userid;
56 $this->completionstate
= $completionstate;
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.");
77 * Whether this module defines this custom rule.
79 * @param string $rule The custom completion rule.
82 public function is_defined(string $rule): bool {
83 return in_array($rule, static::get_defined_custom_rules());
87 * Checks whether the custom completion rule is being used by the activity module instance.
89 * @param string $rule The custom completion rule.
92 public function is_available(string $rule): bool {
93 return in_array($rule, $this->get_available_custom_rules());
97 * Fetches the list of custom completion rules that are being used by this activity module instance.
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
) {
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.
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.
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.
153 public function manual_completion_always_shown(): bool {
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;
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.
184 abstract public static function get_defined_custom_rules(): array;
187 * Returns an associative array of the descriptions of custom completion rules.
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.
198 abstract public function get_sort_order(): array;