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';