[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 require_once($CFG->libdir.'/eventslib.php'); 28 29 defined('MOODLE_INTERNAL') || die(); 30 31 // File areas for file submission assignment. 32 define('ASSIGNSUBMISSION_FILE_MAXSUMMARYFILES', 5); 33 define('ASSIGNSUBMISSION_FILE_FILEAREA', 'submission_files'); 34 35 /** 36 * Library class for file submission plugin extending submission plugin base class 37 * 38 * @package assignsubmission_file 39 * @copyright 2012 NetSpot {@link http://www.netspot.com.au} 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 */ 42 class assign_submission_file extends assign_submission_plugin { 43 44 /** 45 * Get the name of the file submission plugin 46 * @return string 47 */ 48 public function get_name() { 49 return get_string('file', 'assignsubmission_file'); 50 } 51 52 /** 53 * Get file submission information from the database 54 * 55 * @param int $submissionid 56 * @return mixed 57 */ 58 private function get_file_submission($submissionid) { 59 global $DB; 60 return $DB->get_record('assignsubmission_file', array('submission'=>$submissionid)); 61 } 62 63 /** 64 * Get the default setting for file submission plugin 65 * 66 * @param MoodleQuickForm $mform The form to add elements to 67 * @return void 68 */ 69 public function get_settings(MoodleQuickForm $mform) { 70 global $CFG, $COURSE; 71 72 $defaultmaxfilesubmissions = $this->get_config('maxfilesubmissions'); 73 $defaultmaxsubmissionsizebytes = $this->get_config('maxsubmissionsizebytes'); 74 75 $settings = array(); 76 $options = array(); 77 for ($i = 1; $i <= get_config('assignsubmission_file', 'maxfiles'); $i++) { 78 $options[$i] = $i; 79 } 80 81 $name = get_string('maxfilessubmission', 'assignsubmission_file'); 82 $mform->addElement('select', 'assignsubmission_file_maxfiles', $name, $options); 83 $mform->addHelpButton('assignsubmission_file_maxfiles', 84 'maxfilessubmission', 85 'assignsubmission_file'); 86 $mform->setDefault('assignsubmission_file_maxfiles', $defaultmaxfilesubmissions); 87 $mform->disabledIf('assignsubmission_file_maxfiles', 'assignsubmission_file_enabled', 'notchecked'); 88 89 $choices = get_max_upload_sizes($CFG->maxbytes, 90 $COURSE->maxbytes, 91 get_config('assignsubmission_file', 'maxbytes')); 92 93 $settings[] = array('type' => 'select', 94 'name' => 'maxsubmissionsizebytes', 95 'description' => get_string('maximumsubmissionsize', 'assignsubmission_file'), 96 'options'=> $choices, 97 'default'=> $defaultmaxsubmissionsizebytes); 98 99 $name = get_string('maximumsubmissionsize', 'assignsubmission_file'); 100 $mform->addElement('select', 'assignsubmission_file_maxsizebytes', $name, $choices); 101 $mform->addHelpButton('assignsubmission_file_maxsizebytes', 102 'maximumsubmissionsize', 103 'assignsubmission_file'); 104 $mform->setDefault('assignsubmission_file_maxsizebytes', $defaultmaxsubmissionsizebytes); 105 $mform->disabledIf('assignsubmission_file_maxsizebytes', 106 'assignsubmission_file_enabled', 107 'notchecked'); 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 if ($fileoptions['maxbytes'] == 0) { 134 // Use module default. 135 $fileoptions['maxbytes'] = get_config('assignsubmission_file', 'maxbytes'); 136 } 137 return $fileoptions; 138 } 139 140 /** 141 * Add elements to submission form 142 * 143 * @param mixed $submission stdClass|null 144 * @param MoodleQuickForm $mform 145 * @param stdClass $data 146 * @return bool 147 */ 148 public function get_form_elements($submission, MoodleQuickForm $mform, stdClass $data) { 149 150 if ($this->get_config('maxfilesubmissions') <= 0) { 151 return false; 152 } 153 154 $fileoptions = $this->get_file_options(); 155 $submissionid = $submission ? $submission->id : 0; 156 157 $data = file_prepare_standard_filemanager($data, 158 'files', 159 $fileoptions, 160 $this->assignment->get_context(), 161 'assignsubmission_file', 162 ASSIGNSUBMISSION_FILE_FILEAREA, 163 $submissionid); 164 $mform->addElement('filemanager', 'files_filemanager', $this->get_name(), null, $fileoptions); 165 166 return true; 167 } 168 169 /** 170 * Count the number of files 171 * 172 * @param int $submissionid 173 * @param string $area 174 * @return int 175 */ 176 private function count_files($submissionid, $area) { 177 178 $fs = get_file_storage(); 179 $files = $fs->get_area_files($this->assignment->get_context()->id, 180 'assignsubmission_file', 181 $area, 182 $submissionid, 183 'id', 184 false); 185 186 return count($files); 187 } 188 189 /** 190 * Save the files and trigger plagiarism plugin, if enabled, 191 * to scan the uploaded files via events trigger 192 * 193 * @param stdClass $submission 194 * @param stdClass $data 195 * @return bool 196 */ 197 public function save(stdClass $submission, stdClass $data) { 198 global $USER, $DB; 199 200 $fileoptions = $this->get_file_options(); 201 202 $data = file_postupdate_standard_filemanager($data, 203 'files', 204 $fileoptions, 205 $this->assignment->get_context(), 206 'assignsubmission_file', 207 ASSIGNSUBMISSION_FILE_FILEAREA, 208 $submission->id); 209 210 $filesubmission = $this->get_file_submission($submission->id); 211 212 // Plagiarism code event trigger when files are uploaded. 213 214 $fs = get_file_storage(); 215 $files = $fs->get_area_files($this->assignment->get_context()->id, 216 'assignsubmission_file', 217 ASSIGNSUBMISSION_FILE_FILEAREA, 218 $submission->id, 219 'id', 220 false); 221 222 $count = $this->count_files($submission->id, ASSIGNSUBMISSION_FILE_FILEAREA); 223 224 $params = array( 225 'context' => context_module::instance($this->assignment->get_course_module()->id), 226 'courseid' => $this->assignment->get_course()->id, 227 'objectid' => $submission->id, 228 'other' => array( 229 'content' => '', 230 'pathnamehashes' => array_keys($files) 231 ) 232 ); 233 if (!empty($submission->userid) && ($submission->userid != $USER->id)) { 234 $params['relateduserid'] = $submission->userid; 235 } 236 $event = \assignsubmission_file\event\assessable_uploaded::create($params); 237 $event->set_legacy_files($files); 238 $event->trigger(); 239 240 $groupname = null; 241 $groupid = 0; 242 // Get the group name as other fields are not transcribed in the logs and this information is important. 243 if (empty($submission->userid) && !empty($submission->groupid)) { 244 $groupname = $DB->get_field('groups', 'name', array('id' => $submission->groupid), '*', MUST_EXIST); 245 $groupid = $submission->groupid; 246 } else { 247 $params['relateduserid'] = $submission->userid; 248 } 249 250 // Unset the objectid and other field from params for use in submission events. 251 unset($params['objectid']); 252 unset($params['other']); 253 $params['other'] = array( 254 'submissionid' => $submission->id, 255 'submissionattempt' => $submission->attemptnumber, 256 'submissionstatus' => $submission->status, 257 'filesubmissioncount' => $count, 258 'groupid' => $groupid, 259 'groupname' => $groupname 260 ); 261 262 if ($filesubmission) { 263 $filesubmission->numfiles = $this->count_files($submission->id, 264 ASSIGNSUBMISSION_FILE_FILEAREA); 265 $updatestatus = $DB->update_record('assignsubmission_file', $filesubmission); 266 $params['objectid'] = $filesubmission->id; 267 268 $event = \assignsubmission_file\event\submission_updated::create($params); 269 $event->set_assign($this->assignment); 270 $event->trigger(); 271 return $updatestatus; 272 } else { 273 $filesubmission = new stdClass(); 274 $filesubmission->numfiles = $this->count_files($submission->id, 275 ASSIGNSUBMISSION_FILE_FILEAREA); 276 $filesubmission->submission = $submission->id; 277 $filesubmission->assignment = $this->assignment->get_instance()->id; 278 $filesubmission->id = $DB->insert_record('assignsubmission_file', $filesubmission); 279 $params['objectid'] = $filesubmission->id; 280 281 $event = \assignsubmission_file\event\submission_created::create($params); 282 $event->set_assign($this->assignment); 283 $event->trigger(); 284 return $filesubmission->id > 0; 285 } 286 } 287 288 /** 289 * Produce a list of files suitable for export that represent this feedback or submission 290 * 291 * @param stdClass $submission The submission 292 * @param stdClass $user The user record - unused 293 * @return array - return an array of files indexed by filename 294 */ 295 public function get_files(stdClass $submission, stdClass $user) { 296 $result = array(); 297 $fs = get_file_storage(); 298 299 $files = $fs->get_area_files($this->assignment->get_context()->id, 300 'assignsubmission_file', 301 ASSIGNSUBMISSION_FILE_FILEAREA, 302 $submission->id, 303 'timemodified', 304 false); 305 306 foreach ($files as $file) { 307 $result[$file->get_filepath().$file->get_filename()] = $file; 308 } 309 return $result; 310 } 311 312 /** 313 * Display the list of files in the submission status table 314 * 315 * @param stdClass $submission 316 * @param bool $showviewlink Set this to true if the list of files is long 317 * @return string 318 */ 319 public function view_summary(stdClass $submission, & $showviewlink) { 320 $count = $this->count_files($submission->id, ASSIGNSUBMISSION_FILE_FILEAREA); 321 322 // Show we show a link to view all files for this plugin? 323 $showviewlink = $count > ASSIGNSUBMISSION_FILE_MAXSUMMARYFILES; 324 if ($count <= ASSIGNSUBMISSION_FILE_MAXSUMMARYFILES) { 325 return $this->assignment->render_area_files('assignsubmission_file', 326 ASSIGNSUBMISSION_FILE_FILEAREA, 327 $submission->id); 328 } else { 329 return get_string('countfiles', 'assignsubmission_file', $count); 330 } 331 } 332 333 /** 334 * No full submission view - the summary contains the list of files and that is the whole submission 335 * 336 * @param stdClass $submission 337 * @return string 338 */ 339 public function view(stdClass $submission) { 340 return $this->assignment->render_area_files('assignsubmission_file', 341 ASSIGNSUBMISSION_FILE_FILEAREA, 342 $submission->id); 343 } 344 345 346 347 /** 348 * Return true if this plugin can upgrade an old Moodle 2.2 assignment of this type 349 * and version. 350 * 351 * @param string $type 352 * @param int $version 353 * @return bool True if upgrade is possible 354 */ 355 public function can_upgrade($type, $version) { 356 357 $uploadsingletype ='uploadsingle'; 358 $uploadtype ='upload'; 359 360 if (($type == $uploadsingletype || $type == $uploadtype) && $version >= 2011112900) { 361 return true; 362 } 363 return false; 364 } 365 366 367 /** 368 * Upgrade the settings from the old assignment 369 * to the new plugin based one 370 * 371 * @param context $oldcontext - the old assignment context 372 * @param stdClass $oldassignment - the old assignment data record 373 * @param string $log record log events here 374 * @return bool Was it a success? (false will trigger rollback) 375 */ 376 public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) { 377 global $DB; 378 379 if ($oldassignment->assignmenttype == 'uploadsingle') { 380 $this->set_config('maxfilesubmissions', 1); 381 $this->set_config('maxsubmissionsizebytes', $oldassignment->maxbytes); 382 return true; 383 } else if ($oldassignment->assignmenttype == 'upload') { 384 $this->set_config('maxfilesubmissions', $oldassignment->var1); 385 $this->set_config('maxsubmissionsizebytes', $oldassignment->maxbytes); 386 387 // Advanced file upload uses a different setting to do the same thing. 388 $DB->set_field('assign', 389 'submissiondrafts', 390 $oldassignment->var4, 391 array('id'=>$this->assignment->get_instance()->id)); 392 393 // Convert advanced file upload "hide description before due date" setting. 394 $alwaysshow = 0; 395 if (!$oldassignment->var3) { 396 $alwaysshow = 1; 397 } 398 $DB->set_field('assign', 399 'alwaysshowdescription', 400 $alwaysshow, 401 array('id'=>$this->assignment->get_instance()->id)); 402 return true; 403 } 404 } 405 406 /** 407 * Upgrade the submission from the old assignment to the new one 408 * 409 * @param context $oldcontext The context of the old assignment 410 * @param stdClass $oldassignment The data record for the old oldassignment 411 * @param stdClass $oldsubmission The data record for the old submission 412 * @param stdClass $submission The data record for the new submission 413 * @param string $log Record upgrade messages in the log 414 * @return bool true or false - false will trigger a rollback 415 */ 416 public function upgrade(context $oldcontext, 417 stdClass $oldassignment, 418 stdClass $oldsubmission, 419 stdClass $submission, 420 & $log) { 421 global $DB; 422 423 $filesubmission = new stdClass(); 424 425 $filesubmission->numfiles = $oldsubmission->numfiles; 426 $filesubmission->submission = $submission->id; 427 $filesubmission->assignment = $this->assignment->get_instance()->id; 428 429 if (!$DB->insert_record('assignsubmission_file', $filesubmission) > 0) { 430 $log .= get_string('couldnotconvertsubmission', 'mod_assign', $submission->userid); 431 return false; 432 } 433 434 // Now copy the area files. 435 $this->assignment->copy_area_files_for_upgrade($oldcontext->id, 436 'mod_assignment', 437 'submission', 438 $oldsubmission->id, 439 $this->assignment->get_context()->id, 440 'assignsubmission_file', 441 ASSIGNSUBMISSION_FILE_FILEAREA, 442 $submission->id); 443 444 return true; 445 } 446 447 /** 448 * The assignment has been deleted - cleanup 449 * 450 * @return bool 451 */ 452 public function delete_instance() { 453 global $DB; 454 // Will throw exception on failure. 455 $DB->delete_records('assignsubmission_file', 456 array('assignment'=>$this->assignment->get_instance()->id)); 457 458 return true; 459 } 460 461 /** 462 * Formatting for log info 463 * 464 * @param stdClass $submission The submission 465 * @return string 466 */ 467 public function format_for_log(stdClass $submission) { 468 // Format the info for each submission plugin (will be added to log). 469 $filecount = $this->count_files($submission->id, ASSIGNSUBMISSION_FILE_FILEAREA); 470 471 return get_string('numfilesforlog', 'assignsubmission_file', $filecount); 472 } 473 474 /** 475 * Return true if there are no submission files 476 * @param stdClass $submission 477 */ 478 public function is_empty(stdClass $submission) { 479 return $this->count_files($submission->id, ASSIGNSUBMISSION_FILE_FILEAREA) == 0; 480 } 481 482 /** 483 * Determine if a submission is empty 484 * 485 * This is distinct from is_empty in that it is intended to be used to 486 * determine if a submission made before saving is empty. 487 * 488 * @param stdClass $data The submission data 489 * @return bool 490 */ 491 public function submission_is_empty(stdClass $data) { 492 $files = file_get_drafarea_files($data->files_filemanager); 493 return count($files->list) == 0; 494 } 495 496 /** 497 * Get file areas returns a list of areas this plugin stores files 498 * @return array - An array of fileareas (keys) and descriptions (values) 499 */ 500 public function get_file_areas() { 501 return array(ASSIGNSUBMISSION_FILE_FILEAREA=>$this->get_name()); 502 } 503 504 /** 505 * Copy the student's submission from a previous submission. Used when a student opts to base their resubmission 506 * on the last submission. 507 * @param stdClass $sourcesubmission 508 * @param stdClass $destsubmission 509 */ 510 public function copy_submission(stdClass $sourcesubmission, stdClass $destsubmission) { 511 global $DB; 512 513 // Copy the files across. 514 $contextid = $this->assignment->get_context()->id; 515 $fs = get_file_storage(); 516 $files = $fs->get_area_files($contextid, 517 'assignsubmission_file', 518 ASSIGNSUBMISSION_FILE_FILEAREA, 519 $sourcesubmission->id, 520 'id', 521 false); 522 foreach ($files as $file) { 523 $fieldupdates = array('itemid' => $destsubmission->id); 524 $fs->create_file_from_storedfile($fieldupdates, $file); 525 } 526 527 // Copy the assignsubmission_file record. 528 if ($filesubmission = $this->get_file_submission($sourcesubmission->id)) { 529 unset($filesubmission->id); 530 $filesubmission->submission = $destsubmission->id; 531 $DB->insert_record('assignsubmission_file', $filesubmission); 532 } 533 return true; 534 } 535 536 /** 537 * Return a description of external params suitable for uploading a file submission from a webservice. 538 * 539 * @return external_description|null 540 */ 541 public function get_external_parameters() { 542 return array( 543 'files_filemanager' => new external_value( 544 PARAM_INT, 545 'The id of a draft area containing files for this submission.', 546 VALUE_OPTIONAL 547 ) 548 ); 549 } 550 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |