64acaf71e9e5e10bb8aec1fd38a2832a84807c98
[moodle.git] / mod / forum / lib.php
1 <?PHP  // $Id$
3 include_once("$CFG->dirroot/files/mimetypes.php");
5 /// CONSTANTS ///////////////////////////////////////////////////////////
7 $FORUM_DEFAULT_DISPLAY_MODE = 3; 
9 $FORUM_LAYOUT_MODES = array ( "1"  => get_string("modeflatoldestfirst", "forum"),
10                               "-1" => get_string("modeflatnewestfirst", "forum"),
11                               "2"  => get_string("modethreaded", "forum"),
12                               "3"  => get_string("modenested", "forum") );
14 // These are course content forums that can be added to the course manually
15 $FORUM_TYPES   = array ("general"    => get_string("generalforum", "forum"),
16                         "eachuser"   => get_string("eachuserforum", "forum"),
17                         "single"     => get_string("singleforum", "forum") );
19 $FORUM_POST_RATINGS = array ("3" => get_string("postrating3", "forum"),
20                              "2" => get_string("postrating2", "forum"),
21                              "1" => get_string("postrating1", "forum") );
23 $FORUM_OPEN_MODES   = array ("2" => get_string("openmode2", "forum"),
24                              "1" => get_string("openmode1", "forum"),
25                              "0" => get_string("openmode0", "forum") );
28 define("FORUM_SHORT_POST", 300);  // Less non-HTML characters than this is short
30 define("FORUM_LONG_POST", 600);   // More non-HTML characters than this is long
32 define("FORUM_MANY_DISCUSSIONS", 10);
35 /// STANDARD FUNCTIONS ///////////////////////////////////////////////////////////
37 function forum_add_instance($forum) {
38 // Given an object containing all the necessary data, 
39 // (defined by the form in mod.html) this function 
40 // will create a new instance and return the id number 
41 // of the new instance.
43     global $CFG;
45     $forum->timemodified = time();
47     if (! $forum->id = insert_record("forum", $forum)) {
48         return false;
49     }
51     if ($forum->type == "single") {  // Create related discussion.
53         $discussion->course   = $forum->course;
54         $discussion->forum    = $forum->id;
55         $discussion->name     = $forum->name;
56         $discussion->intro    = $forum->intro;
57         $discussion->assessed = $forum->assessed;
59         if (! forum_add_discussion($discussion)) {
60             error("Could not add the discussion for this forum");
61         }
62     }
63     add_to_log($forum->course, "forum", "add", "index.php?f=$forum->id", "$forum->id");
65     return $forum->id;
66 }
69 function forum_update_instance($forum) {
70 // Given an object containing all the necessary data, 
71 // (defined by the form in mod.html) this function 
72 // will update an existing instance with new data.
74     $forum->timemodified = time();
75     $forum->id = $forum->instance;
77     if ($forum->type == "single") {  // Update related discussion and post.
78         if (! $discussion = get_record("forum_discussions", "forum", $forum->id)) {
79             if ($discussions = get_records("forum_discussions", "forum", $forum->id, "timemodified ASC")) {
80                 notify("Warning! There is more than one discussion in this forum - using the most recent");
81                 $discussion = array_pop($discussions);
82             } else {
83                 error("Could not find the discussion in this forum");
84             }
85         }
86         if (! $post = get_record("forum_posts", "id", $discussion->firstpost)) {
87             error("Could not find the first post in this forum discussion");
88         }
90         $post->subject  = $forum->name;
91         $post->message  = $forum->intro;
92         $post->modified = $forum->timemodified;
94         if (! update_record("forum_posts", $post)) {
95             error("Could not update the first post");
96         }
98         $discussion->name = $forum->name;
100         if (! update_record("forum_discussions", $discussion)) {
101             error("Could not update the discussion");
102         }
103     }
105     if (update_record("forum", $forum)) {
106         add_to_log($forum->course, "forum", "update", "index.php?f=$forum->id", "$forum->id");
107         return true;
108     } else {
109         return false;
110     }
114 function forum_delete_instance($id) {
115 // Given an ID of an instance of this module, 
116 // this function will permanently delete the instance 
117 // and any data that depends on it.  
119     if (! $forum = get_record("forum", "id", "$id")) {
120         return false;
121     }
123     $result = true;
125     if ($discussions = get_records("forum_discussions", "forum", $forum->id)) {
126         foreach ($discussions as $discussion) {
127             if (! forum_delete_discussion($discussion)) {
128                 $result = false;
129             }
130         }
131     }
133     if (! delete_records("forum_subscriptions", "forum", "$forum->id")) {
134         $result = false;
135     }
137     if (! delete_records("forum", "id", "$forum->id")) {
138         $result = false;
139     }
141     return $result;
145 function forum_cron () {
146 // Function to be run periodically according to the moodle cron
147 // Finds all posts that have yet to be mailed out, and mails them
149     global $CFG, $USER;
151     $cutofftime = time() - $CFG->maxeditingtime;
153     if ($posts = get_records_sql("SELECT p.*, d.course FROM forum_posts p, forum_discussions d
154                                   WHERE p.mailed = '0' AND p.created < '$cutofftime' AND p.discussion = d.id")) {
156         $timenow = time();
158         foreach ($posts as $post) {
160             print_string("processingpost", "forum", $post->id);
161             echo " ... ";
163             if (! $userfrom = get_record("user", "id", "$post->user")) {
164                 echo "Could not find user $post->user\n";
165                 continue;
166             }
168             if (! $discussion = get_record("forum_discussions", "id", "$post->discussion")) {
169                 echo "Could not find discussion $post->discussion\n";
170                 continue;
171             }
173             if (! $forum = get_record("forum", "id", "$discussion->forum")) {
174                 echo "Could not find forum $discussion->forum\n";
175                 continue;
176             }
178             if (! $course = get_record("course", "id", "$forum->course")) {
179                 echo "Could not find course $forum->course\n";
180                 continue;
181             }
183             if ($users = forum_subscribed_users($course, $forum)) {
184                 $canunsubscribe = ! forum_is_forcesubscribed($forum->id);
186                 $mailcount=0;
187                 foreach ($users as $userto) {
188                     $USER->lang = $userto->lang;  // Affects the language of get_string
189                     $canreply = forum_user_can_post($forum, $userto);
192                     $by->name = "$userfrom->firstname $userfrom->lastname";
193                     $by->date = userdate($post->created, "", $userto->timezone);
194                     $strbynameondate = get_string("bynameondate", "forum", $by);
196                     $strforums = get_string("forums", "forum");
198                     $postsubject = "$course->shortname: $post->subject";
199                     $posttext  = "$course->shortname -> $strforums -> $forum->name";
201                     if ($discussion->name == $forum->name) {
202                         $posttext  .= "\n";
203                     } else {
204                         $posttext  .= " -> $discussion->name\n";
205                     }
206                     $posttext .= "---------------------------------------------------------------------\n";
207                     $posttext .= "$post->subject\n";
208                     $posttext .= $strbynameondate."\n";
209                     $posttext .= "---------------------------------------------------------------------\n";
210                     $posttext .= strip_tags($post->message);
211                     $posttext .= "\n\n";
212                     if ($post->attachment) {
213                         $post->course = $course->id;
214                         $post->forum = $forum->id;
215                         $posttext .= forum_print_attachments($post, "text");
216                     }
217                     if ($canreply) {
218                         $posttext .= "---------------------------------------------------------------------\n";
219                         $posttext .= get_string("postmailinfo", "forum", $course->shortname)."\n";
220                         $posttext .= "$CFG->wwwroot/mod/forum/post.php?reply=$post->id\n";
221                     }
222                     if ($canunsubscribe) {
223                         $posttext .= "\n---------------------------------------------------------------------\n";
224                         $posttext .= get_string("unsubscribe", "forum");
225                         $posttext .= ": $CFG->wwwroot/mod/forum/subscribe.php?id=$forum->id\n";
226                     }
227   
228                     if ($userto->mailformat == 1) {  // HTML
229                         $posthtml = "<P><FONT FACE=sans-serif>".
230                         "<A TARGET=\"_blank\" HREF=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</A> -> ".
231                         "<A TARGET=\"_blank\" HREF=\"$CFG->wwwroot/mod/forum/index.php?id=$course->id\">$strforums</A> -> ".
232                         "<A TARGET=\"_blank\" HREF=\"$CFG->wwwroot/mod/forum/view.php?f=$forum->id\">$forum->name</A>";
233                         if ($discussion->name == $forum->name) {
234                             $posthtml .= "</FONT></P>";
235                         } else {
236                             $posthtml .= " -> <A TARGET=\"_blank\" HREF=\"$CFG->wwwroot/mod/forum/discuss.php?d=$discussion->id\">$discussion->name</A></FONT></P>";
237                         }
238                         $posthtml .= forum_make_mail_post($post, $userfrom, $userto, $course, false, $canreply, false, false);
240                         if ($canunsubscribe) {
241                             $posthtml .= "\n<BR><HR SIZE=1 NOSHADE><P ALIGN=RIGHT><FONT SIZE=1><A HREF=\"$CFG->wwwroot/mod/forum/subscribe.php?id=$forum->id\">".get_string("unsubscribe", "forum")."</A></FONT></P>";
242                         }
244                     } else {
245                       $posthtml = "";
246                     }
247    
248                     if (! email_to_user($userto, $userfrom, $postsubject, $posttext, $posthtml)) {
249                         echo "Error: mod/forum/cron.php: Could not send out mail for id $post->id to user $userto->id ($userto->email)\n";
250                     } else {
251                         $mailcount++;
252                     }
253                 }
254                 echo "mailed to $mailcount users ...";
255             }
257             if (! set_field("forum_posts", "mailed", "1", "id", "$post->id")) {
258                 echo "Could not update the mailed field for id $post->id\n";
259             }
260             echo "\n";
261         }
262     }
264     return true;
267 function forum_user_outline($course, $user, $mod, $forum) {
269     if ($posts = get_records_sql("SELECT p.*, u.id as userid, u.firstname, u.lastname, u.email, u.picture
270                                   FROM forum f, forum_discussions d, forum_posts p, user u 
271                                   WHERE f.id = '$forum->id' AND d.forum = f.id AND p.discussion = d.id
272                                   AND p.user = '$user->id' AND p.user = u.id
273                                   ORDER BY p.modified ASC")) {
275         $result->info = get_string("numposts", "forum", count($posts));
277         $lastpost = array_pop($posts);
278         $result->time = $lastpost->modified;
279         return $result;
280     }
281     return NULL;
285 function forum_user_complete($course, $user, $mod, $forum) {
286     global $CFG;
288     if ($posts = get_records_sql("SELECT p.*, u.id as userid, u.firstname, u.lastname, u.email, u.picture
289                                   FROM forum f, forum_discussions d, forum_posts p, user u 
290                                   WHERE f.id = '$forum->id' AND d.forum = f.id AND p.discussion = d.id
291                                   AND p.user = '$user->id' AND p.user = u.id
292                                   ORDER BY p.modified ASC")) {
294         foreach ($posts as $post) {
295             if ($post->parent) {
296                 $footer = "<A HREF=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion&parent=$post->parent\">".
297                            get_string("parentofthispost", "forum")."</A>";
298             } else {
299                 $footer = "";
300             }
302             forum_print_post($post, $course->id, $ownpost=false, $reply=false, $link=false, $rate=false, $footer);
303         }
305     } else {
306         echo "<P>".get_string("noposts", "forum")."</P>";
307     }
311 function forum_print_recent_activity(&$logs, $isteacher=false) {
312     global $CFG, $COURSE_TEACHER_COLOR;
314     $heading = false;
315     $content = false;
317     foreach ($logs as $log) {
318         if ($log->module == "forum") {
319             $post = NULL;
321             if ($log->action == "add post") {
322                 $post = get_record_sql("SELECT p.*, d.forum, u.firstname, u.lastname, 
323                                                u.email, u.picture, u.id as userid
324                                         FROM forum_discussions d, forum_posts p, user u 
325                                         WHERE p.id = '$log->info' AND d.id = p.discussion 
326                                         AND p.user = u.id and u.deleted <> '1'");
328             } else if ($log->action == "add discussion") {
329                 $post = get_record_sql("SELECT p.*, d.forum, u.firstname, u.lastname, 
330                                                u.email, u.picture, u.id as userid
331                                         FROM forum_discussions d, forum_posts p, user u 
332                                         WHERE d.id = '$log->info' AND d.firstpost = p.id 
333                                         AND p.user = u.id and u.deleted <> '1'");
334             }
336             if ($post) {
337                 $teacherpost = "";
338                 if ($forum = get_record("forum", "id", $post->forum) ) {
339                     if ($forum->type == "teacher") {
340                         if ($isteacher) {
341                             $teacherpost = "COLOR=$COURSE_TEACHER_COLOR";
342                         } else {
343                             continue;
344                         }
345                     }
346                 }
347                 if (! $heading) {
348                     print_headline(get_string("newforumposts", "forum").":");
349                     $heading = true;
350                     $content = true;
351                 }
352                 $date = userdate($post->modified, "%e %b, %H:%M");
353                 echo "<P><FONT SIZE=1 $teacherpost>$date - $post->firstname $post->lastname<BR>";
354                 echo "\"<A HREF=\"$CFG->wwwroot/mod/forum/$log->url\">";
355                 if ($log->action == "add") {
356                     echo "<B>$post->subject</B>";
357                 } else {
358                     echo "$post->subject";
359                 }
360                 echo "</A>\"</FONT></P>";
361             }
362         }
363     }
364     return $content;
368 function forum_grades($forumid) {
369 /// Must return an array of grades, indexed by user, and a max grade.
370     global $FORUM_POST_RATINGS;
372     if (!$forum = get_record("forum", "id", $forumid)) {
373         return false;
374     }
375     if (!$forum->assessed) {
376         return false;
377     }
378     if ($ratings = get_records_sql("SELECT r.id, p.user, r.rating
379                                       FROM forum_discussions d, forum_posts p, forum_ratings r
380                                      WHERE d.forum = '$forumid' 
381                                        AND p.discussion = d.id
382                                        AND r.post = p.id")) {
383         foreach ($ratings as $rating) {
384             $u = $rating->user;
385             $r = $rating->rating;
386             if (!isset($sumrating[$u])) {
387                 $sumrating[$u][1] = 0;
388                 $sumrating[$u][2] = 0;
389                 $sumrating[$u][3] = 0;
390             }
391             $sumrating[$u][$r]++;
392         }
393         foreach ($sumrating as $user => $rating) {
394             $return->grades[$user] = $rating[1]."s/".$rating[2]."/".$rating[3]."c";
395         }
396     } else {
397         $return->grades = array();
398     }
400     $return->maxgrade = "";
401     return $return;
405 /// OTHER FUNCTIONS ///////////////////////////////////////////////////////////
408 function forum_get_course_forum($courseid, $type) {
409 // How to set up special 1-per-course forums
410     if ($forum = get_record_sql("SELECT * from forum WHERE course = '$courseid' AND type = '$type'")) {
411         return $forum;
413     } else {
414         // Doesn't exist, so create one now.
415         $forum->course = $courseid;
416         $forum->type = "$type";
417         switch ($forum->type) {
418             case "news":
419                 $forum->name  = get_string("namenews", "forum");
420                 $forum->intro = get_string("intronews", "forum");
421                 $forum->open = 1;   // 0 - no, 1 - posts only, 2 - discuss and post
422                 $forum->assessed = 0;
423                 $forum->forcesubscribe = 1;
424                 break;
425             case "social":
426                 $forum->name  = get_string("namesocial", "forum");
427                 $forum->intro = get_string("introsocial", "forum");
428                 $forum->open = 2;   // 0 - no, 1 - posts only, 2 - discuss and post
429                 $forum->assessed = 0;
430                 $forum->forcesubscribe = 0;
431                 break;
432             case "teacher":
433                 $forum->name  = get_string("nameteacher", "forum");
434                 $forum->intro = get_string("introteacher", "forum");
435                 $forum->open = 0;   // 0 - no, 1 - posts only, 2 - discuss and post
436                 $forum->assessed = 0;
437                 $forum->forcesubscribe = 0;
438                 break;
439             default:
440                 notify("That forum type doesn't exist!");
441                 return false;
442                 break;
444         }
445         $forum->timemodified = time();
446         $forum->id = insert_record("forum", $forum);
448         if ($forum->type != "teacher") {
449             if (! $module = get_record("modules", "name", "forum")) {
450                 notify("Could not find forum module!!");
451                 return false;
452             }
453             $mod->course = $courseid;
454             $mod->module = $module->id;
455             $mod->instance = $forum->id;
456             $mod->section = 0;
457             if (! $mod->coursemodule = add_course_module($mod) ) {   // assumes course/lib.php is loaded
458                 notify("Could not add a new course module to the course '$course->fullname'");
459                 return false;
460             }
461             if (! $sectionid = add_mod_to_section($mod) ) {   // assumes course/lib.php is loaded
462                 notify("Could not add the new course module to that section");
463                 return false;
464             }
465             if (! set_field("course_modules", "section", $sectionid, "id", $mod->coursemodule)) {
466                 notify("Could not update the course module with the correct section");
467                 return false;
468             }
469         }
470             
471         return get_record("forum", "id", "$forum->id");
472     }
476 function forum_make_mail_post(&$post, $user, $touser, $course, 
477                               $ownpost=false, $reply=false, $link=false, $rate=false, $footer="") {
478 // Given the data about a posting, builds up the HTML to display it and 
479 // returns the HTML in a string.  This is designed for sending via HTML email.
481     global $THEME, $CFG;
483     $output = "";
485     if ($post->parent) {
486         $output .= "<TABLE BORDER=0 CELLPADDING=1 CELLSPACING=1><TR><TD BGCOLOR=#888888>";
487         $output .= "<TABLE BORDER=0 CELLPADDING=3 CELLSPACING=0>";
488     } else {
489         $output .= "<TABLE BORDER=0 CELLPADDING=1 CELLSPACING=1 WIDTH=100%><TR><TD BGCOLOR=#888888>";
490         $output .= "<TABLE BORDER=0 CELLPADDING=3 CELLSPACING=0 WIDTH=100%>";
491     }
493     $output .= "<TR><TD BGCOLOR=\"$THEME->body\" WIDTH=35 VALIGN=TOP>";
494     $output .= print_user_picture($user->id, $course->id, $user->picture, false, true);
495     $output .= "</TD>";
497     if ($post->parent) {
498         $output .= "<TD NOWRAP BGCOLOR=\"$THEME->cellheading\">";
499     } else {
500         $output .= "<TD NOWRAP BGCOLOR=\"$THEME->cellheading2\">";
501     }
502     $output .= "<P>";
503     $output .= "<FONT SIZE=3><B>$post->subject</B></FONT><BR>";
504     $output .= "<FONT SIZE=2>";
505     $by->name = "<A HREF=\"$CFG->wwwroot/user/view.php?id=$user->id&course=$course->id\">$user->firstname $user->lastname</A>";
506     $by->date = userdate($post->created, "", $touser->timezone);
507     $output .= get_string("bynameondate", "forum", $by);
508     $output .= "</FONT></P></TD></TR>";
509     $output .= "<TR><TD BGCOLOR=\"$THEME->body\" WIDTH=10>";
510     $output .= "&nbsp;";
511     $output .= "</TD><TD BGCOLOR=\"$THEME->cellcontent\">\n";
513     if ($post->attachment) {
514         $post->course = $course->id;
515         $post->forum = get_field("forum_discussions", "forum", "id", $post->discussion);
516         $output .= "<DIV ALIGN=right>";
517         $output .= forum_print_attachments($post, "html");
518         $output .= "</DIV>";
519     }
521     $output .= format_text($post->message, $post->format);
523     $output .= "<P ALIGN=right><FONT SIZE=-1>";
525     $age = time() - $post->created;
526     if ($ownpost) {
527         $output .= "<A HREF=\"$CFG->wwwroot/mod/forum/post.php?delete=$post->id\">".get_string("delete", "forum")."</A>";
528         if ($reply) {
529             $output .= " | <A TARGET=\"_blank\" HREF=\"$CFG->wwwroot/mod/forum/post.php?reply=$post->id\">".get_string("reply", "forum")."</A>";
530         }
531         $output .= "&nbsp;&nbsp;";
532     } else {
533         if ($reply) {
534             $output .= "<A TARGET=\"_blank\" HREF=\"$CFG->wwwroot/mod/forum/post.php?reply=$post->id\">".get_string("reply", "forum")."</A>&nbsp;&nbsp;";
535         }
536     }
538     $output .= "</P>";
539     $output .= "<DIV ALIGN=right><P ALIGN=right>";
540     
541     if ($link) {
542         if ($post->replies == 1) {
543             $replystring = get_string("repliesone", "forum", $post->replies);
544         } else {
545             $replystring = get_string("repliesmany", "forum", $post->replies);
546         }
547         $output .= "<A HREF=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\"><B>".get_string("discussthistopic", "forum")."</B></A> ($replystring)&nbsp;&nbsp;";
548     }
549     $output .= "</P></DIV>";
550     if ($footer) {
551         $output .= "<P>$footer</P>";
552     }
553     $output .= "</TD></TR></TABLE>\n";
554     $output .= "</TD></TR></TABLE>\n\n";
556     return $output;
560 function forum_print_post(&$post, $courseid, $ownpost=false, $reply=false, $link=false, $rate=false, $footer="") {
561     global $THEME, $USER, $CFG;
563     if ($post->parent) {
564         echo "<TABLE BORDER=0 CELLPADDING=1 CELLSPACING=1><TR><TD BGCOLOR=#888888>";
565         echo "<TABLE BORDER=0 CELLPADDING=3 CELLSPACING=0>";
566     } else {
567         echo "<TABLE BORDER=0 CELLPADDING=1 CELLSPACING=1 WIDTH=100%><TR><TD BGCOLOR=#888888>";
568         echo "<TABLE BORDER=0 CELLPADDING=3 CELLSPACING=0 WIDTH=100%>";
569     }
571     echo "<TR><TD BGCOLOR=\"$THEME->body\" WIDTH=35 VALIGN=TOP>";
572     print_user_picture($post->userid, $courseid, $post->picture);
573     echo "</TD>";
575     if ($post->parent) {
576         echo "<TD NOWRAP BGCOLOR=\"$THEME->cellheading\" WIDTH=\"100%\">";
577     } else {
578         echo "<TD NOWRAP BGCOLOR=\"$THEME->cellheading2\" WIDTH=\"100%*\">";
579     }
580     echo "<P>";
581     echo "<FONT SIZE=3><B>$post->subject</B></FONT><BR>";
582     echo "<FONT SIZE=2>";
583     $by->name = "<A HREF=\"$CFG->wwwroot/user/view.php?id=$post->userid&course=$courseid\">$post->firstname $post->lastname</A>";
584     $by->date = userdate($post->created);
585     print_string("bynameondate", "forum", $by);
586     echo "</FONT></P></TD></TR>";
587     echo "<TR><TD BGCOLOR=\"$THEME->body\" WIDTH=10>";
588     echo "&nbsp;";
589     echo "</TD><TD BGCOLOR=\"$THEME->cellcontent\">\n";
591     if ($post->attachment) {
592         $post->course = $courseid;
593         $post->forum = get_field("forum_discussions", "forum", "id", $post->discussion);
594         echo "<DIV ALIGN=right>";
595         forum_print_attachments($post);
596         echo "</DIV>";
597     }
599     if ($link and (strlen(strip_tags($post->message)) > FORUM_LONG_POST)) {
600         // Print shortened version
601         echo format_text(forum_shorten_post($post->message), $post->format);
602         $numwords = count_words(strip_tags($post->message));
603         echo "<A HREF=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\">";
604         echo get_string("readtherest", "forum");
605         echo "</A> (".get_string("numwords", "", $numwords).")...";
606     } else {
607         // Print whole message
608         echo format_text($post->message, $post->format);
609     }
611     echo "<P ALIGN=right><FONT SIZE=-1>";
613     $age = time() - $post->created;
614     if ($ownpost) {
615         if ($age < $CFG->maxeditingtime) {
616             echo "<A HREF=\"$CFG->wwwroot/mod/forum/post.php?edit=$post->id\">".get_string("edit", "forum")."</A> | ";
617         }
618     }
619     if ($ownpost or isteacher($courseid)) {
620         echo "<A HREF=\"$CFG->wwwroot/mod/forum/post.php?delete=$post->id\">".get_string("delete", "forum")."</A>";
621         if ($reply) {
622             echo "| ";
623         } else {
624             echo "&nbsp;&nbsp;";
625         }
626     }
627     if ($reply) {
628         echo "<A HREF=\"$CFG->wwwroot/mod/forum/post.php?reply=$post->id\">".get_string("reply", "forum")."</A>";
629         echo "&nbsp;&nbsp;";
630     }
631     echo "</P>";
633     echo "<DIV ALIGN=right><P ALIGN=right>";
634     if ($rate && $USER->id) {
635         if (isteacher($courseid)) {
636             forum_print_ratings($post->id);
637             if ($USER->id != $post->userid) {
638                 forum_print_rating($post->id, $USER->id);
639             }
640         } else if ($USER->id == $post->userid) {
641             forum_print_ratings($post->id);
642         } else {
643             forum_print_rating($post->id, $USER->id);
644         }
645     }
646     
647     if ($link) {
648         if ($post->replies == 1) {
649             $replystring = get_string("repliesone", "forum", $post->replies);
650         } else {
651             $replystring = get_string("repliesmany", "forum", $post->replies);
652         }
653         echo "<A HREF=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\"><B>".get_string("discussthistopic", "forum")."</B></A> ($replystring)&nbsp;&nbsp;";
654     }
655     echo "</P>";
656     if ($footer) {
657         echo "<P>$footer</P>";
658     }
659     echo "</DIV>";
660     echo "</TD></TR></TABLE>";
661     echo "</TD></TR>\n</TABLE>\n\n";
665 function forum_print_post_header(&$post, $courseid, $ownpost=false, $reply=false, $link=false, $rate=false, $footer="") {
666     global $THEME, $USER, $CFG;
668     if ($post->parent) {
669         echo "<TABLE BORDER=0 CELLPADDING=1 CELLSPACING=1><TR><TD BGCOLOR=#888888>";
670         echo "<TABLE BORDER=0 CELLPADDING=3 CELLSPACING=0>";
671     } else {
672         echo "<TABLE BORDER=0 CELLPADDING=1 CELLSPACING=1 WIDTH=100%><TR><TD BGCOLOR=#888888>";
673         echo "<TABLE BORDER=0 CELLPADDING=3 CELLSPACING=0 WIDTH=100%>";
674     }
676     echo "<TR><TD BGCOLOR=\"$THEME->body\" WIDTH=35 VALIGN=TOP>";
677     print_user_picture($post->userid, $courseid, $post->picture);
678     echo "</TD>";
680     if ($post->parent) {
681         echo "<TD NOWRAP BGCOLOR=\"$THEME->cellheading\">";
682     } else {
683         echo "<TD NOWRAP BGCOLOR=\"$THEME->cellheading2\">";
684     }
685     echo "<P>";
686     echo "<FONT SIZE=3><B>$post->subject</B></FONT><BR>";
687     echo "<FONT SIZE=2>";
688     $by->name = "<A HREF=\"$CFG->wwwroot/user/view.php?id=$post->userid&course=$courseid\">$post->firstname $post->lastname</A>";
689     $by->date = userdate($post->created);
690     print_string("bynameondate", "forum", $by);
691     echo "</FONT></P></TD>";
693     if ($post->parent) {
694         echo "<TD VALIGN=BOTTOM BGCOLOR=\"$THEME->cellheading\">";
695     } else {
696         echo "<TD VALIGN=BOTTOM BGCOLOR=\"$THEME->cellheading2\">";
697     }
698     echo "<P ALIGN=right><FONT SIZE=-1>";
700     if ($link) {
701         if ($post->replies == 1) {
702             $replystring = get_string("repliesone", "forum", $post->replies);
703         } else {
704             $replystring = get_string("repliesmany", "forum", $post->replies);
705         }
706         echo "<A HREF=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\"><B>".get_string("discussthistopic", "forum")."</B></A> ($replystring)&nbsp;&nbsp;";
707     }
708     echo "</P>";
709     echo "</TD></TR></TABLE>";
710     echo "</TD></TR>\n</TABLE>\n\n";
714 function forum_shorten_post($message) {
715 // Given a post object that we already know has a long message
716 // this function truncates the message nicely to the first 
717 // sane place between FORUM_LONG_POST and FORUM_SHORT_POST
719    $i = 0;
720    $tag = false;
721    $length = strlen($message);
722    $count = 0;
723    $stopzone = false;
724    $truncate = 0;
726    for ($i=0; $i<$length; $i++) {
727        $char = $message[$i];
729        switch ($char) {
730            case "<": 
731                $tag = true;
732                break;
733            case ">": 
734                $tag = false;
735                break;
736            default:
737                if (!$tag) {
738                    if ($stopzone) {
739                        if ($char == " " or $char == ".") {
740                            $truncate = $i+1;
741                            break 2;
742                        }
743                    }
744                    $count++;
745                }
746                break;
747        }
748        if (!$stopzone) {
749            if ($count > FORUM_SHORT_POST) {
750                $stopzone = true;
751            }
752        }
753    }
755    if (!$truncate) {
756        $truncate = $i;
757    }
759    return substr($message, 0, $truncate)."<BR>";
763 function forum_print_ratings($post) {
764     if ($ratings = get_records_sql("SELECT * from forum_ratings WHERE post='$post'")) {
765         $sumrating[1] = 0;
766         $sumrating[2] = 0;
767         $sumrating[3] = 0;
768         foreach ($ratings as $rating) {
769             $sumrating[$rating->rating]++;
770         }
771         $summary = $sumrating[1]."s/".$sumrating[2]."/".$sumrating[3]."c";
773         echo get_string("ratings", "forum").": ";
774         link_to_popup_window ("/mod/forum/report.php?id=$post", "ratings", $summary, 400, 550);
775     }
778 function forum_print_rating($post, $user) {
779     global $FORUM_POST_RATINGS;
781     if ($rs = get_record_sql("SELECT rating from forum_ratings WHERE user='$user' AND post='$post'")) {
782         if ($FORUM_POST_RATINGS[$rs->rating]) {
783             echo "<FONT SIZE=-1>".get_string("youratedthis", "forum").": <FONT COLOR=green>";
784             echo $FORUM_POST_RATINGS[$rs->rating];
785             echo "</FONT></FONT>";
786             return;
787         }
788     }
789     choose_from_menu($FORUM_POST_RATINGS, $post, "", get_string("rate", "forum")."...");
792 function forum_print_mode_form($discussion, $mode) {
793     GLOBAL $FORUM_LAYOUT_MODES;
795     echo "<CENTER><P>";
796     popup_form("discuss.php?d=$discussion&mode=", $FORUM_LAYOUT_MODES, "mode", $mode, "");
797     echo "</P></CENTER>\n";
800 function forum_print_search_form($course, $search="") {
801     global $CFG;
803     echo "<TABLE BORDER=0 CELLPADDING=10 CELLSPACING=0><TR><TD ALIGN=CENTER>";
804     echo "<FORM NAME=search ACTION=\"$CFG->wwwroot/mod/forum/search.php\">";
805     echo "<INPUT NAME=search TYPE=text SIZE=15 VALUE=\"$search\"><BR>";
806     echo "<INPUT VALUE=\"".get_string("searchforums", "forum")."\" TYPE=submit>";
807     echo "<INPUT NAME=id TYPE=hidden VALUE=\"$course->id\">";
808     echo "</FORM>";
809     echo "</TD></TR></TABLE>";
813 function forum_count_discussion_replies($forum="0") {
814 // Returns an array of counts of replies to each discussion (optionally in one forum)
815     if ($forum) {
816         $forumselect = " AND d.forum = '$forum'";
817     }
818     return get_records_sql("SELECT p.discussion, (count(*)) as replies
819                             FROM forum_posts p, forum_discussions d
820                             WHERE p.parent > 0 AND p.discussion = d.id 
821                             GROUP BY p.discussion");
824 function forum_count_unrated_posts($discussionid, $userid) {
825 // How many unrated posts are in the given discussion for a given user?
826     if ($posts = get_record_sql("SELECT count(*) as num
827                                  FROM forum_posts
828                                  WHERE parent > 0 AND 
829                                        discussion = '$discussionid' AND 
830                                        user <> '$userid' ")) {
832         if ($rated = get_record_sql("SELECT count(*) as num 
833                                      FROM forum_posts p, forum_ratings r
834                                      WHERE p.discussion = '$discussionid'
835                                        AND p.id = r.post 
836                                        AND r.user = '$userid'")) {
837             $difference = $posts->num - $rated->num;
838             if ($difference > 0) {
839                 return $difference;
840             } else {
841                 return 0;    // Just in case there was a counting error
842             }
843         } else {
844             return $posts->num;
845         }
846     } else {
847         return 0;
848     }
852 function forum_set_return() {
853     global $CFG, $SESSION, $HTTP_REFERER;
855     if (! isset($SESSION->fromdiscussion)) {
856         // If the referer is NOT a login screen then save it.
857         if (! strncasecmp("$CFG->wwwroot/login", $HTTP_REFERER, 300)) {
858             $SESSION->fromdiscussion = $HTTP_REFERER;
859             save_session("SESSION");
860         }
861     }
865 function forum_go_back_to($default) {
866     global $SESSION;
868     if ($SESSION->fromdiscussion) {
869         $returnto = $SESSION->fromdiscussion;
870         unset($SESSION->fromdiscussion);
871         save_session("SESSION");
872         return $returnto;
873     } else {
874         return $default;
875     }
878 function forum_get_post_full($postid) {
879     return get_record_sql("SELECT p.*, u.firstname, u.lastname, 
880                                   u.email, u.picture, u.id as userid
881                            FROM forum_posts p, user u 
882                            WHERE p.id = '$postid' AND p.user = u.id");
885 function forum_file_area_name($post) {
886 //  Creates a directory file name, suitable for make_upload_directory()
887     global $CFG;
889     return "$post->course/$CFG->moddata/forum/$post->forum/$post->id";
892 function forum_file_area($post) {
893     return make_upload_directory( forum_file_area_name($post) );
896 function forum_delete_old_attachments($post, $exception="") {
897 // Deletes all the user files in the attachments area for a post
898 // EXCEPT for any file named $exception
900     if ($basedir = forum_file_area($post)) {
901         if ($files = get_directory_list($basedir)) {
902             foreach ($files as $file) {
903                 if ($file != $exception) {
904                     unlink("$basedir/$file");
905                     notify("Existing file '$file' has been deleted!");
906                 }
907             }
908         }
909         if (!$exception) {  // Delete directory as well, if empty
910             rmdir("$basedir");
911         }
912     }
915 function forum_print_attachments($post, $return=NULL) {
916 // if return=html, then return a html string.
917 // if return=text, then return a text-only string.
918 // otherwise, print HTML
920     global $CFG;
922     $filearea = forum_file_area_name($post);
924     if ($basedir = forum_file_area($post)) {
925         if ($files = get_directory_list($basedir)) {
926             $strattachment = get_string("attachment", "forum");
927             foreach ($files as $file) {
928                 $icon = mimeinfo("icon", $file);
929                 if ($CFG->slasharguments) {
930                     $ffurl = "file.php/$filearea/$file";
931                 } else {
932                     $ffurl = "file.php?file=/$filearea/$file";
933                 }
934                 $image = "<IMG BORDER=0 SRC=\"$CFG->wwwroot/files/pix/$icon\" HEIGHT=16 WIDTH=16 ALT=\"File\">";
936                 if ($return == "html") {
937                     $output .= "<A HREF=\"$CFG->wwwroot/$ffurl\">$image</A> ";
938                     $output .= "<A HREF=\"$CFG->wwwroot/$ffurl\">$file</A><BR>";
940                 } else if ($return == "text") {
941                     $output .= "$strattachment $file:\n$CFG->wwwroot/$ffurl\n";
943                 } else {
944                     link_to_popup_window("/$ffurl", "attachment", $image, 500, 500, $strattachment);
945                     echo "<A HREF=\"$CFG->wwwroot/$ffurl\">$file</A>";
946                     echo "<BR>";
947                 }
948             }
949         }
950     }
951     if ($return) {
952         return $output;
953     }
956 function forum_add_attachment($post, $newfile) {
957 // $post is a full post record, including course and forum
958 // $newfile is a full upload array from HTTP_POST_FILES
959 // If successful, this function returns the name of the file
961     if (!isset($newfile['name'])) {
962         return "";
963     }
965     $newfile_name = clean_filename($newfile['name']);
967     if (valid_uploaded_file($newfile)) {
968         if (! $newfile_name) {
969             notify("This file had a wierd filename and couldn't be uploaded");
971         } else if (! $dir = forum_file_area($post)) {
972             notify("Attachment could not be stored");
973             $newfile_name = "";
975         } else {
976             if (move_uploaded_file($newfile['tmp_name'], "$dir/$newfile_name")) {
977                 forum_delete_old_attachments($post, $newfile_name);
978             } else {
979                 notify("An error happened while saving the file on the server");
980                 $newfile_name = "";
981             }
982         }
983     } else {
984         $newfile_name = "";
985     }
987     return $newfile_name;
990 function forum_add_new_post($post) {
992     $post->created = $post->modified = time();
993     $post->mailed = "0";
995     $newfile = $post->attachment;
996     $post->attachment = "";
998     if (! $post->id = insert_record("forum_posts", $post)) { 
999         return false;
1000     }
1002     if ($post->attachment = forum_add_attachment($post, $newfile)) {
1003         set_field("forum_posts", "attachment", $post->attachment, "id", $post->id);
1004     }
1005     
1006     return $post->id;
1009 function forum_update_post($post) {
1011     $post->modified = time();
1013     if (!$post->parent) {   // Post is a discussion starter - update discussion title too
1014         set_field("forum_discussions", "name", $post->subject, "id", $post->discussion);
1015     }
1016     if ($newfilename = forum_add_attachment($post, $post->attachment)) {
1017         $post->attachment = $newfilename;
1018     } else {
1019         unset($post->attachment);
1020     }
1021     return update_record("forum_posts", $post);
1024 function forum_add_discussion($discussion) {
1025 // Given an object containing all the necessary data, 
1026 // create a new discussion and return the id
1028     GLOBAL $USER;
1030     $timenow = time();
1032     // The first post is stored as a real post, and linked 
1033     // to from the discuss entry.
1035     $post->discussion  = 0;
1036     $post->parent      = 0;
1037     $post->user        = $USER->id;
1038     $post->created     = $timenow;
1039     $post->modified    = $timenow;
1040     $post->mailed      = 0;
1041     $post->subject     = $discussion->name;
1042     $post->message     = $discussion->intro;
1043     $post->attachment  = "";
1044     $post->forum       = $discussion->forum;
1045     $post->course      = $discussion->course;
1047     if (! $post->id = insert_record("forum_posts", $post) ) {
1048         return 0;
1049     }
1051     if ($post->attachment = forum_add_attachment($post, $discussion->attachment)) {
1052         set_field("forum_posts", "attachment", $post->attachment, "id", $post->id); //ignore errors
1053     }
1055     // Now do the real module entry
1057     $discussion->firstpost    = $post->id;
1058     $discussion->timemodified = $timenow;
1060     if (! $discussion->id = insert_record("forum_discussions", $discussion) ) {
1061         delete_records("forum_posts", "id", $post->id);
1062         return 0;
1063     }
1065     // Finally, set the pointer on the post.
1066     if (! set_field("forum_posts", "discussion", $discussion->id, "id", $post->id)) {
1067         delete_records("forum_posts", "id", $post->id);
1068         delete_records("forum_discussions", "id", $discussion->id);
1069         return 0;
1070     }
1072     return $discussion->id;
1076 function forum_delete_discussion($discussion) {
1077 // $discussion is a discussion record object
1079     $result = true;
1081     if ($posts = get_records("forum_posts", "discussion", $discussion->id)) {
1082         foreach ($posts as $post) {
1083             $post->course = $discussion->course;
1084             $post->forum  = $discussion->forum;
1085             if (! delete_records("forum_ratings", "post", "$post->id")) {
1086                 $result = false;
1087             }
1088             if (! forum_delete_post($post)) {
1089                 $result = false;
1090             }
1091         }
1092     }
1094     if (! delete_records("forum_discussions", "id", "$discussion->id")) {
1095         $result = false;
1096     }
1098     return $result;
1102 function forum_delete_post($post) {
1103    if (delete_records("forum_posts", "id", $post->id)) {
1104        delete_records("forum_ratings", "post", $post->id);  // Just in case
1105        if ($post->attachment) {
1106            $discussion = get_record("forum_discussions", "id", $post->discussion);
1107            $post->course = $discussion->course;
1108            $post->forum  = $discussion->forum;
1109            forum_delete_old_attachments($post);
1110        }
1111        return true;
1112    }
1113    return false;
1117 function forum_print_user_discussions($courseid, $userid) {
1118     global $CFG, $USER;
1120     $discussions = get_records_sql("SELECT p.*, u.firstname, u.lastname, u.email, u.picture, 
1121                                            u.id as userid, f.type as forumtype, f.name as forumname, f.id as forumid
1122                                     FROM forum_discussions d, forum_posts p, user u, forum f
1123                                     WHERE d.course = '$courseid' AND p.discussion = d.id AND 
1124                                           p.parent = 0 AND p.user = u.id AND u.id = '$userid' AND
1125                                           d.forum = f.id
1126                                     ORDER BY p.created ASC");
1127     
1128     if ($discussions) {
1129         $user = get_record("user", "id", $userid);
1130         echo "<HR>";
1131         print_heading( get_string("discussionsstartedby", "forum", "$user->firstname $user->lastname") );
1132         $replies = forum_count_discussion_replies();
1133         foreach ($discussions as $discussion) {
1134             if (($discussion->forumtype == "teacher") and !isteacher($courseid)) {
1135                 continue;
1136             }
1137             if ($replies[$discussion->discussion]) {
1138                 $discussion->replies = $replies[$discussion->discussion]->replies;
1139             } else {
1140                 $discussion->replies = 0;
1141             }
1142             $inforum = get_string("inforum", "forum", "<A HREF=\"$CFG->wwwroot/mod/forum/view.php?f=$discussion->forumid\">$discussion->forumname</A>");
1143             $discussion->subject .= " ($inforum)";
1144             $ownpost = ($discussion->userid == $USER->id);
1145             forum_print_post($discussion, $courseid, $ownpost, $reply=0, $link=1, $assessed=false);
1146             echo "<BR>\n";
1147         }
1148     }
1151 function forum_forcesubscribe($forumid, $value=1) {
1152     return set_field("forum", "forcesubscribe", $value, "id", $forumid);
1155 function forum_is_forcesubscribed($forumid) {
1156     return get_field("forum", "forcesubscribe", "id", $forumid);
1159 function forum_is_subscribed($userid, $forumid) {
1160     if (forum_is_forcesubscribed($forumid)) {
1161         return true;
1162     }
1163     return record_exists_sql("SELECT * FROM forum_subscriptions WHERE user='$userid' AND forum='$forumid'");
1166 function forum_subscribed_users($course, $forum) {
1167 // Returns list of user objects that are subscribed to this forum
1169     if ($course->category) {   // normal course
1170         if ($forum->forcesubscribe) {
1171             return get_course_users($course->id);
1172         }
1173     }
1174     return get_records_sql("SELECT u.* FROM user u, forum_subscriptions s
1175                             WHERE s.forum = '$forum->id'
1176                               AND s.user = u.id AND u.deleted <> '1'");
1179 function forum_subscribe($userid, $forumid) {
1180     global $db;
1182     return $db->Execute("INSERT INTO forum_subscriptions SET user = '$userid', forum = '$forumid'");
1185 function forum_unsubscribe($userid, $forumid) {
1186     global $db;
1188     return $db->Execute("DELETE FROM forum_subscriptions WHERE user = '$userid' AND forum = '$forumid'");
1192 function forum_user_has_posted_discussion($forumid, $userid) {
1193     if ($discussions = forum_get_discussions($forumid, "DESC", $userid)) {
1194         return true;
1195     } else {
1196         return false;
1197     }
1200 function forum_user_can_post_discussion($forum) {
1201 // $forum is an object
1202     global $USER;
1204     if ($forum->type == "eachuser") {
1205         return (! forum_user_has_posted_discussion($forum->id, $USER->id));
1206     } else if ($forum->type == "teacher") {
1207         return isteacher($forum->course);
1208     } else if (isteacher($forum->course)) {
1209         return true;
1210     } else {
1211         return ($forum->open == 2);
1212     }
1215 function forum_user_can_post($forum, $user=NULL) {
1216 // $forum, $user are objects
1218     if ($user) {
1219         $isteacher = isteacher($forum->course, $user->id);
1220     } else {
1221         $isteacher = isteacher($forum->course);
1222     }
1224     if ($forum->type == "teacher") {
1225         return $isteacher;
1226     } else if ($isteacher) {
1227         return true;
1228     } else {
1229         return $forum->open;
1230     }
1233 function forum_get_discussions($forum="0", $forum_sort="DESC", $user=0) {
1234     if ($user) {
1235         $userselect = " AND u.id = '$user' ";
1236     } else {
1237         $userselect = "";
1238     }
1239     return get_records_sql("SELECT p.*, u.firstname, u.lastname, u.email, u.picture, u.id as userid
1240                             FROM forum_discussions d, forum_posts p, user u 
1241                             WHERE d.forum = '$forum' AND p.discussion = d.id AND 
1242                                   p.parent= 0 AND p.user = u.id $userselect
1243                             ORDER BY p.created $forum_sort");
1248 function forum_print_latest_discussions($forum_id=0, $forum_numdiscussions=5, $forum_style="plain", $forum_sort="DESC") {
1249     global $CFG, $USER;
1250     
1251     if ($forum_id) {
1252         if (! $forum = get_record("forum", "id", $forum_id)) {
1253             error("Forum ID was incorrect");
1254         }
1255         if (! $course = get_record("course", "id", $forum->course)) {
1256             error("Could not find the course this forum belongs to!");
1257         }
1259         if ($course->category) {
1260             require_login($course->id);
1261         }
1263     } else {
1264         if (! $course = get_record("course", "category", 0)) {
1265             error("Could not find a top-level course!");
1266         }
1267         if (! $forum = forum_get_course_forum($course->id, "news")) {
1268             error("Could not find or create a main forum in this course (id $course->id)");
1269         }
1270     }
1272     if (forum_user_can_post_discussion($forum)) {
1273         echo "<P ALIGN=CENTER>";
1274         echo "<A HREF=\"$CFG->wwwroot/mod/forum/post.php?forum=$forum->id\">";
1275         echo get_string("addanewdiscussion", "forum")."</A>...";
1276         echo "</P>\n";
1277     }
1279     if (! $discussions = forum_get_discussions($forum->id, $forum_sort) ) {
1280         echo "<P ALIGN=CENTER><B>(".get_string("nodiscussions", "forum").")</B></P>";
1281         return;
1283     }
1284     
1285     if ((!$forum_numdiscussions) && ($forum_style == "plain") && (count($discussions) > FORUM_MANY_DISCUSSIONS) ) { 
1286         $forum_style = "header";  // Abbreviate display if it's going to be long.
1287     }
1289     $replies = forum_count_discussion_replies($forum->id);
1291     $canreply = forum_user_can_post($forum);
1293     $discussioncount = 0;
1295     foreach ($discussions as $discussion) {
1296         $discussioncount++;
1298         if ($forum_numdiscussions && ($discussioncount > $forum_numdiscussions)) {
1299             echo "<P ALIGN=right><A HREF=\"$CFG->wwwroot/mod/forum/view.php?f=$forum->id\">";
1300             echo get_string("olderdiscussions", "forum")."</A> ...</P>";
1301             break;
1302         }
1303         if ($replies[$discussion->discussion]) {
1304             $discussion->replies = $replies[$discussion->discussion]->replies;
1305         } else {
1306             $discussion->replies = 0;
1307         }
1308         $ownpost = ($discussion->userid == $USER->id);
1309         switch ($forum_style) {
1310             case "minimal":
1311                 echo "<P><FONT COLOR=#555555>".userdate($discussion->modified, "%e %b, %H:%M")." - $discussion->firstname</FONT>";
1312                 echo "<BR>$discussion->subject ";
1313                 echo "<A HREF=\"$CFG->wwwroot/mod/forum/discuss.php?d=$discussion->discussion\">";
1314                 echo get_string("more", "forum")."...</A>";
1315                 echo "</P>\n";
1316             break;
1317             case "header":
1318                 forum_print_post_header($discussion, $forum->course, $ownpost, $reply=0, $link=1, $assessed=false);
1319             break;
1320             default:
1321                 if ($canreply or $discussion->replies) {
1322                     $link = true;
1323                 } else {
1324                     $link = false;
1325                 }
1326                 forum_print_post($discussion, $forum->course, $ownpost, $reply=0, $link, $assessed=false);
1327                 echo "<BR>\n";
1328             break;
1329         }
1330     }
1333 function forum_print_discussion($course, $forum, $discussion, $post, $mode) {
1335     global $USER;
1337     $ownpost = ($USER->id == $post->user);
1338     $reply   = forum_user_can_post($forum);
1340     forum_print_post($post, $course->id, $ownpost, $reply, $link=false, $rate=false);
1342     forum_print_mode_form($discussion->id, $mode);
1344     $ratingform = false;
1345     if ($forum->assessed && $USER->id) {
1346         $unrated = forum_count_unrated_posts($discussion->id, $USER->id);
1347         if ($unrated > 0) {
1348             $ratingform = true;
1349         }
1350     }
1352     if ($ratingform) {
1353         echo "<FORM NAME=form METHOD=POST ACTION=rate.php>";
1354         echo "<INPUT TYPE=hidden NAME=id VALUE=\"$course->id\">";
1355     }
1357     switch ($mode) {
1358         case 1 :   // Flat ascending
1359         case -1 :  // Flat descending
1360         default:   
1361             echo "<UL>";
1362             forum_print_posts_flat($post->discussion, $course->id, $mode, $forum->assessed, $reply);
1363             echo "</UL>";
1364             break;
1366         case 2 :   // Threaded 
1367             forum_print_posts_threaded($post->id, $course->id, 0, $forum->assessed, $reply);
1368             break;
1370         case 3 :   // Nested
1371             forum_print_posts_nested($post->id, $course->id, $forum->assessed, $reply);
1372             break;
1373     }
1375     if ($ratingform) {
1376         echo "<CENTER><P ALIGN=center><INPUT TYPE=submit VALUE=\"".get_string("sendinratings", "forum")."\">";
1377         helpbutton("ratings", get_string("separateandconnected"), "forum");
1378         echo "</P></CENTER>";
1379         echo "</FORM>";
1380     }
1383 function forum_print_posts_flat($discussion, $course, $direction, $assessed, $reply) { 
1384     global $USER;
1386     $link  = false;
1388     if ($direction < 0) {
1389         $sort = "ORDER BY created DESC";
1390     } else {
1391         $sort = "ORDER BY created ASC";
1392     }
1394     if ($posts = get_records_sql("SELECT p.*, u.id as userid, u.firstname, u.lastname, u.email, u.picture
1395                                   FROM forum_posts p, user u
1396                                   WHERE p.discussion = $discussion AND p.parent > 0 AND p.user = u.id $sort")) {
1398         foreach ($posts as $post) {
1399             $ownpost = ($USER->id == $post->user);
1400             forum_print_post($post, $course, $ownpost, $reply, $link, $assessed);
1401         }
1402     } else {
1403         return;
1404     }
1407 function forum_print_posts_threaded($parent, $course, $depth, $assessed, $reply) { 
1408     global $USER;
1410     $link  = false;
1412     if ($posts = get_records_sql("SELECT p.*, u.id as userid, u.firstname, u.lastname, u.email, u.picture
1413                                   FROM forum_posts p, user u
1414                                   WHERE p.parent = '$parent' AND p.user = u.id")) {
1416         foreach ($posts as $post) {
1418             echo "<UL>";
1419             if ($depth > 0) {
1420                 $ownpost = ($USER->id == $post->user);
1421                 forum_print_post($post, $course, $ownpost, $reply, $link, $assessed);  // link=true?
1422                 echo "<BR>";
1423             } else {
1424                 $by->name = "$post->firstname $post->lastname";
1425                 $by->date = userdate($post->created);
1426                 echo "<LI><P><FONT SIZE=-1><B><A HREF=\"discuss.php?d=$post->discussion&parent=$post->id\">$post->subject</A></B> ";
1427                 print_string("bynameondate", "forum", $by);
1428                 echo "</FONT></P></LI>";
1429             }
1431             forum_print_posts_threaded($post->id, $course, $depth-1, $assessed, $reply);
1432             echo "</UL>\n";
1433         }
1434     } else {
1435         return;
1436     }
1439 function forum_print_posts_nested($parent, $course, $assessed, $reply) { 
1440     global $USER;
1442     $link  = false;
1444     if ($posts = get_records_sql("SELECT p.*, u.id as userid, u.firstname, u.lastname, u.email, u.picture
1445                                   FROM forum_posts p, user u
1446                                   WHERE p.parent = $parent AND p.user = u.id
1447                                   ORDER BY p.created ASC ")) {
1449         foreach ($posts as $post) {
1451             $ownpost = ($USER->id == $post->user);
1453             echo "<UL>";
1454             forum_print_post($post, $course, $ownpost, $reply, $link, $assessed);
1455             echo "<BR>";
1456             forum_print_posts_nested($post->id, $course, $assessed, $reply);
1457             echo "</UL>\n";
1458         }
1459     } else {
1460         return;
1461     }
1464 function forum_set_display_mode($mode=0) {
1465     global $USER, $FORUM_DEFAULT_DISPLAY_MODE;
1467     if ($mode) {
1468         $USER->mode = $mode;
1469         save_session("USER");
1470     } else if (!$USER->mode) {
1471         $USER->mode = $FORUM_DEFAULT_DISPLAY_MODE;
1472         save_session("USER");
1473     }
1477 ?>