Better handling of Shibboleth when mixed with other logins
[moodle.git] / mod / assignment / lib.php
CommitLineData
b0f2597e 1<?PHP // $Id$
2/**
3 * assignment_base is the base class for assignment types
4 *
5 * This class provides all the functionality for an assignment
6 */
04eba58f 7
d699cd1e 8
4909e176 9if (!isset($CFG->assignment_maxbytes)) {
10 set_config("assignment_maxbytes", 1024000); // Default maximum size for all assignments
04eba58f 11}
12
13
b0f2597e 14/*
15 * Standard base class for all assignment submodules (assignment types).
16 *
17 *
18 */
19class assignment_base {
20
21 var $cm;
22 var $course;
23 var $assignment;
24
25 /**
26 * Constructor for the base assignment class
27 *
28 * Constructor for the base assignment class.
29 * If cmid is set create the cm, course, assignment objects.
30 *
31 * @param cmid integer, the current course module id - not set for new assignments
32 */
33 function assignment_base($cmid=0) {
34
35 global $CFG;
36
37 if ($cmid) {
38 if (! $this->cm = get_record("course_modules", "id", $cmid)) {
39 error("Course Module ID was incorrect");
40 }
04eba58f 41
b0f2597e 42 if (! $this->course = get_record("course", "id", $this->cm->course)) {
43 error("Course is misconfigured");
44 }
04eba58f 45
b0f2597e 46 if (! $this->assignment = get_record("assignment", "id", $this->cm->instance)) {
47 error("assignment ID was incorrect");
48 }
e6a4906b 49
b0f2597e 50 $this->strassignment = get_string('modulename', 'assignment');
51 $this->strassignments = get_string('modulenameplural', 'assignment');
52 $this->strsubmissions = get_string('submissions', 'assignment');
53 $this->strlastmodified = get_string('lastmodified');
e6a4906b 54
b0f2597e 55 if ($this->course->category) {
56 $this->navigation = "<a target=\"{$CFG->framename}\" href=\"$CFG->wwwroot/course/view.php?id={$this->course->id}\">{$this->course->shortname}</a> -> ".
57 "<a target=\"{$CFG->framename}\" href=\"index.php?id={$this->course->id}\">$this->strassignments</a> ->";
58 } else {
59 $this->navigation = "<a target=\"{$CFG->framename}\" href=\"index.php?id={$this->course->id}\">$this->strassignments</a> ->";
60 }
e6a4906b 61
b0f2597e 62 $this->pagetitle = strip_tags($this->course->shortname.': '.$this->strassignment.': '.$this->assignment->name);
e6a4906b 63
b0f2597e 64 if (!$this->cm->visible and !isteacher($this->course->id)) {
65 $pagetitle = strip_tags($this->course->shortname.': '.$this->strassignment);
66 print_header($pagetitle, $this->course->fullname, "$this->navigation $this->strassignment",
67 "", "", true, '', navmenu($this->course, $this->cm));
68 notice(get_string("activityiscurrentlyhidden"), "$CFG->wwwroot/course/view.php?id={$this->course->id}");
69 }
70
71 $this->currentgroup = get_current_group($this->course->id);
e6a4906b 72
e6a4906b 73 }
74 }
75
b0f2597e 76 /*
77 * Display the assignment to students (sub-modules will most likely override this)
78 */
04eba58f 79
b0f2597e 80 function view() {
81 global $CFG;
04eba58f 82
b0f2597e 83 add_to_log($this->course->id, "assignment", "view", "view.php?id={$this->cm->id}",
84 $this->assignment->id, $this->cm->id);
04eba58f 85
b0f2597e 86 print_header($this->pagetitle, $this->course->fullname, $this->navigation.' '.$this->assignment->name, '', '',
87 true, update_module_button($this->cm->id, $this->course->id, $this->strassignment),
88 navmenu($this->course, $this->cm));
04eba58f 89
b0f2597e 90 echo '<div class="reportlink">'.$this->submittedlink().'</div>';
04eba58f 91
b0f2597e 92 print_simple_box_start('center');
93 echo format_text($this->assignment->description, $this->assignment->format);
94 print_simple_box_end();
04eba58f 95
b0f2597e 96 print_simple_box_start('center', '', '', '', 'time');
97 echo '<table>';
98 echo '<tr><td class="c0">'.get_string('availabledate','assignment').':</td>';
99 echo ' <td class="c1">'.userdate($this->assignment->timeavailable).'</td></tr>';
100 echo '<tr><td class="c0">'.get_string('duedate','assignment').':</td>';
101 echo ' <td class="c1">'.userdate($this->assignment->timedue).'</td></tr>';
102 echo '</table>';
103
104 print_simple_box_end();
04eba58f 105
b0f2597e 106 $this->view_feedback();
107
108 print_footer($this->course);
36eb856f 109 }
110
04eba58f 111
b0f2597e 112 function view_feedback() {
113 global $USER;
e6a4906b 114
b0f2597e 115 /// Get submission for this assignment
116 /// If no submission then just return quietly
117 $submission = $this->get_submission($USER->id);
118 if (empty($submission->timemarked)) {
119 return;
9c48354d 120 }
e6a4906b 121
b0f2597e 122 /// We need the teacher info
123 if (! $teacher = get_record('user', 'id', $submission->teacher)) {
124 print_object($submission);
125 error('Could not find the teacher');
126 }
e6a4906b 127
b0f2597e 128 /// Print the feedback
6d4ecaec 129 print_heading(get_string('feedbackfromteacher', 'assignment', $this->course->teacher));
130
b0f2597e 131 echo '<table cellspacing="0" class="feedback">';
132
133 echo '<tr>';
134 echo '<td class="left picture">';
135 print_user_picture($teacher->id, $this->course->id, $teacher->picture);
136 echo '</td>';
6d4ecaec 137 echo '<td class="topic">';
138 echo '<div class="author">'.fullname($teacher).'</div>';
139 echo '<div class="time">'.userdate($submission->timemarked).'</div>';
b0f2597e 140 echo '</td>';
141 echo '</tr>';
142
143 echo '<tr>';
144 echo '<td class="left side">&nbsp;</td>';
6d4ecaec 145 echo '<td class="content">';
b0f2597e 146 if ($this->assignment->grade) {
6d4ecaec 147 echo '<div class="grade">';
b0f2597e 148 if ($submission->grade or $submission->timemarked) {
6d4ecaec 149 echo get_string("grade").': '.$this->display_grade($submission->grade);
b0f2597e 150 } else {
151 echo get_string("nograde");
152 }
6d4ecaec 153 echo '</div>';
e6a4906b 154 }
dcd338ff 155
6d4ecaec 156 echo '<div class="comment">';
b0f2597e 157 echo text_to_html($submission->comment);
6d4ecaec 158 echo '</div>';
b0f2597e 159 echo '</tr>';
160
161 echo '</table>';
e6a4906b 162 }
e6a4906b 163
164
77db7e4c 165
b0f2597e 166 /*
167 * Print the start of the setup form for the current assignment type
168 */
169 function setup(&$form, $action='') {
170 global $CFG, $THEME;
171
172 if (empty($this->course)) {
173 if (! $this->course = get_record("course", "id", $form->course)) {
174 error("Course is misconfigured");
77db7e4c 175 }
176 }
b0f2597e 177 if (empty($action)) { // Default destination for this form
178 $action = $CFG->wwwroot.'/course/mod.php';
179 }
77db7e4c 180
b0f2597e 181 if (empty($form->name)) {
182 $form->name = "";
183 }
184 if (empty($form->assignmenttype)) {
185 $form->assignmenttype = "";
186 }
187 if (empty($form->description)) {
188 $form->description = "";
189 }
77db7e4c 190
b0f2597e 191 $strname = get_string('name');
192 $strassignments = get_string('modulenameplural', 'assignment');
193 $strheading = empty($form->name) ? get_string("type$form->assignmenttype",'assignment') : $form->name;
77db7e4c 194
b0f2597e 195 print_header($this->course->shortname.': '.$strheading, "$strheading",
196 "<a href=\"$CFG->wwwroot/course/view.php?id={$this->course->id}\">{$this->course->shortname} </a> -> ".
197 "<a href=\"$CFG->wwwroot/mod/assignment/index.php?id={$this->course->id}\">$strassignments</a> -> $strheading");
77db7e4c 198
b0f2597e 199 print_simple_box_start("center");
200 print_heading(get_string("type$form->assignmenttype",'assignment'));
201 include("$CFG->dirroot/mod/assignment/type/common.html");
202 }
203
204 /*
205 * Print the end of the setup form for the current assignment type
206 */
207 function setup_end() {
208 global $CFG, $usehtmleditor;
209
210 include($CFG->dirroot.'/mod/assignment/type/common_end.html');
77db7e4c 211
212 print_simple_box_end();
213
b0f2597e 214 if ($usehtmleditor) {
215 use_html_editor();
216 }
217
218 print_footer($this->course);
77db7e4c 219 }
77db7e4c 220
221
b0f2597e 222 function add_instance($assignment) {
223 // Given an object containing all the necessary data,
224 // (defined by the form in mod.html) this function
225 // will create a new instance and return the id number
226 // of the new instance.
227
228 $assignment->timemodified = time();
229 $assignment->timedue = make_timestamp($assignment->dueyear, $assignment->duemonth,
230 $assignment->dueday, $assignment->duehour,
231 $assignment->dueminute);
232 $assignment->timeavailable = make_timestamp($assignment->availableyear, $assignment->availablemonth,
233 $assignment->availableday, $assignment->availablehour,
234 $assignment->availableminute);
d699cd1e 235
b0f2597e 236 return insert_record("assignment", $assignment);
237 }
d699cd1e 238
b0f2597e 239 function delete_instance($assignment) {
240 if (! delete_records("assignment", "id", "$assignment->id")) {
241 $result = false;
242 }
243 return $result;
244 }
d699cd1e 245
b0f2597e 246 function update_instance($assignment) {
247 // Given an object containing all the necessary data,
248 // (defined by the form in mod.html) this function
249 // will create a new instance and return the id number
250 // of the new instance.
251
252 $assignment->timemodified = time();
253 $assignment->timedue = make_timestamp($assignment->dueyear, $assignment->duemonth,
254 $assignment->dueday, $assignment->duehour,
255 $assignment->dueminute);
256 $assignment->timeavailable = make_timestamp($assignment->availableyear, $assignment->availablemonth,
257 $assignment->availableday, $assignment->availablehour,
258 $assignment->availableminute);
259 $assignment->id = $assignment->instance;
260 return update_record("assignment", $assignment);
261 }
262
263
264
265 /*
266 * Top-level function for handling of submissions called by submissions.php
267 *
268 */
269 function submissions($mode) {
270 switch ($mode) {
271 case 'grade': // We are in a popup window grading
272 if ($submission = $this->process_feedback()) {
273 print_heading(get_string('changessaved'));
be86672d 274 $this->update_main_listing($submission);
b0f2597e 275 }
276 close_window();
277 break;
9cc9b7c1 278
b0f2597e 279 case 'single': // We are in a popup window displaying submission
280 $this->display_submission();
281 break;
a56d79cd 282
b0f2597e 283 case 'all': // Main window, display everything
284 $this->display_submissions();
285 break;
a56d79cd 286 }
b0f2597e 287 }
a56d79cd 288
be86672d 289 function update_main_listing($submission) {
290 global $SESSION;
291
292 /// Run some Javascript to try and update the parent page
293 echo '<script type="text/javascript">'."\n<!--\n";
294 if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['grade'])) {
295 echo 'opener.document.getElementById("g'.$submission->userid.
296 '").innerHTML="'.$this->display_grade($submission->grade)."\";\n";
297 }
298 if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['comment'])) {
299 echo 'opener.document.getElementById("com'.$submission->userid.
300 '").innerHTML="'.shorten_text($submission->comment, 15)."\";\n";
301 }
302 if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['timemodified'])) {
303 echo 'opener.document.getElementById("ts'.$submission->userid.
304 '").innerHTML="'.userdate($submission->timemodified)."\";\n";
305 }
306 if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['timemarked'])) {
307 echo 'opener.document.getElementById("tt'.$submission->userid.
308 '").innerHTML="'.userdate($submission->timemarked)."\";\n";
309 }
310 if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['status'])) {
311 echo 'opener.document.getElementById("up'.$submission->userid.'").className="s1";';
6d4ecaec 312 echo 'opener.document.getElementById("button'.$submission->userid.'").value="'.get_string('update').' ...";';
be86672d 313 }
314 echo "\n-->\n</script>";
315 fflush();
316 }
d699cd1e 317
d59269cf 318 /*
319 * Display a grade in user-friendly form, whether it's a scale or not
320 *
321 */
322 function display_grade($grade) {
323
324 static $scalegrades; // Cached because we only have one per assignment
325
326 if ($this->assignment->grade >= 0) { // Normal number
327 return $grade;
328
329 } else { // Scale
330 if (empty($scalegrades)) {
331 if ($scale = get_record('scale', 'id', -($this->assignment->grade))) {
332 $scalegrades = make_menu_from_list($scale->scale);
333 } else {
334 return '-';
335 }
336 }
0f7d4e5e 337 if (isset($scalegrades[$grade])) {
338 return $scalegrades[$grade];
339 }
340 return '';
d59269cf 341 }
342 }
343
b0f2597e 344 /*
345 * Display a single submission, ready for grading on a popup window
346 *
347 */
348 function display_submission() {
b0f2597e 349
350 $userid = required_param('userid');
d699cd1e 351
b0f2597e 352 if (!$user = get_record('user', 'id', $userid)) {
353 error('No such user!');
354 }
d699cd1e 355
0f7d4e5e 356 if (!$submission = $this->get_submission($user->id, true)) { // Get one or make one
b0f2597e 357 error('Could not find submission!');
358 }
a5a4cd60 359
b0f2597e 360 if ($submission->timemodified > $submission->timemarked) {
361 $subtype = 'assignmentnew';
362 } else {
363 $subtype = 'assignmentold';
364 }
d699cd1e 365
b0f2597e 366 print_header($this->assignment->name.' '.fullname($user, true));
d699cd1e 367
b0f2597e 368 echo '<form action="submissions.php" method="post">';
369 echo '<input type="hidden" name="userid" value="'.$userid.'">';
370 echo '<input type="hidden" name="id" value="'.$this->cm->id.'">';
371 echo '<input type="hidden" name="mode" value="grade">';
d699cd1e 372
b0f2597e 373 echo '<table cellspacing="0" class="submission '.$subtype.'" >';
d699cd1e 374
b0f2597e 375 echo '<tr>';
376 echo '<td width="35" valign="top" class="picture user">';
377 print_user_picture($user->id, $this->course->id, $user->picture);
378 echo '</td>';
379 echo '<td class="heading">'.fullname($user, true).'</td>';
380 echo '</tr>';
c69cb506 381
b0f2597e 382 echo '<tr>';
383 echo '<td width="35" valign="top" class="picture teacher">';
384 if ($submission->teacher) {
385 $teacher = get_record('user', 'id', $submission->teacher);
386 } else {
387 global $USER;
388 $teacher = $USER;
389 }
390 print_user_picture($teacher->id, $this->course->id, $teacher->picture);
391 echo '</td>';
392 echo '<td class="content">';
d699cd1e 393
b0f2597e 394 if (!$submission->grade and !$submission->timemarked) {
395 $submission->grade = -1; /// Hack to stop zero being selected on the menu below (so it shows 'no grade')
396 }
397 echo get_string('feedback', 'assignment').':';
398 choose_from_menu(make_grades_menu($this->assignment->grade), 'grade',
399 $submission->grade, get_string('nograde'));
400
401 if ($submission->timemarked) {
402 echo '&nbsp;&nbsp;'.userdate($submission->timemarked);
d699cd1e 403 }
b0f2597e 404 echo '<br />';
405 print_textarea(false, 6, 60, 500, 400, 'comment', $submission->comment, $this->course->id);
406 echo '</td></tr>';
407 echo '</table>';
408
409 echo '<input type="submit" name="submit" value="'.get_string('savechanges').'" />';
410 echo '<input type="submit" name="cancel" value="'.get_string('cancel').'" />';
411 echo '</form>';
412 print_footer('none');
d699cd1e 413 }
414
d699cd1e 415
b0f2597e 416 /*
417 * Display all the submissions ready for grading
418 */
419 function display_submissions() {
3446205d 420
b0f2597e 421 global $CFG, $db;
3446205d 422
b0f2597e 423 $teacherattempts = true; /// Temporary measure
1b5910c4 424
b0f2597e 425 $page = optional_param('page', 0);
426 $perpage = optional_param('perpage', 10);
d699cd1e 427
b0f2597e 428 $strsaveallfeedback = get_string('saveallfeedback', 'assignment');
d0ac6bc2 429
b0f2597e 430 /// Some shortcuts to make the code read better
431
432 $course = $this->course;
433 $assignment = $this->assignment;
434 $cm = $this->cm;
91719320 435
91719320 436
b0f2597e 437 add_to_log($course->id, 'assignment', 'view submission', 'submissions.php?id='.$this->assignment->id, $this->assignment->id, $this->cm->id);
438
439 print_header_simple($this->assignment->name, "", '<a href="index.php?id='.$course->id.'">'.$this->strassignments.'</a> -> <a href="view.php?a='.$this->assignment->id.'">'.$this->assignment->name.'</a> -> '. $this->strsubmissions, '', '', true, update_module_button($cm->id, $course->id, $this->strassignment), navmenu($course, $cm));
91719320 440
91719320 441
9437c854 442 $tablecolumns = array('picture', 'fullname', 'grade', 'comment', 'timemodified', 'timemarked', 'status');
443 $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'));
91719320 444
d0ac6bc2 445
b0f2597e 446 require_once($CFG->libdir.'/tablelib.php');
447 $table = new flexible_table('mod-assignment-submissions');
448
449 $table->define_columns($tablecolumns);
450 $table->define_headers($tableheaders);
451 $table->define_baseurl($CFG->wwwroot.'/mod/assignment/submissions.php?id='.$this->cm->id);
452
453 $table->sortable(true);
454 $table->collapsible(true);
455 $table->initialbars(true);
456
457 $table->column_suppress('picture');
458 $table->column_suppress('fullname');
459
460 $table->column_class('picture', 'picture');
9437c854 461 $table->column_class('fullname', 'fullname');
462 $table->column_class('grade', 'grade');
463 $table->column_class('comment', 'comment');
464 $table->column_class('timemodified', 'timemodified');
465 $table->column_class('timemarked', 'timemarked');
466 $table->column_class('status', 'status');
b0f2597e 467
468 $table->set_attribute('cellspacing', '0');
469 $table->set_attribute('id', 'attempts');
9437c854 470 $table->set_attribute('class', 'submissions');
b0f2597e 471 $table->set_attribute('width', '90%');
472 $table->set_attribute('align', 'center');
473
474 // Start working -- this is necessary as soon as the niceties are over
475 $table->setup();
476
05855091 477
05855091 478
b0f2597e 479 /// Check to see if groups are being used in this assignment
480 if ($groupmode = groupmode($course, $cm)) { // Groups are being used
306dc7e5 481 $currentgroup = setup_and_print_groups($course, $groupmode, 'submissions.php?id='.$this->cm->id);
b0f2597e 482 } else {
483 $currentgroup = false;
05855091 484 }
05855091 485
0f1a97c2 486
b0f2597e 487 /// Get all teachers and students
488 if ($currentgroup) {
489 $users = get_group_users($currentgroup);
490 } else {
491 $users = get_course_users($course->id);
492 }
493
494 if (!$teacherattempts) {
495 $teachers = get_course_teachers($course->id);
496 if (!empty($teachers)) {
497 $keys = array_keys($teachers);
498 }
499 foreach ($keys as $key) {
500 unset($users[$key]);
501 }
502 }
503
504 if (empty($users)) {
505 print_heading($strnoattempts);
506 return true;
507 }
0f1a97c2 508
0f1a97c2 509
b0f2597e 510 /// Construct the SQL
0f1a97c2 511
b0f2597e 512 if ($where = $table->get_sql_where()) {
513 $where = str_replace('firstname', 'u.firstname', $where);
514 $where = str_replace('lastname', 'u.lastname', $where);
515 $where .= ' AND ';
516 }
0f1a97c2 517
b0f2597e 518 if ($sort = $table->get_sql_sort()) {
519 $sortparts = explode(',', $sort);
520 $newsort = array();
521 foreach ($sortparts as $sortpart) {
522 $sortpart = trim($sortpart);
523 $newsort[] = $sortpart;
524 }
525 $sort = ' ORDER BY '.implode(', ', $newsort);
526 }
9fa49e22 527
9fa49e22 528
9437c854 529 $select = 'SELECT '.$db->Concat('u.id', '\'#\'', $db->IfNull('s.userid', '0')).' AS uvs, u.id, u.firstname, u.lastname, u.picture, s.id AS submissionid, s.grade, s.comment, s.timemodified, s.timemarked, ((s.timemarked > 0) && (s.timemarked >= s.timemodified)) AS status ';
d59269cf 530 $group = 'GROUP BY uvs ';
b0f2597e 531 $sql = 'FROM '.$CFG->prefix.'user u '.
306dc7e5 532 'LEFT JOIN '.$CFG->prefix.'assignment_submissions s ON u.id = s.userid AND s.assignment = '.$this->assignment->id.' '.
533 'WHERE '.$where.'u.id IN ('.implode(',', array_keys($users)).') ';
8ff79e8c 534
8ff79e8c 535
d59269cf 536 $total = count_records_sql('SELECT COUNT(DISTINCT('.$db->Concat('u.id', '\'#\'', $db->IfNull('s.userid', '0')).')) '.$sql);
000cc405 537
b0f2597e 538 $table->pagesize($perpage, $total);
539
540 if($table->get_page_start() !== '' && $table->get_page_size() !== '') {
541 $limit = ' '.sql_paging_limit($table->get_page_start(), $table->get_page_size());
542 }
543 else {
544 $limit = '';
545 }
9fa49e22 546
b0f2597e 547 $strupdate = get_string('update');
9437c854 548 $strgrade = get_string('grade');
b0f2597e 549 $grademenu = make_grades_menu($this->assignment->grade);
550
9437c854 551 if (($ausers = get_records_sql($select.$sql.$group.$sort.$limit)) !== false) {
d59269cf 552
d59269cf 553 foreach ($ausers as $auser) {
554 $picture = print_user_picture($auser->id, $course->id, $auser->picture, false, true);
555 if (!empty($auser->submissionid)) {
556 if ($auser->timemodified > 0) {
557 $studentmodified = '<div id="ts'.$auser->id.'">'.userdate($auser->timemodified).'</div>';
d59269cf 558 } else {
9437c854 559 $studentmodified = '<div id="ts'.$auser->id.'">&nbsp;</div>';
d59269cf 560 }
561 if ($auser->timemarked > 0) {
562 $teachermodified = '<div id="tt'.$auser->id.'">'.userdate($auser->timemarked).'</div>';
b0f2597e 563 } else {
9437c854 564 $teachermodified = '<div id="tt'.$auser->id.'">&nbsp;</div>';
b0f2597e 565 }
9437c854 566
d59269cf 567 $grade = '<div id="g'.$auser->id.'">'.$this->display_grade($auser->grade).'</div>';
9437c854 568 $comment = '<div id="com'.$auser->id.'">'.shorten_text($auser->comment, 15).'</div>';
d59269cf 569
b0f2597e 570 } else {
9437c854 571 $studentmodified = '<div id="ts'.$auser->id.'">&nbsp;</div>';
572 $teachermodified = '<div id="tt'.$auser->id.'">&nbsp;</div>';
d59269cf 573 $status = '<div id="st'.$auser->id.'"></div>';
9437c854 574 $grade = '<div id="g'.$auser->id.'">&nbsp;</div>';
575 $comment = '<div id="com'.$auser->id.'">&nbsp;</div>';
b0f2597e 576 }
9fa49e22 577
0f7d4e5e 578 if ($auser->status === NULL) {
579 $auser->status = 0;
580 }
581
9437c854 582 $buttontext = ($auser->status == 1) ? $strupdate : $strgrade;
9fa49e22 583
9437c854 584 $button = button_to_popup_window ('/mod/assignment/submissions.php?id='.$this->cm->id.'&amp;userid='.$auser->id.'&amp;mode=single',
0f7d4e5e 585 'grade'.$auser->id, $buttontext, 450, 600, $buttontext, 'none', true, 'button'.$auser->id);
586
9437c854 587 $status = '<div id="up'.$auser->id.'" class="s'.$auser->status.'">'.$button.'</div>';
306dc7e5 588
9437c854 589 $row = array($picture, fullname($auser), $grade, $comment, $studentmodified, $teachermodified, $status);
d59269cf 590 $table->add_data($row);
591 }
b0f2597e 592 }
d699cd1e 593
b0f2597e 594 $table->print_html();
d699cd1e 595
b0f2597e 596 print_footer($this->course);
d699cd1e 597
8e340cb0 598 }
d699cd1e 599
d699cd1e 600
d699cd1e 601
b0f2597e 602 /*
603 * Display and process the submissions
604 */
605 function process_feedback() {
d699cd1e 606
b0f2597e 607 global $USER;
d699cd1e 608
b0f2597e 609 if (!$feedback = data_submitted()) { // No incoming data?
610 return false;
d699cd1e 611 }
b7b42874 612
b0f2597e 613 if (!empty($feedback->cancel)) { // User hit cancel button
614 return false;
615 }
d699cd1e 616
0f7d4e5e 617 $newsubmission = $this->get_submission($feedback->userid, true); // Get or make one
d699cd1e 618
b0f2597e 619 $newsubmission->grade = $feedback->grade;
620 $newsubmission->comment = $feedback->comment;
621 $newsubmission->teacher = $USER->id;
622 $newsubmission->mailed = 0; // Make sure mail goes out (again, even)
623 $newsubmission->timemarked = time();
d699cd1e 624
b0f2597e 625 if (empty($submission->timemodified)) { // eg for offline assignments
626 $newsubmission->timemodified = time();
627 }
d699cd1e 628
b0f2597e 629 if (! update_record('assignment_submissions', $newsubmission)) {
630 return false;
631 }
d699cd1e 632
b0f2597e 633 add_to_log($this->course->id, 'assignment', 'update grades',
634 'submissions.php?id='.$this->assignment->id.'&user='.$feedback->userid, $feedback->userid, $this->cm->id);
635
636 return $newsubmission;
d699cd1e 637
d699cd1e 638 }
d699cd1e 639
d699cd1e 640
0f7d4e5e 641 function get_submission($userid, $createnew=false) {
b0f2597e 642 $submission = get_record('assignment_submissions', 'assignment', $this->assignment->id, 'userid', $userid);
d699cd1e 643
b0f2597e 644 if ($submission || !$createnew) {
645 return $submission;
646 }
d699cd1e 647
b0f2597e 648 $newsubmission = new Object;
649 $newsubmission->assignment = $this->assignment->id;
650 $newsubmission->userid = $userid;
651 $newsubmission->timecreated = time();
652 if (!insert_record("assignment_submissions", $newsubmission)) {
653 error("Could not insert a new empty submission");
654 }
d699cd1e 655
b0f2597e 656 return get_record('assignment_submissions', 'assignment', $this->assignment->id, 'userid', $userid);
657 }
d699cd1e 658
3f8247c2 659
b0f2597e 660 function get_submissions($sort='', $dir='DESC') {
661 /// Return all assignment submissions by ENROLLED students (even empty)
662 global $CFG;
663
664 if ($sort == "lastname" or $sort == "firstname") {
665 $sort = "u.$sort $dir";
666 } else if (empty($sort)) {
667 $sort = "a.timemodified DESC";
668 } else {
669 $sort = "a.$sort $dir";
d699cd1e 670 }
d699cd1e 671
b0f2597e 672 $select = "s.course = '$this->assignment->course' AND";
673 $site = get_site();
674 if ($this->assignment->course == $site->id) {
675 $select = '';
676 }
677 return get_records_sql("SELECT a.*
678 FROM {$CFG->prefix}assignment_submissions a,
679 {$CFG->prefix}user_students s,
680 {$CFG->prefix}user u
681 WHERE a.userid = s.userid
682 AND u.id = a.userid
683 AND $select a.assignment = '$this->assignment->id'
684 ORDER BY $sort");
685 }
686
687
688 function count_real_submissions($groupid=0) {
689 /// Return all real assignment submissions by ENROLLED students (not empty ones)
690 global $CFG;
691
692 if ($groupid) { /// How many in a particular group?
693 return count_records_sql("SELECT COUNT(DISTINCT g.userid, g.groupid)
694 FROM {$CFG->prefix}assignment_submissions a,
695 {$CFG->prefix}groups_members g
696 WHERE a.assignment = {$this->assignment->id}
697 AND a.timemodified > 0
698 AND g.groupid = '$groupid'
699 AND a.userid = g.userid ");
700 } else {
701 $select = "s.course = '{$this->assignment->course}' AND";
702 if ($this->assignment->course == SITEID) {
703 $select = '';
d699cd1e 704 }
b0f2597e 705 return count_records_sql("SELECT COUNT(*)
706 FROM {$CFG->prefix}assignment_submissions a,
707 {$CFG->prefix}user_students s
708 WHERE a.assignment = '{$this->assignment->id}'
709 AND a.timemodified > 0
710 AND $select a.userid = s.userid ");
711 }
d59269cf 712 }
d699cd1e 713
b0f2597e 714} ////// End of the assignment_base class
d699cd1e 715
18b8fbfa 716
04eba58f 717
b0f2597e 718/// OTHER STANDARD FUNCTIONS ////////////////////////////////////////////////////////
719
720
721function assignment_delete_instance($id){
26b90e70 722 global $CFG;
723
b0f2597e 724 if (! $assignment = get_record('assignment', 'id', $id)) {
725 return false;
26b90e70 726 }
727
b0f2597e 728 require_once("$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php");
729 $assignmentclass = "assignment_$assignment->assignmenttype";
730 $ass = new $assignmentclass();
731 return $ass->delete_instance($assignment);
732}
f466c9ed 733
ac21ad39 734
b0f2597e 735function assignment_update_instance($assignment){
736 global $CFG;
26b90e70 737
b0f2597e 738 require_once("$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php");
739 $assignmentclass = "assignment_$assignment->assignmenttype";
740 $ass = new $assignmentclass();
741 return $ass->update_instance($assignment);
742}
26b90e70 743
26b90e70 744
b0f2597e 745function assignment_add_instance($assignment) {
746 global $CFG;
f466c9ed 747
b0f2597e 748 require_once("$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php");
749 $assignmentclass = "assignment_$assignment->assignmenttype";
750 $ass = new $assignmentclass();
751 return $ass->add_instance($assignment);
752}
f466c9ed 753
b0f2597e 754function assignment_types() {
755 $types = array();
756 $names = get_list_of_plugins('mod/assignment/type');
757 foreach ($names as $name) {
758 $types[$name] = get_string('type'.$name, 'assignment');
ffeca120 759 }
b0f2597e 760 asort($types);
761 return $types;
f466c9ed 762}
763
b0f2597e 764function assignment_upgrade_submodules() {
f1c1d2f1 765 global $CFG;
26b90e70 766
b0f2597e 767 $types = assignment_types();
26b90e70 768
b0f2597e 769 include_once($CFG->dirroot.'/mod/assignment/version.php'); // defines $module with version etc
26b90e70 770
b0f2597e 771 foreach ($types as $type) {
26b90e70 772
b0f2597e 773 $fullpath = $CFG->dirroot.'/mod/assignment/type/'.$type;
26b90e70 774
b0f2597e 775 /// Check for an external version file (defines $submodule)
26b90e70 776
b0f2597e 777 if (!is_readable($fullpath .'/version.php')) {
778 continue;
ffeca120 779 }
b0f2597e 780 unset($module);
781 include_once($fullpath .'/version.php');
26b90e70 782
b0f2597e 783 /// Check whether we need to upgrade
26b90e70 784
b0f2597e 785 if (!isset($submodule->version)) {
786 continue;
787 }
26b90e70 788
b0f2597e 789 /// Make sure this submodule will work with this assignment version
26b90e70 790
b0f2597e 791 if (isset($submodule->requires) and ($submodules->requires > $module->version)) {
792 notify("Assignment submodule '$type' is too new for your assignment");
793 continue;
794 }
f466c9ed 795
b0f2597e 796 /// If we use versions, make sure an internal record exists
f466c9ed 797
b0f2597e 798 $currentversion = 'assignment_'.$type.'_version';
f466c9ed 799
b0f2597e 800 if (!isset($CFG->$currentversion)) {
801 set_config($currentversion, 0);
f466c9ed 802 }
f466c9ed 803
b0f2597e 804 /// See if we need to upgrade
805
806 if ($submodule->version <= $CFG->$currentversion) {
807 continue;
59c005b7 808 }
59c005b7 809
b0f2597e 810 /// Look for the upgrade file
59c005b7 811
b0f2597e 812 if (!is_readable($fullpath .'/db/'.$CFG->dbtype.'.php')) {
813 continue;
814 }
59c005b7 815
b0f2597e 816 include_once($fullpath .'/db/'. $CFG->dbtype .'.php'); // defines assignment_xxx_upgrade
59c005b7 817
b0f2597e 818 /// Perform the upgrade
59c005b7 819
b0f2597e 820 $upgrade_function = 'assignment_'.$type.'_upgrade';
821 if (function_exists($upgrade_function)) {
822 $db->debug=true;
823 if ($upgrade_function($CFG->$currentversion)) {
824 $db->debug=false;
825 set_config($currentversion, $submodule->version);
59c005b7 826 }
b0f2597e 827 $db->debug=false;
59c005b7 828 }
829 }
9437c854 830
831
59c005b7 832}
833
04eba58f 834?>