diff --git a/course/classes/local/repository/content_item_readonly_repository.php b/course/classes/local/repository/content_item_readonly_repository.php index 54e58156d54..32bd29d2880 100644 --- a/course/classes/local/repository/content_item_readonly_repository.php +++ b/course/classes/local/repository/content_item_readonly_repository.php @@ -61,63 +61,6 @@ class content_item_readonly_repository implements content_item_readonly_reposito return $help; } - /** - * Create a content_item object based on legacy data returned from the get_shortcuts hook implementations. - * - * @param \stdClass $item the stdClass of legacy data. - * @return content_item a content item object. - */ - private function content_item_from_legacy_data(\stdClass $item): content_item { - global $OUTPUT; - - // Make sure the legacy data results in a content_item with id = 0. - // Even with an id, we can't uniquely identify the item, because we can't guarantee what component it came from. - // An id of -1, signifies this. - $item->id = -1; - - // If the module provides the helplink property, append it to the help text to match the look and feel - // of the default course modules. - if (isset($item->help) && isset($item->helplink)) { - $linktext = get_string('morehelp'); - $item->help .= \html_writer::tag('div', - $OUTPUT->doc_link($item->helplink, $linktext, true), ['class' => 'helpdoclink']); - } - - if (is_string($item->title)) { - $item->title = new string_title($item->title); - } else if ($item->title instanceof \lang_string) { - $item->title = new lang_string_title($item->title->get_identifier(), $item->title->get_component()); - } - - // Legacy items had names which are in one of 2 forms: - // modname, i.e. 'assign' or - // modname:link, i.e. lti:http://etc... - // We need to grab the module name out to create the componentname. - $modname = (strpos($item->name, ':') !== false) ? explode(':', $item->name)[0] : $item->name; - $purpose = plugin_supports('mod', $modname, FEATURE_MOD_PURPOSE, MOD_PURPOSE_OTHER); - return new content_item($item->id, $item->name, $item->title, $item->link, $item->icon, $item->help ?? '', - $item->archetype, 'mod_' . $modname, $purpose); - } - - /** - * Create a stdClass type object based on a content_item instance. - * - * @param content_item $contentitem - * @return \stdClass the legacy data. - */ - private function content_item_to_legacy_data(content_item $contentitem): \stdClass { - $item = new \stdClass(); - $item->id = $contentitem->get_id(); - $item->name = $contentitem->get_name(); - $item->title = $contentitem->get_title(); - $item->link = $contentitem->get_link(); - $item->icon = $contentitem->get_icon(); - $item->help = $contentitem->get_help(); - $item->archetype = $contentitem->get_archetype(); - $item->componentname = $contentitem->get_component_name(); - return $item; - } - /** * Helper to get the contentitems from all subplugin hooks for a given module plugin. * @@ -165,20 +108,6 @@ class content_item_readonly_repository implements content_item_readonly_reposito return $contentitems; } - /** - * Helper to make sure any legacy items have certain properties, which, if missing are inherited from the parent module item. - * - * @param \stdClass $legacyitem the legacy information, a stdClass coming from get_shortcuts() hook. - * @param content_item $modulecontentitem The module's content item information, to inherit if needed. - * @return \stdClass the updated legacy item stdClass - */ - private function legacy_item_inherit_missing(\stdClass $legacyitem, content_item $modulecontentitem): \stdClass { - // Fall back to the plugin parent value if the subtype didn't provide anything. - $legacyitem->archetype = $legacyitem->archetype ?? $modulecontentitem->get_archetype(); - $legacyitem->icon = $legacyitem->icon ?? $modulecontentitem->get_icon(); - return $legacyitem; - } - /** * Find all the available content items, not restricted to course or user. * @@ -254,9 +183,6 @@ class content_item_readonly_repository implements content_item_readonly_reposito $modules = $DB->get_records('modules', ['visible' => 1]); $return = []; - // A moodle_url is expected and required by modules in their implementation of the hook 'get_shortcuts'. - $urlbase = new \moodle_url('/course/mod.php', ['id' => $course->id]); - // Now, generate the content_items. foreach ($modules as $modid => $mod) { // Exclude modules if the code doesn't exist. @@ -273,7 +199,7 @@ class content_item_readonly_repository implements content_item_readonly_reposito $mod->id, $mod->name, new lang_string_title("modulename", $mod->name), - new \moodle_url($urlbase, ['add' => $mod->name]), + new \moodle_url('/course/mod.php', ['id' => $course->id, 'add' => $mod->name]), $OUTPUT->pix_icon('monologo', '', $mod->name, ['class' => 'icon activityicon']), $help, $archetype, @@ -281,10 +207,6 @@ class content_item_readonly_repository implements content_item_readonly_reposito $purpose, ); - // Legacy vs new hooks. - // If the new hook is found for a module plugin, use that path (calling mod plugins and their subplugins directly) - // If not, check the legacy hook. This won't provide us with enough information to identify items uniquely within their - // component (lti + lti source being an example), but we can still list these items. $modcontentitemreference = clone($contentitem); if (component_callback_exists('mod_' . $mod->name, 'get_course_content_items')) { @@ -301,37 +223,8 @@ class content_item_readonly_repository implements content_item_readonly_reposito array_push($return, ...$subpluginitems); } - } else if (component_callback_exists('mod_' . $mod->name, 'get_shortcuts')) { - // TODO: MDL-68011 this block needs to be removed in 4.1. - debugging('The callback get_shortcuts has been deprecated. Please use get_course_content_items and - get_all_content_items instead. Some features of the activity chooser, such as favourites and recommendations - are not supported when providing content items via the deprecated callback.'); - - // If get_shortcuts() callback is defined, the default module action is not added. - // It is a responsibility of the callback to add it to the return value unless it is not needed. - // The legacy hook, get_shortcuts, expects a stdClass representation of the core module content_item entry. - $modcontentitemreference = $this->content_item_to_legacy_data($contentitem); - - $legacyitems = component_callback($mod->name, 'get_shortcuts', [$modcontentitemreference], null); - if (!is_null($legacyitems)) { - foreach ($legacyitems as $legacyitem) { - - $legacyitem = $this->legacy_item_inherit_missing($legacyitem, $contentitem); - - // All items must have different links, use them as a key in the return array. - // If plugin returned the only one item with the same link as default item - keep $modname, - // otherwise append the link url to the module name. - $legacyitem->name = (count($legacyitems) == 1 && - $legacyitem->link->out() === $contentitem->get_link()->out()) ? $mod->name : $mod->name . ':' . - $legacyitem->link; - - $plugincontentitem = $this->content_item_from_legacy_data($legacyitem); - - $return[] = $plugincontentitem; - } - } } else { - // Neither callback was found, so just use the default module content item. + // Callback was not found, so just use the default module content item. $return[] = $contentitem; } } diff --git a/course/format/singleactivity/lib.php b/course/format/singleactivity/lib.php index 7f6161ce47a..6a2dd522006 100644 --- a/course/format/singleactivity/lib.php +++ b/course/format/singleactivity/lib.php @@ -378,7 +378,6 @@ class format_singleactivity extends core_courseformat\base { /** * Checks if the activity type has multiple items in the activity chooser. - * This may happen as a result of defining callback modulename_get_shortcuts(). * * @return bool|null (null if the check is not possible) */ diff --git a/course/renderer.php b/course/renderer.php index 27c53644075..bbd2f69be65 100644 --- a/course/renderer.php +++ b/course/renderer.php @@ -134,17 +134,10 @@ class core_course_renderer extends plugin_renderer_base { } /** - * Build the HTML for the module chooser javascript popup - * - * @param array $modules A set of modules as returned form @see - * get_module_metadata - * @param object $course The course that will be displayed - * @return string The composed HTML for the module + * @deprecated since 3.9 */ - public function course_modchooser($modules, $course) { - debugging('course_modchooser() is deprecated. Please use course_activitychooser() instead.', DEBUG_DEVELOPER); - - return $this->course_activitychooser($course->id); + public function course_modchooser() { + throw new coding_exception('course_modchooser() can not be used anymore, please use course_activitychooser() instead.'); } /** diff --git a/course/upgrade.txt b/course/upgrade.txt index 776509a3cdb..d5e7973311b 100644 --- a/course/upgrade.txt +++ b/course/upgrade.txt @@ -1,6 +1,10 @@ This files describes API changes in /course/*, information provided here is intended especially for developers. +=== 4.1 === +* The function course_modchooser() has been finally deprecated and can not be used anymore. Please use + course_activitychooser() instead. + === 4.0 === * All activity icons have been replaced with black monochrome icons. The background colour for these icons is defined using a new 'FEATURE_MOD_PURPOSE' support variable in the module lib.php file diff --git a/lib/deprecatedlib.php b/lib/deprecatedlib.php index 7c7a439922e..9bd6669838f 100644 --- a/lib/deprecatedlib.php +++ b/lib/deprecatedlib.php @@ -2770,102 +2770,11 @@ function report_insights_context_insights(\context $context) { } /** - * Retrieve all metadata for the requested modules - * - * @deprecated since 3.9. - * @param object $course The Course - * @param array $modnames An array containing the list of modules and their - * names - * @param int $sectionreturn The section to return to - * @return array A list of stdClass objects containing metadata about each - * module + * @deprecated since 3.9 */ -function get_module_metadata($course, $modnames, $sectionreturn = null) { - global $OUTPUT; - - debugging('get_module_metadata is deprecated. Please use \core_course\local\service\content_item_service instead.'); - - // 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 = new moodle_url('/course/mod.php', array('id' => $course->id, 'sesskey' => sesskey())); - if ($sectionreturn !== null) { - $urlbase->param('sr', $sectionreturn); - } - foreach($modnames as $modname => $modnamestr) { - if (!course_allowed_module($course, $modname)) { - continue; - } - if (isset($modlist[$course->id][$modname])) { - // This module is already cached - $return += $modlist[$course->id][$modname]; - continue; - } - $modlist[$course->id][$modname] = array(); - - // Create an object for a default representation of this module type in the activity chooser. It will be used - // if module does not implement callback get_shortcuts() and it will also be passed to the callback if it exists. - $defaultmodule = new stdClass(); - $defaultmodule->title = $modnamestr; - $defaultmodule->name = $modname; - $defaultmodule->link = new moodle_url($urlbase, array('add' => $modname)); - $defaultmodule->icon = $OUTPUT->pix_icon('icon', '', $defaultmodule->name, array('class' => 'icon')); - $sm = get_string_manager(); - if ($sm->string_exists('modulename_help', $modname)) { - $defaultmodule->help = get_string('modulename_help', $modname); - if ($sm->string_exists('modulename_link', $modname)) { // Link to further info in Moodle docs. - $link = get_string('modulename_link', $modname); - $linktext = get_string('morehelp'); - $defaultmodule->help .= html_writer::tag('div', - $OUTPUT->doc_link($link, $linktext, true), array('class' => 'helpdoclink')); - } - } - $defaultmodule->archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); - - // Each module can implement callback modulename_get_shortcuts() in its lib.php and return the list - // of elements to be added to activity chooser. - $items = component_callback($modname, 'get_shortcuts', array($defaultmodule), null); - if ($items !== null) { - foreach ($items as $item) { - // Add all items to the return array. All items must have different links, use them as a key in the return array. - if (!isset($item->archetype)) { - $item->archetype = $defaultmodule->archetype; - } - if (!isset($item->icon)) { - $item->icon = $defaultmodule->icon; - } - // If plugin returned the only one item with the same link as default item - cache it as $modname, - // otherwise append the link url to the module name. - $item->name = (count($items) == 1 && - $item->link->out() === $defaultmodule->link->out()) ? $modname : $modname . ':' . $item->link; - - // If the module provides the helptext property, append it to the help text to match the look and feel - // of the default course modules. - if (isset($item->help) && isset($item->helplink)) { - $linktext = get_string('morehelp'); - $item->help .= html_writer::tag('div', - $OUTPUT->doc_link($item->helplink, $linktext, true), array('class' => 'helpdoclink')); - } - $modlist[$course->id][$modname][$item->name] = $item; - } - $return += $modlist[$course->id][$modname]; - // If get_shortcuts() callback is defined, the default module action is not added. - // It is a responsibility of the callback to add it to the return value unless it is not needed. - continue; - } - - // The callback get_shortcuts() was not found, use the default item for the activity chooser. - $modlist[$course->id][$modname][$modname] = $defaultmodule; - $return[$modname] = $defaultmodule; - } - - core_collator::asort_objects_by_property($return, 'title'); - return $return; +function get_module_metadata() { + throw new coding_exception( + 'get_module_metadata() has been removed. Please use \core_course\local\service\content_item_service instead.'); } /** diff --git a/lib/upgrade.txt b/lib/upgrade.txt index bd358165798..cded6d8f4b1 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -37,6 +37,7 @@ information provided here is intended especially for developers. * Added $CFG->proxylogunsafe and proxyfixunsafe to detect code which doesn't honor the proxy config * Function admin_externalpage_setup() now has additional option 'nosearch' allowing to remove Site administration search form. * The function print_error has been deprecated. Kindly use moodle_exception. +* The function get_module_metadata() has been finally deprecated and can not be used anymore. === 4.0 === diff --git a/mod/lti/deprecatedlib.php b/mod/lti/deprecatedlib.php new file mode 100644 index 00000000000..bf00925c88d --- /dev/null +++ b/mod/lti/deprecatedlib.php @@ -0,0 +1,32 @@ +. + +/** + * List of deprecated mod_lti functions. + * + * @package mod_lti + * @copyright 2022 Mihail Geshoski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * @deprecated since 3.9 + **/ +function lti_get_shortcuts() { + throw new coding_exception( + 'The callback get_shortcuts() is now removed. Please use get_course_content_items and get_all_content_items instead.' + ); +} diff --git a/mod/lti/lib.php b/mod/lti/lib.php index 528bc2c863c..bfe7cd71e28 100644 --- a/mod/lti/lib.php +++ b/mod/lti/lib.php @@ -225,39 +225,6 @@ function lti_delete_instance($id) { } -/** - * Return aliases of this activity. LTI should have an alias for each configured tool type - * This is so you can add an external tool types directly to the activity chooser - * - * @deprecated since 3.9 - * @todo MDL-68011 This is to be moved from here to deprecatedlib.php in Moodle 4.1 - * @param stdClass $defaultitem default item that would be added to the activity chooser if this callback was not present. - * It has properties: archetype, name, title, help, icon, link - * @return array An array of aliases for this activity. Each element is an object with same list of properties as $defaultitem, - * plus an additional property, helplink. - * Properties title and link are required - **/ -function lti_get_shortcuts($defaultitem) { - global $CFG, $COURSE; - require_once($CFG->dirroot.'/mod/lti/locallib.php'); - - $types = lti_get_configured_types($COURSE->id, $defaultitem->link->param('sr')); - if (has_capability('mod/lti:addmanualinstance', context_course::instance($COURSE->id))) { - $types[] = $defaultitem; - } - - // Add items defined in ltisource plugins. - foreach (core_component::get_plugin_list('ltisource') as $pluginname => $dir) { - // LTISOURCE plugins can also implement callback get_shortcuts() to add items to the activity chooser. - // The return values are the same as of the 'mod' callbacks except that $defaultitem is only passed for reference and - // should not be added to the return value. - if ($moretypes = component_callback("ltisource_$pluginname", 'get_shortcuts', array($defaultitem))) { - $types = array_merge($types, $moretypes); - } - } - return $types; -} - /** * Return the preconfigured tools which are configured for inclusion in the activity picker. * diff --git a/mod/lti/source/upgrade.txt b/mod/lti/source/upgrade.txt index 59239721ab2..0951dd1e3b3 100644 --- a/mod/lti/source/upgrade.txt +++ b/mod/lti/source/upgrade.txt @@ -1,6 +1,10 @@ This files describes API changes in /mod/lti/source/* - LTI source plugins, information provided here is intended especially for developers. +=== 4.1 === + +* The callback get_shortcuts() is now removed. Please use get_course_content_items and get_all_content_items instead. + === 3.9 === * The callback get_shortcuts() is now deprecated. Please use get_course_content_items and get_all_content_items instead. diff --git a/mod/lti/upgrade.txt b/mod/lti/upgrade.txt index 318c625ce78..5fed05c84b1 100644 --- a/mod/lti/upgrade.txt +++ b/mod/lti/upgrade.txt @@ -1,5 +1,9 @@ This files describes API changes in the lti code. +=== 4.1 === + +* The callback get_shortcuts() is now removed. Please use get_course_content_items and get_all_content_items instead. + === 3.10 === * Select Content supports multiple, allowing a tool to return more than one link at a time. diff --git a/mod/upgrade.txt b/mod/upgrade.txt index 3c5fd2d0040..df69896e334 100644 --- a/mod/upgrade.txt +++ b/mod/upgrade.txt @@ -1,6 +1,10 @@ This files describes API changes in /mod/* - activity modules, information provided here is intended especially for developers. +=== 4.1 === + +* The callback get_shortcuts() is now removed. Please use get_course_content_items and get_all_content_items instead. + === 4.0 === * A new API function introduced to handle custom completion logic. Refer to completion/upgrade.txt for additional information. * Modules that extend the settings navigation via '_extend_settings_navigation()' should use the get_page() method from diff --git a/theme/upgrade.txt b/theme/upgrade.txt index d4e6038ff70..c2fa7046373 100644 --- a/theme/upgrade.txt +++ b/theme/upgrade.txt @@ -1,6 +1,10 @@ This files describes API changes in /theme/* themes, information provided here is intended especially for theme designer. +=== 4.1 === +* The function core_course_renderer::course_modchooser() has been finally deprecated and can not be used anymore. + Please use core_course_renderer::course_activitychooser() instead. + === 4.0 === * A new theme config 'removedprimarynavitems' allows a theme to customise primary navigation by specifying the list of items to remove. * A new theme config 'usescourseindex' allows a theme to specify whether it implements and uses course index.