diff --git a/course/lib.php b/course/lib.php index 3335c67c253..5e30aa553ec 100644 --- a/course/lib.php +++ b/course/lib.php @@ -2981,7 +2981,11 @@ function include_course_editor(course_format $format) { function get_sorted_course_formats($enabledonly = false) { global $CFG; - $formats = core_plugin_manager::instance()->get_installed_plugins('format'); + // Include both formats that exist on disk (but might not have been installed yet), and those + // which were installed but no longer exist on disk. + $installedformats = core_plugin_manager::instance()->get_installed_plugins('format'); + $existingformats = core_component::get_plugin_list('format'); + $formats = array_merge($installedformats, $existingformats); if (!empty($CFG->format_plugins_sortorder)) { $order = explode(',', $CFG->format_plugins_sortorder); diff --git a/course/tests/courselib_test.php b/course/tests/courselib_test.php index d6c38ddf46c..1cb2f4cef8c 100644 --- a/course/tests/courselib_test.php +++ b/course/tests/courselib_test.php @@ -7501,4 +7501,36 @@ class courselib_test extends advanced_testcase { $this->assertEquals('course_sections', $event->objecttable); $this->assertEquals($section->id, $event->objectid); } + + /** + * Tests get_sorted_course_formats returns all plugins in cases where plugins are installed now, + * installed previously but no longer exist, or not installed yet. + * + * @covers ::get_sorted_course_formats() + */ + public function test_get_sorted_course_formats_installed_or_not(): void { + global $DB; + + $this->resetAfterTest(); + + // By default returns all course formats. + $formats = get_sorted_course_formats(); + $this->assertEquals(['topics', 'weeks', 'singleactivity', 'social'], $formats); + + // If there is an extra format installed that no longer exists, include in list (at end). + $DB->insert_record('config_plugins', [ + 'plugin' => 'format_frogs', + 'name' => 'version', + 'value' => '20240916', + ]); + \core\plugin_manager::reset_caches(); + $formats = get_sorted_course_formats(); + $this->assertEquals(['topics', 'weeks', 'singleactivity', 'social', 'frogs'], $formats); + + // If one of the formats is not installed yet, we still return it. + $DB->delete_records('config_plugins', ['plugin' => 'format_weeks']); + \core\plugin_manager::reset_caches(); + $formats = get_sorted_course_formats(); + $this->assertEquals(['topics', 'weeks', 'singleactivity', 'social', 'frogs'], $formats); + } }