diff --git a/course/lib.php b/course/lib.php index d34d9ecbeb2..772dd41e712 100644 --- a/course/lib.php +++ b/course/lib.php @@ -1806,65 +1806,49 @@ function print_section_add_menus($course, $section, $modnames, $vertical=false, return false; } - $urlbase = "/course/mod.php?id=$course->id§ion=$section&sesskey=".sesskey().'&add='; + // Retrieve all modules with associated metadata + $modules = get_module_metadata($course, $modnames); + // We'll sort resources and activities into two lists $resources = array(); $activities = array(); - foreach($modnames as $modname=>$modnamestr) { - if (!course_allowed_module($course, $modname)) { - continue; - } + // We need to add the section section to the link for each module + $sectionlink = '§ion=' . $section; - $libfile = "$CFG->dirroot/mod/$modname/lib.php"; - if (!file_exists($libfile)) { - continue; - } - include_once($libfile); - $gettypesfunc = $modname.'_get_types'; - if (function_exists($gettypesfunc)) { + foreach ($modules as $module) { + if (isset($module->types)) { + // This module has a subtype // NOTE: this is legacy stuff, module subtypes are very strongly discouraged!! - if ($types = $gettypesfunc()) { - $menu = array(); - $atype = null; - $groupname = null; - foreach($types as $type) { - if ($type->typestr === '--') { - continue; - } - if (strpos($type->typestr, '--') === 0) { - $groupname = str_replace('--', '', $type->typestr); - continue; - } - $type->type = str_replace('&', '&', $type->type); - if ($type->modclass == MOD_CLASS_RESOURCE) { - $atype = MOD_CLASS_RESOURCE; - } - $menu[$urlbase.$type->type] = $type->typestr; - } - if (!is_null($groupname)) { - if ($atype == MOD_CLASS_RESOURCE) { - $resources[] = array($groupname=>$menu); - } else { - $activities[] = array($groupname=>$menu); - } + $subtypes = array(); + foreach ($module->types as $subtype) { + $subtypes[$subtype->link . $sectionlink] = $subtype->title; + } + + // Sort module subtypes into the list + if (!empty($module->title)) { + // This grouping has a name + if ($module->archetype == MOD_CLASS_RESOURCE) { + $resources[] = array($module->title=>$subtypes); } else { - if ($atype == MOD_CLASS_RESOURCE) { - $resources = array_merge($resources, $menu); - } else { - $activities = array_merge($activities, $menu); - } + $activities[] = array($module->title=>$subtypes); + } + } else { + // This grouping does not have a name + if ($module->archetype == MOD_CLASS_RESOURCE) { + $resources = array_merge($resources, $subtypes); + } else { + $activities = array_merge($activities, $subtypes); } } } else { - $archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); - if ($archetype == MOD_ARCHETYPE_RESOURCE) { - $resources[$urlbase.$modname] = $modnamestr; - } else if ($archetype === MOD_ARCHETYPE_SYSTEM) { + // This module has no subtypes + if ($module->archetype == MOD_ARCHETYPE_RESOURCE) { + $resources[$module->link . $sectionlink] = $module->title; + } else if ($module->archetype === MOD_ARCHETYPE_SYSTEM) { // System modules cannot be added by user, do not add to dropdown } else { - // all other archetypes are considered activity - $activities[$urlbase.$modname] = $modnamestr; + $activities[$module->link . $sectionlink] = $module->title; } } } @@ -1903,6 +1887,96 @@ function print_section_add_menus($course, $section, $modnames, $vertical=false, } } +/** + * Retrieve all metadata for the requested modules + * + * @param object $course The Course + * @param array $modnames An array containing the list of modules and their + * names + * @return array A list of stdClass objects containing metadata about each + * module + */ +function get_module_metadata($course, $modnames) { + global $CFG, $OUTPUT; + + // get_module_metadata will be called once per section on the page and courses may show + // different modules to one another + static $modlist = array(); + if (!isset($modlist[$course->id])) { + $modlist[$course->id] = array(); + } + + $return = array(); + $urlbase = "/course/mod.php?id=$course->id&sesskey=".sesskey().'&add='; + foreach($modnames as $modname => $modnamestr) { + if (!course_allowed_module($course, $modname)) { + continue; + } + if (isset($modlist[$modname])) { + // This module is already cached + $return[$modname] = $modlist[$course->id][$modname]; + continue; + } + + // Include the module lib + $libfile = "$CFG->dirroot/mod/$modname/lib.php"; + if (!file_exists($libfile)) { + continue; + } + include_once($libfile); + + // NOTE: this is legacy stuff, module subtypes are very strongly discouraged!! + $gettypesfunc = $modname.'_get_types'; + if (function_exists($gettypesfunc)) { + if ($types = $gettypesfunc()) { + $group = new stdClass(); + $group->name = $modname; + $group->icon = $OUTPUT->pix_icon('icon', '', $modname, array('class' => 'icon')); + foreach($types as $type) { + if ($type->typestr === '--') { + continue; + } + if (strpos($type->typestr, '--') === 0) { + $group->title = str_replace('--', '', $type->typestr); + continue; + } + // Set the Sub Type metadata + $subtype = new stdClass(); + $subtype->title = $type->typestr; + $subtype->type = str_replace('&', '&', $type->type); + $subtype->name = preg_replace('/.*type=/', '', $subtype->type); + $subtype->archetype = $type->modclass; + + // The group archetype should match the subtype archetypes and all subtypes + // should have the same archetype + $group->archetype = $subtype->archetype; + + if (get_string_manager()->string_exists('help' . $subtype->name, $modname)) { + $subtype->help = get_string('help' . $subtype->name, $modname); + } + $subtype->link = $urlbase . $type->type; + $group->types[] = $subtype; + } + $modlist[$course->id][$modname] = $group; + } + } else { + $module = new stdClass(); + $module->title = get_string('modulename', $modname); + $module->name = $modname; + $module->link = $urlbase . $modname; + $module->icon = $OUTPUT->pix_icon('icon', '', $module->name, array('class' => 'icon')); + if (get_string_manager()->string_exists('modulename_help', $modname)) { + $module->help = get_string('modulename_help', $modname); + } + $module->archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); + $modlist[$course->id][$modname] = $module; + } + $return[$modname] = $modlist[$course->id][$modname]; + } + + return $return; +} + /** * Return the course category context for the category with id $categoryid, except * that if $categoryid is 0, return the system context.