Fixed a capability name: MDL-6727
[moodle.git] / mod / assignment / type / upload / assignment.class.php
CommitLineData
fcdcc372 1<?php // $Id$
2
3/**
4 * Extend the base assignment class for assignments where you upload one or more files and where teacher can upload one or more response files
5 *
6 */
6fc73d59 7
8 /*
9 *defining constants for status indicators
10 */
11
12 //submissionstatusblank
13 define('BLANK', 'Blank');
14
15 //submissionstatussubmitted
16 define('SUBMITTED', 'Submitted');
17
18 //submissionstatusgraded
19 define('GRADED', 'Graded');
20
21 //submissionstatusreturned
22 define('RETURNED', 'Returned');
23 /***********************************************************************
24* CUSTOM SQL
25************************************************************************/
26 function display_submissions_sql($table, $users, $assignmentID) {
27 global $CFG, $USER;
28
29 if ($where = $table->get_sql_where()) {
30 $where .= ' AND ';
31 }
32
33 if ($sort = $table->get_sql_sort()) {
34 $sort = ' ORDER BY '.$sort;
35 }
36
37 /*
38 *select has been modified. because we also need to get student
39 *id & assignment status == upload_status = {Draft,
40 *Submitted, Marked, Returned}
41 */
42 $select = 'SELECT u.id, u.id, u.firstname, u.lastname, u.picture, u.idnumber, s.id AS submissionid, s.grade, s.comment, s.timemodified, s.timemarked, ((s.timemarked > 0) AND (s.timemarked >= s.timemodified)) AS status, s.data1 as upload_status ';
43
44 $sql = 'FROM '.$CFG->prefix.'user u '.
45 'LEFT JOIN '.$CFG->prefix.'assignment_submissions s ON u.id = s.userid AND s.assignment = '.$assignmentID.' '.
46 'WHERE '.$where.'u.id IN ('.implode(',', array_keys($users)).') ';
47
48
49
50 if($table->get_page_start() !== '' && $table->get_page_size() !== '') {
51 $limit = ' '.sql_paging_limit($table->get_page_start(), $table->get_page_size());
52 }
53 else {
54 $limit = '';
55 }
56 $temp = $select.$sql.$sort.$limit;
57
58 return $temp;
59 } // end function display_submissions_sql()
60
61 function next_student_sql($assignmentID, $users) {
62 global $CFG, $offset;
63 $select = 'SELECT u.id, u.id, u.firstname, u.lastname, u.picture,'.
64 's.id AS submissionid, s.grade, s.comment, s.timemodified, s.timemarked, ((s.timemarked > 0) AND (s.timemarked >= s.timemodified)) AS status ';
65 $sql = 'FROM '.$CFG->prefix.'user u '.
66 'LEFT JOIN '.$CFG->prefix.'assignment_submissions s ON u.id = s.userid AND s.assignment = '.$assignmentID.' '.
67 'WHERE u.id IN ('.implode(',', array_keys($users)).') AND s.data1 <> "Draft" AND s.data1 <> ""';
68 //we don't need to grade drafts or empty assignments
69
70 require_once($CFG->libdir.'/tablelib.php');
71 if($sort = flexible_table::get_sql_sort('mod-assignment-submissions')) {
72 $sort = 'ORDER BY '.$sort.' ';
73 }
74
75 $limit = sql_paging_limit($offset+1, 1);
76
77 $temp = $select.$sql.$sort.$limit;
78 return $temp;
79
80 }
81
82/***********************************************************************
83* END CUSTOM SQL
84************************************************************************/
fcdcc372 85class assignment_upload extends assignment_base {
6fc73d59 86
fcdcc372 87 function print_student_answer($userid, $return=false){
88 global $CFG, $USER;
fcdcc372 89
6fc73d59 90 $filearea = $this->file_area_name($userid);
fcdcc372 91 $output = '';
6fc73d59 92
fcdcc372 93 if ($basedir = $this->file_area($userid)) {
94 if ($files = get_directory_list($basedir)) {
95 require_once($CFG->libdir.'/filelib.php');
96 foreach ($files as $key => $file) {
6fc73d59 97
fcdcc372 98 $icon = mimeinfo('icon', $file);
6fc73d59 99
fcdcc372 100 if ($CFG->slasharguments) {
6fc73d59 101 $ffurl = "{$CFG->wwwroot}/file.php/$filearea/$file";
102 }
103 else {
104 $ffurl = "{$CFG->wwwroot}/file.php/$filearea/$file";
fcdcc372 105 }
fcdcc372 106 $output .= '<img align="middle" src="'.$CFG->pixpath.'/f/'.$icon.'" height="16" width="16" alt="'.$icon.'" />'.
107 '<a href="'.$ffurl.'" >'.$file.'</a><br />';
108 }
109 }
110 }
111
112 $output = '<div class="files">'.$output.'</div>';
6fc73d59 113 return $output;
fcdcc372 114 }
115
116 function assignment_upload($cmid=0) {
117 parent::assignment_base($cmid);
fcdcc372 118 }
119
120 //generates page for file upload, list of uploaded files, feedbacks from teachers, etc
121 function view() {
fcdcc372 122 global $USER;
123
6fc73d59 124 require_login($this->course->id, false, $cm);
fcdcc372 125
6fc73d59 126 // Guests are not allowed to view student's or teacher's assignment information.
127 if (isguest($USER->id)) {
128 error(get_string('usererror', 'assignment'));
129 }
130 else if (isteacher($this->course->id, $USER->id, true) or isstudent($this->course->id, $USER->id)) {
fcdcc372 131
6fc73d59 132 $this->view_header();
133 $this->view_intro();
134 $this->view_dates();
fcdcc372 135
6fc73d59 136 $filecount = $this->count_user_files($USER->id);
fcdcc372 137
6fc73d59 138 //prints students draft and final uploads
139 if ($submission = $this->get_submission()) {
140 if ($submission->timemarked == true) {
141 print_simple_box($this->print_user_files($USER->id, true), 'center');
142 $this->view_feedback();
143 }
144 else if ($filecount >= 0) {
145 print_simple_box($this->print_user_files($USER->id, true), 'center');
146 }
147
148 // data2 = holds teacher's id for teacher responses
149 if ($submission->data2 != NULL) {
150 print_heading(get_string('responsesfromteacher', 'assignment'));
151 $this->print_response_students(true);
152 }
fcdcc372 153 }
6fc73d59 154
155 //display Blank if there were no files uploaded yet, otherwise display submission status
156 //if there are no more files uploaded, $submission_status should be blank.
157 if ($submission->numfiles == 0) {
158 $submission_status = get_string('submissionstatusblank','assignment');
159 }
160 else {
161 // data1 = submission status of the submitted assignment.
162 if($submission->data1 == GRADED) {
163 $submission_status = get_string('submissionstatusgraded','assignment');
164 }else {
165 $submission_status = $submission->data1;
166 }
fcdcc372 167 }
fcdcc372 168
fcdcc372 169
6fc73d59 170 //display submission status
171 notify("<b>".get_string('submissionstatus', 'assignment').":" . " </b> ". $submission_status);
172
173 //checks to see if files are of submitted status or not
174 //checks if the file is part of multiple file uploading
175 //and that it is of returned status
176 //checks if the file is of graded status
177 //checks again to see if file is of returned status
178 //checks if the teacher has graded the assignment.
179 //will allow users to see the file uploading page.
180 /*
181 *var1 indicates that multiple file upload is active(1 active, 0 off).
182 */
183
184 if ($submission->data1 != SUBMITTED && $this->isopen() &&
185 ((!$this->assignment->var1 && $submission->data1 == RETURNED) ||
186 !$filecount ||
187 ($this->assignment->resubmit && $submission->data1 == GRADED) ||
188 $submission->data1 == RETURNED ||
189 !$submission->timemarked)
190 ) {
191 $this->view_upload_form();
192 }
193 $this->view_footer();
194
38ac07d2 195 }
6fc73d59 196
fcdcc372 197 }
198
199 function view_upload_form() {
200 global $CFG;
6fc73d59 201 require_once($CFG->libdir.'/uploadlib.php');
202
203
fcdcc372 204 $struploadafile = get_string("uploadafile");
205
206 $strmaxsize = get_string("maxsize", "", display_size($this->assignment->maxbytes));
207
6fc73d59 208 // for student uploads
fcdcc372 209 echo '<center>';
6fc73d59 210 echo '<form enctype="multipart/form-data" method="post" ';
211 echo 'action="'.$CFG->wwwroot.'/mod/assignment/upload.php">';
212 echo '<p><b>'.get_string('step1','assignment').'</b>'.get_string('attachfiletoassignment','assignment')." ($strmaxsize)</p>";
fcdcc372 213 echo '<input type="hidden" name="id" value="'.$this->cm->id.'" />';
6fc73d59 214 echo '<input type="hidden" name="sesskey" value="'.sesskey().'">';
fcdcc372 215 upload_print_form_fragment(1,array('newfile'),false,null,0,$this->assignment->maxbytes,false);
6fc73d59 216
fcdcc372 217 //upload files
218 echo '<input type="submit" name="save" value="'.get_string('attachfile','assignment').'" />';
61240489 219 echo "<p><b>".get_string('step2','assignment')."</b>".get_string('submitformarking','assignment')."</p>";
6fc73d59 220
fcdcc372 221 //final submit
222 echo '<input type="submit" name="save" value="'.get_string('sendformarking','assignment').'" />';
223 echo "<p>".get_string('onceassignmentsent','assignment')."</p>";
fcdcc372 224 echo '</form>';
fcdcc372 225 echo '</center>';
226 }
227
228 //from upload&review. generates upload form for markers response
229 function view_upload_response_form($userid,$offset) {
230 global $CFG;
6fc73d59 231 require_once($CFG->libdir.'/uploadlib.php');
232
233 $userid = required_param('userid', PARAM_INT);
fcdcc372 234
6fc73d59 235 //for teacher's responses
fcdcc372 236 echo '<center>';
61240489 237 echo get_string('choosereviewfile','assignment').'<br>';
fcdcc372 238
6fc73d59 239 echo '<form enctype="multipart/form-data" method="post" ';
240 echo 'action="'.$CFG->wwwroot.'/mod/assignment/upload.php">';
fcdcc372 241 echo '<input type="hidden" name="userid" value="'.$userid.'" />';
242 echo '<input type="hidden" name="offset" value="'.$offset.'" />';
243 echo '<input type="hidden" name="id" value="'.$this->cm->id.'" />';
6fc73d59 244 echo '<input type="hidden" name="sesskey" value="'.sesskey().'">';
245 upload_print_form_fragment(1, array('newfile'), false, null, 0, $this->assignment->maxbytes, false);
fcdcc372 246 echo '<input type="submit" name="save" value="'.get_string('uploadthisfile').'" />';
247 echo '</form>';
248 echo '</center>';
249 }
250
6fc73d59 251 //general function which calls function for drafts upload, final upload, teachers response upload
fcdcc372 252 function upload(){
6fc73d59 253 global $offset, $USER;
fcdcc372 254 //if this is final submit
6fc73d59 255 if(optional_param('save', PARAM_ALPHANUM) === get_string('sendformarking','assignment')) {
256 $this->final_upload(sesskey());
257 }
258 else {
259 //if this is draft upload
260 if (optional_param('save', PARAM_ALPHANUM)==get_string('attachfile','assignment') && !$userid) {
261 $this->submission_upload(sesskey());
262 }
263 else { //if this is upload of teacher's response
264 $id = optional_param('id', '', PARAM_INT); //Course module ID
265 $a = optional_param('a', '', PARAM_INT); //Assignment ID
266 $userid = required_param('userid', PARAM_INT); //Stores student id for uploading a review file to
267
268 $this->response_upload($userid, sesskey()); // Upload files // Upload files
269 echo '<form action="submissions.php">';
270 echo '<input type="hidden" value="'.$userid.'" name="userid" />';
271 echo '<input type="hidden" value="'.$id.'" name="id" />';
272 echo '<input type="hidden" value="'.$a.'" name="a" />';
273 echo '<input type="hidden" value="single" name="mode" />';
274 echo '<input type="hidden" name="offset" value="'.$offset.'" />';
275 echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
276 echo '<center><input type="submit" value="'.get_string('feedback', 'assignment').'" name="submit"></center></form>';
277 }
278 }
fcdcc372 279 }
280
281 //implements upload regular submissuion - draft files
6fc73d59 282 function submission_upload($sesskey) {
fcdcc372 283 global $CFG, $USER, $counter;
284
6fc73d59 285 require_once($CFG->dirroot.'/lib/uploadlib.php');
fcdcc372 286
6fc73d59 287 if (!confirm_sesskey()) {
288 error('Bad Session Key');
289 }
fcdcc372 290
6fc73d59 291 //checking for teachers/students/guests of the course
292 if (isguest($USER->id)) {
293 error(get_string('guestnoupload','assignment'));
294 }
295 else if (isteacher($this->course->id, $USER->id, true) or isstudent($this->course->id, $USER->id)){
fcdcc372 296
6fc73d59 297 $course = $this->course;
298 $this->view_header(get_string('upload'));
fcdcc372 299
6fc73d59 300 $filecount = $this->count_user_files($USER->id);
301 $submission = $this->get_submission($USER->id);
fcdcc372 302
6fc73d59 303 //need to get student's directory and all previously uploaded files
304 $basedir = $this->file_area($USER->id);
305 $files = get_directory_list($basedir);
fcdcc372 306
6fc73d59 307 if ($this->isopen() ){
308 if ($submission) {
309 //TODO: change later to ">= 0", to prevent resubmission when graded 0
310 if (($submission->grade >= 0) and $this->assignment->resubmit) {
311 error(get_string('submissionerror','assignment'));
312 } else if ($submission->grade >= 0 and $this->numfiles == 0){
313 error(get_string('nofilesforsubmit', 'assignment'));
314 }
315 }
316
317 $dir = $this->file_area_name($USER->id);
318 $um = new upload_manager('newfile',!$this->assignment->var1,false,$course,false,$this->assignment->maxbytes);
319
320 if ($um->process_file_uploads($dir)) {
321 $newfile_name = $um->get_new_filename();
322 //if student already submitted something before
323 if ($submission) {
324 //assignment is not submited for marking
325 $newsubmission->timemodified = '0';
326 //$submission->timemodified = time();
327 $flag=false;
328 foreach ($files as $key => $file) {
329 if ($file == $newfile_name) {
330 $flag = true;
331 }
38ac07d2 332 }
6fc73d59 333
334 //if this is an assignment for single upload
335 if (!$this->assignment->var1) {
336 //if numfiles=1
337 if ($submission->numfiles==0 && !$flag) {
338 $submission->numfiles ++;
339 }
38ac07d2 340 }
6fc73d59 341 else {
342 //if file with the same name has not been uploaded before
343 if (!$flag) $submission->numfiles ++;
344 }
345
346 $submission->comment = addslashes($submission->comment);
347 $submission->data1 = addslashes($submission->data1);
348 unset($submission->data2); //Don't need to update.
349
350 if (update_record("assignment_submissions", $submission)) {
351 add_to_log($this->course->id, 'assignment', 'upload', 'view.php?a='.$this->assignment->id, $this->assignment->id, $this->cm->id);
352 print_heading(get_string('uploadedfile'));
353 }
354 else {
355 error(get_string("uploadfailnoupdate", "assignment"));
38ac07d2 356 }
38ac07d2 357
6fc73d59 358 //if it's first student's submission
359 }
360 else {
361 $newsubmission = $this->prepare_new_submission($USER->id);
362 //submissions has been created, but not submitted for marking
363 $newsubmission->timecreated = time();
364 $newsubmission->timemodified = '0';
365 $newsubmission->data1 = get_string("submissionstatusdraft", "assignment");
366 $newsubmission->numfiles = 1;
367 if (insert_record('assignment_submissions', $newsubmission)) {
368 add_to_log($this->course->id, 'assignment', 'upload', 'view.php?a='.$this->assignment->id, $this->assignment->id, $this->cm->id);
369 print_heading(get_string('uploadedfile'));
370 }
371 else {
372 error(get_string("uploadnotregistered", "assignment", $newfile_name) );
373 }
fcdcc372 374 }
375 }
6fc73d59 376 }
377 else {
378 error(get_string("uploaderror", "assignment")); //submitting not allowed!
fcdcc372 379 }
6fc73d59 380 print_continue('view.php?id='.$this->cm->id);
381 $this->view_footer();
fcdcc372 382 }
fcdcc372 383 }
384
385 //implements final upload (submitting for marking)
6fc73d59 386 function final_upload($sesskey) {
fcdcc372 387 global $CFG, $USER;
388
6fc73d59 389 require_once($CFG->dirroot.'/lib/uploadlib.php');
390
391 if (!confirm_sesskey()) {
392 error('Bad Session Key');
393 }
fcdcc372 394
6fc73d59 395 if (isguest($USER->id)) {
396 error(get_string('guestnoupload','assignment'));
397 }
398 else if (isteacher($this->course->id, $USER->id, true) or isstudent($this->course->id, $USER->id)) {
399 $this->view_header(get_string('upload'));
400 $filecount = $this->count_user_files($USER->id);
401 $submission = $this->get_submission($USER->id);
fcdcc372 402
6fc73d59 403 if ($this->isopen() && ($this->assignment->var1 || $filecount || $this->assignment->resubmit || !$submission->timemarked)) {
404 if ($submission) {
405 //TODO: change later to ">= 0", to prevent resubmission when graded 0
406 if (($submission->grade > 0) and $this->assignment->resubmit) {
407 error(get_string('submissionerror', 'assignment'));
408 }
fcdcc372 409 }
fcdcc372 410
6fc73d59 411 $dir = $this->file_area_name($USER->id);
412 $um = new upload_manager('newfile',!$this->assignment->var1,false,$course,false,$this->assignment->maxbytes);
fcdcc372 413
6fc73d59 414 $newfile_name = $um->get_new_filename();
fcdcc372 415
6fc73d59 416 //if student already submitted something before
417 if ($submission) {
418 if ( $submission->numfiles == 0){
419 error(get_string("nofilesforsubmit","assignment"));
420 }
421 else {
422 $submission->timemodified = time();
423 $submission->data1 = get_string("submissionstatussubmitted", "assignment");
424 if (update_record("assignment_submissions", $submission)) {
425 add_to_log($this->course->id, 'assignment', 'upload', 'view.php?a='.$this->assignment->id, $this->assignment->id, $this->cm->id);
426 }
427 else {
428 error(get_string("uploadfailnoupdate", "assignment"));
429 }
430 }
431 }
432 else {
433 error(get_string("nofilesforsubmit","assignment"));
434 }
435 }
436 else {
437 error(get_string("uploaderror", "assignment")); //submitting not allowed!
438 }
439 notify(get_string('onceassignmentsent', 'assignment'));
440 print_continue('view.php?id='.$this->cm->id);
fcdcc372 441
6fc73d59 442 $this->view_footer();
443 }
444 else {
445 error(get_string('unauthorizeduserupload', 'assignment'));
446 }
fcdcc372 447 }
448
449
6fc73d59 450 //from upload&review
fcdcc372 451 function response_file_area_name($userid, $teachid = 0) {
6fc73d59 452 //Creates a directory file name, suitable for make_upload_directory()
fcdcc372 453 global $CFG, $USER;
38ac07d2 454 $fileloc = "";
6fc73d59 455
fcdcc372 456 if ($teachid == 0) {
38ac07d2 457 $fileloc = "$USER->id/$userid";
6fc73d59 458 }
459 else {
38ac07d2 460 $fileloc = "$teachid/$USER->id";
461 }
462 return $this->course->id.'/'.$CFG->moddata.'/assignment/'.$this->assignment->id.'/responses/'.$fileloc;
fcdcc372 463 }
464
6fc73d59 465 //from upload&review
466 //make the folder which going to hold response files
467 function response_file_area($userid, $teachid = 0) {
38ac07d2 468 if ($teachid == 0) {
469 return make_upload_directory( $this->response_file_area_name($userid) );
6fc73d59 470 }
471 else {
38ac07d2 472 return make_upload_directory( $this->response_file_area_name($userid, $teachid) );
473 }
6fc73d59 474 }
fcdcc372 475
6fc73d59 476 //from upload&review
477 //upload responce file
478 function response_upload($userid, $sesskey) {
fcdcc372 479 global $CFG, $USER;
480
6fc73d59 481 require_once($CFG->dirroot.'/lib/uploadlib.php');
482
483 if (!confirm_sesskey()) {
484 error('Bad Session Key');
485 }
fcdcc372 486
487 if (!$this->isopen()) {
6fc73d59 488 error(get_string("uploadfailnoupdate", "assignment"));
489 }
490 else {
38ac07d2 491 $submission = $this->get_submission($userid);
fcdcc372 492 $dir = $this->response_file_area_name($userid);
38ac07d2 493 $um = new upload_manager('newfile',false,false,$course,false,$this->assignment->maxbytes);
fcdcc372 494
495 if ($um->process_file_uploads($dir)) {
496 $newfile_name = $um->get_new_filename();
497 if ($submission) {
6fc73d59 498 //stores teacher id's in data2 in comma-separated list so students can view all responses from all teachers
fcdcc372 499 if ($teachids = $submission->data2) {
38ac07d2 500 $teachidarr = explode(',', $teachids);
501 $teachidexists = false;
502 foreach($teachidarr as $t) {
503 if ($t == $USER->id) {
504 $teachidexists = true;
505 }
506 }
507 if ($teachidexists == false) {
508 $teachids .= ",$USER->id";
509 }
510 $submission->data2 = $teachids;
6fc73d59 511 }
512 else {
fcdcc372 513 $submission->data2 = $USER->id;
514 }
fcdcc372 515
6fc73d59 516 if (!update_record("assignment_submissions", $submission)) {
517 error(get_string("uploadfailnoupdate", "assignment"));
518 }
519 }
520 else {
521 error(get_string("studentrecorderror", "assignment"));
fcdcc372 522 }
523 notify(get_string("uploadsuccessresponse", "assignment"));
524 }
525 }
fcdcc372 526 }
527
6fc73d59 528 /*
529 *Display and process the submissions
530 */
531 function process_feedback($sesskey) {
532 global $USER;
fcdcc372 533
6fc73d59 534 if (!confirm_sesskey()) {
535 error('Bad Session Key');
fcdcc372 536 }
537
6fc73d59 538 if (!$feedback = data_submitted()) { //No incoming data?
539 return false;
fcdcc372 540 }
fcdcc372 541
fcdcc372 542 ///For save and next, we need to know the userid to save, and the userid to go...
543 ///We use a new hidden field in the form, and set it to -1. If it's set, we use this
544 ///as the userid to store...
545 //removed by Oksana. it was braking functionality and submitting teacher's feedback to.. teacher-user
6fc73d59 546 //this was inherited from upload type. check if nothing brakes???????????????
547 if ((int)$feedback->saveuserid !== -1){
fcdcc372 548 $feedback->userid = $feedback->saveuserid;
6fc73d59 549 }
550 if (!empty($feedback->cancel)) { //User hit cancel button
fcdcc372 551 return false;
552 }
6fc73d59 553
554 //Get or make a new submission
555 $newsubmission = new stdClass;
556 $newsubmission = $this->get_submission($feedback->userid, true);
61240489 557 $newsubmission->grade = $feedback->grade;
6fc73d59 558 $newsubmission->comment = $feedback->comment;
fcdcc372 559 $newsubmission->format = $feedback->format;
560 $newsubmission->teacher = $USER->id;
fcdcc372 561 $newsubmission->timemarked = time();
6fc73d59 562
563 if ($feedback->grade != -1 ) {
564 $newsubmission->data1 = get_string('submissionstatusgraded', 'assignment');
38ac07d2 565 }
566 else {
6fc73d59 567 $newsubmission->data1 = get_string('submissionstatusreturned', 'assignment');
38ac07d2 568 }
fcdcc372 569
6fc73d59 570 if (!update_record('assignment_submissions', $newsubmission)) {
fcdcc372 571 return false;
572 }
6fc73d59 573
574 add_to_log($this->course->id, 'assignment', 'update grades', 'submissions.php?id='.$this->assignment->id.'&user='.$feedback->userid, $feedback->userid, $this->cm->id);
575
576 $newsubmission->data1 = addslashes($newsubmission->data1);
577 unset($newsubmission->data2); //Don't need to update
578 $newsubmission->comment = addslashes($newsubmission->comment);
579
fcdcc372 580 return $newsubmission;
6fc73d59 581 }
582
fcdcc372 583 /*
6fc73d59 584 *Top-level function for handling of submissions called by submissions.php
fcdcc372 585 *
586 */
587 //from lib.php
588 //needed to update case of fastgrading. upgrade upload_statuses
589 function submissions($mode) {
fcdcc372 590 //make user global so we can use the id
591 global $USER;
592
6fc73d59 593 $id = required_param('id', PARAM_INT); // Course module ID
594 $userid = optional_param('userid', PARAM_INT); // User ID
595 $comment = optional_param('comment', '', PARAM_ALPHANUM); //replaced $_POST['comment']
596 $menu = optional_param('menu', '', PARAM_ALPHANUM); //replaced $_POST['menu']
597 $colum = optional_param($col, '', PARAM_ALPHANUM); //replaced $_POST['$col']
598
599 //Guests, non-studnets and non-teachers are not allowed to view student's or teacher's assignment information.
600 if (isguest($USER->id)){
601 error(get_string('unauthorizeduser', 'assignment'));
602 } else if (isstudent($this->course->id, $USER->id)){
603 error(get_string('unauthorizeduser', 'assignment'));
604 } else if (!isteacher($this->course->id, $USER->id, true)){
605 error(get_string('unauthorizeduser', 'assignment'));
606 } else {
607 if ($submission = $this->get_submission()) {
608 if ($submission->timemarked == true) {
609 print_simple_box($this->print_user_files($USER->id, true), 'center');
610 $this->view_feedback();
fcdcc372 611 }
6fc73d59 612 else if ($filecount >= 0) {
613 print_simple_box($this->print_user_files($USER->id, true), 'center');
fcdcc372 614 }
6fc73d59 615 if ($submission->data2 != NULL) {
616 print_heading(get_string('responsesfromteacher', 'assignment'));
617 $this->print_response_students(true);
fcdcc372 618 }
6fc73d59 619 }
fcdcc372 620
6fc73d59 621 switch ($mode) {
622 case 'grade':
623 //We are in a popup window grading
624 if ($submission = $this->process_feedback(sesskey())) {
625 print_header(get_string('feedback', 'assignment').':'.format_string($this->assignment->name));
626 print_heading(get_string('changessaved'));
627 $this->update_main_listing($submission);
fcdcc372 628 }
6fc73d59 629 close_window();
630 break;
631
632 case 'single':
633 //We are in a popup window displaying submission
634 $this->display_submissions(sesskey());
635 break;
636
637 case 'all':
638 //Main window, display everything
639 $this->display_submissions(sesskey());
640 break;
fcdcc372 641
6fc73d59 642 case 'fastgrade':
643 //fast grading - this process should work for all 3 subclasses
644 $grading = false;
645 $commenting = false;
646 $col = false;
647 if ($comment) {
648 $col = 'comment';
649 $commenting = true;
38ac07d2 650 }
6fc73d59 651 if ($menu) {
652 $col = 'menu';
653 $grading = true;
38ac07d2 654 }
6fc73d59 655 if (!$col) {
656 //both comment and grade columns collapsed..
657 $this->display_submissions(sesskey());
658 break;
fcdcc372 659 }
660
6fc73d59 661 foreach ($colum as $id => $unusedvalue){
662
663 $id = (int)$id; //clean parameter name
664 if (!$submission = $this->get_submission($id)) {
665 $submission = $this->prepare_new_submission($id);
666 $newsubmission = true;
667 }
668 else {
669 $newsubmission = false;
670 }
671 $submission->data1 = addslashes($submission->data1);
672 unset($submission->data2); //Don't need to update
fcdcc372 673
6fc73d59 674 //for fast grade, we need to check if any changes take place
675 $updatedb = false;
fcdcc372 676
6fc73d59 677 if ($grading) {
678 $grade = $menu[$id];
679 $updatedb = $updatedb || ($submission->grade != $grade);
680 $submission->grade = $grade;
681 }
682 else {
683 if (!$newsubmission) {
684 unset($submission->grade); // Don't need to update this.
fcdcc372 685 }
6fc73d59 686 }
687
688 //change status if assignment was graded or returned
689 if ($submission->grade != -1 )
690 $submission->data1 = get_string('submissionstatusgraded', 'assignment');
691 else
692 $submission->data1 = get_string('submissionstatusreturned', 'assignment');
693
694 if ($commenting) {
695 $commentvalue = trim($comment[$id]);
696 $updatedb = $updatedb || ($submission->comment != stripslashes($commentvalue));
697 $submission->comment = $commentvalue;
fcdcc372 698 } else {
6fc73d59 699 unset($submission->comment); // Don't need to update this.
fcdcc372 700 }
fcdcc372 701
6fc73d59 702 $submission->teacher = $USER->id;
703 $submission->timemarked = time();
fcdcc372 704
6fc73d59 705 //if it is not an update, we don't change the last modified time etc.
706 //this will also not write into database if no comment and grade is entered.
707 if ($updatedb){
708 if ($newsubmission) {
709 if (!insert_record('assignment_submissions', $submission)) {
710 return false;
711 }
712 } else {
713 if (!update_record('assignment_submissions', $submission)) {
714 return false;
715 }
716 }
717 //add to log only if updating
718 add_to_log($this->course->id, 'assignment', 'update grades', 'submissions.php?id='.$this->assignment->id.'&user='.$submission->userid, $submission->userid, $this->cm->id);
719 }
720 }
721 $this->display_submissions();
722 break;
fcdcc372 723
6fc73d59 724 case 'next':
725 // in pop up skip to next without saving
726 $this->display_submission();
727 break;
fcdcc372 728
6fc73d59 729 case 'saveandnext':
730 //We are in pop up. save the current one and go to the next one.
731 //first we save the current changes
732 if ($submission = $this->process_feedback()) {
733 $this->update_main_listing($submission);
734 }
735 $this->display_submission();
736 break;
fcdcc372 737
6fc73d59 738 default:
739 error ("There has been an error, cannot move or save to the next assignment!!");
740 break;
741 }
fcdcc372 742 }
743 }
744
6fc73d59 745 /*
746 function that updates the listing on the main script from popup
747 using javascript
748 from lib.php
749 needed to display teachers response files and upload_statuses
750 */
fcdcc372 751 function update_main_listing($submission) {
752 global $SESSION;
753
754 $perpage = get_user_preferences('assignment_perpage', 10);
fcdcc372 755 $quickgrade = get_user_preferences('assignment_quickgrade', 0);
756
757 /// Run some Javascript to try and update the parent page
758 echo '<script type="text/javascript">'."\n<!--\n";
6fc73d59 759 if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['comment'])) {
fcdcc372 760 if ($quickgrade){
6fc73d59 761 echo 'opener.document.getElementById("comment['.$submission->userid.']").value="'.trim($submission->comment).'";'."\n";
762 }
763 else {
764 echo 'opener.document.getElementById("com'.$submission->userid.'").innerHTML="'.shorten_text(trim(strip_tags($submission->comment)), 15)."\";\n";
fcdcc372 765 }
766 }
767
768 if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['grade'])) {
fcdcc372 769 if ($quickgrade){
6fc73d59 770 echo 'opener.document.getElementById("menumenu['.$submission->userid.']").selectedIndex="'.required_param('menuindex', 0, PARAM_INT).'";'."\n";
fcdcc372 771 } else {
6fc73d59 772 echo 'opener.document.getElementById("g'.$submission->userid.'").innerHTML="'.$this->display_grade($submission->grade)."\";\n";
773
fcdcc372 774 }
775 }
776
777 //need to add student's assignments in there too.
778 if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['timemodified']) &&
779 $submission->timemodified) {
6fc73d59 780 echo 'opener.document.getElementById("ts'.$submission->userid.'").innerHTML="'.addslashes($this->print_student_answer($submission->userid)).userdate($submission->timemodified)."\";\n";
fcdcc372 781 }
782
783 if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['timemarked']) &&
784 $submission->timemarked) {
785 //display teachers feedback files here as well
6fc73d59 786 echo 'opener.document.getElementById("tt'.$submission->userid.'").innerHTML="'.addslashes($this->print_user_response_files($submission->userid,false)).userdate($submission->timemarked)."\";\n";
fcdcc372 787 }
788
789 if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['status'])) {
790 echo 'opener.document.getElementById("up'.$submission->userid.'").className="s1";';
791 //replace "Update" by upload_status
6fc73d59 792 $buttontext = $submission->data1;
793 $button = link_to_popup_window ('/mod/assignment/submissions.php?id='.$this->cm->id.'&amp;userid='.$submission->userid.'&amp;mode=single'.'&amp;offset='.optional_param('offset', '', PARAM_INT), 'grade'.$submission->userid, $buttontext, 450, 700, $buttontext, 'none', true, 'button'.$submission->userid);
fcdcc372 794 echo 'opener.document.getElementById("up'.$submission->userid.'").innerHTML="'.addslashes($button).'";';
795 }
796 echo "\n-->\n</script>";
797 flush();
798 }
799
6fc73d59 800 //display student's submission for marking in pop-up window
38ac07d2 801 function display_submission() {
fcdcc372 802
803 global $CFG, $offset;
6fc73d59 804
805 $userid = required_param('userid', PARAM_INT); //the user's id
806 $offset = required_param('offset', PARAM_INT);
807
808 // Guests, non-studnets and non-teachers are not allowed to view student's or teacher's assignment information.
809 if (isguest($USER->id)) {
810 error(get_string('unauthorizeduser', 'assignment'));
811 } else if (isstudent($this->course->id, $USER->id)) {
812 error(get_string('unauthorizeduser', 'assignment'));
813 } else if (!isteacher($this->course->id, $USER->id, true)) {
814 error(get_string('unauthorizeduser', 'assignment'));
815 } else {
816 if (!$user = get_record('user', 'id', $userid)) {
817 error(get_string('nouser'));
818 }
fcdcc372 819
6fc73d59 820 if (!$submission = $this->get_submission($user->id)) {
821 $submission = $this->prepare_new_submission($userid);
822 }
fcdcc372 823
6fc73d59 824 if ($submission->timemodified > $submission->timemarked) {
825 $subtype = 'assignmentnew';
826 }
827 else {
828 $subtype = 'assignmentold';
829 }
fcdcc372 830
6fc73d59 831 $course = $this->course;
832 $assignment = $this->assignment;
833 $cm = $this->cm;
fcdcc372 834
6fc73d59 835 if ($groupmode = groupmode($course, $cm)) { // Groups are being used
836 $currentgroup = setup_and_print_groups($course, $groupmode, 'submissions.php?id='.$this->cm->id);
837 } else {
838 $currentgroup = false;
839 }
fcdcc372 840
6fc73d59 841 // Get all teachers and students
842 if ($currentgroup) {
843 $users = get_group_users($currentgroup);
844 } else {
845 $users = get_course_users($course->id);
846 }
fcdcc372 847
6fc73d59 848 $sql_next_student = next_student_sql($this->assignment->id, $users);
fcdcc372 849
6fc73d59 850 $nextid = 0;
851 if (($auser = get_record_sql($sql_next_student, false, true)) !== false) {
852 $nextid = $auser->id;
853 }
854 print_header(get_string('feedback', 'assignment').':'.$user->firstname. ' '. $user->lastname.':'.format_string($this->assignment->name));
fcdcc372 855
6fc73d59 856 ///Some javascript to help with setting up student grading >.>
fcdcc372 857
6fc73d59 858 echo '<script type="text/javascript">'."\n";
859 echo 'function setNext(){'."\n";
860 echo 'document.submitform.mode.value=\'next\';'."\n";
861 echo 'document.submitform.userid.value="'.$nextid.'";'."\n";
862 echo '}'."\n";
fcdcc372 863
6fc73d59 864 echo 'function saveNext(){'."\n";
865 echo 'document.submitform.mode.value=\'saveandnext\';'."\n";
866 echo 'document.submitform.userid.value="'.$nextid.'";'."\n";
867 echo 'document.submitform.saveuserid.value="'.$userid.'";'."\n";
868 echo 'document.submitform.menuindex.value = document.submitform.grade.selectedIndex;'."\n";
869 echo '}'."\n";
fcdcc372 870
6fc73d59 871 echo '</script>'."\n";
fcdcc372 872
6fc73d59 873 // Prints upload form for teachers to upload response file
874 $this->view_upload_response_form($userid,$offset);
875 //+++
876 echo '<table border="0" align="center" cellpadding="5" cellspacing="1" class="feedback '.$subtype.'" >';
fcdcc372 877
6fc73d59 878 ///Start of teacher info row
fcdcc372 879
6fc73d59 880 echo '<tr>';
881 echo '<td width="35" valign="top" class="picture teacher">';
882 if ($submission->teacher) {
883 $teacher = get_record('user', 'id', $submission->teacher);
884 } else {
885 global $USER;
886 $teacher = $USER;
887 }
888 print_user_picture($teacher->id, $this->course->id, $teacher->picture);
889 echo '</td>';
890 echo '<td class="content">';
891 echo '<form name="submitform" action="submissions.php" method="post">';
892 echo '<input type="hidden" name="offset" value="'.++$offset.'">';
893 echo '<input type="hidden" name="userid" value="'.$userid.'" />';
894 echo '<input type="hidden" name="id" value="'.$this->cm->id.'" />';
895 echo '<input type="hidden" name="mode" value="grade" />';
896 //selected menu index
897 echo '<input type="hidden" name="menuindex" value="0" />';
898 //new hidden field, initialized to -1.
899 echo '<input type="hidden" name="saveuserid" value="-1" />';
900
901 // Shows teacher response files to teacher
902 echo "<div class=\"from\">". get_string('responsefile','assignment')."</div>";
903 echo $this->print_user_response_files($userid,true,--$offset);
904 echo "<br /><br />";
fcdcc372 905
6fc73d59 906 if ($submission->timemarked) {
907 echo '<div class="from">';
908 echo '<div class="fullname">'.$auser->firstname. ' '. $auser->lastname.'</div>';
909 echo '<div class="time">'.userdate($submission->timemarked).'</div>';
910 echo '</div>';
911 }
fcdcc372 912
6fc73d59 913 echo '<div class="grade">'.get_string('grade').':';
914 choose_from_menu(make_grades_menu($this->assignment->grade), 'grade', $submission->grade, get_string('nograde'), '', -1);
fcdcc372 915
fcdcc372 916 echo '</div>';
6fc73d59 917 echo '<div class="clearer"></div>';
fcdcc372 918
fcdcc372 919
6fc73d59 920 $this->preprocess_submission($submission);
fcdcc372 921
6fc73d59 922 echo '<br />';
923 print_textarea($this->usehtmleditor, 14, 58, 0, 0, 'comment', $submission->comment, $this->course->id);
924
925 if ($this->usehtmleditor) {
926 echo '<input type="hidden" name="format" value="'.FORMAT_HTML.'" />';
927 }
928 else {
929 echo '<div align="right" class="format">';
930 choose_from_menu(format_text_menu(), "format", $submission->format, "");
931 helpbutton("textformat", get_string("helpformatting"));
932 echo '</div>';
933 }
934
935 ///Print Buttons in Single View
936 echo '<div class="buttons" align="center">';
937 echo '<input type="submit" name="submit" value="'.get_string('savechanges').'" onclick = "document.submitform.menuindex.value = document.submitform.grade.selectedIndex" />';
938 echo '<input type="submit" name="cancel" value="'.get_string('cancel').'" />';
939 //if there are more to be graded.
940 if ($nextid) {
941 echo '<input type="submit" name="saveandnext" value="'.get_string('saveandnext').'" onclick="saveNext()" />';
942 echo '<input type="submit" name="next" value="'.get_string('next').'" onclick="setNext();" />';
943 }
fcdcc372 944 echo '</div>';
6fc73d59 945 echo '</form>';
946 echo '</td></tr>';
947 //End of teacher info row, Start of student info row
948 echo '<tr>';
949 echo '<td width="35" valign="top" class="picture user">';
950 print_user_picture($user->id, $this->course->id, $user->picture);
951 echo '</td>';
952 echo '<td class="topic">';
953 echo '<div class="from">';
954 echo '<div class="fullname">'.$auser->firstname. ' '. $auser->lastname.'</div>';
955 if ($submission->timemodified) {
956 echo '<div class="time">'.userdate($submission->timemodified).
957 $this->display_lateness($submission->timemodified).'</div>';
958 }
959 echo '</div>';
960 $this->print_user_files($user->id);
961 echo '</td>';
962 echo '</tr>';
fcdcc372 963
6fc73d59 964 ///End of student info row
fcdcc372 965
6fc73d59 966 echo '</table>';
fcdcc372 967
6fc73d59 968 if ($this->usehtmleditor) {
969 use_html_editor();
970 }
fcdcc372 971
6fc73d59 972 print_footer('none');
fcdcc372 973 }
fcdcc372 974 }
975
6fc73d59 976 /*
977 From upload&review
978 Prints response files to students
979 */
fcdcc372 980 function print_response_students($return) {
981 global $CFG, $USER;
6fc73d59 982 require_once($CFG->libdir.'/filelib.php');
983
fcdcc372 984 $stuid = $USER->id;
985
986 echo '<table border="0" align="center" cellpadding="5" cellspacing="1" class="feedback">';
987
988 $submission = $this->get_submission($stuid);
fcdcc372 989
6fc73d59 990 // Only will show files if there is a submission
991 if ($teachids = $submission->data2) {
992 $teachidarr = explode(',', $teachids);
38ac07d2 993 foreach ($teachidarr as $t) {
994 if (! $teacher = get_record('user', 'id', $t)) {
995 print_object($submission);
6fc73d59 996 error(get_string('teachererror', 'assignment'));
38ac07d2 997 }
998 echo '<tr>';
999 echo '<td class="left picture">';
1000 print_user_picture($teacher->id, $this->course->id, $teacher->picture);
1001 echo '</td>';
1002 echo '<td class="topic">';
1003 echo '<div class="from">';
6fc73d59 1004 echo '<div class="fullname">'.$auser->firstname. ' '. $user->lastname.'</div>';
38ac07d2 1005 echo '</div>';
1006
1007 $filearea = $this->response_file_area_name($stuid, $t);
1008 if ($basedir = $this->response_file_area($stuid, $t)) {
1009 $output = '';
1010 if ($files = get_directory_list($basedir)) {
1011 foreach ($files as $key => $file) {
38ac07d2 1012 $icon = mimeinfo('icon', $file);
1013 if ($CFG->slasharguments) {
6fc73d59 1014 $ffurl = "mod/assignment/type/uploadreview/file.php/$filearea/$file";
1015 }
1016 else {
1017 $ffurl = "mod/assignment/type/uploadreview/file.php?file=/$filearea/$file";
38ac07d2 1018 }
38ac07d2 1019 }
6fc73d59 1020 //displays multiple teachers responces
1021 $output .='<img align="middle" src="'.$CFG->pixpath.'/f/'.$icon.'" height="16" width="16" alt="'.$icon.'" />';
1022 $output .= link_to_popup_window ('/'.$ffurl, 'file'.$key, $file, 450, 580, $file, 'none', true)."<br />";
38ac07d2 1023 }
1024 }
38ac07d2 1025 }
6fc73d59 1026 echo '<div class="files"><left>'.$output.'</left></div>';
1027 echo '</td></tr>';
fcdcc372 1028 }
6fc73d59 1029 echo '</table>';
fcdcc372 1030 }
1031
6fc73d59 1032
fcdcc372 1033 //print teacher's files
6fc73d59 1034 function print_user_response_files($stuid,$display_remove_button=false,$offset=NULL){
fcdcc372 1035
1036 global $CFG, $USER;
fcdcc372 1037 $userid = $USER->id;
1038
1039 $filearea = $this->response_file_area_name($stuid);
fcdcc372 1040 $output = '';
fcdcc372 1041 if ($basedir = $this->response_file_area($stuid)) {
1042 if ($files = get_directory_list($basedir)) {
1043 require_once($CFG->libdir.'/filelib.php');
1044 foreach ($files as $key => $file) {
fcdcc372 1045 $icon = mimeinfo('icon', $file);
1046
6fc73d59 1047 if ($CFG->slasharguments) {
fcdcc372 1048 $ffurl = "file.php/$filearea/$file";
6fc73d59 1049 }
1050 else {
fcdcc372 1051 $ffurl = "file.php?file=/$filearea/$file";
1052 }
fcdcc372 1053 //get feedback file size, generate and display remove file link
1054 $filesize = display_size(filesize($basedir."/".$file));
6fc73d59 1055 $remove_link='';
1056 if ($display_remove_button) {
1057 $course_mod_id=$this->cm->id;
1058 $deleteurl="$CFG->wwwroot/mod/assignment/type/upload/deleteonesubmission.php?confirm=0&view=teacher&userid=$stuid&id=$course_mod_id&name=$file&file=".$filearea."/".$file."&offset=".$offset."&sesskey=".sesskey();
1059 $remove_link='[<a href="'.$deleteurl.'">'.get_string("removelink", "assignment").'</a>]'."";
fcdcc372 1060 }
1061 $output .= '<img align="middle" src="'.$CFG->pixpath.'/f/'.$icon.'" height="16" width="16" alt="'.$icon.'" />'.
6fc73d59 1062 $output .= $file.' ['.$filesize.'] '.$remove_link.'<br />';
fcdcc372 1063 }
1064 }
1065 }
1066 $output = '<div class="files">'.$output.'</div>';
fcdcc372 1067 return $output;
1068 }
1069
6fc73d59 1070 /*
1071 print student's files.
1072 if it's teacher view - teacher can view the files, but can't delete them
1073 if it's student's view - student can delete files, but can't view them
1074 */
fcdcc372 1075 function print_user_files($userid=0, $return=false) {
1076 global $CFG, $USER;
1077
6fc73d59 1078 require_once($CFG->libdir.'/filelib.php');
1079
1080
fcdcc372 1081 if (!$userid) {
1082 if (!isloggedin()) {
1083 return '';
1084 }
1085 $userid = $USER->id;
1086 }
1087
1088 $filearea = $this->file_area_name($userid);
fcdcc372 1089 $output = '';
1090
1091 if ($basedir = $this->file_area($userid)) {
1092 if ($files = get_directory_list($basedir)) {
fcdcc372 1093 foreach ($files as $key => $file) {
fcdcc372 1094
1095 $icon = mimeinfo('icon', $file);
1096 //get filesize for displaying
1097 $filesize = display_size(filesize($basedir."/".$file));
1098
1099 if ($CFG->slasharguments) {
1100 $ffurl = "$CFG->wwwroot/file.php/$filearea/$file";
6fc73d59 1101 }
1102 else {
fcdcc372 1103 $ffurl = "$CFG->wwwroot/file.php?file=/$filearea/$file";
1104 }
6fc73d59 1105 if (isteacher($this->course->id, $USER->id, true)) {
1106 $output .= '<img align="middle" src="'.$CFG->pixpath.'/f/'.$icon.'" height="16" width="16" alt="'.$icon.'" /><a href="'.$ffurl.'" >'.$file.'</a> ['.$filesize.'] <br />';
1107 }
1108 else {
1109 if (isset($USER->id)) {
1110 if ($submission = $this->get_submission($USER->id)){
1111 //changed timemodified=0 for Draft assignments so student's see their own submissions
61240489 1112 if ($submission->timemodified <= $this->assignment->timedue || empty($this->assignment->timedue)) {
38ac07d2 1113 $remove_link = '';
61240489 1114 if ($submission->data1 == get_string("submissionstatusdraft", "assignment") || $submission->data1 == get_string("submissionstatusreturned", "assignment")) {
38ac07d2 1115 $course_mod_id=$this->cm->id;
6fc73d59 1116 $deleteurl="$CFG->wwwroot/mod/assignment/type/upload/deleteonesubmission.php?confirm=0&view=student&userid=$userid&id=$course_mod_id&name=$file&file=".$filearea."/".$file."&sesskey=".sesskey();
38ac07d2 1117 $remove_link= '[<a href="'.$deleteurl.'">'.get_string("removelink", "assignment").'</a>]'; //students of the course
6fc73d59 1118 }
1119 $file_path = "$CFG->wwwroot/file.php?file=/$filearea/$file";
1120 $file_link = '<a href="'.$file_path.'">'.$file.'</a>';
1121 $output .= '<img align="middle" src="'.$CFG->pixpath.'/f/'.$icon.'" height="16" width="16" alt="'.$icon.'" />'.$file_link.' ['.$filesize.']'.$remove_link.'<br />';
1122 }
1123 else {
61240489 1124 $output .= '';
38ac07d2 1125 }
6fc73d59 1126 }
fcdcc372 1127 }
61240489 1128 }
fcdcc372 1129 }
1130 }
1131 }
1132
1133 $output = '<div class="files">'.$output.'</div>';
1134
1135 if ($return) {
1136 return $output;
1137 }
1138 echo $output;
1139 }
1140
1141 /*
6fc73d59 1142 *Display all the submissions ready for grading
1143 *from lib.php
1144 *we needed so select more information from database and add
1145 *upload_statuses display
1146 */
fcdcc372 1147 function display_submissions() {
6fc73d59 1148 global $CFG, $db, $USER;
fcdcc372 1149
6fc73d59 1150 require_once($CFG->libdir.'/tablelib.php');
1151
1152
1153 //see if the form has just been submitted to request user_preference updates
1154 $updatepref = optional_param('updatepref', '', PARAM_ALPHANUM);
1155 if (isset($updatepref)){
fcdcc372 1156 $perpage = optional_param('perpage', 10, PARAM_INT);
1157 $perpage = ($perpage <= 0) ? 10 : $perpage ;
1158 set_user_preference('assignment_perpage', $perpage);
1159 set_user_preference('assignment_quickgrade', optional_param('quickgrade',0, PARAM_BOOL));
1160 }
1161
6fc73d59 1162 // get perpage and quickgrade params from database
fcdcc372 1163 $perpage = get_user_preferences('assignment_perpage', 10);
1164 $quickgrade = get_user_preferences('assignment_quickgrade', 0);
1165
6fc73d59 1166 $teacherattempts = true;
fcdcc372 1167 $page = optional_param('page', 0, PARAM_INT);
1168 $strsaveallfeedback = get_string('saveallfeedback', 'assignment');
1169
6fc73d59 1170 //Some shortcuts to make the code read better
fcdcc372 1171 $course = $this->course;
1172 $assignment = $this->assignment;
1173 $cm = $this->cm;
1174
6fc73d59 1175 //tabindex for quick grading tabbing; Not working for dropdowns yet
1176 $tabindex = 1;
fcdcc372 1177
1178 add_to_log($course->id, 'assignment', 'view submission', 'submissions.php?id='.$this->assignment->id, $this->assignment->id, $this->cm->id);
1179
1180 print_header_simple(format_string($this->assignment->name,true), "", '<a href="index.php?id='.$course->id.'">'.$this->strassignments.'</a> -> <a href="view.php?a='.$this->assignment->id.'">'.format_string($this->assignment->name,true).'</a> -> '. $this->strsubmissions, '', '', true, update_module_button($cm->id, $course->id, $this->strassignment), navmenu($course, $cm));
1181
1182 //change column name to upload_status to allow ordering by upload_statuses
6fc73d59 1183 $tablecolumns = array('picture', 'fullname', 'grade', 'comment', 'timemodified', 'timemarked', 'upload status');
fcdcc372 1184 $tableheaders = array('', get_string('fullname'), get_string('grade'), get_string('comment', 'assignment'), get_string('lastmodified').' ('.$course->student.')', get_string('lastmodified').' ('.$course->teacher.')', get_string('status'));
1185
fcdcc372 1186 $table = new flexible_table('mod-assignment-submissions');
1187
1188 $table->define_columns($tablecolumns);
1189 $table->define_headers($tableheaders);
1190 $table->define_baseurl($CFG->wwwroot.'/mod/assignment/submissions.php?id='.$this->cm->id);
1191
1192 $table->sortable(true);
1193 $table->collapsible(true);
1194 $table->initialbars(true);
1195
1196 $table->column_suppress('picture');
1197 $table->column_suppress('fullname');
1198
1199 $table->column_class('picture', 'picture');
1200 $table->column_class('fullname', 'fullname');
1201 $table->column_class('grade', 'grade');
6fc73d59 1202 $table->column_class('comment', 'comment');
fcdcc372 1203 $table->column_class('timemodified', 'timemodified');
1204 $table->column_class('timemarked', 'timemarked');
1205 $table->column_class('status', 'status');
1206
1207 $table->set_attribute('cellspacing', '0');
1208 $table->set_attribute('id', 'attempts');
1209 $table->set_attribute('class', 'submissions');
1210 $table->set_attribute('width', '90%');
1211 $table->set_attribute('align', 'center');
1212
1213 // Start working -- this is necessary as soon as the niceties are over
1214 $table->setup();
1215
6fc73d59 1216 // Check to see if groups are being used in this assignment
1217 // Groups are being used
1218 if ($groupmode = groupmode($course, $cm)) {
fcdcc372 1219 $currentgroup = setup_and_print_groups($course, $groupmode, 'submissions.php?id='.$this->cm->id);
6fc73d59 1220 }
1221 else {
fcdcc372 1222 $currentgroup = false;
1223 }
1224
6fc73d59 1225 // Get all teachers and students
fcdcc372 1226 if ($currentgroup) {
1227 $users = get_group_users($currentgroup);
6fc73d59 1228 }
1229 else {
61240489 1230 $users = get_course_users($course->id);
fcdcc372 1231 }
1232
1233 if (!$teacherattempts) {
61240489 1234 $teachers = get_course_teachers($course->id);
fcdcc372 1235 if (!empty($teachers)) {
1236 $keys = array_keys($teachers);
1237 }
1238 foreach ($keys as $key) {
1239 unset($users[$key]);
1240 }
1241 }
1242
6fc73d59 1243 if (empty($users)) {
fcdcc372 1244 print_heading(get_string('noattempts','assignment'));
1245 return true;
1246 }
1247
fcdcc372 1248 $table->pagesize($perpage, count($users));
1249
6fc73d59 1250 $customQuery = display_submissions_sql($table, $users, $this->assignment->id);
fcdcc372 1251
6fc73d59 1252 // offset used to calculate index of student in that particular query, needed for the pop up to know who's next
fcdcc372 1253 $offset = $page * $perpage;
1254
6fc73d59 1255 if (($ausers = get_records_sql($customQuery)) !== false) {
fcdcc372 1256
1257 foreach ($ausers as $auser) {
1258 $picture = print_user_picture($auser->id, $course->id, $auser->picture, false, true);
1259
6fc73d59 1260 if (empty($auser->submissionid)) {
fcdcc372 1261 $auser->grade = -1; //no submission yet
1262 }
1263
1264 //if there is no upload status, then display "blank"
38ac07d2 1265 if (empty($auser->upload_status)) {
fcdcc372 1266 $auser->upload_status=get_string("submissionstatusblank", "assignment");
38ac07d2 1267 }
1268 if (!empty($auser->submissionid)) {
6fc73d59 1269
1270 //Print student answer and student modified date attach file or print link to student answer, depending on the type of the assignment.
1271 //Refer to print_student_answer in inherited classes do not display draft submissions to marker.
fcdcc372 1272 if ($auser->timemodified > 0 && $auser->upload_status != get_string("submissionstatusdraft", "assignment")) {
1273 $studentmodified = '<div id="ts'.$auser->id.'">'.$this->print_student_answer($auser->id).userdate($auser->timemodified).'</div>';
1274 } else {
1275 $studentmodified = '<div id="ts'.$auser->id.'">&nbsp;</div>';
1276 }
6fc73d59 1277
fcdcc372 1278 ///Print grade, dropdown or text
1279 if ($auser->timemarked > 0) {
1280 //display teachers feedback files here as well
1281 $teachermodified = '<div id="tt'.$auser->id.'">'.$this->print_user_response_files($auser->id,false).userdate($auser->timemarked).'</div>';
1282 //disable grading ability in case of Blank or Draft assignment
6fc73d59 1283 if ($quickgrade ){
fcdcc372 1284 $grade = '<div id="g'.$auser->id.'">'.choose_from_menu(make_grades_menu($this->assignment->grade),
1285 'menu['.$auser->id.']', $auser->grade, get_string('nograde'),'',-1,true,false,$tabindex++).'</div>';
1286 } else {
1287 $grade = '<div id="g'.$auser->id.'">'.$this->display_grade($auser->grade).'</div>';
1288 }
1289
1290 } else {
1291 $teachermodified = '<div id="tt'.$auser->id.'">&nbsp;</div>';
1292
6fc73d59 1293 if ($quickgrade && $auser->upload_status != get_string("submissionstatusdraft", "assignment") && $auser->upload_status != get_string("submissionstatusblank", "assignment")){
fcdcc372 1294 $grade = '<div id="g'.$auser->id.'">'.choose_from_menu(make_grades_menu($this->assignment->grade),
1295 'menu['.$auser->id.']', $auser->grade, get_string('nograde'),'',-1,true,false,$tabindex++).'</div>';
1296 } else {
1297 $grade = '<div id="g'.$auser->id.'">'.$this->display_grade($auser->grade).'</div>';
1298 }
1299 }
1300 ///Print Comment
6fc73d59 1301 if ($quickgrade && $auser->upload_status != get_string("submissionstatusdraft", "assignment") && $auser->upload_status != get_string("submissionstatusblank", "assignment")){
1302 $comment = '<div id="com'.$auser->id.'"><textarea tabindex="'.$tabindex++.'" name="comment['.$auser->id.']" id="comment['.$auser->id.']">'.($auser->comment).'</textarea></div>';
fcdcc372 1303 } else {
6fc73d59 1304 $comment = '<div id="com'.$auser->id.'">'.shorten_text(strip_tags($auser->comment),15).'</div>';
fcdcc372 1305 }
1306 } else {
1307 $studentmodified = '<div id="ts'.$auser->id.'">&nbsp;</div>';
1308 $teachermodified = '<div id="tt'.$auser->id.'">&nbsp;</div>';
1309 $status = '<div id="st'.$auser->id.'">&nbsp;</div>';
1310
6fc73d59 1311 if ($quickgrade && $auser->upload_status != get_string("submissionstatusdraft", "assignment") && $auser->upload_status != get_string("submissionstatusblank", "assignment") ){
1312 // allow editing
fcdcc372 1313 $grade = '<div id="g'.$auser->id.'">'.choose_from_menu(make_grades_menu($this->assignment->grade),
1314 'menu['.$auser->id.']', $auser->grade, get_string('nograde'),'',-1,true,false,$tabindex++).'</div>';
1315 } else {
1316 $grade = '<div id="g'.$auser->id.'">-</div>';
1317 }
1318 if ($quickgrade && $auser->upload_status != get_string("submissionstatusdraft", "assignment") && $auser->upload_status != get_string("submissionstatusblank", "assignment") ){
6fc73d59 1319 $comment = '<div id="com'.$auser->id.'"><textarea tabindex="'.$tabindex++.'" name="comment['.$auser->id.']" id="comment['.$auser->id.']">'.($auser->comment).'</textarea></div>';
fcdcc372 1320 } else {
1321 $comment = '<div id="com'.$auser->id.'">&nbsp;</div>';
1322 }
1323 }
1324
1325 //display upload statuses instead of old ones ={Grade, Update}
6fc73d59 1326
fcdcc372 1327 $buttontext=$auser->upload_status;
fcdcc372 1328
6fc73d59 1329 //do not display link to the grading pop-up if upload_status={Blank, Draft}
fcdcc372 1330 if ($auser->upload_status == get_string("submissionstatusdraft", "assignment") || $auser->upload_status == get_string("submissionstatusblank", "assignment")){
1331 $button = $buttontext;
6fc73d59 1332 }
1333 else{
1334
fcdcc372 1335 ///No more buttons, we use popups ;-).
1336 $button = link_to_popup_window ('/mod/assignment/submissions.php?id='.$this->cm->id.'&amp;userid='.$auser->id.'&amp;mode=single'.'&amp;offset='.$offset++,'grade'.$auser->id, $buttontext, 500, 780, $buttontext, 'none', true, 'button'.$auser->id);
1337 }
1338 //changed to $auser->upload_status
1339 $status = '<div id="up'.$auser->id.'" class="s'.$auser->upload_status.'">'.$button.'</div>';
6fc73d59 1340 $row = array($picture, $auser->firstname. ' '. $auser->lastname, $grade, $comment, $studentmodified, $teachermodified, $status);
fcdcc372 1341 $table->add_data($row);
1342 }
6fc73d59 1343
fcdcc372 1344 }
1345
1346 /// Print quickgrade form around the table
6fc73d59 1347 if ($quickgrade){
fcdcc372 1348 echo '<form action="submissions.php" name="fastg" method="post">';
1349 echo '<input type="hidden" name="id" value="'.$this->cm->id.'">';
1350 echo '<input type="hidden" name="mode" value="fastgrade">';
1351 echo '<input type="hidden" name="page" value="'.$page.'">';
1352 }
1353
1354 $table->print_html(); /// Print the whole table
1355
6fc73d59 1356 if ($quickgrade){
fcdcc372 1357 echo '<p align="center"><input type="submit" name="fastg" value="'.get_string('saveallfeedback', 'assignment').'" /></p>';
1358 echo '</form>';
1359 }
1360 /// End of fast grading form
1361
1362 /// Mini form for setting user preference
1363 echo '<br />';
1364 echo '<form name="options" action="submissions.php?id='.$this->cm->id.'" method="post">';
1365 echo '<input type="hidden" id="updatepref" name="updatepref" value="1" />';
1366 echo '<table id="optiontable" align="center">';
1367 echo '<tr align="right"><td>';
1368 echo '<label for="perpage">'.get_string('pagesize','assignment').'</label>';
1369 echo ':</td>';
1370 echo '<td align="left">';
1371 echo '<input type="text" id="perpage" name="perpage" size="1" value="'.$perpage.'" />';
1372 helpbutton('pagesize', get_string('pagesize','assignment'), 'assignment');
1373 echo '</td></tr>';
1374 echo '<tr align="right">';
1375 echo '<td>';
1376 print_string('quickgrade','assignment');
1377 echo ':</td>';
1378 echo '<td align="left">';
6fc73d59 1379 if ($quickgrade){
fcdcc372 1380 echo '<input type="checkbox" name="quickgrade" value="1" checked="checked" />';
1381 } else {
1382 echo '<input type="checkbox" name="quickgrade" value="1" />';
1383 }
1384 helpbutton('quickgrade', get_string('quickgrade', 'assignment'), 'assignment').'</p></div>';
1385 echo '</td></tr>';
1386 echo '<tr>';
1387 echo '<td colspan="2" align="right">';
1388 echo '<input type="submit" value="'.get_string('savepreferences').'" />';
1389 echo '</td></tr></table>';
1390 echo '</form>';
1391 ///End of mini form
1392 print_footer($this->course);
1393 }
1394
1395 //deletes submitted file (assignment or response)
6fc73d59 1396 function deleteonesubmission (){
1397 global $CFG, $USER;
1398
1399 require_login($this->course->id, false, $cm);
1400
1401 require_once($CFG->libdir.'/filelib.php');
1402
1403 $id = required_param('id', PARAM_INT); //Course module ID
1404 $a = optional_param('a', '', PARAM_INT); //Assignment ID
1405 $file = optional_param('file', '', PARAM_PATH); //file path
1406 $userid = $USER->id; //current user's id
1407 $confirm = optional_param('confirm', '', PARAM_INT); //confirmation of deletion
1408 $name = optional_param('name', '', PARAM_FILE); //name of file
1409 $offset = optional_param('offset', '', PARAM_INT); //offset value
1410 $view = optional_param('view', '', PARAM_ALPHA);
1411
1412 $submission = $this->get_submission($USER->id); //teacher or student view
1413 $filearea = $this->file_area_name($userid);
1414
1415 //path where upload assignment is located
1416 $filepath = "$CFG->dataroot/$filearea/$name";
1417 $SESSION->file_path = $filepath;
1418 $fileresponse = $this->response_file_area_name($userid);
1419
1420 //path where reponse files are held
1421 $fileresponsepath = "$CFG->dataroot/$fileresponse/$name";
1422 $SESSION->file_response_path = $fileresponsepath;
1423
1424 if ($view == 'teacher'){
1425 if (!isteacher($this->course->id, $USER->id, true)){
1426 error(get_string('deleteerror', 'assignment'));
1427 } else {
1428 $yes_url = "$CFG->wwwroot/mod/assignment/type/upload/deleteonesubmission.php?confirm=1&view=teacher&userid=$userid&id=$id&name=$name&offset=$offset&sesskey=".sesskey();
fcdcc372 1429 $no_url = "../../submissions.php?userid=$userid&id=$id&mode=single&offset=$offset";
6fc73d59 1430
fcdcc372 1431 $back_button = get_string("backtofeedback", "assignment");
1432 $action_url = '../../submissions.php';
6fc73d59 1433 }
1434 }else{
1435 $yes_url = "$CFG->wwwroot/mod/assignment/type/upload/deleteonesubmission.php?confirm=1&view=student&userid=$userid&id=$id&name=$name&offset=$offset&sesskey=".sesskey();
fcdcc372 1436 $no_url = "../../view.php?id=$id&offset=$offset";
1437 $back_button = get_string("backtoassignment", "assignment");
1438 $action_url = '../../view.php';
6fc73d59 1439 }
1440
1441 if ($view == 'student') $this->view_header();
1442
1443 // see if the user is a student if not, then they can't delete files, except for their assignment response file
1444 if (!isstudent($this->courseid->id, $USER->id) || isteacher($this->course->id)){
1445 if (!empty($confirm)) {
1446 //this code will allow the teacher to delete the user response
1447 //file
1448 if($view == 'teacher') {
1449 fulldelete($SESSION->file_response_path);}
1450 else {
1451 if (!fulldelete($SESSION->file_path)) {
1452 print_object($SESSION);
1453 error(get_string("deletefail", "assignment").' '.$name);
38ac07d2 1454 }
6fc73d59 1455 else {
1456 //if student deletes submitted files then numfiles should be changed
1457 if ($view == 'student'){
1458 //deleting the files
1459 fulldelete($SESSION->file_path);
1460
1461 $submission->numfiles--;
1462
1463 if (update_record("assignment_submissions", $submission)) {
1464 error(get_string("deleteednotification", "assignment"));
1465 }
1466 else {
1467 error(get_string("deletefail", "assignment"));
1468 }
1469 }
1470 else {
1471 error(get_string("deleteednotification", "assignment"));
1472 }
1473 }
fcdcc372 1474 }
38ac07d2 1475 echo "<form action=\"".$action_url."\">";
1476 echo '<input type="hidden" name="offset" value="'.$offset.'">';
1477 echo "<input type=\"hidden\" value=\"$userid\" name=\"userid\">";
1478 echo "<input type=\"hidden\" value=\"$id\" name=\"id\">";
38ac07d2 1479 echo "<input type=\"hidden\" value=\"single\" name=\"mode\">";
1480 echo "<center><input type=\"submit\" value=\"".$back_button."\" name=\"submit\"></center></form>";
6fc73d59 1481
1482 }
1483 else {
1484 notify (get_string("namedeletefile", "assignment"));
1485 notify($name);
1486 notice_yesno (get_string("deletecheckfile", "assignment"), $yes_url, $no_url);
38ac07d2 1487 }
fcdcc372 1488 }
6fc73d59 1489 else {
1490 error(get_string('unauthorizeduser', 'assignment'));
38ac07d2 1491 }
fcdcc372 1492
6fc73d59 1493 if ($view == 'student') {
1494 $this->view_footer();
fcdcc372 1495 }
fcdcc372 1496
6fc73d59 1497 unset($SESSION->file_path);
1498 unset($SESSION->file_response_path);
38ac07d2 1499 }
fcdcc372 1500}
fcdcc372 1501?>