MDL-54061 mod_assign: Added encoding and separator to upload form.
[moodle.git] / mod / assign / feedback / offline / importgradeslib.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * This file contains the forms to create and edit an instance of this module
19  *
20  * @package assignfeedback_offline
21  * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
22  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.');
27 /**
28  * CSV Grade importer
29  *
30  * @package   assignfeedback_offline
31  * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
32  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33  */
34 class assignfeedback_offline_grade_importer {
36     /** @var string $importid - unique id for this import operation - must be passed between requests */
37     public $importid;
39     /** @var csv_import_reader $csvreader - the csv importer class */
40     private $csvreader;
42     /** @var assignment $assignment - the assignment class */
43     private $assignment;
45     /** @var int $gradeindex the column index containing the grades */
46     private $gradeindex = -1;
48     /** @var int $idindex the column index containing the unique id  */
49     private $idindex = -1;
51     /** @var int $modifiedindex the column index containing the last modified time */
52     private $modifiedindex = -1;
54     /** @var array $validusers only the enrolled users with the correct capability in this course */
55     private $validusers;
57     /** @var array $feedbackcolumnindexes A lookup of column indexes for feedback plugin text import columns */
58     private $feedbackcolumnindexes = array();
60     /** @var string $encoding Encoding to use when reading the csv file. Defaults to utf-8. */
61     private $encoding;
63     /** @var string $separator How each bit of information is separated in the file. Defaults to comma separated. */
64     private $separator;
66     /**
67      * Constructor
68      *
69      * @param string $importid A unique id for this import
70      * @param assign $assignment The current assignment
71      */
72     public function __construct($importid, assign $assignment, $encoding = 'utf-8', $separator = 'comma') {
73         $this->importid = $importid;
74         $this->assignment = $assignment;
75         $this->encoding = $encoding;
76         $this->separator = $separator;
77     }
79     /**
80      * Parse a csv file and save the content to a temp file
81      * Should be called before init()
82      *
83      * @param string $csvdata The csv data
84      * @return bool false is a failed import
85      */
86     public function parsecsv($csvdata) {
87         $this->csvreader = new csv_import_reader($this->importid, 'assignfeedback_offline');
88         $this->csvreader->load_csv_content($csvdata, $this->encoding, $this->separator);
89     }
91     /**
92      * Initialise the import reader and locate the column indexes.
93      *
94      * @return bool false is a failed import
95      */
96     public function init() {
97         if ($this->csvreader == null) {
98             $this->csvreader = new csv_import_reader($this->importid, 'assignfeedback_offline');
99         }
100         $this->csvreader->init();
102         $columns = $this->csvreader->get_columns();
104         $strgrade = get_string('grade');
105         $strid = get_string('recordid', 'assign');
106         $strmodified = get_string('lastmodifiedgrade', 'assign');
108         foreach ($this->assignment->get_feedback_plugins() as $plugin) {
109             if ($plugin->is_enabled() && $plugin->is_visible()) {
110                 foreach ($plugin->get_editor_fields() as $field => $description) {
111                     $this->feedbackcolumnindexes[$description] = array('plugin'=>$plugin,
112                                                                        'field'=>$field,
113                                                                        'description'=>$description);
114                 }
115             }
116         }
118         if ($columns) {
119             foreach ($columns as $index => $column) {
120                 if (isset($this->feedbackcolumnindexes[$column])) {
121                     $this->feedbackcolumnindexes[$column]['index'] = $index;
122                 }
123                 if ($column == $strgrade) {
124                     $this->gradeindex = $index;
125                 }
126                 if ($column == $strid) {
127                     $this->idindex = $index;
128                 }
129                 if ($column == $strmodified) {
130                     $this->modifiedindex = $index;
131                 }
132             }
133         }
135         if ($this->idindex < 0 || $this->gradeindex < 0 || $this->modifiedindex < 0) {
136             return false;
137         }
139         $groupmode = groups_get_activity_groupmode($this->assignment->get_course_module());
140         // All users.
141         $groupid = 0;
142         $groupname = '';
143         if ($groupmode) {
144             $groupid = groups_get_activity_group($this->assignment->get_course_module(), true);
145             $groupname = groups_get_group_name($groupid).'-';
146         }
147         $this->validusers = $this->assignment->list_participants($groupid, false);
148         return true;
149     }
151     /**
152      * Return the encoding for this csv import.
153      *
154      * @return string The encoding for this csv import.
155      */
156     public function get_encoding() {
157         return $this->encoding;
158     }
160     /**
161      * Return the separator for this csv import.
162      *
163      * @return string The separator for this csv import.
164      */
165     public function get_separator() {
166         return $this->separator;
167     }
169     /**
170      * Get the next row of data from the csv file (only the columns we care about)
171      *
172      * @return stdClass or false The stdClass is an object containing user, grade and lastmodified
173      */
174     public function next() {
175         global $DB;
176         $result = new stdClass();
178         while ($record = $this->csvreader->next()) {
179             $idstr = $record[$this->idindex];
180             // Strip the integer from the end of the participant string.
181             $id = substr($idstr, strlen(get_string('hiddenuser', 'assign')));
182             if ($userid = $this->assignment->get_user_id_for_uniqueid($id)) {
183                 if (array_key_exists($userid, $this->validusers)) {
184                     $result->grade = $record[$this->gradeindex];
185                     $result->modified = strtotime($record[$this->modifiedindex]);
186                     $result->user = $this->validusers[$userid];
187                     $result->feedback = array();
188                     foreach ($this->feedbackcolumnindexes as $description => $details) {
189                         if (!empty($details['index'])) {
190                             $details['value'] = $record[$details['index']];
191                             $result->feedback[] = $details;
192                         }
193                     }
195                     return $result;
196                 }
197             }
198         }
200         // If we got here the csvreader had no more rows.
201         return false;
202     }
204     /**
205      * Close the grade importer file and optionally delete any temp files
206      *
207      * @param bool $delete
208      */
209     public function close($delete) {
210         $this->csvreader->close();
211         if ($delete) {
212             $this->csvreader->cleanup();
213         }
214     }