. defined('MOODLE_INTERNAL') || die(); require_once('../../lib.php'); function create_submission ($data, $gradeimporterid, $userid) { global $DB; $timenow = time(); if (empty($data->id)) { // If is new db entry; $data->gradeimporterid = $gradeimporterid; $data->usermodified = $userid; $data->timecreated = $timenow; $isnewentry = true; } else { $isnewentry = false; } $data->introformat = $data->intro["format"]; $data->intro = $data->intro["text"]; $data->timemodified = $timenow; $data->position = -1; // Do later if ($isnewentry) { // If is new entry insert data into DB and gets id $data->id = $DB->insert_record('gradeimporter_submission', $data); } // If not new entry updates information // If new entry inserts id into DB $DB->update_record('gradeimporter_submission', $data); return $data; } function store_files ($context, $cm, $data) { global $CFG; $fs = get_file_storage(); $files = $fs->get_area_files($context->id, 'mod_gradeimporter', 'submissionfiles', $data->id ); foreach ($files as $file) { if ($file->get_mimetype() == 'text/csv') { read_csv($file->get_content(), $context, $data); return; } if ($file->get_mimetype() == 'application/zip') { // If it is a .zip file, extract files from the zip $zipfiles = read_zip($file, $context, $fs); // Search a .csv file foreach ($zipfiles as $file) { if ($file->get_mimetype() == 'text/csv') { // If csv is found, pass it to read_csv() read_csv($file->get_content(), $context, $data, $zipfiles); // Only expects one csv so doesn't look for another } } // Finished processing files from zip, so delete temp copies $fs->delete_area_files($context->id, 'mod_gradeimporter', 'unpacktemp', 0); } } } function read_csv ($content, $context, $data, $zipfiles = null) { $csv = prepare_csv($content); foreach ($csv as $line => $feedback) { $feedback = fix_feedback($feedback, $line); // Check if data is correct $feedbackid = store_feedback($feedback, $context->id, $data->id); gradeimporter_update_grades($data, $feedback['id']); if ($feedback['file'] != "") { // If feedback has associated file, insert it into pluginfile foreach ($zipfiles as $file) { // Search in zipfiles to find same name then feedback['file'] if ($feedback['file'] == $file->get_filename()) { $feedbackfileinfo = store_feedback_file($feedback, $context, $data, $file, $feedbackid); break; } } } } } function prepare_csv ($content) { $csvlines = explode(PHP_EOL, $content); $csv = array(); foreach ($csvlines as $line) { $csv[] = str_getcsv($line); } $header = array_shift($csv); $outputcsv = array(); $outputcsv = array_map( function($v)use($header){ return array_combine($header, $v); }, $csv ); return $outputcsv; } function store_feedback ($feedback, $contextid, $submissionid) { global $DB, $USER; // Prepare data to submit to gradeimporter_feedback table $entry = feedback_exists($feedback, $submissionid); $isnewentry = false; if (!$entry) { $entry = new stdClass(); $entry->id = null; $entry->timecreated = time(); $entry->submissionid = $submissionid; $entry->studentid = $feedback['id']; $entry->contextid = $contextid; $isnewentry = true; } else { // If already had a feedback // Deletes its files and remove its entry on DB delete_feedback_files($entry); $DB->delete_records('gradeimporter_feedback', array('submissionid' => $submissionid, 'studentid' => $feedback['id']) ); } $entry->timemodified = time(); $entry->grade = $feedback['grade']; $entry->comment = $feedback['comment']; $entry->filename = $feedback['file']; $entry->usermodified = $USER->id; // If is not a new feedback update previous record and return id return $DB->insert_record('gradeimporter_feedback', $entry); } function store_feedback_file ($feedback, $context, $submission, $filetostore, $feedbackid) { // Prepare file $fs = get_file_storage(); // Create file information needed $fileinfo = array( 'contextid' => $context->id, 'component' => 'mod_gradeimporter', 'filearea' => 'submissionfiles', 'itemid' => $feedbackid, 'filepath' => "/", 'filename' => $filetostore->get_filename(), 'timecreated' => time(), 'timemodified' => time() ); // Store files in correct area return $fs->create_file_from_storedfile($fileinfo, $filetostore); } function read_zip ($file, $context, $fs) { global $CFG; // Get file packer to unpack zip $packer = get_file_packer('application/zip'); // Clear area_files if it has been used before $fs->delete_area_files($context->id, 'mod_gradeimporter', 'unpacktemp' ); // Extract to temp areafiles $file->extract_to_storage($packer, $context->id, 'mod_gradeimporter', 'unpacktemp', 0, $CFG->tempdir, false ); // Get extracted files from unpacktemp area file $tempfiles = $fs->get_area_files($context->id, 'mod_gradeimporter', 'unpacktemp' ); // Returns an array of files object return $tempfiles; } function get_types_array($gradeimporterid) { global $DB, $CFG; // Gets moodle table prefix, usually mdl_ $tp = $CFG->prefix; $query = "select id, name from {$tp}gradeimporter_submissiontype where gradeimporterid = $gradeimporterid"; return $DB->get_records_sql($query); } function validate_formdata($data) { if ($data->type == -1) { throw new moodle_exception(get_string('invalidtype', 'gradeimporter')); } } function feedback_exists($feedback, $submissionid) { global $DB; $feedback = $DB->get_record('gradeimporter_feedback', array('submissionid' => $submissionid, 'studentid' => $feedback['id']), ); return $feedback; } /** * Searches if a feedback has a file when updating it * If already has file then delete it to open space for a new file * Or if updated feedback doesnt have associated file * @param $feedback - record of already submited feedback * @return void */ function delete_feedback_files($feedback) { $fs = get_file_storage(); $file = $fs->get_file($feedback->contextid, 'mod_gradeimporter', 'submissionfiles', $feedback->id, '/', $feedback->filename); if ($file) { $file->delete(); } } /** * Checks if $feedback csv line is correct * if id is missing throw error * if grade is missing change it to 0 * @param array $feedback - line with feedback data for a student * @param int $line - which line of the csv file the feedback is * @return array $feedback - Either empty grade changed to 0 or the same as param */ function fix_feedback ($feedback, $line) { if ($feedback['id'] == "") { throw new moodle_exception(get_string('studentidmissing', 'gradeimporter'), $line); } if ($feedback['grade'] == "") { $feedback['grade'] = 0; } return $feedback; } function delete_feedback($feedback) { global $DB; delete_feedback_files($feedback); $DB->delete_records('gradeimporter_feedback', array('submissionid' => $feedback->submissionid, 'studentid' => $feedback->studentid) ); }