submission_functions.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. <?php
  2. // This file is part of
  3. //
  4. // Moodle is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // Moodle is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16. defined('MOODLE_INTERNAL') || die();
  17. require_once('../../lib.php');
  18. function create_submission ($data, $gradeimporterid, $userid) {
  19. global $DB;
  20. $timenow = time();
  21. if (empty($data->id)) {
  22. // If is new db entry;
  23. $data->gradeimporterid = $gradeimporterid;
  24. $data->usermodified = $userid;
  25. $data->timecreated = $timenow;
  26. $isnewentry = true;
  27. } else {
  28. $isnewentry = false;
  29. }
  30. $data->introformat = $data->intro["format"];
  31. $data->intro = $data->intro["text"];
  32. $data->timemodified = $timenow;
  33. $data->position = -1; // Do later
  34. if ($isnewentry) {
  35. // If is new entry insert data into DB and gets id
  36. $data->id = $DB->insert_record('gradeimporter_submission', $data);
  37. }
  38. // If not new entry updates information
  39. // If new entry inserts id into DB
  40. $DB->update_record('gradeimporter_submission', $data);
  41. return $data;
  42. }
  43. function store_files ($context, $cm, $data) {
  44. global $CFG;
  45. $fs = get_file_storage();
  46. $files = $fs->get_area_files($context->id, 'mod_gradeimporter',
  47. 'submissionfiles', $data->id
  48. );
  49. foreach ($files as $file) {
  50. if ($file->get_mimetype() == 'text/csv') {
  51. read_csv($file->get_content(), $context, $data);
  52. return;
  53. }
  54. if ($file->get_mimetype() == 'application/zip') {
  55. // If it is a .zip file, extract files from the zip
  56. $zipfiles = read_zip($file, $context, $fs);
  57. // Search a .csv file
  58. foreach ($zipfiles as $file) {
  59. if ($file->get_mimetype() == 'text/csv') {
  60. // If csv is found, pass it to read_csv()
  61. read_csv($file->get_content(), $context, $data, $zipfiles);
  62. // Only expects one csv so doesn't look for another
  63. }
  64. }
  65. // Finished processing files from zip, so delete temp copies
  66. $fs->delete_area_files($context->id, 'mod_gradeimporter', 'unpacktemp', 0);
  67. }
  68. }
  69. }
  70. function read_csv ($content, $context, $data, $zipfiles = null) {
  71. $csv = prepare_csv($content);
  72. foreach ($csv as $line => $feedback) {
  73. $feedback = fix_feedback($feedback, $line); // Check if data is correct
  74. $feedbackid = store_feedback($feedback, $context->id, $data->id);
  75. gradeimporter_update_grades($data, $feedback['id']);
  76. if ($feedback['file'] != "") {
  77. // If feedback has associated file, insert it into pluginfile
  78. foreach ($zipfiles as $file) {
  79. // Search in zipfiles to find same name then feedback['file']
  80. if ($feedback['file'] == $file->get_filename()) {
  81. $feedbackfileinfo = store_feedback_file($feedback, $context, $data, $file, $feedbackid);
  82. break;
  83. }
  84. }
  85. }
  86. }
  87. }
  88. function prepare_csv ($content) {
  89. $csvlines = explode(PHP_EOL, $content);
  90. $csv = array();
  91. foreach ($csvlines as $line) {
  92. $csv[] = str_getcsv($line);
  93. }
  94. $header = array_shift($csv);
  95. $outputcsv = array();
  96. $outputcsv = array_map(
  97. function($v)use($header){
  98. return array_combine($header, $v);
  99. },
  100. $csv
  101. );
  102. return $outputcsv;
  103. }
  104. function store_feedback ($feedback, $contextid, $submissionid) {
  105. global $DB, $USER;
  106. // Prepare data to submit to gradeimporter_feedback table
  107. $entry = feedback_exists($feedback, $submissionid);
  108. $isnewentry = false;
  109. if (!$entry) {
  110. $entry = new stdClass();
  111. $entry->id = null;
  112. $entry->timecreated = time();
  113. $entry->submissionid = $submissionid;
  114. $entry->studentid = $feedback['id'];
  115. $entry->contextid = $contextid;
  116. $isnewentry = true;
  117. } else {
  118. // If already had a feedback
  119. // Deletes its files and remove its entry on DB
  120. delete_feedback_files($entry);
  121. $DB->delete_records('gradeimporter_feedback',
  122. array('submissionid' => $submissionid,
  123. 'studentid' => $feedback['id'])
  124. );
  125. }
  126. $entry->timemodified = time();
  127. $entry->grade = $feedback['grade'];
  128. $entry->comment = $feedback['comment'];
  129. $entry->filename = $feedback['file'];
  130. $entry->usermodified = $USER->id;
  131. // If is not a new feedback update previous record and return id
  132. return $DB->insert_record('gradeimporter_feedback', $entry);
  133. }
  134. function store_feedback_file ($feedback, $context, $submission, $filetostore, $feedbackid) {
  135. // Prepare file
  136. $fs = get_file_storage();
  137. // Create file information needed
  138. $fileinfo = array(
  139. 'contextid' => $context->id,
  140. 'component' => 'mod_gradeimporter',
  141. 'filearea' => 'submissionfiles',
  142. 'itemid' => $feedbackid,
  143. 'filepath' => "/",
  144. 'filename' => $filetostore->get_filename(),
  145. 'timecreated' => time(), 'timemodified' => time()
  146. );
  147. // Store files in correct area
  148. return $fs->create_file_from_storedfile($fileinfo, $filetostore);
  149. }
  150. function read_zip ($file, $context, $fs) {
  151. global $CFG;
  152. // Get file packer to unpack zip
  153. $packer = get_file_packer('application/zip');
  154. // Clear area_files if it has been used before
  155. $fs->delete_area_files($context->id,
  156. 'mod_gradeimporter',
  157. 'unpacktemp'
  158. );
  159. // Extract to temp areafiles
  160. $file->extract_to_storage($packer,
  161. $context->id,
  162. 'mod_gradeimporter',
  163. 'unpacktemp',
  164. 0,
  165. $CFG->tempdir,
  166. false
  167. );
  168. // Get extracted files from unpacktemp area file
  169. $tempfiles = $fs->get_area_files($context->id,
  170. 'mod_gradeimporter',
  171. 'unpacktemp'
  172. );
  173. // Returns an array of files object
  174. return $tempfiles;
  175. }
  176. function get_types_array($gradeimporterid) {
  177. global $DB, $CFG;
  178. // Gets moodle table prefix, usually mdl_
  179. $tp = $CFG->prefix;
  180. $query = "select id, name from {$tp}gradeimporter_submissiontype where gradeimporterid = $gradeimporterid";
  181. return $DB->get_records_sql($query);
  182. }
  183. function validate_formdata($data) {
  184. if ($data->type == -1) {
  185. throw new moodle_exception(get_string('invalidtype', 'gradeimporter'));
  186. }
  187. }
  188. function feedback_exists($feedback, $submissionid) {
  189. global $DB;
  190. $feedback = $DB->get_record('gradeimporter_feedback',
  191. array('submissionid' => $submissionid,
  192. 'studentid' => $feedback['id']),
  193. );
  194. return $feedback;
  195. }
  196. /**
  197. * Searches if a feedback has a file when updating it
  198. * If already has file then delete it to open space for a new file
  199. * Or if updated feedback doesnt have associated file
  200. * @param $feedback - record of already submited feedback
  201. * @return void
  202. */
  203. function delete_feedback_files($feedback) {
  204. $fs = get_file_storage();
  205. $file = $fs->get_file($feedback->contextid, 'mod_gradeimporter', 'submissionfiles', $feedback->id, '/', $feedback->filename);
  206. if ($file) {
  207. $file->delete();
  208. }
  209. }
  210. /**
  211. * Checks if $feedback csv line is correct
  212. * if id is missing throw error
  213. * if grade is missing change it to 0
  214. * @param array $feedback - line with feedback data for a student
  215. * @param int $line - which line of the csv file the feedback is
  216. * @return array $feedback - Either empty grade changed to 0 or the same as param
  217. */
  218. function fix_feedback ($feedback, $line) {
  219. if ($feedback['id'] == "") {
  220. throw new moodle_exception(get_string('studentidmissing', 'gradeimporter'), $line);
  221. }
  222. if ($feedback['grade'] == "") {
  223. $feedback['grade'] = 0;
  224. }
  225. return $feedback;
  226. }
  227. function delete_feedback($feedback) {
  228. global $DB;
  229. delete_feedback_files($feedback);
  230. $DB->delete_records('gradeimporter_feedback',
  231. array('submissionid' => $feedback->submissionid,
  232. 'studentid' => $feedback->studentid)
  233. );
  234. }