Skip to content

Commit

Permalink
MDL-46599 gradebook: Added a time exported column to grade export via…
Browse files Browse the repository at this point in the history
… csv.

This will be useful for checking if a csv import is trying to overwrite
new grade updates.
  • Loading branch information
abgreeve authored and lameze committed Oct 16, 2014
1 parent a5240a8 commit b9cafe3
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 54 deletions.
4 changes: 4 additions & 0 deletions grade/export/txt/grade_export_txt.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ public function print_grades() {
$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.
Expand Down Expand Up @@ -110,6 +112,8 @@ public function print_grades() {
$exportdata[] = $this->format_feedback($userdata->feedbacks[$itemid]);
}
}
// Time exported.
$exportdata[] = time();
$csvexport->add_data($exportdata);
}
$gui->close();
Expand Down
1 change: 1 addition & 0 deletions grade/export/txt/lang/en/gradeexport_txt.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
26 changes: 18 additions & 8 deletions grade/import/csv/classes/load_data.php
Original file line number Diff line number Diff line change
Expand Up @@ -531,15 +531,25 @@ public function prepare_import_grade_data($header, $formdata, $csvimport, $cours
$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;

}
$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;
}
}
}

// 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;
}

$insertid = self::insert_grade_record($newgrade, $this->studentid);
// Check to see if the insert was successful.
if (empty($insertid)) {
Expand Down
3 changes: 1 addition & 2 deletions grade/import/csv/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
$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 !== '') {
Expand Down Expand Up @@ -68,7 +68,6 @@

// 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);
Expand Down
168 changes: 128 additions & 40 deletions grade/import/csv/tests/load_data_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,20 @@
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!",[email protected],56.00,"We welcome feedback",56.00,1412327067
Bobby,Bunce,2,"Moodle HQ","Rock on!",[email protected],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!",[email protected],56.00,"We welcome feedback",56.00
Bobby,Bunce,,"Moodle HQ","Rock on!",[email protected],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!",[email protected],56.00,56.00,78.00
Bobby,Bunce,,"Moodle HQ","Rock on!",[email protected],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!",[email protected],56.00,"We welcome feedback",56.00,{exportdate}
Bobby,Bunce,,"Moodle HQ","Rock on!",[email protected],75.00,,75.00,{exportdate}';

/** @var int $iid Import ID. */
protected $iid;

Expand Down Expand Up @@ -94,26 +99,24 @@ public function test_load_csv_content() {
$expecteddata = array(array(
'Anne',
'Able',
'1',
'',
'Moodle HQ',
'Rock on!',
'[email protected]',
56.00,
'We welcome feedback',
56.00,
1412327067
56.00
),
array(
'Bobby',
'Bunce',
'2',
'',
'Moodle HQ',
'Rock on!',
'[email protected]',
75.00,
'',
75.00,
1412327067
75.00
)
);

Expand All @@ -126,10 +129,8 @@ public function test_load_csv_content() {
'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.
Expand Down Expand Up @@ -386,29 +387,22 @@ public function test_map_user_data_with_value() {
*/
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 = '[email protected]';
$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 = '[email protected]';
$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;
Expand All @@ -431,38 +425,132 @@ public function test_prepare_import_grade_data() {
$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();
$dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport, $this->courseid, '', '',
$verbosescales);
// If everything inserted properly then this should be true.
$this->assertTrue($dataloaded);
grade_import_commit($this->courseid, $importcode, false, false);
}

/*
* 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 = '[email protected]';
$user->id_number = 1;
$user1 = $this->getDataGenerator()->create_user($user);
$user = new stdClass();
$user->firstname = 'Bobby';
$user->lastname = 'Bunce';
$user->email = '[email protected]';
$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;

// Test using force import disabled.
$formdata->mapping_6 = $assign1->id;
$formdata->forceimport = 0;
$csvdata[0][6] = '76.00';
// 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'));
}
}
2 changes: 1 addition & 1 deletion grade/import/direct/classes/import_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public function definition() {
$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'));
}
}
2 changes: 1 addition & 1 deletion grade/import/direct/classes/mapping_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public function definition() {
$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'));
}
Expand Down
2 changes: 1 addition & 1 deletion grade/import/direct/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
$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));

Expand Down
3 changes: 2 additions & 1 deletion grade/import/grade_import_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ function definition (){
$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'));
Expand Down
1 change: 1 addition & 0 deletions lang/en/grades.php
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@
$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.';
Expand Down

0 comments on commit b9cafe3

Please sign in to comment.