From f166b15b28f8d0d6d5c16d3cbbd6300280d875a5 Mon Sep 17 00:00:00 2001 From: ferranrecio Date: Wed, 12 Jun 2024 13:49:40 +0200 Subject: [PATCH] MDL-81769 core_courseformat: prevent delegated section modules actions --- course/format/classes/stateactions.php | 24 ++++++++++++++++++++++++ course/lib.php | 6 ++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/course/format/classes/stateactions.php b/course/format/classes/stateactions.php index 34535375d96..8ee286a717c 100644 --- a/course/format/classes/stateactions.php +++ b/course/format/classes/stateactions.php @@ -705,6 +705,10 @@ class stateactions { $this->validate_cms($course, $ids, __FUNCTION__, ['moodle/course:manageactivities']); $modinfo = get_fast_modinfo($course); $cms = $this->get_cm_info($modinfo, $ids); + $cms = $this->filter_cms_with_section_delegate($cms); + if (empty($cms)) { + return; + } list($insql, $inparams) = $DB->get_in_or_equal(array_keys($cms), SQL_PARAMS_NAMED); $DB->set_field_select('course_modules', 'indent', $indent, "id $insql", $inparams); rebuild_course_cache($course->id, false, true); @@ -1071,6 +1075,26 @@ class stateactions { } } + /** + * Remove course modules with section delegate from a list. + * + * @param cm_info[] $cms the list of course modules to filter. + * @return cm_info[] the filtered list of course modules indexed by id. + */ + protected function filter_cms_with_section_delegate(array $cms): array { + $filtered = []; + $modules = []; + foreach ($cms as $cm) { + if (!isset($modules[$cm->module])) { + $modules[$cm->module] = sectiondelegate::has_delegate_class('mod_' . $cm->modname); + } + if (!$modules[$cm->module]) { + $filtered[$cm->id] = $cm; + } + } + return $filtered; + } + /** * Checks related to sections: course format support them, all given sections exist and topic 0 is not included. * diff --git a/course/lib.php b/course/lib.php index 3a3fb8f556a..37a28627d1b 100644 --- a/course/lib.php +++ b/course/lib.php @@ -29,6 +29,7 @@ use core\hook; use core_course\external\course_summary_exporter; use core_courseformat\base as course_format; use core_courseformat\formatactions; +use core_courseformat\sectiondelegate; use core\output\local\action_menu\subpanel as action_menu_subpanel; require_once($CFG->libdir.'/completionlib.php'); @@ -1430,6 +1431,7 @@ function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null) { $courseformat = course_get_format($mod->get_course()); $usecomponents = $courseformat->supports_components(); $sectioninfo = $mod->get_section_info(); + $hasdelegatesection = sectiondelegate::has_delegate_class('mod_'.$mod->modname); $editcaps = array('moodle/course:manageactivities', 'moodle/course:activityvisibility', 'moodle/role:assign'); $dupecaps = array('moodle/backup:backuptargetimport', 'moodle/restore:restoretargetimport'); @@ -1488,7 +1490,7 @@ function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null) { } // Indent. - if ($hasmanageactivities && $indent >= 0) { + if ($hasmanageactivities && $indent >= 0 && !$hasdelegatesection) { $indentlimits = new stdClass(); $indentlimits->min = 0; // Legacy indentation could continue using a limit of 16, @@ -1569,7 +1571,7 @@ function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null) { } // Assign. - if (has_capability('moodle/role:assign', $modcontext)){ + if (has_capability('moodle/role:assign', $modcontext) && !$hasdelegatesection) { $actions['assign'] = new action_menu_link_secondary( new moodle_url('/admin/roles/assign.php', array('contextid' => $modcontext->id)), new pix_icon('t/assignroles', '', 'moodle', array('class' => 'iconsmall')),