Automatic installer.php lang files by installer_builder (20070726)
[moodle-linuxchix.git] / grade / import / csv / index.php
blob21b15c38975c64151e523b62fe9c54801b3dadd6
1 <?php //$Id$
2 require_once '../../../config.php';
3 require_once $CFG->dirroot.'/grade/lib.php';
4 require_once '../grade_import_form.php';
5 require_once '../lib.php';
7 $id = required_param('id', PARAM_INT); // course id
9 if (!$course = get_record('course', 'id', $id)) {
10 print_error('nocourseid');
13 require_login($course);
14 $context = get_context_instance(CONTEXT_COURSE, $id);
15 require_capability('moodle/grade:import', $context);
16 require_capability('gradeimport/csv:view', $context);
19 // sort out delimiter
20 $csv_encode = '/\&\#44/';
21 if (isset($CFG->CSV_DELIMITER)) {
22 $csv_delimiter = '\\' . $CFG->CSV_DELIMITER;
23 $csv_delimiter2 = $CFG->CSV_DELIMITER;
25 if (isset($CFG->CSV_ENCODE)) {
26 $csv_encode = '/\&\#' . $CFG->CSV_ENCODE . '/';
28 } else {
29 $csv_delimiter = "\,";
30 $csv_delimiter2 = ",";
33 $strgrades = get_string('grades', 'grades');
34 $actionstr = get_string('importcsv', 'grades');
35 $gradenav = "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a>";
36 $gradenav .= " -> <a href=\"$CFG->wwwroot/grade/index.php?id=$course->id\">$strgrades</a>";
37 $gradenav .= " -> $actionstr";
38 print_header($course->shortname.': '.get_string('grades'), $course->fullname, $gradenav);
40 $mform = new grade_import_form();
41 //$mform2 = new grade_import_mapping_form();
42 //if ($formdata = $mform2->get_data() ) {
43 // i am not able to get the mapping[] and map[] array using the following line
44 // they are somehow not returned with get_data()
45 if (($formdata = data_submitted()) && !empty($formdata->map)) {
47 // temporary file name supplied by form
48 $filename = $CFG->dataroot.'/temp/'.clean_param($formdata->filename, PARAM_FILE);
50 if ($fp = fopen($filename, "r")) {
51 // --- get header (field names) ---
52 $header = split($csv_delimiter, clean_param(fgets($fp,1024), PARAM_RAW));
54 foreach ($header as $i => $h) {
55 $h = trim($h); $header[$i] = $h; // remove whitespace
57 } else {
58 error ('could not open file '.$filename);
61 $map = array();
62 // loops mapping_0, mapping_1 .. mapping_n and construct $map array
63 foreach ($header as $i => $head) {
64 $map[$i] = $formdata->{'mapping_'.$i};
67 // if mapping informatioin is supplied
68 $map[clean_param($formdata->mapfrom, PARAM_RAW)] = clean_param($formdata->mapto, PARAM_RAW);
70 // check for mapto collisions
71 $maperrors = array();
72 foreach ($map as $i=>$j) {
73 if ($j == 0) {
74 // you can have multiple ignores
75 continue;
76 } else {
77 if (!isset($maperrors[$j])) {
78 $maperrors[$j] = true;
79 } else {
80 // collision
81 unlink($filename); // needs to be uploaded again, sorry
82 error('mapping collision detected, 2 fields maps to the same grdae item '.$j);
87 // Large files are likely to take their time and memory. Let PHP know
88 // that we'll take longer, and that the process should be recycled soon
89 // to free up memory.
90 @set_time_limit(0);
91 @raise_memory_limit("192M");
92 if (function_exists('apache_child_terminate')) {
93 @apache_child_terminate();
96 // we only operate if file is readable
97 if ($fp = fopen($filename, "r")) {
99 // read the first line makes sure this doesn't get read again
100 $header = split($csv_delimiter, clean_param(fgets($fp,1024), PARAM_RAW));
102 // use current (non-conflicting) time stamp
103 $importcode = time();
104 while (get_record('grade_import_values', 'import_code', $importcode)) {
105 $importcode = time();
108 $newgradeitems = array(); // temporary array to keep track of what new headers are processed
109 $status = true;
111 while (!feof ($fp)) {
112 // add something
113 $line = split($csv_delimiter, fgets($fp,1024));
115 // array to hold all grades to be inserted
116 $newgrades = array();
117 // array to hold all feedback
118 $newfeedbacks = array();
119 // each line is a student record
120 foreach ($line as $key => $value) {
121 //decode encoded commas
122 $value = clean_param($value, PARAM_RAW);
123 $value = preg_replace($csv_encode,$csv_delimiter2,trim($value));
126 * the options are
127 * 1) userid, useridnumber, usermail, username - used to identify user row
128 * 2) new - new grade item
129 * 3) id - id of the old grade item to map onto
130 * 3) feedback_id - feedback for grade item id
133 $t = explode("_", $map[$key]);
134 $t0 = $t[0];
135 if (isset($t[1])) {
136 $t1 = $t[1];
137 } else {
138 $t1 = '';
141 switch ($t0) {
142 case 'userid': //
143 if (!$user = get_record('user','id', $value)) {
144 // user not found, abort whold import
145 import_cleanup($importcode);
146 notify("user mapping error, could not find user with id \"$value\"");
147 $status = false;
148 break 3;
150 $studentid = $value;
151 break;
152 case 'useridnumber':
153 if (!$user = get_record('user', 'idnumber', $value)) {
154 // user not found, abort whold import
155 import_cleanup($importcode);
156 notify("user mapping error, could not find user with idnumber \"$value\"");
157 $status = false;
158 break 3;
160 $studentid = $user->id;
161 break;
162 case 'useremail':
163 if (!$user = get_record('user', 'email', $value)) {
164 import_cleanup($importcode);
165 notify("user mapping error, could not find user with email address \"$value\"");
166 $status = false;
167 break 3;
169 $studentid = $user->id;
170 break;
171 case 'username':
172 if (!$user = get_record('user', 'username', $value)) {
173 import_cleanup($importcode);
174 notify("user mapping error, could not find user with username \"$value\"");
175 $status = false;
176 break 3;
178 $studentid = $user->id;
179 break;
180 case 'new':
181 // first check if header is already in temp database
183 if (empty($newgradeitems[$key])) {
185 $newgradeitem->itemname = $header[$key];
186 $newgradeitem->import_code = $importcode;
188 // failed to insert into new grade item buffer
189 if (!$newgradeitems[$key] = insert_record('grade_import_newitem', $newgradeitem)) {
190 $status = false;
191 import_cleanup($importcode);
192 notify(get_string('importfailed', 'grades'));
193 break 3;
195 // add this to grade_import_newitem table
196 // add the new id to $newgradeitem[$key]
198 unset($newgrade);
199 $newgrade -> newgradeitem = $newgradeitems[$key];
200 $newgrade -> finalgrade = $value;
201 $newgrades[] = $newgrade;
203 // if not, put it in
204 // else, insert grade into the table
205 break;
206 case 'feedback':
207 if ($t1) {
208 // t1 is the id of the grade item
209 $feedback -> itemid = $t1;
210 $feedback -> feedback = $value;
211 $newfeedbacks[] = $feedback;
213 break;
214 default:
215 // existing grade items
216 if (!empty($map[$key]) && $value!=="") {
218 // non numeric grade value supplied, possibly mapped wrong column
219 if (!is_numeric($value)) {
220 echo "<br/>t0 is $t0";
221 echo "<br/>grade is $value";
222 $status = false;
223 import_cleanup($importcode);
224 notify(get_string('badgrade', 'grades'));
225 break 3;
228 // case of an id, only maps id of a grade_item
229 // this was idnumber
230 include_once($CFG->libdir.'/grade/grade_item.php');
231 if (!$gradeitem = new grade_item(array('id'=>$map[$key]))) {
232 // supplied bad mapping, should not be possible since user
233 // had to pick mapping
234 $status = false;
235 import_cleanup($importcode);
236 notify(get_string('importfailed', 'grades'));
237 break 3;
240 // check if grade item is locked if so, abort
241 if ($gradeitem->locked) {
242 $status = false;
243 import_cleanup($importcode);
244 notify(get_string('gradeitemlocked', 'grades'));
245 break 3;
248 unset($newgrade);
249 $newgrade -> itemid = $gradeitem->id;
250 $newgrade -> finalgrade = $value;
251 $newgrades[] = $newgrade;
252 } // otherwise, we ignore this column altogether
253 // because user has chosen to ignore them (e.g. institution, address etc)
254 break;
258 // no user mapping supplied at all, or user mapping failed
259 if (empty($studentid) || !is_numeric($studentid)) {
260 // user not found, abort whold import
261 $status = false;
262 import_cleanup($importcode);
263 notify('user mapping error, could not find user!');
264 break;
267 // insert results of this students into buffer
268 if (!empty($newgrades)) {
270 foreach ($newgrades as $newgrade) {
272 // check if grade_grade is locked and if so, abort
273 if ($grade_grade = new grade_grade(array('itemid'=>$newgrade->itemid, 'userid'=>$studentid))) {
274 if ($grade_grade->locked) {
275 // individual grade locked
276 $status = false;
277 import_cleanup($importcode);
278 notify(get_string('gradegradeslocked', 'grades'));
279 break 2;
283 $newgrade->import_code = $importcode;
284 $newgrade->userid = $studentid;
285 if (!insert_record('grade_import_values', $newgrade)) {
286 // could not insert into temporary table
287 $status = false;
288 import_cleanup($importcode);
289 notify(get_string('importfailed', 'grades'));
290 break 2;
295 // updating/inserting all comments here
296 if (!empty($newfeedbacks)) {
297 foreach ($newfeedbacks as $newfeedback) {
298 if ($feedback = get_record('grade_import_values', 'import_code', $importcode, 'userid', $studentid, 'itemid', $newfeedback->itemid)) {
299 $newfeedback ->id = $feedback ->id;
300 update_record('grade_import_values', $newfeedback);
301 } else {
302 // the grade item for this is not updated
303 $newfeedback->import_code = $importcode;
304 $newfeedback->userid = $studentid;
305 insert_record('grade_import_values', $newfeedback);
311 /// at this stage if things are all ok, we commit the changes from temp table
312 if ($status) {
313 grade_import_commit($course->id, $importcode);
315 // temporary file can go now
316 unlink($filename);
317 } else {
318 error ('import file '.$filename.' not readable');
321 } else if ($formdata = $mform->get_data()) {
322 // else if file is just uploaded
324 $filename = $mform->get_userfile_name();
326 // Large files are likely to take their time and memory. Let PHP know
327 // that we'll take longer, and that the process should be recycled soon
328 // to free up memory.
329 @set_time_limit(0);
330 @raise_memory_limit("192M");
331 if (function_exists('apache_child_terminate')) {
332 @apache_child_terminate();
335 $text = my_file_get_contents($filename);
336 // trim utf-8 bom
337 $textlib = new textlib();
338 /// normalize line endings and do the encoding conversion
339 $text = $textlib->convert($text, $formdata->encoding);
340 $text = $textlib->trim_utf8_bom($text);
341 // Fix mac/dos newlines
342 $text = preg_replace('!\r\n?!',"\n",$text);
343 $fp = fopen($filename, "w");
344 fwrite($fp,$text);
345 fclose($fp);
347 $fp = fopen($filename, "r");
349 // --- get header (field names) ---
350 $header = split($csv_delimiter, clean_param(fgets($fp,1024), PARAM_RAW));
352 // print some preview
353 $numlines = 0; // 0 preview lines displayed
355 print_heading(get_string('importpreview', 'grades'));
356 echo '<table>';
357 echo '<tr>';
358 foreach ($header as $h) {
359 $h = clean_param($h, PARAM_RAW);
360 echo '<th>'.$h.'</th>';
362 echo '</tr>';
363 while (!feof ($fp) && $numlines <= $formdata->previewrows) {
364 $lines = split($csv_delimiter, fgets($fp,1024));
365 echo '<tr>';
366 foreach ($lines as $line) {
367 echo '<td>'.$line.'</td>';;
369 $numlines ++;
370 echo '</tr>';
372 echo '</table>';
374 /// feeding gradeitems into the grade_import_mapping_form
375 include_once($CFG->libdir.'/grade/grade_item.php');
376 $gradeitems = array();
377 if ($id) {
378 if ($grade_items = grade_item::fetch_all(array('courseid'=>$id))) {
379 foreach ($grade_items as $grade_item) {
380 // skip course type and category type
381 if ($grade_item->itemtype == 'course' || $grade_item->itemtype == 'category') {
382 continue;
385 // this was idnumber
386 $gradeitems[$grade_item->id] = $grade_item->itemname;
390 // display the mapping form with header info processed
391 $mform2 = new grade_import_mapping_form(qualified_me(), array('gradeitems'=>$gradeitems, 'header'=>$header, 'filename'=>$filename));
392 $mform2->display();
393 } else {
394 // display the standard upload file form
395 $mform->display();
398 print_footer();