Merge branch 'MDL-71016' of git://github.com/paulholden/moodle
authorSara Arjona <sara@moodle.com>
Thu, 29 Apr 2021 07:21:39 +0000 (09:21 +0200)
committerSara Arjona <sara@moodle.com>
Thu, 29 Apr 2021 07:21:39 +0000 (09:21 +0200)
grade/export/xml/grade_export_xml.php
grade/export/xml/tests/behat/export.feature

index 659fa6b..c078919 100644 (file)
@@ -23,6 +23,16 @@ class grade_export_xml extends grade_export {
     public $plugin = 'xml';
     public $updatedgradesonly = false; // default to export ALL grades
 
+    /**
+     * Ensure we produce correctly formed XML content by encoding idnumbers appropriately
+     *
+     * @param string $idnumber
+     * @return string
+     */
+    private static function xml_export_idnumber(string $idnumber): string {
+        return htmlspecialchars($idnumber, ENT_QUOTES | ENT_XML1);
+    }
+
     /**
      * To be implemented by child classes
      * @param boolean $feedback
@@ -84,9 +94,11 @@ class grade_export_xml extends grade_export {
                 }
 
                 // only need id number
-                fwrite($handle,  "\t\t<assignment>{$grade_item->idnumber}</assignment>\n");
+                $gradeitemidnumber = self::xml_export_idnumber($grade_item->idnumber);
+                fwrite($handle, "\t\t<assignment>{$gradeitemidnumber}</assignment>\n");
                 // this column should be customizable to use either student id, idnumber, uesrname or email.
-                fwrite($handle,  "\t\t<student>{$user->idnumber}</student>\n");
+                $useridnumber = self::xml_export_idnumber($user->idnumber);
+                fwrite($handle, "\t\t<student>{$useridnumber}</student>\n");
                 // Format and display the grade in the selected display type (real, letter, percentage).
                 if (is_array($this->displaytype)) {
                     // Grades display type came from the return of export_bulk_export_data() on grade publishing.
index 38f6d78..c9515c8 100644 (file)
@@ -12,10 +12,12 @@ Feature: I need to export grades as xml
       | username | firstname | lastname | email | idnumber |
       | teacher1 | Teacher | 1 | teacher1@example.com | t1 |
       | student1 | Student | 1 | student1@example.com | s1 |
+      | student2 | Student | 2 | student2@example.com | 'Bill'&"Ben"<tag>Hello</tag> |
     And the following "course enrolments" exist:
       | user | course | role |
       | teacher1 | C1 | editingteacher |
       | student1 | C1 | student |
+      | student2 | C1 | student |
     And the following "activities" exist:
       | activity | course | idnumber | name | intro |
       | assign | C1 | a1 | Test assignment name | Submit something! |
@@ -24,15 +26,21 @@ Feature: I need to export grades as xml
     And I navigate to "View > Grader report" in the course gradebook
     And I turn editing mode on
     And I give the grade "80.00" to the user "Student 1" for the grade item "Test assignment name"
+    And I give the grade "42.00" to the user "Student 2" for the grade item "Test assignment name"
     And I press "Save changes"
 
   @javascript
-  Scenario: Export grades as text
+  Scenario: Export grades as XML
     When I navigate to "Export > XML file" in the course gradebook
     And I expand all fieldsets
     And I set the field "Grade export decimal places" to "1"
     And I press "Download"
-    Then I should see "s1"
-    And I should see "a1"
-    And I should see "80.0"
-    And I should not see "80.00"
+    Then I should see "s1" in the "//results//result[1]//student" "xpath_element"
+    And I should see "a1" in the "//results//result[1]//assignment" "xpath_element"
+    And I should see "80.0" in the "//results//result[1]//score" "xpath_element"
+    And I should not see "80.00" in the "//results//result[1]//score" "xpath_element"
+    # Ensure we have the encoded ID number of student 2.
+    And I should see "'Bill'&\"Ben\"<tag>Hello</tag>" in the "//results//result[2]//student" "xpath_element"
+    And I should see "a1" in the "//results//result[2]//assignment" "xpath_element"
+    And I should see "42.0" in the "//results//result[2]//score" "xpath_element"
+    And I should not see "42.00" in the "//results//result[2]//score" "xpath_element"