diff --git a/course/format/classes/base.php b/course/format/classes/base.php index c87f6f486aaaa..a91a16cafa70d 100644 --- a/course/format/classes/base.php +++ b/course/format/classes/base.php @@ -950,11 +950,33 @@ public function get_view_url($section, $options = array()) { * @param moodle_url|null $returnurl optional custom return url * @return \moodle_url */ - public function get_update_url(?moodle_url $returnurl = null): moodle_url { + public function get_update_url( + string $action, + array $ids = [], + ?int $targetsectionid = null, + ?int $targetcmid = null, + ?moodle_url $returnurl = null + ): moodle_url { $params = [ 'courseid' => $this->get_courseid(), 'sesskey' => sesskey(), + 'action' => $action, ]; + + if (count($ids) === 1) { + $params['id'] = reset($ids); + } else { + foreach ($ids as $key => $id) { + $params["ids[]"] = $id; + } + } + + if ($targetsectionid) { + $params['sectionid'] = $targetsectionid; + } + if ($targetcmid) { + $params['cmid'] = $targetcmid; + } if ($returnurl) { $params['pageurl'] = $returnurl->out_as_local_url(); } @@ -968,30 +990,38 @@ public function get_update_url(?moodle_url $returnurl = null): moodle_url { * so we must translate to an old non-ajax url while non-ajax * course editing is still supported. * + * @deprecated since Moodle 5.0 + * @todo Remove this method in Moodle 6.0 (MDL-83530). + * * @param string $action action name the reactive action * @param cm_info $cm course module * @return moodle_url */ + #[\core\attribute\deprecated( + replacement: 'core_courseformat\output\local\content\cm\controlmenu', + since: '5.0', + mdl: 'MDL-83527', + reason: 'Replaced by get_update_url.', + final: true, + )] public function get_non_ajax_cm_action_url(string $action, cm_info $cm): moodle_url { + \core\deprecation::emit_deprecation_if_present([$this, __FUNCTION__]); $nonajaxactions = [ - 'cmDelete' => 'delete', - 'cmDuplicate' => 'duplicate', - 'cmHide' => 'hide', - 'cmShow' => 'show', - 'cmStealth' => 'stealth', + 'cmDelete' => 'cm_delete', + 'cmDuplicate' => 'cm_duplicate', + 'cmHide' => 'cm_hide', + 'cmShow' => 'cm_show', + 'cmStealth' => 'cm_stealth', ]; if (!isset($nonajaxactions[$action])) { throw new coding_exception('Unknown activity action: ' . $action); } $nonajaxaction = $nonajaxactions[$action]; - $nonajaxurl = new moodle_url( - '/course/mod.php', - ['sesskey' => sesskey(), $nonajaxaction => $cm->id] + return $this->get_update_url( + action: $nonajaxaction, + ids: [$cm->id], + returnurl: $this->get_view_url($this->get_sectionnum(), ['navigation' => true]), ); - if (!is_null($this->get_sectionid())) { - $nonajaxurl->param('sr', $this->get_sectionnum()); - } - return $nonajaxurl; } /** diff --git a/course/format/classes/output/local/content/cm/controlmenu.php b/course/format/classes/output/local/content/cm/controlmenu.php index eea4e70eafdf5..97853f40cb9f6 100644 --- a/course/format/classes/output/local/content/cm/controlmenu.php +++ b/course/format/classes/output/local/content/cm/controlmenu.php @@ -238,14 +238,10 @@ protected function get_cm_moveend_item(): ?action_menu_link { return null; } - $url = new url( - '/course/mod.php', - [ - 'sesskey' => sesskey(), - 'sr' => $this->mod->sectionnum, - 'id' => $this->mod->id, - 'indent' => 1, - ], + $url = $this->format->get_update_url( + action: 'cm_moveright', + ids: [$this->mod->id], + returnurl: $this->baseurl, ); $icon = (right_to_left()) ? 't/left' : 't/right'; @@ -274,14 +270,10 @@ protected function get_cm_movestart_item(): ?action_menu_link { return null; } - $url = new url( - '/course/mod.php', - [ - 'sesskey' => sesskey(), - 'sr' => $this->mod->sectionnum, - 'id' => $this->mod->id, - 'indent' => -1, - ], + $url = $this->format->get_update_url( + action: 'cm_moveleft', + ids: [$this->mod->id], + returnurl: $this->baseurl, ); $icon = (right_to_left()) ? 't/right' : 't/left'; @@ -332,8 +324,14 @@ protected function get_cm_duplicate_item(): ?action_menu_link { return null; } + $url = $this->format->get_update_url( + action: 'cm_duplicate', + ids: [$this->mod->id], + returnurl: $this->baseurl, + ); + return new action_menu_link_secondary( - url: new url($this->baseurl, ['duplicate' => $this->mod->id]), + url: $url, icon: new pix_icon('t/copy', ''), text: get_string('duplicate'), attributes: [ @@ -403,13 +401,10 @@ protected function get_cm_delete_item(): ?action_menu_link { return null; } - $url = new url( - '/course/mod.php', - [ - 'sesskey' => sesskey(), - 'delete' => $this->mod->id, - 'sr' => $this->mod->sectionnum, - ], + $url = $this->format->get_update_url( + action: 'cm_delete', + ids: [$this->mod->id], + returnurl: $this->baseurl, ); return new action_menu_link_secondary( diff --git a/course/format/classes/output/local/content/cm/delegatedcontrolmenu.php b/course/format/classes/output/local/content/cm/delegatedcontrolmenu.php index 5d59eb607553f..84a0f6b14c3f6 100644 --- a/course/format/classes/output/local/content/cm/delegatedcontrolmenu.php +++ b/course/format/classes/output/local/content/cm/delegatedcontrolmenu.php @@ -178,13 +178,12 @@ protected function get_section_visibility_item(): ?action_menu_link { } $sectionreturn = $this->format->get_sectionnum(); - $url = clone ($this->baseurl); $strhide = get_string('hide'); $strshow = get_string('show'); if ($this->section->visible) { - $url->param('hide', $this->section->sectionnum); + $action = 'section_hide'; $icon = 'i/show'; $name = $strhide; $attributes = [ @@ -197,7 +196,7 @@ protected function get_section_visibility_item(): ?action_menu_link { 'data-swapicon' => 'i/hide', ]; } else { - $url->param('show', $this->section->sectionnum); + $action = 'section_show'; $icon = 'i/hide'; $name = $strshow; $attributes = [ @@ -211,6 +210,12 @@ protected function get_section_visibility_item(): ?action_menu_link { ]; } + $url = $this->format->get_update_url( + action: $action, + ids: [$this->section->id], + returnurl: $this->baseurl, + ); + return new action_menu_link_secondary( url: $url, icon: new pix_icon($icon, ''), @@ -262,13 +267,10 @@ protected function get_cm_delete_item(): ?action_menu_link { return null; } - $url = new url( - '/course/mod.php', - [ - 'sesskey' => sesskey(), - 'delete' => $this->mod->id, - 'sr' => $this->mod->sectionnum, - ], + $url = $this->format->get_update_url( + action: 'cm_delete', + ids: [$this->mod->id], + returnurl: $this->baseurl, ); return new action_menu_link_secondary( diff --git a/course/format/classes/output/local/content/cm/groupmode.php b/course/format/classes/output/local/content/cm/groupmode.php index 21434749ae633..f28d92ea18eb6 100644 --- a/course/format/classes/output/local/content/cm/groupmode.php +++ b/course/format/classes/output/local/content/cm/groupmode.php @@ -158,17 +158,17 @@ public function get_choice_list(): choicelist { $choice->add_option( NOGROUPS, get_string('groupsnone', 'group'), - $this->get_option_data(null, 'cmNoGroups', $this->mod->id) + $this->get_option_data(null, 'cmNoGroups', 'cm_nogroups') ); $choice->add_option( SEPARATEGROUPS, get_string('groupsseparate', 'group'), - $this->get_option_data('groupsseparate', 'cmSeparateGroups', $this->mod->id) + $this->get_option_data('groupsseparate', 'cmSeparateGroups', 'cm_separategroups') ); $choice->add_option( VISIBLEGROUPS, get_string('groupsvisible', 'group'), - $this->get_option_data('groupsvisible', 'cmVisibleGroups', $this->mod->id) + $this->get_option_data('groupsvisible', 'cmVisibleGroups', 'cm_visiblegroups') ); $choice->set_selected_value($this->mod->effectivegroupmode); return $choice; @@ -177,18 +177,26 @@ public function get_choice_list(): choicelist { /** * Get the data for the option. * @param string|null $name the name of the option - * @param string $action the state action of the option - * @param int $id the id of the module + * @param string $mutation the mutation name + * @param string $stateaction the state action name * @return array */ - private function get_option_data(?string $name, string $action, int $id): array { + private function get_option_data(?string $name, string $mutation, string $stateaction): array { + $format = $this->format; + $nonajaxurl = $format->get_update_url( + action: $stateaction, + ids: [$this->mod->id], + returnurl: $format->get_view_url($format->get_sectionnum(), ['navigation' => true]), + ); + return [ 'description' => ($name) ? get_string("groupmode_{$name}_help", 'group') : null, // The dropdown icons are decorative, so we don't need to provide alt text. - 'icon' => $this->get_action_icon($action), + 'icon' => $this->get_action_icon($mutation), + 'url' => $nonajaxurl, 'extras' => [ - 'data-id' => $id, - 'data-action' => $action, + 'data-id' => $this->mod->id, + 'data-action' => $mutation, ] ]; } diff --git a/course/format/classes/output/local/content/cm/visibility.php b/course/format/classes/output/local/content/cm/visibility.php index 2af03a27bd43c..51dbd76ad7c35 100644 --- a/course/format/classes/output/local/content/cm/visibility.php +++ b/course/format/classes/output/local/content/cm/visibility.php @@ -236,20 +236,20 @@ protected function create_choice_list(): choicelist { $choice->add_option( 'show', get_string("availability_{$label}", 'core_courseformat'), - $this->get_option_data($label, 'cmShow') + $this->get_option_data($label, 'cmShow', 'cm_show') ); } $choice->add_option( 'hide', get_string('availability_hide', 'core_courseformat'), - $this->get_option_data('hide', 'cmHide') + $this->get_option_data('hide', 'cmHide', 'cm_hide') ); if ($CFG->allowstealth && $this->format->allow_stealth_module_visibility($this->mod, $this->section)) { $choice->add_option( 'stealth', get_string('availability_stealth', 'core_courseformat'), - $this->get_option_data('stealth', 'cmStealth') + $this->get_option_data('stealth', 'cmStealth', 'cm_stealth') ); } return $choice; @@ -258,19 +258,25 @@ protected function create_choice_list(): choicelist { /** * Get the data for the option. * @param string $name the name of the option - * @param string $action the state action of the option + * @param string $mutation the mutation name + * @param string $stateaction the state action name * @return array */ - private function get_option_data(string $name, string $action): array { + private function get_option_data(string $name, string $mutation, string $stateaction): array { + $format = $this->format; + $nonajaxurl = $format->get_update_url( + action: $stateaction, + ids: [$this->mod->id], + returnurl: $format->get_view_url($format->get_sectionnum(), ['navigation' => true]), + ); + return [ 'description' => get_string("availability_{$name}_help", 'core_courseformat'), 'icon' => $this->get_icon($name), - // Non-ajax behat is not smart enough to discrimante hidden links - // so we need to keep providing the non-ajax links. - 'url' => $this->format->get_non_ajax_cm_action_url($action, $this->mod), + 'url' => $nonajaxurl, 'extras' => [ 'data-id' => $this->mod->id, - 'data-action' => $action, + 'data-action' => $mutation, ] ]; } diff --git a/course/format/classes/output/local/content/section/controlmenu.php b/course/format/classes/output/local/content/section/controlmenu.php index 377f9bddcffd4..ce817d3c3148d 100644 --- a/course/format/classes/output/local/content/section/controlmenu.php +++ b/course/format/classes/output/local/content/section/controlmenu.php @@ -186,13 +186,11 @@ protected function get_section_visibility_item(): ?action_menu_link { } $sectionreturn = $this->format->get_sectionnum(); - $url = clone($this->baseurl); - $strhide = get_string('hide'); $strshow = get_string('show'); if ($this->section->visible) { - $url->param('hide', $this->section->sectionnum); + $stateaction = 'section_hide'; $icon = 'i/show'; $name = $strhide; $attributes = [ @@ -205,7 +203,7 @@ protected function get_section_visibility_item(): ?action_menu_link { 'data-swapicon' => 'i/hide', ]; } else { - $url->param('show', $this->section->sectionnum); + $stateaction = 'section_show'; $icon = 'i/hide'; $name = $strshow; $attributes = [ @@ -219,6 +217,12 @@ protected function get_section_visibility_item(): ?action_menu_link { ]; } + $url = $this->format->get_update_url( + action: $stateaction, + ids: [$this->section->id], + returnurl: $this->baseurl, + ); + return new action_menu_link_secondary( url: $url, icon: new pix_icon($icon, ''), @@ -300,17 +304,12 @@ protected function get_section_delete_item(): ?action_menu_link { return null; } - $params = [ - 'id' => $this->section->id, - 'delete' => 1, - 'sesskey' => sesskey(), - ]; - $params['sr'] ??= $this->format->get_sectionnum(); - - $url = new url( - '/course/editsection.php', - $params, + $url = $this->format->get_update_url( + action: 'section_delete', + ids: [$this->section->id], + returnurl: $this->baseurl, ); + return new action_menu_link_secondary( url: $url, icon: new pix_icon('i/delete', ''), diff --git a/course/format/classes/output/local/content/section/visibility.php b/course/format/classes/output/local/content/section/visibility.php index dbc38e45d6cd9..fe6446729f09e 100644 --- a/course/format/classes/output/local/content/section/visibility.php +++ b/course/format/classes/output/local/content/section/visibility.php @@ -119,12 +119,12 @@ protected function get_visibility_dropdown(\renderer_base $output): array { $choice->add_option( 'show', get_string('availability_show', 'core_courseformat'), - $this->get_option_data('show', 'sectionShow') + $this->get_option_data('show', 'sectionShow', 'section_show') ); $choice->add_option( 'hide', get_string('availability_hide', 'core_courseformat'), - $this->get_option_data('hide', 'sectionHide') + $this->get_option_data('hide', 'sectionHide', 'section_hide') ); $choice->set_selected_value('hide'); @@ -140,23 +140,25 @@ protected function get_visibility_dropdown(\renderer_base $output): array { * Get the data for the option. * * @param string $name the name of the option - * @param string $action the state action of the option + * @param string $mutation the mutation name + * @param string $stateaction the state action name * @return array */ - private function get_option_data(string $name, string $action): array { - $baseurl = course_get_url($this->section->course, $this->section); - $baseurl->param('sesskey', sesskey()); - $baseurl->param($action, $this->section->section); + private function get_option_data(string $name, string $mutation, string $stateaction): array { + $format = $this->format; + $nonajaxurl = $format->get_update_url( + action: $stateaction, + ids: [$this->section->id], + returnurl: $format->get_view_url($format->get_sectionnum(), ['navigation' => true]), + ); return [ 'description' => get_string("availability_{$name}_help", 'core_courseformat'), 'icon' => $this->get_icon($name), - // Non-ajax behat is not smart enough to discrimante hidden links - // so we need to keep providing the non-ajax links. - 'url' => $baseurl, + 'url' => $nonajaxurl, 'extras' => [ 'data-id' => $this->section->id, - 'data-action' => $action, + 'data-action' => $mutation, ], ]; } diff --git a/course/format/tests/behat/activity_nonajax_edit.feature b/course/format/tests/behat/activity_nonajax_edit.feature new file mode 100644 index 0000000000000..0b34ef2a154c7 --- /dev/null +++ b/course/format/tests/behat/activity_nonajax_edit.feature @@ -0,0 +1,108 @@ +@core @core_courseformat +Feature: Validate some activity editing has a non-ajax alternative + In order to edit the course activities faster + As a teacher + I need to be able use some edit tools without ajax. + + Background: + Given the following "course" exists: + | fullname | Course 1 | + | shortname | C1 | + | category | 0 | + | numsections | 3 | + | initsections | 1 | + And the following "activities" exist: + | activity | name | intro | course | idnumber | section | + | assign | Activity sample 1 | Test assignment description | C1 | sample1 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + + Scenario: Activity settings can be accessed without ajax + Given I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + When I click on "Edit settings" "link" in the "Activity sample 1" "activity" + Then I should see "Assignment name" + And I set the field "Assignment name" to "New name" + And I press "Save and return to course" + And I should see "New name" + + Scenario: Indent an activity can be done without ajax + Given I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I should not see "Move left" + When I click on "Move right" "link" in the "Activity sample 1" "activity" + Then I should see "Move left" + And I should not see "Move right" + And I click on "Move left" "link" in the "Activity sample 1" "activity" + And I should not see "Move left" + And I should see "Move right" + + Scenario: Hide and show an activity can be done without ajax + Given I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I should not see "Show" in the ".cm_action_menu" "css_element" + When I click on "Hide" "link" in the "Activity sample 1" "activity" + Then I should see "Show" in the ".cm_action_menu" "css_element" + And I should not see "Hide" in the ".cm_action_menu" "css_element" + And I click on "Show" "link" in the "Activity sample 1" "activity" + And I should not see "Show" in the ".cm_action_menu" "css_element" + And I should see "Hide" in the ".cm_action_menu" "css_element" + + Scenario: Activity visibility with stealth option can be changed without ajax + Given the following config values are set as admin: + | allowstealth | 1 | + And I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I should see "Show on course page" + And I should see "Hide on course page" + And I should see "Make available but don't show on course page" + And ".activity-badges" "css_element" should not exist + When I click on "Hide on course page" "link" in the "Activity sample 1" "activity" + Then I should see "Hidden from students" in the "Activity sample 1" "core_courseformat > Activity visibility" + And I should not see "Available but not shown on course page" in the "Activity sample 1" "core_courseformat > Activity visibility" + And I click on "Make available but don't show on course page" "link" in the "Activity sample 1" "activity" + And I should not see "Hidden from students" in the "Activity sample 1" "core_courseformat > Activity visibility" + And I should see "Available but not shown on course page" in the "Activity sample 1" "core_courseformat > Activity visibility" + And I click on "Show on course page" "link" in the "Activity sample 1" "activity" + And ".activity-badges" "css_element" should not exist + + Scenario: Duplicate activity can be done without ajax + Given I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + When I click on "Duplicate" "link" in the "Activity sample 1" "activity" + Then I should see "Activity sample 1 (copy)" + + Scenario: Delete activity can be done without ajax + Given I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + When I click on "Delete" "link" in the "Activity sample 1" "activity" + And I should see "Delete activity?" + And I should see "This will delete Activity sample 1 and any user data it contains" + And I click on "Continue" "button" + Then I should not see "Activity sample 1" + + Scenario: The activity groupmode can be changed without ajax + Given the following "groups" exist: + | name | course | idnumber | + | G1 | C1 | GI1 | + And I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And "No groups" "icon" should exist in the "Activity sample 1" "activity" + And "Visible groups" "icon" should not exist in the "Activity sample 1" "activity" + And "Separate groups" "icon" should not exist in the "Activity sample 1" "activity" + When I click on "Separate groups" "link" in the "Activity sample 1" "activity" + And "No groups" "icon" should not exist in the "Activity sample 1" "activity" + And "Visible groups" "icon" should not exist in the "Activity sample 1" "activity" + And "Separate groups" "icon" should exist in the "Activity sample 1" "activity" + And I click on "Visible groups" "link" in the "Activity sample 1" "activity" + And "No groups" "icon" should not exist in the "Activity sample 1" "activity" + And "Visible groups" "icon" should exist in the "Activity sample 1" "activity" + And "Separate groups" "icon" should not exist in the "Activity sample 1" "activity" + And I click on "No groups" "link" in the "Activity sample 1" "activity" + And "No groups" "icon" should exist in the "Activity sample 1" "activity" + And "Visible groups" "icon" should not exist in the "Activity sample 1" "activity" + And "Separate groups" "icon" should not exist in the "Activity sample 1" "activity" diff --git a/course/format/tests/behat/section_nonajax_edit.feature b/course/format/tests/behat/section_nonajax_edit.feature new file mode 100644 index 0000000000000..265aad918184a --- /dev/null +++ b/course/format/tests/behat/section_nonajax_edit.feature @@ -0,0 +1,52 @@ +@core @core_courseformat +Feature: Validate some section editing has a non-ajax alternative + In order to edit the course sections faster + As a teacher + I need to be able use some edit tools without ajax. + + Background: + Given the following "course" exists: + | fullname | Course 1 | + | shortname | C1 | + | category | 0 | + | numsections | 3 | + | initsections | 1 | + And the following "activities" exist: + | activity | name | intro | course | idnumber | section | + | assign | Activity sample 1 | Test assignment description | C1 | sample1 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + + Scenario: Section settings can be accessed without ajax + Given I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + When I click on "Edit settings" "link" in the "Section 1" "core_courseformat > Section actions menu" + Then I should see "Section name" + And I set the field "Section name" to "New name" + And I press "Save changes" + And I should see "New name" + + Scenario: Hide and show a section can be done without ajax + Given I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I should not see "Show" in the "Section 1" "core_courseformat > Section actions menu" + When I click on "Hide" "link" in the "Section 1" "core_courseformat > Section actions menu" + Then I should see "Show" in the "Section 1" "core_courseformat > Section actions menu" + And I should not see "Hide" in the "Section 1" "core_courseformat > Section actions menu" + And I click on "Show" "link" in the "Section 1" "core_courseformat > Section actions menu" + And I should not see "Show" in the "Section 1" "core_courseformat > Section actions menu" + And I should see "Hide" in the "Section 1" "core_courseformat > Section actions menu" + + Scenario: Delete a section can be done without ajax + Given I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + When I click on "Delete" "link" in the "Section 1" "core_courseformat > Section actions menu" + Then I should see "Delete section?" + And I should see "This will delete Section 1 and all the activities it contains." + And I should see "Section 3" + And I click on "Continue" "button" + Then I should not see "Section 1" diff --git a/course/format/topics/classes/output/courseformat/content/section/controlmenu.php b/course/format/topics/classes/output/courseformat/content/section/controlmenu.php index 8d72ef0dd8e74..92bc8f6421d7f 100644 --- a/course/format/topics/classes/output/courseformat/content/section/controlmenu.php +++ b/course/format/topics/classes/output/courseformat/content/section/controlmenu.php @@ -72,7 +72,14 @@ public function section_control_items() { * * @return url */ + #[\core\attribute\deprecated( + since: '5.0', + mdl: 'MDL-82767', + reason: 'Not used anymore, use $this->format->get_update_url instead', + final: true, + )] protected function get_course_url(): url { + \core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]); $format = $this->format; $section = $this->section; $course = $format->get_course(); @@ -97,10 +104,6 @@ protected function get_section_highlight_item(): action_menu_link_secondary { $section = $this->section; $course = $format->get_course(); $sectionreturn = $format->get_sectionnum(); - $url = $this->get_course_url(); - if (!is_null($sectionreturn)) { - $url->param('sectionid', $format->get_sectionid()); - } $highlightoff = get_string('highlightoff'); $highlightofficon = 'i/marked'; @@ -109,7 +112,7 @@ protected function get_section_highlight_item(): action_menu_link_secondary { $highlightonicon = 'i/marker'; if ($course->marker == $section->sectionnum) { // Show the "light globe" on/off. - $url->param('marker', 0); + $action = 'section_unhighlight'; $icon = $highlightofficon; $name = $highlightoff; $attributes = [ @@ -122,7 +125,7 @@ protected function get_section_highlight_item(): action_menu_link_secondary { 'data-swapicon' => $highlightonicon, ]; } else { - $url->param('marker', $section->section); + $action = 'section_highlight'; $icon = $highlightonicon; $name = $highlighton; $attributes = [ @@ -135,6 +138,13 @@ protected function get_section_highlight_item(): action_menu_link_secondary { 'data-swapicon' => $highlightofficon, ]; } + + $url = $this->format->get_update_url( + action: $action, + ids: [$section->id], + returnurl: $this->baseurl, + ); + return new action_menu_link_secondary( url: $url, icon: new pix_icon($icon, ''), diff --git a/course/format/topics/tests/behat/highlight_sections.feature b/course/format/topics/tests/behat/highlight_sections.feature index 0a33f41776975..8c5f1dc286335 100644 --- a/course/format/topics/tests/behat/highlight_sections.feature +++ b/course/format/topics/tests/behat/highlight_sections.feature @@ -51,3 +51,11 @@ Feature: Sections can be highlighted When I open section "3" edit menu And I click on "Unhighlight" "link" in the "Section 3" "section" Then I should not see "Highlighted" in the "Section 3" "section" + + Scenario: Highlight and unhighlight a section can be done without ajax + # Without javascript hidden elements cannot be detected with a simple I should see step. + Given ".section.current" "css_element" should not exist + When I click on "Highlight" "link" in the "Section 2" "core_courseformat > Section actions menu" + Then ".section.current[data-number='2']" "css_element" should exist + And I click on "Unhighlight" "link" in the "Section 2" "core_courseformat > Section actions menu" + And ".section.current" "css_element" should not exist diff --git a/course/format/update.php b/course/format/update.php index 8588c37e1f46a..fd5255503037b 100644 --- a/course/format/update.php +++ b/course/format/update.php @@ -70,8 +70,8 @@ 'sesskey' => sesskey(), ] ); -foreach ($ids as $id) { - $currenturl->param('ids[]', $id); +foreach ($ids as $key => $id) { + $currenturl->param("ids[]", $id); } require_sesskey(); diff --git a/course/mod.php b/course/mod.php index c365002524e0d..caa2309ad35a1 100644 --- a/course/mod.php +++ b/course/mod.php @@ -29,20 +29,20 @@ $sectionreturn = optional_param('sr', null, PARAM_INT); $add = optional_param('add', '', PARAM_ALPHANUM); $type = optional_param('type', '', PARAM_ALPHA); -$indent = optional_param('indent', 0, PARAM_INT); +$indent = optional_param('indent', 0, PARAM_INT); // TODO remove this param as part of MDL-83530. $update = optional_param('update', 0, PARAM_INT); -$duplicate = optional_param('duplicate', 0, PARAM_INT); -$hide = optional_param('hide', 0, PARAM_INT); -$stealth = optional_param('stealth', 0, PARAM_INT); -$show = optional_param('show', 0, PARAM_INT); +$duplicate = optional_param('duplicate', 0, PARAM_INT); // TODO remove this param as part of MDL-83530. +$hide = optional_param('hide', 0, PARAM_INT); // TODO remove this param as part of MDL-83530. +$stealth = optional_param('stealth', 0, PARAM_INT); // TODO remove this param as part of MDL-83530. +$show = optional_param('show', 0, PARAM_INT); // TODO remove this param as part of MDL-83530. $copy = optional_param('copy', 0, PARAM_INT); $moveto = optional_param('moveto', 0, PARAM_INT); $movetosection = optional_param('movetosection', 0, PARAM_INT); -$delete = optional_param('delete', 0, PARAM_INT); +$delete = optional_param('delete', 0, PARAM_INT); // TODO remove this param as part of MDL-83530. $course = optional_param('course', 0, PARAM_INT); -$groupmode = optional_param('groupmode', -1, PARAM_INT); +$groupmode = optional_param('groupmode', -1, PARAM_INT); // TODO remove this param as part of MDL-83530. $cancelcopy = optional_param('cancelcopy', 0, PARAM_BOOL); -$confirm = optional_param('confirm', 0, PARAM_BOOL); +$confirm = optional_param('confirm', 0, PARAM_BOOL); // TODO remove this param as part of MDL-83530. // This page should always redirect $url = new moodle_url('/course/mod.php'); @@ -118,6 +118,11 @@ ) ); } else if (!empty($duplicate) and confirm_sesskey()) { + // TODO remove this else if as part of MDL-83530. + debugging( + 'The duplicate param is deprecated. Please use action cm_duplicate in course/format/update.php instead.', + DEBUG_DEVELOPER + ); $cm = get_coursemodule_from_id('', $duplicate, 0, true, MUST_EXIST); $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); @@ -130,6 +135,11 @@ redirect(course_get_url($course, $cm->sectionnum, $urloptions)); } else if (!empty($delete)) { + // TODO remove this else if as part of MDL-83530. + debugging( + 'The delete param is deprecated. Please use action cm_delete in course/format/update.php instead.', + DEBUG_DEVELOPER + ); $cm = get_coursemodule_from_id('', $delete, 0, true, MUST_EXIST); $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); @@ -216,6 +226,11 @@ redirect(course_get_url($course, $section->section, $urloptions)); } else if (!empty($indent) and confirm_sesskey()) { + // TODO remove this else if as part of MDL-83530. + debugging( + 'The delete param deprecated. Please use action cm_moveleft and cm_moveright in course/format/update.php instead.', + DEBUG_DEVELOPER + ); $id = required_param('id', PARAM_INT); $cm = get_coursemodule_from_id('', $id, 0, true, MUST_EXIST); @@ -241,6 +256,11 @@ redirect(course_get_url($course, $cm->sectionnum, $urloptions)); } else if (!empty($hide) and confirm_sesskey()) { + // TODO remove this else if as part of MDL-83530. + debugging( + 'The hide param deprecated. Please use action cm_hide in course/format/update.php instead.', + DEBUG_DEVELOPER + ); $cm = get_coursemodule_from_id('', $hide, 0, true, MUST_EXIST); $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); @@ -255,6 +275,11 @@ redirect(course_get_url($course, $cm->sectionnum, $urloptions)); } else if (!empty($stealth) and confirm_sesskey()) { + // TODO remove this else if as part of MDL-83530. + debugging( + 'The stealth param deprecated. Please use action cm_stealth in course/format/update.php instead.', + DEBUG_DEVELOPER + ); list($course, $cm) = get_course_and_cm_from_cmid($stealth); require_login($course, false, $cm); require_capability('moodle/course:activityvisibility', $cm->context); @@ -265,6 +290,11 @@ redirect(course_get_url($course, $cm->sectionnum, array('sr' => $sectionreturn))); } else if (!empty($show) and confirm_sesskey()) { + // TODO remove this else if as part of MDL-83530. + debugging( + 'The show param deprecated. Please use action cm_show in course/format/update.php instead.', + DEBUG_DEVELOPER + ); list($course, $cm) = get_course_and_cm_from_cmid($show); require_login($course, false, $cm); require_capability('moodle/course:activityvisibility', $cm->context); @@ -276,6 +306,11 @@ redirect(course_get_url($course, $section->section, $urloptions)); } else if ($groupmode > -1 and confirm_sesskey()) { + // TODO remove this else if as part of MDL-83530. + debugging( + 'The gruopmode param deprecated. Please use the group mode actions in course/format/update.php instead.', + DEBUG_DEVELOPER + ); $id = required_param('id', PARAM_INT); $cm = get_coursemodule_from_id('', $id, 0, true, MUST_EXIST); diff --git a/course/view.php b/course/view.php index ff29d5ba103f9..1a71f20afe0a0 100644 --- a/course/view.php +++ b/course/view.php @@ -31,15 +31,15 @@ $id = optional_param('id', 0, PARAM_INT); $name = optional_param('name', '', PARAM_TEXT); $edit = optional_param('edit', -1, PARAM_BOOL); -$hide = optional_param('hide', 0, PARAM_INT); -$show = optional_param('show', 0, PARAM_INT); +$hide = optional_param('hide', 0, PARAM_INT); // TODO remove this param as part of MDL-83530. +$show = optional_param('show', 0, PARAM_INT); // TODO remove this param as part of MDL-83530. $duplicatesection = optional_param('duplicatesection', 0, PARAM_INT); $idnumber = optional_param('idnumber', '', PARAM_RAW); $sectionid = optional_param('sectionid', 0, PARAM_INT); $section = optional_param('section', null, PARAM_INT); $expandsection = optional_param('expandsection', -1, PARAM_INT); $move = optional_param('move', 0, PARAM_INT); -$marker = optional_param('marker', -1 , PARAM_INT); +$marker = optional_param('marker', -1 , PARAM_INT); // TODO remove this param as part of MDL-83530. $switchrole = optional_param('switchrole', -1, PARAM_INT); // Deprecated, use course/switchrole.php instead. $return = optional_param('return', 0, PARAM_LOCALURL); @@ -199,8 +199,13 @@ } } + // TODO remove this if as part of MDL-83530. if (has_capability('moodle/course:sectionvisibility', $context)) { if ($hide && confirm_sesskey()) { + debugging( + 'The hide param in course view is deprecated. Please use course/format/update.php instead.', + DEBUG_DEVELOPER + ); set_section_visible($course->id, $hide, '0'); if ($sectionid) { redirect(course_get_url($course, $section, ['navigation' => true])); @@ -210,6 +215,10 @@ } if ($show && confirm_sesskey()) { + debugging( + 'The show param in course view is deprecated. Please use course/format/update.php instead.', + DEBUG_DEVELOPER + ); set_section_visible($course->id, $show, '1'); if ($sectionid) { redirect(course_get_url($course, $section, ['navigation' => true])); @@ -219,7 +228,12 @@ } } + // TODO remove this if as part of MDL-83530. if ($marker >= 0 && confirm_sesskey()) { + debugging( + 'The marker param in course view is deprecated. Please use course/format/update.php instead.', + DEBUG_DEVELOPER + ); course_set_marker($course->id, $marker); if ($sectionid) { redirect(course_get_url($course, $section, ['navigation' => true]));