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