MDL-46599 gradebook: Added a time exported column to grade export via csv.

This will be useful for checking if a csv import is trying to overwrite
new grade updates.
This commit is contained in:
Adrian Greeve 2014-10-08 11:25:09 +08:00 committed by Simey Lameze
parent a5240a82a6
commit b9cafe3b40
10 changed files with 157 additions and 53 deletions

View File

@ -76,6 +76,8 @@ class grade_export_txt extends grade_export {
$exporttitle[] = $this->format_column_name($grade_item, true);
}
}
// Last downloaded column header.
$exporttitle[] = get_string('timeexported', 'gradeexport_txt');
$csvexport->add_data($exporttitle);
// Print all the lines of data.
@ -110,6 +112,8 @@ class grade_export_txt extends grade_export {
$exportdata[] = $this->format_feedback($userdata->feedbacks[$itemid]);
}
}
// Time exported.
$exportdata[] = time();
$csvexport->add_data($exportdata);
}
$gui->close();

View File

@ -24,5 +24,6 @@
*/
$string['pluginname'] = 'Plain text file';
$string['timeexported'] = 'Last downloaded from this course';
$string['txt:publish'] = 'Publish TXT grade export';
$string['txt:view'] = 'Use text grade export';

View File

@ -531,15 +531,25 @@ class gradeimport_csv_load_data {
$this->cleanup_import(get_string('gradelocked', 'grades'));
return $this->status;
}
}
// Check if the force import option is disabled and the last exported date column is present.
if (!$forceimport && !empty($timeexportkey)) {
$exportedtime = $line[$timeexportkey];
if (clean_param($exportedtime, PARAM_INT) != $exportedtime || $exportedtime > time() ||
$exportedtime < strtotime("-1 year", time())) {
// The date is invalid, or in the future, or more than a year old.
$this->cleanup_import(get_string('invalidgradeexporteddate', 'grades'));
return $this->status;
// The grade was modified since the export.
if ($forceimport === 0 && !empty($timeexportkey) && ($line[$timeexportkey] < $gradegrade->get_dategraded())) {
$user = core_user::get_user($this->studentid);
$this->cleanup_import(get_string('gradealreadyupdated', 'grades', fullname($user)));
break;
}
$timemodified = $gradegrade->get_dategraded();
if (!empty($timemodified) && ($exportedtime < $timemodified)) {
// The item was graded after we exported it, we return here not to override it.
$user = core_user::get_user($this->studentid);
$this->cleanup_import(get_string('gradealreadyupdated', 'grades', fullname($user)));
return $this->status;
}
}
}
$insertid = self::insert_grade_record($newgrade, $this->studentid);
// Check to see if the insert was successful.
if (empty($insertid)) {

View File

@ -27,7 +27,7 @@ $separator = optional_param('separator', '', PARAM_ALPHA);
$verbosescales = optional_param('verbosescales', 1, PARAM_BOOL);
$iid = optional_param('iid', null, PARAM_INT);
$importcode = optional_param('importcode', '', PARAM_FILE);
$forceimport = optional_param('forceimport', 0, PARAM_BOOL);
$forceimport = optional_param('forceimport', false, PARAM_BOOL);
$url = new moodle_url('/grade/import/csv/index.php', array('id'=>$id));
if ($separator !== '') {
@ -68,7 +68,6 @@ if (!$iid) {
// If the import form has been submitted.
if ($formdata = $mform->get_data()) {
$text = $mform->get_file_content('userfile');
$csvimport = new gradeimport_csv_load_data();
$csvimport->load_csv_content($text, $formdata->encoding, $separator, $formdata->previewrows);

View File

@ -41,15 +41,20 @@ require_once($CFG->libdir . '/grade/tests/fixtures/lib.php');
class gradeimport_csv_load_data_testcase extends grade_base_testcase {
/** @var string $oktext Text to be imported. This data should have no issues being imported. */
protected $oktext = '"First name",Surname,"ID number",Institution,Department,"Email address","Assignment: Assignment for grape group", "Feedback: Assignment for grape group","Course total","Last downloaded from this course"
Anne,Able,1,"Moodle HQ","Rock on!",student7@mail.com,56.00,"We welcome feedback",56.00,1412327067
Bobby,Bunce,2,"Moodle HQ","Rock on!",student5@mail.com,75.00,,75.00,1412327067';
protected $oktext = '"First name",Surname,"ID number",Institution,Department,"Email address","Assignment: Assignment for grape group", "Feedback: Assignment for grape group","Course total"
Anne,Able,,"Moodle HQ","Rock on!",student7@mail.com,56.00,"We welcome feedback",56.00
Bobby,Bunce,,"Moodle HQ","Rock on!",student5@mail.com,75.00,,75.00';
/** @var string $badtext Text to be imported. This data has an extra column and should not succeed in being imported. */
protected $badtext = '"First name",Surname,"ID number",Institution,Department,"Email address","Assignment: Assignment for grape group","Course total"
Anne,Able,,"Moodle HQ","Rock on!",student7@mail.com,56.00,56.00,78.00
Bobby,Bunce,,"Moodle HQ","Rock on!",student5@mail.com,75.00,75.00';
/** @var string $csvtext CSV data to be imported with Last download from this course column. */
protected $csvtext = '"First name",Surname,"ID number",Institution,Department,"Email address","Assignment: Assignment for grape group", "Feedback: Assignment for grape group","Course total","Last downloaded from this course"
Anne,Able,,"Moodle HQ","Rock on!",student7@mail.com,56.00,"We welcome feedback",56.00,{exportdate}
Bobby,Bunce,,"Moodle HQ","Rock on!",student5@mail.com,75.00,,75.00,{exportdate}';
/** @var int $iid Import ID. */
protected $iid;
@ -94,26 +99,24 @@ Bobby,Bunce,,"Moodle HQ","Rock on!",student5@mail.com,75.00,75.00';
$expecteddata = array(array(
'Anne',
'Able',
'1',
'',
'Moodle HQ',
'Rock on!',
'student7@mail.com',
56.00,
'We welcome feedback',
56.00,
1412327067
56.00
),
array(
'Bobby',
'Bunce',
'2',
'',
'Moodle HQ',
'Rock on!',
'student5@mail.com',
75.00,
'',
75.00,
1412327067
75.00
)
);
@ -126,10 +129,8 @@ Bobby,Bunce,,"Moodle HQ","Rock on!",student5@mail.com,75.00,75.00';
'Email address',
'Assignment: Assignment for grape group',
'Feedback: Assignment for grape group',
'Course total',
'Last downloaded from this course'
'Course total'
);
// Check that general data is returned as expected.
$this->assertEquals($csvpreview->get_previewdata(), $expecteddata);
// Check that headers are returned as expected.
@ -386,29 +387,22 @@ Bobby,Bunce,,"Moodle HQ","Rock on!",student5@mail.com,75.00,75.00';
*/
public function test_prepare_import_grade_data() {
global $DB;
$course1 = $this->getDataGenerator()->create_course();
// Need to add one of the users into the system.
$user = new stdClass();
$user->firstname = 'Anne';
$user->lastname = 'Able';
$user->email = 'student7@mail.com';
$user->id_number = 1;
// Insert user 1.
$user1 = $this->getDataGenerator()->create_user($user);
$this->getDataGenerator()->enrol_user($user1->id, $course1->id);
$this->getDataGenerator()->create_user($user);
$user = new stdClass();
$user->firstname = 'Bobby';
$user->lastname = 'Bunce';
$user->email = 'student5@mail.com';
$user->id_number = 2;
// Insert user 2.
$user2 = $this->getDataGenerator()->create_user($user);
$this->getDataGenerator()->enrol_user($user2->id, $course1->id);
$this->getDataGenerator()->create_user($user);
$assign1 = $this->getDataGenerator()->create_module('assign', array('course' => $course1->id, 'itemid' => 1));
$csvdata =$this->csv_load($this->oktext);
$this->csv_load($this->oktext);
$importcode = 007;
$verbosescales = 0;
@ -431,7 +425,7 @@ Bobby,Bunce,,"Moodle HQ","Rock on!",student5@mail.com,75.00,75.00';
$formdata->id = 2;
$formdata->iid = $this->iid;
$formdata->importcode = $importcode;
$formdata->forceimport = 1;
$formdata->forceimport = false;
// Blam go time.
$testobject = new phpunit_gradeimport_csv_load_data();
@ -439,30 +433,124 @@ Bobby,Bunce,,"Moodle HQ","Rock on!",student5@mail.com,75.00,75.00';
$verbosescales);
// If everything inserted properly then this should be true.
$this->assertTrue($dataloaded);
grade_import_commit($this->courseid, $importcode, false, false);
}
// Test using force import disabled.
$formdata->mapping_6 = $assign1->id;
$formdata->forceimport = 0;
$csvdata[0][6] = '76.00';
/*
* Test importing csv data into the gradebook using "Last downloaded from this course" column and force import option.
*/
public function test_force_import_option () {
// Need to add users into the system.
$user = new stdClass();
$user->firstname = 'Anne';
$user->lastname = 'Able';
$user->email = 'student7@mail.com';
$user->id_number = 1;
$user1 = $this->getDataGenerator()->create_user($user);
$user = new stdClass();
$user->firstname = 'Bobby';
$user->lastname = 'Bunce';
$user->email = 'student5@mail.com';
$user->id_number = 2;
$user2 = $this->getDataGenerator()->create_user($user);
// Create a new grade item.
$params = array(
'itemtype' => 'manual',
'itemname' => 'Grade item 1',
'gradetype' => GRADE_TYPE_VALUE,
'courseid' => $this->courseid
);
$gradeitem = new grade_item($params, false);
$gradeitemid = $gradeitem->insert();
$importcode = 001;
$verbosescales = 0;
// Form data object.
$formdata = new stdClass();
$formdata->mapfrom = 5;
$formdata->mapto = 'useremail';
$formdata->mapping_0 = 0;
$formdata->mapping_1 = 0;
$formdata->mapping_2 = 0;
$formdata->mapping_3 = 0;
$formdata->mapping_4 = 0;
$formdata->mapping_5 = 0;
$formdata->mapping_6 = $gradeitemid;
$formdata->mapping_7 = 'feedback_2';
$formdata->mapping_8 = 0;
$formdata->mapping_9 = 0;
$formdata->map = 1;
$formdata->id = 2;
$formdata->iid = $this->iid;
$formdata->importcode = $importcode;
$formdata->forceimport = false;
// Add last download from this course column to csv content.
$exportdate = time();
$newcsvdata = str_replace('{exportdate}', $exportdate, $this->csvtext);
$this->csv_load($newcsvdata);
$testobject = new phpunit_gradeimport_csv_load_data();
$dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport, $this->courseid, '', '',
$verbosescales);
$dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport,
$this->courseid, '', '', $verbosescales);
$this->assertTrue($dataloaded);
// We must update the last modified date.
grade_import_commit($this->courseid, $importcode, false, false);
// Test last exported date.
$formdata->mapping_6 = $assign1->id;
$formdata->forceimport = 0;
$csvdata[0][6] = '77.00';
// Test using force import disabled and a date in the past.
$pastdate = strtotime('-1 day', time());
$newcsvdata = str_replace('{exportdate}', $pastdate, $this->csvtext);
$this->csv_load($newcsvdata);
$testobject = new phpunit_gradeimport_csv_load_data();
$dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport, $this->courseid, '', '',
$verbosescales);
// Should return false now, since the grade were updated since last export.
$dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport,
$this->courseid, '', '', $verbosescales);
$this->assertFalse($dataloaded);
// Make sure we get a error message.
$errors = $testobject->get_gradebookerrors();
$this->assertEquals($errors[0], get_string('gradealreadyupdated', 'grades', fullname($user1)));
// Test using force import enabled and a date in the past.
$formdata->forceimport = true;
$testobject = new phpunit_gradeimport_csv_load_data();
$dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport,
$this->courseid, '', '', $verbosescales);
$this->assertTrue($dataloaded);
// Test importing using an old exported file (2 years ago).
$formdata->forceimport = false;
$twoyearsago = strtotime('-2 year', time());
$newcsvdata = str_replace('{exportdate}', $twoyearsago, $this->csvtext);
$this->csv_load($newcsvdata);
$testobject = new phpunit_gradeimport_csv_load_data();
$dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport,
$this->courseid, '', '', $verbosescales);
$this->assertFalse($dataloaded);
$errors = $testobject->get_gradebookerrors();
$this->assertEquals($errors[0], get_string('invalidgradeexporteddate', 'grades'));
// Test importing using invalid exported date.
$baddate = '0123A56B89';
$newcsvdata = str_replace('{exportdate}', $baddate, $this->csvtext);
$this->csv_load($newcsvdata);
$formdata->mapping_6 = $gradeitemid;
$testobject = new phpunit_gradeimport_csv_load_data();
$dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport,
$this->courseid, '', '', $verbosescales);
$this->assertFalse($dataloaded);
$errors = $testobject->get_gradebookerrors();
$this->assertEquals($errors[0], get_string('invalidgradeexporteddate', 'grades'));
// Test importing using date in the future.
$oneyearahead = strtotime('+1 year', time());
$oldcsv = str_replace('{exportdate}', $oneyearahead, $this->csvtext);
$this->csv_load($oldcsv);
$formdata->mapping_6 = $gradeitemid;
$testobject = new phpunit_gradeimport_csv_load_data();
$dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport,
$this->courseid, '', '', $verbosescales);
$this->assertFalse($dataloaded);
$errors = $testobject->get_gradebookerrors();
$this->assertEquals($errors[0], get_string('invalidgradeexporteddate', 'grades'));
}
}

View File

@ -68,7 +68,7 @@ class gradeimport_direct_import_form extends moodleform {
$mform->setType('groupid', PARAM_INT);
$mform->addElement('advcheckbox', 'forceimport', get_string('forceimport', 'grades'));
$mform->addHelpButton('forceimport', 'forceimport', 'grades');
$mform->setDefault('forceimport', 0);
$mform->setDefault('forceimport', false);
$this->add_action_buttons(false, get_string('uploadgrades', 'grades'));
}
}

View File

@ -107,7 +107,7 @@ class gradeimport_direct_mapping_form extends moodleform {
$mform->setType('groupid', PARAM_INT);
$mform->setConstant('groupid', groups_get_course_group($COURSE));
$mform->addElement('hidden', 'forceimport', $this->_customdata['forceimport']);
$mform->setType('forceimport', PARAM_INT);
$mform->setType('forceimport', PARAM_BOOL);
$mform->setConstant('forceimport', $this->_customdata['forceimport']);
$this->add_action_buttons(false, get_string('uploadgrades', 'grades'));
}

View File

@ -24,7 +24,7 @@ $id = required_param('id', PARAM_INT); // Course id.
$verbosescales = optional_param('verbosescales', 1, PARAM_BOOL);
$iid = optional_param('iid', null, PARAM_INT);
$importcode = optional_param('importcode', '', PARAM_FILE);
$forceimport = optional_param('forceimport', null, PARAM_INT);
$forceimport = optional_param('forceimport', false, PARAM_BOOL);
$url = new moodle_url('/grade/import/direct/index.php', array('id' => $id));

View File

@ -72,7 +72,8 @@ class grade_import_form extends moodleform {
$mform->setType('previewrows', PARAM_INT);
$mform->addElement('checkbox', 'forceimport', get_string('forceimport', 'grades'));
$mform->addHelpButton('forceimport', 'forceimport', 'grades');
$mform->setDefault('forceimport', 0);
$mform->setDefault('forceimport', false);
$mform->setType('forceimport', PARAM_BOOL);
$mform->addElement('hidden', 'groupid', groups_get_course_group($COURSE));
$mform->setType('groupid', PARAM_INT);
$this->add_action_buttons(false, get_string('uploadgrades', 'grades'));

View File

@ -394,6 +394,7 @@ $string['incorrectcustomscale'] = '(Incorrect custom scale, please change.)';
$string['incorrectminmax'] = 'The minimum must be lower than the maximum';
$string['inherit'] = 'Inherit';
$string['intersectioninfo'] = 'Student/Grade info';
$string['invalidgradeexporteddate'] = 'The export date is invalid because it is more than a year ago, or in the future, or because the format is invalid.';
$string['item'] = 'Item';
$string['iteminfo'] = 'Item info';
$string['iteminfo_help'] = 'This setting provides space for entering information about the item. The information is not displayed anywhere else.';