Merge commit 'catalyst/MOODLE_19_STABLE' into mdl19-linuxchix
[moodle-linuxchix.git] / mod / exercise / locallib.php
blobe7a12fbd6622780199fd406af74dc8ea939c7318
1 <?php // $Id$
3 /// Library of extra functions for the exercise module
5 //////////////////////////////////////////////////////////////////////////////////////
7 /*** Functions for the exercise module ******
9 function exercise_add_custom_scales($exercise) {
10 function exercise_compare_assessments($exercise, $assessment1, $assessment2) {
11 function exercise_copy_assessment($assessment, $submission, $withfeedback = false) {
12 function exercise_count_all_submissions_for_assessment($exercise, $user) {
13 function exercise_count_assessments($submission) {
14 function exercise_count_assessments_by_teacher($exercise, $teacher) {
15 function exercise_count_student_submissions($exercise) {
16 function exercise_count_teacher_assessments($exercise, $user) {
17 function exercise_count_teacher_submissions($exercise) {
18 function exercise_count_teacher_submissions_for_assessment($exercise, $user) {
19 function exercise_count_unassessed_student_submissions($exercise) {
20 function exercise_count_ungraded_assessments_student($exercise) {
21 function exercise_count_ungraded_assessments_teacher($exercise) {
22 function exercise_count_user_assessments($exercise, $user, $type = "all") { $type is all, student or teacher
23 function exercise_count_user_assessments_done($exercise,$user) {
24 function exercise_count_user_submissions($exercise, $user) {
26 function exercise_delete_submitted_files($exercise, $submission) {
27 function exercise_delete_user_files($exercise, $user, $exception) {
29 function exercise_file_area($exercise, $submission) { <--- in lib.php
30 function exercise_file_area_name($exercise, $submission) { <--- in lib.php
32 function exercise_get_assess_logs($course, $timestart) { <--- in lib.php
33 function exercise_get_assessments($submission) <--- in lib.php{
34 function exercise_get_best_submission_grades($exercise) { <--- in lib.php
35 function exercise_get_grade_logs($course, $timestart) { <--- in lib.php
36 function exercise_get_mean_submission_grades($exercise) { <--- in lib.php
37 function exercise_get_student_submission($exercise, $user) {
38 function exercise_get_student_submissions($exercise) {
39 function exercise_get_submission_assessment($submission, $user) {
40 function exercise_get_submit_logs($course, $timestart) {
41 function exercise_get_teacher_submission_assessments($exercise) { <--- in lib.php
42 function exercise_get_teacher_submissions($exercise) {
43 function exercise_get_ungraded_assessments($exercise) {
44 function exercise_get_unmailed_assessments($cutofftime) { <--- in lib.php
45 function exercise_get_unmailed_graded_assessments($cutofftime) { <--- in lib.php
46 function exercise_get_user_assessments($exercise, $user) {
47 function exercise_get_user_submissions($exercise, $user) {
49 function exercise_list_all_ungraded_assessments($exercise) {
50 function exercise_list_submissions_for_admin($exercise) {
51 function exercise_list_teacher_assessments($exercise, $user) {
52 function exercise_list_teacher_submissions($exercise, $user, $reassess) {
53 function exercise_list_unassessed_student_submissions($exercise, $user) {
54 function exercise_list_unassessed_teacher_submissions($exercise, $user) {
55 function exercise_list_ungraded_assessments($exercise, $stype) {
56 function exercise_list_user_submissions($exercise, $user) {
59 function exercise_print_assessment_form($exercise, $assessment, $allowchanges, $returnto)
60 function exercise_print_assessments_by_user_for_admin($exercise, $user) {
61 function exercise_print_assessments_for_admin($exercise, $submission) {
62 function exercise_print_assignment_info($exercise) {
63 function exercise_print_difference($time) {
64 function exercise_print_feedback($course, $submission) {
65 function exercise_print_league_table($exercise) {
66 function exercise_print_submission_assessments($exercise, $submission, $type) {
67 function exercise_print_submission_title($exercise, $submission) { <--- in lib.php
68 function exercise_print_tabbed_table($table) {
69 function exercise_print_teacher_assessment_form($exercise, $assessment, $submission, $returnto)
70 function exercise_print_teacher_table($course) {
71 function exercise_print_time_to_deadline($time) {
72 function exercise_print_upload_form($exercise) {
73 function exercise_print_user_assessments($exercise, $user) {
75 function exercise_test_for_resubmission($exercise, $user) {
76 function exercise_test_user_assessments($exercise, $user) {
77 ***************************************/
79 ///////////////////////////////////////////////////////////////////////////////////////////////
80 function exercise_add_custom_scales($exercise) {
81 global $EXERCISE_SCALES;
83 if (! $course = get_record("course", "id", $exercise->course)) {
84 error("Course is misconfigured");
87 if ($scales = get_records("scale", "courseid", $course->id, "name ASC")) {
88 foreach ($scales as $scale) {
89 $labels = explode(",", $scale->scale);
90 $EXERCISE_SCALES[] = array('name' => $scale->name, 'type' => 'radio', 'size' => count($labels),
91 'start' => trim($labels[0]), 'end' => trim($labels[count($labels) - 1]));
94 return;
97 ///////////////////////////////////////////////////////////////////////////////////////////////
98 function exercise_compare_assessments($exercise, $assessment1, $assessment2) {
99 global $EXERCISE_ASSESSMENT_COMPS, $EXERCISE_EWEIGHTS;
100 // first get the assignment elements for maxscores...
101 $elementsraw = get_records("exercise_elements", "exerciseid", $exercise->id, "elementno ASC");
102 foreach ($elementsraw as $element) {
103 $maxscore[] = $element->maxscore; // to renumber index 0,1,2...
104 $weight[] = $EXERCISE_EWEIGHTS[$element->weight]; // get real value and renumber index 0,1,2...
106 for ($i = 0; $i < 2; $i++) {
107 if ($i) {
108 $rawgrades = get_records("exercise_grades", "assessmentid", $assessment1->id, "elementno ASC");
109 } else {
110 $rawgrades = get_records("exercise_grades", "assessmentid", $assessment2->id, "elementno ASC");
112 foreach ($rawgrades as $grade) {
113 $grades[$i][] = $grade->grade;
116 $sumdiffs = 0;
117 $sumweights = 0;
118 switch ($exercise->gradingstrategy) {
119 case 1 : // accumulative grading and...
120 case 4 : // ...rubic grading
121 for ($i=0; $i < $exercise->nelements; $i++) {
122 $diff = ($grades[0][$i] - $grades[1][$i]) * $weight[$i] / $maxscore[$i];
123 $sumdiffs += $diff * $diff; // use squared distances
124 $sumweights += $weight[$i];
126 break;
127 case 2 : // error banded grading
128 // ignore maxscores here, the grades are either 0 or 1,
129 for ($i=0; $i < $exercise->nelements; $i++) {
130 $diff = ($grades[0][$i] - $grades[1][$i]) * $weight[$i];
131 $sumdiffs += $diff * $diff; // use squared distances
132 $sumweights += $weight[$i];
134 break;
135 case 3 : // criterion grading
136 // here we only need to look at the difference between the "zero" grade elements
137 $diff = ($grades[0][0] - $grades[1][0]) / (count($elementsraw) - 1);
138 $sumdiffs = $diff * $diff;
139 $sumweights = 1;
140 break;
142 // convert to a sensible grade (always out of 100)
143 $COMP = (object)$EXERCISE_ASSESSMENT_COMPS[$exercise->assessmentcomps];
144 $factor = $COMP->value;
145 $gradinggrade = (($factor - ($sumdiffs / $sumweights)) / $factor) * 100;
146 if ($gradinggrade < 0) {
147 $gradinggrade = 0;
149 return $gradinggrade;
152 ///////////////////////////////////////////////////////////////////////////////////////////////
153 function exercise_copy_assessment($assessment, $submission, $withfeedback = false) {
154 // adds a copy of the given assessment for the submission specified to the exercise_assessemnts table.
155 // The grades and optionally the comments are added to the exercise_grades table. Returns the new
156 // assessment object
157 global $USER;
159 $yearfromnow = time() + 365 * 86400;
160 $newassessment->exerciseid = $assessment->exerciseid;
161 $newassessment->submissionid = $submission->id;
162 $newassessment->userid = $USER->id;
163 $newassessment->timecreated = $yearfromnow;
164 $newassessment->timegraded = 0;
165 $newassessment->grade = $assessment->grade;
166 if ($withfeedback) {
167 $newassessment->generalcomment = addslashes($assessment->generalcomment);
168 $newassessment->teachercomment = addslashes($assessment->teachercomment);
170 if (!$newassessment->id = insert_record("exercise_assessments", $newassessment)) {
171 error("Copy Assessment: Could not insert exercise assessment!");
174 if ($grades = get_records("exercise_grades", "assessmentid", $assessment->id)) {
175 foreach ($grades as $grade) {
176 unset($grade->id); // clear id, insert record now seems to believe it!
177 if (!$withfeedback) {
178 $grade->feedback = '';
180 else {
181 $grade->feedback = addslashes($grade->feedback);
182 // $grade->feedback = $grade->feedback;
184 $grade->assessmentid = $newassessment->id;
185 if (!$grade->id = insert_record("exercise_grades", $grade)) {
186 error("Copy Assessment: Could not insert exercise grade!");
190 if ($withfeedback) {
191 // remove the slashes from comments as the new assessment record is used
192 // in assessments and in lib
193 $newassessment->generalcomment = stripslashes($assessment->generalcomment);
194 $newassessment->teachercomment = stripslashes($assessment->teachercomment);
197 return $newassessment;
202 ///////////////////////////////////////////////////////////////////////////////////////////////
203 function exercise_count_all_submissions_for_assessment($exercise, $user) {
204 // looks at all submissions and deducts the number which has been assessed by this user
205 $n = 0;
206 if ($submissions = get_records_select("exercise_submissions", "exerciseid = $exercise->id AND timecreated > 0")) {
207 $n =count($submissions);
208 foreach ($submissions as $submission) {
209 $n -= count_records("exercise_assessments", "submissionid", $submission->id, "userid", $user->id);
212 return $n;
216 ///////////////////////////////////////////////////////////////////////////////////////////////
217 function exercise_count_assessments($submission) {
218 // Return the (cold) assessments for this submission,
219 global $CFG;
221 $timethen = time() - $CFG->maxeditingtime;
222 return count_records_select("exercise_assessments", "submissionid = $submission->id AND
223 timecreated < $timethen");
227 ///////////////////////////////////////////////////////////////////////////////////////////////
228 function exercise_count_assessments_by_teacher($exercise, $teacher) {
229 // Return the number of assessments done by a teacher
231 return count_records_select("exercise_assessments", "exerciseid = $exercise->id AND
232 userid = $teacher->id");
236 ///////////////////////////////////////////////////////////////////////////////////////////////
237 function exercise_count_student_submissions($exercise) {
238 global $CFG;
240 // make sure it works on the site course
241 // Where is table u? I remove it, try to make SQL correct.
242 // $select = "u.course = '$exercise->course' AND";
243 // if ($exercise->course == SITEID) {
244 // $select = '';
245 // }
247 return count_records_sql("SELECT count(*) FROM {$CFG->prefix}exercise_submissions s
248 WHERE s.exerciseid = $exercise->id
249 AND timecreated > 0");
253 ///////////////////////////////////////////////////////////////////////////////////////////////
254 function exercise_count_teacher_assessments($exercise, $user) {
255 // returns the number of assessments made by teachers on user's submissions
257 $n = 0;
258 if ($submissions = exercise_get_user_submissions($exercise, $user)) {
259 foreach ($submissions as $submission) {
260 if ($assessments = exercise_get_assessments($submission)) {
261 foreach ($assessments as $assessment) {
262 // count only teacher assessments
263 if (isteacher($exercise->course, $assessment->userid)) {
264 $n++;
270 return $n;
274 ///////////////////////////////////////////////////////////////////////////////////////////////
275 function exercise_count_teacher_submissions($exercise) {
277 return count_records("exercise_submissions", "isexercise", 1, "exerciseid", $exercise->id);
281 ///////////////////////////////////////////////////////////////////////////////////////////////
282 function exercise_count_teacher_submissions_for_assessment($exercise, $user) {
284 $n = 0;
285 if ($submissions = exercise_get_teacher_submissions($exercise)) {
286 $n =count($submissions);
287 foreach ($submissions as $submission) {
288 $n -= count_records("exercise_assessments", "submissionid", $submission->id, "userid", $user->id);
291 return $n;
295 ///////////////////////////////////////////////////////////////////////////////////////////////
296 function exercise_count_unassessed_student_submissions($exercise) {
297 // returns the number of students submissions which have not been assessed by a teacher
298 global $CFG;
300 if (! $course = get_record("course", "id", $exercise->course)) {
301 error("Course is misconfigured");
303 $timenow = time();
304 $n = 0;
305 // look at all the student submissions, exercise_get_student_submissions is group aware
306 $groupid = get_current_group($course->id);
307 if ($submissions = exercise_get_student_submissions($exercise, "time", $groupid)) {
308 foreach ($submissions as $submission) {
309 // only look at "cold" submissions
310 if ($submission->timecreated < $timenow - $CFG->maxeditingtime) {
311 $teacherassessed = false;
312 if ($assessments = exercise_get_assessments($submission)) {
313 foreach ($assessments as $assessment) {
314 // exercise_get_assessments only returns "cold" assessments, look for one made by a teacher
315 if (isteacher($course->id, $assessment->userid)) {
316 $teacherassessed = true;
317 break; // no need to look further
321 if (!$teacherassessed) {
322 $n++;
327 return $n;
331 ///////////////////////////////////////////////////////////////////////////////////////////////
332 function exercise_count_ungraded_assessments_student($exercise, $groupid = 0) {
333 // function returns the number of ungraded assessments by students of STUDENT submissions
335 $n = 0;
336 if ($submissions = exercise_get_student_submissions($exercise, $groupid)) {
337 foreach ($submissions as $submission) {
338 if ($assessments = exercise_get_assessments($submission)) {
339 foreach ($assessments as $assessment) {
340 if ($assessment->timegraded == 0) {
341 // ignore teacher assessments
342 if (!isteacher($exercise->course, $assessment->userid)) {
343 $n++;
350 return $n;
354 ///////////////////////////////////////////////////////////////////////////////////////////////
355 function exercise_count_ungraded_assessments_teacher($exercise) {
356 // function returns the number of ungraded assessments by students of TEACHER submissions
357 global $CFG;
359 $timenow = time();
360 $n = 0;
361 if ($submissions = exercise_get_teacher_submissions($exercise)) {
362 foreach ($submissions as $submission) {
363 if ($assessments = exercise_get_assessments($submission)) {
364 foreach ($assessments as $assessment) {
365 if ($assessment->timegraded == 0) {
366 // ignore teacher assessments
367 if (!isteacher($exercise->course, $assessment->userid)) {
368 // must have created a little time ago
369 if (($timenow - $assessment->timecreated) > $CFG->maxeditingtime) {
370 $n++;
378 return $n;
382 ///////////////////////////////////////////////////////////////////////////////////////////////
383 function exercise_count_user_assessments($exercise, $user, $stype = "all") {
384 // returns the number of assessments allocated/made by a user, all of them, or just those for the student or teacher submissions
385 // the student's self assessments are included in the count
386 // the maxeditingtime is NOT taken into account here also allocated assessments which have not yet
387 // been done are counted as well
389 $n = 0;
390 if ($assessments = exercise_get_user_assessments($exercise, $user)) {
391 foreach ($assessments as $assessment) {
392 switch ($stype) {
393 case "all" :
394 $n++;
395 break;
396 case "student" :
397 $submission = get_record("exercise_submissions", "id", $assessment->submissionid);
398 if (isstudent($exercise->course, $submission->userid)) {
399 $n++;
401 break;
402 case "teacher" :
403 $submission = get_record("exercise_submissions", "id", $assessment->submissionid);
404 if (isteacher($exercise->course, $submission->userid)) {
405 $n++;
407 break;
411 return $n;
415 ///////////////////////////////////////////////////////////////////////////////////////////////
416 function exercise_count_user_assessments_done($exercise, $user) {
417 // returns the number of assessments actually done by a user
418 // the student's self assessments are included in the count
419 // the maxeditingtime is NOT taken into account here
421 $n = 0;
422 $timenow = time();
423 if ($assessments = exercise_get_user_assessments($exercise, $user)) {
424 foreach ($assessments as $assessment) {
425 if ($assessment->timecreated < $timenow) {
426 $n++;
430 return $n;
434 ///////////////////////////////////////////////////////////////////////////////////////////////
435 function exercise_count_user_submissions($exercise, $user) {
436 // returns the number of submissions make by this user
437 return count_records("exercise_submissions", "exerciseid", $exercise->id, "userid", $user->id);
441 ///////////////////////////////////////////////////////////////////////////////////////////////
442 function exercise_delete_submitted_files($exercise, $submission) {
443 // Deletes the files in the exercise area for this submission
445 if ($basedir = exercise_file_area($exercise, $submission)) {
446 if ($files = get_directory_list($basedir)) {
447 foreach ($files as $file) {
448 if (unlink("$basedir/$file")) {
449 notify("Existing file '$file' has been deleted!");
451 else {
452 notify("Attempt to delete file $basedir/$file has failed!");
460 ///////////////////////////////////////////////////////////////////////////////////////////////
461 function exercise_delete_user_files($exercise, $user, $exception) {
462 // Deletes all the user files in the exercise area for a user
463 // EXCEPT for any file named $exception
465 if (!$submissions = exercise_get_submissions($exercise, $user)) {
466 notify("No submissions!");
467 return;
469 foreach ($submissions as $submission) {
470 if ($basedir = exercise_file_area($exercise, $submission)) {
471 if ($files = get_directory_list($basedir)) {
472 foreach ($files as $file) {
473 if ($file != $exception) {
474 unlink("$basedir/$file");
475 notify("Existing file '$file' has been deleted!");
484 ///////////////////////////////////////////////////////////////////////////////////////////////
485 function exercise_get_best_submission_grades($exercise) {
486 // Returns the grades of students' best submissions
487 global $CFG;
489 // make sure it works on the site course
490 // Where is table u? I remove it, try to make SQL correct.
491 // $select = "u.course = '$exercise->course' AND";
492 // if ($exercise->course == SITEID) {
493 // $select = '';
494 // }
496 return get_records_sql("SELECT DISTINCT s.userid, MAX(a.grade) AS grade FROM
497 {$CFG->prefix}exercise_submissions s,
498 {$CFG->prefix}exercise_assessments a
499 WHERE s.exerciseid = $exercise->id
500 AND s.late = 0
501 AND a.submissionid = s.id
502 GROUP BY s.userid");
506 ///////////////////////////////////////////////////////////////////////////////////////////////
507 function exercise_get_mean_grade($submission) {
508 // Returns the mean grade of students' submission (may, very occassionally, be more than one assessment)
509 global $CFG;
511 return get_record_sql("SELECT AVG(a.grade) AS grade FROM
512 {$CFG->prefix}exercise_assessments a
513 WHERE a.submissionid = $submission->id
514 GROUP BY a.submissionid");
518 ///////////////////////////////////////////////////////////////////////////////////////////////
519 function exercise_get_student_submission($exercise, $user) {
520 // Return a submission for a particular user
521 global $CFG;
523 $submission = get_record("exercise_submissions", "exerciseid", $exercise->id, "userid", $user->id);
524 if (!empty($submission->timecreated)) {
525 return $submission;
527 return NULL;
531 ///////////////////////////////////////////////////////////////////////////////////////////////
532 function exercise_get_student_submissions($exercise, $order = "time", $groupid = 0) {
533 // Return all ENROLLED student submissions
534 // if order can grade|title|name|nothing, nothing is oldest first, youngest last
535 global $CFG;
537 if ($groupid) {
538 // just look at a single group
539 if ($order == "grade") {
540 // allow for multiple assessments of submissions (coming from different teachers)
542 // make sure it works on the site course
543 // Where is table u? I remove it, try to make SQL correct.
544 // $select = "u.course = '$exercise->course' AND";
545 // if ($exercise->course == SITEID) {
546 // $select = '';
547 // }
549 return get_records_sql("SELECT s.*, AVG(a.grade) AS grade FROM
550 {$CFG->prefix}groups_members g, {$CFG->prefix}exercise_submissions s,
551 {$CFG->prefix}exercise_assessments a
552 WHERE g.groupid = $groupid
553 AND s.exerciseid = $exercise->id
554 AND a.submissionid = s.id
555 GROUP BY s.id
556 ORDER BY a.grade DESC");
559 if ($order == "title") {
560 $order = "s.title";
561 } elseif ($order == "name") {
562 $order = "n.firstname, n.lastname, s.timecreated DESC";
563 } elseif ($order == "time") {
564 $order = "s.timecreated";
567 // make sure it works on the site course
568 // Where is table u? I remove it, try to make SQL correct.
569 // $select = "u.course = '$exercise->course' AND";
570 // if ($exercise->course == SITEID) {
571 // $select = '';
572 // }
574 return get_records_sql("SELECT s.* FROM {$CFG->prefix}user n,
575 {$CFG->prefix}groups_members g, {$CFG->prefix}exercise_submissions s
576 WHERE g.groupid = $groupid
577 AND s.exerciseid = $exercise->id
578 ORDER BY $order");
581 else { // no group - all users
582 if ($order == "grade") {
583 // allow for multiple assessments of submissions (coming from different teachers)
585 // make sure it works on the site course
586 // Where is table u? I remove it, try to make SQL correct.
587 // $select = "u.course = '$exercise->course' AND";
588 // if ($exercise->course == SITEID) {
589 // $select = '';
590 // }
592 return get_records_sql("SELECT s.*, AVG(a.grade) AS grade FROM {$CFG->prefix}exercise_submissions s,
593 {$CFG->prefix}exercise_assessments a
594 WHERE s.exerciseid = $exercise->id
595 AND a.submissionid = s.id
596 GROUP BY s.id
597 ORDER BY a.grade DESC");
600 if ($order == "title") {
601 $order = "s.title";
602 } elseif ($order == "name") {
603 $order = "n.firstname, n.lastname, s.timecreated DESC";
604 } elseif ($order == "time") {
605 $order = "s.timecreated";
608 // make sure it works on the site course
609 // Where is table u? I remove it, try to make SQL correct.
610 // $select = "u.course = '$exercise->course' AND";
611 // if ($exercise->course == SITEID) {
612 // $select = '';
613 // }
615 return get_records_sql("SELECT s.* FROM {$CFG->prefix}exercise_submissions s,
616 {$CFG->prefix}user n
617 WHERE s.exerciseid = $exercise->id
618 ORDER BY $order");
623 ///////////////////////////////////////////////////////////////////////////////////////////////
624 function exercise_get_submission_assessment($submission, $user = null) {
625 // Return a user's assessment for this submission
626 if ($user) {
627 return get_record("exercise_assessments", "submissionid", $submission->id, "userid", $user->id);
628 } else { // likely to be the teacher's assessment
629 return get_record("exercise_assessments", "submissionid", $submission->id);
634 ///////////////////////////////////////////////////////////////////////////////////////////////
635 function exercise_get_teacher_submissions($exercise) {
636 // Return all teacher submissions, ordered by title
637 global $CFG;
639 return get_records_sql("SELECT s.* FROM {$CFG->prefix}exercise_submissions s
640 WHERE s.isexercise = 1
641 AND s.exerciseid = $exercise->id
642 ORDER BY s.title");
646 ///////////////////////////////////////////////////////////////////////////////////////////////
647 function exercise_get_ungraded_assessments($exercise) {
648 global $CFG;
649 // Return all assessments which have not been graded or just graded
650 $cutofftime =time() - $CFG->maxeditingtime;
651 return get_records_select("exercise_assessments", "exerciseid = $exercise->id AND (timegraded = 0 OR
652 timegraded > $cutofftime)", "timecreated");
656 ///////////////////////////////////////////////////////////////////////////////////////////////
657 function exercise_get_ungraded_assessments_student($exercise) {
658 global $CFG;
659 // Return all assessments which have not been graded or just graded of student's submissions
661 // make sure it works on the site course
662 // Where is table u? I remove it, try to make SQL correct.
663 // $select = "u.course = '$exercise->course' AND";
664 // if ($exercise->course == SITEID) {
665 // $select = '';
666 // }
668 $cutofftime =time() - $CFG->maxeditingtime;
669 return get_records_sql("SELECT a.* FROM {$CFG->prefix}exercise_submissions s
670 {$CFG->prefix}exercise_assessments a
671 WHERE s.exerciseid = $exercise->id
672 AND a.submissionid = s.id
673 AND (a.timegraded = 0 OR a.timegraded > $cutofftime)
674 AND a.timecreated < $cutofftime
675 ORDER BY a.timecreated ASC");
679 ///////////////////////////////////////////////////////////////////////////////////////////////
680 function exercise_get_ungraded_assessments_teacher($exercise) {
681 global $CFG;
682 // Return all assessments which have not been graded or just graded of teacher's submissions
684 $cutofftime =time() - $CFG->maxeditingtime;
685 return get_records_sql("SELECT a.* FROM {$CFG->prefix}exercise_submissions s, {$CFG->prefix}exercise_assessments a
686 WHERE s.isexercise = 1
687 AND s.exerciseid = $exercise->id
688 AND a.submissionid = s.id
689 AND (a.timegraded = 0 OR a.timegraded > $cutofftime)
690 AND a.timecreated < $cutofftime
691 ORDER BY a.timecreated ASC");
695 ///////////////////////////////////////////////////////////////////////////////////////////////
696 function exercise_get_user_assessments($exercise, $user) {
697 // Return all the user's assessments, newest first, oldest last
698 // students will have only one, teachers will have more...
699 return get_records_select("exercise_assessments", "exerciseid = $exercise->id AND userid = $user->id",
700 "timecreated DESC");
704 ///////////////////////////////////////////////////////////////////////////////////////////////
705 function exercise_list_all_ungraded_assessments($exercise) {
706 // lists all the assessments for comment by teacher
707 global $CFG;
709 $table->head = array (get_string("title", "exercise"), get_string("timeassessed", "exercise"), get_string("action", "exercise"));
710 $table->align = array ("left", "left", "left");
711 $table->size = array ("*", "*", "*");
712 $table->cellpadding = 2;
713 $table->cellspacing = 0;
714 $timenow = time();
716 if ($assessments = exercise_get_ungraded_assessments($exercise)) {
717 foreach ($assessments as $assessment) {
718 if (!isteacher($exercise->course, $assessment->userid)) {
719 if (($timenow - $assessment->timegraded) < $CFG->maxeditingtime) {
720 $action = "<a href=\"assessments.php?action=gradeassessment&amp;a=$exercise->id&amp;aid=$assessment->id\">".
721 get_string("edit", "exercise")."</a>";
723 else {
724 $action = "<a href=\"assessments.php?action=gradeassessment&amp;a=$exercise->id&amp;aid=$assessment->id\">".
725 get_string("gradeassessment", "exercise")."</a>";
727 $submission = get_record("exercise_submissions", "id", $assessment->submissionid);
728 $table->data[] = array(exercise_print_submission_title($exercise, $submission),
729 userdate($assessment->timecreated), $action);
732 if (isset($table->data)) {
733 print_table($table);
739 ///////////////////////////////////////////////////////////////////////////////////////////////
740 function exercise_list_submissions_for_admin($exercise) {
741 // list the teacher sublmissions first
742 global $CFG, $USER;
744 if (! $course = get_record("course", "id", $exercise->course)) {
745 error("Course is misconfigured");
747 if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
748 error("Course Module ID was incorrect");
750 $groupid = get_current_group($course->id);
752 exercise_print_assignment_info($exercise);
753 print_heading_with_help(get_string("administration"), "administration", "exercise");
754 echo"<p align=\"center\"><b><a href=\"assessments.php?action=teachertable&amp;id=$cm->id\">".
755 get_string("teacherassessmenttable", "exercise", $course->teacher)."</a></b></p>\n";
758 if (isteacheredit($course->id)) {
759 // list any teacher submissions
760 $table->head = array (get_string("title", "exercise"), get_string("submitted", "exercise"),
761 get_string("action", "exercise"));
762 $table->align = array ("left", "left", "left");
763 $table->size = array ("*", "*", "*");
764 $table->cellpadding = 2;
765 $table->cellspacing = 0;
767 if ($submissions = exercise_get_teacher_submissions($exercise)) {
768 foreach ($submissions as $submission) {
769 $action = "<a href=\"submissions.php?action=adminamendtitle&amp;id=$cm->id&amp;sid=$submission->id\">".
770 get_string("amendtitle", "exercise")."</a>";
771 if (isteacheredit($course->id)) {
772 $action .= " | <a href=\"submissions.php?action=adminconfirmdelete&amp;id=$cm->id&amp;sid=$submission->id\">".
773 get_string("delete", "exercise")."</a>";
775 $table->data[] = array(exercise_print_submission_title($exercise, $submission),
776 userdate($submission->timecreated), $action);
778 print_heading(get_string("studentsubmissions", "exercise", $course->teacher), "center");
779 print_table($table);
783 // list student assessments
784 // Get all the students...
785 if ($users = get_course_students($course->id, "u.lastname, u.firstname")) {
786 $timenow = time();
787 unset($table);
788 $table->head = array(get_string("name"), get_string("title", "exercise"),
789 get_string("assessed", "exercise"), get_string("action", "exercise"));
790 $table->align = array ("left", "left", "left", "left");
791 $table->size = array ("*", "*", "*", "*");
792 $table->cellpadding = 2;
793 $table->cellspacing = 0;
794 $nassessments = 0;
795 foreach ($users as $user) {
796 // check group membership, if necessary
797 if ($groupid) {
798 // check user's group
799 if (!groups_is_member($groupid, $user->id)) {
800 continue; // skip this user
803 if ($assessments = exercise_get_user_assessments($exercise, $user)) {
804 $title ='';
805 foreach ($assessments as $assessment) {
806 if (!$submission = get_record("exercise_submissions", "id", $assessment->submissionid)) {
807 error("exercise_list_submissions_for_admin: Submission record not found!");
809 $title .= $submission->title;
810 // test for allocated assesments which have not been done
811 if ($assessment->timecreated < $timenow) {
812 // show only warm or cold assessments
813 $title .= " {".number_format($assessment->grade * $exercise->grade / 100.0, 0);
814 if ($assessment->timegraded) {
815 $title .= "/".number_format($assessment->gradinggrade * $exercise->gradinggrade / 100.0, 0);
817 $title .= "} ";
818 if ($realassessments = exercise_count_user_assessments_done($exercise, $user)) {
819 $action = "<a href=\"assessments.php?action=adminlistbystudent&amp;id=$cm->id&amp;userid=$user->id\">".
820 get_string("view", "exercise")."</a>";
822 else {
823 $action ="";
825 $nassessments++;
826 $table->data[] = array(fullname($user), $title,
827 userdate($assessment->timecreated), $action);
832 if (isset($table->data)) {
833 if ($groupid) {
834 if (! groups_group_exists($groupid)) { //TODO:
835 error("List unassessed student submissions: group not found");
837 print_heading("$group->name ".get_string("studentassessments", "exercise", $course->student).
838 " [$nassessments]");
839 } else {
840 print_heading(get_string("studentassessments", "exercise", $course->student)." [$nassessments]");
842 print_table($table);
843 echo "<p align=\"center\">".get_string("noteonstudentassessments", "exercise");
844 echo "<br />{".get_string("maximumgrade").": $exercise->grade / ".
845 get_string("maximumgrade").": $exercise->gradinggrade}</p>\n";
846 // grading grade analysis
847 unset($table);
848 $table->head = array (get_string("count", "exercise"), get_string("mean", "exercise"),
849 get_string("standarddeviation", "exercise"), get_string("maximum", "exercise"),
850 get_string("minimum", "exercise"));
851 $table->align = array ("center", "center", "center", "center", "center");
852 $table->size = array ("*", "*", "*", "*", "*");
853 $table->cellpadding = 2;
854 $table->cellspacing = 0;
855 if ($groupid) {
856 $stats = get_record_sql("SELECT COUNT(*) as count, AVG(gradinggrade) AS mean,
857 STDDEV(gradinggrade) AS stddev, MIN(gradinggrade) AS min, MAX(gradinggrade) AS max
858 FROM {$CFG->prefix}groups_members g, {$CFG->prefix}exercise_assessments a
859 WHERE g.groupid = $groupid AND a.userid = g.userid AND a.timegraded > 0
860 AND a.exerciseid = $exercise->id");
861 } else { // no group/all participants
862 $stats = get_record_sql("SELECT COUNT(*) as count, AVG(gradinggrade) AS mean,
863 STDDEV(gradinggrade) AS stddev, MIN(gradinggrade) AS min, MAX(gradinggrade) AS max
864 FROM {$CFG->prefix}exercise_assessments a
865 WHERE a.timegraded > 0 AND a.exerciseid = $exercise->id");
867 $table->data[] = array($stats->count, number_format($stats->mean * $exercise->gradinggrade / 100.0, 1),
868 number_format($stats->stddev * $exercise->gradinggrade / 100.0, 1),
869 number_format($stats->max * $exercise->gradinggrade / 100.0, 1),
870 number_format($stats->min * $exercise->gradinggrade / 100.0, 1));
871 print_heading(get_string("gradinggrade", "exercise")." ".get_string("analysis", "exercise"));
872 print_table($table);
873 echo "<p align=\"center\"><a href=\"assessments.php?id=$cm->id&amp;action=regradestudentassessments\">".
874 get_string("regradestudentassessments", "exercise")."</a> ";
875 helpbutton("regrading", get_string("regradestudentassessments", "exercise"), "exercise");
876 echo "</p>\n";
880 // now the sudent submissions
881 unset($table);
882 if ($users) {
883 $table->head = array (get_string("submittedby", "exercise"), get_string("title", "exercise"),
884 get_string("submitted", "exercise"), get_string("action", "exercise"));
885 $table->align = array ("left", "left", "left", "left");
886 $table->size = array ("*", "*", "*", "*");
887 $table->cellpadding = 2;
888 $table->cellspacing = 0;
890 $nsubmissions = 0;
891 foreach ($users as $user) {
892 // check group membership, if necessary
893 if ($groupid) {
894 // check user's group
895 if (!groups_is_member($groupid, $user->id)) {
896 continue; // skip this user
899 if ($submissions = exercise_get_user_submissions($exercise, $user)) {
900 foreach ($submissions as $submission) {
901 $action = "<a href=\"submissions.php?action=adminamendtitle&amp;id=$cm->id&amp;sid=$submission->id\">".
902 get_string("amendtitle", "exercise")."</a>";
903 // has teacher already assessed this submission
904 if ($assessment = get_record_select("exercise_assessments",
905 "submissionid = $submission->id AND userid = $USER->id")) {
906 $curtime = time();
907 if (($curtime - $assessment->timecreated) > $CFG->maxeditingtime) {
908 $action .= " | <a href=\"assessments.php?action=assesssubmission&amp;id=$cm->id&amp;sid=$submission->id\">".
909 get_string("reassess", "exercise")."</a>";
911 else { // there's still time left to edit...
912 $action .= " | <a href=\"assessments.php?action=assesssubmission&amp;id=$cm->id&amp;sid=$submission->id\">".
913 get_string("edit", "exercise")."</a>";
916 else { // user has not assessed this submission
917 $action .= " | <a href=\"assessments.php?action=assesssubmission&amp;id=$cm->id&amp;sid=$submission->id\">".
918 get_string("assess", "exercise")."</a>";
920 if ($nassessments = exercise_count_assessments($submission)) {
921 $action .= " | <a href=\"assessments.php?action=adminlist&amp;id=$cm->id&amp;sid=$submission->id\">".
922 get_string("view", "exercise")." ($nassessments)</a>";
924 if ($submission->late) {
925 $action .= " | <a href=\"submissions.php?action=adminlateflag&amp;id=$cm->id&amp;sid=$submission->id\">".
926 get_string("clearlateflag", "exercise")."</a>";
928 $action .= " | <a href=\"submissions.php?action=adminconfirmdelete&amp;id=$cm->id&amp;sid=$submission->id\">".
929 get_string("delete", "exercise")."</a>";
930 $title = $submission->title;
931 if ($submission->resubmit) {
932 $title .= "*";
934 $datesubmitted = userdate($submission->timecreated);
935 if ($submission->late) {
936 $datesubmitted = "<font color=\"red\">".$datesubmitted."</font>";
938 $table->data[] = array(fullname($user), $title.
939 " ".exercise_print_submission_assessments($exercise, $submission),
940 $datesubmitted, $action);
941 $nsubmissions++;
945 if (isset($table->data)) {
946 if ($groupid) {
947 if (! groups_group_exists($groupid)) {
948 error("List unassessed student submissions: group not found");
950 print_heading("$group->name ".get_string("studentsubmissions", "exercise", $course->student).
951 " [$nsubmissions]");
952 } else {
953 print_heading(get_string("studentsubmissions", "exercise", $course->student)." [$nsubmissions]",
954 "center");
956 print_table($table);
957 echo "<p align=\"center\">[] - ".get_string("gradeforsubmission", "exercise");
958 echo "<br />".get_string("maximumgrade").": $exercise->grade</p>\n";
959 echo "<p align=\"center\">".get_string("resubmitnote", "exercise", $course->student)."</p>\n";
960 // grade analysis
961 unset($table);
962 $table->head = array (get_string("count", "exercise"), get_string("mean", "exercise"),
963 get_string("standarddeviation", "exercise"), get_string("maximum", "exercise"),
964 get_string("minimum", "exercise"));
965 $table->align = array ("center", "center", "center", "center", "center");
966 $table->size = array ("*", "*", "*", "*", "*");
967 $table->cellpadding = 2;
968 $table->cellspacing = 0;
970 /// NOTE: user_teachers was ripped from the following SQL without a proper fix - XXX TO DO
972 if ($groupid) {
973 $stats = get_record_sql("SELECT COUNT(*) as count, AVG(grade) AS mean,
974 STDDEV(grade) AS stddev, MIN(grade) AS min, MAX(grade) AS max
975 FROM {$CFG->prefix}groups_members g, {$CFG->prefix}exercise_assessments a,
976 {$CFG->prefix}exercise_submissions s
977 WHERE g.groupid = $groupid AND s.userid = g.userid AND a.submissionid = s.id
978 AND a.exerciseid = $exercise->id");
979 } else { // no group/all participants
980 $stats = get_record_sql("SELECT COUNT(*) as count, AVG(grade) AS mean,
981 STDDEV(grade) AS stddev, MIN(grade) AS min, MAX(grade) AS max
982 FROM {$CFG->prefix}exercise_assessments a
983 WHERE a.exerciseid = $exercise->id");
985 $table->data[] = array($stats->count, number_format($stats->mean * $exercise->grade / 100.0, 1),
986 number_format($stats->stddev * $exercise->grade / 100.0, 1),
987 number_format($stats->max * $exercise->grade / 100.0, 1),
988 number_format($stats->min * $exercise->grade / 100.0, 1));
989 print_heading(get_string("grade")." ".get_string("analysis", "exercise"));
990 print_table($table);
996 ///////////////////////////////////////////////////////////////////////////////////////////////
997 function exercise_list_teacher_assessments($exercise, $user) {
998 global $CFG;
999 $timenow = time();
1001 if (! $course = get_record("course", "id", $exercise->course)) {
1002 error("Course is misconfigured");
1004 $table->head = array (get_string("title", "exercise"), get_string("action", "exercise"), get_string("comment", "exercise"));
1005 $table->align = array ("left", "left", "left");
1006 $table->size = array ("*", "*", "*");
1007 $table->cellpadding = 2;
1008 $table->cellspacing = 0;
1010 // get user's submissions
1011 if ($submissions = exercise_get_user_submissions($exercise, $user)) {
1012 foreach ($submissions as $submission) {
1013 // get the assessments
1014 if ($assessments = exercise_get_assessments($submission)) {
1015 foreach ($assessments as $assessment) {
1016 if (isteacher($exercise->course, $assessment->userid)) { // assessments by teachers only
1017 $action = "<a href=\"assessments.php?action=viewassessment&amp;a=$exercise->id&amp;aid=$assessment->id\">".
1018 get_string("view", "exercise")."</a>";
1019 // has teacher commented on teacher's assessment? shouldn't happen but leave test in
1020 if ($assessment->timegraded and ($timenow - $assessment->timegraded > $CFG->maxeditingtime)) {
1021 $comment = get_string("gradedbyteacher", "exercise", $course->teacher);
1023 else {
1024 $comment = userdate($assessment->timecreated);
1026 $table->data[] = array(exercise_print_submission_title($exercise, $submission), $action, $comment);
1032 if (isset($table->data)) {
1033 print_table($table);
1035 else {
1036 echo "<center>".get_string("noassessmentsdone", "exercise")."</center>\n";
1042 ///////////////////////////////////////////////////////////////////////////////////////////////
1043 function exercise_list_teacher_submissions($exercise, $user, $reassess = false) {
1044 // always allow user to reassess if that flag is true
1045 global $CFG;
1047 if (! $course = get_record("course", "id", $exercise->course)) {
1048 error("Course is misconfigured");
1050 if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
1051 error("Course Module ID was incorrect");
1054 $strexercises = get_string("modulenameplural", "exercise");
1055 $strexercise = get_string("modulename", "exercise");
1057 // get any assessment this user has done (could include hot one)
1058 if (!$assessment = get_record_select("exercise_assessments", "exerciseid = $exercise->id
1059 AND userid = $user->id")) {
1060 // the user has not yet assessed this exercise, set up a hot assessment record for this user for one
1061 // of the teacher submissions, first count the number of assessments for each teacher submission...
1062 if ($submissions = exercise_get_teacher_submissions($exercise)) {
1063 // mt_srand ((float)microtime()*1000000); // initialise random number generator, assume php>=4.2.0
1064 foreach ($submissions as $submission) {
1065 $n = count_records("exercise_assessments", "submissionid", $submission->id);
1066 // ...OK to have zero, we add a small random number to randomise things...
1067 $nassessments[$submission->id] = $n + mt_rand(0, 99) / 100;
1069 // ...put the submissions with the lowest number of assessments first...
1070 asort($nassessments);
1071 reset($nassessments);
1072 foreach ($nassessments as $submissionid => $n) { // break out of loop after the first element
1073 $submission = get_record("exercise_submissions", "id", $submissionid);
1074 // ... provided the user has NOT already assessed that submission...
1075 if (!$assessment = exercise_get_submission_assessment($submission, $user)) {
1076 $yearfromnow = time() + 365 * 86400;
1077 // ...create one and set timecreated way in the future, reset when record is updated
1078 $assessment->exerciseid = $exercise->id;
1079 $assessment->submissionid = $submission->id;
1080 $assessment->userid = $user->id;
1081 $assessment->grade = -1; // set impossible grade
1082 $assessment->timecreated = $yearfromnow;
1083 $assessment->mailed = 1; // no need to email to the teacher!
1084 if (!$assessment->id = insert_record("exercise_assessments", $assessment)) {
1085 error("Could not insert exercise assessment!");
1087 break;
1091 } else {
1092 // get hold of the teacher submission
1093 if (!$submission = get_record("exercise_submissions", "id", $assessment->submissionid)) {
1094 error("List teacher submissions: submission record not found");
1097 print_simple_box_start("center");
1098 print_heading_with_help(get_string("theexercise", "exercise"), "junk", "exercise");
1099 print_simple_box_start("center");
1100 echo "<p align=\"center\"><b>".get_string("description", "exercise").": </b>\n";
1101 echo exercise_print_submission_title($exercise, $submission);
1102 echo "</p>\n";
1103 print_simple_box_end();
1104 print_simple_box_end();
1106 $table->head = array (get_string("action", "exercise"), get_string("assessed", "exercise"),
1107 get_string("comment", "exercise"));
1108 $table->align = array ("left", "left", "left");
1109 $table->size = array ("*", "*", "*");
1110 $table->cellpadding = 2;
1111 $table->cellspacing = 0;
1113 // now list user's assessments (but only list those which come from teacher submissions)
1114 print_heading(get_string("yourassessment", "exercise"));
1115 $assessed = false;
1116 if ($assessments = exercise_get_user_assessments($exercise, $user)) {
1117 $timenow = time();
1118 foreach ($assessments as $assessment) {
1119 if (!$submission = get_record("exercise_submissions", "id", $assessment->submissionid)) {
1120 error ("exercise_list_teacher_submissions: unable to get submission");
1122 // submission from a teacher, i.e an exercise submission?
1123 if ($submission->isexercise) {
1124 $comment = '';
1125 if ($reassess) { // just show re-assess
1126 $action = "<a href=\"assessments.php?action=assesssubmission&amp;id=$cm->id&amp;sid=$submission->id\">".
1127 get_string("reassess", "exercise")."</a>";
1129 else { // reassess is false - assessment is a "normal state"
1130 // user assessment has three states: record created but not assessed (date created
1131 // in the future); just assessed but still editable; and "static" (may or may not
1132 // have been graded by teacher, that is shown in the comment)
1133 if ($assessment->timecreated > $timenow) { // user needs to assess this submission
1134 $action = "<a href=\"assessments.php?action=assesssubmission&amp;id=$cm->id&amp;sid=$submission->id\">".
1135 get_string("assess", "exercise")."</a>";
1137 elseif ($assessment->timecreated > ($timenow - $CFG->maxeditingtime)) {
1138 // there's still time left to edit...
1139 $action = "<a href=\"assessments.php?action=assesssubmission&amp;id=$cm->id&amp;sid=$submission->id\">".
1140 get_string("edit", "exercise")."</a>";
1142 else {
1143 $action = "<a href=\"assessments.php?action=viewassessment&amp;id=$cm->id&amp;aid=$assessment->id\">"
1144 .get_string("view", "exercise")."</a>";
1147 // show the date if in the past (otherwise the user hasn't done the assessment yet
1148 $assessmentdate = '';
1149 if ($assessment->timecreated < $timenow) {
1150 $assessmentdate = userdate($assessment->timecreated);
1151 // if user has submitted work, see if teacher has graded assessment
1152 if (exercise_count_user_submissions($exercise, $user) > 0) {
1153 if ($assessment->timegraded and (($timenow - $assessment->timegraded) > $CFG->maxeditingtime)) {
1154 $comment .= get_string("gradeforassessment", "exercise").": ".
1155 number_format($assessment->gradinggrade * $exercise->gradinggrade / 100.0, 1).
1156 " (".get_string("maximumgrade")." ".number_format($exercise->gradinggrade, 0).")";
1157 $assessed = true;
1159 else {
1160 $comment .= get_string("awaitingassessmentbythe", "exercise", $course->teacher);
1164 $table->data[] = array($action, $assessmentdate, $comment);
1167 print_table($table);
1168 if ($assessed) {
1169 echo "<p align=\"center\">".get_string("noteongradinggrade", "exercise", $course->teacher)."</p>\n";
1175 ///////////////////////////////////////////////////////////////////////////////////////////////
1176 function exercise_list_unassessed_student_submissions($exercise, $user) {
1177 // list the student submissions not assessed by the teacher
1178 global $CFG;
1180 $timenow = time();
1182 if (! $course = get_record("course", "id", $exercise->course)) {
1183 error("Course is misconfigured");
1185 if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
1186 error("Course Module ID was incorrect");
1189 $table->head = array (get_string("title", "exercise"), get_string("submittedby", "exercise"),
1190 get_string("submitted", "exercise"), get_string("action", "exercise"),
1191 get_string("comment", "exercise"));
1192 $table->align = array ("left", "left", "left", "left", "left");
1193 $table->size = array ("*", "*", "*", "*", "*");
1194 $table->cellpadding = 2;
1195 $table->cellspacing = 0;
1197 // get all the submissions, oldest first, youngest last
1198 // exercise_get_student_submissions is group aware
1199 $groupid = get_current_group($course->id);
1200 if ($groupid) {
1201 if (! groups_group_exists($groupid)) {
1202 error("List unassessed student submissions: group not found");
1204 print_heading(get_string("studentsubmissionsforassessment", "exercise", $group->name));
1206 if ($submissions = exercise_get_student_submissions($exercise, "time", $groupid)) {
1207 foreach ($submissions as $submission) {
1208 // only consider "cold" submissions
1209 if ($submission->timecreated < $timenow - $CFG->maxeditingtime) {
1210 $comment = "";
1211 // see if student has already submitted
1212 $submissionowner = get_record("user", "id", $submission->userid);
1213 if (exercise_count_user_submissions($exercise, $submissionowner) == 1) {
1214 // it's the student's first submission
1215 // see if there are no cold assessments for this submission
1216 if (!exercise_count_assessments($submission)) {
1217 // now see if the teacher has already assessed this submission
1218 $warm = false;
1219 if ($assessments = get_records("exercise_assessments", "submissionid", $submission->id)) {
1220 foreach ($assessments as $assessment) {
1221 if (isteacher($course->id, $assessment->userid)) {
1222 if ($assessment->timecreated > $timenow -$CFG->maxeditingtime) {
1223 $warm = true;
1225 break; // no need to look further
1229 // get their assessment
1230 if ($assessments = exercise_get_user_assessments($exercise, $submissionowner)) {
1231 foreach ($assessments as $assessment) {
1232 $studentassessment = $assessment;
1233 break; // there should only be one!
1235 $timegap = get_string("ago", "exercise", format_time($submission->timecreated -
1236 $timenow));
1237 if ($submission->late) {
1238 $timegap = "<font color=\"red\">".$timegap."</font>";
1240 if ($warm) {
1241 // last chance salon
1242 $action = "<a href=\"assessments.php?action=teacherassessment&amp;id=$cm->id&amp;aid=$studentassessment->id&amp;sid=$submission->id\">".
1243 get_string("edit", "exercise")."</a>";
1244 $table->data[] = array(exercise_print_submission_title($exercise, $submission),
1245 fullname($submissionowner),
1246 $timegap, $action, $comment);
1247 } else {
1248 $action = "<a href=\"assessments.php?action=teacherassessment&amp;id=$cm->id&amp;aid=$studentassessment->id&amp;sid=$submission->id\">".
1249 get_string("assess", "exercise")."</a>";
1250 $table->data[] = array(exercise_print_submission_title($exercise, $submission),
1251 fullname($submissionowner),
1252 $timegap, $action, $comment);
1254 } else {
1255 // there's no student assessment, odd!!
1259 // this is student's second... submission
1260 else {
1261 $teacherassessed = false;
1262 $warm = false;
1263 if ($assessments = get_records("exercise_assessments", "submissionid", $submission->id)) {
1264 foreach ($assessments as $assessment) {
1265 if (isteacher($course->id, $assessment->userid)) {
1266 $teacherassessed = true;
1267 if (!$teacher = get_record("user", "id", $assessment->userid)) {
1268 error("List unassessed student submissions: teacher record not found");
1270 $comment = get_string("resubmissionfor", "exercise",
1271 fullname($teacher));
1272 if ($assessment->timecreated > $timenow - $CFG->maxeditingtime) {
1273 $warm = true;
1275 break; // no need to look further
1279 if ($teacherassessed and $warm) {
1280 // last chance salon
1281 $action = "<a href=\"assessments.php?action=assessresubmission&amp;id=$cm->id&amp;sid=$submission->id\">".
1282 get_string("edit", "exercise")."</a>";
1283 $timegap = get_string("ago", "exercise", format_time($submission->timecreated -
1284 $timenow));
1285 if ($submission->late) {
1286 $timegap = "<font color=\"red\">".$timegap."</font>";
1288 $table->data[] = array(exercise_print_submission_title($exercise, $submission),
1289 fullname($submissionowner),
1290 $timegap, $action, $comment);
1292 if (!$teacherassessed) {
1293 // no teacher's assessment
1294 // find who did the previous assessment
1295 if (!$submissions = exercise_get_user_submissions($exercise, $submissionowner)) {
1296 error("List unassessed student submissions: submission records not found");
1298 // get the oldest submission, exercise_get_user_submissions returns that first
1299 foreach ($submissions as $tempsubmission) {
1300 $prevsubmission = $tempsubmission;
1301 break;
1303 // get the teacher's assessment of the student's previous submission
1304 if ($assessments = get_records("exercise_assessments", "submissionid",
1305 $prevsubmission->id)) {
1306 foreach ($assessments as $assessment) {
1307 if (isteacher($course->id, $assessment->userid)) {
1308 if (!$teacher = get_record("user", "id", $assessment->userid)) {
1309 error("List unassessed student submissions: teacher record not found");
1311 $comment = get_string("resubmissionfor", "exercise",
1312 fullname($teacher));
1313 break; // no need to look further
1318 $action = "<a href=\"assessments.php?action=assessresubmission&amp;id=$cm->id&amp;sid=$submission->id\">".
1319 get_string("assess", "exercise")."</a>";
1320 $timegap = get_string("ago", "exercise", format_time($submission->timecreated -
1321 $timenow));
1322 if ($submission->late) {
1323 $timegap = "<font color=\"red\">".$timegap."</font>";
1325 $table->data[] = array(exercise_print_submission_title($exercise, $submission),
1326 fullname($submissionowner),
1327 $timegap, $action, $comment);
1332 if (isset($table->data)) {
1333 print_table($table);
1339 ///////////////////////////////////////////////////////////////////////////////////////////////
1340 function exercise_list_unassessed_teacher_submissions($exercise, $user) {
1341 // list the teacher submissions not assessed by this user
1342 global $CFG;
1344 $table->head = array (get_string("title", "exercise"), get_string("action", "exercise"), get_string("comment", "exercise"));
1345 $table->align = array ("left", "left", "left");
1346 $table->size = array ("*", "*", "*");
1347 $table->cellpadding = 2;
1348 $table->cellspacing = 0;
1350 if ($submissions = exercise_get_teacher_submissions($exercise)) {
1351 foreach ($submissions as $submission) {
1352 $comment = "";
1353 // see if user already graded this assessment
1354 if ($assessment = get_record_select("exercise_assessments", "submissionid = $submission->id
1355 AND userid = $user->id")) {
1356 $timenow = time();
1357 if (($timenow - $assessment->timecreated < $CFG->maxeditingtime)) {
1358 // last chance salon
1359 $action = "<a href=\"assessments.php?action=assesssubmission&amp;a=$exercise->id&amp;sid=$submission->id\">".
1360 get_string("edit", "exercise")."</a>";
1361 $table->data[] = array(exercise_print_submission_title($exercise, $submission), $action, $comment);
1364 else { // no assessment
1365 $action = "<a href=\"assessments.php?action=assesssubmission&amp;a=$exercise->id&amp;sid=$submission->id\">".
1366 get_string("assess", "exercise")."</a>";
1367 $table->data[] = array(exercise_print_submission_title($exercise, $submission), $action, $comment);
1370 if (isset($table->data)) {
1371 print_table($table);
1377 ///////////////////////////////////////////////////////////////////////////////////////////////
1378 function exercise_list_ungraded_assessments($exercise, $stype) {
1379 global $CFG;
1381 if (! $course = get_record("course", "id", $exercise->course)) {
1382 error("Course is misconfigured");
1384 if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
1385 error("Course Module ID was incorrect");
1388 // lists all the assessments of student submissions for grading by teacher
1389 $table->head = array (get_string("title", "exercise"), get_string("submittedby", "exercise"),
1390 get_string("assessor", "exercise"), get_string("timeassessed", "exercise"), get_string("action", "exercise"));
1391 $table->align = array ("left", "left", "left", "left");
1392 $table->size = array ("*", "*", "*", "*");
1393 $table->cellpadding = 2;
1394 $table->cellspacing = 0;
1395 $timenow = time();
1397 switch ($stype) {
1398 case "student" :
1399 $assessments = exercise_get_ungraded_assessments_student($exercise);
1400 break;
1401 case "teacher" :
1402 $assessments = exercise_get_ungraded_assessments_teacher($exercise);
1403 break;
1405 if ($assessments) {
1406 foreach ($assessments as $assessment) {
1407 if (!isteacher($exercise->course, $assessment->userid)) { // don't let teacher grade their own assessments
1408 if (($timenow - $assessment->timegraded) < $CFG->maxeditingtime) {
1409 $action = "<a href=\"assessments.php?action=gradeassessment&amp;id=$cm->id&amp;stype=$stype&amp;aid=$assessment->id\">".
1410 get_string("edit", "exercise")."</a>";
1412 else {
1413 $action = "<a href=\"assessments.php?action=gradeassessment&amp;id=$cm->id&amp;stype=$stype&amp;aid=$assessment->id\">".
1414 get_string("grade")."</a>";
1416 $submission = get_record("exercise_submissions", "id", $assessment->submissionid);
1417 $submissionowner = get_record("user", "id", $submission->userid);
1418 $assessor = get_record("user", "id", $assessment->userid);
1419 $table->data[] = array(exercise_print_submission_title($exercise, $submission),
1420 fullname($submissionowner),
1421 fullname($assessor), userdate($assessment->timecreated), $action);
1424 if (isset($table->data)) {
1425 print_table($table);
1431 ///////////////////////////////////////////////////////////////////////////////////////////////
1432 function exercise_list_user_submissions($exercise, $user) {
1433 global $CFG;
1435 if (! $course = get_record("course", "id", $exercise->course)) {
1436 error("Course is misconfigured");
1438 if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
1439 error("Course Module ID was incorrect");
1442 $timenow = time();
1443 $table->head = array (get_string("title", "exercise"), get_string("action", "exercise"),
1444 get_string("submitted", "exercise"), get_string("assessment", "exercise"));
1445 $table->align = array ("left", "left", "left", "left");
1446 $table->size = array ("*", "*", "*", "*");
1447 $table->cellpadding = 2;
1448 $table->cellspacing = 0;
1450 if ($submissions = exercise_get_user_submissions($exercise, $user)) {
1451 foreach ($submissions as $submission) {
1452 $action = '';
1453 $comment = '';
1454 // allow user to delete submission if it's warm
1455 if ($submission->timecreated > $timenow - $CFG->maxeditingtime) {
1456 $action = "<a href=\"submissions.php?action=userconfirmdelete&amp;id=$cm->id&amp;sid=$submission->id\">".
1457 get_string("delete", "exercise")."</a>";
1459 // if this is a teacher's submission (an exercise description) ignore any assessments
1460 if (!$submission->isexercise) {
1461 // get the teacher assessments (could be more than one, if unlikely, when multiple teachers)
1462 if ($assessments = get_records_select("exercise_assessments", "exerciseid = $exercise->id AND
1463 submissionid = $submission->id")) {
1464 foreach ($assessments as $assessment) {
1465 // make sure it's real
1466 if ($assessment->timecreated < $timenow - $CFG->maxeditingtime) { // it's cold
1467 if ($action) {
1468 $action .= " | ";
1470 $action .= "<a href=\"assessments.php?action=viewassessment&amp;id=$cm->id&amp;aid=$assessment->id\">".
1471 get_string("viewteacherassessment", "exercise", $course->teacher)."</a>";
1472 if ($comment) {
1473 $comment .= " | ";
1475 $comment .= get_string("teacherassessment", "exercise", $course->teacher).": ".
1476 number_format($assessment->grade * $exercise->grade / 100.0, 1).
1477 " (".get_string("maximumgrade")." ".number_format($exercise->grade, 0).")";
1482 if (!$comment and isstudent($course->id, $user->id)) {
1483 $comment = get_string("awaitingassessmentbythe", "exercise", $course->teacher);
1485 $submissiondate = userdate($submission->timecreated);
1486 if ($submission->late) {
1487 $submissiondate = "<font color=\"red\">".$submissiondate."</font>";
1489 $table->data[] = array(exercise_print_submission_title($exercise, $submission), $action,
1490 $submissiondate, $comment);
1492 print_table($table);
1497 ///////////////////////////////////////////////////////////////////////////////////////////////
1498 function exercise_print_assessment_form($exercise, $assessment = false, $allowchanges = false, $returnto = '') {
1499 // prints several variants of the assessment form
1500 global $CFG, $USER, $EXERCISE_SCALES, $EXERCISE_EWEIGHTS;
1502 if (! $course = get_record("course", "id", $exercise->course)) {
1503 error("Course is misconfigured");
1505 if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
1506 error("Course Module ID was incorrect");
1509 $timenow = time();
1511 if ($assessment) {
1513 if (!$submission = get_record("exercise_submissions", "id", $assessment->submissionid)) {
1514 error ("exercise_print_assessment_form: Submission record not found");
1516 // test if this assessment is from a teacher or student.
1517 // Teacher's assessments are more complicated as we need to go back a couple of steps
1518 // to find the exercise. Student's assessments are directly associated with an exercise.
1519 if (isteacher($course->id, $assessment->userid)) {
1520 // A teacher's assessment, requires getting the student's assessment(s)
1521 // and finding which of those assessments which comes from a teacher submission,
1522 // that is the exercise
1523 $exercisefound = false;
1524 if (!$submissionowner = get_record("user", "id", $submission->userid)) {
1525 error ("exercise_print_assessment_form: User record not found");
1527 if ($initialassessments = exercise_get_user_assessments($exercise, $submissionowner)) {
1528 // should only be one but we'll loop anyway
1529 foreach($initialassessments as $initialassessment) {
1530 if (!$teachersubmission = get_record("exercise_submissions", "id", $initialassessment->submissionid)) {
1531 error ("exercise_print_assessment_form: Teacher Submission record not found");
1533 if ($teachersubmission->isexercise) {
1534 $exercisefound = true;
1535 break;
1539 if ($exercisefound) {
1540 print_heading(get_string("theexerciseandthesubmissionby", "exercise",
1541 fullname($submissionowner)));
1542 echo "<center><table border=\"1\" width=\"30%\"><tr>
1543 <td align=\"center\">\n";
1544 echo exercise_print_submission_title($exercise, $teachersubmission);
1545 echo "</td></tr></table><br clear=\"all\" />\n";
1548 else {
1549 // it's a student assessment, print instructions if it's their own assessment
1550 if ($assessment->userid == $USER->id) {
1551 print_heading_with_help(get_string("pleaseusethisform", "exercise"), "grading", "exercise");
1555 echo "<center><table border=\"1\" width=\"30%\"><tr>
1556 <td align=\"center\">\n";
1557 echo exercise_print_submission_title($exercise, $submission);
1558 echo "</td></tr></table><br clear=\"all\" />\n";
1560 // only show the grade if grading strategy > 0 and the grade is positive
1561 if ($exercise->gradingstrategy and $assessment->grade >= 0) {
1563 echo "<center><b>".get_string("thegradeis", "exercise").": ".
1564 number_format($assessment->grade * $exercise->grade / 100.0, 2)." (".
1565 get_string("maximumgrade")." ".number_format($exercise->grade, 0).")</b></center><br clear=\"all\" />\n";
1569 // now print the grading form with the teacher's comments if any
1570 // FORM is needed for Mozilla browsers, else radio bttons are not checked
1572 <form id="assessmentform" method="post" action="assessments.php">
1573 <input type="hidden" name="id" value="<?php echo $cm->id ?>" />
1574 <input type="hidden" name="aid" value="<?php echo @$assessment->id ?>" />
1575 <input type="hidden" name="action" value="updateassessment" />
1576 <input type="hidden" name="resubmit" value="0" />
1577 <input type="hidden" name="returnto" value="<?php echo $returnto ?>" />
1578 <?php
1579 if ($assessment) {
1580 if (!$assessmentowner = get_record("user", "id", $assessment->userid)) {
1581 error("Exercise_print_assessment_form: could not find user record");
1583 if ($assessmentowner->id == $USER->id) {
1584 $formtitle = get_string("yourassessment", "exercise");
1586 else {
1587 $formtitle = get_string("assessmentby", "exercise", fullname($assessmentowner));
1590 else {
1591 $formtitle = get_string("assessmentform", "exercise");
1593 echo "<center><table cellpadding=\"2\" border=\"1\">\n";
1594 echo "<tr valign=\"top\">\n";
1596 echo " <td colspan=\"2\"><center><b>$formtitle</b></center></td>\n";
1598 echo "</tr>\n";
1600 // get the assignment elements...
1601 if (!$elementsraw = get_records("exercise_elements", "exerciseid", $exercise->id, "elementno ASC")) {
1602 print_string("noteonassignmentelements", "exercise");
1604 else {
1605 foreach ($elementsraw as $element) {
1606 $elements[] = $element; // to renumber index 0,1,2...
1610 if ($assessment) {
1611 $assessment->generalcomment = clean_text($assessment->generalcomment); //clean html first
1612 // get any previous grades...
1613 if ($gradesraw = get_records_select("exercise_grades", "assessmentid = $assessment->id", "elementno")) {
1614 foreach ($gradesraw as $grade) {
1615 $grade->feedback = clean_text($grade->feedback); //clean the html first
1616 $grades[] = $grade; // to renumber index 0,1,2...
1620 else {
1621 // setup dummy grades array
1622 for($i = 0; $i < count($elementsraw); $i++) { // gives a suitable sized loop
1623 $grades[$i]->feedback = get_string("yourfeedbackgoeshere", "exercise");
1624 $grades[$i]->grade = 0;
1628 // determine what sort of grading
1629 switch ($exercise->gradingstrategy) {
1630 case 0: // no grading
1631 // now print the form
1632 for ($i=0; $i < count($elements); $i++) {
1633 $iplus1 = $i+1;
1634 echo "<tr valign=\"top\">\n";
1635 echo " <td align=\"right\"><p><b>". get_string("element","exercise")." $iplus1:</b></p></td>\n";
1636 echo " <td>".text_to_html($elements[$i]->description);
1637 echo "</td></tr>\n";
1638 echo "<tr valign=\"top\">\n";
1639 echo " <td align=\"right\"><p><b>". get_string("feedback").":</b></p></td>\n";
1640 echo " <td>\n";
1641 if ($allowchanges) {
1642 echo " <textarea name=\"feedback[]\" rows=\"3\" cols=\"75\" wrap=\"virtual\">\n";
1643 if (isset($grades[$i]->feedback)) {
1644 echo $grades[$i]->feedback;
1646 echo "</textarea>\n";
1648 else {
1649 echo text_to_html($grades[$i]->feedback);
1651 echo " </td>\n";
1652 echo "</tr>\n";
1653 echo "<tr valign=\"top\">\n";
1654 echo " <td colspan=\"2\">&nbsp;</td>\n";
1655 echo "</tr>\n";
1657 break;
1659 case 1: // accumulative grading
1660 // now print the form
1661 for ($i=0; $i < count($elements); $i++) {
1662 $iplus1 = $i+1;
1663 echo "<tr valign=\"top\">\n";
1664 echo " <td align=\"right\"><p><b>". get_string("element","exercise")." $iplus1:</b></p></td>\n";
1666 echo " <td>".text_to_html($elements[$i]->description);
1667 echo "<p align=\"right\"><font size=\"1\">Weight: "
1668 .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</font>\n";
1669 echo "</td></tr>\n";
1670 echo "<tr valign=\"top\">\n";
1671 echo " <td align=\"right\"><p><b>". get_string("grade"). ":</b></p></td>\n";
1672 echo " <td valign=\"top\">\n";
1674 // get the appropriate scale
1675 $scalenumber=$elements[$i]->scale;
1676 $SCALE = (object)$EXERCISE_SCALES[$scalenumber];
1677 switch ($SCALE->type) {
1678 case 'radio' :
1679 // show selections highest first
1680 echo "<center><b>$SCALE->start</b>&nbsp;&nbsp;&nbsp;";
1681 for ($j = $SCALE->size - 1; $j >= 0 ; $j--) {
1682 $checked = false;
1683 if (isset($grades[$i]->grade)) {
1684 if ($j == $grades[$i]->grade) {
1685 $checked = true;
1688 else { // there's no previous grade so check the lowest option
1689 if ($j == 0) {
1690 $checked = true;
1693 if ($checked) {
1694 echo " <input type=\"RADIO\" name=\"grade[$i]\" value=\"$j\" checked=\"checked\" /> &nbsp;&nbsp;&nbsp;\n";
1696 else {
1697 echo " <input type=\"RADIO\" name=\"grade[$i]\" value=\"$j\" /> &nbsp;&nbsp;&nbsp;\n";
1700 echo "&nbsp;&nbsp;&nbsp;<b>$SCALE->end</b></center>\n";
1701 break;
1702 case 'selection' :
1703 unset($numbers);
1704 for ($j = $SCALE->size; $j >= 0; $j--) {
1705 $numbers[$j] = $j;
1707 if (isset($grades[$i]->grade)) {
1708 choose_from_menu($numbers, "grade[$i]", $grades[$i]->grade, "");
1710 else {
1711 choose_from_menu($numbers, "grade[$i]", 0, "");
1713 break;
1715 echo " </td>\n";
1716 echo "</tr>\n";
1718 echo "<tr valign=\"top\">\n";
1719 echo " <td align=\"right\"><p><b>". get_string("feedback").":</b></p></td>\n";
1720 echo " <td>\n";
1721 if ($allowchanges) {
1722 echo " <textarea name=\"feedback[]\" rows=\"3\" cols=\"75\" wrap=\"virtual\">\n";
1723 if (isset($grades[$i]->feedback)) {
1724 echo $grades[$i]->feedback;
1726 echo "</textarea>\n";
1728 else {
1729 echo text_to_html($grades[$i]->feedback);
1731 echo " </td>\n";
1732 echo "</tr>\n";
1733 echo "<tr valign=\"top\">\n";
1734 echo " <td colspan=\"2\">&nbsp;</td>\n";
1735 echo "</tr>\n";
1737 break;
1739 case 2: // error banded grading
1740 // now run through the elements
1741 $error = 0;
1742 for ($i=0; $i < count($elements) - 1; $i++) {
1743 $iplus1 = $i+1;
1744 echo "<tr valign=\"top\">\n";
1746 echo " <td align=\"right\"><p><b>". get_string("element","exercise")." $iplus1:</b></p></td>\n";
1748 echo " <td>".text_to_html($elements[$i]->description);
1749 echo "<p align=\"right\"><font size=\"1\">Weight: "
1750 .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</font>\n";
1751 echo "</td></tr>\n";
1752 echo "<tr valign=\"top\">\n";
1753 echo " <td align=\"right\"><p><b>". get_string("grade"). ":</b></p></td>\n";
1754 echo " <td valign=\"top\">\n";
1756 // get the appropriate scale - yes/no scale (0)
1757 $SCALE = (object) $EXERCISE_SCALES[0];
1758 switch ($SCALE->type) {
1759 case 'radio' :
1760 // show selections highest first
1761 echo "<center><b>$SCALE->start</b>&nbsp;&nbsp;&nbsp;";
1762 for ($j = $SCALE->size - 1; $j >= 0 ; $j--) {
1763 $checked = false;
1764 if (isset($grades[$i]->grade)) {
1765 if ($j == $grades[$i]->grade) {
1766 $checked = true;
1769 else { // there's no previous grade so check the lowest option
1770 if ($j == 0) {
1771 $checked = true;
1774 if ($checked) {
1775 echo " <input type=\"RADIO\" name=\"grade[$i]\" value=\"$j\" checked=\"checked\" /> &nbsp;&nbsp;&nbsp;\n";
1777 else {
1778 echo " <input type=\"RADIO\" name=\"grade[$i]\" value=\"$j\" /> &nbsp;&nbsp;&nbsp;\n";
1781 echo "&nbsp;&nbsp;&nbsp;<b>$SCALE->end</b></center>\n";
1782 break;
1783 case 'selection' :
1784 unset($numbers);
1785 for ($j = $SCALE->size; $j >= 0; $j--) {
1786 $numbers[$j] = $j;
1788 if (isset($grades[$i]->grade)) {
1789 choose_from_menu($numbers, "grade[$i]", $grades[$i]->grade, "");
1791 else {
1792 choose_from_menu($numbers, "grade[$i]", 0, "");
1794 break;
1797 echo " </td>\n";
1798 echo "</tr>\n";
1799 echo "<tr valign=\"top\">\n";
1800 echo " <td align=\"right\"><p><b>". get_string("feedback").":</b></p></td>\n";
1801 echo " <td>\n";
1802 if ($allowchanges) {
1803 echo " <textarea name=\"feedback[$i]\" rows=\"3\" cols=\"75\" wrap=\"virtual\">\n";
1804 if (isset($grades[$i]->feedback)) {
1805 echo $grades[$i]->feedback;
1807 echo "</textarea>\n";
1809 else {
1810 if (isset($grades[$i]->feedback)) {
1811 echo text_to_html($grades[$i]->feedback);
1814 echo "&nbsp;</td>\n";
1815 echo "</tr>\n";
1816 echo "<tr valign=\"top\">\n";
1817 echo " <td colspan=\"2\">&nbsp;</td>\n";
1818 echo "</tr>\n";
1819 if (empty($grades[$i]->grade)) {
1820 $error += $EXERCISE_EWEIGHTS[$elements[$i]->weight];
1823 // print the number of negative elements
1824 // echo "<tr><td>".get_string("numberofnegativeitems", "exercise")."</td><td>$negativecount</td></tr>\n";
1825 // echo "<tr valign=\"top\">\n";
1826 // echo " <td colspan=\"2\">&nbsp;</td>\n";
1827 echo "</table></center>\n";
1828 // now print the grade table
1829 echo "<p><center><b>".get_string("gradetable","exercise")."</b></center>\n";
1830 echo "<center><table cellpadding=\"5\" border=\"1\"><tr><td align=\"CENTER\">".
1831 get_string("numberofnegativeresponses", "exercise");
1832 echo "</td><td>". get_string("suggestedgrade", "exercise")."</td></tr>\n";
1833 for ($i=0; $i<=$exercise->nelements; $i++) {
1834 if ($i == intval($error + 0.5)) {
1835 echo "<tr><td align=\"CENTER\"><img src=\"$CFG->pixpath/t/right.gif\" alt=\"\" /> $i</td><td align=\"CENTER\">{$elements[$i]->maxscore}</td></tr>\n";
1837 else {
1838 echo "<tr><td align=\"CENTER\">$i</td><td align=\"CENTER\">{$elements[$i]->maxscore}</td></tr>\n";
1841 echo "</table></center>\n";
1842 echo "<p><center><table cellpadding=\"5\" border=\"1\"><tr><td align=\"right\"><b>".
1843 get_string("optionaladjustment", "exercise").":</b></td><td>\n";
1844 unset($numbers);
1845 for ($j = 20; $j >= -20; $j--) {
1846 $numbers[$j] = $j;
1848 if (isset($grades[$exercise->nelements]->grade)) {
1849 choose_from_menu($numbers, "grade[$exercise->nelements]", $grades[$exercise->nelements]->grade, "");
1851 else {
1852 choose_from_menu($numbers, "grade[$exercise->nelements]", 0, "");
1854 echo "</td></tr>\n";
1855 break;
1857 case 3: // criteria grading
1858 echo "<tr valign=\"top\">\n";
1860 echo " <td>&nbsp;</td>\n";
1862 echo " <td><b>". get_string("criterion","exercise")."</b></td>\n";
1864 echo " <td><b>".get_string("select")."</b></td>\n";
1865 echo " <td><b>".get_string("suggestedgrade", "exercise")."</b></td>\n";
1866 // find which criteria has been selected (saved in the zero element), if any
1867 if (isset($grades[0]->grade)) {
1868 $selection = $grades[0]->grade;
1870 else {
1871 $selection = 0;
1873 // now run through the elements
1874 for ($i=0; $i < count($elements); $i++) {
1875 $iplus1 = $i+1;
1876 echo "<tr valign=\"top\">\n";
1878 echo " <td>$iplus1</td><td>".text_to_html($elements[$i]->description)."</td>\n";
1879 if ($selection == $i) {
1880 echo " <td align=\"center\"><input type=\"RADIO\" name=\"grade[0]\" value=\"$i\" checked=\"checked\" /></td>\n";
1882 else {
1883 echo " <td align=\"center\"><input type=\"RADIO\" name=\"grade[0]\" value=\"$i\" /></td>\n";
1885 echo "<td align=\"center\">{$elements[$i]->maxscore}</td></tr>\n";
1887 echo "</table></center>\n";
1888 echo "<p><center><table cellpadding=\"5\" border=\"1\"><tr><td align=\"right\"><b>".
1889 get_string("optionaladjustment", "exercise")."</b></td><td>\n";
1890 unset($numbers);
1891 for ($j = 20; $j >= -20; $j--) {
1892 $numbers[$j] = $j;
1894 if (isset($grades[1]->grade)) {
1895 choose_from_menu($numbers, "grade[1]", $grades[1]->grade, "");
1897 else {
1898 choose_from_menu($numbers, "grade[1]", 0, "");
1900 echo "</td></tr>\n";
1901 break;
1903 case 4: // rubric grading
1904 // now run through the elements...
1905 for ($i=0; $i < count($elements); $i++) {
1906 $iplus1 = $i+1;
1907 echo "<tr valign=\"top\">\n";
1909 echo "<td align=\"right\"><b>".get_string("element", "exercise")." $iplus1:</b></td>\n";
1910 echo "<td>".text_to_html($elements[$i]->description).
1911 "<p align=\"right\"><font size=\"1\">Weight: "
1912 .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</font></td></tr>\n";
1913 echo "<tr valign=\"top\">\n";
1915 echo " <td align=\"center\"><b>".get_string("select")."</b></td>\n";
1916 echo " <td><b>". get_string("criterion","exercise")."</b></td></tr>\n";
1918 if (isset($grades[$i])) {
1919 $selection = $grades[$i]->grade;
1920 } else {
1921 $selection = 0;
1923 // ...and the rubrics
1924 if ($rubricsraw = get_records_select("exercise_rubrics", "exerciseid = $exercise->id AND
1925 elementno = $i", "rubricno ASC")) {
1926 unset($rubrics);
1927 foreach ($rubricsraw as $rubic) {
1928 $rubrics[] = $rubic; // to renumber index 0,1,2...
1930 for ($j=0; $j<5; $j++) {
1931 if (empty($rubrics[$j]->description)) {
1932 break; // out of inner for loop
1934 echo "<tr valign=\"top\">\n";
1936 if ($selection == $j) {
1937 echo " <td align=\"center\"><input type=\"RADIO\" name=\"grade[$i]\" value=\"$j\" checked=\"checked\" /></td>\n";
1938 }else {
1939 echo " <td align=\"center\"><input type=\"RADIO\" name=\"grade[$i]\" value=\"$j\" /></td>\n";
1941 echo "<td>".text_to_html($rubrics[$j]->description)."</td>\n";
1943 echo "<tr valign=\"top\">\n";
1944 echo " <td align=\"right\"><p><b>". get_string("feedback").":</b></p></td>\n";
1945 echo " <td>\n";
1946 if ($allowchanges) {
1947 echo " <textarea name=\"feedback[]\" rows=\"3\" cols=\"75\" wrap=\"virtual\">\n";
1948 if (isset($grades[$i]->feedback)) {
1949 echo $grades[$i]->feedback;
1951 echo "</textarea>\n";
1953 else {
1954 echo text_to_html($grades[$i]->feedback);
1956 echo " </td>\n";
1957 echo "</tr>\n";
1958 echo "<tr valign=\"top\">\n";
1959 echo " <td colspan=\"2\">&nbsp;</td>\n";
1960 echo "</tr>\n";
1963 break;
1964 } // end of outer switch
1966 // now get the general comment (present in all types)
1967 echo "<tr valign=\"top\">\n";
1968 switch ($exercise->gradingstrategy) {
1969 case 0:
1970 case 1:
1971 case 4 : // no grading, accumulative and rubic
1972 echo " <td align=\"right\"><p><b>". get_string("generalcomment", "exercise").":</b></p></td>\n";
1973 break;
1974 default :
1975 echo " <td align=\"right\"><p><b>". get_string("reasonforadjustment", "exercise").":</b></p></td>\n";
1977 echo " <td>\n";
1978 if ($allowchanges) {
1979 echo " <textarea name=\"generalcomment\" rows=\"5\" cols=\"75\" wrap=\"virtual\">\n";
1980 if (isset($assessment->generalcomment)) {
1981 echo $assessment->generalcomment;
1983 echo "</textarea>\n";
1985 else {
1986 if ($assessment) {
1987 if (isset($assessment->generalcomment)) {
1988 echo text_to_html($assessment->generalcomment);
1991 else {
1992 print_string("yourfeedbackgoeshere", "exercise");
1996 echo "&nbsp;</td>\n";
1998 echo "</tr>\n";
2000 echo "<tr valign=\"top\">\n";
2002 echo " <td colspan=\"2\">&nbsp;</td>\n";
2004 echo "</tr>\n";
2006 $timenow = time();
2008 // always show the teacher the grading grade if it's not their assessment!
2009 if ($assessment and isteacher($course->id) and ($assessment->userid != $USER->id) and $exercise->gradinggrade) {
2010 echo "<tr><td align=\"right\"><b>".get_string("gradeforstudentsassessment", "exercise", $course->student).
2011 "</td><td>\n";
2012 echo number_format($exercise->gradinggrade * $assessment->gradinggrade / 100.0, 0);
2013 echo "</td></tr>\n";
2016 // ...and close the table, show buttons if needed...
2017 echo "</table><br />\n";
2018 if ($assessment and $allowchanges) {
2019 if (isteacher($course->id)) {
2020 // ...show two buttons...to resubmit or not to resubmit
2021 echo "<input type=\"button\" value=\"".get_string("studentnotallowed", "exercise", $course->student)."\"
2022 onclick=\"getElementById('assessmentform').submit();\" />\n";
2023 echo "<input type=\"button\" value=\"".get_string("studentallowedtoresubmit", "exercise", $course->student)."\"
2024 onclick=\"getElementById('assessmentform').resubmit.value='1';getElementById('assessmentform').submit();\" />\n";
2026 else {
2027 // ... show save button
2028 echo "<input type=\"submit\" value=\"".get_string("savemyassessment", "exercise")."\" />\n";
2031 echo "</center></form>\n";
2036 ///////////////////////////////////////////////////////////////////////////////////////////////
2037 function exercise_print_assessments_by_user_for_admin($exercise, $user) {
2039 if (! $course = get_record("course", "id", $exercise->course)) {
2040 error("Course is misconfigured");
2042 if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
2043 error("Course Module ID was incorrect");
2046 if ($assessments =exercise_get_user_assessments($exercise, $user)) {
2047 foreach ($assessments as $assessment) {
2048 echo "<p><center><b>".get_string("assessmentby", "exercise", fullname($user))."</b></center></p>\n";
2049 exercise_print_assessment_form($exercise, $assessment);
2050 echo "<p align=\"right\"><a href=\"assessments.php?action=adminamendgradinggrade&amp;id=$cm->id&amp;aid=$assessment->id\">".
2051 get_string("amend", "exercise")." ".get_string("gradeforstudentsassessment","exercise",
2052 $course->student)."</a>\n";
2053 echo " | <a href=\"assessments.php?action=adminconfirmdelete&amp;id=$cm->id&amp;aid=$assessment->id\">".
2054 get_string("delete", "exercise")."</a></p><hr />\n";
2060 ///////////////////////////////////////////////////////////////////////////////////////////////
2061 function exercise_print_assessments_for_admin($exercise, $submission) {
2063 if (! $course = get_record("course", "id", $exercise->course)) {
2064 error("Course is misconfigured");
2066 if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
2067 error("Course Module ID was incorrect");
2070 if ($assessments = exercise_get_assessments($submission)) {
2071 foreach ($assessments as $assessment) {
2072 if (!$user = get_record("user", "id", $assessment->userid)) {
2073 error (" exercise_print_assessments_for_admin: unable to get user record");
2075 echo "<p><center><b>".get_string("assessmentby", "exercise", fullname($user))."</b></center></p>\n";
2076 exercise_print_assessment_form($exercise, $assessment);
2077 echo "<p align=\"right\"><a href=\"assessments.php?action=adminconfirmdelete&amp;id=$cm->id&amp;aid=$assessment->id\">".
2078 get_string("delete", "exercise")."</a></p><hr />\n";
2084 ///////////////////////////////////////////////////////////////////////////////////////////////
2085 function exercise_print_assignment_info($exercise) {
2087 if (! $course = get_record("course", "id", $exercise->course)) {
2088 error("Course is misconfigured");
2090 if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
2091 error("Course Module ID was incorrect");
2093 // print standard assignment heading
2094 $strdifference = format_time($exercise->deadline - time());
2095 if (($exercise->deadline - time()) < 0) {
2096 $strdifference = "<font color=\"red\">$strdifference</font>";
2098 $strduedate = userdate($exercise->deadline)." ($strdifference)";
2099 print_simple_box_start("center");
2100 print_heading(format_string($exercise->name), "center");
2101 print_simple_box_start("center");
2102 echo "<b>".get_string("duedate", "exercise")."</b>: $strduedate<br />";
2103 $maxgrade = $exercise->grade + $exercise->gradinggrade;
2104 echo "<b>".get_string("maximumgrade")."</b>: $maxgrade<br />";
2105 echo "<b>".get_string("handlingofmultiplesubmissions", "exercise")."</b>:";
2106 if ($exercise->usemaximum) {
2107 echo get_string("usemaximum", "exercise")."<br />\n";
2109 else {
2110 echo get_string("usemean", "exercise")."<br />\n";
2112 echo "<b>".get_string("detailsofassessment", "exercise")."</b>:
2113 <a href=\"assessments.php?id=$cm->id&amp;action=displaygradingform\">".
2114 get_string("specimenassessmentform", "exercise")."</a><br />";
2115 print_simple_box_end();
2116 print_simple_box_end();
2117 echo "<br />";
2121 ///////////////////////////////////////////////////////////////////////////////////////////////
2122 function exercise_print_difference($time) {
2123 if ($time < 0) {
2124 $timetext = get_string("late", "assignment", format_time($time));
2125 return " (<font color=\"red\">$timetext</font>)";
2126 } else {
2127 $timetext = get_string("early", "assignment", format_time($time));
2128 return " ($timetext)";
2133 ///////////////////////////////////////////////////////////////////////////////////////////////
2134 function exercise_print_feedback($course, $submission) {
2135 global $CFG, $RATING;
2137 if (! $teacher = get_record("user", "id", $submission->teacher)) {
2138 error("Weird exercise error");
2141 echo "\n<table border=\"0\" cellpadding=\"1\" cellspacing=\"1\" align=\"center\"><tr><td bgcolor=#888888>";
2142 echo "\n<table border=\"0\" cellpadding=\"3\" cellspacing=\"0\" valign=\"top\">";
2144 echo "\n<tr>";
2145 echo "\n<td rowspan=\"3\" width=\"35\" valign=\"top\">";
2146 print_user_picture($teacher->id, $course->id, $teacher->picture);
2147 echo "</td>";
2148 echo "<td nowrap=\"nowrap\" width=\"100%\">".fullname($teacher);
2149 echo "&nbsp;&nbsp;<font size=\"2\"><i>".userdate($submission->timemarked)."</i>";
2150 echo "</tr>";
2152 echo "\n<tr><td width=\"100%\">";
2154 echo "<p align=\"right\"><font size=-1><i>";
2155 if ($submission->grade) {
2156 echo get_string("grade").": $submission->grade";
2157 } else {
2158 echo get_string("nograde");
2160 echo "</i></font></p>";
2162 echo text_to_html($submission->assessorcomment);
2163 echo "</td></tr></table>";
2164 echo "</td></tr></table>";
2168 ///////////////////////////////////////////////////////////////////////////////////////////////
2169 function exercise_print_league_table($exercise) {
2170 // print an order table of (student) submissions in grade order, only print the student's best submission when
2171 // there are multiple submissions
2172 if (! $course = get_record("course", "id", $exercise->course)) {
2173 error("Print league table: Course is misconfigured");
2175 $groupid = get_current_group($course->id);
2176 $nentries = $exercise->showleaguetable;
2177 if ($nentries == 99) {
2178 $nentries = 999999; // a large number
2181 if ($exercise->anonymous and isstudent($course->id)) {
2182 $table->head = array (get_string("title", "exercise"), get_string("grade"));
2183 $table->align = array ("left", "center");
2184 $table->size = array ("*", "*");
2185 } else { // show names
2186 $table->head = array (get_string("title", "exercise"), get_string("name"), get_string("grade"));
2187 $table->align = array ("left", "left", "center");
2188 $table->size = array ("*", "*", "*");
2190 $table->cellpadding = 2;
2191 $table->cellspacing = 0;
2193 if ($submissions = exercise_get_student_submissions($exercise, "grade", $groupid)) {
2194 $n = 1;
2195 foreach ($submissions as $submission) {
2196 if (empty($done[$submission->userid])) {
2197 if ($submission->late) {
2198 continue;
2200 if (!$user = get_record("user", "id", $submission->userid)) {
2201 error("Print league table: user not found");
2203 if ($exercise->anonymous and isstudent($course->id)) {
2204 $table->data[] = array(exercise_print_submission_title($exercise, $submission),
2205 number_format($submission->grade * $exercise->grade / 100.0, 1));
2206 } else {
2207 $table->data[] = array(exercise_print_submission_title($exercise, $submission),
2208 fullname($user),
2209 number_format($submission->grade * $exercise->grade / 100.0, 1));
2211 $n++;
2212 if ($n > $nentries) {
2213 break;
2215 $done[$submission->userid] = 'ok';
2218 print_heading(get_string("leaguetable", "exercise"));
2219 print_table($table);
2224 ///////////////////////////////////////////////////////////////////////////////////////////////
2225 function exercise_print_submission_assessments($exercise, $submission) {
2226 // Returns a list of grades for this submission
2228 if (! $course = get_record("course", "id", $exercise->course)) {
2229 error("Course is misconfigured");
2231 if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
2232 error("Course Module ID was incorrect");
2235 $str = '';
2236 if ($assessments = exercise_get_assessments($submission)) {
2237 foreach ($assessments as $assessment) {
2238 if (isteacher($exercise->course, $assessment->userid)) {
2239 $str .= "[".number_format($assessment->grade * $exercise->grade / 100.0, 0)."] ";
2241 else { // assessment by student - shouldn't happen!
2242 $str .= "{".number_format($assessment->grade * $exercise->grade / 100.0, 0)."} ";
2246 if (!$str) {
2247 $str = "&nbsp;"; // be kind to Mozilla browsers!
2249 return $str;
2253 //////////////////////////////////////////////////////////////////////////////////////
2254 function exercise_print_tabbed_heading($tabs) {
2255 // Prints a tabbed heading where one of the tabs highlighted.
2256 // $tabs is an object with several properties.
2257 // $tabs->names is an array of tab names
2258 // $tabs->urls is an array of links
2259 // $tabs->align is an array of column alignments (defaults to "center")
2260 // $tabs->size is an array of column sizes
2261 // $tabs->wrap is an array of "nowrap"s or nothing
2262 // $tabs->highlight is an index (zero based) of "active" heading .
2263 // $tabs->width is an percentage of the page (defualts to 80%)
2264 // $tabs->cellpadding padding on each cell (defaults to 5)
2266 global $CFG;
2268 if (isset($tabs->names)) {
2269 foreach ($tabs->names as $key => $name) {
2270 if (!empty($tabs->urls[$key])) {
2271 $url =$tabs->urls[$key];
2272 if ($tabs->highlight == $key) {
2273 $tabcontents[$key] = "<b>$name</b>";
2274 } else {
2275 $tabcontents[$key] = "<a class= \"dimmed\" href=\"$url\"><b>$name</b></a>";
2277 } else {
2278 $tabcontents[$key] = "<b>$name</b>";
2283 if (empty($tabs->width)) {
2284 $tabs->width = "80%";
2287 if (empty($tabs->cellpadding)) {
2288 $tabs->cellpadding = "5";
2291 // print_simple_box_start("center", "$table->width", "#ffffff", 0);
2292 echo "<table width=\"$tabs->width\" border=\"0\" valign=\"top\" align=\"center\" ";
2293 echo " cellpadding=\"$tabs->cellpadding\" cellspacing=\"0\" class=\"generaltable\">\n";
2295 if (!empty($tabs->names)) {
2296 echo "<tr>";
2297 echo "<td class=\"generaltablecell\">".
2298 "<img width=\"10\" src=\"$CFG->wwwroot/pix/spacer.gif\" alt=\"\" /></td>\n";
2299 foreach ($tabcontents as $key => $tab) {
2300 if (isset($align[$key])) {
2301 $alignment = "align=\"$align[$key]\"";
2302 } else {
2303 $alignment = "align=\"center\"";
2305 if (isset($size[$key])) {
2306 $width = "width=\"$size[$key]\"";
2307 } else {
2308 $width = "";
2310 if (isset($wrap[$key])) {
2311 $wrapping = "no wrap";
2312 } else {
2313 $wrapping = "";
2315 if ($key == $tabs->highlight) {
2316 echo "<td valign=\"top\" class=\"generaltabselected\" $alignment $width $wrapping>$tab</td>\n";
2317 } else {
2318 echo "<td valign=\"top\" class=\"generaltab\" $alignment $width $wrapping>$tab</td>\n";
2320 echo "<td class=\"generaltablecell\">".
2321 "<img width=\"10\" src=\"$CFG->wwwroot/pix/spacer.gif\" alt=\"\" /></td>\n";
2323 echo "</tr>\n";
2324 } else {
2325 echo "<tr><td>No names specified</td></tr>\n";
2327 // bottom stripe
2328 $ncells = count($tabs->names)*2 +1;
2329 $height = 2;
2330 echo "<tr><td colspan=\"$ncells\">".
2331 "<img height=\"$height\" src=\"$CFG->wwwroot/pix/spacer.gif\" alt=\"\" /></td></tr>\n";
2332 echo "</table>\n";
2333 // print_simple_box_end();
2335 return true;
2339 ///////////////////////////////////////////////////////////////////////////////////////////////
2340 function exercise_print_teacher_assessment_form($exercise, $assessment, $submission, $returnto = '') {
2341 // prints an assessment form based on the student's assessment
2342 // if the teacher is re-assessing a submission they would use exercise_print_assessment_form()
2343 // (for teachers only)
2344 global $CFG, $USER, $EXERCISE_SCALES, $EXERCISE_EWEIGHTS;
2346 if (! $course = get_record("course", "id", $exercise->course)) {
2347 error("Course is misconfigured");
2349 if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
2350 error("Course Module ID was incorrect");
2353 $timenow = time();
2355 if(!$submissionowner = get_record("user", "id", $submission->userid)) {
2356 error("Print teacher assessment form: User record not found");
2359 echo "<center><table border=\"1\" width=\"30%\"><tr>
2360 <td align=\"center\">\n";
2361 if (!$teachersubmission = get_record("exercise_submissions", "id", $assessment->submissionid)) {
2362 error ("Print teacher assessment form: Submission record not found");
2364 echo exercise_print_submission_title($exercise, $teachersubmission);
2365 echo "</td></tr></table><br clear=\"all\" />\n";
2367 echo "<center><table border=\"1\" width=\"30%\"><tr>
2368 <td align=\"center\">\n";
2369 echo exercise_print_submission_title($exercise, $submission);
2370 echo "</td></tr></table></center><br clear=\"all\" />\n";
2373 <form id="assessmentform" method="post" action="assessments.php">
2374 <input type="hidden" name="id" value="<?php echo $cm->id ?>" />
2375 <input type="hidden" name="said" value="<?php echo $assessment->id ?>" />
2376 <input type="hidden" name="sid" value="<?php echo $submission->id ?>" />
2377 <input type="hidden" name="action" value="updateteacherassessment" />
2378 <input type="hidden" name="resubmit" value="0" />
2379 <input type="hidden" name="returnto" value="<?php echo $returnto ?>" />
2380 <?php
2382 // now print a normal assessment form based on the student's assessment for this submission
2383 // and allow the teacher to grade and add additional comments
2384 $studentassessment = $assessment;
2385 $allowchanges = true;
2387 print_heading_with_help(get_string("pleasemakeyourownassessment", "exercise",
2388 fullname($submissionowner)), "grading", "exercise");
2390 // is there an existing assessment for the submission
2391 if (!$assessment = exercise_get_submission_assessment($submission, $USER)) {
2392 // copy student's assessment with their comments for the teacher's assessment
2393 $assessment = exercise_copy_assessment($studentassessment, $submission, true);
2396 // only show the grade if grading strategy > 0 and the grade is positive
2397 if ($exercise->gradingstrategy and $assessment->grade >= 0) {
2398 echo "<center><b>".get_string("thegradeis", "exercise").": ".
2399 number_format($assessment->grade * $exercise->grade / 100.0, 2)." (".
2400 get_string("maximumgrade")." ".number_format($exercise->grade, 0).")</b></center><br clear=\"all\" />\n";
2403 echo "<center><table cellpadding=\"2\" border=\"1\">\n";
2404 echo "<tr valign=\"top\">\n";
2405 echo " <td colspan=\"2\"><center><b>".get_string("yourassessment", "exercise").
2406 "</b></center></td>\n";
2407 echo "</tr>\n";
2409 // get the assignment elements...
2410 if (!$elementsraw = get_records("exercise_elements", "exerciseid", $exercise->id, "elementno ASC")) {
2411 error("Teacher assessment form: Elements not found");
2413 foreach ($elementsraw as $element) {
2414 $elements[] = $element; // to renumber index 0,1,2...
2417 // ...and get any previous grades...
2418 if ($gradesraw = get_records_select("exercise_grades", "assessmentid = $assessment->id", "elementno")) {
2419 foreach ($gradesraw as $grade) {
2420 $grades[] = $grade; // to renumber index 0,1,2...
2424 // determine what sort of grading
2425 switch ($exercise->gradingstrategy) {
2426 case 0: // no grading
2427 // now print the form
2428 for ($i=0; $i < count($elements); $i++) {
2429 $iplus1 = $i+1;
2430 echo "<tr valign=\"top\">\n";
2431 echo " <td align=\"right\"><p><b>". get_string("element","exercise")." $iplus1:</b></p></td>\n";
2432 echo " <td>".text_to_html($elements[$i]->description);
2433 echo "</td></tr>\n";
2434 echo "<tr valign=\"top\">\n";
2435 echo " <td align=\"right\"><p><b>". get_string("feedback").":</b></p></td>\n";
2436 echo " <td>\n";
2437 if ($allowchanges) {
2438 echo " <textarea name=\"feedback[]\" rows=\"3\" cols=\"75\" wrap=\"virtual\">\n";
2439 if (isset($grades[$i]->feedback)) {
2440 echo $grades[$i]->feedback;
2442 echo "</textarea>\n";
2444 else {
2445 echo text_to_html($grades[$i]->feedback);
2447 echo " </td>\n";
2448 echo "</tr>\n";
2449 echo "<tr valign=\"top\">\n";
2450 echo " <td colspan=\"2\">&nbsp;</td>\n";
2451 echo "</tr>\n";
2453 break;
2455 case 1: // accumulative grading
2456 // now print the form
2457 for ($i=0; $i < count($elements); $i++) {
2458 $iplus1 = $i+1;
2459 echo "<tr valign=\"top\">\n";
2460 echo " <td align=\"right\"><p><b>". get_string("element","exercise")." $iplus1:</b></p></td>\n";
2461 echo " <td>".text_to_html($elements[$i]->description);
2462 echo "<p align=\"right\"><font size=\"1\">Weight: "
2463 .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</font>\n";
2464 echo "</td></tr>\n";
2465 echo "<tr valign=\"top\">\n";
2466 echo " <td align=\"right\"><p><b>". get_string("grade"). ":</b></p></td>\n";
2467 echo " <td valign=\"top\">\n";
2469 // get the appropriate scale
2470 $scalenumber=$elements[$i]->scale;
2471 $SCALE = (object)$EXERCISE_SCALES[$scalenumber];
2472 switch ($SCALE->type) {
2473 case 'radio' :
2474 // show selections highest first
2475 echo "<center><b>$SCALE->start</b>&nbsp;&nbsp;&nbsp;";
2476 for ($j = $SCALE->size - 1; $j >= 0 ; $j--) {
2477 $checked = false;
2478 if (isset($grades[$i]->grade)) {
2479 if ($j == $grades[$i]->grade) {
2480 $checked = true;
2483 else { // there's no previous grade so check the lowest option
2484 if ($j == 0) {
2485 $checked = true;
2488 if ($checked) {
2489 echo " <input type=\"RADIO\" name=\"grade[$i]\" value=\"$j\" checked=\"checked\" /> &nbsp;&nbsp;&nbsp;\n";
2491 else {
2492 echo " <input type=\"RADIO\" name=\"grade[$i]\" value=\"$j\" /> &nbsp;&nbsp;&nbsp;\n";
2495 echo "&nbsp;&nbsp;&nbsp;<b>$SCALE->end</b></center>\n";
2496 break;
2497 case 'selection' :
2498 unset($numbers);
2499 for ($j = $SCALE->size; $j >= 0; $j--) {
2500 $numbers[$j] = $j;
2502 if (isset($grades[$i]->grade)) {
2503 choose_from_menu($numbers, "grade[$i]", $grades[$i]->grade, "");
2505 else {
2506 choose_from_menu($numbers, "grade[$i]", 0, "");
2508 break;
2510 echo " </td>\n";
2511 echo "</tr>\n";
2513 echo "<tr valign=\"top\">\n";
2514 echo " <td align=\"right\"><p><b>". get_string("feedback").":</b></p></td>\n";
2515 echo " <td>\n";
2516 if ($allowchanges) {
2517 echo " <textarea name=\"feedback[]\" rows=\"3\" cols=\"75\" wrap=\"virtual\">\n";
2518 if (isset($grades[$i]->feedback)) {
2519 echo $grades[$i]->feedback;
2521 echo "</textarea>\n";
2523 else {
2524 echo text_to_html($grades[$i]->feedback);
2526 echo " </td>\n";
2527 echo "</tr>\n";
2528 echo "<tr valign=\"top\">\n";
2529 echo " <td colspan=\"2\">&nbsp;</td>\n";
2530 echo "</tr>\n";
2532 break;
2534 case 2: // error banded grading
2535 // now run through the elements
2536 $error = 0;
2537 for ($i=0; $i < count($elements) - 1; $i++) {
2538 $iplus1 = $i+1;
2539 echo "<tr valign=\"top\">\n";
2540 echo " <td align=\"right\"><p><b>". get_string("element","exercise")." $iplus1:</b></p></td>\n";
2541 echo " <td>".text_to_html($elements[$i]->description);
2542 echo "<p align=\"right\"><font size=\"1\">Weight: "
2543 .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</font>\n";
2544 echo "</td></tr>\n";
2545 echo "<tr valign=\"top\">\n";
2546 echo " <td align=\"right\"><p><b>". get_string("grade"). ":</b></p></td>\n";
2547 echo " <td valign=\"top\">\n";
2549 // get the appropriate scale - yes/no scale (0)
2550 $SCALE = (object) $EXERCISE_SCALES[0];
2551 switch ($SCALE->type) {
2552 case 'radio' :
2553 // show selections highest first
2554 echo "<center><b>$SCALE->start</b>&nbsp;&nbsp;&nbsp;";
2555 for ($j = $SCALE->size - 1; $j >= 0 ; $j--) {
2556 $checked = false;
2557 if (isset($grades[$i]->grade)) {
2558 if ($j == $grades[$i]->grade) {
2559 $checked = true;
2562 else { // there's no previous grade so check the lowest option
2563 if ($j == 0) {
2564 $checked = true;
2567 if ($checked) {
2568 echo " <input type=\"RADIO\" name=\"grade[$i]\" value=\"$j\" checked=\"checked\" /> &nbsp;&nbsp;&nbsp;\n";
2570 else {
2571 echo " <input type=\"RADIO\" name=\"grade[$i]\" value=\"$j\" /> &nbsp;&nbsp;&nbsp;\n";
2574 echo "&nbsp;&nbsp;&nbsp;<b>$SCALE->end</b></center>\n";
2575 break;
2576 case 'selection' :
2577 unset($numbers);
2578 for ($j = $SCALE->size; $j >= 0; $j--) {
2579 $numbers[$j] = $j;
2581 if (isset($grades[$i]->grade)) {
2582 choose_from_menu($numbers, "grade[$i]", $grades[$i]->grade, "");
2584 else {
2585 choose_from_menu($numbers, "grade[$i]", 0, "");
2587 break;
2590 echo " </td>\n";
2591 echo "</tr>\n";
2592 echo "<tr valign=\"top\">\n";
2593 echo " <td align=\"right\"><p><b>". get_string("feedback").":</b></p></td>\n";
2594 echo " <td>\n";
2595 if ($allowchanges) {
2596 echo " <textarea name=\"feedback[$i]\" rows=\"3\" cols=\"75\" wrap=\"virtual\">\n";
2597 if (isset($grades[$i]->feedback)) {
2598 echo $grades[$i]->feedback;
2600 echo "</textarea>\n";
2602 else {
2603 if (isset($grades[$i]->feedback)) {
2604 echo text_to_html($grades[$i]->feedback);
2607 echo "&nbsp;</td>\n";
2608 echo "</tr>\n";
2609 echo "<tr valign=\"top\">\n";
2610 echo " <td colspan=\"2\">&nbsp;</td>\n";
2611 echo "</tr>\n";
2612 if (empty($grades[$i]->grade)) {
2613 $error += $EXERCISE_EWEIGHTS[$elements[$i]->weight];
2616 // print the number of negative elements
2617 // echo "<tr><td>".get_string("numberofnegativeitems", "exercise")."</td><td>$negativecount</td></tr>\n";
2618 // echo "<tr valign=\"top\">\n";
2619 // echo " <td colspan=\"2\">&nbsp;</td>\n";
2620 echo "</table></center>\n";
2621 // now print the grade table
2622 echo "<p><center><b>".get_string("gradetable","exercise")."</b></center>\n";
2623 echo "<center><table cellpadding=\"5\" border=\"1\"><tr><td align=\"CENTER\">".
2624 get_string("numberofnegativeresponses", "exercise");
2625 echo "</td><td>". get_string("suggestedgrade", "exercise")."</td></tr>\n";
2626 for ($i=0; $i<=$exercise->nelements; $i++) {
2627 if ($i == intval($error + 0.5)) {
2628 echo "<tr><td align=\"CENTER\"><img src=\"$CFG->pixpath/t/right.gif\" alt=\"\" /> $i</td><td align=\"CENTER\">{$elements[$i]->maxscore}</td></tr>\n";
2630 else {
2631 echo "<tr><td align=\"CENTER\">$i</td><td align=\"CENTER\">{$elements[$i]->maxscore}</td></tr>\n";
2634 echo "</table></center>\n";
2635 echo "<p><center><table cellpadding=\"5\" border=\"1\"><tr><td align=\"right\"><b>".
2636 get_string("optionaladjustment", "exercise")."</b></td><td>\n";
2637 unset($numbers);
2638 for ($j = 20; $j >= -20; $j--) {
2639 $numbers[$j] = $j;
2641 if (isset($grades[$exercise->nelements]->grade)) {
2642 choose_from_menu($numbers, "grade[$exercise->nelements]", $grades[$exercise->nelements]->grade, "");
2644 else {
2645 choose_from_menu($numbers, "grade[$exercise->nelements]", 0, "");
2647 echo "</td></tr>\n";
2648 break;
2650 case 3: // criteria grading
2651 echo "<tr valign=\"top\">\n";
2652 echo " <td>&nbsp;</td>\n";
2653 echo " <td><b>". get_string("criterion","exercise")."</b></td>\n";
2654 echo " <td><b>".get_string("select")."</b></td>\n";
2655 echo " <td><b>".get_string("suggestedgrade", "exercise")."</b></td>\n";
2656 // find which criteria has been selected (saved in the zero element), if any
2657 if (isset($grades[0]->grade)) {
2658 $selection = $grades[0]->grade;
2660 else {
2661 $selection = 0;
2663 // now run through the elements
2664 for ($i=0; $i < count($elements); $i++) {
2665 $iplus1 = $i+1;
2666 echo "<tr valign=\"top\">\n";
2667 echo " <td>$iplus1</td><td>".text_to_html($elements[$i]->description)."</td>\n";
2668 if ($selection == $i) {
2669 echo " <td align=\"center\"><input type=\"RADIO\" name=\"grade[0]\" value=\"$i\" checked=\"checked\" /></td>\n";
2671 else {
2672 echo " <td align=\"center\"><input type=\"RADIO\" name=\"grade[0]\" value=\"$i\" /></td>\n";
2674 echo "<td align=\"center\">{$elements[$i]->maxscore}</td></tr>\n";
2676 echo "</table></center>\n";
2677 echo "<p><center><table cellpadding=\"5\" border=\"1\"><tr><td align=\"right\"><b>".
2678 get_string("optionaladjustment", "exercise")."</b></td><td>\n";
2679 unset($numbers);
2680 for ($j = 20; $j >= -20; $j--) {
2681 $numbers[$j] = $j;
2683 if (isset($grades[1]->grade)) {
2684 choose_from_menu($numbers, "grade[1]", $grades[1]->grade, "");
2686 else {
2687 choose_from_menu($numbers, "grade[1]", 0, "");
2689 echo "</td></tr>\n";
2690 break;
2692 case 4: // rubric grading
2693 // now run through the elements...
2694 for ($i=0; $i < count($elements); $i++) {
2695 $iplus1 = $i+1;
2696 echo "<tr valign=\"top\">\n";
2697 echo "<td align=\"right\"><b>".get_string("element", "exercise")." $iplus1:</b></td>\n";
2698 echo "<td>".text_to_html($elements[$i]->description).
2699 "<p align=\"right\"><font size=\"1\">Weight: "
2700 .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</font></td></tr>\n";
2701 echo "<tr valign=\"top\">\n";
2702 echo " <td align=\"center\"><b>".get_string("select")."</b></td>\n";
2703 echo " <td><b>". get_string("criterion","exercise")."</b></td></tr>\n";
2704 if (isset($grades[$i])) {
2705 $selection = $grades[$i]->grade;
2706 } else {
2707 $selection = 0;
2709 // ...and the rubrics
2710 if ($rubricsraw = get_records_select("exercise_rubrics", "exerciseid = $exercise->id AND
2711 elementno = $i", "rubricno ASC")) {
2712 unset($rubrics);
2713 foreach ($rubricsraw as $rubic) {
2714 $rubrics[] = $rubic; // to renumber index 0,1,2...
2716 for ($j=0; $j<5; $j++) {
2717 if (empty($rubrics[$j]->description)) {
2718 break; // out of inner for loop
2720 echo "<tr valign=\"top\">\n";
2721 if ($selection == $j) {
2722 echo " <td align=\"center\"><input type=\"RADIO\" name=\"grade[$i]\" value=\"$j\" checked=\"checked\" /></td>\n";
2723 } else {
2724 echo " <td align=\"center\"><input type=\"RADIO\" name=\"grade[$i]\" value=\"$j\" /></td>\n";
2726 echo "<td>".text_to_html($rubrics[$j]->description)."</td>\n";
2728 echo "<tr valign=\"top\">\n";
2729 echo " <td align=\"right\"><p><b>". get_string("feedback").":</b></p></td>\n";
2730 echo " <td>\n";
2731 if ($allowchanges) {
2732 echo " <textarea name=\"feedback[]\" rows=\"3\" cols=\"75\" wrap=\"virtual\">\n";
2733 if (isset($grades[$i]->feedback)) {
2734 echo $grades[$i]->feedback;
2736 echo "</textarea>\n";
2738 else {
2739 echo text_to_html($grades[$i]->feedback);
2741 echo " </td>\n";
2742 echo "</tr>\n";
2743 echo "<tr valign=\"top\">\n";
2744 echo " <td colspan=\"2\">&nbsp;</td>\n";
2745 echo "</tr>\n";
2748 break;
2749 } // end of outer switch
2751 // now get the general comment (present in all types)
2752 echo "<tr valign=\"top\">\n";
2753 switch ($exercise->gradingstrategy) {
2754 case 0:
2755 case 1:
2756 case 4 : // no grading, accumulative and rubic
2757 echo " <td align=\"right\"><p><b>". get_string("generalcomment", "exercise").":</b></p></td>\n";
2758 break;
2759 default :
2760 echo " <td align=\"right\"><p><b>". get_string("reasonforadjustment", "exercise").":</b></p></td>\n";
2762 echo " <td>\n";
2763 if ($allowchanges) {
2764 echo " <textarea name=\"generalcomment\" rows=\"5\" cols=\"75\" wrap=\"virtual\">\n";
2765 if (isset($assessment->generalcomment)) {
2766 echo $assessment->generalcomment;
2768 echo "</textarea>\n";
2770 else {
2771 if ($assessment) {
2772 if (isset($assessment->generalcomment)) {
2773 echo text_to_html($assessment->generalcomment);
2776 else {
2777 print_string("yourfeedbackgoeshere", "exercise");
2780 echo "&nbsp;</td>\n";
2781 echo "</tr>\n";
2782 echo "<tr valign=\"top\">\n";
2783 echo " <td colspan=\"2\">&nbsp;</td>\n";
2784 echo "</tr>\n";
2786 // ...and close the table and show two buttons...to resubmit or not to resubmit
2787 echo "</table>\n";
2788 echo "<br /><input type=\"button\" value=\"".get_string("studentnotallowed", "exercise", $course->student)."\"
2789 onclick=\"getElementById('assessmentform').submit();\" />\n";
2790 echo "<input type=\"button\" value=\"".get_string("studentallowedtoresubmit", "exercise", $course->student)."\"
2791 onclick=\"getElementById('assessmentform').resubmit.value='1';getElementById('assessmentform').submit();\" />\n";
2792 echo "</center></form>\n";
2796 ///////////////////////////////////////////////////////////////////////////////////////////////
2797 function exercise_print_teacher_table($course) {
2798 // print how many assessments each teacher has done in each exercise
2800 if (! $exercises = get_all_instances_in_course("exercise", $course)) {
2801 notice(get_string('thereareno', 'moodle', get_string('modulenameplural', 'exercise')), "../../course/view.php?id=$course->id");
2802 die;
2805 $timenow = time();
2807 $table->head[] = '';
2808 $table->align[] = 'left';
2809 $table->size[] = '*';
2810 $table->head[] = get_string("total");
2811 $table->align[] = "center";
2812 $table->size[] = "*";
2813 foreach ($exercises as $exercise) {
2814 $table->head[] = format_string($exercise->name);
2815 $table->align[] = "center";
2816 $table->size[] = "*";
2818 $table->cellpadding = 2;
2819 $table->cellspacing = 0;
2821 if (!$teachers = get_course_teachers($course->id, "u.firstname, u.lastname")) {
2822 error("No teachers on this course!");
2824 for ($j = 0; $j < count($exercises); $j++) {
2825 $grand[$j] = 0;
2827 $grandtotal = 0;
2828 foreach ($teachers as $teacher) {
2829 unset($n);
2830 $total = 0;
2831 $j = 0;
2832 foreach ($exercises as $exercise) {
2833 $i = exercise_count_assessments_by_teacher($exercise, $teacher);
2834 $n[] = $i;
2835 $total += $i;
2836 $grand[$j] += $i;
2837 $j++;
2839 $grandtotal += $total;
2840 $table->data[] = array_merge(array(fullname($teacher)), array($total), $n);
2842 $table->data[] = array_merge(array(get_string("total")), array($grandtotal), $grand);
2843 print_heading(get_string("teacherassessmenttable", "exercise", $course->teacher));
2844 print_table($table);
2848 ///////////////////////////////////////////////////////////////////////////////////////////////
2849 function exercise_print_time_to_deadline($time) {
2850 if ($time < 0) {
2851 $timetext = get_string("afterdeadline", "exercise", format_time($time));
2852 return " (<font color=\"red\">$timetext</font>)";
2853 } else {
2854 $timetext = get_string("beforedeadline", "exercise", format_time($time));
2855 return " ($timetext)";
2860 ///////////////////////////////////////////////////////////////////////////////////////////////
2861 function exercise_print_upload_form($exercise) {
2863 global $CFG;
2865 if (! $course = get_record("course", "id", $exercise->course)) {
2866 error("Course is misconfigured");
2868 if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
2869 error("Course Module ID was incorrect");
2872 echo "<div align=\"center\">";
2873 echo "<form enctype=\"multipart/form-data\" method=\"post\" action=\"upload.php\">";
2874 echo " <input type=\"hidden\" name=\"id\" value=\"$cm->id\" />";
2875 require_once($CFG->dirroot.'/lib/uploadlib.php');
2876 upload_print_form_fragment(1,array('newfile'),null,true,array('title'),$course->maxbytes,$exercise->maxbytes,false);
2877 echo " <input type=\"submit\" name=\"save\" value=\"".get_string("uploadthisfile")."\" />";
2878 echo " (".get_string("maximumupload").": ".display_size($exercise->maxbytes).")\n";
2879 echo "</form>";
2880 echo "</div>";
2884 ///////////////////////////////////////////////////////////////////////////////////////////////
2885 function exercise_print_user_assessments($exercise, $user) {
2886 // Returns the number of assessments and a hyperlinked list of grading grades for the assessments made by this user
2888 if ($assessments = exercise_get_user_assessments($exercise, $user)) {
2889 $n = count($assessments);
2890 $str = "$n (";
2891 foreach ($assessments as $assessment) {
2892 if ($assessment->timegraded) {
2893 $gradingscaled = round($assessment->gradinggrade * $exercise->gradinggrade / 100.0);
2894 $str .= "<a href=\"assessments.php?action=viewassessment&amp;a=$exercise->id&amp;aid=$assessment->id\">";
2895 $str .= "$gradingscaled</a> ";
2897 else {
2898 $str .= "<a href=\"assessments.php?action=viewassessment&amp;a=$exercise->id&amp;aid=$assessment->id\">";
2899 $str .= "-</a> ";
2902 $str .= ")";
2904 else {
2905 $str ="0";
2907 return $str;
2911 ///////////////////////////////////////////////////////////////////////////////////////////////
2912 function exercise_test_for_resubmission($exercise, $user) {
2913 // see if any of the user's submissions have the resubmit flag set
2914 $result = false;
2915 if ($submissions = exercise_get_user_submissions($exercise, $user)) {
2916 foreach ($submissions as $submission) {
2917 if ($submission->resubmit) {
2918 $result =true;
2919 break;
2923 return $result;
2927 ///////////////////////////////////////////////////////////////////////////////////////////////
2928 function exercise_test_user_assessments($exercise, $user) {
2929 // see if user has assessed one of teacher's exercises/submissions...
2930 global $CFG;
2932 $result = false;
2933 $timenow =time();
2934 if ($submissions = exercise_get_teacher_submissions($exercise)) {
2935 foreach ($submissions as $submission) {
2936 if ($assessment = exercise_get_submission_assessment($submission, $user)) {
2937 // ...the date stamp on the assessment should be in the past
2938 if ($assessment->timecreated < $timenow) {
2939 $result = true;
2940 break;
2945 return $result;