- Not Categorized is now the default view for category tab.
[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();
0927b54b 87 echo "<p><font size=1>";
77db7e4c 88 echo get_string("lastmodified").": ";
89 echo userdate($submission->timemodified);
90 echo assignment_print_difference($assignment->timedue - $submission->timemodified);
0927b54b 91 echo "</font></p>";
77db7e4c 92
93 assignment_print_user_files($assignment, $user);
94
0927b54b 95 echo "<br />";
77db7e4c 96
0927b54b 97 if (empty($submission->timemarked)) {
98 print_string("notgradedyet", "assignment");
99 } else {
100 assignment_print_feedback($course, $submission);
101 }
77db7e4c 102
103 print_simple_box_end();
104
105 } else {
106 print_string("notsubmittedyet", "assignment");
107 }
108}
109
110
d699cd1e 111function assignment_cron () {
112// Function to be run periodically according to the moodle cron
113// Finds all assignment notifications that have yet to be mailed out, and mails them
114
a16c2180 115 global $CFG, $USER;
d699cd1e 116
117 $cutofftime = time() - $CFG->maxeditingtime;
118
9fa49e22 119 if ($submissions = assignment_get_unmailed_submissions($cutofftime)) {
d699cd1e 120 $timenow = time();
121
122 foreach ($submissions as $submission) {
123
124 echo "Processing assignment submission $submission->id\n";
125
ebc3bd2b 126 if (! $user = get_record("user", "id", "$submission->userid")) {
127 echo "Could not find user $post->userid\n";
d699cd1e 128 continue;
129 }
130
a5a4cd60 131 $USER->lang = $user->lang;
132
d699cd1e 133 if (! $course = get_record("course", "id", "$submission->course")) {
134 echo "Could not find course $submission->course\n";
135 continue;
136 }
137
138 if (! isstudent($course->id, $user->id) and !isteacher($course->id, $user->id)) {
b9287b2f 139 echo "$user->firstname $user->lastname not an active participant in $course->shortname\n";
140 continue;
d699cd1e 141 }
142
143 if (! $teacher = get_record("user", "id", "$submission->teacher")) {
144 echo "Could not find teacher $submission->teacher\n";
145 continue;
146 }
147
148 if (! $mod = get_coursemodule_from_instance("assignment", $submission->assignment, $course->id)) {
149 echo "Could not find course module for assignment id $submission->assignment\n";
150 continue;
151 }
152
153 $strassignments = get_string("modulenameplural", "assignment");
154 $strassignment = get_string("modulename", "assignment");
155
ae078a98 156 unset($assignmentinfo);
157 $assignmentinfo->teacher = "$teacher->firstname $teacher->lastname";
158 $assignmentinfo->assignment = "$submission->name";
159 $assignmentinfo->url = "$CFG->wwwroot/mod/assignment/view.php?id=$mod->id";
160
d699cd1e 161 $postsubject = "$course->shortname: $strassignments: $submission->name";
162 $posttext = "$course->shortname -> $strassignments -> $submission->name\n";
163 $posttext .= "---------------------------------------------------------------------\n";
ae078a98 164 $posttext .= get_string("assignmentmail", "assignment", $assignmentinfo);
d699cd1e 165 $posttext .= "---------------------------------------------------------------------\n";
ae078a98 166
d699cd1e 167 if ($user->mailformat == 1) { // HTML
ae078a98 168 $posthtml = "<p><font face=\"sans-serif\">".
169 "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> ->".
170 "<a href=\"$CFG->wwwroot/mod/assignment/index.php?id=$course->id\">$strassignments</a> ->".
171 "<a href=\"$CFG->wwwroot/mod/assignment/view.php?id=$mod->id\">$submission->name</a></font></p>";
172 $posthtml .= "<hr><font face=\"sans-serif\">";
173 $posthtml .= "<p>".get_string("assignmentmailhtml", "assignment", $assignmentinfo)."</p>";
174 $posthtml .= "</font><hr>";
d699cd1e 175 } else {
ae078a98 176 $posthtml = "";
d699cd1e 177 }
178
179 if (! email_to_user($user, $teacher, $postsubject, $posttext, $posthtml)) {
180 echo "Error: assignment cron: Could not send out mail for id $submission->id to user $user->id ($user->email)\n";
181 }
182 if (! set_field("assignment_submissions", "mailed", "1", "id", "$submission->id")) {
183 echo "Could not update the mailed field for id $submission->id\n";
184 }
185 }
186 }
187
188 return true;
189}
190
1b5910c4 191function assignment_print_recent_activity($course, $isteacher, $timestart) {
3d891989 192 global $CFG;
3446205d 193
194 $content = false;
195 $assignments = NULL;
196
1b5910c4 197 if (!$logs = get_records_select("log", "time > '$timestart' AND ".
198 "course = '$course->id' AND ".
199 "module = 'assignment' AND ".
200 "action = 'upload' ", "time ASC")) {
201 return false;
202 }
203
204 foreach ($logs as $log) {
205 //Create a temp valid module structure (course,id)
206 $tempmod->course = $log->course;
207 $tempmod->id = $log->info;
208 //Obtain the visible property from the instance
209 $modvisible = instance_is_visible($log->module,$tempmod);
210
211 //Only if the mod is visible
212 if ($modvisible) {
213 $assignments[$log->info] = assignment_log_info($log);
214 $assignments[$log->info]->time = $log->time;
215 $assignments[$log->info]->url = $log->url;
3446205d 216 }
217 }
218
219 if ($assignments) {
dcde9f02 220 $strftimerecent = get_string("strftimerecent");
3446205d 221 $content = true;
222 print_headline(get_string("newsubmissions", "assignment").":");
223 foreach ($assignments as $assignment) {
dcde9f02 224 $date = userdate($assignment->time, $strftimerecent);
1b5910c4 225 echo "<p><font size=1>$date - $assignment->firstname $assignment->lastname<br>";
226 echo "\"<a href=\"$CFG->wwwroot/mod/assignment/$assignment->url\">";
3446205d 227 echo "$assignment->name";
1b5910c4 228 echo "</a>\"</font></p>";
3446205d 229 }
230 }
231
232 return $content;
233}
d699cd1e 234
d0ac6bc2 235function assignment_grades($assignmentid) {
858deff0 236/// Must return an array of grades, indexed by user, and a max grade.
d0ac6bc2 237
91719320 238
239 if (!$assignment = get_record("assignment", "id", $assignmentid)) {
240 return NULL;
241 }
242
243 $grades = get_records_menu("assignment_submissions", "assignment",
244 $assignment->id, "", "userid,grade");
245
246 if ($assignment->grade >= 0) {
247 $return->grades = $grades;
734bec5d 248 $return->maxgrade = $assignment->grade;
91719320 249
250 } else {
251 $scaleid = - ($assignment->grade);
252 if ($scale = get_record("scale", "id", $scaleid)) {
253 $scalegrades = make_menu_from_list($scale->scale);
254 foreach ($grades as $key => $grade) {
255 $grades[$key] = $scalegrades[$grade];
256 }
257 }
258 $return->grades = $grades;
259 $return->maxgrade = "";
260 }
261
858deff0 262 return $return;
d0ac6bc2 263}
264
9fa49e22 265/// SQL STATEMENTS //////////////////////////////////////////////////////////////////
266
267function assignment_log_info($log) {
268 global $CFG;
269 return get_record_sql("SELECT a.name, u.firstname, u.lastname
270 FROM {$CFG->prefix}assignment a,
271 {$CFG->prefix}user u
272 WHERE a.id = '$log->info'
ebc3bd2b 273 AND u.id = '$log->userid'");
9fa49e22 274}
275
df48be74 276function assignment_get_all_submissions($assignment, $sort="", $dir="DESC") {
9fa49e22 277/// Return all assignment submissions by ENROLLED students
278 global $CFG;
000cc405 279
280 if ($sort == "lastname" or $sort == "firstname") {
281 $sort = "u.$sort $dir";
282 } else if (empty($sort)) {
283 $sort = "a.timemodified DESC";
284 } else {
285 $sort = "a.$sort $dir";
286 }
9fa49e22 287 return get_records_sql("SELECT a.*
288 FROM {$CFG->prefix}assignment_submissions a,
000cc405 289 {$CFG->prefix}user_students s,
290 {$CFG->prefix}user u
ebc3bd2b 291 WHERE a.userid = s.userid
b2d0ca3b 292 AND u.id = a.userid
9fa49e22 293 AND s.course = '$assignment->course'
294 AND a.assignment = '$assignment->id'
000cc405 295 ORDER BY $sort");
9fa49e22 296}
297
298function assignment_get_users_done($assignment) {
299/// Return list of users who have done an assignment
300 global $CFG;
301 return get_records_sql("SELECT u.*
302 FROM {$CFG->prefix}user u,
303 {$CFG->prefix}user_students s,
304 {$CFG->prefix}assignment_submissions a
305 WHERE s.course = '$assignment->course'
ebc3bd2b 306 AND s.userid = u.id
307 AND u.id = a.userid
9fa49e22 308 AND a.assignment = '$assignment->id'
309 ORDER BY a.timemodified DESC");
310}
311
312function assignment_get_unmailed_submissions($cutofftime) {
a2631c99 313/// Return list of marked submissions that have not been mailed out for currently enrolled students
9fa49e22 314 global $CFG;
315 return get_records_sql("SELECT s.*, a.course, a.name
316 FROM {$CFG->prefix}assignment_submissions s,
a2631c99 317 {$CFG->prefix}assignment a,
318 {$CFG->prefix}user_students us
9fa49e22 319 WHERE s.mailed = 0
320 AND s.timemarked < $cutofftime
321 AND s.timemarked > 0
a2631c99 322 AND s.assignment = a.id
323 AND s.userid = us.userid
324 AND a.course = us.course");
9fa49e22 325}
326
327
d699cd1e 328//////////////////////////////////////////////////////////////////////////////////////
329
330function assignment_file_area_name($assignment, $user) {
331// Creates a directory file name, suitable for make_upload_directory()
ca4f8eb8 332 global $CFG;
333
334 return "$assignment->course/$CFG->moddata/assignment/$assignment->id/$user->id";
d699cd1e 335}
336
337function assignment_file_area($assignment, $user) {
338 return make_upload_directory( assignment_file_area_name($assignment, $user) );
339}
340
341function assignment_get_submission($assignment, $user) {
21a15d9f 342 $submission = get_record("assignment_submissions", "assignment", $assignment->id, "userid", $user->id);
343 if (!empty($submission->timemodified)) {
344 return $submission;
8e340cb0 345 }
346 return NULL;
d699cd1e 347}
348
349function assignment_print_difference($time) {
350 if ($time < 0) {
351 $timetext = get_string("late", "assignment", format_time($time));
352 return " (<FONT COLOR=RED>$timetext</FONT>)";
353 } else {
354 $timetext = get_string("early", "assignment", format_time($time));
355 return " ($timetext)";
356 }
357}
358
359function assignment_print_submission($assignment, $user, $submission, $teachers, $grades) {
ce78926d 360 global $THEME, $USER;
d699cd1e 361
b7b42874 362 echo "\n<TABLE BORDER=1 CELLSPACING=0 valign=top cellpadding=10 align=center>";
d699cd1e 363
364 echo "\n<TR>";
b7b42874 365 if ($assignment->type == OFFLINE) {
366 echo "\n<TD BGCOLOR=\"$THEME->body\" WIDTH=35 VALIGN=TOP>";
367 } else {
368 echo "\n<TD ROWSPAN=2 BGCOLOR=\"$THEME->body\" WIDTH=35 VALIGN=TOP>";
369 }
d699cd1e 370 print_user_picture($user->id, $assignment->course, $user->picture);
371 echo "</TD>";
b7b42874 372 echo "<TD NOWRAP BGCOLOR=\"$THEME->cellheading\">$user->firstname $user->lastname";
373 if ($submission->timemodified) {
d699cd1e 374 echo "&nbsp;&nbsp;<FONT SIZE=1>".get_string("lastmodified").": ";
375 echo userdate($submission->timemodified);
376 echo assignment_print_difference($assignment->timedue - $submission->timemodified);
377 echo "</FONT>";
378 }
379 echo "</TR>";
380
b7b42874 381 if ($assignment->type != OFFLINE) {
382 echo "\n<TR><TD BGCOLOR=\"$THEME->cellcontent\">";
ff446576 383 if ($submission->timemodified) {
b7b42874 384 assignment_print_user_files($assignment, $user);
385 } else {
386 print_string("notsubmittedyet", "assignment");
d699cd1e 387 }
d699cd1e 388 echo "</TD></TR>";
389 }
b7b42874 390
391 echo "\n<TR>";
392 echo "<TD WIDTH=35 VALIGN=TOP>";
393 if (!$submission->teacher) {
394 $submission->teacher = $USER->id;
395 }
396 print_user_picture($submission->teacher, $assignment->course, $teachers[$submission->teacher]->picture);
397 if ($submission->timemodified > $submission->timemarked) {
398 echo "<TD BGCOLOR=\"$THEME->cellheading2\">";
399 } else {
400 echo "<TD BGCOLOR=\"$THEME->cellheading\">";
401 }
f830b324 402 echo get_string("feedback", "assignment").":";
94d0cea5 403 choose_from_menu($grades, "g$submission->id", $submission->grade, get_string("nograde"));
b7b42874 404 if ($submission->timemarked) {
405 echo "&nbsp;&nbsp;<FONT SIZE=1>".userdate($submission->timemarked)."</FONT>";
406 }
407 echo "<BR><TEXTAREA NAME=\"c$submission->id\" ROWS=6 COLS=60 WRAP=virtual>";
408 p($submission->comment);
409 echo "</TEXTAREA><BR>";
410 echo "</TD></TR>";
411
d699cd1e 412 echo "</TABLE><BR CLEAR=ALL>\n";
413}
414
415function assignment_print_feedback($course, $submission) {
416 global $CFG, $THEME, $RATING;
417
418 if (! $teacher = get_record("user", "id", $submission->teacher)) {
419 error("Weird assignment error");
420 }
421
b0f01dff 422 echo "\n<TABLE BORDER=0 CELLPADDING=1 CELLSPACING=1 ALIGN=CENTER><TR><TD BGCOLOR=#888888>";
423 echo "\n<TABLE BORDER=0 CELLPADDING=3 CELLSPACING=0 VALIGN=TOP>";
d699cd1e 424
425 echo "\n<TR>";
426 echo "\n<TD ROWSPAN=3 BGCOLOR=\"$THEME->body\" WIDTH=35 VALIGN=TOP>";
427 print_user_picture($teacher->id, $course->id, $teacher->picture);
428 echo "</TD>";
429 echo "<TD NOWRAP WIDTH=100% BGCOLOR=\"$THEME->cellheading\">$teacher->firstname $teacher->lastname";
430 echo "&nbsp;&nbsp;<FONT SIZE=2><I>".userdate($submission->timemarked)."</I>";
431 echo "</TR>";
432
433 echo "\n<TR><TD WIDTH=100% BGCOLOR=\"$THEME->cellcontent\">";
434
435 echo "<P ALIGN=RIGHT><FONT SIZE=-1><I>";
436 if ($submission->grade) {
437 echo get_string("grade").": $submission->grade";
438 } else {
439 echo get_string("nograde");
440 }
441 echo "</I></FONT></P>";
442
443 echo text_to_html($submission->comment);
444 echo "</TD></TR></TABLE>";
b0f01dff 445 echo "</TD></TR></TABLE>";
d699cd1e 446}
447
448
449function assignment_print_user_files($assignment, $user) {
450// Arguments are objects
451
452 global $CFG;
453
454 $filearea = assignment_file_area_name($assignment, $user);
455
456 if ($basedir = assignment_file_area($assignment, $user)) {
457 if ($files = get_directory_list($basedir)) {
458 foreach ($files as $file) {
459 $icon = mimeinfo("icon", $file);
3f8247c2 460 if ($CFG->slasharguments) {
461 $ffurl = "file.php/$filearea/$file";
462 } else {
463 $ffurl = "file.php?file=/$filearea/$file";
464 }
465
d699cd1e 466 echo "<IMG SRC=\"$CFG->wwwroot/files/pix/$icon\" HEIGHT=16 WIDTH=16 BORDER=0 ALT=\"File\">";
3f8247c2 467 echo "&nbsp;<A TARGET=\"uploadedfile\" HREF=\"$CFG->wwwroot/$ffurl\">$file</A>";
d699cd1e 468 echo "<BR>";
469 }
470 }
471 }
472}
473
474function assignment_delete_user_files($assignment, $user, $exception) {
475// Deletes all the user files in the assignment area for a user
476// EXCEPT for any file named $exception
477
478 if ($basedir = assignment_file_area($assignment, $user)) {
479 if ($files = get_directory_list($basedir)) {
480 foreach ($files as $file) {
481 if ($file != $exception) {
482 unlink("$basedir/$file");
483 notify("Existing file '$file' has been deleted!");
484 }
485 }
486 }
487 }
488}
489
490function assignment_print_upload_form($assignment) {
491// Arguments are objects
492
493 echo "<DIV ALIGN=CENTER>";
494 echo "<FORM ENCTYPE=\"multipart/form-data\" METHOD=\"POST\" ACTION=upload.php>";
ce78926d 495 echo " <INPUT TYPE=hidden NAME=MAX_FILE_SIZE value=\"$assignment->maxbytes\">";
d699cd1e 496 echo " <INPUT TYPE=hidden NAME=id VALUE=\"$assignment->id\">";
497 echo " <INPUT NAME=\"newfile\" TYPE=\"file\" size=\"50\">";
498 echo " <INPUT TYPE=submit NAME=save VALUE=\"".get_string("uploadthisfile")."\">";
499 echo "</FORM>";
500 echo "</DIV>";
501}
04eba58f 502
2bae0d44 503function assignment_get_participants($assignmentid) {
504//Returns the users with data in one assignment
505//(users with records in assignment_submissions, students and teachers)
506
507 global $CFG;
508
509 //Get students
510 $students = get_records_sql("SELECT DISTINCT u.*
511 FROM {$CFG->prefix}user u,
512 {$CFG->prefix}assignment_submissions a
513 WHERE a.assignment = '$assignmentid' and
514 u.id = a.userid");
515 //Get teachers
516 $teachers = get_records_sql("SELECT DISTINCT u.*
517 FROM {$CFG->prefix}user u,
518 {$CFG->prefix}assignment_submissions a
519 WHERE a.assignment = '$assignmentid' and
520 u.id = a.teacher");
521
522 //Add teachers to students
b32bbab6 523 if ($teachers) {
524 foreach ($teachers as $teacher) {
525 $students[$teacher->id] = $teacher;
526 }
2bae0d44 527 }
528 //Return students array (it contains an array of unique users)
529 return ($students);
530}
531
04eba58f 532?>