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);
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
. '/';
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
58 error ('could not open file '.$filename);
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
72 foreach ($map as $i=>$j) {
74 // you can have multiple ignores
77 if (!isset($maperrors[$j])) {
78 $maperrors[$j] = true;
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
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
111 while (!feof ($fp)) {
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));
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]);
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\"");
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\"");
160 $studentid = $user->id
;
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\"");
169 $studentid = $user->id
;
172 if (!$user = get_record('user', 'username', $value)) {
173 import_cleanup($importcode);
174 notify("user mapping error, could not find user with username \"$value\"");
178 $studentid = $user->id
;
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)) {
191 import_cleanup($importcode);
192 notify(get_string('importfailed', 'grades'));
195 // add this to grade_import_newitem table
196 // add the new id to $newgradeitem[$key]
199 $newgrade -> newgradeitem
= $newgradeitems[$key];
200 $newgrade -> finalgrade
= $value;
201 $newgrades[] = $newgrade;
204 // else, insert grade into the table
208 // t1 is the id of the grade item
209 $feedback -> itemid
= $t1;
210 $feedback -> feedback
= $value;
211 $newfeedbacks[] = $feedback;
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";
223 import_cleanup($importcode);
224 notify(get_string('badgrade', 'grades'));
228 // case of an id, only maps id of a grade_item
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
235 import_cleanup($importcode);
236 notify(get_string('importfailed', 'grades'));
240 // check if grade item is locked if so, abort
241 if ($gradeitem->locked
) {
243 import_cleanup($importcode);
244 notify(get_string('gradeitemlocked', 'grades'));
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)
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
262 import_cleanup($importcode);
263 notify('user mapping error, could not find user!');
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
277 import_cleanup($importcode);
278 notify(get_string('gradegradeslocked', 'grades'));
283 $newgrade->import_code
= $importcode;
284 $newgrade->userid
= $studentid;
285 if (!insert_record('grade_import_values', $newgrade)) {
286 // could not insert into temporary table
288 import_cleanup($importcode);
289 notify(get_string('importfailed', 'grades'));
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);
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
313 grade_import_commit($course->id
, $importcode);
315 // temporary file can go now
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.
330 @raise_memory_limit
("192M");
331 if (function_exists('apache_child_terminate')) {
332 @apache_child_terminate
();
335 $text = my_file_get_contents($filename);
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");
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'));
358 foreach ($header as $h) {
359 $h = clean_param($h, PARAM_RAW
);
360 echo '<th>'.$h.'</th>';
363 while (!feof ($fp) && $numlines <= $formdata->previewrows
) {
364 $lines = split($csv_delimiter, fgets($fp,1024));
366 foreach ($lines as $line) {
367 echo '<td>'.$line.'</td>';;
374 /// feeding gradeitems into the grade_import_mapping_form
375 include_once($CFG->libdir
.'/grade/grade_item.php');
376 $gradeitems = array();
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') {
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));
394 // display the standard upload file form