Merge branch 'mdl-83511_500' of https://github.com/james-cnz/moodle into MOODLE_500_STABLE

This commit is contained in:
Mihail Geshoski
2025-10-08 13:13:36 +08:00
7 changed files with 54 additions and 23 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+23 -12
View File
@@ -120,7 +120,8 @@ const registerListenerEvents = (courseId, chooserConfig) => {
document.addEventListener(event, async(e) => {
if (e.target.closest(selectors.elements.sectionmodchooser)) {
let caller;
let sectionnum;
let sectionnum = null;
let sectionid = null;
// We need to know who called this.
// Standard courses use the ID in the main section info.
const sectionDiv = e.target.closest(selectors.elements.section);
@@ -135,17 +136,18 @@ const registerListenerEvents = (courseId, chooserConfig) => {
// We check for attributes just in case of outdated contrib course formats.
caller = sectionDiv;
sectionnum = sectionDiv.getAttribute('data-number');
sectionid = sectionDiv.getAttribute('data-id');
} else {
caller = button;
if (caller.hasAttribute('data-sectionid')) {
window.console.warn(
'The data-sectionid attribute has been deprecated. ' +
'Please update your code to use data-sectionnum instead.'
'Please update your code to use data-section-id passing the real section ID instead.'
);
caller.setAttribute('data-sectionnum', caller.dataset.sectionid);
}
sectionnum = caller.dataset.sectionnum;
sectionid = caller.getAttribute('data-section-id');
}
// We want to show the modal instantly but loading whilst waiting for our data.
@@ -176,13 +178,14 @@ const registerListenerEvents = (courseId, chooserConfig) => {
data,
sectionnum,
caller.dataset.sectionreturnnum,
caller.dataset.beforemod
caller.dataset.beforemod,
sectionid
);
ChooserDialogue.displayChooser(
sectionModal,
builtModuleData,
partiallyAppliedFavouriteManager(data, sectionnum),
partiallyAppliedFavouriteManager(data, sectionnum, sectionid),
footerData,
);
@@ -206,16 +209,22 @@ const registerListenerEvents = (courseId, chooserConfig) => {
* @param {Number} num The number of the section we need to append to the links
* @param {Number|null} sectionreturnnum The number of the section return we need to append to the links
* @param {Number|null} beforemod The ID of the cm we need to append to the links
* @param {Number|null} id The number of the section we need to append to the links
* @return {Array} [modules] with URL's built
*/
const sectionMapper = (webServiceData, num, sectionreturnnum, beforemod) => {
const sectionMapper = (webServiceData, num, sectionreturnnum, beforemod, id = null) => {
// We need to take a fresh deep copy of the original data as an object is a reference type.
const newData = JSON.parse(JSON.stringify(webServiceData));
let urlParams = '&beforemod=' + (beforemod ?? 0);
if (id) {
urlParams += `&sectionid=${id}`;
}
urlParams += `&section=${num}`;
if (sectionreturnnum) {
urlParams += `&sr=${sectionreturnnum}`;
}
newData.content_items.forEach((module) => {
module.link += '&section=' + num + '&beforemod=' + (beforemod ?? 0);
if (sectionreturnnum) {
module.link += '&sr=' + sectionreturnnum;
}
module.link += urlParams;
});
return newData.content_items;
};
@@ -368,9 +377,11 @@ const nullFavouriteDomManager = (favouriteTabNav, modalBody) => {
* @method partiallyAppliedFavouriteManager
* @param {Array} moduleData This is our raw WS data that we need to manipulate
* @param {Number} sectionnum We need this to add the sectionnum to the URL's in the faves area after rerender
* @param {Number|null} sectionid We need this to add the sectionid to the URL's in the faves area
* Section ID is preferred over section number, as section numbers can change.
* @return {Function} partially applied function so we can manipulate DOM nodes easily & update our internal array
*/
const partiallyAppliedFavouriteManager = (moduleData, sectionnum) => {
const partiallyAppliedFavouriteManager = (moduleData, sectionnum, sectionid = null) => {
/**
* Curried function that is being returned.
*
@@ -393,7 +404,7 @@ const partiallyAppliedFavouriteManager = (moduleData, sectionnum) => {
// eslint-disable-next-line camelcase
newFaves.content_items = moduleData.content_items.filter(mod => mod.favourite === true);
const builtFaves = sectionMapper(newFaves, sectionnum);
const builtFaves = sectionMapper(newFaves, sectionnum, null, null, sectionid);
const {html, js} = await Templates.renderForPromise('core_course/local/activitychooser/favourites',
{favourites: builtFaves});
@@ -72,7 +72,9 @@ class activitychooserbutton implements templatable, renderable {
);
return (object)[
'sectionnum' => $this->section->section,
// We keep the old sectionnum properties for backwards compatibility.
'sectionnum' => $this->section->sectionnum,
'sectionid' => $this->section->id,
'sectionname' => get_section_name($this->section->course, $this->section),
'sectionreturn' => $this->sectionreturn ?? false,
'modid' => $this->mod ? $this->mod->id : false,
+8 -2
View File
@@ -76,16 +76,22 @@ require_login();
//check if we are adding / editing a module that has new forms using formslib
if (!empty($add)) {
$id = required_param('id', PARAM_INT);
$section = required_param('section', PARAM_INT);
$sectionid = optional_param('sectionid', null, PARAM_INT);
$type = optional_param('type', '', PARAM_ALPHA);
$returntomod = optional_param('return', 0, PARAM_BOOL);
$beforemod = optional_param('beforemod', 0, PARAM_INT);
if (empty($sectionid)) {
$section = required_param('section', PARAM_INT);
$sectioninfo = get_fast_modinfo($id)->get_section_info($section);
$sectionid = $sectioninfo?->id;
}
$params = [
'add' => $add,
'type' => $type,
'course' => $id,
'section' => $section,
'sectionid' => $sectionid,
'return' => $returntomod,
'beforemod' => $beforemod,
];
+12 -6
View File
@@ -56,11 +56,17 @@ if (!empty($showonly)) {
}
if (!empty($add)) {
$section = required_param('section', PARAM_INT);
$course = required_param('course', PARAM_INT);
$sectionid = optional_param('sectionid', null, PARAM_INT);
if (empty($sectionid)) {
$sectionnum = required_param('section', PARAM_INT);
} else {
$sectionnum = get_fast_modinfo($course)->get_section_info_by_id($sectionid, MUST_EXIST)->sectionnum;
}
$url->param('add', $add);
$url->param('section', $section);
$url->param('section', $sectionnum);
$url->param('course', $course);
$PAGE->set_url($url);
@@ -70,18 +76,18 @@ if (!empty($add)) {
// There is no page for this in the navigation. The closest we'll have is the course section.
// If the course section isn't displayed on the navigation this will fall back to the course which
// will be the closest match we have.
navigation_node::override_active_url(course_get_url($course, $section));
navigation_node::override_active_url(course_get_url($course, $sectionnum));
// MDL-69431 Validate that $section (url param) does not exceed the maximum for this course / format.
// MDL-69431 Validate that $sectionnum (from url param) does not exceed the maximum for this course / format.
// If too high (e.g. section *id* not number) non-sequential sections inserted in course_sections table.
// Then on import, backup fills 'gap' with empty sections (see restore_rebuild_course_cache). Avoid this.
$courseformat = course_get_format($course);
$maxsections = $courseformat->get_max_sections();
if ($section > $maxsections) {
if ($sectionnum > $maxsections) {
throw new \moodle_exception('maxsectionslimit', 'moodle', '', $maxsections);
}
list($module, $context, $cw, $cm, $data) = prepare_new_moduleinfo_data($course, $add, $section);
[$module, $context, $cw, $cm, $data] = prepare_new_moduleinfo_data($course, $add, $sectionnum);
$data->return = 0;
if (!is_null($sectionreturn)) {
$data->sr = $sectionreturn;
@@ -22,6 +22,7 @@
Example context (json):
{
"sectionnum": 0,
"sectionid": 0,
"modid": 1,
"activityname": "Activity example",
"sectionreturn": 0
@@ -32,6 +33,11 @@
}}{{#hasactionlinks}}dropdown-item{{/hasactionlinks}}"
data-action="open-chooser"
data-sectionnum="{{sectionnum}}"
{{!
data-sectionid was wrongly used for the section number in Moodle 4.4,
so we use data-section-id instead for now.
}}
{{#sectionid}}data-section-id="{{.}}"{{/sectionid}}
{{#sectionreturn}}data-sectionreturnnum="{{.}}"{{/sectionreturn}}
{{#modid}}
data-beforemod="{{modid}}"