When posting a forum, users can unsubscribe/subscribe on the fly.
[moodle.git] / mod / assignment / lib.php
CommitLineData
04eba58f 1<?PHP // $Id$
2
b0e3a925 3require_once("$CFG->dirroot/files/mimetypes.php");
d699cd1e 4
b7b42874 5define("OFFLINE", "0");
6define("UPLOADSINGLE", "1");
7
8$ASSIGNMENT_TYPE = array (OFFLINE => get_string("typeoffline", "assignment"),
9 UPLOADSINGLE => get_string("typeuploadsingle", "assignment") );
d699cd1e 10
11
04eba58f 12function 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.
17
18 $assignment->timemodified = time();
d699cd1e 19
20 $assignment->timedue = make_timestamp($assignment->dueyear, $assignment->duemonth, $assignment->dueday,
21 $assignment->duehour, $assignment->dueminute);
04eba58f 22
23 return insert_record("assignment", $assignment);
24}
25
26
27function 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.
31
32 $assignment->timemodified = time();
d699cd1e 33 $assignment->timedue = make_timestamp($assignment->dueyear, $assignment->duemonth, $assignment->dueday,
34 $assignment->duehour, $assignment->dueminute);
04eba58f 35 $assignment->id = $assignment->instance;
36
37 return update_record("assignment", $assignment);
38}
39
40
41function 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.
45
46 if (! $assignment = get_record("assignment", "id", "$id")) {
47 return false;
48 }
49
50 $result = true;
51
52 if (! delete_records("assignment_submissions", "assignment", "$assignment->id")) {
53 $result = false;
54 }
55
56 if (! delete_records("assignment", "id", "$assignment->id")) {
57 $result = false;
58 }
59
60 return $result;
61}
62
77db7e4c 63function assignment_user_outline($course, $user, $mod, $assignment) {
64 if ($submission = assignment_get_submission($assignment, $user)) {
98092498 65
66 if ($submission->grade) {
67 $result->info = get_string("grade").": $submission->grade";
77db7e4c 68 }
77db7e4c 69 $result->time = $submission->timemodified;
70 return $result;
71 }
72 return NULL;
73}
74
75function 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 }
85
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>";
92
93 assignment_print_user_files($assignment, $user);
94
95 echo "<BR>";
96
97 assignment_print_feedback($course, $submission);
98
99 print_simple_box_end();
100
101 } else {
102 print_string("notsubmittedyet", "assignment");
103 }
104}
105
106
d699cd1e 107function 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
110
a16c2180 111 global $CFG, $USER;
d699cd1e 112
113 $cutofftime = time() - $CFG->maxeditingtime;
114
9fa49e22 115 if ($submissions = assignment_get_unmailed_submissions($cutofftime)) {
d699cd1e 116 $timenow = time();
117
118 foreach ($submissions as $submission) {
119
120 echo "Processing assignment submission $submission->id\n";
121
ebc3bd2b 122 if (! $user = get_record("user", "id", "$submission->userid")) {
123 echo "Could not find user $post->userid\n";
d699cd1e 124 continue;
125 }
126
a5a4cd60 127 $USER->lang = $user->lang;
128
d699cd1e 129 if (! $course = get_record("course", "id", "$submission->course")) {
130 echo "Could not find course $submission->course\n";
131 continue;
132 }
133
134 if (! isstudent($course->id, $user->id) and !isteacher($course->id, $user->id)) {
b9287b2f 135 echo "$user->firstname $user->lastname not an active participant in $course->shortname\n";
136 continue;
d699cd1e 137 }
138
139 if (! $teacher = get_record("user", "id", "$submission->teacher")) {
140 echo "Could not find teacher $submission->teacher\n";
141 continue;
142 }
143
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 }
148
149 $strassignments = get_string("modulenameplural", "assignment");
150 $strassignment = get_string("modulename", "assignment");
151
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 }
173
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 }
182
183 return true;
184}
185
1b5910c4 186function assignment_print_recent_activity($course, $isteacher, $timestart) {
3d891989 187 global $CFG;
3446205d 188
189 $content = false;
190 $assignments = NULL;
191
1b5910c4 192 if (!$logs = get_records_select("log", "time > '$timestart' AND ".
193 "course = '$course->id' AND ".
194 "module = 'assignment' AND ".
195 "action = 'upload' ", "time ASC")) {
196 return false;
197 }
198
199 foreach ($logs as $log) {
200 //Create a temp valid module structure (course,id)
201 $tempmod->course = $log->course;
202 $tempmod->id = $log->info;
203 //Obtain the visible property from the instance
204 $modvisible = instance_is_visible($log->module,$tempmod);
205
206 //Only if the mod is visible
207 if ($modvisible) {
208 $assignments[$log->info] = assignment_log_info($log);
209 $assignments[$log->info]->time = $log->time;
210 $assignments[$log->info]->url = $log->url;
3446205d 211 }
212 }
213
214 if ($assignments) {
dcde9f02 215 $strftimerecent = get_string("strftimerecent");
3446205d 216 $content = true;
217 print_headline(get_string("newsubmissions", "assignment").":");
218 foreach ($assignments as $assignment) {
dcde9f02 219 $date = userdate($assignment->time, $strftimerecent);
1b5910c4 220 echo "<p><font size=1>$date - $assignment->firstname $assignment->lastname<br>";
221 echo "\"<a href=\"$CFG->wwwroot/mod/assignment/$assignment->url\">";
3446205d 222 echo "$assignment->name";
1b5910c4 223 echo "</a>\"</font></p>";
3446205d 224 }
225 }
226
227 return $content;
228}
d699cd1e 229
d0ac6bc2 230function assignment_grades($assignmentid) {
858deff0 231/// Must return an array of grades, indexed by user, and a max grade.
d0ac6bc2 232
9fa49e22 233 $return->grades = get_records_menu("assignment_submissions", "assignment",
ebc3bd2b 234 $assignmentid, "", "userid,grade");
858deff0 235 $return->maxgrade = get_field("assignment", "grade", "id", "$assignmentid");
236 return $return;
d0ac6bc2 237}
238
9fa49e22 239/// SQL STATEMENTS //////////////////////////////////////////////////////////////////
240
241function assignment_log_info($log) {
242 global $CFG;
243 return get_record_sql("SELECT a.name, u.firstname, u.lastname
244 FROM {$CFG->prefix}assignment a,
245 {$CFG->prefix}user u
246 WHERE a.id = '$log->info'
ebc3bd2b 247 AND u.id = '$log->userid'");
9fa49e22 248}
249
df48be74 250function assignment_get_all_submissions($assignment, $sort="", $dir="DESC") {
9fa49e22 251/// Return all assignment submissions by ENROLLED students
252 global $CFG;
000cc405 253
254 if ($sort == "lastname" or $sort == "firstname") {
255 $sort = "u.$sort $dir";
256 } else if (empty($sort)) {
257 $sort = "a.timemodified DESC";
258 } else {
259 $sort = "a.$sort $dir";
260 }
9fa49e22 261 return get_records_sql("SELECT a.*
262 FROM {$CFG->prefix}assignment_submissions a,
000cc405 263 {$CFG->prefix}user_students s,
264 {$CFG->prefix}user u
ebc3bd2b 265 WHERE a.userid = s.userid
b2d0ca3b 266 AND u.id = a.userid
9fa49e22 267 AND s.course = '$assignment->course'
268 AND a.assignment = '$assignment->id'
000cc405 269 ORDER BY $sort");
9fa49e22 270}
271
272function assignment_get_users_done($assignment) {
273/// Return list of users who have done an assignment
274 global $CFG;
275 return get_records_sql("SELECT u.*
276 FROM {$CFG->prefix}user u,
277 {$CFG->prefix}user_students s,
278 {$CFG->prefix}assignment_submissions a
279 WHERE s.course = '$assignment->course'
ebc3bd2b 280 AND s.userid = u.id
281 AND u.id = a.userid
9fa49e22 282 AND a.assignment = '$assignment->id'
283 ORDER BY a.timemodified DESC");
284}
285
286function assignment_get_unmailed_submissions($cutofftime) {
a2631c99 287/// Return list of marked submissions that have not been mailed out for currently enrolled students
9fa49e22 288 global $CFG;
289 return get_records_sql("SELECT s.*, a.course, a.name
290 FROM {$CFG->prefix}assignment_submissions s,
a2631c99 291 {$CFG->prefix}assignment a,
292 {$CFG->prefix}user_students us
9fa49e22 293 WHERE s.mailed = 0
294 AND s.timemarked < $cutofftime
295 AND s.timemarked > 0
a2631c99 296 AND s.assignment = a.id
297 AND s.userid = us.userid
298 AND a.course = us.course");
9fa49e22 299}
300
301
d699cd1e 302//////////////////////////////////////////////////////////////////////////////////////
303
304function assignment_file_area_name($assignment, $user) {
305// Creates a directory file name, suitable for make_upload_directory()
ca4f8eb8 306 global $CFG;
307
308 return "$assignment->course/$CFG->moddata/assignment/$assignment->id/$user->id";
d699cd1e 309}
310
311function assignment_file_area($assignment, $user) {
312 return make_upload_directory( assignment_file_area_name($assignment, $user) );
313}
314
315function assignment_get_submission($assignment, $user) {
ebc3bd2b 316 return get_record("assignment_submissions", "assignment", $assignment->id, "userid", $user->id);
d699cd1e 317}
318
319function assignment_print_difference($time) {
320 if ($time < 0) {
321 $timetext = get_string("late", "assignment", format_time($time));
322 return " (<FONT COLOR=RED>$timetext</FONT>)";
323 } else {
324 $timetext = get_string("early", "assignment", format_time($time));
325 return " ($timetext)";
326 }
327}
328
329function assignment_print_submission($assignment, $user, $submission, $teachers, $grades) {
ce78926d 330 global $THEME, $USER;
d699cd1e 331
b7b42874 332 echo "\n<TABLE BORDER=1 CELLSPACING=0 valign=top cellpadding=10 align=center>";
d699cd1e 333
334 echo "\n<TR>";
b7b42874 335 if ($assignment->type == OFFLINE) {
336 echo "\n<TD BGCOLOR=\"$THEME->body\" WIDTH=35 VALIGN=TOP>";
337 } else {
338 echo "\n<TD ROWSPAN=2 BGCOLOR=\"$THEME->body\" WIDTH=35 VALIGN=TOP>";
339 }
d699cd1e 340 print_user_picture($user->id, $assignment->course, $user->picture);
341 echo "</TD>";
b7b42874 342 echo "<TD NOWRAP BGCOLOR=\"$THEME->cellheading\">$user->firstname $user->lastname";
343 if ($submission->timemodified) {
d699cd1e 344 echo "&nbsp;&nbsp;<FONT SIZE=1>".get_string("lastmodified").": ";
345 echo userdate($submission->timemodified);
346 echo assignment_print_difference($assignment->timedue - $submission->timemodified);
347 echo "</FONT>";
348 }
349 echo "</TR>";
350
b7b42874 351 if ($assignment->type != OFFLINE) {
352 echo "\n<TR><TD BGCOLOR=\"$THEME->cellcontent\">";
ff446576 353 if ($submission->timemodified) {
b7b42874 354 assignment_print_user_files($assignment, $user);
355 } else {
356 print_string("notsubmittedyet", "assignment");
d699cd1e 357 }
d699cd1e 358 echo "</TD></TR>";
359 }
b7b42874 360
361 echo "\n<TR>";
362 echo "<TD WIDTH=35 VALIGN=TOP>";
363 if (!$submission->teacher) {
364 $submission->teacher = $USER->id;
365 }
366 print_user_picture($submission->teacher, $assignment->course, $teachers[$submission->teacher]->picture);
367 if ($submission->timemodified > $submission->timemarked) {
368 echo "<TD BGCOLOR=\"$THEME->cellheading2\">";
369 } else {
370 echo "<TD BGCOLOR=\"$THEME->cellheading\">";
371 }
f830b324 372 echo get_string("feedback", "assignment").":";
b7b42874 373 choose_from_menu($grades, "g$submission->id", $submission->grade, get_string("grade")."...");
374 if ($submission->timemarked) {
375 echo "&nbsp;&nbsp;<FONT SIZE=1>".userdate($submission->timemarked)."</FONT>";
376 }
377 echo "<BR><TEXTAREA NAME=\"c$submission->id\" ROWS=6 COLS=60 WRAP=virtual>";
378 p($submission->comment);
379 echo "</TEXTAREA><BR>";
380 echo "</TD></TR>";
381
d699cd1e 382 echo "</TABLE><BR CLEAR=ALL>\n";
383}
384
385function assignment_print_feedback($course, $submission) {
386 global $CFG, $THEME, $RATING;
387
388 if (! $teacher = get_record("user", "id", $submission->teacher)) {
389 error("Weird assignment error");
390 }
391
b0f01dff 392 echo "\n<TABLE BORDER=0 CELLPADDING=1 CELLSPACING=1 ALIGN=CENTER><TR><TD BGCOLOR=#888888>";
393 echo "\n<TABLE BORDER=0 CELLPADDING=3 CELLSPACING=0 VALIGN=TOP>";
d699cd1e 394
395 echo "\n<TR>";
396 echo "\n<TD ROWSPAN=3 BGCOLOR=\"$THEME->body\" WIDTH=35 VALIGN=TOP>";
397 print_user_picture($teacher->id, $course->id, $teacher->picture);
398 echo "</TD>";
399 echo "<TD NOWRAP WIDTH=100% BGCOLOR=\"$THEME->cellheading\">$teacher->firstname $teacher->lastname";
400 echo "&nbsp;&nbsp;<FONT SIZE=2><I>".userdate($submission->timemarked)."</I>";
401 echo "</TR>";
402
403 echo "\n<TR><TD WIDTH=100% BGCOLOR=\"$THEME->cellcontent\">";
404
405 echo "<P ALIGN=RIGHT><FONT SIZE=-1><I>";
406 if ($submission->grade) {
407 echo get_string("grade").": $submission->grade";
408 } else {
409 echo get_string("nograde");
410 }
411 echo "</I></FONT></P>";
412
413 echo text_to_html($submission->comment);
414 echo "</TD></TR></TABLE>";
b0f01dff 415 echo "</TD></TR></TABLE>";
d699cd1e 416}
417
418
419function assignment_print_user_files($assignment, $user) {
420// Arguments are objects
421
422 global $CFG;
423
424 $filearea = assignment_file_area_name($assignment, $user);
425
426 if ($basedir = assignment_file_area($assignment, $user)) {
427 if ($files = get_directory_list($basedir)) {
428 foreach ($files as $file) {
429 $icon = mimeinfo("icon", $file);
3f8247c2 430 if ($CFG->slasharguments) {
431 $ffurl = "file.php/$filearea/$file";
432 } else {
433 $ffurl = "file.php?file=/$filearea/$file";
434 }
435
d699cd1e 436 echo "<IMG SRC=\"$CFG->wwwroot/files/pix/$icon\" HEIGHT=16 WIDTH=16 BORDER=0 ALT=\"File\">";
3f8247c2 437 echo "&nbsp;<A TARGET=\"uploadedfile\" HREF=\"$CFG->wwwroot/$ffurl\">$file</A>";
d699cd1e 438 echo "<BR>";
439 }
440 }
441 }
442}
443
444function assignment_delete_user_files($assignment, $user, $exception) {
445// Deletes all the user files in the assignment area for a user
446// EXCEPT for any file named $exception
447
448 if ($basedir = assignment_file_area($assignment, $user)) {
449 if ($files = get_directory_list($basedir)) {
450 foreach ($files as $file) {
451 if ($file != $exception) {
452 unlink("$basedir/$file");
453 notify("Existing file '$file' has been deleted!");
454 }
455 }
456 }
457 }
458}
459
460function assignment_print_upload_form($assignment) {
461// Arguments are objects
462
463 echo "<DIV ALIGN=CENTER>";
464 echo "<FORM ENCTYPE=\"multipart/form-data\" METHOD=\"POST\" ACTION=upload.php>";
ce78926d 465 echo " <INPUT TYPE=hidden NAME=MAX_FILE_SIZE value=\"$assignment->maxbytes\">";
d699cd1e 466 echo " <INPUT TYPE=hidden NAME=id VALUE=\"$assignment->id\">";
467 echo " <INPUT NAME=\"newfile\" TYPE=\"file\" size=\"50\">";
468 echo " <INPUT TYPE=submit NAME=save VALUE=\"".get_string("uploadthisfile")."\">";
469 echo "</FORM>";
470 echo "</DIV>";
471}
04eba58f 472
473?>