diff --git a/completion/classes/bulkedit_form.php b/completion/classes/bulkedit_form.php
index 061ac53117f..3826a83553e 100644
--- a/completion/classes/bulkedit_form.php
+++ b/completion/classes/bulkedit_form.php
@@ -14,15 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
-/**
- * Bulk edit activity completion form
- *
- * @package core_completion
- * @copyright 2017 Marina Glancy
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die;
+use core_completion\manager;
/**
* Bulk edit activity completion form
@@ -80,26 +72,11 @@ class core_completion_bulkedit_form extends core_completion_edit_base_form {
}
$cm = reset($this->cms);
- $course = $this->course;
- $modname = $cm->modname;
-
- $modmoodleform = "$CFG->dirroot/mod/$modname/mod_form.php";
- if (file_exists($modmoodleform)) {
- require_once($modmoodleform);
- } else {
- throw new \moodle_exception('noformdesc');
- }
-
- list($cmrec, $context, $module, $data, $cw) = get_moduleinfo_data($cm, $course);
- $data->return = 0;
- $data->sr = 0;
- $data->update = $modname;
-
- // Initialise the form but discard all JS requirements it adds, our form has already added them.
- $mformclassname = 'mod_'.$modname.'_mod_form';
- $PAGE->start_collecting_javascript_requirements();
- $this->_moduleform = new $mformclassname($data, 0, $cmrec, $course);
- $PAGE->end_collecting_javascript_requirements();
+ $this->_moduleform = manager::get_module_form(
+ modname: $cm->modname,
+ course: $this->course,
+ cm: $cm,
+ );
return $this->_moduleform;
}
diff --git a/completion/classes/defaultedit_form.php b/completion/classes/defaultedit_form.php
index 8200723e5e8..5880ec26e0c 100644
--- a/completion/classes/defaultedit_form.php
+++ b/completion/classes/defaultedit_form.php
@@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
+use core_completion\manager;
+
/**
* Default activity completion form
*
@@ -68,34 +70,16 @@ class core_completion_defaultedit_form extends core_completion_edit_base_form {
* @return moodleform_mod|null
*/
protected function get_module_form() {
- global $CFG, $PAGE;
-
if ($this->_moduleform) {
return $this->_moduleform;
}
$modnames = array_keys($this->get_module_names());
- $modname = $modnames[0];
- $course = $this->course;
-
- $modmoodleform = "$CFG->dirroot/mod/$modname/mod_form.php";
- if (file_exists($modmoodleform)) {
- require_once($modmoodleform);
- } else {
- throw new \moodle_exception('noformdesc');
- }
-
- list($module, $context, $cw, $cmrec, $data) = prepare_new_moduleinfo_data($course, $modname, 0, $this->get_suffix());
- $data->return = 0;
- $data->sr = 0;
- $data->add = $modname;
-
- // Initialise the form but discard all JS requirements it adds, our form has already added them.
- $mformclassname = 'mod_'.$modname.'_mod_form';
- $PAGE->start_collecting_javascript_requirements();
- $this->_moduleform = new $mformclassname($data, 0, $cmrec, $course);
- $this->_moduleform->set_suffix('_' . $modname);
- $PAGE->end_collecting_javascript_requirements();
+ $this->_moduleform = manager::get_module_form(
+ modname: $modnames[0],
+ course: $this->course,
+ suffix: $this->get_suffix(),
+ );
return $this->_moduleform;
}
diff --git a/completion/classes/edit_base_form.php b/completion/classes/edit_base_form.php
index ff2efd2f247..3cdcc470d79 100644
--- a/completion/classes/edit_base_form.php
+++ b/completion/classes/edit_base_form.php
@@ -109,10 +109,15 @@ abstract class core_completion_edit_base_form extends moodleform {
$component = "mod_{$modnames[0]}";
$itemnames = \core_grades\component_gradeitems::get_itemname_mapping_for_component($component);
$hascustomrules = count($itemnames) > 1;
+ $customcompletionelements = [];
try {
// Add completion rules from the module form to this form.
$moduleform = $this->get_module_form();
+ // If the module doesn't return a form for any reason, we don't continue checking.
+ if (!$moduleform) {
+ return [false, []];
+ }
$moduleform->_form = $this->_form;
if ($customcompletionelements = $moduleform->{$function}()) {
$hascustomrules = true;
@@ -135,7 +140,7 @@ abstract class core_completion_edit_base_form extends moodleform {
} catch (Exception $e) {
debugging('Could not add custom completion rule of module ' . $modnames[0] .
' to this form, this has to be fixed by the developer', DEBUG_DEVELOPER);
- return [$hascustomrules, $customcompletionelements];
+ return [false, $customcompletionelements];
}
}
diff --git a/completion/classes/manager.php b/completion/classes/manager.php
index f2b661a50b8..4c9fc29fbde 100644
--- a/completion/classes/manager.php
+++ b/completion/classes/manager.php
@@ -238,7 +238,12 @@ class manager {
$context = $this->get_context();
$canmanage = has_capability('moodle/course:manageactivities', $context);
$course = get_course($this->courseid);
+ $availablemodules = [];
foreach ($data->modules as $module) {
+ $libfile = "$CFG->dirroot/mod/$module->name/lib.php";
+ if (!file_exists($libfile)) {
+ continue;
+ }
$module->icon = $OUTPUT->image_url('monologo', $module->name)->out();
$module->formattedname = format_string(get_string('modulename', 'mod_' . $module->name),
true, ['context' => $context]);
@@ -248,13 +253,13 @@ class manager {
$defaults->modname = $module->name;
$module->completionstatus = $this->get_completion_detail($defaults);
}
+ $availablemodules[] = $module;
}
// Order modules by displayed name.
- $modules = (array) $data->modules;
- usort($modules, function($a, $b) {
+ usort($availablemodules, function($a, $b) {
return strcmp($a->formattedname, $b->formattedname);
});
- $data->modules = $modules;
+ $data->modules = $availablemodules;
return $data;
}
@@ -591,4 +596,57 @@ class manager {
return $data;
}
+
+ /**
+ * Return a mod_form of the given module.
+ *
+ * @param string $modname Module to get the form from.
+ * @param stdClass $course Course object.
+ * @param ?cm_info $cm cm_info object to use.
+ * @param string $suffix The suffix to add to the name of the completion rules.
+ * @return ?\moodleform_mod The moodleform_mod object if everything goes fine. Null otherwise.
+ */
+ public static function get_module_form(
+ string $modname,
+ stdClass $course,
+ ?cm_info $cm = null,
+ string $suffix = ''
+ ): ?\moodleform_mod {
+ global $CFG, $PAGE;
+
+ $modmoodleform = "$CFG->dirroot/mod/$modname/mod_form.php";
+ if (file_exists($modmoodleform)) {
+ require_once($modmoodleform);
+ } else {
+ throw new \moodle_exception('noformdesc');
+ }
+
+ if ($cm) {
+ [$cmrec, $context, $module, $data, $cw] = get_moduleinfo_data($cm, $course);
+ $data->update = $modname;
+ } else {
+ [$module, $context, $cw, $cmrec, $data] = prepare_new_moduleinfo_data($course, $modname, 0, $suffix);
+ $data->add = $modname;
+ }
+ $data->return = 0;
+ $data->sr = 0;
+
+ // Initialise the form but discard all JS requirements it adds, our form has already added them.
+ $mformclassname = 'mod_'.$modname.'_mod_form';
+ $PAGE->start_collecting_javascript_requirements();
+ try {
+ $moduleform = new $mformclassname($data, 0, $cmrec, $course);
+ if (!$cm) {
+ $moduleform->set_suffix('_' . $modname);
+ }
+ } catch (\Exception $e) {
+ // The form class has thrown an error when instantiating.
+ // This could happen because some conditions for the module are not met.
+ $moduleform = null;
+ } finally {
+ $PAGE->end_collecting_javascript_requirements();
+ }
+
+ return $moduleform;
+ }
}
diff --git a/course/classes/output/bulk_activity_completion_renderer.php b/course/classes/output/bulk_activity_completion_renderer.php
index e7a06767d1e..1d4cd87c729 100644
--- a/course/classes/output/bulk_activity_completion_renderer.php
+++ b/course/classes/output/bulk_activity_completion_renderer.php
@@ -14,13 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
-/**
- * Contains renderers for the bulk activity completion stuff.
- *
- * @package core_course
- * @copyright 2017 Adrian Greeve
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
+use core_completion\manager;
defined('MOODLE_INTERNAL') || die;
@@ -82,7 +76,18 @@ class core_course_bulk_activity_completion_renderer extends plugin_renderer_base
);
$module->modulecollapsed = true;
}
- $module->formhtml = $modform->render();
+
+ $moduleform = manager::get_module_form($module->name, $course);
+ if ($moduleform) {
+ $module->formhtml = $modform->render();
+ } else {
+ // If the module form is not available, then display a message.
+ $module->formhtml = $this->output->notification(
+ get_string('incompatibleplugin', 'completion'),
+ \core\output\notification::NOTIFY_INFO,
+ false
+ );
+ }
}
}
$data->issite = $course->id == SITEID;
diff --git a/lang/en/completion.php b/lang/en/completion.php
index 5a148022ef5..8e036459c42 100644
--- a/lang/en/completion.php
+++ b/lang/en/completion.php
@@ -176,6 +176,7 @@ $string['failed'] = 'Failed';
$string['fraction'] = 'Fraction';
$string['graderequired'] = 'Required course grade';
$string['gradexrequired'] = '{$a} required';
+$string['incompatibleplugin'] = 'This activity does not support default completion settings. Completion conditions must be manually set for each use.';
$string['inprogress'] = 'In progress';
$string['manual'] = 'Manual';
$string['manualcompletionby'] = 'Manual completion by others';