From aa9a591ecd4d40155bed9eba4ec2e72245eb8d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luca=20B=C3=B6sch?= Date: Tue, 29 Dec 2020 12:55:28 +0100 Subject: [PATCH] MDL-70433 grades: prevent double escaping in titles --- grade/edit/tree/lib.php | 2 +- grade/lib.php | 5 +- grade/report/grader/lib.php | 3 +- grade/templates/edit_tree.mustache | 2 +- grade/tests/behat/grade_aggregation.feature | 89 ++++++++++--------- .../behat/grade_aggregation_changes.feature | 31 +++---- lib/grade/grade_category.php | 9 +- lib/grade/grade_item.php | 7 +- lib/grade/tests/fixtures/lib.php | 4 +- lib/grade/tests/grade_category_test.php | 21 ++++- lib/grade/tests/grade_item_test.php | 25 ++++-- lib/upgrade.txt | 2 + 12 files changed, 120 insertions(+), 80 deletions(-) diff --git a/grade/edit/tree/lib.php b/grade/edit/tree/lib.php index 8e1be55d6538b..7317c8ea62439 100644 --- a/grade/edit/tree/lib.php +++ b/grade/edit/tree/lib.php @@ -1021,7 +1021,7 @@ public function get_category_cell($category, $levelclass, $params) { $masterlabel = get_string('all'); // Use category name if available. if ($category->fullname !== '?') { - $masterlabel = format_string($category->fullname); + $masterlabel = format_string($category->fullname, true, ['escape' => false]); // Limit the displayed category name to prevent the Select column from getting too wide. if (core_text::strlen($masterlabel) > 20) { $masterlabel = get_string('textellipsis', 'core', core_text::substr($masterlabel, 0, 12)); diff --git a/grade/lib.php b/grade/lib.php index 0ae85d9b9af3f..b03820624f995 100644 --- a/grade/lib.php +++ b/grade/lib.php @@ -1639,6 +1639,7 @@ public function get_element_header(&$element, $withlink = false, $icon = true, $ } $title = $element['object']->get_name($fulltotal); + $titleunescaped = $element['object']->get_name($fulltotal, false); $header .= $title; if ($element['type'] != 'item' and $element['type'] != 'categoryitem' and @@ -1649,12 +1650,12 @@ public function get_element_header(&$element, $withlink = false, $icon = true, $ if ($withlink && $url = $this->get_activity_link($element)) { $a = new stdClass(); $a->name = get_string('modulename', $element['object']->itemmodule); - $a->title = $title; + $a->title = $titleunescaped; $title = get_string('linktoactivity', 'grades', $a); $header = html_writer::link($url, $header, array('title' => $title, 'class' => 'gradeitemheader')); } else { - $header = html_writer::span($header, 'gradeitemheader', array('title' => $title, 'tabindex' => '0')); + $header = html_writer::span($header, 'gradeitemheader', array('title' => $titleunescaped, 'tabindex' => '0')); } if ($withdescription) { diff --git a/grade/report/grader/lib.php b/grade/report/grader/lib.php index bba2d312bed8c..874af23cf80c3 100644 --- a/grade/report/grader/lib.php +++ b/grade/report/grader/lib.php @@ -1666,9 +1666,10 @@ protected function get_course_header($element) { } $name = $element['object']->get_name(); + $nameunescaped = $element['object']->get_name(false); $describedbyid = uniqid(); $courseheader = html_writer::tag('span', $name, [ - 'title' => $name, + 'title' => $nameunescaped, 'class' => 'gradeitemheader', 'aria-describedby' => $describedbyid ]); diff --git a/grade/templates/edit_tree.mustache b/grade/templates/edit_tree.mustache index 5767d761ddc36..eb678f87a8608 100644 --- a/grade/templates/edit_tree.mustache +++ b/grade/templates/edit_tree.mustache @@ -60,7 +60,7 @@ diff --git a/grade/tests/behat/grade_aggregation.feature b/grade/tests/behat/grade_aggregation.feature index 68a9104123439..d9abd0485c3ed 100644 --- a/grade/tests/behat/grade_aggregation.feature +++ b/grade/tests/behat/grade_aggregation.feature @@ -17,25 +17,25 @@ Feature: We can use calculated grade totals | teacher1 | C1 | editingteacher | | student1 | C1 | student | And the following "grade categories" exist: - | fullname | course | - | Sub category 1 | C1 | - | Sub category 2 | C1 | + | fullname | course | + | Sub category 1 | C1 | + | Sub category 2 & | C1 | And the following "activities" exist: - | activity | course | idnumber | name | intro | grade | - | assign | C1 | a1 | Test assignment one | Submit something! | 300 | - | assign | C1 | a2 | Test assignment two | Submit something! | 100 | - | assign | C1 | a3 | Test assignment three | Submit something! | 150 | - | assign | C1 | a4 | Test assignment four | Submit nothing! | 150 | + | activity | course | idnumber | name | intro | grade | + | assign | C1 | a1 | Test assignment one & | Submit something! | 300 | + | assign | C1 | a2 | Test assignment two | Submit something! | 100 | + | assign | C1 | a3 | Test assignment three | Submit something! | 150 | + | assign | C1 | a4 | Test assignment four | Submit nothing! | 150 | And the following "activities" exist: | activity | course | idnumber | name | intro | gradecategory | grade | | assign | C1 | a5 | Test assignment five | Submit something! | Sub category 1 | 20 | | assign | C1 | a6 | Test assignment six | Submit something! | Sub category 1 | 10 | | assign | C1 | a7 | Test assignment seven | Submit nothing! | Sub category 1 | 15 | And the following "activities" exist: - | activity | course | idnumber | name | intro | gradecategory | grade | - | assign | C1 | a8 | Test assignment eight | Submit something! | Sub category 2 | 20 | - | assign | C1 | a9 | Test assignment nine | Submit something! | Sub category 2 | 10 | - | assign | C1 | 10 | Test assignment ten | Submit nothing! | Sub category 2 | 15 | + | activity | course | idnumber | name | intro | gradecategory | grade | + | assign | C1 | a8 | Test assignment eight | Submit something! | Sub category 2 & | 20 | + | assign | C1 | a9 | Test assignment nine | Submit something! | Sub category 2 & | 10 | + | assign | C1 | 10 | Test assignment ten | Submit nothing! | Sub category 2 & | 15 | And I log in as "admin" And I set the following administration settings values: | grade_aggregations_visible | Mean of grades,Weighted mean of grades,Simple weighted mean of grades,Mean of grades (with extra credits),Median of grades,Lowest grade,Highest grade,Mode of grades,Natural | @@ -45,7 +45,7 @@ Feature: We can use calculated grade totals And I navigate to "View > Grader report" in the course gradebook And I turn editing mode on And I change window size to "large" - And I give the grade "60.00" to the user "Student 1" for the grade item "Test assignment one" + And I give the grade "60.00" to the user "Student 1" for the grade item "Test assignment one &" And I give the grade "20.00" to the user "Student 1" for the grade item "Test assignment two" And I give the grade "40.00" to the user "Student 1" for the grade item "Test assignment three" And I give the grade "10.00" to the user "Student 1" for the grade item "Test assignment five" @@ -69,7 +69,7 @@ Feature: We can use calculated grade totals | Aggregation | Mean of grades | And I set the following settings for grade item "Sub category 1": | Aggregation | Mean of grades | - And I set the following settings for grade item "Sub category 2": + And I set the following settings for grade item "Sub category 2 &": | Aggregation | Mean of grades | | Exclude empty grades | 0 | And I turn editing mode off @@ -88,11 +88,11 @@ Feature: We can use calculated grade totals And I set the following settings for grade item "Sub category 1": | Aggregation | Weighted mean of grades | | Item weight | 1 | - And I set the following settings for grade item "Sub category 2": + And I set the following settings for grade item "Sub category 2 &": | Aggregation | Weighted mean of grades | | Item weight | 1 | | Exclude empty grades | 0 | - And I set the following settings for grade item "Test assignment one": + And I set the following settings for grade item "Test assignment one &": | Item weight | 3 | And I turn editing mode off Then I should see "27.14 (27.14 %)" in the ".course" "css_element" @@ -109,10 +109,10 @@ Feature: We can use calculated grade totals | Aggregation | Simple weighted mean of grades | And I set the following settings for grade item "Sub category 1": | Aggregation | Simple weighted mean of grades | - And I set the following settings for grade item "Sub category 2": + And I set the following settings for grade item "Sub category 2 &": | Aggregation | Simple weighted mean of grades | | Exclude empty grades | 0 | - And I set the following settings for grade item "Test assignment one": + And I set the following settings for grade item "Test assignment one &": | Extra credit | 1 | And I turn editing mode off Then I should see "45.19 (45.19 %)" in the ".course" "css_element" @@ -129,10 +129,10 @@ Feature: We can use calculated grade totals | Aggregation | Mean of grades (with extra credits) | And I set the following settings for grade item "Sub category 1": | Aggregation | Mean of grades (with extra credits) | - And I set the following settings for grade item "Sub category 2": + And I set the following settings for grade item "Sub category 2 &": | Aggregation | Mean of grades (with extra credits) | | Exclude empty grades | 0 | - And I set the following settings for grade item "Test assignment one": + And I set the following settings for grade item "Test assignment one &": | Extra credit weight | 2 | And I turn editing mode off Then I should see "42.50 (42.50 %)" in the ".course" "css_element" @@ -149,7 +149,7 @@ Feature: We can use calculated grade totals | Aggregation | Median of grades | And I set the following settings for grade item "Sub category 1": | Aggregation | Median of grades | - And I set the following settings for grade item "Sub category 2": + And I set the following settings for grade item "Sub category 2 &": | Aggregation | Median of grades | | Exclude empty grades | 0 | And I turn editing mode off @@ -167,7 +167,7 @@ Feature: We can use calculated grade totals | Aggregation | Lowest grade | And I set the following settings for grade item "Sub category 1": | Aggregation | Lowest grade | - And I set the following settings for grade item "Sub category 2": + And I set the following settings for grade item "Sub category 2 &": | Aggregation | Lowest grade | | Exclude empty grades | 0 | And I set the following settings for grade item "Test assignment five": @@ -189,10 +189,10 @@ Feature: We can use calculated grade totals | Aggregation | Highest grade | And I set the following settings for grade item "Sub category 1": | Aggregation | Highest grade | - And I set the following settings for grade item "Sub category 2": + And I set the following settings for grade item "Sub category 2 &": | Aggregation | Highest grade | | Exclude empty grades | 0 | - And I set the following settings for grade item "Test assignment one": + And I set the following settings for grade item "Test assignment one &": | Hidden | 1 | And I turn editing mode off Then I should see "50.00 (50.00 %)" in the ".course" "css_element" @@ -212,7 +212,7 @@ Feature: We can use calculated grade totals And I set the following settings for grade item "Sub category 1": | Aggregation | Mode of grades | | Exclude empty grades | 0 | - And I set the following settings for grade item "Test assignment one": + And I set the following settings for grade item "Test assignment one &": | Hidden | 1 | And I turn editing mode off Then I should see "50.00 (50.00 %)" in the ".course" "css_element" @@ -318,7 +318,7 @@ Feature: We can use calculated grade totals And I set the following settings for grade item "Sub category 1": | Aggregation | Natural | | Exclude empty grades | 0 | - And I set the following settings for grade item "Sub category 2": + And I set the following settings for grade item "Sub category 2 &": | Aggregation | Natural | | Exclude empty grades | 1 | And I set the following settings for grade item "Course 1": @@ -348,7 +348,7 @@ Feature: We can use calculated grade totals | Test assignment eight | 66.67 % | 10.00 (50.00 %) | 0–20 | 1.60 % | | Test assignment nine | 33.33 % | 5.00 (50.00 %) | 0–10 | 0.80 % | | Test assignment ten | 0.00 %( Empty ) | - | 0–15 | 0.00 % | - | Test assignment one | 48.00 % | 60.00 (20.00 %) | 0–300 | 9.60 % | + | Test assignment one & | 48.00 % | 60.00 (20.00 %) | 0–300 | 9.60 % | | Test assignment two | 16.00 % | 20.00 (20.00 %) | 0–100 | 3.20 % | | Test assignment three | 24.00 %( Extra credit ) | 40.00 (26.67 %) | 0–150 | 6.40 % | | Test assignment four | 24.00 % | - | 0–150 | 0.00 % | @@ -363,7 +363,7 @@ Feature: We can use calculated grade totals | Test assignment seven | 30.00 % | - | 0–15 | 0.00 % | | Test assignment nine | 100.00 % | 5.00 (50.00 %) | 0–10 | 1.03 % | | Test assignment ten | -( Empty ) | - | 0–15 | - | - | Test assignment one | 61.86 % | 60.00 (20.00 %) | 0–300 | 12.37 % | + | Test assignment one & | 61.86 % | 60.00 (20.00 %) | 0–300 | 12.37 % | | Test assignment three | 30.93 %( Extra credit ) | 40.00 (26.67 %) | 0–150 | 8.25 % | | Test assignment four | 30.93 % | - | 0–150 | 0.00 % | @@ -376,7 +376,7 @@ Feature: We can use calculated grade totals And I set the following settings for grade item "Sub category 1": | Aggregation | Natural | | Exclude empty grades | 0 | - And I set the following settings for grade item "Sub category 2": + And I set the following settings for grade item "Sub category 2 &": | Aggregation | Natural | | Exclude empty grades | 0 | And I set the following settings for grade item "Course 1": @@ -450,16 +450,17 @@ Feature: We can use calculated grade totals @javascript Scenario: Natural aggregation from the setup screen And I navigate to "Setup > Gradebook setup" in the course gradebook + And I set the following settings for grade item "Course 1": | Aggregation | Natural | And I set the following settings for grade item "Sub category 1": | Aggregation | Natural | - And I set the following settings for grade item "Sub category 2": + And I set the following settings for grade item "Sub category 2 &": | Aggregation | Natural | - And I set the field "Override weight of Test assignment one" to "1" - And the field "Weight of Test assignment one" matches value "37.975" - And I set the field "Weight of Test assignment one" to "10" + And I set the field "Override weight of Test assignment one &" to "1" + And the field "Weight of Test assignment one &" matches value "37.975" + And I set the field "Weight of Test assignment one &" to "10" And I set the field "Override weight of Test assignment two" to "1" And the field "Weight of Test assignment two" matches value "12.658" @@ -482,21 +483,21 @@ Feature: We can use calculated grade totals And I set the field "Override weight of Test assignment two" to "1" And I set the field "Override weight of Test assignment six" to "1" - Then the field "Weight of Test assignment one" matches value "10.0" + Then the field "Weight of Test assignment one &" matches value "10.0" And the field "Weight of Test assignment two" matches value "16.854" And the field "Weight of Test assignment six" matches value "22.222" And the field "Weight of Test assignment ten" matches value "50.0" And the field "Weight of Sub category 1" matches value "15.0" - And I set the field "Override weight of Test assignment one" to "0" + And I set the field "Override weight of Test assignment one &" to "0" And I set the field "Override weight of Test assignment two" to "0" And I set the field "Override weight of Test assignment six" to "0" And I set the field "Override weight of Sub category 1" to "0" And I press "Save changes" - And I set the field "Override weight of Test assignment one" to "1" + And I set the field "Override weight of Test assignment one &" to "1" And I set the field "Override weight of Sub category 1" to "1" - And the field "Weight of Test assignment one" matches value "37.975" + And the field "Weight of Test assignment one &" matches value "37.975" And the field "Weight of Sub category 1" matches value "5.696" - And I reset weights for grade category "Sub category 2" + And I reset weights for grade category "Sub category 2 &" And the field "Weight of Test assignment ten" matches value "33.333" @javascript @@ -507,13 +508,15 @@ Feature: We can use calculated grade totals And I set the following settings for grade item "Sub category 1": | Aggregation | Natural | | Exclude empty grades | 0 | - And I set the following settings for grade item "Sub category 2": + And I set the following settings for grade item "Sub category 2 &": | Aggregation | Natural | | Exclude empty grades | 0 | And I turn editing mode off And I navigate to "Setup > Gradebook setup" in the course gradebook - And I set the field "Override weight of Test assignment one" to "1" - And I set the field "Weight of Test assignment one" to "0" + And "//span[@class='grateitemheader'][@title='Sub category 2 &']" "xpath_element" should not exist + And "//span[@class='grateitemheader'][@title='Link to Test assignment one & Assignment']" "xpath_element" should not exist + And I set the field "Override weight of Test assignment one &" to "1" + And I set the field "Weight of Test assignment one &" to "0" And I set the field "Override weight of Test assignment six" to "1" And I set the field "Weight of Test assignment six" to "0" And I set the field "Override weight of Test assignment nine" to "1" @@ -537,7 +540,7 @@ Feature: We can use calculated grade totals | Test assignment eight | 0.00 % | 10.00 (50.00 %) | 0.00 % | | Test assignment nine | 100.00 % | 5.00 (50.00 %) | 1.12 % | | Test assignment ten | 0.00 % | - | 0.00 % | - | Test assignment one | 0.00 % | 60.00 (20.00 %) | 0.00 % | + | Test assignment one & | 0.00 % | 60.00 (20.00 %) | 0.00 % | | Test assignment two | 22.47 % | 20.00 (20.00 %) | 4.49 % | | Test assignment three | 33.71 % | 40.00 (26.67 %) | 8.99 % | | Test assignment four | 33.71 % | - | 0.00 | @@ -552,6 +555,6 @@ Feature: We can use calculated grade totals | Test assignment seven | 100.00 % | - | 0.00 % | | Test assignment nine | 100.00 % | 5.00 (50.00 %) | 1.54 % | | Test assignment ten | 0.00 | - | 0.00 % | - | Test assignment one | 0.00 % | 60.00 (20.00 %) | 0.00 % | + | Test assignment one & | 0.00 % | 60.00 (20.00 %) | 0.00 % | | Test assignment three | 46.15 % | 40.00 (26.67 %) | 12.31 % | | Test assignment four | 46.15 % | - | 0.00 % | diff --git a/grade/tests/behat/grade_aggregation_changes.feature b/grade/tests/behat/grade_aggregation_changes.feature index 68835bb361ee4..f626875dc3816 100644 --- a/grade/tests/behat/grade_aggregation_changes.feature +++ b/grade/tests/behat/grade_aggregation_changes.feature @@ -19,17 +19,17 @@ Feature: Changing the aggregation of an item affects its weight and extra credit | Cat weighted2 | C1 | 10 | | Cat simple | C1 | 11 | | Cat ec | C1 | 12 | - | Cat natural | C1 | 13 | + | Cat natural & | C1 | 13 | And the following "grade items" exist: - | itemname | course | category | aggregationcoef | aggregationcoef2 | weightoverride | - | Item a1 | C1 | ? | 0 | 0 | 0 | - | Item a2 | C1 | ? | 0 | 0.40 | 1 | - | Item a3 | C1 | ? | 1 | 0.10 | 1 | - | Item a4 | C1 | ? | 1 | 0 | 0 | - | Item b1 | C1 | Cat natural | 0 | 0 | 0 | - | Item b2 | C1 | Cat natural | 0 | 0.40 | 1 | - | Item b3 | C1 | Cat natural | 1 | 0.10 | 1 | - | Item b4 | C1 | Cat natural | 1 | 0 | 0 | + | itemname | course | category | aggregationcoef | aggregationcoef2 | weightoverride | + | Item a1 | C1 | ? | 0 | 0 | 0 | + | Item a2 | C1 | ? | 0 | 0.40 | 1 | + | Item a3 | C1 | ? | 1 | 0.10 | 1 | + | Item a4 | C1 | ? | 1 | 0 | 0 | + | Item b1 | C1 | Cat natural & | 0 | 0 | 0 | + | Item b2 | C1 | Cat natural & | 0 | 0.40 | 1 | + | Item b3 | C1 | Cat natural & | 1 | 0.10 | 1 | + | Item b4 | C1 | Cat natural & | 1 | 0 | 0 | And I log in as "admin" And I set the following administration settings values: | grade_aggregations_visible | Mean of grades,Weighted mean of grades,Simple weighted mean of grades,Mean of grades (with extra credits),Median of grades,Lowest grade,Highest grade,Mode of grades,Natural | @@ -133,7 +133,7 @@ Feature: Changing the aggregation of an item affects its weight and extra credit And I should not see "Weight" in the "#id_headerparent" "css_element" And I should not see "Extra credit" And I press "Cancel" - And I follow "Edit Cat natural" + And I follow "Edit Cat natural &" And I set the field "Aggregation" to "Mean of grades" And I press "Save changes" And I follow "Edit Item b1" @@ -191,7 +191,7 @@ Feature: Changing the aggregation of an item affects its weight and extra credit And the field "Weight adjusted" matches value "0" And the field "Extra credit" matches value "0" And I press "Cancel" - And I follow "Edit Cat natural" + And I follow "Edit Cat natural &" And I set the field "Aggregation" to "Natural" And I press "Save changes" And I follow "Edit Item b1" @@ -253,7 +253,7 @@ Feature: Changing the aggregation of an item affects its weight and extra credit And I should not see "Extra credit" And the field "Item weight" matches value "1" And I press "Cancel" - And I follow "Edit Cat natural" + And I follow "Edit Cat natural &" And I set the field "Aggregation" to "Weighted mean of grades" And I press "Save changes" And I follow "Edit Item b1" @@ -311,7 +311,7 @@ Feature: Changing the aggregation of an item affects its weight and extra credit And the field "Weight adjusted" matches value "0" And the field "Extra credit" matches value "0" And I press "Cancel" - And I follow "Edit Cat natural" + And I follow "Edit Cat natural &" And I set the field "Aggregation" to "Natural" And I press "Save changes" And I follow "Edit Item b1" @@ -339,7 +339,8 @@ Feature: Changing the aggregation of an item affects its weight and extra credit And I set the field "Select Item a2" to "1" And I set the field "Select Item a3" to "1" And I set the field "Select Item a4" to "1" - When I select "Cat natural" from the "Move selected items to" singleselect + And I should not see "Cat natural &" in the "select#menumoveafter" "css_element" + When I select "Cat natural &" from the "Move selected items to" singleselect And I navigate to "View > Grader report" in the course gradebook And I follow "Edit Item a1" Then the field "Weight adjusted" matches value "0" diff --git a/lib/grade/grade_category.php b/lib/grade/grade_category.php index b057fce0b5d66..3f96c3c6f0ebf 100644 --- a/lib/grade/grade_category.php +++ b/lib/grade/grade_category.php @@ -2311,18 +2311,21 @@ public function get_parent_category() { * Returns the most descriptive field for this grade category * * @return string name + * @param bool $escape Whether the returned category name is to be HTML escaped or not. */ - public function get_name() { + public function get_name($escape = true) { global $DB; // For a course category, we return the course name if the fullname is set to '?' in the DB (empty in the category edit form) if (empty($this->parent) && $this->fullname == '?') { $course = $DB->get_record('course', array('id'=> $this->courseid)); - return format_string($course->fullname, false, array("context" => context_course::instance($this->courseid))); + return format_string($course->fullname, false, ['context' => context_course::instance($this->courseid), + 'escape' => $escape]); } else { // Grade categories can't be set up at system context (unlike scales and outcomes) // We therefore must have a courseid, and don't need to handle system contexts when filtering. - return format_string($this->fullname, false, array("context" => context_course::instance($this->courseid))); + return format_string($this->fullname, false, ['context' => context_course::instance($this->courseid), + 'escape' => $escape]); } } diff --git a/lib/grade/grade_item.php b/lib/grade/grade_item.php index e0a7c39925bf2..cee2aa1b10481 100644 --- a/lib/grade/grade_item.php +++ b/lib/grade/grade_item.php @@ -1471,9 +1471,10 @@ public static function fix_duplicate_sortorder($courseid) { * Determines what type of grade item it is then returns the appropriate string * * @param bool $fulltotal If the item is a category total, returns $categoryname."total" instead of "Category total" or "Course total" + * @param bool $escape Whether the returned category name is to be HTML escaped or not. * @return string name */ - public function get_name($fulltotal=false) { + public function get_name($fulltotal=false, $escape = true) { global $CFG; require_once($CFG->dirroot . '/course/lib.php'); if (strval($this->itemname) !== '') { @@ -1483,7 +1484,7 @@ public function get_name($fulltotal=false) { $deletionpending = course_module_instance_pending_deletion($this->courseid, $this->itemmodule, $this->iteminstance); $deletionnotice = get_string('gradesmoduledeletionprefix', 'grades'); - $options = ['context' => context_course::instance($this->courseid)]; + $options = ['context' => context_course::instance($this->courseid), 'escape' => $escape]; return $deletionpending ? format_string($deletionnotice . ' ' . $this->itemname, true, $options) : format_string($this->itemname, true, $options); @@ -1495,7 +1496,7 @@ public function get_name($fulltotal=false) { if ($fulltotal) { $category = $this->load_parent_category(); $a = new stdClass(); - $a->category = $category->get_name(); + $a->category = $category->get_name($escape); return get_string('categorytotalfull', 'grades', $a); } else { return get_string('categorytotal', 'grades'); diff --git a/lib/grade/tests/fixtures/lib.php b/lib/grade/tests/fixtures/lib.php index 16050c828d21b..4fd35aa973622 100644 --- a/lib/grade/tests/fixtures/lib.php +++ b/lib/grade/tests/fixtures/lib.php @@ -181,7 +181,7 @@ private function load_grade_categories() { $grade_category = new stdClass(); - $grade_category->fullname = 'unittestcategory1'; + $grade_category->fullname = 'unittestcategory1 &'; $grade_category->courseid = $this->course->id; $grade_category->aggregation = GRADE_AGGREGATE_MEAN; $grade_category->aggregateonlygraded = 1; @@ -324,7 +324,7 @@ protected function load_grade_items() { $grade_item->courseid = $this->course->id; $grade_item->categoryid = $this->grade_categories[1]->id; - $grade_item->itemname = 'unittestgradeitem1'; + $grade_item->itemname = 'unittestgradeitem1 &'; $grade_item->itemtype = 'mod'; $grade_item->itemmodule = $this->course_module[0]->modname; $grade_item->iteminstance = $this->course_module[0]->instance; diff --git a/lib/grade/tests/grade_category_test.php b/lib/grade/tests/grade_category_test.php index 03a6fe1e52715..f995310251caa 100644 --- a/lib/grade/tests/grade_category_test.php +++ b/lib/grade/tests/grade_category_test.php @@ -48,7 +48,8 @@ public function test_grade_category() { $this->sub_test_grade_category_get_grade_item(); $this->sub_test_grade_category_load_parent_category(); $this->sub_test_grade_category_get_parent_category(); - $this->sub_test_grade_category_get_name(); + $this->sub_test_grade_category_get_name_escaped(); + $this->sub_test_grade_category_get_name_unescaped(); $this->sub_test_grade_category_generate_grades_aggregationweight(); $this->sub_test_grade_category_set_parent(); $this->sub_test_grade_category_get_final(); @@ -692,10 +693,24 @@ protected function sub_test_grade_category_get_parent_category() { $this->assertEquals($this->grade_categories[0]->id, $parent_category->id); } - protected function sub_test_grade_category_get_name() { + /** + * Tests the getter of the category fullname with escaped HTML. + */ + protected function sub_test_grade_category_get_name_escaped() { + $category = new grade_category($this->grade_categories[0]); + $this->assertTrue(method_exists($category, 'get_name')); + $this->assertEquals(format_string($this->grade_categories[0]->fullname, true, ['escape' => true]), + $category->get_name(true)); + } + + /** + * Tests the getter of the category fullname with unescaped HTML. + */ + protected function sub_test_grade_category_get_name_unescaped() { $category = new grade_category($this->grade_categories[0]); $this->assertTrue(method_exists($category, 'get_name')); - $this->assertEquals($this->grade_categories[0]->fullname, $category->get_name()); + $this->assertEquals(format_string($this->grade_categories[0]->fullname, true, ['escape' => false]), + $category->get_name(false)); } protected function sub_test_grade_category_set_parent() { diff --git a/lib/grade/tests/grade_item_test.php b/lib/grade/tests/grade_item_test.php index 28b7f9c525cac..a3988760efd51 100644 --- a/lib/grade/tests/grade_item_test.php +++ b/lib/grade/tests/grade_item_test.php @@ -42,7 +42,8 @@ public function test_grade_item() { $this->sub_test_grade_item_get_sortorder(); $this->sub_test_grade_item_set_sortorder(); $this->sub_test_grade_item_move_after_sortorder(); - $this->sub_test_grade_item_get_name(); + $this->sub_test_grade_item_get_name_escaped(); + $this->sub_test_grade_item_get_name_unescaped(); $this->sub_test_grade_item_set_parent(); $this->sub_test_grade_item_get_parent_category(); $this->sub_test_grade_item_load_parent_category(); @@ -271,12 +272,24 @@ protected function sub_test_grade_item_move_after_sortorder() { $this->assertEquals($after->sortorder, 8); } - protected function sub_test_grade_item_get_name() { - $grade_item = new grade_item($this->grade_items[0], false); - $this->assertTrue(method_exists($grade_item, 'get_name')); + /** + * Tests the getter of the item name with escaped HTML. + */ + protected function sub_test_grade_item_get_name_escaped() { + $gradeitem = new grade_item($this->grade_items[0], false); + $this->assertTrue(method_exists($gradeitem, 'get_name')); + $this->assertEquals(format_string($this->grade_items[0]->itemname, true, ['escape' => true]), + $gradeitem->get_name(false, true)); + } - $name = $grade_item->get_name(); - $this->assertEquals($this->grade_items[0]->itemname, $name); + /** + * Tests the getter of the item name with unescaped HTML. + */ + protected function sub_test_grade_item_get_name_unescaped() { + $gradeitem = new grade_item($this->grade_items[0], false); + $this->assertTrue(method_exists($gradeitem, 'get_name')); + $this->assertEquals(format_string($this->grade_items[0]->itemname, true, ['escape' => false]), + $gradeitem->get_name(false, false)); } protected function sub_test_grade_item_set_parent() { diff --git a/lib/upgrade.txt b/lib/upgrade.txt index b827f050ef392..636199a26c37c 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -63,6 +63,8 @@ information provided here is intended especially for developers. * New method \core_user::awaiting_action() has been introduced to check if the user is fully ready to use the site or whether there is an action (such as filling the missing profile field, changing password or agreeing to the site policy) needed. +* The signature of the get_name() function for grade_category and grade_item has been extended. The new parameter allows + callers to get the name without escaped characters. === 3.11.2 === * For security reasons, filelib has been updated so all requests now use emulated redirects.