libdir.'/gradelib.php'); include_once($CFG->libdir.'/grade/grade_item.php'); $commitstart = time(); // start time in case we need to roll back $newitemids = array(); // array to hold new grade_item ids from grade_import_newitem table, mapping array /// first select distinct new grade_items with this batch if ($newitems = get_records_sql("SELECT * FROM {$CFG->prefix}grade_import_newitem WHERE import_code = $importcode")) { // instances of the new grade_items created, cached // in case grade_update fails, so that we can remove them $instances = array(); foreach ($newitems as $newitem) { // get all grades with this item if ($grades = get_records('grade_import_values', 'newgradeitem', $newitem->id)) { // make the grades array for update_grade // find the max instance number of 'manual' grade item // and increment that number by 1 by hand // I can not find other ways to make 'manual' type work, // unless we have a 'new' flag for grade_update to let it // know that this is a new grade_item, and let grade_item // handle the instance id in the case of a 'manual' import? if ($lastimport = get_record_sql("SELECT * FROM {$CFG->prefix}grade_items WHERE courseid = $courseid AND itemtype = 'manual' ORDER BY iteminstance DESC", true)) { $instance = $lastimport->iteminstance + 1; } else { $instance = 1; } $instances[] = $instance; // TODO clean up following comment? // if fails, deletes all the created grade_items and grades /// create a new grade item for this $gradeitem = new grade_item(array('courseid'=>$courseid, 'itemtype'=>'manual', 'iteminstance'=>$instance, 'itemname'=>$newitem->itemname)); $gradeitem->insert(); // insert each individual grade to this new grade item $failed = 0; foreach ($grades as $grade) { if (!$gradeitem->update_final_grade($grade->userid, $grade->finalgrade, NULL, NULL, $grade->feedback)) { $failed = 1; break; } } if ($failed) { foreach ($instances as $instance) { $gradeitem = new grade_item(array('courseid'=>$courseid, 'itemtype'=>'manual', 'iteminstance'=>$instance)); // TODO this method does not seem to delete all the raw grades and the item itself // which I think should be deleted in this case, can I use sql directly here? $gradeitem->delete(); } import_cleanup($importcode); return false; } } } } /// then find all existing items if ($gradeitems = get_records_sql("SELECT DISTINCT (itemid) FROM {$CFG->prefix}grade_import_values WHERE import_code = $importcode AND itemid > 0")) { $modifieditems = array(); foreach ($gradeitems as $itemid=>$iteminfo) { if (!$gradeitem = new grade_item(array('id'=>$itemid))) { // not supposed to happen, but just in case import_cleanup($importcode); return false; } // get all grades with this item if ($grades = get_records('grade_import_values', 'itemid', $itemid)) { // make the grades array for update_grade foreach ($grades as $grade) { if (!$gradeitem->update_final_grade($grade->userid, $grade->finalgrade, NULL, NULL, $grade->feedback)) { $failed = 1; break 2; } } //$itemdetails -> idnumber = $gradeitem->idnumber; $modifieditems[] = $itemid; } if (!empty($failed)) { import_cleanup($importcode); return false; } } } notify(get_string('importsuccess', 'grades')); print_continue($CFG->wwwroot.'/course/view.php?id='.$courseid); // clean up import_cleanup($importcode); } /** * removes entries from grade import buffer tables grade_import_value and grade_import_newitem * after a successful import, or during an import abort * @param string importcode - import batch identifier */ function import_cleanup($importcode) { // remove entries from buffer table delete_records('grade_import_values', 'import_code', $importcode); delete_records('grade_import_newitem', 'import_code', $importcode); } /// Returns the file as one big long string function my_file_get_contents($filename, $use_include_path = 0) { $data = ""; $file = @fopen($filename, "rb", $use_include_path); if ($file) { while (!feof($file)) { $data .= fread($file, 1024); } fclose($file); } return $data; } ?>