Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
// This file is part of Moodle - http://moodle.org/
4
//
5
// Moodle is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
//
10
// Moodle is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17
 
18
require_once($CFG->dirroot.'/grade/export/lib.php');
19
require_once($CFG->libdir.'/filelib.php');
20
 
21
class grade_export_xml extends grade_export {
22
 
23
    public $plugin = 'xml';
24
    public $updatedgradesonly = false; // default to export ALL grades
25
 
26
    /**
27
     * Ensure we produce correctly formed XML content by encoding idnumbers appropriately
28
     *
29
     * @param string $idnumber
30
     * @return string
31
     */
32
    private static function xml_export_idnumber(string $idnumber): string {
33
        return htmlspecialchars($idnumber, ENT_QUOTES | ENT_XML1);
34
    }
35
 
36
    /**
37
     * Handle form processing for export. Note we need to handle the case where there are no 'itemids[]' being included in the
38
     * form, because each is disabled for selection due to having empty idnumber
39
     *
40
     * @param stdClass $formdata
41
     */
42
    public function process_form($formdata) {
43
        if (!isset($formdata->itemids)) {
44
            $formdata->itemids = self::EXPORT_SELECT_NONE;
45
        }
46
 
47
        parent::process_form($formdata);
48
    }
49
 
50
    /**
51
     * To be implemented by child classes
52
     * @param boolean $feedback
53
     * @param boolean $publish Whether to output directly, or send as a file
54
     * @return string
55
     */
56
    public function print_grades($feedback = false) {
57
        global $CFG;
58
        require_once($CFG->libdir.'/filelib.php');
59
 
60
        $export_tracking = $this->track_exports();
61
 
62
        $strgrades = get_string('grades');
63
 
64
        /// Calculate file name
65
        $shortname = format_string($this->course->shortname, true, array('context' => context_course::instance($this->course->id)));
66
        $downloadfilename = clean_filename("$shortname $strgrades.xml");
67
 
68
        make_temp_directory('gradeexport');
69
        $tempfilename = $CFG->tempdir .'/gradeexport/'. md5(sesskey().microtime().$downloadfilename);
70
        if (!$handle = fopen($tempfilename, 'w+b')) {
71
            throw new \moodle_exception('cannotcreatetempdir');
72
        }
73
 
74
        /// time stamp to ensure uniqueness of batch export
75
        fwrite($handle,  '<results batch="xml_export_'.time().'">'."\n");
76
 
77
        $export_buffer = array();
78
 
79
        $geub = new grade_export_update_buffer();
80
        $gui = new graded_users_iterator($this->course, $this->columns, $this->groupid);
81
        $gui->require_active_enrolment($this->onlyactive);
82
        $gui->init();
83
        while ($userdata = $gui->next_user()) {
84
            $user = $userdata->user;
85
 
86
            if (empty($user->idnumber)) {
87
                //id number must exist otherwise we cant match up students when importing
88
                continue;
89
            }
90
 
91
            // studentgrades[] index should match with corresponding $index
92
            foreach ($userdata->grades as $itemid => $grade) {
93
                $grade_item = $this->grade_items[$itemid];
94
                $grade->grade_item =& $grade_item;
95
 
96
                // MDL-11669, skip exported grades or bad grades (if setting says so)
97
                if ($export_tracking) {
98
                    $status = $geub->track($grade);
99
                    if ($this->updatedgradesonly && ($status == 'nochange' || $status == 'unknown')) {
100
                        continue;
101
                    }
102
                }
103
 
104
                fwrite($handle,  "\t<result>\n");
105
 
106
                if ($export_tracking) {
107
                    fwrite($handle,  "\t\t<state>$status</state>\n");
108
                }
109
 
110
                // only need id number
111
                $gradeitemidnumber = self::xml_export_idnumber($grade_item->idnumber);
112
                fwrite($handle, "\t\t<assignment>{$gradeitemidnumber}</assignment>\n");
113
                // this column should be customizable to use either student id, idnumber, uesrname or email.
114
                $useridnumber = self::xml_export_idnumber($user->idnumber);
115
                fwrite($handle, "\t\t<student>{$useridnumber}</student>\n");
116
                // Format and display the grade in the selected display type (real, letter, percentage).
117
                if (is_array($this->displaytype)) {
118
                    // Grades display type came from the return of export_bulk_export_data() on grade publishing.
119
                    foreach ($this->displaytype as $gradedisplayconst) {
120
                        $gradestr = $this->format_grade($grade, $gradedisplayconst);
121
                        fwrite($handle,  "\t\t<score>$gradestr</score>\n");
122
                    }
123
                } else {
124
                    // Grade display type submitted directly from the grade export form.
125
                    $gradestr = $this->format_grade($grade, $this->displaytype);
126
                    fwrite($handle,  "\t\t<score>$gradestr</score>\n");
127
                }
128
 
129
                if ($this->export_feedback) {
130
                    $feedbackstr = $this->format_feedback($userdata->feedbacks[$itemid], $grade);
131
                    fwrite($handle,  "\t\t<feedback>$feedbackstr</feedback>\n");
132
                }
133
                fwrite($handle,  "\t</result>\n");
134
            }
135
        }
136
        fwrite($handle,  "</results>");
137
        fclose($handle);
138
        $gui->close();
139
        $geub->close();
140
 
141
        if (defined('BEHAT_SITE_RUNNING')) {
142
            // If behat is running, we cannot test the output if we force a file download.
143
            include($tempfilename);
144
        } else {
145
            @header("Content-type: text/xml; charset=UTF-8");
146
            send_temp_file($tempfilename, $downloadfilename, false);
147
        }
148
    }
149
}
150
 
151