Ejemplo n.º 1
0
function import_xml_grades($text, $course, &$error)
{
    global $USER;
    $importcode = get_new_importcode();
    $status = true;
    $content = xmlize($text);
    if (!empty($content['results']['#']['result'])) {
        $results = $content['results']['#']['result'];
        foreach ($results as $i => $result) {
            $gradeidnumber = $result['#']['assignment'][0]['#'];
            if (!($grade_items = grade_item::fetch_all(array('idnumber' => $gradeidnumber, 'courseid' => $course->id)))) {
                // gradeitem does not exist
                // no data in temp table so far, abort
                $status = false;
                $error = get_string('errincorrectgradeidnumber', 'gradeimport_xml', $gradeidnumber);
                break;
            } else {
                if (count($grade_items) != 1) {
                    $status = false;
                    $error = get_string('errduplicategradeidnumber', 'gradeimport_xml', $gradeidnumber);
                    break;
                } else {
                    $grade_item = reset($grade_items);
                }
            }
            // grade item locked, abort
            if ($grade_item->is_locked()) {
                $status = false;
                $error = get_string('gradeitemlocked', 'grades');
                break;
            }
            // check if user exist and convert idnumber to user id
            $useridnumber = $result['#']['student'][0]['#'];
            if (!($user = get_record('user', 'idnumber', addslashes($useridnumber)))) {
                // no user found, abort
                $status = false;
                $error = get_string('errincorrectuseridnumber', 'gradeimport_xml', $useridnumber);
                break;
            }
            // check if grade_grade is locked and if so, abort
            if ($grade_grade = new grade_grade(array('itemid' => $grade_item->id, 'userid' => $user->id))) {
                $grade_grade->grade_item =& $grade_item;
                if ($grade_grade->is_locked()) {
                    // individual grade locked, abort
                    $status = false;
                    $error = get_string('gradegradeslocked', 'grades');
                    break;
                }
            }
            $newgrade = new object();
            $newgrade->itemid = $grade_item->id;
            $newgrade->userid = $user->id;
            $newgrade->importcode = $importcode;
            $newgrade->importer = $USER->id;
            // check grade value exists and is a numeric grade
            if (isset($result['#']['score'][0]['#'])) {
                if (is_numeric($result['#']['score'][0]['#'])) {
                    $newgrade->finalgrade = $result['#']['score'][0]['#'];
                } else {
                    $status = false;
                    $error = get_string('badgrade', 'grades');
                    break;
                }
            } else {
                $newgrade->finalgrade = NULL;
            }
            // check grade feedback exists
            if (isset($result['#']['feedback'][0]['#'])) {
                $newgrade->feedback = $result['#']['feedback'][0]['#'];
            } else {
                $newgrade->feedback = NULL;
            }
            // insert this grade into a temp table
            if (!insert_record('grade_import_values', addslashes_recursive($newgrade))) {
                $status = false;
                // could not insert into temp table
                $error = get_string('importfailed', 'grades');
                break;
            }
        }
    } else {
        // no results section found in xml,
        // assuming bad format, abort import
        $status = false;
        $error = get_string('errbadxmlformat', 'gradeimport_xml');
    }
    if ($status) {
        return $importcode;
    } else {
        import_cleanup($importcode);
        return false;
    }
}
Ejemplo n.º 2
0
 /**
  * Tests for importing grades from an external source.
  */
 public function test_grade_import_commit()
 {
     global $USER, $DB, $CFG;
     $this->resetAfterTest();
     $importcode = get_new_importcode();
     $user1 = $this->getDataGenerator()->create_user();
     $user2 = $this->getDataGenerator()->create_user();
     $course = $this->getDataGenerator()->create_course();
     $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
     $itemname = $assign->name;
     $modulecontext = context_module::instance($assign->cmid);
     // The generator returns a dummy object, lets get the real assign object.
     $assign = new assign($modulecontext, false, false);
     $cm = $assign->get_course_module();
     // Enrol users in the course.
     $this->getDataGenerator()->enrol_user($user1->id, $course->id);
     $this->getDataGenerator()->enrol_user($user2->id, $course->id);
     // Enter a new grade into an existing grade item.
     $gradeitem = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'mod'));
     // Keep this value around for a test further down.
     $originalgrade = 55;
     $this->import_grades(array('importcode' => $importcode, 'itemid' => $gradeitem->id, 'userid' => $user1->id, 'finalgrade' => $originalgrade));
     $status = grade_import_commit($course->id, $importcode, false, false);
     $this->assertTrue($status);
     // Get imported grade_grade.
     $gradegrade = grade_grade::fetch(array('itemid' => $gradeitem->id, 'userid' => $user1->id));
     $this->assertEquals($originalgrade, $gradegrade->finalgrade);
     // Overriden field will be a timestamp and will evaluate out to true.
     $this->assertTrue($gradegrade->is_overridden());
     // Create a new grade item and import into that.
     $importcode = get_new_importcode();
     $record = new stdClass();
     $record->itemname = 'New grade item';
     $record->importcode = $importcode;
     $record->importer = $USER->id;
     $insertid = $DB->insert_record('grade_import_newitem', $record);
     $finalgrade = 75;
     $this->import_grades(array('importcode' => $importcode, 'userid' => $user1->id, 'finalgrade' => $finalgrade, 'newgradeitem' => $insertid));
     $status = grade_import_commit($course->id, $importcode, false, false);
     $this->assertTrue($status);
     // Check that we have a new grade_item.
     $gradeitem = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'manual'));
     $this->assertEquals($record->itemname, $gradeitem->itemname);
     // Grades were imported.
     $gradegrade = grade_grade::fetch(array('itemid' => $gradeitem->id, 'userid' => $user1->id));
     $this->assertEquals($finalgrade, $gradegrade->finalgrade);
     // As this is a new item the grade has not been overridden.
     $this->assertFalse($gradegrade->is_overridden());
     // Import feedback only.
     $importcode = get_new_importcode();
     $gradeitem = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'mod'));
     $originalfeedback = 'feedback can be useful';
     $this->import_grades(array('importcode' => $importcode, 'userid' => $user1->id, 'itemid' => $gradeitem->id, 'feedback' => $originalfeedback, 'importonlyfeedback' => true));
     $status = grade_import_commit($course->id, $importcode, true, false);
     $this->assertTrue($status);
     $gradegrade = grade_grade::fetch(array('itemid' => $gradeitem->id, 'userid' => $user1->id));
     // The final grade should be the same as the first record further up. We are only altering the feedback.
     $this->assertEquals($originalgrade, $gradegrade->finalgrade);
     $this->assertTrue($gradegrade->is_overridden());
     // Import grades only.
     $importcode = get_new_importcode();
     $gradeitem = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'mod'));
     $finalgrade = 60;
     $this->import_grades(array('importcode' => $importcode, 'userid' => $user1->id, 'itemid' => $gradeitem->id, 'finalgrade' => $finalgrade, 'feedback' => 'feedback can still be useful'));
     $status = grade_import_commit($course->id, $importcode, false, false);
     $this->assertTrue($status);
     $gradegrade = grade_grade::fetch(array('itemid' => $gradeitem->id, 'userid' => $user1->id));
     $this->assertEquals($finalgrade, $gradegrade->finalgrade);
     // The final feedback should not have changed.
     $this->assertEquals($originalfeedback, $gradegrade->feedback);
     $this->assertTrue($gradegrade->is_overridden());
     // Check that printing of import status is correct.
     $importcode = get_new_importcode();
     $gradeitem = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'mod'));
     $this->import_grades(array('importcode' => $importcode, 'userid' => $user1->id, 'itemid' => $gradeitem->id));
     $url = $CFG->wwwroot . '/grade/index.php';
     $expectedresponse = "++ Grade import success ++\n<div class=\"continuebutton\"><form method=\"get\" action=\"{$url}\"><div><input type=\"submit\" value=\"Continue\" /><input type=\"hidden\" name=\"id\" value=\"{$course->id}\" /></div></form></div>";
     ob_start();
     $status = grade_import_commit($course->id, $importcode);
     $output = ob_get_contents();
     ob_end_clean();
     $this->assertTrue($status);
     $this->assertEquals($expectedresponse, $output);
 }
Ejemplo n.º 3
0
    }
}
// Set up the import form.
$mform = new grade_import_form(null, array('includeseparator' => true, 'verbosescales' => true));
// If the csv file hasn't been imported yet then look for a form submission or
// show the initial submission form.
if (!$iid) {
    // If the import form has been submitted.
    if ($formdata = $mform->get_data()) {
        // 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.
        core_php_time_limit::raise();
        raise_memory_limit(MEMORY_EXTRA);
        // Use current (non-conflicting) time stamp.
        $importcode = get_new_importcode();
        $text = $mform->get_file_content('userfile');
        $iid = csv_import_reader::get_new_iid('grade');
        $csvimport = new csv_import_reader($iid, 'grade');
        $csvimport->load_csv_content($text, $formdata->encoding, $separator);
        // --- get header (field names) ---
        $header = $csvimport->get_columns();
        // Print a preview of the data.
        $numlines = 0;
        // 0 lines previewed so far.
        echo $OUTPUT->heading(get_string('importpreview', 'grades'));
        foreach ($header as $i => $h) {
            $h = trim($h);
            // Remove whitespace.
            $h = clean_param($h, PARAM_RAW);
            // Clean the header.
Ejemplo n.º 4
0
 public function execute()
 {
     global $CFG, $DB, $USER;
     require_once $CFG->dirroot . '/course/lib.php';
     require_once $CFG->libdir . '/gradelib.php';
     require_once $CFG->dirroot . '/grade/lib.php';
     require_once $CFG->dirroot . '/grade/import/lib.php';
     require_once $CFG->libdir . '/csvlib.class.php';
     $options = $this->expandedOptions;
     $USER = $this->user;
     $text = file_get_contents($this->arguments[0]);
     if (!$text) {
         cli_error("No data in file '{$this->arguments[0]}''");
     }
     if ($options['course-idnumber']) {
         $course = $DB->get_record('course', array('idnumber' => $this->arguments[1]), '*', MUST_EXIST);
     } else {
         $course = $DB->get_record('course', array('id' => $this->arguments[1]), '*', MUST_EXIST);
     }
     $iid = \csv_import_reader::get_new_iid('moosh-gradebook');
     $csvimport = new \csv_import_reader($iid, 'moosh-gradebook');
     $csvimport->load_csv_content($text, 'utf-8', 'comma');
     $header = $csvimport->get_columns();
     //use "Email address" or "ID number" for mapping users
     if ($options['map-users-by'] == 'idnumber') {
         $usermap = array_search('ID number', $header);
         if ($usermap === false) {
             cli_error("Didn't find column called 'ID number' for mapping users");
         }
     } elseif ($options['map-users-by'] == 'email') {
         $usermap = array_search('Email address', $header);
         if ($usermap === false) {
             cli_error("Didn't find column called 'Email address' for mapping users");
         }
     } else {
         cli_error(' Wrong map-users-by value');
     }
     $map = array();
     //Try to automatically map columns in CSV file onto activities with the same name
     $grade_items = \grade_item::fetch_all(array('courseid' => $course->id));
     foreach ($grade_items as $grade_item) {
         // Skip course type and category type.
         if ($grade_item->itemtype == 'course' || $grade_item->itemtype == 'category') {
             continue;
         }
         $displaystring = null;
         if (!empty($grade_item->itemmodule)) {
             $displaystring = get_string('modulename', $grade_item->itemmodule) . ': ' . $grade_item->get_name();
         } else {
             $displaystring = $grade_item->get_name();
         }
         //echo $displaystring . "\n";
         $pos = array_search($displaystring, $header);
         if ($pos !== false) {
             $map[$pos] = $grade_item->id;
             echo "CSV column '{$header[$pos]}' will be mapped to grade item '{$displaystring}'\n";
         } else {
             echo "No mapping for gradebook item '{$displaystring}'\n";
         }
     }
     //iterate over all CSV records
     $csvimport->init();
     $newgrades = array();
     while ($line = $csvimport->next()) {
         //first find user
         if ($options['map-users-by'] == 'idnumber') {
             if (!($user = $DB->get_record('user', array('idnumber' => $line[$usermap])))) {
                 cli_error("Couldn't find user with idnumber '{$line[$usermap]}'");
             }
         } elseif ($options['map-users-by'] == 'email') {
             if (!($user = $DB->get_record('user', array('email' => $line[$usermap])))) {
                 cli_error("Couldn't find user with email '{$line[$usermap]}'");
             }
         }
         echo "Processing user {$user->email} ({$user->id},{$user->idnumber})\n";
         foreach ($map as $k => $v) {
             $gradeitem = $grade_items[$v];
             $value = $line[$k];
             $newgrade = new \stdClass();
             $newgrade->itemid = $gradeitem->id;
             //handle scales
             if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
                 $scale = $gradeitem->load_scale();
                 $scales = explode(',', $scale->scale);
                 $scales = array_map('trim', $scales);
                 //hack - trim whitespace around scale options
                 array_unshift($scales, '-');
                 // scales start at key 1
                 $key = array_search($value, $scales);
                 if ($key === false) {
                     echo "\tThe correct scale value '{$value}' for item '{$gradeitem->get_name()}' could not be found.\n";
                 } else {
                     echo "\tMapped value '{$value}' to '{$key}' as scale is used for '{$gradeitem->get_name()}'\n";
                     $value = $key;
                 }
             } else {
                 if ($value === '' or $value == '-') {
                     $value = null;
                     // no grade
                 }
             }
             echo "\tGrade for '{$gradeitem->get_name()}', type {$gradeitem->gradetype} will be set to '{$value}'\n";
             $newgrade->finalgrade = $value;
             $newgrade->userid = $user->id;
             $newgrade->importer = $USER->id;
             $newgrades[] = $newgrade;
         }
     }
     if ($options['test']) {
         echo "Test mode - exiting without performing import.\n";
     }
     //we will use safer method of importing useing temporary table
     $importcode = get_new_importcode();
     foreach ($newgrades as $newgrade) {
         $newgrade->importcode = $importcode;
         $DB->insert_record('grade_import_values', $newgrade);
     }
     grade_import_commit($course->id, $importcode);
 }