]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-9363, some fixes for grade import, not finished!
authortoyomoyo <toyomoyo>
Fri, 13 Jul 2007 08:06:30 +0000 (08:06 +0000)
committertoyomoyo <toyomoyo>
Fri, 13 Jul 2007 08:06:30 +0000 (08:06 +0000)
grade/import/csv/index.php
grade/import/grade_import_form.php
grade/import/lib.php

index 1ed05acc52efdbc5141b11a5953482614198fb43..146b9556ddbb434a65517439ac504046b721a1f2 100755 (executable)
@@ -1,10 +1,13 @@
 <?php
 require_once('../../../config.php');
+include_once($CFG->libdir.'/gradelib.php');
+
 
 $id = required_param('id', PARAM_INT); // course id
 $course = get_record('course', 'id', $id); // actual course
 
 // capability check
+require_login($id);
 require_capability('moodle/course:managegrades', get_context_instance(CONTEXT_COURSE, $course->id));
 
 require_once('../grade_import_form.php');
@@ -29,25 +32,34 @@ $action = 'importcsv';
 print_header($course->shortname.': '.get_string('grades'), $course->fullname, grade_nav($course, $action));
 
 $mform = new grade_import_form();
-
+//$mform2 = new grade_import_mapping_form();
 //if ($formdata = $mform2->get_data() ) {
 // i am not able to get the mapping[] and map[] array using the following line
 // they are somehow not returned with get_data()
-// if ($formdata = $mform2->get_data()) {
 if (($formdata = data_submitted()) && !empty($formdata->map)) {
+   
+    // temporary file name supplied by form
+    $filename = $CFG->dataroot.'/temp/'.clean_param($formdata->filename, PARAM_FILE);   
 
-    // if mapping informatioin is supplied
-
-    foreach ($formdata->maps as $i=>$header) {
-        // either "new" or existing ids, clean using alphanum
-        $map[clean_param($header, PARAM_RAW)] = clean_param($formdata->mapping[clean_param($i, PARAM_INT)], PARAM_ALPHANUM);
+    if ($fp = fopen($filename, "r")) {
+        // --- get header (field names) ---
+        $header = split($csv_delimiter, clean_param(fgets($fp,1024), PARAM_RAW));
+    
+        foreach ($header as $i => $h) {
+            $h = trim($h); $header[$i] = $h; // remove whitespace
+        }  
+    } else {
+        error ('could not open file '.$filename);  
+    }
+    
+    // loops mapping_0, mapping_1 .. mapping_n and construct $map array
+    foreach ($header as $i=>$head) {
+        $map[$i] = $formdata->{'mapping_'.$i};      
     }
 
+    // if mapping informatioin is supplied
     $map[clean_param($formdata->mapfrom, PARAM_RAW)] = clean_param($formdata->mapto, PARAM_RAW);
 
-    // temporary file name supplied by form
-    $filename = $CFG->dataroot.'/temp/'.clean_param($formdata->filename, PARAM_FILE);
-
     // Large files are likely to take their time and memory. Let PHP know
     // that we'll take longer, and that the process should be recycled soon
     // to free up memory.
@@ -59,15 +71,14 @@ if (($formdata = data_submitted()) && !empty($formdata->map)) {
     
     // we only operate if file is readable
     if ($fp = fopen($filename, "r")) {
-    
-        // use current time stamp
-        $importcode = time();
-    
-        // --- get header (field names) ---
+        
+        // read the first line makes sure this doesn't get read again
         $header = split($csv_delimiter, clean_param(fgets($fp,1024), PARAM_RAW));
     
-        foreach ($header as $i => $h) {
-            $h = trim($h); $header[$i] = $h; // remove whitespace
+        // use current (non-conflicting) time stamp        
+        $importcode = time();  
+        while (get_record('grade_import_values', 'import_code', $importcode)) {
+            $importcode = time();         
         }
         
         $newgradeitems = array(); // temporary array to keep track of what new headers are processed
@@ -79,14 +90,31 @@ if (($formdata = data_submitted()) && !empty($formdata->map)) {
         
             // array to hold all grades to be inserted
             $newgrades = array();
-            
+            // array to hold all feedback
+            $newfeedbacks = array();            
             // each line is a student record
             foreach ($line as $key => $value) {  
                 //decode encoded commas
                 $value = clean_param($value, PARAM_RAW);
                 $value = preg_replace($csv_encode,$csv_delimiter2,trim($value));
 
-                switch ($map[$header[$key]]) {
+                /*
+                 * the options are
+                 * 1) userid, useridnumber, usermail, username - used to identify user row
+                 * 2) new - new grade item
+                 * 3) id - id of the old grade item to map onto
+                 * 3) feedback_id - feedback for grade item id
+                 */
+
+                $t = explode("_", $map[$key]);
+                $t0 = $t[0];
+                if (isset($t[1])) {
+                    $t1 = $t[1];
+                } else {
+                    $t1 = '';  
+                }
+                
+                switch ($t0) {
                     case 'userid': //
                         if (!$user = get_record('user','id', $value)) {
                             // user not found, abort whold import
@@ -145,45 +173,54 @@ if (($formdata = data_submitted()) && !empty($formdata->map)) {
                         } 
                         unset($newgrade);
                         $newgrade -> newgradeitem = $newgradeitems[$key];
-                        $newgrade -> rawgrade = $value;                        
+                        $newgrade -> finalgrade = $value;                        
                         $newgrades[] = $newgrade;
                         
                         // if not, put it in                        
                         // else, insert grade into the table
                     break;
+                    case 'feeback':
+                        if ($t1) {
+                            // t1 is the id of the grade item
+                            $feedback -> itemid = $t1;
+                            $feedback -> feedback = $value;
+                            $newfeedback[] = $feedback;
+                        }
+                    break;                  
                     default:
                         // existing grade items
-                        if (!empty($map[$header[$key]])) {
+                        if (!empty($map[$key]) && $value!=="") {
                             
                             // non numeric grade value supplied, possibly mapped wrong column
-                            if (!is_numeric($value)) {
-                                $status = false;
+                            if (!is_numeric($value)) {                                
+                                $status = false;                                
                                 import_cleanup($importcode);
                                 notify(get_string('badgrade', 'grades'));
                                 break 3;
                             }
                             
-                            // case of an id, only maps idnumber of a grade_item                            
+                            // case of an id, only maps id of a grade_item     
+                            // this was idnumber
                             include_once($CFG->libdir.'/grade/grade_item.php');
-                            if (!$gradeitem = new grade_item(array('idnumber'=>$map[$header[$key]]))) {
+                            if (!$gradeitem = new grade_item(array('id'=>$map[$key]))) {
                                 // supplied bad mapping, should not be possible since user
                                 // had to pick mapping
                                 $status = false;
                                 import_cleanup($importcode);
                                 notify(get_string('importfailed', 'grades'));
                                 break 3;                             
-                            }                            
-                            
+                            }
+
                             unset($newgrade);
                             $newgrade -> itemid = $gradeitem->id;
-                            $newgrade -> rawgrade = $value;                            
+                            $newgrade -> finalgrade = $value;                            
                             $newgrades[] = $newgrade;
                         } // otherwise, we ignore this column altogether 
                           // because user has chosen to ignore them (e.g. institution, address etc)
                     break;  
                 }
             }
-            
+
             // no user mapping supplied at all, or user mapping failed
             if (empty($studentid) || !is_numeric($studentid)) {
                 // user not found, abort whold import
@@ -192,9 +229,10 @@ if (($formdata = data_submitted()) && !empty($formdata->map)) {
                 notify('user mapping error, could not find user!');
                 break; 
             }
-            
+
             // insert results of this students into buffer
             if (!empty($newgrades)) {
+              
                 foreach ($newgrades as $newgrade) {
                     $newgrade->import_code = $importcode;
                     $newgrade->userid = $studentid;
@@ -207,8 +245,24 @@ if (($formdata = data_submitted()) && !empty($formdata->map)) {
                     }
                 }
             }
+
+            // updating/inserting all comments here
+            if (!empty($newfeedbacks)) {
+                foreach ($newfeedbacks as $newfeedback) {
+                    if ($feedback = get_record('grade_import_values', 'importcode', $importcode, 'userid', $studentid, 'itemid', $newfeedback->itemid)) {
+                        $newfeedback ->id = $feedback ->id;
+                        update_record('grade_import_values', $newfeedback);
+                    } else {
+                        // the grade item for this is not updated
+                        $newfeedback->import_code = $importcode;
+                        $newfeedback->userid = $studentid;
+                        insert_record('grade_import_values', $newfeedback);  
+                    }
+                }
+            }
+            
         }
-    
+
         /// at this stage if things are all ok, we commit the changes from temp table 
         if ($status) {
             grade_import_commit($course->id, $importcode);
@@ -224,7 +278,6 @@ if (($formdata = data_submitted()) && !empty($formdata->map)) {
     
     $filename = $mform->get_userfile_name();
     
-    
     // Large files are likely to take their time and memory. Let PHP know
     // that we'll take longer, and that the process should be recycled soon
     // to free up memory.
@@ -266,20 +319,36 @@ if (($formdata = data_submitted()) && !empty($formdata->map)) {
         $lines = split($csv_delimiter, fgets($fp,1024));     
         echo '<tr>';
         foreach ($lines as $line) {
-            echo '<td>'.clean_param($line, PARAM_RAW).'</td>';;
+            echo '<td>'.$line.'</td>';;
         }
         $numlines ++;
         echo '</tr>';
     }
     echo '</table>';
-        
     
+    /// feeding gradeitems into the grade_import_mapping_form
+    include_once($CFG->libdir.'/grade/grade_item.php');
+    $gradeitems = array();
+    if ($id) {
+        if ($grade_items = grade_item::fetch_all(array('courseid'=>$id))) {
+            foreach ($grade_items as $grade_item) {
+                // skip course type and category type
+                if ($grade_item->itemtype == 'course' || $grade_item->itemtype == 'category') {
+                    continue;  
+                } 
+                
+                // this was idnumber
+                $gradeitems[$grade_item->id] = $grade_item->itemname;      
+            }
+        }
+    }
     // display the mapping form with header info processed
-    $mform2 = new grade_import_mapping_form(qualified_me(), array('id'=>$id, 'header'=>$header, 'filename'=>$filename));
+    $mform2 = new grade_import_mapping_form(qualified_me(), array('gradeitems'=>$gradeitems, 'header'=>$header, 'filename'=>$filename));
     $mform2->display();
 } else {
     // display the standard upload file form
     $mform->display();
 }
+
 print_footer();
 ?>
\ No newline at end of file
index 13314be619e537b05211a1f41a4723b915fdc1e8..4ab0777e91dc4eb206d54e510f719b299dc9bcf3 100755 (executable)
@@ -45,14 +45,13 @@ class grade_import_mapping_form extends moodleform {
         // temporary filename
         $filename = $this->_customdata['filename'];
         // course id
-        $id = $this->_customdata['id'];
 
         $mform->addElement('header', 'general', get_string('identifier', 'grades'));
         $mapfromoptions = array();
         
         if ($header) {
-            foreach ($header as $h) {
-                $mapfromoptions[$h] = $h;
+            foreach ($header as $i=>$h) {
+                $mapfromoptions[$i] = $h;
             }
         }
         $mform->addElement('select', 'mapfrom', get_string('mapfrom', 'grades'), $mapfromoptions);
@@ -64,34 +63,33 @@ class grade_import_mapping_form extends moodleform {
         
         $mform->addElement('header', 'general', get_string('mappings', 'grades'));
         
-        $gradeitems = array();
-    
+        $gradeitems = $this->_customdata['gradeitems'];
+
         include_once($CFG->libdir.'/gradelib.php');
-        
-        if ($id) {
-            if ($grade_items = grade_item::fetch_all(array('courseid'=>$id))) {
-                foreach ($grade_items as $grade_item) {
-                    $gradeitems[$grade_item->idnumber] = $grade_item->itemname;      
-                }
-            }
-        }    
 
-        if ($header) {
+        if ($header) {          
+            $i = 0; // index
             foreach ($header as $h) {
-            
                 $h = trim($h);
                 // this is the order of the headers
-                $mform->addElement('hidden', 'maps[]', $h);
-                //echo '<input type="hidden" name="maps[]" value="'.$h.'"/>';
-                // this is what they map to
-        
-                $mapfromoptions = array_merge(array('0'=>'ignore', 'new'=>'new gradeitem'), $gradeitems);
-                $mform->addElement('select', 'mapping[]', $h, $mapfromoptions);
-                //choose_from_menu($mapfromoptions, 'mapping[]', $h);
+                // $mform->addElement('hidden', 'maps[]', $h);
+                
+                // this is what they map to        
+                $mapfromoptions = array('0'=>'ignore', 'new'=>'new gradeitem') + $gradeitems;
 
+                $mform->addElement('select', 'mapping_'.$i, s($h), $mapfromoptions);
+                $i++;
             }
         }
+        
+        // find a non-conflicting file name based on time stamp
         $newfilename = 'cvstemp_'.time();
+        while (file_exists($CFG->dataroot.'/temp/'.$newfilename)) {
+            $newfilename = 'cvstemp_'.time();
+        }
+        
+        // move the uploaded file
         move_uploaded_file($filename, $CFG->dataroot.'/temp/'.$newfilename);
         
         // course id needs to be passed for auth purposes
index 50db97f2344b052554f134bd31808ecdcc12ea47..93ae6459cf01cff36c555137d4f8615b1910f158 100755 (executable)
@@ -12,7 +12,7 @@ function grade_import_commit($courseid, $importcode) {
     global $CFG;
     
     include_once($CFG->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
     
@@ -28,20 +28,10 @@ function grade_import_commit($courseid, $importcode) {
         foreach ($newitems as $newitem) {
             // get all grades with this item
             
-            if ($grades = get_records('grade_import_values', 'newgradeitem', $newitem->id)) {
-                
-                $studentgrades = array();
-                // make the grardes array for update_grade
-                foreach ($grades as $grade) {
-                    
-                    $g = new object();
-                    $g -> userid = $grade->userid;
-                    $g -> rawgrade = $grade->rawgrade;                    
-                    $studentgrades[] = $g ;  
-
-                }
-                $itemdetails -> itemname = $newitem->itemname; 
+            if ($grades = get_records('grade_import_values', 'newgradeitem', $newitem->id)) {                
 
+                // make the grardes 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,
@@ -60,18 +50,29 @@ function grade_import_commit($courseid, $importcode) {
                 
                 $instances[] = $instance;
                 // if fails, deletes all the created grade_items and grades
-                                
-                if (!grade_update('import', $courseid, 'manual', NULL, $instance, NULL, $studentgrades, $itemdetails) == GRADE_UPDATE_OK) {
-                    // undo existings ones
-                    include_once($CFG->libdir.'/grade/grade_item.php');
+
+                /// 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));                            
                         // 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);  
-                }          
+                    import_cleanup($importcode);
+                    return false;
+                }
             }
         } 
     }
@@ -80,36 +81,37 @@ function grade_import_commit($courseid, $importcode) {
 
     if ($gradeitems = get_records_sql("SELECT DISTINCT (itemid) 
                                        FROM {$CFG->prefix}grade_import_values
-                                       WHERE import_code = $importcode")) {
+                                       WHERE import_code = $importcode
+                                       AND itemid > 0")) {
+
         $modifieditems = array();
-        foreach ($gradeitems as $itemid) {
+        
+        foreach ($gradeitems as $itemid=>$iteminfo) {
             
-            if (!$gradeitem = get_record('grade_items', 'id', $itemid->itemid)) {
-                continue; // new items which are already processed  
+            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->itemid)) {
+            if ($grades = get_records('grade_import_values', 'itemid', $itemid)) {
                 
-                $studentgrades = array();
                 // make the grardes array for update_grade
                 foreach ($grades as $grade) {
-                    
-                    $g = new object();
-                    $g -> userid = $grade->userid;
-                    $g -> rawgrade = $grade->rawgrade;                    
-                    $studentgrades[] = $g ;  
-
+                    if (!$gradeitem->update_final_grade($grade->userid, $grade->finalgrade, NULL, NULL, $grade->feedback)) {
+                        $failed = 1;
+                        break 2; 
+                    }
                 }
-                //$itemdetails -> idnumber = $gradeitem->idnumber;
-                
-                $modifieditems[] = $itemid;                      
+                //$itemdetails -> idnumber = $gradeitem->idnumber;                
+                $modifieditems[] = $itemid;                                      
+
+            }                    
                 
-                if (!grade_update('import', $courseid, $gradeitem->itemtype, $gradeitem->itemmodule, $gradeitem->iteminstance, $gradeitem->itemnumber, $studentgrades) == GRADE_UPDATE_OK) {
-                    // here we could possibly roll back by using grade_history
-                    // to compare timestamps? 
-                    import_cleanup($importcode); 
-                }
-            }           
+            if (!empty($failed)) {
+                import_cleanup($importcode);
+                return false;        
+            }      
         }
     }