Hack from Roberto Pinna (Bobo) to add sorting when viewing submissions
[moodle.git] / mod / assignment / lib.php
1 <?PHP  // $Id$
3 require_once("$CFG->dirroot/files/mimetypes.php");
5 define("OFFLINE",      "0");
6 define("UPLOADSINGLE", "1");
8 $ASSIGNMENT_TYPE = array (OFFLINE       => get_string("typeoffline",      "assignment"),
9                           UPLOADSINGLE  => get_string("typeuploadsingle", "assignment") );
12 function assignment_add_instance($assignment) {
13 // Given an object containing all the necessary data, 
14 // (defined by the form in mod.html) this function 
15 // will create a new instance and return the id number 
16 // of the new instance.
18     $assignment->timemodified = time();
19     
20     $assignment->timedue = make_timestamp($assignment->dueyear, $assignment->duemonth, $assignment->dueday, 
21                                           $assignment->duehour, $assignment->dueminute);
23     return insert_record("assignment", $assignment);
24 }
27 function assignment_update_instance($assignment) {
28 // Given an object containing all the necessary data, 
29 // (defined by the form in mod.html) this function 
30 // will update an existing instance with new data.
32     $assignment->timemodified = time();
33     $assignment->timedue = make_timestamp($assignment->dueyear, $assignment->duemonth, $assignment->dueday, 
34                                           $assignment->duehour, $assignment->dueminute);
35     $assignment->id = $assignment->instance;
37     return update_record("assignment", $assignment);
38 }
41 function assignment_delete_instance($id) {
42 // Given an ID of an instance of this module, 
43 // this function will permanently delete the instance 
44 // and any data that depends on it.  
46     if (! $assignment = get_record("assignment", "id", "$id")) {
47         return false;
48     }
50     $result = true;
52     if (! delete_records("assignment_submissions", "assignment", "$assignment->id")) {
53         $result = false;
54     }
56     if (! delete_records("assignment", "id", "$assignment->id")) {
57         $result = false;
58     }
60     return $result;
61 }
63 function assignment_user_outline($course, $user, $mod, $assignment) {
64     if ($submission = assignment_get_submission($assignment, $user)) {
65         
66         if ($submission->grade) {
67             $result->info = get_string("grade").": $submission->grade";
68         }
69         $result->time = $submission->timemodified;
70         return $result;
71     }
72     return NULL;
73 }
75 function assignment_user_complete($course, $user, $mod, $assignment) {
76     if ($submission = assignment_get_submission($assignment, $user)) {
77         if ($basedir = assignment_file_area($assignment, $user)) {
78             if ($files = get_directory_list($basedir)) {
79                 $countfiles = count($files)." ".get_string("uploadedfiles", "assignment");
80                 foreach ($files as $file) {
81                     $countfiles .= "; $file";
82                 }
83             }
84         }
86         print_simple_box_start();
87         echo "<P><FONT SIZE=1>";
88         echo get_string("lastmodified").": ";
89         echo userdate($submission->timemodified);
90         echo assignment_print_difference($assignment->timedue - $submission->timemodified);
91         echo "</FONT></P>";
93         assignment_print_user_files($assignment, $user);
95         echo "<BR>";
97         assignment_print_feedback($course, $submission);
99         print_simple_box_end();
101     } else {
102         print_string("notsubmittedyet", "assignment");
103     }
107 function assignment_cron () {
108 // Function to be run periodically according to the moodle cron
109 // Finds all assignment notifications that have yet to be mailed out, and mails them
111     global $CFG, $USER;
113     $cutofftime = time() - $CFG->maxeditingtime;
115     if ($submissions = assignment_get_unmailed_submissions($cutofftime)) {
116         $timenow = time();
118         foreach ($submissions as $submission) {
120             echo "Processing assignment submission $submission->id\n";
122             if (! $user = get_record("user", "id", "$submission->userid")) {
123                 echo "Could not find user $post->userid\n";
124                 continue;
125             }
127             $USER->lang = $user->lang;
129             if (! $course = get_record("course", "id", "$submission->course")) {
130                 echo "Could not find course $submission->course\n";
131                 continue;
132             }
134             if (! isstudent($course->id, $user->id) and !isteacher($course->id, $user->id)) {
135                 echo "$user->firstname $user->lastname not an active participant in $course->shortname\n";
136                 continue;
137             }
139             if (! $teacher = get_record("user", "id", "$submission->teacher")) {
140                 echo "Could not find teacher $submission->teacher\n";
141                 continue;
142             }
144             if (! $mod = get_coursemodule_from_instance("assignment", $submission->assignment, $course->id)) {
145                 echo "Could not find course module for assignment id $submission->assignment\n";
146                 continue;
147             }
149             $strassignments = get_string("modulenameplural", "assignment");
150             $strassignment  = get_string("modulename", "assignment");
152             $postsubject = "$course->shortname: $strassignments: $submission->name";
153             $posttext  = "$course->shortname -> $strassignments -> $submission->name\n";
154             $posttext .= "---------------------------------------------------------------------\n";
155             $posttext .= "$teacher->firstname $teacher->lastname has posted some feedback on your\n";
156             $posttext .= "assignment submission for '$submission->name'\n\n";
157             $posttext .= "You can see it appended to your assignment submission:\n";
158             $posttext .= "   $CFG->wwwroot/mod/assignment/view.php?id=$mod->id\n";
159             $posttext .= "---------------------------------------------------------------------\n";
160             if ($user->mailformat == 1) {  // HTML
161                 $posthtml = "<P><FONT FACE=sans-serif>".
162               "<A HREF=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</A> ->".
163               "<A HREF=\"$CFG->wwwroot/mod/assignment/index.php?id=$course->id\">$strassignments</A> ->".
164               "<A HREF=\"$CFG->wwwroot/mod/assignment/view.php?id=$mod->id\">$submission->name</A></FONT></P>";
165               $posthtml .= "<HR><FONT FACE=sans-serif>";
166               $posthtml .= "<P>$teacher->firstname $teacher->lastname has posted some feedback on your";
167               $posthtml .= " assignment submission for '<B>$submission->name</B>'</P>";
168               $posthtml .= "<P>You can see it <A HREF=\"$CFG->wwwroot/mod/assignment/view.php?id=$mod->id\">";
169               $posthtml .= "appended to your assignment submission</A>.</P></FONT><HR>";
170             } else {
171               $posthtml = "";
172             }
174             if (! email_to_user($user, $teacher, $postsubject, $posttext, $posthtml)) {
175                 echo "Error: assignment cron: Could not send out mail for id $submission->id to user $user->id ($user->email)\n";
176             }
177             if (! set_field("assignment_submissions", "mailed", "1", "id", "$submission->id")) {
178                 echo "Could not update the mailed field for id $submission->id\n";
179             }
180         }
181     }
183     return true;
186 function assignment_print_recent_activity(&$logs, $isteacher=false) {
187     global $CFG, $COURSE_TEACHER_COLOR;
189     $content = false;
190     $assignments = NULL;
192     foreach ($logs as $log) {
193         if ($log->module == "assignment" and $log->action == "upload") {
194             $assignments[$log->info] = assignment_log_info($log);
195             $assignments[$log->info]->time = $log->time;
196             $assignments[$log->info]->url  = $log->url;
197         }
198     }
200     if ($assignments) {
201         $strftimerecent = get_string("strftimerecent");
202         $content = true;
203         print_headline(get_string("newsubmissions", "assignment").":");
204         foreach ($assignments as $assignment) {
205             $date = userdate($assignment->time, $strftimerecent);
206             echo "<P><FONT SIZE=1>$date - $assignment->firstname $assignment->lastname<BR>";
207             echo "\"<A HREF=\"$CFG->wwwroot/mod/assignment/$assignment->url\">";
208             echo "$assignment->name";
209             echo "</A>\"</FONT></P>";
210         }
211     }
212  
213     return $content;
216 function assignment_grades($assignmentid) {
217 /// Must return an array of grades, indexed by user, and a max grade.
219     $return->grades = get_records_menu("assignment_submissions", "assignment", 
220                                        $assignmentid, "", "userid,grade");
221     $return->maxgrade = get_field("assignment", "grade", "id", "$assignmentid");
222     return $return;
225 /// SQL STATEMENTS //////////////////////////////////////////////////////////////////
227 function assignment_log_info($log) {
228     global $CFG;
229     return get_record_sql("SELECT a.name, u.firstname, u.lastname
230                              FROM {$CFG->prefix}assignment a, 
231                                   {$CFG->prefix}user u
232                             WHERE a.id = '$log->info' 
233                               AND u.id = '$log->userid'");
236 function assignment_get_all_submissions($assignment, $sort="timemodified", $dir="DESC") {
237 /// Return all assignment submissions by ENROLLED students
238     global $CFG;
240     if ($sort == "lastname" or $sort == "firstname") {
241         $sort = "u.$sort $dir";
242     } else if (empty($sort)) {
243         $sort = "a.timemodified DESC";
244     } else {
245         $sort = "a.$sort $dir";
246     }
247     return get_records_sql("SELECT a.* 
248                               FROM {$CFG->prefix}assignment_submissions a, 
249                                    {$CFG->prefix}user_students s,
250                                    {$CFG->prefix}user u
251                              WHERE a.userid = s.userid
252                                            AND u.id = a.userid
253                                AND s.course = '$assignment->course'
254                                AND a.assignment = '$assignment->id' 
255                           ORDER BY $sort");
258 function assignment_get_users_done($assignment) {
259 /// Return list of users who have done an assignment
260     global $CFG;
261     return get_records_sql("SELECT u.* 
262                               FROM {$CFG->prefix}user u, 
263                                    {$CFG->prefix}user_students s, 
264                                    {$CFG->prefix}assignment_submissions a
265                              WHERE s.course = '$assignment->course' 
266                                AND s.userid = u.id
267                                AND u.id = a.userid 
268                                AND a.assignment = '$assignment->id'
269                           ORDER BY a.timemodified DESC");
272 function assignment_get_unmailed_submissions($cutofftime) {
273 /// Return list of marked submissions that have not been mailed out for currently enrolled students
274     global $CFG;
275     return get_records_sql("SELECT s.*, a.course, a.name
276                               FROM {$CFG->prefix}assignment_submissions s, 
277                                    {$CFG->prefix}assignment a,
278                                    {$CFG->prefix}user_students us
279                              WHERE s.mailed = 0 
280                                AND s.timemarked < $cutofftime 
281                                AND s.timemarked > 0
282                                AND s.assignment = a.id
283                                AND s.userid = us.userid
284                                AND a.course = us.course");
288 //////////////////////////////////////////////////////////////////////////////////////
290 function assignment_file_area_name($assignment, $user) {
291 //  Creates a directory file name, suitable for make_upload_directory()
292     global $CFG;
294     return "$assignment->course/$CFG->moddata/assignment/$assignment->id/$user->id";
297 function assignment_file_area($assignment, $user) {
298     return make_upload_directory( assignment_file_area_name($assignment, $user) );
301 function assignment_get_submission($assignment, $user) {
302     return get_record("assignment_submissions", "assignment", $assignment->id, "userid", $user->id);
305 function assignment_print_difference($time) {
306     if ($time < 0) {
307         $timetext = get_string("late", "assignment", format_time($time));
308         return " (<FONT COLOR=RED>$timetext</FONT>)";
309     } else {
310         $timetext = get_string("early", "assignment", format_time($time));
311         return " ($timetext)";
312     }
315 function assignment_print_submission($assignment, $user, $submission, $teachers, $grades) {
316     global $THEME, $USER;
318     echo "\n<TABLE BORDER=1 CELLSPACING=0 valign=top cellpadding=10 align=center>";
320     echo "\n<TR>";
321     if ($assignment->type == OFFLINE) {
322         echo "\n<TD BGCOLOR=\"$THEME->body\" WIDTH=35 VALIGN=TOP>";
323     } else {
324         echo "\n<TD ROWSPAN=2 BGCOLOR=\"$THEME->body\" WIDTH=35 VALIGN=TOP>";
325     }
326     print_user_picture($user->id, $assignment->course, $user->picture);
327     echo "</TD>";
328     echo "<TD NOWRAP BGCOLOR=\"$THEME->cellheading\">$user->firstname $user->lastname";
329     if ($submission->timemodified) {
330         echo "&nbsp;&nbsp;<FONT SIZE=1>".get_string("lastmodified").": ";
331         echo userdate($submission->timemodified);
332         echo assignment_print_difference($assignment->timedue - $submission->timemodified);
333         echo "</FONT>";
334     }
335     echo "</TR>";
337     if ($assignment->type != OFFLINE) {
338         echo "\n<TR><TD BGCOLOR=\"$THEME->cellcontent\">";
339         if ($submission->timemodified) {
340             assignment_print_user_files($assignment, $user);
341         } else {
342             print_string("notsubmittedyet", "assignment");
343         }
344         echo "</TD></TR>";
345     }
347     echo "\n<TR>";
348     echo "<TD WIDTH=35 VALIGN=TOP>";
349     if (!$submission->teacher) {
350         $submission->teacher = $USER->id;
351     }
352     print_user_picture($submission->teacher, $assignment->course, $teachers[$submission->teacher]->picture);
353     if ($submission->timemodified > $submission->timemarked) {
354         echo "<TD BGCOLOR=\"$THEME->cellheading2\">";
355     } else {
356         echo "<TD BGCOLOR=\"$THEME->cellheading\">";
357     }
358     echo get_string("feedback", "assignment").":";
359     choose_from_menu($grades, "g$submission->id", $submission->grade, get_string("grade")."...");
360     if ($submission->timemarked) {
361         echo "&nbsp;&nbsp;<FONT SIZE=1>".userdate($submission->timemarked)."</FONT>";
362     }
363     echo "<BR><TEXTAREA NAME=\"c$submission->id\" ROWS=6 COLS=60 WRAP=virtual>";
364     p($submission->comment);
365     echo "</TEXTAREA><BR>";
366     echo "</TD></TR>";
367    
368     echo "</TABLE><BR CLEAR=ALL>\n";
371 function assignment_print_feedback($course, $submission) {
372     global $CFG, $THEME, $RATING;
374     if (! $teacher = get_record("user", "id", $submission->teacher)) {
375         error("Weird assignment error");
376     }
378     echo "\n<TABLE BORDER=0 CELLPADDING=1 CELLSPACING=1 ALIGN=CENTER><TR><TD BGCOLOR=#888888>";
379     echo "\n<TABLE BORDER=0 CELLPADDING=3 CELLSPACING=0 VALIGN=TOP>";
381     echo "\n<TR>";
382     echo "\n<TD ROWSPAN=3 BGCOLOR=\"$THEME->body\" WIDTH=35 VALIGN=TOP>";
383     print_user_picture($teacher->id, $course->id, $teacher->picture);
384     echo "</TD>";
385     echo "<TD NOWRAP WIDTH=100% BGCOLOR=\"$THEME->cellheading\">$teacher->firstname $teacher->lastname";
386     echo "&nbsp;&nbsp;<FONT SIZE=2><I>".userdate($submission->timemarked)."</I>";
387     echo "</TR>";
389     echo "\n<TR><TD WIDTH=100% BGCOLOR=\"$THEME->cellcontent\">";
391     echo "<P ALIGN=RIGHT><FONT SIZE=-1><I>";
392     if ($submission->grade) {
393         echo get_string("grade").": $submission->grade";
394     } else {
395         echo get_string("nograde");
396     }
397     echo "</I></FONT></P>";
399     echo text_to_html($submission->comment);
400     echo "</TD></TR></TABLE>";
401     echo "</TD></TR></TABLE>";
405 function assignment_print_user_files($assignment, $user) {
406 // Arguments are objects
408     global $CFG;
410     $filearea = assignment_file_area_name($assignment, $user);
412     if ($basedir = assignment_file_area($assignment, $user)) {
413         if ($files = get_directory_list($basedir)) {
414             foreach ($files as $file) {
415                 $icon = mimeinfo("icon", $file);
416                 if ($CFG->slasharguments) {
417                     $ffurl = "file.php/$filearea/$file";
418                 } else {
419                     $ffurl = "file.php?file=/$filearea/$file";
420                 }
422                 echo "<IMG SRC=\"$CFG->wwwroot/files/pix/$icon\" HEIGHT=16 WIDTH=16 BORDER=0 ALT=\"File\">";
423                 echo "&nbsp;<A TARGET=\"uploadedfile\" HREF=\"$CFG->wwwroot/$ffurl\">$file</A>";
424                 echo "<BR>";
425             }
426         }
427     }
430 function assignment_delete_user_files($assignment, $user, $exception) {
431 // Deletes all the user files in the assignment area for a user
432 // EXCEPT for any file named $exception
434     if ($basedir = assignment_file_area($assignment, $user)) {
435         if ($files = get_directory_list($basedir)) {
436             foreach ($files as $file) {
437                 if ($file != $exception) {
438                     unlink("$basedir/$file");
439                     notify("Existing file '$file' has been deleted!");
440                 }
441             }
442         }
443     }
446 function assignment_print_upload_form($assignment) {
447 // Arguments are objects
449     echo "<DIV ALIGN=CENTER>";
450     echo "<FORM ENCTYPE=\"multipart/form-data\" METHOD=\"POST\" ACTION=upload.php>";
451     echo " <INPUT TYPE=hidden NAME=MAX_FILE_SIZE value=\"$assignment->maxbytes\">";
452     echo " <INPUT TYPE=hidden NAME=id VALUE=\"$assignment->id\">";
453     echo " <INPUT NAME=\"newfile\" TYPE=\"file\" size=\"50\">";
454     echo " <INPUT TYPE=submit NAME=save VALUE=\"".get_string("uploadthisfile")."\">";
455     echo "</FORM>";
456     echo "</DIV>";
459 ?>