diff --git a/lang/en/user.php b/lang/en/user.php index 0ea92252237..e55d295ff8b 100644 --- a/lang/en/user.php +++ b/lang/en/user.php @@ -139,6 +139,7 @@ $string['supportmessagealternative'] = 'Instead you can email {$a}.'; $string['target:upcomingactivitiesdue'] = 'Upcoming activities due'; $string['target:upcomingactivitiesdue_help'] = 'This target generates reminders for upcoming activities due.'; $string['target:upcomingactivitiesdueinfo'] = 'All upcoming activities due insights are listed here. These students have received these insights directly.'; +$string['userprofile'] = 'User profile'; // Deprecated since Moodle 4.1. $string['addcondition'] = 'Add condition'; diff --git a/lib/classes/output/activity_header.php b/lib/classes/output/activity_header.php index 6dc63327f8f..7b23b69cf7b 100644 --- a/lib/classes/output/activity_header.php +++ b/lib/classes/output/activity_header.php @@ -197,4 +197,22 @@ class activity_header implements \renderable, \templatable { 'additional_items' => $this->hideoverflow ? '' : $this->additionalnavitems, ]; } + + /** + * Get the heading level for a given heading depending on whether the theme's activity header displays a heading + * (usually the activity name). + * + * @param int $defaultlevel The default heading level when the activity header does not display a heading. + * @return int + */ + public function get_heading_level(int $defaultlevel = 2): int { + // The heading level depends on whether the theme's activity header displays a heading (usually the activity name). + $headinglevel = $defaultlevel; + if ($this->is_title_allowed() && !empty(trim($this->title))) { + // A heading for the activity name is displayed on this page with a heading level 2. + // Increment the default level for this heading by 1. + $headinglevel++; + } + return $headinglevel; + } } diff --git a/lib/tests/output/activity_header_test.php b/lib/tests/output/activity_header_test.php index 84ac118ad92..aa9717c2176 100644 --- a/lib/tests/output/activity_header_test.php +++ b/lib/tests/output/activity_header_test.php @@ -123,4 +123,37 @@ class activity_header_test extends \advanced_testcase { $PAGE->activityheader->set_attrs(['unknown' => true]); $this->assertDebuggingCalledCount(1, ['Invalid class member variable: unknown']); } + + /** + * Data provider for {@see test_get_heading_level()}. + * + * @return array[] + */ + public function get_heading_level_provider(): array { + return [ + 'Title not allowed' => [false, '', 2], + 'Title allowed, no title' => [true, '', 2], + 'Title allowed, empty string title' => [true, ' ', 2], + 'Title allowed, non-empty string title' => [true, 'Cool', 3], + ]; + } + + /** + * Test the heading level getter + * + * @dataProvider get_heading_level_provider + * @covers ::get_heading_level + * @param bool $allowtitle Whether the title is allowed. + * @param string $title The activity heading. + * @param int $expectedheadinglevel The expected heading level. + */ + public function test_get_heading_level(bool $allowtitle, string $title, int $expectedheadinglevel): void { + $activityheaderstub = $this->getMockBuilder(activity_header::class) + ->disableOriginalConstructor() + ->onlyMethods(['is_title_allowed']) + ->getMock(); + $activityheaderstub->method('is_title_allowed')->willReturn($allowtitle); + $activityheaderstub->set_title($title); + $this->assertEquals($expectedheadinglevel, $activityheaderstub->get_heading_level()); + } } diff --git a/lib/upgrade.txt b/lib/upgrade.txt index 3bdc64d97bb..75c79327028 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -5,6 +5,8 @@ information provided here is intended especially for developers. * Added new \admin_setting::is_forceable() method to determine whether the setting can be overridden or not. Therefore, whether the settings can be overriden or not will depend on the value of implemented \admin_setting::is_forceable() method, even if we define the settings in config.php. +* New \core\output\activity_header::get_heading_level() method to get the heading level for a given heading level depending whether + the page displays a heading for the activity (usually a h2 heading containing the activity name). === 4.1.4 === * Added a new parameter in address_in_subnet to give us the ability to check for 0.0.0.0 or not. diff --git a/mod/lesson/classes/output/edit_action_area.php b/mod/lesson/classes/output/edit_action_area.php index c33edb1e694..0bcc4c8ade5 100644 --- a/mod/lesson/classes/output/edit_action_area.php +++ b/mod/lesson/classes/output/edit_action_area.php @@ -60,6 +60,7 @@ class edit_action_area implements templatable, renderable { * @return array Said data. */ public function export_for_template(\renderer_base $output): array { + global $PAGE; $viewurl = new moodle_url('/mod/lesson/edit.php', ['id' => $this->cmid, 'mode' => 'collapsed']); $fullviewurl = new moodle_url('/mod/lesson/edit.php', ['id' => $this->cmid, 'mode' => 'full']); @@ -69,14 +70,18 @@ class edit_action_area implements templatable, renderable { ]; $selectmenu = new \url_select($menu, $this->currenturl->out(false), null, 'mod_lesson_navigation_select'); + $selectmenu->label = get_string('displaymode', 'mod_lesson'); + $selectmenu->labelattributes = ['class' => 'sr-only']; + $headinglevel = $PAGE->activityheader->get_heading_level(); return [ 'back' => [ 'text' => get_string('back', 'core'), 'link' => (new moodle_url('/mod/lesson/view.php', ['id' => $this->cmid]))->out(false) ], 'viewselect' => $selectmenu->export_for_template($output), - 'heading' => get_string('editinglesson', 'mod_lesson') + 'heading' => get_string('editinglesson', 'mod_lesson'), + 'headinglevel' => $headinglevel, ]; } } diff --git a/mod/lesson/classes/output/override_action_menu.php b/mod/lesson/classes/output/override_action_menu.php index 6555ac10e9b..43a68e5d709 100644 --- a/mod/lesson/classes/output/override_action_menu.php +++ b/mod/lesson/classes/output/override_action_menu.php @@ -69,7 +69,10 @@ class override_action_menu implements templatable, renderable { $userlink->out(false) => get_string('useroverrides', 'mod_lesson'), $grouplink->out(false) => get_string('groupoverrides', 'mod_lesson'), ]; - return new \url_select($menu, $this->currenturl->out(false), null, 'mod_lesson_override_select'); + $selectmenu = new \url_select($menu, $this->currenturl->out(false), null, 'mod_lesson_override_select'); + $selectmenu->label = get_string('manageoverrides', 'mod_lesson'); + $selectmenu->labelattributes = ['class' => 'sr-only']; + return $selectmenu; } /** @@ -79,6 +82,8 @@ class override_action_menu implements templatable, renderable { * @return array Said data. */ public function export_for_template(\renderer_base $output): array { + global $PAGE; + $type = $this->currenturl->get_param('mode'); if ($type == 'user') { $text = get_string('addnewuseroverride', 'mod_lesson'); @@ -100,6 +105,7 @@ class override_action_menu implements templatable, renderable { ]; } $data['heading'] = get_string($type == 'user' ? 'useroverrides' : 'groupoverrides', 'mod_lesson'); + $data['headinglevel'] = $PAGE->activityheader->get_heading_level(); return $data; } } diff --git a/mod/lesson/classes/output/report_action_menu.php b/mod/lesson/classes/output/report_action_menu.php index f8544036e91..4690fafe176 100644 --- a/mod/lesson/classes/output/report_action_menu.php +++ b/mod/lesson/classes/output/report_action_menu.php @@ -60,6 +60,8 @@ class report_action_menu implements templatable, renderable { * @return array The data for the template. */ public function export_for_template(\renderer_base $output): array { + global $PAGE; + $overviewlink = new moodle_url('/mod/lesson/report.php', ['id' => $this->lessonid, 'action' => 'reportoverview']); $fulllink = new moodle_url('/mod/lesson/report.php', ['id' => $this->lessonid, 'action' => 'reportdetail']); $menu = [ @@ -67,9 +69,13 @@ class report_action_menu implements templatable, renderable { $fulllink->out(false) => get_string('detailedstats', 'mod_lesson') ]; $reportselect = new \url_select($menu, $this->url->out(false), null, 'lesson-report-select'); + $reportselect->label = get_string('selectreport', 'mod_lesson'); + $reportselect->labelattributes = ['class' => 'sr-only']; + $data = [ 'reportselect' => $reportselect->export_for_template($output), - 'heading' => $menu[$reportselect->selected] ?? '' + 'heading' => $menu[$reportselect->selected] ?? '', + 'headinglevel' => $PAGE->activityheader->get_heading_level(), ]; return $data; } diff --git a/mod/lesson/import.php b/mod/lesson/import.php index 2e00a64ca6a..ec15da8f765 100644 --- a/mod/lesson/import.php +++ b/mod/lesson/import.php @@ -63,7 +63,8 @@ $mform->set_data($data); ]); $PAGE->add_body_class('limitedwidth'); echo $OUTPUT->header(); - echo $OUTPUT->heading_with_help($strimportquestions, 'importquestions', 'lesson', '', '', 3); + $headinglevel = $PAGE->activityheader->get_heading_level(); + echo $OUTPUT->heading_with_help($strimportquestions, 'importquestions', 'lesson', '', '', $headinglevel); if ($data = $mform->get_data()) { diff --git a/mod/lesson/lang/en/lesson.php b/mod/lesson/lang/en/lesson.php index 9835843fe03..17281f8d1dd 100644 --- a/mod/lesson/lang/en/lesson.php +++ b/mod/lesson/lang/en/lesson.php @@ -168,6 +168,7 @@ $string['displayleftif'] = 'Minimum grade to display menu'; $string['displayleftif_help'] = 'This setting determines whether a student must obtain a certain grade before viewing the lesson menu. This forces the student to go through the entire lesson on their first attempt, then after obtaining the required grade they can use the menu for review.'; $string['displayleftmenu'] = 'Display menu'; $string['displayleftmenu_help'] = 'If enabled, a menu allowing users to navigate through the list of pages is displayed.'; +$string['displaymode'] = 'Display mode'; $string['displayofgrade'] = 'Display of grade (for students only)'; $string['displayreview'] = 'Provide option to try a question again'; $string['displayreview_help'] = 'If enabled, when a question is answered incorrectly, the student is given the option to try it again for no point credit, or continue with the lesson. If the student clicks to move on to another question then the selected (wrong) answer will be followed. By default wrong answer jumps are set to "this page" and have a score of 0, so it is recommended that you set the wrong answer jump to a different page to avoid confusion with your students.'; @@ -318,6 +319,7 @@ $string['linkedmedia'] = 'Linked media'; $string['loginfail'] = 'Login failed, please try again...'; $string['lowscore'] = 'Low score'; $string['lowtime'] = 'Low time'; +$string['manageoverrides'] = 'Manage overrides'; $string['manualgrading'] = 'Grade essays'; $string['matchesanswer'] = 'Matches with answer'; $string['matching'] = 'Matching'; @@ -542,6 +544,7 @@ $string['search:activity'] = 'Lesson - activity information'; $string['secondpluswrong'] = 'Not quite. Would you like to try again?'; $string['selectaqtype'] = 'Select a question type'; $string['selectallattempts'] = 'Select all attempts'; +$string['selectreport'] = 'Select report'; $string['sent'] = 'Sent'; $string['shortanswer'] = 'Short answer'; $string['showanunansweredpage'] = 'Show an unanswered page'; diff --git a/mod/lesson/lesson.php b/mod/lesson/lesson.php index 74baa8c70a9..9b7089ce391 100644 --- a/mod/lesson/lesson.php +++ b/mod/lesson/lesson.php @@ -81,7 +81,8 @@ switch ($action) { $title = $DB->get_field("lesson_pages", "title", array("id" => $pageid)); echo $lessonoutput->header($lesson, $cm, '', false, null, get_string('moving', 'lesson', format_String($title))); - echo $OUTPUT->heading(get_string("moving", "lesson", format_string($title)), 3); + $headinglevel = $PAGE->activityheader->get_heading_level(); + echo $OUTPUT->heading(get_string("moving", "lesson", format_string($title)), $headinglevel); $params = array ("lessonid" => $lesson->id, "prevpageid" => 0); if (!$page = $DB->get_record_select("lesson_pages", "lessonid = :lessonid AND prevpageid = :prevpageid", $params)) { diff --git a/mod/lesson/pagetypes/branchtable.php b/mod/lesson/pagetypes/branchtable.php index 148d25e0e05..7ce0f2c8d1f 100644 --- a/mod/lesson/pagetypes/branchtable.php +++ b/mod/lesson/pagetypes/branchtable.php @@ -113,8 +113,10 @@ class lesson_page_type_branchtable extends lesson_page { if ($this->lesson->slideshow) { $output .= $renderer->slideshow_start($this->lesson); } - // We are using level 3 header because the page title is a sub-heading of lesson title (MDL-30911). - $output .= $renderer->heading(format_string($this->properties->title), 3); + + // The heading level depends on whether the theme's activity header displays a heading (usually the activity name). + $headinglevel = $PAGE->activityheader->get_heading_level(); + $output .= $renderer->heading(format_string($this->properties->title), $headinglevel); $output .= $renderer->box($this->get_contents(), 'contents'); $buttons = array(); diff --git a/mod/lesson/renderer.php b/mod/lesson/renderer.php index 09d29fc42cb..d32f557b138 100644 --- a/mod/lesson/renderer.php +++ b/mod/lesson/renderer.php @@ -368,10 +368,10 @@ class mod_lesson_renderer extends plugin_renderer_base { * @return string */ public function add_first_page_links(lesson $lesson) { - global $CFG; $prevpageid = 0; - $output = $this->output->heading(get_string("whatdofirst", "lesson"), 3); + $headinglevel = $this->page->activityheader->get_heading_level(3); + $output = $this->output->heading(get_string("whatdofirst", "lesson"), $headinglevel); $links = array(); $importquestionsurl = new moodle_url('/mod/lesson/import.php',array('id'=>$this->page->cm->id, 'pageid'=>$prevpageid)); @@ -567,8 +567,8 @@ class mod_lesson_renderer extends plugin_renderer_base { } if ($data->gradelesson) { - // We are using level 3 header because the page title is a sub-heading of lesson title (MDL-30911). - $output .= $this->heading(get_string("congratulations", "lesson"), 3); + $headinglevel = $this->page->activityheader->get_heading_level(); + $output .= $this->heading(get_string("congratulations", "lesson"), $headinglevel); $output .= $this->box_start('generalbox boxaligncenter'); } diff --git a/mod/lesson/templates/edit_action_area.mustache b/mod/lesson/templates/edit_action_area.mustache index 15325a35e7e..f0278897d6c 100644 --- a/mod/lesson/templates/edit_action_area.mustache +++ b/mod/lesson/templates/edit_action_area.mustache @@ -64,7 +64,9 @@ ]}], "disabled": false, "title": "Some cool title" - } + }, + "headinglevel": 3, + "heading": "Some heading" } }} @@ -80,4 +82,4 @@ {{/viewselect}} -

{{heading}}

+{{heading}} diff --git a/mod/lesson/templates/override_action_menu.mustache b/mod/lesson/templates/override_action_menu.mustache index 6ef1fbad332..6fd20bb9361 100644 --- a/mod/lesson/templates/override_action_menu.mustache +++ b/mod/lesson/templates/override_action_menu.mustache @@ -64,7 +64,9 @@ "addoverride": { "link": "https://moodle.org", "text": "Add override" - } + }, + "headinglevel": 3, + "heading": "Some heading" } }} @@ -82,4 +84,4 @@ {{/addoverride}} -

{{heading}}

+{{heading}} diff --git a/mod/lesson/templates/report_action_menu.mustache b/mod/lesson/templates/report_action_menu.mustache index 905b2bbbf2c..2ac0ec91bc0 100644 --- a/mod/lesson/templates/report_action_menu.mustache +++ b/mod/lesson/templates/report_action_menu.mustache @@ -58,7 +58,9 @@ {"name": "Item 4", "isgroup": false, "value": "4"} ]}], "disabled": false, - "title": "Some cool title" + "title": "Some cool title", + "headinglevel": 3, + "heading": "Some heading" } }} @@ -71,4 +73,4 @@ {{/reportselect}} -

{{heading}}

+{{heading}} diff --git a/user/profile.php b/user/profile.php index 93f53787f5a..be5ce4851ae 100644 --- a/user/profile.php +++ b/user/profile.php @@ -220,6 +220,7 @@ if ($user->description && !isset($hiddenfields['description'])) { echo ''; } +echo $OUTPUT->heading(get_string('userprofile', 'core_user'), 2, 'sr-only'); echo $OUTPUT->custom_block_region('content'); // Render custom blocks.