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