[ Index ] |
PHP Cross Reference of moodle-2.8 |
[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 feedback plugin 19 * 20 * 21 * @package assignfeedback_file 22 * @copyright 2012 NetSpot {@link http://www.netspot.com.au} 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 // File areas for file feedback assignment. 29 define('ASSIGNFEEDBACK_FILE_FILEAREA', 'feedback_files'); 30 define('ASSIGNFEEDBACK_FILE_BATCH_FILEAREA', 'feedback_files_batch'); 31 define('ASSIGNFEEDBACK_FILE_IMPORT_FILEAREA', 'feedback_files_import'); 32 define('ASSIGNFEEDBACK_FILE_MAXSUMMARYFILES', 5); 33 define('ASSIGNFEEDBACK_FILE_MAXSUMMARYUSERS', 5); 34 define('ASSIGNFEEDBACK_FILE_MAXFILEUNZIPTIME', 120); 35 36 /** 37 * Library class for file feedback plugin extending feedback plugin base class. 38 * 39 * @package assignfeedback_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_feedback_file extends assign_feedback_plugin { 44 45 /** 46 * Get the name of the file feedback plugin. 47 * 48 * @return string 49 */ 50 public function get_name() { 51 return get_string('file', 'assignfeedback_file'); 52 } 53 54 /** 55 * Get file feedback information from the database. 56 * 57 * @param int $gradeid 58 * @return mixed 59 */ 60 public function get_file_feedback($gradeid) { 61 global $DB; 62 return $DB->get_record('assignfeedback_file', array('grade'=>$gradeid)); 63 } 64 65 /** 66 * File format options. 67 * 68 * @return array 69 */ 70 private function get_file_options() { 71 global $COURSE; 72 73 $fileoptions = array('subdirs'=>1, 74 'maxbytes'=>$COURSE->maxbytes, 75 'accepted_types'=>'*', 76 'return_types'=>FILE_INTERNAL); 77 return $fileoptions; 78 } 79 80 /** 81 * Copy all the files from one file area to another. 82 * 83 * @param file_storage $fs - The source context id 84 * @param int $fromcontextid - The source context id 85 * @param string $fromcomponent - The source component 86 * @param string $fromfilearea - The source filearea 87 * @param int $fromitemid - The source item id 88 * @param int $tocontextid - The destination context id 89 * @param string $tocomponent - The destination component 90 * @param string $tofilearea - The destination filearea 91 * @param int $toitemid - The destination item id 92 * @return boolean 93 */ 94 private function copy_area_files(file_storage $fs, 95 $fromcontextid, 96 $fromcomponent, 97 $fromfilearea, 98 $fromitemid, 99 $tocontextid, 100 $tocomponent, 101 $tofilearea, 102 $toitemid) { 103 104 $newfilerecord = new stdClass(); 105 $newfilerecord->contextid = $tocontextid; 106 $newfilerecord->component = $tocomponent; 107 $newfilerecord->filearea = $tofilearea; 108 $newfilerecord->itemid = $toitemid; 109 110 if ($files = $fs->get_area_files($fromcontextid, $fromcomponent, $fromfilearea, $fromitemid)) { 111 foreach ($files as $file) { 112 if ($file->is_directory() and $file->get_filepath() === '/') { 113 // We need a way to mark the age of each draft area. 114 // By not copying the root dir we force it to be created 115 // automatically with current timestamp. 116 continue; 117 } 118 $newfile = $fs->create_file_from_storedfile($newfilerecord, $file); 119 } 120 } 121 return true; 122 } 123 124 /** 125 * Get form elements for grading form. 126 * 127 * @param stdClass $grade 128 * @param MoodleQuickForm $mform 129 * @param stdClass $data 130 * @param int $userid The userid we are currently grading 131 * @return bool true if elements were added to the form 132 */ 133 public function get_form_elements_for_user($grade, MoodleQuickForm $mform, stdClass $data, $userid) { 134 135 $fileoptions = $this->get_file_options(); 136 $gradeid = $grade ? $grade->id : 0; 137 $elementname = 'files_' . $userid; 138 139 $data = file_prepare_standard_filemanager($data, 140 $elementname, 141 $fileoptions, 142 $this->assignment->get_context(), 143 'assignfeedback_file', 144 ASSIGNFEEDBACK_FILE_FILEAREA, 145 $gradeid); 146 $mform->addElement('filemanager', $elementname . '_filemanager', $this->get_name(), null, $fileoptions); 147 148 return true; 149 } 150 151 /** 152 * Count the number of files. 153 * 154 * @param int $gradeid 155 * @param string $area 156 * @return int 157 */ 158 private function count_files($gradeid, $area) { 159 160 $fs = get_file_storage(); 161 $files = $fs->get_area_files($this->assignment->get_context()->id, 162 'assignfeedback_file', 163 $area, 164 $gradeid, 165 'id', 166 false); 167 168 return count($files); 169 } 170 171 /** 172 * Update the number of files in the file area. 173 * 174 * @param stdClass $grade The grade record 175 * @return bool - true if the value was saved 176 */ 177 public function update_file_count($grade) { 178 global $DB; 179 180 $filefeedback = $this->get_file_feedback($grade->id); 181 if ($filefeedback) { 182 $filefeedback->numfiles = $this->count_files($grade->id, ASSIGNFEEDBACK_FILE_FILEAREA); 183 return $DB->update_record('assignfeedback_file', $filefeedback); 184 } else { 185 $filefeedback = new stdClass(); 186 $filefeedback->numfiles = $this->count_files($grade->id, ASSIGNFEEDBACK_FILE_FILEAREA); 187 $filefeedback->grade = $grade->id; 188 $filefeedback->assignment = $this->assignment->get_instance()->id; 189 return $DB->insert_record('assignfeedback_file', $filefeedback) > 0; 190 } 191 } 192 193 /** 194 * Save the feedback files. 195 * 196 * @param stdClass $grade 197 * @param stdClass $data 198 * @return bool 199 */ 200 public function save(stdClass $grade, stdClass $data) { 201 $fileoptions = $this->get_file_options(); 202 203 // The element name may have been for a different user. 204 foreach ($data as $key => $value) { 205 if (strpos($key, 'files_') === 0 && strpos($key, '_filemanager')) { 206 $elementname = substr($key, 0, strpos($key, '_filemanager')); 207 } 208 } 209 210 $data = file_postupdate_standard_filemanager($data, 211 $elementname, 212 $fileoptions, 213 $this->assignment->get_context(), 214 'assignfeedback_file', 215 ASSIGNFEEDBACK_FILE_FILEAREA, 216 $grade->id); 217 218 return $this->update_file_count($grade); 219 } 220 221 /** 222 * Display the list of files in the feedback status table. 223 * 224 * @param stdClass $grade 225 * @param bool $showviewlink - Set to true to show a link to see the full list of files 226 * @return string 227 */ 228 public function view_summary(stdClass $grade, & $showviewlink) { 229 230 $count = $this->count_files($grade->id, ASSIGNFEEDBACK_FILE_FILEAREA); 231 232 // Show a view all link if the number of files is over this limit. 233 $showviewlink = $count > ASSIGNFEEDBACK_FILE_MAXSUMMARYFILES; 234 235 if ($count <= ASSIGNFEEDBACK_FILE_MAXSUMMARYFILES) { 236 return $this->assignment->render_area_files('assignfeedback_file', 237 ASSIGNFEEDBACK_FILE_FILEAREA, 238 $grade->id); 239 } else { 240 return get_string('countfiles', 'assignfeedback_file', $count); 241 } 242 } 243 244 /** 245 * Display the list of files in the feedback status table. 246 * 247 * @param stdClass $grade 248 * @return string 249 */ 250 public function view(stdClass $grade) { 251 return $this->assignment->render_area_files('assignfeedback_file', 252 ASSIGNFEEDBACK_FILE_FILEAREA, 253 $grade->id); 254 } 255 256 /** 257 * The assignment has been deleted - cleanup. 258 * 259 * @return bool 260 */ 261 public function delete_instance() { 262 global $DB; 263 // Will throw exception on failure. 264 $DB->delete_records('assignfeedback_file', 265 array('assignment'=>$this->assignment->get_instance()->id)); 266 267 return true; 268 } 269 270 /** 271 * Return true if there are no feedback files. 272 * 273 * @param stdClass $grade 274 */ 275 public function is_empty(stdClass $grade) { 276 return $this->count_files($grade->id, ASSIGNFEEDBACK_FILE_FILEAREA) == 0; 277 } 278 279 /** 280 * Get file areas returns a list of areas this plugin stores files. 281 * 282 * @return array - An array of fileareas (keys) and descriptions (values) 283 */ 284 public function get_file_areas() { 285 return array(ASSIGNFEEDBACK_FILE_FILEAREA=>$this->get_name()); 286 } 287 288 /** 289 * Return true if this plugin can upgrade an old Moodle 2.2 assignment of this type 290 * and version. 291 * 292 * @param string $type old assignment subtype 293 * @param int $version old assignment version 294 * @return bool True if upgrade is possible 295 */ 296 public function can_upgrade($type, $version) { 297 if (($type == 'upload' || $type == 'uploadsingle') && $version >= 2011112900) { 298 return true; 299 } 300 return false; 301 } 302 303 /** 304 * Upgrade the settings from the old assignment to the new plugin based one. 305 * 306 * @param context $oldcontext - the context for the old assignment 307 * @param stdClass $oldassignment - the data for the old assignment 308 * @param string $log - can be appended to by the upgrade 309 * @return bool was it a success? (false will trigger a rollback) 310 */ 311 public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) { 312 // First upgrade settings (nothing to do). 313 return true; 314 } 315 316 /** 317 * Upgrade the feedback from the old assignment to the new one. 318 * 319 * @param context $oldcontext - the database for the old assignment context 320 * @param stdClass $oldassignment The data record for the old assignment 321 * @param stdClass $oldsubmission The data record for the old submission 322 * @param stdClass $grade The data record for the new grade 323 * @param string $log Record upgrade messages in the log 324 * @return bool true or false - false will trigger a rollback 325 */ 326 public function upgrade(context $oldcontext, 327 stdClass $oldassignment, 328 stdClass $oldsubmission, 329 stdClass $grade, 330 & $log) { 331 global $DB; 332 333 // Now copy the area files. 334 $this->assignment->copy_area_files_for_upgrade($oldcontext->id, 335 'mod_assignment', 336 'response', 337 $oldsubmission->id, 338 $this->assignment->get_context()->id, 339 'assignfeedback_file', 340 ASSIGNFEEDBACK_FILE_FILEAREA, 341 $grade->id); 342 343 // Now count them! 344 $filefeedback = new stdClass(); 345 $filefeedback->numfiles = $this->count_files($grade->id, ASSIGNFEEDBACK_FILE_FILEAREA); 346 $filefeedback->grade = $grade->id; 347 $filefeedback->assignment = $this->assignment->get_instance()->id; 348 if (!$DB->insert_record('assignfeedback_file', $filefeedback) > 0) { 349 $log .= get_string('couldnotconvertgrade', 'mod_assign', $grade->userid); 350 return false; 351 } 352 return true; 353 } 354 355 /** 356 * Return a list of the batch grading operations performed by this plugin. 357 * This plugin supports batch upload files and upload zip. 358 * 359 * @return array The list of batch grading operations 360 */ 361 public function get_grading_batch_operations() { 362 return array('uploadfiles'=>get_string('uploadfiles', 'assignfeedback_file')); 363 } 364 365 /** 366 * Upload files and send them to multiple users. 367 * 368 * @param array $users - An array of user ids 369 * @return string - The response html 370 */ 371 public function view_batch_upload_files($users) { 372 global $CFG, $DB, $USER; 373 374 require_capability('mod/assign:grade', $this->assignment->get_context()); 375 require_once($CFG->dirroot . '/mod/assign/feedback/file/batchuploadfilesform.php'); 376 require_once($CFG->dirroot . '/mod/assign/renderable.php'); 377 378 $formparams = array('cm'=>$this->assignment->get_course_module()->id, 379 'users'=>$users, 380 'context'=>$this->assignment->get_context()); 381 382 $usershtml = ''; 383 384 $usercount = 0; 385 foreach ($users as $userid) { 386 if ($usercount >= ASSIGNFEEDBACK_FILE_MAXSUMMARYUSERS) { 387 $moreuserscount = count($users) - ASSIGNFEEDBACK_FILE_MAXSUMMARYUSERS; 388 $usershtml .= get_string('moreusers', 'assignfeedback_file', $moreuserscount); 389 break; 390 } 391 $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST); 392 393 $usersummary = new assign_user_summary($user, 394 $this->assignment->get_course()->id, 395 has_capability('moodle/site:viewfullnames', 396 $this->assignment->get_course_context()), 397 $this->assignment->is_blind_marking(), 398 $this->assignment->get_uniqueid_for_user($user->id), 399 get_extra_user_fields($this->assignment->get_context())); 400 $usershtml .= $this->assignment->get_renderer()->render($usersummary); 401 $usercount += 1; 402 } 403 404 $formparams['usershtml'] = $usershtml; 405 406 $mform = new assignfeedback_file_batch_upload_files_form(null, $formparams); 407 408 if ($mform->is_cancelled()) { 409 redirect(new moodle_url('view.php', 410 array('id'=>$this->assignment->get_course_module()->id, 411 'action'=>'grading'))); 412 return; 413 } else if ($data = $mform->get_data()) { 414 // Copy the files from the draft area to a temporary import area. 415 $data = file_postupdate_standard_filemanager($data, 416 'files', 417 $this->get_file_options(), 418 $this->assignment->get_context(), 419 'assignfeedback_file', 420 ASSIGNFEEDBACK_FILE_BATCH_FILEAREA, 421 $USER->id); 422 $fs = get_file_storage(); 423 424 // Now copy each of these files to the users feedback file area. 425 foreach ($users as $userid) { 426 $grade = $this->assignment->get_user_grade($userid, true); 427 $this->assignment->notify_grade_modified($grade); 428 429 $this->copy_area_files($fs, 430 $this->assignment->get_context()->id, 431 'assignfeedback_file', 432 ASSIGNFEEDBACK_FILE_BATCH_FILEAREA, 433 $USER->id, 434 $this->assignment->get_context()->id, 435 'assignfeedback_file', 436 ASSIGNFEEDBACK_FILE_FILEAREA, 437 $grade->id); 438 439 $filefeedback = $this->get_file_feedback($grade->id); 440 if ($filefeedback) { 441 $filefeedback->numfiles = $this->count_files($grade->id, 442 ASSIGNFEEDBACK_FILE_FILEAREA); 443 $DB->update_record('assignfeedback_file', $filefeedback); 444 } else { 445 $filefeedback = new stdClass(); 446 $filefeedback->numfiles = $this->count_files($grade->id, 447 ASSIGNFEEDBACK_FILE_FILEAREA); 448 $filefeedback->grade = $grade->id; 449 $filefeedback->assignment = $this->assignment->get_instance()->id; 450 $DB->insert_record('assignfeedback_file', $filefeedback); 451 } 452 } 453 454 // Now delete the temporary import area. 455 $fs->delete_area_files($this->assignment->get_context()->id, 456 'assignfeedback_file', 457 ASSIGNFEEDBACK_FILE_BATCH_FILEAREA, 458 $USER->id); 459 460 redirect(new moodle_url('view.php', 461 array('id'=>$this->assignment->get_course_module()->id, 462 'action'=>'grading'))); 463 return; 464 } else { 465 466 $header = new assign_header($this->assignment->get_instance(), 467 $this->assignment->get_context(), 468 false, 469 $this->assignment->get_course_module()->id, 470 get_string('batchuploadfiles', 'assignfeedback_file')); 471 $o = ''; 472 $o .= $this->assignment->get_renderer()->render($header); 473 $o .= $this->assignment->get_renderer()->render(new assign_form('batchuploadfiles', $mform)); 474 $o .= $this->assignment->get_renderer()->render_footer(); 475 } 476 477 return $o; 478 } 479 480 /** 481 * User has chosen a custom grading batch operation and selected some users. 482 * 483 * @param string $action - The chosen action 484 * @param array $users - An array of user ids 485 * @return string - The response html 486 */ 487 public function grading_batch_operation($action, $users) { 488 489 if ($action == 'uploadfiles') { 490 return $this->view_batch_upload_files($users); 491 } 492 return ''; 493 } 494 495 /** 496 * View the upload zip form. 497 * 498 * @return string - The html response 499 */ 500 public function view_upload_zip() { 501 global $CFG, $USER; 502 503 require_capability('mod/assign:grade', $this->assignment->get_context()); 504 require_once($CFG->dirroot . '/mod/assign/feedback/file/uploadzipform.php'); 505 require_once($CFG->dirroot . '/mod/assign/feedback/file/importziplib.php'); 506 require_once($CFG->dirroot . '/mod/assign/feedback/file/importzipform.php'); 507 508 $formparams = array('context'=>$this->assignment->get_context(), 509 'cm'=>$this->assignment->get_course_module()->id); 510 $mform = new assignfeedback_file_upload_zip_form(null, $formparams); 511 512 $o = ''; 513 514 $confirm = optional_param('confirm', 0, PARAM_BOOL); 515 $renderer = $this->assignment->get_renderer(); 516 517 // Delete any existing files. 518 $importer = new assignfeedback_file_zip_importer(); 519 $contextid = $this->assignment->get_context()->id; 520 521 if ($mform->is_cancelled()) { 522 $importer->delete_import_files($contextid); 523 $urlparams = array('id'=>$this->assignment->get_course_module()->id, 524 'action'=>'grading'); 525 $url = new moodle_url('view.php', $urlparams); 526 redirect($url); 527 return; 528 } else if ($confirm) { 529 $params = array('assignment'=>$this->assignment, 'importer'=>$importer); 530 531 $mform = new assignfeedback_file_import_zip_form(null, $params); 532 if ($mform->is_cancelled()) { 533 $importer->delete_import_files($contextid); 534 $urlparams = array('id'=>$this->assignment->get_course_module()->id, 535 'action'=>'grading'); 536 $url = new moodle_url('view.php', $urlparams); 537 redirect($url); 538 return; 539 } 540 541 $o .= $importer->import_zip_files($this->assignment, $this); 542 $importer->delete_import_files($contextid); 543 } else if (($data = $mform->get_data()) && 544 ($zipfile = $mform->save_stored_file('feedbackzip', 545 $contextid, 546 'assignfeedback_file', 547 ASSIGNFEEDBACK_FILE_IMPORT_FILEAREA, 548 $USER->id, 549 '/', 550 'import.zip', 551 true))) { 552 553 $importer->extract_files_from_zip($zipfile, $contextid); 554 555 $params = array('assignment'=>$this->assignment, 'importer'=>$importer); 556 557 $mform = new assignfeedback_file_import_zip_form(null, $params); 558 559 $header = new assign_header($this->assignment->get_instance(), 560 $this->assignment->get_context(), 561 false, 562 $this->assignment->get_course_module()->id, 563 get_string('confirmuploadzip', 'assignfeedback_file')); 564 $o .= $renderer->render($header); 565 $o .= $renderer->render(new assign_form('confirmimportzip', $mform)); 566 $o .= $renderer->render_footer(); 567 568 } else { 569 570 $header = new assign_header($this->assignment->get_instance(), 571 $this->assignment->get_context(), 572 false, 573 $this->assignment->get_course_module()->id, 574 get_string('uploadzip', 'assignfeedback_file')); 575 $o .= $renderer->render($header); 576 $o .= $renderer->render(new assign_form('uploadfeedbackzip', $mform)); 577 $o .= $renderer->render_footer(); 578 } 579 580 return $o; 581 } 582 583 /** 584 * Called by the assignment module when someone chooses something from the 585 * grading navigation or batch operations list. 586 * 587 * @param string $action - The page to view 588 * @return string - The html response 589 */ 590 public function view_page($action) { 591 if ($action == 'uploadfiles') { 592 $users = required_param('selectedusers', PARAM_SEQUENCE); 593 return $this->view_batch_upload_files(explode(',', $users)); 594 } 595 if ($action == 'uploadzip') { 596 return $this->view_upload_zip(); 597 } 598 599 return ''; 600 } 601 602 /** 603 * Return a list of the grading actions performed by this plugin. 604 * This plugin supports upload zip. 605 * 606 * @return array The list of grading actions 607 */ 608 public function get_grading_actions() { 609 return array('uploadzip'=>get_string('uploadzip', 'assignfeedback_file')); 610 } 611 612 /** 613 * Return a description of external params suitable for uploading a feedback file from a webservice. 614 * 615 * @return external_description|null 616 */ 617 public function get_external_parameters() { 618 return array( 619 'files_filemanager' => new external_value( 620 PARAM_INT, 621 'The id of a draft area containing files for this feedback.' 622 ) 623 ); 624 } 625 626 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |