Merge branch 'MDL-84291-main-v03' of https://github.com/ferranrecio/moodle

This commit is contained in:
Sara Arjona
2025-06-03 17:12:24 +02:00
35 changed files with 236 additions and 269 deletions
@@ -0,0 +1,8 @@
issueNumber: MDL-84291
notes:
core_courseformat:
- message: >-
The maxsections setting is now considered deprecated and will be removed
in Moodle 6.0. Consider implementing your own setting in your format
plugin if needed.
type: deprecated
@@ -0,0 +1,8 @@
issueNumber: MDL-84291
notes:
format_weeks:
- message: >-
The weekly sections format now has a system setting called Maximum
initial number of weeks that replaced the old "Max sections" when
creating a new course
type: improved
@@ -0,0 +1,8 @@
issueNumber: MDL-84291
notes:
format_topics:
- message: >-
Now the custom sections format won't ask for initial sections on the
creation form. Instead it will use the system number of sections
settings directly.
type: improved
@@ -0,0 +1,8 @@
issueNumber: MDL-84291
notes:
core_courseformat:
- message: >-
The param $maxsections of get_num_sections_data in addsection output is
not used anymore. If your format overrides this method, you should add
a default value 0 to be consistent with the new implementation.
type: changed
@@ -0,0 +1,7 @@
issueNumber: MDL-84291
notes:
core_courseformat:
- message: >-
The format base method get_max_sections has been deprecated, as the
maxsections setting is also deprecated and no longer in use.
type: deprecated
+1
View File
@@ -93,6 +93,7 @@ class manager {
'adminpresets_admin_settings_country_select' => 'adminpresets_admin_setting_configmultiselect_with_loader',
'adminpresets_admin_settings_coursecat_select' => 'adminpresets_admin_setting_configmultiselect_with_loader',
'adminpresets_admin_settings_h5plib_handler_select' => 'adminpresets_admin_setting_configselect',
// TODO: remove adminpresets_admin_settings_num_course_sections in Moodle 6.0 (MDL-85272).
'adminpresets_admin_settings_num_course_sections' => 'adminpresets_admin_setting_configmultiselect_with_loader',
'adminpresets_admin_settings_sitepolicy_handler_select' => 'adminpresets_admin_setting_configselect',
'adminpresets_antivirus_clamav_pathtounixsocket_setting' => 'adminpresets_admin_setting_configtext',
+8 -2
View File
@@ -157,11 +157,17 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
$temp->add(new admin_setting_configselect('moodlecourse/format', new lang_string('format'), new lang_string('coursehelpformat'),
'topics', $formcourseformats));
// TODO: remove this setting in Moodle 6.0 (MDL-85272).
$temp->add(new admin_setting_configtext('moodlecourse/maxsections', new lang_string('maxnumberweeks'),
new lang_string('maxnumberweeks_desc'), 52));
$temp->add(new admin_settings_num_course_sections('moodlecourse/numsections', new lang_string('numberweeks'),
new lang_string('coursehelpnumberweeks'), 4));
$temp->add(new admin_setting_configtext(
name: 'moodlecourse/numsections',
visiblename: new lang_string('numberweeks'),
description: new lang_string('coursehelpnumberweeks'),
defaultsetting: 4,
paramtype: PARAM_INT,
));
$choices = array();
$choices['0'] = new lang_string('hiddensectionscollapsed');
-13
View File
@@ -48,7 +48,6 @@ require_sesskey();
$desirednumsections = 0;
$courseformat = course_get_format($course);
$lastsectionnumber = $courseformat->get_last_section_number();
$maxsections = $courseformat->get_max_sections();
if (isset($courseformatoptions['numsections']) && $increase !== null) {
$desirednumsections = $courseformatoptions['numsections'] + 1;
@@ -57,18 +56,6 @@ if (isset($courseformatoptions['numsections']) && $increase !== null) {
$desirednumsections = $lastsectionnumber + $numsections;
}
if ($desirednumsections > $maxsections) {
// Increase in number of sections is not allowed.
\core\notification::warning(get_string('maxsectionslimit', 'moodle', $maxsections));
$increase = null;
$insertsection = null;
$numsections = 0;
if (!$returnurl) {
$returnurl = course_get_url($course);
}
}
if (isset($courseformatoptions['numsections']) && $increase !== null) {
if ($increase) {
// Add an additional section.
@@ -277,11 +277,8 @@ class content_item_service {
return course_allowed_module($course, explode('_', $parents[$contentitem->get_component_name()])[1], $user);
});
$format = course_get_format($course);
$maxsectionsreached = ($format->get_last_section_number() >= $format->get_max_sections());
// Now, check there is no delegated section into a delegated section.
if (is_null($sectioninfo) || $sectioninfo->is_delegated() || $maxsectionsreached) {
if (is_null($sectioninfo) || $sectioninfo->is_delegated()) {
$availablecontentitems = array_filter($availablecontentitems, function($contentitem){
return !sectiondelegate::has_delegate_class($contentitem->get_component_name());
});
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -71
View File
@@ -39,11 +39,8 @@ import {prefetchStrings} from 'core/prefetch';
import {getString} from 'core/str';
import {getFirst} from 'core/normalise';
import {toggleBulkSelectionAction} from 'core_courseformat/local/content/actions/bulkselection';
import * as CourseEvents from 'core_course/events';
import Pending from 'core/pending';
import ContentTree from 'core_courseformat/local/courseeditor/contenttree';
// The jQuery module is only used for interacting with Boostrap 4. It can we removed when MDL-71979 is integrated.
import Notification from "core/notification";
// Load global strings.
prefetchStrings('core', ['movecoursesection', 'movecoursemodule', 'confirm', 'delete']);
@@ -87,7 +84,6 @@ export default class extends BaseComponent {
// Availability modal selectors.
OPTIONSRADIO: `[type='radio']`,
COURSEADDSECTION: `#course-addsection`,
MAXSECTIONSWARNING: `[data-region='max-sections-warning']`,
ADDSECTIONREGION: `[data-region='section-addsection']`,
};
// Component css classes.
@@ -114,25 +110,14 @@ export default class extends BaseComponent {
/**
* Initial state ready method.
*
* @param {Object} state the state data.
*
*/
stateReady(state) {
stateReady() {
// Delegate dispatch clicks.
this.addEventListener(
this.element,
'click',
this._dispatchClick
);
// Check section limit.
this._checkSectionlist({state});
// Add an Event listener to recalculate limits it if a section HTML is altered.
this.addEventListener(
this.element,
CourseEvents.sectionRefreshed,
() => this._checkSectionlist({state})
);
// Any inplace editable update needs state refresh.
this.addEventListener(
this.element,
@@ -141,18 +126,6 @@ export default class extends BaseComponent {
);
}
/**
* Return the component watchers.
*
* @returns {Array} of watchers
*/
getWatchers() {
return [
// Check section limit.
{watch: `course.sectionlist:updated`, handler: this._checkSectionlist},
];
}
_dispatchClick(event) {
const target = event.target.closest(this.selectors.ACTIONLINK);
if (!target) {
@@ -188,17 +161,6 @@ export default class extends BaseComponent {
return `_request${requestName}`;
}
/**
* Check the section list and disable some options if needed.
*
* @param {Object} detail the update details.
* @param {Object} detail.state the state object.
*/
_checkSectionlist({state}) {
// Disable "add section" actions if the course max sections has been exceeded.
this._setAddSectionLocked(state.course.sectionlist.length > state.course.maxsections);
}
/**
* Handle inplace editable updates.
*
@@ -813,38 +775,6 @@ export default class extends BaseComponent {
);
}
/**
* Disable all add sections actions.
*
* @param {boolean} locked the new locked value.
*/
_setAddSectionLocked(locked) {
const targets = this.getElements(this.selectors.ADDSECTIONREGION);
targets.forEach(element => {
element.classList.toggle(this.classes.DISABLED, locked);
const addSectionElement = element.querySelector(this.selectors.ADDSECTION);
addSectionElement.classList.toggle(this.classes.DISABLED, locked);
this.setElementLocked(addSectionElement, locked);
// We tweak the element to show a tooltip as a title attribute.
if (locked) {
getString('sectionaddmax', 'core_courseformat')
.then((text) => addSectionElement.setAttribute('title', text))
.catch(Notification.exception);
addSectionElement.style.pointerEvents = null; // Unlocks the pointer events.
addSectionElement.style.userSelect = null; // Unlocks the pointer events.
} else {
addSectionElement.setAttribute('title', addSectionElement.dataset.addSections);
}
});
const courseAddSection = this.getElement(this.selectors.COURSEADDSECTION);
if (courseAddSection) {
const addSection = courseAddSection.querySelector(this.selectors.ADDSECTION);
addSection.classList.toggle(this.classes.DISPLAYNONE, locked);
const noMoreSections = courseAddSection.querySelector(this.selectors.MAXSECTIONSWARNING);
noMoreSections.classList.toggle(this.classes.DISPLAYNONE, !locked);
}
}
/**
* Replace an element with a copy with a different tag name.
*
+10
View File
@@ -448,9 +448,19 @@ abstract class base {
/**
* Method used to get the maximum number of sections for this course format.
*
* @deprecated Since 5.1 the setting is removed.
* @todo Remove this method in Moodle 6.0 (MDL-85272).
* @return int
*/
#[\core\attribute\deprecated(
replacement: null,
reason: 'The maxsection setting is removed.',
since: '5.1',
mdl: 'MDL-84291',
)]
public function get_max_sections() {
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
$maxsections = get_config('moodlecourse', 'maxsections');
if (!isset($maxsections) || !is_numeric($maxsections)) {
$maxsections = 52;
@@ -72,16 +72,15 @@ class addsection implements named_templatable, renderable {
$options = $format->get_format_options();
$lastsection = $format->get_last_section_number();
$maxsections = $format->get_max_sections();
// Component based formats handle add section button in the frontend.
$show = ($lastsection < $maxsections) || $format->supports_components();
$show = $format->supports_components();
$supportsnumsections = array_key_exists('numsections', $options);
if ($supportsnumsections) {
$data = $this->get_num_sections_data($output, $lastsection, $maxsections);
$data = $this->get_num_sections_data($output, $lastsection);
} else if (course_get_format($course)->uses_sections() && $show) {
$data = $this->get_add_section_data($output, $lastsection, $maxsections);
$data = $this->get_add_section_data($output, $lastsection);
}
if (count((array)$data)) {
@@ -99,22 +98,20 @@ class addsection implements named_templatable, renderable {
*
* @param \renderer_base $output typically, the renderer that's calling this function
* @param int $lastsection the last section number
* @param int $maxsections the maximum number of sections
* @param int $maxsections unused (max sections is not needed anymore)
* @return stdClass data context for a mustache template
*/
protected function get_num_sections_data(\renderer_base $output, int $lastsection, int $maxsections): stdClass {
protected function get_num_sections_data(\renderer_base $output, int $lastsection, int $maxsections = 0): stdClass {
$format = $this->format;
$course = $format->get_course();
$data = new stdClass();
if ($lastsection < $maxsections) {
$data->increase = (object) [
'url' => new moodle_url(
'/course/changenumsections.php',
['courseid' => $course->id, 'increase' => true, 'sesskey' => sesskey()]
),
];
}
$data->increase = (object) [
'url' => new moodle_url(
'/course/changenumsections.php',
['courseid' => $course->id, 'increase' => true, 'sesskey' => sesskey()]
),
];
if ($course->numsections > 0) {
$data->decrease = (object) [
@@ -137,10 +134,10 @@ class addsection implements named_templatable, renderable {
*
* @param \renderer_base $output typically, the renderer that's calling this function
* @param int $lastsection the last section number
* @param int $maxsections the maximum number of sections
* @param int $maxsections unused (max sections is not needed anymore)
* @return stdClass data context for a mustache template
*/
protected function get_add_section_data(\renderer_base $output, int $lastsection, int $maxsections): stdClass {
protected function get_add_section_data(\renderer_base $output, int $lastsection, int $maxsections = 0): stdClass {
$format = $this->format;
$course = $format->get_course();
$data = new stdClass();
@@ -156,8 +153,8 @@ class addsection implements named_templatable, renderable {
$data->addsections = (object) [
'url' => new moodle_url('/course/changenumsections.php', $params),
'title' => $addstring,
'newsection' => $maxsections - $lastsection,
'canaddsection' => $lastsection < $maxsections,
'newsection' => $lastsection + 1,
'canaddsection' => true,
];
return $data;
}
@@ -67,7 +67,6 @@ class course implements renderable {
'sectionlist' => [],
'editmode' => $format->show_editor(),
'highlighted' => $format->get_section_highlighted_name(),
'maxsections' => $format->get_max_sections(),
'baseurl' => $url->out(),
'statekey' => course_format::session_cache($course),
'maxbytes' => $maxbytes,
-9
View File
@@ -267,15 +267,6 @@ class stateactions {
$coursecontext = context_course::instance($course->id);
require_capability('moodle/course:update', $coursecontext);
// Get course format settings.
$format = course_get_format($course->id);
$lastsectionnumber = $format->get_last_section_number();
$maxsections = $format->get_max_sections();
if ($lastsectionnumber >= $maxsections) {
throw new moodle_exception('maxsectionslimit', 'moodle', '', $maxsections);
}
$modinfo = get_fast_modinfo($course);
// Get target section.
@@ -61,14 +61,6 @@
{{#pix}} t/add, core {{/pix}}
{{title}}
</a>
<div class="d-none p-3 max-section-alert" data-region="max-sections-warning">
<div class="w-100 text-center">
{{#pix}}t/block, moodle{{/pix}}
</div>
<div class="w-100 fst-italic text-center">
{{#str}}maxsectionaddmessage, core_courseformat{{/str}}
</div>
</div>
{{/addsections}}
</div>
{{/showaddsection}}
@@ -381,17 +381,3 @@ Feature: Course index depending on role
And I turn editing mode on
When I set the field "Edit section name" in the "page-header" "region" to "Custom section name"
Then I should see "Custom section name" in the "courseindex-content" "region"
@javascript
Scenario: We cannot add a section when the number of section reaches maxsections but as soon as we reach under the limit we can add a section again.
Given the following config values are set as admin:
| maxsections | 4 | moodlecourse|
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
Then I should see "Section 1" in the "courseindex-content" "region"
And ".disabled" "css_element" should exist in the "[data-action='addSection']" "css_element"
And I should see "You have reached the maximum number of sections allowed for a course."
And I delete section "4"
And I click on "Delete" "button" in the ".modal" "css_element"
And ".disabled" "css_element" should not exist in the "[data-action='addSection']" "css_element"
And I should not see "You have reached the maximum number of sections allowed for a course."
+3 -9
View File
@@ -285,17 +285,11 @@ class format_topics extends core_courseformat\base {
$elements = parent::create_edit_form_elements($mform, $forsection);
if (!$forsection && (empty($COURSE->id) || $COURSE->id == SITEID)) {
// Add "numsections" element to the create course form - it will force new course to be prepopulated
// with empty sections.
// The "Number of sections" option is no longer available when editing course, instead teachers should
// delete and add sections when needed.
// Custom sections are always created with the default number of sections.
$courseconfig = get_config('moodlecourse');
$max = (int)$courseconfig->maxsections;
$element = $mform->addElement('select', 'numsections', get_string('numberweeks'), range(0, $max ?: 52));
$element = $mform->addElement('hidden', 'numsections');
$mform->setType('numsections', PARAM_INT);
if (is_null($mform->getElementValue('numsections'))) {
$mform->setDefault('numsections', $courseconfig->numsections);
}
$mform->setDefault('numsections', $courseconfig->numsections);
array_unshift($elements, $element);
}
@@ -0,0 +1,25 @@
@format @format_topics
Feature: Custom sections are created with the system default number of sections
In order to create courses
As a course creator
I need my courses to be created as the system default number of sections
@javascript
Scenario: Default number of sections in course creation
Given the following config values are set as admin:
| numsections | 5 | moodlecourse |
When I log in as "admin"
And I navigate to "Courses > Manage courses and categories" in site administration
And I click on "Create new course" "link"
And I expand all fieldsets
And I set the field "Course full name" to "Course 1"
And I set the field "Course short name" to "C1"
And I set the field "Format" to "Custom sections"
Then I should not see "Number of sections"
And I click on "Save and display" "button"
And "[data-for='section'][data-number='1']" "css_element" should exist
And "[data-for='section'][data-number='2']" "css_element" should exist
And "[data-for='section'][data-number='3']" "css_element" should exist
And "[data-for='section'][data-number='4']" "css_element" should exist
And "[data-for='section'][data-number='5']" "css_element" should exist
And "[data-for='section'][data-number='6']" "css_element" should not exist
+14
View File
@@ -46,5 +46,19 @@ function xmldb_format_weeks_upgrade($oldversion) {
// Automatically generated Moodle v5.0.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2025052600) {
$config = get_config('format_weeks');
// Crerate the default maxinitialsections setting if is not set.
if (!isset($config->maxinitialsections)) {
// The system may have some maxsections defined. We will keep the same value.
$courseconfig = get_config('moodlecourse');
$max = (int) $courseconfig->maxsections;
$config->maxinitialsections = $max ?: 52;
set_config('maxinitialsections', $config->maxinitialsections, 'format_weeks');
}
upgrade_plugin_savepoint(true, 2025052600, 'format', 'weeks');
}
return true;
}
@@ -27,6 +27,8 @@ $string['automaticenddate'] = 'Calculate the end date from the number of section
$string['automaticenddate_help'] = 'If enabled, the end date for the course will be automatically calculated from the number of sections and the course start date.';
$string['currentsection'] = 'Current week';
$string['hidefromothers'] = 'Hide';
$string['maxinitialsections'] = 'Maximum number of weeks at course creation';
$string['maxinitialsections_help'] = 'Sets the maximum number of weeks that can be assigned to a course at the time of creation. This limit helps prevent accidental creation of overly long courses. It does not restrict teachers from adding more weeks later during course editing.';
$string['page-course-view-weeks'] = 'Any course main page in weekly sections format';
$string['page-course-view-weeks-x'] = 'Any course page in weekly sections format';
$string['pluginname'] = 'Weekly sections';
+2 -1
View File
@@ -319,7 +319,8 @@ class format_weeks extends core_courseformat\base {
// The "Number of sections" option is no longer available when editing course, instead teachers should
// delete and add sections when needed.
$courseconfig = get_config('moodlecourse');
$max = (int)$courseconfig->maxsections;
$weeksconfig = get_config('format_weeks');
$max = (int)$weeksconfig->maxinitialsections;
$element = $mform->addElement('select', 'numsections', get_string('numberweeks'), range(0, $max ?: 52));
$mform->setType('numsections', PARAM_INT);
if (is_null($mform->getElementValue('numsections'))) {
+8
View File
@@ -33,4 +33,12 @@ if ($ADMIN->fulltree) {
new lang_string('indentation_help', 'format_weeks').'<br />'.$link,
1
));
$settings->add(new admin_setting_configtext(
name: 'format_weeks/maxinitialsections',
visiblename: new lang_string('maxinitialsections', 'format_weeks'),
description: new lang_string('maxinitialsections_help', 'format_weeks'),
defaultsetting: 52,
paramtype: PARAM_INT,
));
}
@@ -0,0 +1,74 @@
@format @format_weeks
Feature: Weeks format courses are created with the system default number of sections
In order to create courses
As a course creator
I need my week courses to be created as the system default number of sections
@javascript
Scenario: Weeks formats cannot be created with more sections than the format max
Given the following config values are set as admin:
| maxinitialsections | 5 | format_weeks |
| numsections | 40 | moodlecourse |
When I log in as "admin"
And I navigate to "Courses > Manage courses and categories" in site administration
And I click on "Create new course" "link"
And I expand all fieldsets
And I set the field "Course full name" to "Course 1"
And I set the field "Course short name" to "C1"
And I set the field "Format" to "Weekly sections"
Then the "Number of sections" select box should contain "5"
And the "Number of sections" select box should not contain "6"
And I expand all fieldsets
And I set the field "Number of sections" to "5"
And I click on "Save and display" "button"
And "[data-for='section'][data-number='1']" "css_element" should exist
And "[data-for='section'][data-number='2']" "css_element" should exist
And "[data-for='section'][data-number='3']" "css_element" should exist
And "[data-for='section'][data-number='4']" "css_element" should exist
And "[data-for='section'][data-number='5']" "css_element" should exist
And "[data-for='section'][data-number='6']" "css_element" should not exist
@javascript
Scenario: Weeks formats will be created with the system default
Given the following config values are set as admin:
| numsections | 5 | moodlecourse |
When I log in as "admin"
And I navigate to "Courses > Manage courses and categories" in site administration
And I click on "Create new course" "link"
And I expand all fieldsets
And I set the field "Course full name" to "Course 1"
And I set the field "Course short name" to "C1"
And I set the field "Format" to "Weekly sections"
Then the "Number of sections" select box should contain "52"
And the "Number of sections" select box should not contain "53"
And I click on "Save and display" "button"
And "[data-for='section'][data-number='1']" "css_element" should exist
And "[data-for='section'][data-number='2']" "css_element" should exist
And "[data-for='section'][data-number='3']" "css_element" should exist
And "[data-for='section'][data-number='4']" "css_element" should exist
And "[data-for='section'][data-number='5']" "css_element" should exist
And "[data-for='section'][data-number='6']" "css_element" should not exist
@javascript
Scenario: Weeks formats can be created with a specific number of sections
Given the following config values are set as admin:
| numsections | 4 | moodlecourse |
| maxinitialsections | 10 | format_weeks |
When I log in as "admin"
And I navigate to "Courses > Manage courses and categories" in site administration
And I click on "Create new course" "link"
And I expand all fieldsets
And I set the field "Course full name" to "Course 1"
And I set the field "Course short name" to "C1"
And I set the field "Format" to "Weekly sections"
Then the "Number of sections" select box should contain "10"
And the "Number of sections" select box should not contain "11"
And I expand all fieldsets
And I set the field "Number of sections" to "5"
And I click on "Save and display" "button"
And "[data-for='section'][data-number='1']" "css_element" should exist
And "[data-for='section'][data-number='2']" "css_element" should exist
And "[data-for='section'][data-number='3']" "css_element" should exist
And "[data-for='section'][data-number='4']" "css_element" should exist
And "[data-for='section'][data-number='5']" "css_element" should exist
And "[data-for='section'][data-number='6']" "css_element" should not exist
+1 -1
View File
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2025052600; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'format_weeks'; // Full name of the plugin (used for diagnostics).
-9
View File
@@ -72,15 +72,6 @@ if (!empty($add)) {
// will be the closest match we have.
navigation_node::override_active_url(course_get_url($course, $section));
// MDL-69431 Validate that $section (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) {
throw new \moodle_exception('maxsectionslimit', 'moodle', '', $maxsections);
}
list($module, $context, $cw, $cm, $data) = prepare_new_moduleinfo_data($course, $add, $section);
$data->return = 0;
if (!is_null($sectionreturn)) {
@@ -1,50 +0,0 @@
@core @core_course
Feature: The maximum number of weeks/topics in a course can be configured
In order to set boundaries to courses size
As a manager
I need to limit the number of weeks/topics a course can have
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| manager1 | Manager | 1 | manager1@example.com |
And the following "system role assigns" exist:
| user | course | role |
| manager1 | Acceptance test site | manager |
And I log in as "admin"
And I navigate to "Courses > Default settings > Course default settings" in site administration
@javascript
Scenario: The number of sections can be increased and the limits are applied to courses
Given I set the field "Maximum number of sections" to "100"
When I press "Save changes"
And the field "Maximum number of sections" matches value "100"
And the "Number of sections" select box should contain "100"
And I log out
And I log in as "manager1"
And the following "course" exists:
| fullname | New course fullname |
| shortname | New course shortname |
| format | topics |
| numsections | 90 |
| initsections | 1 |
And I am on the "New course fullname" course page
Then I should see "Section 90"
@javascript
Scenario: The number of sections can be reduced to 0 and the limits are applied to courses
Given I set the field "Maximum number of sections" to "0"
When I press "Save changes"
And the field "Maximum number of sections" matches value "0"
And the "Number of sections" select box should contain "0"
And the "Number of sections" select box should not contain "52"
And I log out
And I log in as "manager1"
And the following "course" exists:
| fullname | New course fullname |
| shortname | New course shortname |
| format | topics |
| numsections | 0 |
| initsections | 1 |
And I am on the "New course fullname" course page
Then I should not see "Section 1"
+3 -1
View File
@@ -70,7 +70,6 @@ $string['cmsmove_title'] = 'Move selected activities';
$string['cmsmove_info'] = 'Move {$a} activities after';
$string['courseindex'] = 'Course index';
$string['courseindexoptions'] = 'Course index options';
$string['maxsectionaddmessage'] = 'You have reached the maximum number of sections allowed for a course.';
$string['nobulkaction'] = 'No bulk actions available';
$string['orphansectionwarning'] = 'This section and its content are not part of the course structure and are not visible to students. To use any of this content, move it to a different section.';
$string['preference:coursesectionspreferences'] = 'Section user preferences for course {$a}';
@@ -98,3 +97,6 @@ $string['sectionsmove_info'] = 'Move {$a} sections after';
$string['sectionsmove_title'] = 'Move selected sections';
$string['selectcm'] = 'Select activity {$a}';
$string['selectsection'] = 'Select section {$a}';
// Deprecated since Moodle 5.1.
$string['maxsectionaddmessage'] = 'You have reached the maximum number of sections allowed for a course.';
+2
View File
@@ -82,3 +82,5 @@ lockverbose,core_grades
showverbose,core_grades
unlockverbose,core_grades
aiusagestats,core_hub
maxsectionslimit,core
maxsectionaddmessage,core_courseformat
+5 -3
View File
@@ -1288,7 +1288,6 @@ $string['match'] = 'Match';
$string['matchingsearchandrole'] = 'Matching \'{$a->search}\' and {$a->role}';
$string['matchofthefollowing'] = 'of the following:';
$string['maxareabytesreached'] = 'The file (or the total size of several files) is larger than the space remaining in this area.';
$string['maxsectionslimit'] = 'Cannot create new section as it would exceed the maximum number of sections allowed for this course ({$a}).';
$string['maxfilesize'] = 'Maximum size for new files: {$a}';
$string['maxfilesreached'] = 'You are allowed to attach a maximum of {$a} file(s) to this item';
$string['maximumchars'] = 'Maximum of {$a} characters';
@@ -1297,8 +1296,8 @@ $string['maximumgradex'] = 'Maximum grade: {$a}';
$string['maximumshort'] = 'Max';
$string['maximumupload'] = 'Maximum upload size';
$string['maximumupload_help'] = 'The maximum file size allowed for student uploads to the course. Additionally, you can further restrict the maximum upload size for each activity.';
$string['maxnumberweeks'] = 'Maximum number of sections';
$string['maxnumberweeks_desc'] = 'The maximum value in the number of sections drop-down menu (applies to certain course formats only).';
$string['maxnumberweeks'] = 'Maximum number of sections (deprecated)';
$string['maxnumberweeks_desc'] = 'The maximum value in the number of sections drop-down menu (applies to certain course formats only). This setting is deprecated and will be removed in a future version of Moodle. Please use the course format settings instead.';
$string['maxnumcoursesincombo'] = 'Browse <a href="{$a->link}">{$a->numberofcourses} courses</a>.';
$string['maxsize'] = 'Max size: {$a}';
$string['maxsizeandareasize'] = 'Maximum size for new files: {$a->size}, overall limit: {$a->areasize}';
@@ -2488,3 +2487,6 @@ $string['registrationcontactyes'] = 'Yes, provide a form for other Moodlers to c
// Deprecated since Moodle 5.0.
$string['failedtaskcontexturlname'] = 'Status report';
// Deprecated since Moodle 5.1.
$string['maxsectionslimit'] = 'Cannot create new section as it would exceed the maximum number of sections allowed for this course ({$a}).';
+18
View File
@@ -5414,11 +5414,29 @@ class admin_settings_country_select extends admin_setting_configselect {
* admin_setting_configselect for the default number of sections in a course,
* simply so we can lazy-load the choices.
*
* @deprecated since Moodle 5.2.
* @todo Remove this class in Moodle 6.0 (MDL-85272).
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class admin_settings_num_course_sections extends admin_setting_configselect {
/**
* Constructor.
*
* @param string $name The name of the setting
* @param string $visiblename The visible name of the setting
* @param string $description The description of the setting
* @param int $defaultsetting The default setting value
* @deprecated since Moodle 5.2
* @todo Final deprecation in Moodle 6.0 (MDL-84291)
*/
#[\core\attribute\deprecated(
replacement: 'admin_setting_configtext',
since: '5.1',
mdl: 'MDL-84291',
)]
public function __construct($name, $visiblename, $description, $defaultsetting) {
\core\deprecation::emit_deprecation_if_present(__FUNCTION__);
parent::__construct($name, $visiblename, $description, $defaultsetting, array());
}
-3
View File
@@ -49,9 +49,6 @@ class permission {
return false;
}
$format = course_get_format($section->course);
if ($format->get_last_section_number() >= $format->get_max_sections()) {
return false;
}
if (!$format->supports_components()) {
return false;
}
@@ -1,29 +0,0 @@
@mod @mod_subsection
Feature: Teacher can only add subsection when certain conditions are met
In order to limit subsections
As an teacher
I need to create subsections only when possible
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
And the following "courses" exist:
| fullname | shortname | category | numsections | initsections |
| Course 1 | C1 | 0 | 5 | 1 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
@javascript
Scenario: We cannot add subsections when maxsections is reached
Given the following config values are set as admin:
| maxsections | 10 | moodlecourse |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I click on "Add content" "button" in the "Section 1" "section"
And I click on "Subsection" "link" in the ".dropdown-menu.show" "css_element"
When the following config values are set as admin:
| maxsections | 4 | moodlecourse |
And I am on "Course 1" course homepage
And I should see "You have reached the maximum number of sections allowed for a course."
+1 -20
View File
@@ -37,7 +37,6 @@ final class permission_test extends advanced_testcase {
* @param bool $ismoddisabled
* @param bool $missingcapability
* @param bool $isdelegated
* @param bool $maxsectionsreached
* @param string $format
* @param bool $expected
*
@@ -47,7 +46,6 @@ final class permission_test extends advanced_testcase {
bool $ismoddisabled,
bool $missingcapability,
bool $isdelegated,
bool $maxsectionsreached,
string $format,
bool $expected
): void {
@@ -68,10 +66,6 @@ final class permission_test extends advanced_testcase {
assign_capability('mod/subsection:addinstance', CAP_PROHIBIT, $userrole, context_course::instance($course->id));
}
if ($maxsectionsreached) {
set_config('maxsections', 5, 'moodlecourse');
}
if ($isdelegated) {
$this->getDataGenerator()->create_module('subsection', ['course' => $course->id, 'section' => 1]);
$targetsection = $courseformat->get_modinfo()->get_section_info(6);
@@ -92,7 +86,6 @@ final class permission_test extends advanced_testcase {
'ismoddisabled' => true,
'missingcapability' => false,
'isdelegated' => false,
'maxsectionsreached' => false,
'format' => 'topics',
'expected' => false,
],
@@ -100,15 +93,6 @@ final class permission_test extends advanced_testcase {
'ismoddisabled' => false,
'missingcapability' => true,
'isdelegated' => false,
'maxsectionsreached' => false,
'format' => 'topics',
'expected' => false,
],
'Max sections reached' => [
'ismoddisabled' => false,
'missingcapability' => false,
'isdelegated' => false,
'maxsectionsreached' => true,
'format' => 'topics',
'expected' => false,
],
@@ -116,7 +100,6 @@ final class permission_test extends advanced_testcase {
'ismoddisabled' => false,
'missingcapability' => false,
'isdelegated' => true,
'maxsectionsreached' => false,
'format' => 'topics',
'expected' => false,
],
@@ -124,15 +107,13 @@ final class permission_test extends advanced_testcase {
'ismoddisabled' => false,
'missingcapability' => false,
'isdelegated' => false,
'maxsectionsreached' => false,
'format' => 'singleactivity',
'expected' => false,
],
'Plugin enabled, with capability, max sections not reached, not inside a delegated section' => [
'Plugin enabled, with capability, not inside a delegated section' => [
'ismoddisabled' => false,
'missingcapability' => false,
'isdelegated' => false,
'maxsectionsreached' => false,
'format' => 'topics',
'expected' => true,
],