Commit | Line | Data |
---|---|---|
bbd0e548 DW |
1 | <?php |
2 | // This file is part of Moodle - http://moodle.org/ | |
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 | ||
17 | /** | |
18 | * This file contains the definition for the library class for file submission plugin | |
19 | * | |
20 | * This class provides all the functionality for the new assign module. | |
21 | * | |
22 | * @package assignsubmission_file | |
23 | * @copyright 2012 NetSpot {@link http://www.netspot.com.au} | |
24 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
25 | */ | |
26 | ||
bbd0e548 DW |
27 | require_once($CFG->libdir.'/eventslib.php'); |
28 | ||
29 | defined('MOODLE_INTERNAL') || die(); | |
e5403f8c DW |
30 | |
31 | // File areas for file submission assignment. | |
8ab7bb9f DW |
32 | define('ASSIGNSUBMISSION_FILE_MAXFILES', 20); |
33 | define('ASSIGNSUBMISSION_FILE_MAXSUMMARYFILES', 5); | |
34 | define('ASSIGNSUBMISSION_FILE_FILEAREA', 'submission_files'); | |
bbd0e548 DW |
35 | |
36 | /** | |
e5403f8c | 37 | * Library class for file submission plugin extending submission plugin base class |
bbd0e548 DW |
38 | * |
39 | * @package assignsubmission_file | |
40 | * @copyright 2012 NetSpot {@link http://www.netspot.com.au} | |
41 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
42 | */ | |
43 | class assign_submission_file extends assign_submission_plugin { | |
44 | ||
45 | /** | |
46 | * Get the name of the file submission plugin | |
47 | * @return string | |
48 | */ | |
49 | public function get_name() { | |
50 | return get_string('file', 'assignsubmission_file'); | |
51 | } | |
52 | ||
53 | /** | |
54 | * Get file submission information from the database | |
55 | * | |
56 | * @param int $submissionid | |
57 | * @return mixed | |
58 | */ | |
59 | private function get_file_submission($submissionid) { | |
60 | global $DB; | |
61 | return $DB->get_record('assignsubmission_file', array('submission'=>$submissionid)); | |
62 | } | |
63 | ||
64 | /** | |
65 | * Get the default setting for file submission plugin | |
66 | * | |
67 | * @param MoodleQuickForm $mform The form to add elements to | |
68 | * @return void | |
69 | */ | |
70 | public function get_settings(MoodleQuickForm $mform) { | |
71 | global $CFG, $COURSE; | |
72 | ||
73 | $defaultmaxfilesubmissions = $this->get_config('maxfilesubmissions'); | |
74 | $defaultmaxsubmissionsizebytes = $this->get_config('maxsubmissionsizebytes'); | |
75 | ||
76 | $settings = array(); | |
77 | $options = array(); | |
e5403f8c | 78 | for ($i = 1; $i <= ASSIGNSUBMISSION_FILE_MAXFILES; $i++) { |
bbd0e548 DW |
79 | $options[$i] = $i; |
80 | } | |
81 | ||
e5403f8c DW |
82 | $name = get_string('maxfilessubmission', 'assignsubmission_file'); |
83 | $mform->addElement('select', 'assignsubmission_file_maxfiles', $name, $options); | |
84 | $mform->addHelpButton('assignsubmission_file_maxfiles', | |
85 | 'maxfilessubmission', | |
86 | 'assignsubmission_file'); | |
bbd0e548 | 87 | $mform->setDefault('assignsubmission_file_maxfiles', $defaultmaxfilesubmissions); |
b0da618b | 88 | $mform->disabledIf('assignsubmission_file_maxfiles', 'assignsubmission_file_enabled', 'notchecked'); |
bbd0e548 | 89 | |
e5403f8c DW |
90 | $choices = get_max_upload_sizes($CFG->maxbytes, |
91 | $COURSE->maxbytes, | |
92 | get_config('assignsubmission_file', 'maxbytes')); | |
6d976f3f | 93 | |
bbd0e548 DW |
94 | $settings[] = array('type' => 'select', |
95 | 'name' => 'maxsubmissionsizebytes', | |
96 | 'description' => get_string('maximumsubmissionsize', 'assignsubmission_file'), | |
97 | 'options'=> $choices, | |
98 | 'default'=> $defaultmaxsubmissionsizebytes); | |
99 | ||
e5403f8c DW |
100 | $name = get_string('maximumsubmissionsize', 'assignsubmission_file'); |
101 | $mform->addElement('select', 'assignsubmission_file_maxsizebytes', $name, $choices); | |
102 | $mform->addHelpButton('assignsubmission_file_maxsizebytes', | |
103 | 'maximumsubmissionsize', | |
104 | 'assignsubmission_file'); | |
bbd0e548 | 105 | $mform->setDefault('assignsubmission_file_maxsizebytes', $defaultmaxsubmissionsizebytes); |
e5403f8c DW |
106 | $mform->disabledIf('assignsubmission_file_maxsizebytes', |
107 | 'assignsubmission_file_enabled', | |
b0da618b | 108 | 'notchecked'); |
bbd0e548 DW |
109 | } |
110 | ||
111 | /** | |
112 | * Save the settings for file submission plugin | |
113 | * | |
114 | * @param stdClass $data | |
115 | * @return bool | |
116 | */ | |
117 | public function save_settings(stdClass $data) { | |
118 | $this->set_config('maxfilesubmissions', $data->assignsubmission_file_maxfiles); | |
119 | $this->set_config('maxsubmissionsizebytes', $data->assignsubmission_file_maxsizebytes); | |
120 | return true; | |
121 | } | |
122 | ||
123 | /** | |
124 | * File format options | |
125 | * | |
126 | * @return array | |
127 | */ | |
128 | private function get_file_options() { | |
129 | $fileoptions = array('subdirs'=>1, | |
130 | 'maxbytes'=>$this->get_config('maxsubmissionsizebytes'), | |
131 | 'maxfiles'=>$this->get_config('maxfilesubmissions'), | |
132 | 'accepted_types'=>'*', | |
133 | 'return_types'=>FILE_INTERNAL); | |
134 | return $fileoptions; | |
135 | } | |
136 | ||
137 | /** | |
138 | * Add elements to submission form | |
139 | * | |
140 | * @param mixed $submission stdClass|null | |
141 | * @param MoodleQuickForm $mform | |
142 | * @param stdClass $data | |
143 | * @return bool | |
144 | */ | |
145 | public function get_form_elements($submission, MoodleQuickForm $mform, stdClass $data) { | |
146 | ||
147 | if ($this->get_config('maxfilesubmissions') <= 0) { | |
148 | return false; | |
149 | } | |
150 | ||
151 | $fileoptions = $this->get_file_options(); | |
152 | $submissionid = $submission ? $submission->id : 0; | |
153 | ||
e5403f8c DW |
154 | $data = file_prepare_standard_filemanager($data, |
155 | 'files', | |
156 | $fileoptions, | |
157 | $this->assignment->get_context(), | |
158 | 'assignsubmission_file', | |
159 | ASSIGNSUBMISSION_FILE_FILEAREA, | |
160 | $submissionid); | |
7e5be074 MN |
161 | $mform->addElement('filemanager', 'files_filemanager', html_writer::tag('span', $this->get_name(), |
162 | array('class' => 'accesshide')), null, $fileoptions); | |
163 | ||
bbd0e548 DW |
164 | return true; |
165 | } | |
166 | ||
167 | /** | |
168 | * Count the number of files | |
169 | * | |
170 | * @param int $submissionid | |
171 | * @param string $area | |
172 | * @return int | |
173 | */ | |
174 | private function count_files($submissionid, $area) { | |
175 | ||
176 | $fs = get_file_storage(); | |
e5403f8c DW |
177 | $files = $fs->get_area_files($this->assignment->get_context()->id, |
178 | 'assignsubmission_file', | |
179 | $area, | |
180 | $submissionid, | |
181 | 'id', | |
182 | false); | |
bbd0e548 DW |
183 | |
184 | return count($files); | |
185 | } | |
186 | ||
187 | /** | |
e5403f8c DW |
188 | * Save the files and trigger plagiarism plugin, if enabled, |
189 | * to scan the uploaded files via events trigger | |
bbd0e548 DW |
190 | * |
191 | * @param stdClass $submission | |
192 | * @param stdClass $data | |
193 | * @return bool | |
194 | */ | |
195 | public function save(stdClass $submission, stdClass $data) { | |
196 | global $USER, $DB; | |
197 | ||
198 | $fileoptions = $this->get_file_options(); | |
199 | ||
e5403f8c DW |
200 | $data = file_postupdate_standard_filemanager($data, |
201 | 'files', | |
202 | $fileoptions, | |
203 | $this->assignment->get_context(), | |
204 | 'assignsubmission_file', | |
205 | ASSIGNSUBMISSION_FILE_FILEAREA, | |
206 | $submission->id); | |
bbd0e548 DW |
207 | |
208 | $filesubmission = $this->get_file_submission($submission->id); | |
209 | ||
e5403f8c | 210 | // Plagiarism code event trigger when files are uploaded. |
bbd0e548 DW |
211 | |
212 | $fs = get_file_storage(); | |
e5403f8c DW |
213 | $files = $fs->get_area_files($this->assignment->get_context()->id, |
214 | 'assignsubmission_file', | |
215 | ASSIGNSUBMISSION_FILE_FILEAREA, | |
216 | $submission->id, | |
217 | 'id', | |
218 | false); | |
219 | ||
8ab7bb9f | 220 | $count = $this->count_files($submission->id, ASSIGNSUBMISSION_FILE_FILEAREA); |
e5403f8c DW |
221 | |
222 | // Send files to event system. | |
223 | // This lets Moodle know that an assessable file was uploaded (eg for plagiarism detection). | |
bbd0e548 DW |
224 | $eventdata = new stdClass(); |
225 | $eventdata->modulename = 'assign'; | |
226 | $eventdata->cmid = $this->assignment->get_course_module()->id; | |
227 | $eventdata->itemid = $submission->id; | |
228 | $eventdata->courseid = $this->assignment->get_course()->id; | |
229 | $eventdata->userid = $USER->id; | |
230 | if ($count > 1) { | |
e5403f8c | 231 | $eventdata->files = $files; |
bbd0e548 | 232 | } |
e5403f8c | 233 | $eventdata->file = $files; |
4447223b | 234 | $eventdata->pathnamehashes = array_keys($files); |
bbd0e548 DW |
235 | events_trigger('assessable_file_uploaded', $eventdata); |
236 | ||
bbd0e548 | 237 | if ($filesubmission) { |
e5403f8c DW |
238 | $filesubmission->numfiles = $this->count_files($submission->id, |
239 | ASSIGNSUBMISSION_FILE_FILEAREA); | |
bbd0e548 DW |
240 | return $DB->update_record('assignsubmission_file', $filesubmission); |
241 | } else { | |
242 | $filesubmission = new stdClass(); | |
e5403f8c DW |
243 | $filesubmission->numfiles = $this->count_files($submission->id, |
244 | ASSIGNSUBMISSION_FILE_FILEAREA); | |
bbd0e548 DW |
245 | $filesubmission->submission = $submission->id; |
246 | $filesubmission->assignment = $this->assignment->get_instance()->id; | |
247 | return $DB->insert_record('assignsubmission_file', $filesubmission) > 0; | |
248 | } | |
249 | } | |
250 | ||
251 | /** | |
252 | * Produce a list of files suitable for export that represent this feedback or submission | |
253 | * | |
254 | * @param stdClass $submission The submission | |
255 | * @return array - return an array of files indexed by filename | |
256 | */ | |
2406815b | 257 | public function get_files(stdClass $submission, stdClass $user) { |
bbd0e548 DW |
258 | $result = array(); |
259 | $fs = get_file_storage(); | |
260 | ||
e5403f8c DW |
261 | $files = $fs->get_area_files($this->assignment->get_context()->id, |
262 | 'assignsubmission_file', | |
263 | ASSIGNSUBMISSION_FILE_FILEAREA, | |
264 | $submission->id, | |
265 | 'timemodified', | |
266 | false); | |
bbd0e548 DW |
267 | |
268 | foreach ($files as $file) { | |
269 | $result[$file->get_filename()] = $file; | |
270 | } | |
271 | return $result; | |
272 | } | |
273 | ||
274 | /** | |
275 | * Display the list of files in the submission status table | |
276 | * | |
277 | * @param stdClass $submission | |
278 | * @param bool $showviewlink Set this to true if the list of files is long | |
279 | * @return string | |
280 | */ | |
7ee1548a | 281 | public function view_summary(stdClass $submission, & $showviewlink) { |
8ab7bb9f | 282 | $count = $this->count_files($submission->id, ASSIGNSUBMISSION_FILE_FILEAREA); |
bbd0e548 | 283 | |
e5403f8c | 284 | // Show we show a link to view all files for this plugin? |
8ab7bb9f DW |
285 | $showviewlink = $count > ASSIGNSUBMISSION_FILE_MAXSUMMARYFILES; |
286 | if ($count <= ASSIGNSUBMISSION_FILE_MAXSUMMARYFILES) { | |
e5403f8c DW |
287 | return $this->assignment->render_area_files('assignsubmission_file', |
288 | ASSIGNSUBMISSION_FILE_FILEAREA, | |
289 | $submission->id); | |
bbd0e548 DW |
290 | } else { |
291 | return get_string('countfiles', 'assignsubmission_file', $count); | |
292 | } | |
293 | } | |
294 | ||
295 | /** | |
296 | * No full submission view - the summary contains the list of files and that is the whole submission | |
297 | * | |
298 | * @param stdClass $submission | |
299 | * @return string | |
300 | */ | |
301 | public function view(stdClass $submission) { | |
e5403f8c DW |
302 | return $this->assignment->render_area_files('assignsubmission_file', |
303 | ASSIGNSUBMISSION_FILE_FILEAREA, | |
304 | $submission->id); | |
bbd0e548 DW |
305 | } |
306 | ||
307 | ||
308 | ||
309 | /** | |
310 | * Return true if this plugin can upgrade an old Moodle 2.2 assignment of this type | |
311 | * and version. | |
312 | * | |
313 | * @param string $type | |
314 | * @param int $version | |
315 | * @return bool True if upgrade is possible | |
316 | */ | |
317 | public function can_upgrade($type, $version) { | |
318 | ||
319 | $uploadsingletype ='uploadsingle'; | |
320 | $uploadtype ='upload'; | |
321 | ||
322 | if (($type == $uploadsingletype || $type == $uploadtype) && $version >= 2011112900) { | |
323 | return true; | |
324 | } | |
325 | return false; | |
326 | } | |
327 | ||
328 | ||
329 | /** | |
330 | * Upgrade the settings from the old assignment | |
331 | * to the new plugin based one | |
332 | * | |
333 | * @param context $oldcontext - the old assignment context | |
334 | * @param stdClass $oldassignment - the old assignment data record | |
335 | * @param string $log record log events here | |
336 | * @return bool Was it a success? (false will trigger rollback) | |
337 | */ | |
e5403f8c | 338 | public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) { |
01d29b39 DW |
339 | global $DB; |
340 | ||
bbd0e548 DW |
341 | if ($oldassignment->assignmenttype == 'uploadsingle') { |
342 | $this->set_config('maxfilesubmissions', 1); | |
343 | $this->set_config('maxsubmissionsizebytes', $oldassignment->maxbytes); | |
344 | return true; | |
01d29b39 | 345 | } else if ($oldassignment->assignmenttype == 'upload') { |
bbd0e548 DW |
346 | $this->set_config('maxfilesubmissions', $oldassignment->var1); |
347 | $this->set_config('maxsubmissionsizebytes', $oldassignment->maxbytes); | |
01d29b39 DW |
348 | |
349 | // Advanced file upload uses a different setting to do the same thing. | |
350 | $DB->set_field('assign', | |
351 | 'submissiondrafts', | |
352 | $oldassignment->var4, | |
353 | array('id'=>$this->assignment->get_instance()->id)); | |
f531ca72 DW |
354 | |
355 | // Convert advanced file upload "hide description before due date" setting. | |
356 | $alwaysshow = 0; | |
357 | if (!$oldassignment->var3) { | |
358 | $alwaysshow = 1; | |
359 | } | |
360 | $DB->set_field('assign', | |
361 | 'alwaysshowdescription', | |
362 | $alwaysshow, | |
363 | array('id'=>$this->assignment->get_instance()->id)); | |
bbd0e548 DW |
364 | return true; |
365 | } | |
bbd0e548 DW |
366 | } |
367 | ||
368 | /** | |
369 | * Upgrade the submission from the old assignment to the new one | |
370 | * | |
371 | * @param context $oldcontext The context of the old assignment | |
372 | * @param stdClass $oldassignment The data record for the old oldassignment | |
373 | * @param stdClass $oldsubmission The data record for the old submission | |
374 | * @param stdClass $submission The data record for the new submission | |
375 | * @param string $log Record upgrade messages in the log | |
376 | * @return bool true or false - false will trigger a rollback | |
377 | */ | |
e5403f8c DW |
378 | public function upgrade(context $oldcontext, |
379 | stdClass $oldassignment, | |
380 | stdClass $oldsubmission, | |
381 | stdClass $submission, | |
382 | & $log) { | |
bbd0e548 DW |
383 | global $DB; |
384 | ||
385 | $filesubmission = new stdClass(); | |
386 | ||
387 | $filesubmission->numfiles = $oldsubmission->numfiles; | |
388 | $filesubmission->submission = $submission->id; | |
389 | $filesubmission->assignment = $this->assignment->get_instance()->id; | |
390 | ||
391 | if (!$DB->insert_record('assignsubmission_file', $filesubmission) > 0) { | |
392 | $log .= get_string('couldnotconvertsubmission', 'mod_assign', $submission->userid); | |
393 | return false; | |
394 | } | |
395 | ||
e5403f8c | 396 | // Now copy the area files. |
bbd0e548 DW |
397 | $this->assignment->copy_area_files_for_upgrade($oldcontext->id, |
398 | 'mod_assignment', | |
399 | 'submission', | |
400 | $oldsubmission->id, | |
bbd0e548 DW |
401 | $this->assignment->get_context()->id, |
402 | 'assignsubmission_file', | |
8ab7bb9f | 403 | ASSIGNSUBMISSION_FILE_FILEAREA, |
bbd0e548 DW |
404 | $submission->id); |
405 | ||
bbd0e548 DW |
406 | return true; |
407 | } | |
408 | ||
409 | /** | |
410 | * The assignment has been deleted - cleanup | |
411 | * | |
412 | * @return bool | |
413 | */ | |
414 | public function delete_instance() { | |
415 | global $DB; | |
e5403f8c DW |
416 | // Will throw exception on failure. |
417 | $DB->delete_records('assignsubmission_file', | |
418 | array('assignment'=>$this->assignment->get_instance()->id)); | |
bbd0e548 DW |
419 | |
420 | return true; | |
421 | } | |
422 | ||
423 | /** | |
424 | * Formatting for log info | |
425 | * | |
426 | * @param stdClass $submission The submission | |
bbd0e548 DW |
427 | * @return string |
428 | */ | |
429 | public function format_for_log(stdClass $submission) { | |
e5403f8c | 430 | // Format the info for each submission plugin (will be added to log). |
8ab7bb9f | 431 | $filecount = $this->count_files($submission->id, ASSIGNSUBMISSION_FILE_FILEAREA); |
bbd0e548 | 432 | |
e5403f8c | 433 | return get_string('numfilesforlog', 'assignsubmission_file', $filecount); |
bbd0e548 DW |
434 | } |
435 | ||
436 | /** | |
437 | * Return true if there are no submission files | |
438 | * @param stdClass $submission | |
439 | */ | |
440 | public function is_empty(stdClass $submission) { | |
8ab7bb9f | 441 | return $this->count_files($submission->id, ASSIGNSUBMISSION_FILE_FILEAREA) == 0; |
bbd0e548 DW |
442 | } |
443 | ||
444 | /** | |
445 | * Get file areas returns a list of areas this plugin stores files | |
446 | * @return array - An array of fileareas (keys) and descriptions (values) | |
447 | */ | |
448 | public function get_file_areas() { | |
8ab7bb9f | 449 | return array(ASSIGNSUBMISSION_FILE_FILEAREA=>$this->get_name()); |
bbd0e548 DW |
450 | } |
451 | ||
452 | } |