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