- Not Categorized is now the default view for category tab.
[moodle.git] / mod / forum / lib.php
CommitLineData
f93f848a 1<?PHP // $Id$
2
b0e3a925 3require_once("$CFG->dirroot/files/mimetypes.php");
7f6689e4 4
501cdbd8 5/// CONSTANTS ///////////////////////////////////////////////////////////
f93f848a 6
2e2e71a8 7define("FORUM_MODE_FLATOLDEST", 1);
8define("FORUM_MODE_FLATNEWEST", -1);
9define("FORUM_MODE_THREADED", 2);
10define("FORUM_MODE_NESTED", 3);
11
12$FORUM_LAYOUT_MODES = array ( FORUM_MODE_FLATOLDEST => get_string("modeflatoldestfirst", "forum"),
13 FORUM_MODE_FLATNEWEST => get_string("modeflatnewestfirst", "forum"),
14 FORUM_MODE_THREADED => get_string("modethreaded", "forum"),
15 FORUM_MODE_NESTED => get_string("modenested", "forum") );
f93f848a 16
11b0c469 17// These are course content forums that can be added to the course manually
ffe11640 18$FORUM_TYPES = array ("general" => get_string("generalforum", "forum"),
19 "eachuser" => get_string("eachuserforum", "forum"),
20 "single" => get_string("singleforum", "forum") );
f93f848a 21
70c476a7 22$FORUM_OPEN_MODES = array ("2" => get_string("openmode2", "forum"),
23 "1" => get_string("openmode1", "forum"),
24 "0" => get_string("openmode0", "forum") );
25
5be7800c 26if (!isset($CFG->forum_displaymode)) {
2e2e71a8 27 set_config("forum_displaymode", FORUM_MODE_NESTED);
5be7800c 28}
73bb0835 29
5be7800c 30if (!isset($CFG->forum_shortpost)) {
31 set_config("forum_shortpost", 300); // Less non-HTML characters than this is short
32}
4d871a72 33
5be7800c 34if (!isset($CFG->forum_longpost)) {
35 set_config("forum_longpost", 600); // More non-HTML characters than this is long
36}
4d871a72 37
5be7800c 38if (!isset($CFG->forum_manydiscussions)) {
39 set_config("forum_manydiscussions", 100); // Number of discussions on a page
40}
e07635f4 41
42
caadf009 43/// STANDARD FUNCTIONS ///////////////////////////////////////////////////////////
44
45function forum_add_instance($forum) {
46// Given an object containing all the necessary data,
47// (defined by the form in mod.html) this function
48// will create a new instance and return the id number
49// of the new instance.
50
51 global $CFG;
52
53 $forum->timemodified = time();
54
55 if (! $forum->id = insert_record("forum", $forum)) {
56 return false;
57 }
58
f2f56406 59 if (!$forum->userating) {
60 $forum->assessed = 0;
61 }
62
98914efd 63 if (!empty($forum->ratingtime)) {
64 $forum->assesstimestart = make_timestamp($forum->startyear, $forum->startmonth, $forum->startday,
65 $forum->starthour, $forum->startminute, 0);
66 $forum->assesstimefinish = make_timestamp($forum->finishyear, $forum->finishmonth, $forum->finishday,
67 $forum->finishhour, $forum->finishminute, 0);
68 } else {
69 $forum->assesstimestart = 0;
70 $forum->assesstimefinish = 0;
71 }
caadf009 72
98914efd 73 if ($forum->type == "single") { // Create related discussion.
caadf009 74 $discussion->course = $forum->course;
75 $discussion->forum = $forum->id;
76 $discussion->name = $forum->name;
77 $discussion->intro = $forum->intro;
78 $discussion->assessed = $forum->assessed;
79
80 if (! forum_add_discussion($discussion)) {
81 error("Could not add the discussion for this forum");
82 }
83 }
84 add_to_log($forum->course, "forum", "add", "index.php?f=$forum->id", "$forum->id");
85
86 return $forum->id;
87}
88
89
90function forum_update_instance($forum) {
91// Given an object containing all the necessary data,
92// (defined by the form in mod.html) this function
93// will update an existing instance with new data.
94
95 $forum->timemodified = time();
96 $forum->id = $forum->instance;
97
f2f56406 98 if (!$forum->userating) {
99 $forum->assessed = 0;
100 }
101
98914efd 102 if (!empty($forum->ratingtime)) {
103 $forum->assesstimestart = make_timestamp($forum->startyear, $forum->startmonth, $forum->startday,
104 $forum->starthour, $forum->startminute, 0);
105 $forum->assesstimefinish = make_timestamp($forum->finishyear, $forum->finishmonth, $forum->finishday,
106 $forum->finishhour, $forum->finishminute, 0);
107 } else {
108 $forum->assesstimestart = 0;
109 $forum->assesstimefinish = 0;
110 }
111
caadf009 112 if ($forum->type == "single") { // Update related discussion and post.
113 if (! $discussion = get_record("forum_discussions", "forum", $forum->id)) {
114 if ($discussions = get_records("forum_discussions", "forum", $forum->id, "timemodified ASC")) {
115 notify("Warning! There is more than one discussion in this forum - using the most recent");
116 $discussion = array_pop($discussions);
117 } else {
118 error("Could not find the discussion in this forum");
119 }
120 }
121 if (! $post = get_record("forum_posts", "id", $discussion->firstpost)) {
122 error("Could not find the first post in this forum discussion");
123 }
124
125 $post->subject = $forum->name;
126 $post->message = $forum->intro;
127 $post->modified = $forum->timemodified;
128
129 if (! update_record("forum_posts", $post)) {
130 error("Could not update the first post");
131 }
132
133 $discussion->name = $forum->name;
134
135 if (! update_record("forum_discussions", $discussion)) {
136 error("Could not update the discussion");
137 }
138 }
139
140 if (update_record("forum", $forum)) {
141 add_to_log($forum->course, "forum", "update", "index.php?f=$forum->id", "$forum->id");
142 return true;
143 } else {
144 return false;
145 }
146}
147
148
149function forum_delete_instance($id) {
150// Given an ID of an instance of this module,
151// this function will permanently delete the instance
152// and any data that depends on it.
153
154 if (! $forum = get_record("forum", "id", "$id")) {
155 return false;
156 }
157
158 $result = true;
159
160 if ($discussions = get_records("forum_discussions", "forum", $forum->id)) {
161 foreach ($discussions as $discussion) {
162 if (! forum_delete_discussion($discussion)) {
163 $result = false;
164 }
165 }
166 }
167
168 if (! delete_records("forum_subscriptions", "forum", "$forum->id")) {
169 $result = false;
170 }
171
172 if (! delete_records("forum", "id", "$forum->id")) {
173 $result = false;
174 }
175
176 return $result;
177}
178
179
180function forum_cron () {
edffca15 181/// Function to be run periodically according to the moodle cron
182/// Finds all posts that have yet to be mailed out, and mails them
183/// out to all subscribers
caadf009 184
185 global $CFG, $USER;
186
187 $cutofftime = time() - $CFG->maxeditingtime;
188
1f48942e 189 if ($posts = forum_get_unmailed_posts($cutofftime)) {
caadf009 190
edffca15 191 /// Mark them all now as being mailed. It's unlikely but possible there
192 /// might be an error later so that a post is NOT actually mailed out,
193 /// but since mail isn't crucial, we can accept this risk. Doing it now
194 /// prevents the risk of duplicated mails, which is a worse problem.
195
196 foreach ($posts as $key => $post) {
197 if (! set_field("forum_posts", "mailed", "1", "id", "$post->id")) {
198 echo "Error marking post id post->id as being mailed. This post will not be mailed.\n";
199 unset($posts[$key]);
200 }
201 }
202
caadf009 203 $timenow = time();
204
205 foreach ($posts as $post) {
206
edffca15 207 echo "\n";
caadf009 208 print_string("processingpost", "forum", $post->id);
edffca15 209 echo "\n";
caadf009 210
ebc3bd2b 211 if (! $userfrom = get_record("user", "id", "$post->userid")) {
212 echo "Could not find user $post->userid\n";
caadf009 213 continue;
214 }
215
216 if (! $discussion = get_record("forum_discussions", "id", "$post->discussion")) {
217 echo "Could not find discussion $post->discussion\n";
218 continue;
219 }
220
221 if (! $forum = get_record("forum", "id", "$discussion->forum")) {
222 echo "Could not find forum $discussion->forum\n";
223 continue;
224 }
225
226 if (! $course = get_record("course", "id", "$forum->course")) {
227 echo "Could not find course $forum->course\n";
228 continue;
229 }
230
231 if ($users = forum_subscribed_users($course, $forum)) {
232 $canunsubscribe = ! forum_is_forcesubscribed($forum->id);
233
234 $mailcount=0;
235 foreach ($users as $userto) {
edffca15 236 /// Override the language of get_string, so that mail is in correct language for the receiver.
237 $USER->lang = $userto->lang;
f690562f 238 $canreply = forum_user_can_post($forum, $userto);
caadf009 239
caadf009 240 $by->name = "$userfrom->firstname $userfrom->lastname";
d62413e8 241 $by->date = userdate($post->modified, "", $userto->timezone);
caadf009 242 $strbynameondate = get_string("bynameondate", "forum", $by);
243
244 $strforums = get_string("forums", "forum");
245
246 $postsubject = "$course->shortname: $post->subject";
247 $posttext = "$course->shortname -> $strforums -> $forum->name";
248
249 if ($discussion->name == $forum->name) {
250 $posttext .= "\n";
251 } else {
252 $posttext .= " -> $discussion->name\n";
253 }
254 $posttext .= "---------------------------------------------------------------------\n";
255 $posttext .= "$post->subject\n";
256 $posttext .= $strbynameondate."\n";
257 $posttext .= "---------------------------------------------------------------------\n";
d342c763 258 $posttext .= format_text_email($post->message, $post->format);
caadf009 259 $posttext .= "\n\n";
260 if ($post->attachment) {
261 $post->course = $course->id;
262 $post->forum = $forum->id;
263 $posttext .= forum_print_attachments($post, "text");
264 }
f690562f 265 if ($canreply) {
266 $posttext .= "---------------------------------------------------------------------\n";
267 $posttext .= get_string("postmailinfo", "forum", $course->shortname)."\n";
268 $posttext .= "$CFG->wwwroot/mod/forum/post.php?reply=$post->id\n";
269 }
caadf009 270 if ($canunsubscribe) {
271 $posttext .= "\n---------------------------------------------------------------------\n";
272 $posttext .= get_string("unsubscribe", "forum");
273 $posttext .= ": $CFG->wwwroot/mod/forum/subscribe.php?id=$forum->id\n";
274 }
275
276 if ($userto->mailformat == 1) { // HTML
edffca15 277 $posthtml = "<p><font face=\"sans-serif\">".
278 "<a target=\"_blank\" href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> -> ".
279 "<a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/index.php?id=$course->id\">$strforums</a> -> ".
280 "<a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/view.php?f=$forum->id\">$forum->name</a>";
caadf009 281 if ($discussion->name == $forum->name) {
edffca15 282 $posthtml .= "</font></p>";
caadf009 283 } else {
edffca15 284 $posthtml .= " -> <a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$discussion->id\">$discussion->name</a></font></p>";
caadf009 285 }
f690562f 286 $posthtml .= forum_make_mail_post($post, $userfrom, $userto, $course, false, $canreply, false, false);
caadf009 287
288 if ($canunsubscribe) {
edffca15 289 $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>";
caadf009 290 }
291
292 } else {
293 $posthtml = "";
294 }
295
296 if (! email_to_user($userto, $userfrom, $postsubject, $posttext, $posthtml)) {
edffca15 297 echo "Error: mod/forum/cron.php: Could not send out mail for id $post->id to user $userto->id ($userto->email) .. not trying again.\n";
caadf009 298 } else {
299 $mailcount++;
300 }
301 }
caadf009 302
edffca15 303 echo ".... mailed to $mailcount users.\n";
caadf009 304 }
caadf009 305 }
306 }
307
308 return true;
309}
310
311function forum_user_outline($course, $user, $mod, $forum) {
312
1f48942e 313 if ($posts = forum_get_user_posts($forum->id, $user->id)) {
caadf009 314 $result->info = get_string("numposts", "forum", count($posts));
315
316 $lastpost = array_pop($posts);
317 $result->time = $lastpost->modified;
318 return $result;
319 }
320 return NULL;
321}
322
323
324function forum_user_complete($course, $user, $mod, $forum) {
325 global $CFG;
326
1f48942e 327 if ($posts = forum_get_user_posts($forum->id, $user->id)) {
caadf009 328 foreach ($posts as $post) {
329 if ($post->parent) {
330 $footer = "<A HREF=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion&parent=$post->parent\">".
331 get_string("parentofthispost", "forum")."</A>";
332 } else {
333 $footer = "";
334 }
335
336 forum_print_post($post, $course->id, $ownpost=false, $reply=false, $link=false, $rate=false, $footer);
337 }
338
339 } else {
340 echo "<P>".get_string("noposts", "forum")."</P>";
341 }
caadf009 342}
343
1b5910c4 344function forum_print_recent_activity($course, $isteacher, $timestart) {
cc3655a2 345/// Given a course and a date, prints a summary of all the new
346/// messages posted in the course since that date
347
3d891989 348 global $CFG;
caadf009 349
350 $heading = false;
351 $content = false;
352
1b5910c4 353 if (!$logs = get_records_select("log", "time > '$timestart' AND ".
354 "course = '$course->id' AND ".
355 "module = 'forum' AND ".
356 "action LIKE 'add %' ", "time ASC")){
357 return false;
358 }
359
dcde9f02 360 $strftimerecent = get_string("strftimerecent");
361
1b5910c4 362 foreach ($logs as $log) {
363 //Get post info, I'll need it later
364 $post = forum_get_post_from_log($log);
365
366 //Create a temp valid module structure (course,id)
367 $tempmod->course = $log->course;
368 $tempmod->id = $post->forum;
369 //Obtain the visible property from the instance
370 $modvisible = instance_is_visible($log->module,$tempmod);
371
372 //Only if the mod is visible
373 if ($modvisible) {
374 if ($post) {
375 $teacheronly = "";
376 if ($forum = get_record("forum", "id", $post->forum) ) {
377 if ($forum->type == "teacher") {
378 if ($isteacher) {
379 $teacheronly = "class=\"teacheronly\"";
ad08fdc2 380 } else {
1b5910c4 381 continue;
ad08fdc2 382 }
caadf009 383 }
384 }
1b5910c4 385 if (! $heading) {
386 print_headline(get_string("newforumposts", "forum").":");
387 $heading = true;
388 $content = true;
389 }
390 $date = userdate($post->modified, $strftimerecent);
391 echo "<p $teacheronly><font size=1>$date - $post->firstname $post->lastname<br>";
392 echo "\"<a href=\"$CFG->wwwroot/mod/forum/$log->url\">";
393 if ($log->action == "add discussion") {
394 echo "<b>$post->subject</b>";
395 } else {
396 echo "$post->subject";
397 }
398 echo "</a>\"</font></p>";
caadf009 399 }
400 }
401 }
1b5910c4 402
caadf009 403 return $content;
404}
405
406
10696dc1 407
408function forum_print_recent_instance_activity($forum, $timestart, $detail=false) {
409
410 global $CFG, $THEME;
411
412 if (!$posts = forum_get_recent_posts($timestart, $forum->id)) {
413 return false;
414 }
415
416 foreach ($posts as $post) {
417 echo '<table border="0" cellpadding="3" cellspacing="0" class="forumpost">';
418 echo "<tr><td bgcolor=\"$THEME->cellcontent2\" class=\"forumpostpicture\" width=\"35\" valign=\"top\">";
419 print_user_picture($post->userid, $forum->course, $post->picture);
420 echo "</td>";
421
422 if ($post->parent) {
423 echo "<td nowrap bgcolor=\"$THEME->cellheading\" class=\"forumpostheader\" width=\"100%\">";
424 } else {
425 echo "<td nowrap bgcolor=\"$THEME->cellheading2\" class=\"forumpostheadertopic\" width=\"100%\">";
426 }
427 echo "<p>";
428 echo "<font size=3>";
429 echo "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion#$post->id\">";
430 echo $post->subject;
431 echo "</a></font><br>";
432 echo "<font size=2>";
433 $by->name = "<a href=\"$CFG->wwwroot/user/view.php?id=$post->userid&course=$courseid\">$post->firstname $post->lastname</a>";
434 $by->date = userdate($post->modified);
435 print_string("bynameondate", "forum", $by);
436 echo "</font></p></td></tr></table>";
437 }
438}
439
440
caadf009 441function forum_grades($forumid) {
442/// Must return an array of grades, indexed by user, and a max grade.
caadf009 443
4db9d14d 444 if (!$forum = get_record("forum", "id", $forumid)) {
445 return false;
446 }
447 if (!$forum->assessed) {
448 return false;
449 }
d6bdd9d5 450 $scalemenu = make_grades_menu($forum->scale);
02ebf404 451
452 $currentuser = 0;
453 $ratingsuser = array();
454
1f48942e 455 if ($ratings = forum_get_user_grades($forumid)) {
02ebf404 456 foreach ($ratings as $rating) { // Ordered by user
457 if ($currentuser and $rating->userid != $currentuser) {
458 if (!empty($ratingsuser)) {
d6bdd9d5 459 if ($forum->scale < 0) {
460 $return->grades[$currentuser] = forum_get_ratings_mean(0, $scalemenu, $ratingsuser);
461 $return->grades[$currentuser] .= "<br />".forum_get_ratings_summary(0, $scalemenu, $ratingsuser);
462 } else {
463 $total = 0;
464 $count = 0;
465 foreach ($ratingsuser as $ra) {
466 $total += $ra;
467 $count ++;
468 }
469 $return->grades[$currentuser] = format_float($total/$count, 2);
470 }
02ebf404 471 } else {
472 $return->grades[$currentuser] = "";
473 }
474 $ratingsuser = array();
caadf009 475 }
02ebf404 476 $ratingsuser[] = $rating->rating;
477 $currentuser = $rating->userid;
caadf009 478 }
02ebf404 479 if (!empty($ratingsuser)) {
d6bdd9d5 480 if ($forum->scale < 0) {
481 $return->grades[$currentuser] = forum_get_ratings_mean(0, $scalemenu, $ratingsuser);
482 $return->grades[$currentuser] .= "<br />".forum_get_ratings_summary(0, $scalemenu, $ratingsuser);
483 } else {
484 $total = 0;
485 $count = 0;
486 foreach ($ratingsuser as $ra) {
487 $total += $ra;
488 $count ++;
489 }
490 $return->grades[$currentuser] = format_float((float)$total/(float)$count, 2);
491 }
02ebf404 492 } else {
493 $return->grades[$currentuser] = "";
caadf009 494 }
495 } else {
496 $return->grades = array();
497 }
498
d6bdd9d5 499 if ($forum->scale < 0) {
500 $return->maxgrade = "";
501 } else {
502 $return->maxgrade = $forum->scale;
503 }
caadf009 504 return $return;
505}
506
507
9fa49e22 508/// SQL FUNCTIONS ///////////////////////////////////////////////////////////
509
1f48942e 510function forum_get_post_full($postid) {
511/// Gets a post with all info ready for forum_print_post
512 global $CFG;
513
ebc3bd2b 514 return get_record_sql("SELECT p.*, u.firstname, u.lastname, u.email, u.picture
1f48942e 515 FROM {$CFG->prefix}forum_posts p,
516 {$CFG->prefix}user u
517 WHERE p.id = '$postid'
ebc3bd2b 518 AND p.userid = u.id");
1f48942e 519}
520
521function forum_get_discussion_posts($discussion, $sort) {
522/// Gets posts with all info ready for forum_print_post
523 global $CFG;
524
ebc3bd2b 525 return get_records_sql("SELECT p.*, u.firstname, u.lastname, u.email, u.picture
1f48942e 526 FROM {$CFG->prefix}forum_posts p,
527 {$CFG->prefix}user u
528 WHERE p.discussion = $discussion
529 AND p.parent > 0
ebc3bd2b 530 AND p.userid = u.id $sort");
1f48942e 531}
532
533function forum_get_child_posts($parent) {
534/// Gets posts with all info ready for forum_print_post
535 global $CFG;
536
ebc3bd2b 537 return get_records_sql("SELECT p.*, u.firstname, u.lastname, u.email, u.picture
1f48942e 538 FROM {$CFG->prefix}forum_posts p,
539 {$CFG->prefix}user u
540 WHERE p.parent = '$parent'
ebc3bd2b 541 AND p.userid = u.id
1f48942e 542 ORDER BY p.created ASC");
543}
544
545
8b9c7aa0 546function forum_search_posts($searchterms, $courseid, $page=0, $recordsperpage=50, &$totalcount) {
547/// Returns a list of posts found using an array of search terms
548/// eg word +word -word
549///
550
9fa49e22 551 global $CFG;
552
553 if (!isteacher($courseid)) {
554 $notteacherforum = "AND f.type <> 'teacher'";
4cabd355 555
556 $forummodule = get_record("modules", "name", "forum");
557 $onlyvisible = " AND f.id = cm.instance AND cm.visible = 1 AND cm.module = $forummodule->id";
558 $onlyvisibletable = ", {$CFG->prefix}course_modules cm";
9fa49e22 559 } else {
560 $notteacherforum = "";
4cabd355 561
562 $onlyvisible = "";
563 $onlyvisibletable = "";
9fa49e22 564 }
565
c2a96d6b 566 switch ($CFG->dbtype) {
567 case "mysql":
568 $limit = "LIMIT $page,$recordsperpage";
569 break;
570 case "postgres7":
571 $limit = "LIMIT $recordsperpage OFFSET ".($page * $recordsperpage);
572 break;
573 default:
574 $limit = "LIMIT $recordsperpage,$page";
97485d07 575 }
576
63d99fcb 577 /// Some differences in syntax for PostgreSQL
578 if ($CFG->dbtype == "postgres7") {
a74f950c 579 $LIKE = "ILIKE"; // case-insensitive
2b4c64e9 580 $NOTLIKE = "NOT ILIKE"; // case-insensitive
581 $REGEXP = "~*";
582 $NOTREGEXP = "!~*";
b800ac5a 583 } else {
a74f950c 584 $LIKE = "LIKE";
2b4c64e9 585 $NOTLIKE = "NOT LIKE";
a74f950c 586 $REGEXP = "REGEXP";
2b4c64e9 587 $NOTREGEXP = "NOT REGEXP";
c4c57597 588 }
589
b800ac5a 590 $messagesearch = "";
591 $subjectsearch = "";
592
b800ac5a 593
594 foreach ($searchterms as $searchterm) {
8b9c7aa0 595 if (strlen($searchterm) < 2) {
596 continue;
597 }
b800ac5a 598 if ($messagesearch) {
599 $messagesearch .= " AND ";
600 }
b800ac5a 601 if ($subjectsearch) {
602 $subjectsearch .= " AND ";
603 }
63d99fcb 604
a74f950c 605 if (substr($searchterm,0,1) == "+") {
606 $searchterm = substr($searchterm,1);
63d99fcb 607 $messagesearch .= " p.message $REGEXP '(^|[^a-zA-Z0-9])$searchterm([^a-zA-Z0-9]|$)' ";
608 $subjectsearch .= " p.subject $REGEXP '(^|[^a-zA-Z0-9])$searchterm([^a-zA-Z0-9]|$)' ";
a74f950c 609 } else if (substr($searchterm,0,1) == "-") {
610 $searchterm = substr($searchterm,1);
2b4c64e9 611 $messagesearch .= " p.message $NOTREGEXP '(^|[^a-zA-Z0-9])$searchterm([^a-zA-Z0-9]|$)' ";
612 $subjectsearch .= " p.subject $NOTREGEXP '(^|[^a-zA-Z0-9])$searchterm([^a-zA-Z0-9]|$)' ";
63d99fcb 613 } else {
614 $messagesearch .= " p.message $LIKE '%$searchterm%' ";
615 $subjectsearch .= " p.subject $LIKE '%$searchterm%' ";
616 }
b800ac5a 617 }
618
8b9c7aa0 619 $selectsql = "{$CFG->prefix}forum_posts p,
620 {$CFG->prefix}forum_discussions d,
621 {$CFG->prefix}user u,
4cabd355 622 {$CFG->prefix}forum f $onlyvisibletable
8b9c7aa0 623 WHERE ($messagesearch OR $subjectsearch)
624 AND p.userid = u.id
625 AND p.discussion = d.id
626 AND d.course = '$courseid'
4cabd355 627 AND d.forum = f.id $notteacherforum $onlyvisible";
8b9c7aa0 628
629 $totalcount = count_records_sql("SELECT COUNT(*) FROM $selectsql");
b800ac5a 630
8b9c7aa0 631 return get_records_sql("SELECT p.*,u.firstname,u.lastname,u.email,u.picture FROM
632 $selectsql ORDER BY p.modified DESC $limit");
9fa49e22 633}
634
63d99fcb 635
9fa49e22 636function forum_get_ratings($postid, $sort="u.firstname ASC") {
637/// Returns a list of ratings for a particular post - sorted.
638 global $CFG;
639 return get_records_sql("SELECT u.*, r.rating, r.time
640 FROM {$CFG->prefix}forum_ratings r,
641 {$CFG->prefix}user u
1f48942e 642 WHERE r.post = '$postid'
ebc3bd2b 643 AND r.userid = u.id
9fa49e22 644 ORDER BY $sort");
645}
646
1f48942e 647function forum_get_unmailed_posts($cutofftime) {
648/// Returns a list of all new posts that have not been mailed yet
649 global $CFG;
650 return get_records_sql("SELECT p.*, d.course
651 FROM {$CFG->prefix}forum_posts p,
652 {$CFG->prefix}forum_discussions d
653 WHERE p.mailed = 0
654 AND p.created < '$cutofftime'
655 AND p.discussion = d.id");
656}
657
658function forum_get_user_posts($forumid, $userid) {
659/// Get all the posts for a user in a forum suitable for forum_print_post
660 global $CFG;
661
ebc3bd2b 662 return get_records_sql("SELECT p.*, u.firstname, u.lastname, u.email, u.picture
1f48942e 663 FROM {$CFG->prefix}forum f,
664 {$CFG->prefix}forum_discussions d,
665 {$CFG->prefix}forum_posts p,
666 {$CFG->prefix}user u
667 WHERE f.id = '$forumid'
668 AND d.forum = f.id
669 AND p.discussion = d.id
ebc3bd2b 670 AND p.userid = '$userid'
671 AND p.userid = u.id
1f48942e 672 ORDER BY p.modified ASC");
673}
674
675function forum_get_post_from_log($log) {
676/// Given a log entry, return the forum post details for it.
677 global $CFG;
678
679 if ($log->action == "add post") {
680
ebc3bd2b 681 return get_record_sql("SELECT p.*, d.forum, u.firstname, u.lastname, u.email, u.picture
1f48942e 682 FROM {$CFG->prefix}forum_discussions d,
683 {$CFG->prefix}forum_posts p,
684 {$CFG->prefix}user u
685 WHERE p.id = '$log->info'
686 AND d.id = p.discussion
ebc3bd2b 687 AND p.userid = u.id
1f48942e 688 AND u.deleted <> '1'");
689
690
691 } else if ($log->action == "add discussion") {
692
ebc3bd2b 693 return get_record_sql("SELECT p.*, d.forum, u.firstname, u.lastname, u.email, u.picture
1f48942e 694 FROM {$CFG->prefix}forum_discussions d,
695 {$CFG->prefix}forum_posts p,
696 {$CFG->prefix}user u
697 WHERE d.id = '$log->info'
698 AND d.firstpost = p.id
ebc3bd2b 699 AND p.userid = u.id
1f48942e 700 AND u.deleted <> '1'");
701 }
702 return NULL;
703}
704
705
706function forum_get_user_grades($forumid) {
707/// Get all user grades for a forum
708 global $CFG;
709
ebc3bd2b 710 return get_records_sql("SELECT r.id, p.userid, r.rating
1f48942e 711 FROM {$CFG->prefix}forum_discussions d,
712 {$CFG->prefix}forum_posts p,
713 {$CFG->prefix}forum_ratings r
714 WHERE d.forum = '$forumid'
715 AND p.discussion = d.id
02ebf404 716 AND r.post = p.id
717 ORDER by p.userid ");
1f48942e 718}
719
720
721function forum_count_discussion_replies($forum="0") {
722// Returns an array of counts of replies to each discussion (optionally in one forum)
723 global $CFG;
724
725 if ($forum) {
726 $forumselect = " AND d.forum = '$forum'";
727 }
728 return get_records_sql("SELECT p.discussion, (count(*)) as replies
729 FROM {$CFG->prefix}forum_posts p,
730 {$CFG->prefix}forum_discussions d
731 WHERE p.parent > 0
732 AND p.discussion = d.id
733 GROUP BY p.discussion");
734}
735
736function forum_count_unrated_posts($discussionid, $userid) {
737// How many unrated posts are in the given discussion for a given user?
738 global $CFG;
739 if ($posts = get_record_sql("SELECT count(*) as num
740 FROM {$CFG->prefix}forum_posts
741 WHERE parent > 0
742 AND discussion = '$discussionid'
ebc3bd2b 743 AND userid <> '$userid' ")) {
1f48942e 744
745 if ($rated = get_record_sql("SELECT count(*) as num
746 FROM {$CFG->prefix}forum_posts p,
747 {$CFG->prefix}forum_ratings r
748 WHERE p.discussion = '$discussionid'
749 AND p.id = r.post
ebc3bd2b 750 AND r.userid = '$userid'")) {
1f48942e 751 $difference = $posts->num - $rated->num;
752 if ($difference > 0) {
753 return $difference;
754 } else {
755 return 0; // Just in case there was a counting error
756 }
757 } else {
758 return $posts->num;
759 }
760 } else {
761 return 0;
762 }
763}
764
2ab968e9 765function forum_get_discussions($forum="0", $forumsort="d.timemodified DESC", $user=0, $fullpost=true) {
1f48942e 766/// Get all discussions in a forum
767 global $CFG;
768
769 if ($user) {
770 $userselect = " AND u.id = '$user' ";
771 } else {
772 $userselect = "";
773 }
29507631 774 if (empty($forumsort)) {
775 $forumsort = "d.timemodified DESC";
776 }
2ab968e9 777 if (empty($fullpost)) {
b879effb 778 $postdata = "p.id,p.subject,p.modified,p.discussion,p.userid";
2ab968e9 779 } else {
780 $postdata = "p.*";
781 }
782 return get_records_sql("SELECT $postdata, d.timemodified, u.firstname, u.lastname, u.email, u.picture
1f48942e 783 FROM {$CFG->prefix}forum_discussions d,
784 {$CFG->prefix}forum_posts p,
785 {$CFG->prefix}user u
786 WHERE d.forum = '$forum'
787 AND p.discussion = d.id
2ab968e9 788 AND p.parent = 0
ebc3bd2b 789 AND p.userid = u.id $userselect
29507631 790 ORDER BY $forumsort");
1f48942e 791}
792
793
794
795function forum_get_user_discussions($courseid, $userid) {
796/// Get all discussions started by a particular user in a course
797 global $CFG;
798
799 return get_records_sql("SELECT p.*, u.firstname, u.lastname, u.email, u.picture,
ebc3bd2b 800 f.type as forumtype, f.name as forumname, f.id as forumid
1f48942e 801 FROM {$CFG->prefix}forum_discussions d,
802 {$CFG->prefix}forum_posts p,
803 {$CFG->prefix}user u,
804 {$CFG->prefix}forum f
805 WHERE d.course = '$courseid'
806 AND p.discussion = d.id
807 AND p.parent = 0
ebc3bd2b 808 AND p.userid = u.id
1f48942e 809 AND u.id = '$userid'
810 AND d.forum = f.id
b8bf90c5 811 ORDER BY p.created DESC");
1f48942e 812}
813
814
815function forum_subscribed_users($course, $forum) {
816/// Returns list of user objects that are subscribed to this forum
817 global $CFG;
818
adaf3928 819 if ($forum->forcesubscribe) {
820 if ($course->category) {
170a9c46 821 if ($forum->type == "teacher") {
822 return get_course_teachers($course->id); // Only teachers can be subscribed to teacher forums
823 } else {
824 return get_course_users($course->id); // Otherwise get everyone in the course
825 }
adaf3928 826 } else {
2d0b30a0 827 return get_site_users();
1f48942e 828 }
829 }
713386aa 830 return get_records_sql("SELECT u.id, u.username, u.firstname, u.lastname, u.maildisplay, u.mailformat,
0351b1f9 831 u.email, u.city, u.country, u.lastaccess, u.lastlogin, u.picture, u.timezone, u.lang
1f48942e 832 FROM {$CFG->prefix}user u,
833 {$CFG->prefix}forum_subscriptions s
834 WHERE s.forum = '$forum->id'
ebc3bd2b 835 AND s.userid = u.id
7c81b6e2 836 AND u.deleted <> 1
837 ORDER BY u.email ASC");
1f48942e 838}
9fa49e22 839
10696dc1 840function forum_get_recent_posts($sincetime, $forum="0") {
841// Returns all forum posts since a given time. If forum is specified then
842// this restricts the results
843
844 global $CFG;
845
846 if ($forum) {
847 $forumselect = " AND d.forum = '$forum'";
848 } else {
849 $forumselect = "";
850 }
851
9400ee33 852 return get_records_sql("SELECT p.*, d.name, u.id, u.firstname, u.lastname, u.picture
10696dc1 853 FROM {$CFG->prefix}forum_posts p,
854 {$CFG->prefix}forum_discussions d,
855 {$CFG->prefix}user u
856 WHERE p.modified > '$sincetime' $forumselect
857 AND p.userid = u.id
858 AND p.discussion = d.id
859 ORDER BY p.discussion ASC");
860}
861
9fa49e22 862
caadf009 863/// OTHER FUNCTIONS ///////////////////////////////////////////////////////////
f93f848a 864
865
11b0c469 866function forum_get_course_forum($courseid, $type) {
867// How to set up special 1-per-course forums
a6fcdf98 868 global $CFG;
869
29cbd93a 870 if ($forums = get_records_select("forum", "course = '$courseid' AND type = '$type'", "id ASC")) {
871 // There should always only be ONE, but with the right combination of
872 // errors there might be more. In this case, just return the oldest one (lowest ID).
873 foreach ($forums as $forum) {
874 return $forum; // ie the first one
11b0c469 875 }
8daaf761 876 }
e6874d9f 877
8daaf761 878 // Doesn't exist, so create one now.
879 $forum->course = $courseid;
880 $forum->type = "$type";
881 switch ($forum->type) {
882 case "news":
65a3ef30 883 $forum->name = addslashes(get_string("namenews", "forum"));
884 $forum->intro = addslashes(get_string("intronews", "forum"));
8daaf761 885 $forum->forcesubscribe = 1;
8daaf761 886 $forum->open = 1; // 0 - no, 1 - posts only, 2 - discuss and post
887 $forum->assessed = 0;
888 if ($site = get_site()) {
889 if ($courseid == $site->id) {
890 $forum->name = get_string("sitenews");
891 $forum->forcesubscribe = 0;
892 }
a6fcdf98 893 }
8daaf761 894 break;
895 case "social":
65a3ef30 896 $forum->name = addslashes(get_string("namesocial", "forum"));
897 $forum->intro = addslashes(get_string("introsocial", "forum"));
8daaf761 898 $forum->open = 2; // 0 - no, 1 - posts only, 2 - discuss and post
899 $forum->assessed = 0;
900 $forum->forcesubscribe = 0;
901 break;
902 case "teacher":
65a3ef30 903 $forum->name = addslashes(get_string("nameteacher", "forum"));
904 $forum->intro = addslashes(get_string("introteacher", "forum"));
8daaf761 905 $forum->open = 0; // 0 - no, 1 - posts only, 2 - discuss and post
906 $forum->assessed = 0;
907 $forum->forcesubscribe = 0;
908 break;
909 default:
910 notify("That forum type doesn't exist!");
911 return false;
912 break;
913 }
914
915 $forum->timemodified = time();
916 $forum->id = insert_record("forum", $forum);
917
918 if ($forum->type != "teacher") {
919 if (! $module = get_record("modules", "name", "forum")) {
920 notify("Could not find forum module!!");
921 return false;
922 }
923 $mod->course = $courseid;
924 $mod->module = $module->id;
925 $mod->instance = $forum->id;
926 $mod->section = 0;
927 if (! $mod->coursemodule = add_course_module($mod) ) { // assumes course/lib.php is loaded
928 notify("Could not add a new course module to the course '$course->fullname'");
929 return false;
930 }
931 if (! $sectionid = add_mod_to_section($mod) ) { // assumes course/lib.php is loaded
932 notify("Could not add the new course module to that section");
933 return false;
934 }
935 if (! set_field("course_modules", "section", $sectionid, "id", $mod->coursemodule)) {
936 notify("Could not update the course module with the correct section");
937 return false;
938 }
939 include_once("$CFG->dirroot/course/lib.php");
d769d2ee 940 rebuild_course_cache($courseid);
82aa0e8d 941 }
8daaf761 942
943 return get_record("forum", "id", "$forum->id");
82aa0e8d 944}
945
f93f848a 946
11b0c469 947function forum_make_mail_post(&$post, $user, $touser, $course,
948 $ownpost=false, $reply=false, $link=false, $rate=false, $footer="") {
501cdbd8 949// Given the data about a posting, builds up the HTML to display it and
950// returns the HTML in a string. This is designed for sending via HTML email.
951
952 global $THEME, $CFG;
953
954 $output = "";
955
956 if ($post->parent) {
72d497d4 957 $output .= '<table border="0" cellpadding="1" cellspacing="1"><tr><td bgcolor="#888888">';
958 $output .= '<table border="0" cellpadding="3" cellspacing="0">';
501cdbd8 959 } else {
72d497d4 960 $output .= '<table border="0" cellpadding="1" cellspacing="1" width="100%"><tr><td bgcolor="#888888">';
961 $output .= '<table border="0" cellpadding="3" cellspacing="0" width="100%">';
501cdbd8 962 }
963
72d497d4 964 $output .= "<tr><td bgcolor=\"$THEME->cellcontent2\" width=\"35\" valign=\"top\">";
501cdbd8 965 $output .= print_user_picture($user->id, $course->id, $user->picture, false, true);
72d497d4 966 $output .= "</td>";
501cdbd8 967
968 if ($post->parent) {
72d497d4 969 $output .= "<td nowrap bgcolor=\"$THEME->cellheading\">";
501cdbd8 970 } else {
72d497d4 971 $output .= "<td nowrap bgcolor=\"$THEME->cellheading2\">";
501cdbd8 972 }
72d497d4 973 $output .= "<p>";
974 $output .= "<font size=3><b>$post->subject</b></font><br />";
975 $output .= "<font size=2>";
976 $by->name = "<a href=\"$CFG->wwwroot/user/view.php?id=$user->id&course=$course->id\">$user->firstname $user->lastname</a>";
d62413e8 977 $by->date = userdate($post->modified, "", $touser->timezone);
ffe11640 978 $output .= get_string("bynameondate", "forum", $by);
72d497d4 979 $output .= "</font></p></td></tr>";
980 $output .= "<tr><td bgcolor=\"$THEME->cellcontent2\" width=10>";
501cdbd8 981 $output .= "&nbsp;";
72d497d4 982 $output .= "</td><td bgcolor=\"$THEME->cellcontent\">\n";
501cdbd8 983
7f6689e4 984 if ($post->attachment) {
985 $post->course = $course->id;
986 $post->forum = get_field("forum_discussions", "forum", "id", $post->discussion);
72d497d4 987 $output .= "<div align=right>";
7f6689e4 988 $output .= forum_print_attachments($post, "html");
72d497d4 989 $output .= "</div>";
7f6689e4 990 }
991
73bb0835 992 $output .= format_text($post->message, $post->format);
501cdbd8 993
72d497d4 994 $output .= "<p align=right><font size=-1>";
501cdbd8 995
2e2e71a8 996 if ($post->parent) {
ce45515e 997 $output .= "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion&parent=$post->parent\">".get_string("parent", "forum")."</a> | ";
2e2e71a8 998 }
ce45515e 999
501cdbd8 1000 $age = time() - $post->created;
1001 if ($ownpost) {
ce45515e 1002 $output .= "<a href=\"$CFG->wwwroot/mod/forum/post.php?delete=$post->id\">".get_string("delete", "forum")."</a>";
501cdbd8 1003 if ($reply) {
ce45515e 1004 $output .= " | <a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/post.php?reply=$post->id\">".get_string("reply", "forum")."</a>";
501cdbd8 1005 }
1006 $output .= "&nbsp;&nbsp;";
1007 } else {
1008 if ($reply) {
ce45515e 1009 $output .= "<a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/post.php?reply=$post->id\">".get_string("reply", "forum")."</a>&nbsp;&nbsp;";
501cdbd8 1010 }
1011 }
1012
72d497d4 1013 $output .= "</p>";
1014 $output .= "<div align=right><p align=right>";
501cdbd8 1015
1016 if ($link) {
1017 if ($post->replies == 1) {
ffe11640 1018 $replystring = get_string("repliesone", "forum", $post->replies);
501cdbd8 1019 } else {
ffe11640 1020 $replystring = get_string("repliesmany", "forum", $post->replies);
501cdbd8 1021 }
72d497d4 1022 $output .= "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\"><B>".get_string("discussthistopic", "forum")."</b></a> ($replystring)&nbsp;&nbsp;";
501cdbd8 1023 }
72d497d4 1024 $output .= "</p></div>";
501cdbd8 1025 if ($footer) {
72d497d4 1026 $output .= "<p>$footer</p>";
501cdbd8 1027 }
72d497d4 1028 $output .= "</td></tr></table>\n";
1029 $output .= "</td></tr></table>\n\n";
501cdbd8 1030
1031 return $output;
1032}
1033
1034
98914efd 1035function forum_print_post(&$post, $courseid, $ownpost=false, $reply=false, $link=false,
1036 $ratings=NULL, $footer="", $highlight="") {
c585fa17 1037 global $THEME, $USER, $CFG;
501cdbd8 1038
2e2e71a8 1039 static $stredit, $strdelete, $strreply, $strparent, $threadedmode;
1040
1041 if (empty($stredit)) {
1042 $stredit = get_string("edit", "forum");
1043 $strdelete = get_string("delete", "forum");
1044 $strreply = get_string("reply", "forum");
1045 $strparent = get_string("parent", "forum");
1046 $threadedmode = (!empty($USER->mode) and ($USER->mode == FORUM_MODE_THREADED));
1047 }
1048
b22b0e61 1049 echo "<a name=\"$post->id\"></a>";
501cdbd8 1050 if ($post->parent) {
72d497d4 1051 echo '<table border="0" cellpadding="3" cellspacing="0" class="forumpost">';
501cdbd8 1052 } else {
72d497d4 1053 echo '<table border="0" cellpadding="3" cellspacing="0" class="forumpost" width="100%">';
501cdbd8 1054 }
1055
72d497d4 1056 echo "<tr><td bgcolor=\"$THEME->cellcontent2\" class=\"forumpostpicture\" width=\"35\" valign=\"top\">";
501cdbd8 1057 print_user_picture($post->userid, $courseid, $post->picture);
72d497d4 1058 echo "</td>";
501cdbd8 1059
1060 if ($post->parent) {
834f1c7f 1061 echo "<td bgcolor=\"$THEME->cellheading\" class=\"forumpostheader\" width=\"100%\">";
501cdbd8 1062 } else {
834f1c7f 1063 echo "<td bgcolor=\"$THEME->cellheading2\" class=\"forumpostheadertopic\" width=\"100%\">";
501cdbd8 1064 }
72d497d4 1065 echo "<p>";
834f1c7f 1066 echo "<font size=3><b>$post->subject</b></font><br \>";
1067 echo "<font size=2>";
72d497d4 1068 $by->name = "<a href=\"$CFG->wwwroot/user/view.php?id=$post->userid&course=$courseid\">$post->firstname $post->lastname</a>";
d62413e8 1069 $by->date = userdate($post->modified);
ffe11640 1070 print_string("bynameondate", "forum", $by);
72d497d4 1071 echo "</font></p></td></tr>";
1072 echo "<tr><td bgcolor=\"$THEME->cellcontent2\" class=\"forumpostside\" width=\"10\">";
501cdbd8 1073 echo "&nbsp;";
72d497d4 1074 echo "</td><td bgcolor=\"$THEME->cellcontent\" class=\"forumpostmessage\">\n";
501cdbd8 1075
7f6689e4 1076 if ($post->attachment) {
1077 $post->course = $courseid;
1078 $post->forum = get_field("forum_discussions", "forum", "id", $post->discussion);
72d497d4 1079 echo "<div align=\"right\">";
1080 $attachedimages = forum_print_attachments($post);
1081 echo "</div>";
e9c2dc1f 1082 } else {
1083 $attachedimages = "";
7f6689e4 1084 }
1085
5be7800c 1086 if ($link and (strlen(strip_tags($post->message)) > $CFG->forum_longpost)) {
aa153f29 1087 // Print shortened version
73bb0835 1088 echo format_text(forum_shorten_post($post->message), $post->format);
c585fa17 1089 $numwords = count_words(strip_tags($post->message));
72d497d4 1090 echo "<p><a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\">";
ffe11640 1091 echo get_string("readtherest", "forum");
72d497d4 1092 echo "</a> (".get_string("numwords", "", $numwords).")...</p>";
501cdbd8 1093 } else {
aa153f29 1094 // Print whole message
88438a58 1095 if ($highlight) {
1096 echo highlight($highlight, format_text($post->message, $post->format));
1097 } else {
1098 echo format_text($post->message, $post->format);
1099 }
c99ce77b 1100 echo $attachedimages;
501cdbd8 1101 }
1102
72d497d4 1103 echo "<p align=right><font size=-1>";
501cdbd8 1104
2e2e71a8 1105 if ($post->parent) {
1106 if ($threadedmode) {
1107 echo "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion&parent=$post->parent\">$strparent</a> | ";
1108 } else {
1109 echo "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion#$post->parent\">$strparent</a> | ";
1110 }
1111 }
1112
501cdbd8 1113 $age = time() - $post->created;
1114 if ($ownpost) {
1115 if ($age < $CFG->maxeditingtime) {
2e2e71a8 1116 echo "<a href=\"$CFG->wwwroot/mod/forum/post.php?edit=$post->id\">$stredit</a> | ";
501cdbd8 1117 }
64eacd6f 1118 }
1119 if ($ownpost or isteacher($courseid)) {
2e2e71a8 1120 echo "<a href=\"$CFG->wwwroot/mod/forum/post.php?delete=$post->id\">$strdelete</a>";
501cdbd8 1121 if ($reply) {
64eacd6f 1122 echo "| ";
1123 } else {
1124 echo "&nbsp;&nbsp;";
501cdbd8 1125 }
64eacd6f 1126 }
1127 if ($reply) {
2e2e71a8 1128 echo "<a href=\"$CFG->wwwroot/mod/forum/post.php?reply=$post->id\">$strreply</a>";
501cdbd8 1129 echo "&nbsp;&nbsp;";
501cdbd8 1130 }
72d497d4 1131 echo "</p>";
501cdbd8 1132
72d497d4 1133 echo "<div align=right><p align=right>";
02ebf404 1134 if (!empty($ratings) and !empty($USER->id)) {
98914efd 1135 $useratings = true;
1136 if ($ratings->assesstimestart and $ratings->assesstimefinish) {
1137 if ($post->created < $ratings->assesstimestart or $post->created > $ratings->assesstimefinish) {
1138 $useratings = false;
1139 }
1140 }
1141 if ($useratings) {
1142 if (isteacher($courseid)) {
1143 forum_print_ratings_mean($post->id, $ratings->scale);
1144 if ($USER->id != $post->userid) {
1145 forum_print_rating_menu($post->id, $USER->id, $ratings->scale);
1146 }
1147 } else if ($USER->id == $post->userid) {
1148 forum_print_ratings_mean($post->id, $ratings->scale);
1149 } else if (!empty($ratings->allow) ) {
1150 forum_print_rating_menu($post->id, $USER->id, $ratings->scale);
2a3cda19 1151 }
501cdbd8 1152 }
1153 }
1154
1155 if ($link) {
1156 if ($post->replies == 1) {
ffe11640 1157 $replystring = get_string("repliesone", "forum", $post->replies);
501cdbd8 1158 } else {
ffe11640 1159 $replystring = get_string("repliesmany", "forum", $post->replies);
501cdbd8 1160 }
72d497d4 1161 echo "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\"><b>".get_string("discussthistopic", "forum")."</b></a> ($replystring)&nbsp;&nbsp;";
501cdbd8 1162 }
72d497d4 1163 echo "</p>";
501cdbd8 1164 if ($footer) {
72d497d4 1165 echo "<p>$footer</p>";
501cdbd8 1166 }
72d497d4 1167 echo "</div>";
1168 echo "</td></tr>\n</table>\n\n";
501cdbd8 1169}
1170
3335f6fb 1171
2ab968e9 1172function forum_print_discussion_header(&$post, $courseid, $datestring="") {
c585fa17 1173 global $THEME, $USER, $CFG;
3335f6fb 1174
29507631 1175 echo "<tr class=\"forumpostheader\">";
3335f6fb 1176
29507631 1177 // Topic
546be6dd 1178 echo "<td bgcolor=\"$THEME->cellheading2\" class=\"forumpostheadertopic\" width=\"100%\">";
29507631 1179 echo "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\">$post->subject</a>";
1180 echo "</td>\n";
1181
1182 // Picture
96e301a7 1183 echo "<td bgcolor=\"$THEME->cellcontent2\" class=\"forumpostheaderpicture\" width=35>";
3335f6fb 1184 print_user_picture($post->userid, $courseid, $post->picture);
29507631 1185 echo "</td>\n";
3335f6fb 1186
29507631 1187 // User name
96e301a7 1188 echo "<td bgcolor=\"$THEME->cellcontent2\" class=\"forumpostheadername\" align=left nowrap>";
29507631 1189 echo "<a href=\"$CFG->wwwroot/user/view.php?id=$post->userid&course=$courseid\">$post->firstname $post->lastname</a>";
1190 echo "</td>\n";
1191
1192 // Replies
96e301a7 1193 echo "<td bgcolor=\"$THEME->cellcontent2\" class=\"forumpostheaderreplies\" align=center nowrap>";
2ab968e9 1194 echo "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\">$post->replies</a>";
29507631 1195 echo "</td>\n";
3335f6fb 1196
96e301a7 1197 echo "<td bgcolor=\"$THEME->cellcontent2\" class=\"forumpostheaderdate\" align=right nowrap>";
29507631 1198 if (!empty($post->timemodified)) {
2ab968e9 1199 echo userdate($post->timemodified, $datestring);
3335f6fb 1200 } else {
2ab968e9 1201 echo userdate($post->modified, $datestring);
3335f6fb 1202 }
29507631 1203 echo "</td>\n";
1204
1205 echo "</tr>\n";
3335f6fb 1206
3335f6fb 1207}
1208
1209
aa153f29 1210function forum_shorten_post($message) {
c585fa17 1211// Given a post object that we already know has a long message
1212// this function truncates the message nicely to the first
5be7800c 1213// sane place between $CFG->forum_longpost and $CFG->forum_shortpost
1214
1215 global $CFG;
c585fa17 1216
1217 $i = 0;
1218 $tag = false;
1219 $length = strlen($message);
1220 $count = 0;
1221 $stopzone = false;
1222 $truncate = 0;
1223
1224 for ($i=0; $i<$length; $i++) {
a8afb411 1225 $char = $message[$i];
c585fa17 1226
1227 switch ($char) {
1228 case "<":
1229 $tag = true;
1230 break;
1231 case ">":
1232 $tag = false;
1233 break;
1234 default:
1235 if (!$tag) {
1236 if ($stopzone) {
67f0b4cc 1237 if ($char == ".") {
a8afb411 1238 $truncate = $i+1;
c585fa17 1239 break 2;
1240 }
1241 }
1242 $count++;
1243 }
a8afb411 1244 break;
c585fa17 1245 }
1246 if (!$stopzone) {
5be7800c 1247 if ($count > $CFG->forum_shortpost) {
c585fa17 1248 $stopzone = true;
1249 }
1250 }
1251 }
aa153f29 1252
c585fa17 1253 if (!$truncate) {
a8afb411 1254 $truncate = $i;
c585fa17 1255 }
1256
67f0b4cc 1257 return substr($message, 0, $truncate);
aa153f29 1258}
1259
501cdbd8 1260
0761d83f 1261function forum_print_ratings_mean($postid, $scale) {
02ebf404 1262/// Print the multiple ratings on a post given to the current user by others.
1263/// Scale is an array of ratings
1264
1265 static $strrate;
05c47ef7 1266
1267 $mean = forum_get_ratings_mean($postid, $scale);
02ebf404 1268
05c47ef7 1269 if ($mean !== "") {
02ebf404 1270
1271 if (empty($strratings)) {
1272 $strratings = get_string("ratings", "forum");
501cdbd8 1273 }
501cdbd8 1274
02ebf404 1275 echo "$strratings: ";
0761d83f 1276 link_to_popup_window ("/mod/forum/report.php?id=$postid", "ratings", $mean, 400, 600);
501cdbd8 1277 }
1278}
1279
501cdbd8 1280
0761d83f 1281function forum_get_ratings_mean($postid, $scale, $ratings=NULL) {
1282/// Return the mean rating of a post given to the current user by others.
02ebf404 1283/// Scale is an array of possible ratings in the scale
1284/// Ratings is an optional simple array of actual ratings (just integers)
1285
1286 if (!$ratings) {
1287 $ratings = array();
1288 if ($rates = get_records("forum_ratings", "post", $postid)) {
1289 foreach ($rates as $rate) {
1290 $ratings[] = $rate->rating;
1291 }
501cdbd8 1292 }
501cdbd8 1293 }
02ebf404 1294
0761d83f 1295 $count = count($ratings);
1296
1297 if ($count == 0) {
02ebf404 1298 return "";
02ebf404 1299
0761d83f 1300 } else if ($count == 1) {
1301 return $scale[$ratings[0]];
1302
02ebf404 1303 } else {
0761d83f 1304 $total = 0;
1305 foreach ($ratings as $rating) {
1306 $total += $rating;
1307 }
1308 $mean = round( ((float)$total/(float)$count) + 0.001); // Little fudge factor so that 0.5 goes UP
1309
1310 if (isset($scale[$mean])) {
1311 return $scale[$mean]." ($count)";
1312 } else {
1313 return "$mean ($count)"; // Should never happen, hopefully
1314 }
02ebf404 1315 }
1316}
1317
1318function forum_get_ratings_summary($postid, $scale, $ratings=NULL) {
1319/// Return a summary of post ratings given to the current user by others.
1320/// Scale is an array of possible ratings in the scale
1321/// Ratings is an optional simple array of actual ratings (just integers)
1322
1323 if (!$ratings) {
1324 $ratings = array();
1325 if ($rates = get_records("forum_ratings", "post", $postid)) {
1326 foreach ($rates as $rate) {
1327 $rating[] = $rate->rating;
1328 }
1329 }
1330 }
1331
1332
1333 if (!$count = count($ratings)) {
1334 return "";
1335 }
1336
1337
1338 foreach ($scale as $key => $scaleitem) {
1339 $sumrating[$key] = 0;
1340 }
1341
1342 foreach ($ratings as $rating) {
1343 $sumrating[$rating]++;
1344 }
1345
1346 $summary = "";
1347 foreach ($scale as $key => $scaleitem) {
1348 $summary = $sumrating[$key].$summary;
1349 if ($key > 1) {
1350 $summary = "/$summary";
1351 }
1352 }
1353 return $summary;
1354}
1355
1356function forum_print_rating_menu($postid, $userid, $scale) {
1357/// Print the menu of ratings as part of a larger form.
1358/// If the post has already been - set that value.
1359/// Scale is an array of ratings
1360
1361 static $strrate;
1362
1363 if (!$rating = get_record("forum_ratings", "userid", $userid, "post", $postid)) {
1364 $rating->rating = 0;
1365 }
1366
1367 if (empty($strrate)) {
1368 $strrate = get_string("rate", "forum");
1369 }
1370
1371 choose_from_menu($scale, $postid, $rating->rating, "$strrate...");
501cdbd8 1372}
1373
7a12aab4 1374function forum_print_mode_form($discussion, $mode) {
1375 GLOBAL $FORUM_LAYOUT_MODES;
501cdbd8 1376
8b9c7aa0 1377 echo "<center><p>";
7a12aab4 1378 popup_form("discuss.php?d=$discussion&mode=", $FORUM_LAYOUT_MODES, "mode", $mode, "");
8b9c7aa0 1379 echo "</p></center>\n";
501cdbd8 1380}
1381
97485d07 1382function forum_print_search_form($course, $search="", $return=false, $type="") {
501cdbd8 1383 global $CFG;
1384
97485d07 1385 if ($type == "plain") {
8b9c7aa0 1386 $output = "<table border=0 cellpadding=0 cellspacing=0><tr><td nowrap>";
1387 $output .= "<form name=search action=\"$CFG->wwwroot/mod/forum/search.php\">";
1388 $output .= "<font size=\"-1\">";
1389 $output .= "<input name=search type=text size=20 value=\"$search\">";
1390 $output .= "<input value=\"".get_string("searchforums", "forum")."\" type=submit>";
1391 $output .= "</font>";
1392 $output .= "<input name=id type=hidden value=\"$course->id\">";
1393 $output .= "</form>";
1394 $output .= "</td></tr></table>";
97485d07 1395 } else {
8b9c7aa0 1396 $output = "<table border=0 cellpadding=10 cellspacing=0><tr><td align=center>";
1397 $output .= "<form name=search action=\"$CFG->wwwroot/mod/forum/search.php\">";
1398 $output .= "<font size=\"-1\">";
1399 $output .= "<input name=search type=text size=20 value=\"$search\"><br>";
1400 $output .= "<input value=\"".get_string("searchforums", "forum")."\" type=submit>";
1401 $output .= "</font>";
1402 $output .= "<input name=id type=hidden value=\"$course->id\">";
1403 $output .= "</form>";
1404 $output .= "</td></tr></table>";
97485d07 1405 }
5e367a2d 1406
1407 if ($return) {
1408 return $output;
1409 }
1410 echo $output;
501cdbd8 1411}
1412
1413
11b0c469 1414function forum_set_return() {
607809b3 1415 global $CFG, $SESSION;
501cdbd8 1416
28e1e8b9 1417 if (! isset($SESSION->fromdiscussion)) {
48d38fad 1418 if (!empty($_SERVER['HTTP_REFERER'])) {
1419 $referer = $_SERVER['HTTP_REFERER'];
1420 } else {
1421 $referer = "";
1422 }
28e1e8b9 1423 // If the referer is NOT a login screen then save it.
48d38fad 1424 if (! strncasecmp("$CFG->wwwroot/login", $referer, 300)) {
607809b3 1425 $SESSION->fromdiscussion = $_SERVER["HTTP_REFERER"];
28e1e8b9 1426 }
501cdbd8 1427 }
1428}
1429
1430
11b0c469 1431function forum_go_back_to($default) {
501cdbd8 1432 global $SESSION;
1433
9c9f7d77 1434 if (!empty($SESSION->fromdiscussion)) {
501cdbd8 1435 $returnto = $SESSION->fromdiscussion;
1436 unset($SESSION->fromdiscussion);
1437 return $returnto;
1438 } else {
1439 return $default;
1440 }
1441}
1442
7f6689e4 1443function forum_file_area_name($post) {
1444// Creates a directory file name, suitable for make_upload_directory()
1445 global $CFG;
1446
1447 return "$post->course/$CFG->moddata/forum/$post->forum/$post->id";
1448}
1449
1450function forum_file_area($post) {
1451 return make_upload_directory( forum_file_area_name($post) );
1452}
1453
1454function forum_delete_old_attachments($post, $exception="") {
1455// Deletes all the user files in the attachments area for a post
1456// EXCEPT for any file named $exception
1457
1458 if ($basedir = forum_file_area($post)) {
1459 if ($files = get_directory_list($basedir)) {
1460 foreach ($files as $file) {
1461 if ($file != $exception) {
1462 unlink("$basedir/$file");
1463 notify("Existing file '$file' has been deleted!");
1464 }
1465 }
1466 }
1467 if (!$exception) { // Delete directory as well, if empty
1468 rmdir("$basedir");
1469 }
1470 }
1471}
1472
cc2b7ea5 1473function forum_move_attachments($discussion, $forumid) {
1474/// Given a discussion object that is being moved to forumid,
1475/// this function checks all posts in that discussion
1476/// for attachments, and if any are found, these are
1477/// moved to the new forum directory.
1478
1479 global $CFG;
1480
1481 $return = true;
1482
1483 if ($posts = get_records_select("forum_posts", "discussion = '$discussion->id' AND attachment <> ''")) {
1484 foreach ($posts as $oldpost) {
1485 $oldpost->course = $discussion->course;
1486 $oldpost->forum = $discussion->forum;
1487 $oldpostdir = "$CFG->dataroot/".forum_file_area_name($oldpost);
1488 if (is_dir($oldpostdir)) {
1489 $newpost = $oldpost;
1490 $newpost->forum = $forumid;
1491 $newpostdir = "$CFG->dataroot/".forum_file_area_name($newpost);
1492 if (! @rename($oldpostdir, $newpostdir)) {
1493 $return = false;
1494 }
1495 }
1496 }
1497 }
1498 return $return;
1499}
1500
7f6689e4 1501function forum_print_attachments($post, $return=NULL) {
1502// if return=html, then return a html string.
1503// if return=text, then return a text-only string.
72d497d4 1504// otherwise, print HTML for non-images, and return image HTML
7f6689e4 1505
1506 global $CFG;
1507
1508 $filearea = forum_file_area_name($post);
1509
72d497d4 1510 $imagereturn = "";
1511 $output = "";
1512
7f6689e4 1513 if ($basedir = forum_file_area($post)) {
1514 if ($files = get_directory_list($basedir)) {
1515 $strattachment = get_string("attachment", "forum");
6afe8558 1516 $strpopupwindow = get_string("popupwindow");
7f6689e4 1517 foreach ($files as $file) {
1518 $icon = mimeinfo("icon", $file);
1519 if ($CFG->slasharguments) {
1520 $ffurl = "file.php/$filearea/$file";
1521 } else {
1522 $ffurl = "file.php?file=/$filearea/$file";
1523 }
6afe8558 1524 $image = "<img border=0 src=\"$CFG->wwwroot/files/pix/$icon\" height=16 width=16 alt=\"$strpopupwindow\">";
7f6689e4 1525
1526 if ($return == "html") {
6afe8558 1527 $output .= "<a href=\"$CFG->wwwroot/$ffurl\">$image</a> ";
1528 $output .= "<a href=\"$CFG->wwwroot/$ffurl\">$file</a><br />";
7f6689e4 1529
1530 } else if ($return == "text") {
1531 $output .= "$strattachment $file:\n$CFG->wwwroot/$ffurl\n";
1532
1533 } else {
72d497d4 1534 if ($icon == "image.gif") { // Image attachments don't get printed as links
1535 $imagereturn .= "<br /><img src=\"$CFG->wwwroot/$ffurl\">";
1536 } else {
1537 link_to_popup_window("/$ffurl", "attachment", $image, 500, 500, $strattachment);
1538 echo "<a href=\"$CFG->wwwroot/$ffurl\">$file</a>";
1539 echo "<br />";
1540 }
7f6689e4 1541 }
1542 }
1543 }
1544 }
72d497d4 1545
7f6689e4 1546 if ($return) {
1547 return $output;
1548 }
72d497d4 1549
1550 return $imagereturn;
7f6689e4 1551}
1552
1553function forum_add_attachment($post, $newfile) {
1554// $post is a full post record, including course and forum
3b7c1de9 1555// $newfile is a full upload array from $_FILES
7f6689e4 1556// If successful, this function returns the name of the file
1557
9dd0b378 1558 global $CFG;
1559
3b7c1de9 1560 if (empty($newfile['name'])) {
7f6689e4 1561 return "";
1562 }
1563
1564 $newfile_name = clean_filename($newfile['name']);
1565
1566 if (valid_uploaded_file($newfile)) {
1567 if (! $newfile_name) {
1568 notify("This file had a wierd filename and couldn't be uploaded");
1569
1570 } else if (! $dir = forum_file_area($post)) {
1571 notify("Attachment could not be stored");
1572 $newfile_name = "";
1573
1574 } else {
1575 if (move_uploaded_file($newfile['tmp_name'], "$dir/$newfile_name")) {
9dd0b378 1576 chmod("$dir/$newfile_name", $CFG->directorypermissions);
7f6689e4 1577 forum_delete_old_attachments($post, $newfile_name);
1578 } else {
1579 notify("An error happened while saving the file on the server");
1580 $newfile_name = "";
1581 }
1582 }
1583 } else {
1584 $newfile_name = "";
1585 }
1586
1587 return $newfile_name;
1588}
501cdbd8 1589
11b0c469 1590function forum_add_new_post($post) {
501cdbd8 1591
ffe11640 1592 $post->created = $post->modified = time();
501cdbd8 1593 $post->mailed = "0";
1594
7f6689e4 1595 $newfile = $post->attachment;
1596 $post->attachment = "";
1597
1598 if (! $post->id = insert_record("forum_posts", $post)) {
1599 return false;
1600 }
1601
1602 if ($post->attachment = forum_add_attachment($post, $newfile)) {
1603 set_field("forum_posts", "attachment", $post->attachment, "id", $post->id);
1604 }
29507631 1605
1606 // Update discussion modified date
1607 set_field("forum_discussions", "timemodified", $post->modified, "id", $post->discussion);
7f6689e4 1608
1609 return $post->id;
501cdbd8 1610}
1611
11b0c469 1612function forum_update_post($post) {
501cdbd8 1613
ffe11640 1614 $post->modified = time();
501cdbd8 1615
0ab85112 1616 if (!$post->parent) { // Post is a discussion starter - update discussion title too
1617 set_field("forum_discussions", "name", $post->subject, "id", $post->discussion);
1618 }
29507631 1619
7f6689e4 1620 if ($newfilename = forum_add_attachment($post, $post->attachment)) {
1621 $post->attachment = $newfilename;
1622 } else {
1623 unset($post->attachment);
1624 }
29507631 1625
1626 // Update discussion modified date
1627 set_field("forum_discussions", "timemodified", $post->modified, "id", $post->discussion);
1628
ffe11640 1629 return update_record("forum_posts", $post);
501cdbd8 1630}
1631
1632function forum_add_discussion($discussion) {
1633// Given an object containing all the necessary data,
1634// create a new discussion and return the id
1635
1636 GLOBAL $USER;
1637
1638 $timenow = time();
1639
1640 // The first post is stored as a real post, and linked
1641 // to from the discuss entry.
1642
1643 $post->discussion = 0;
1644 $post->parent = 0;
ebc3bd2b 1645 $post->userid = $USER->id;
501cdbd8 1646 $post->created = $timenow;
1647 $post->modified = $timenow;
1648 $post->mailed = 0;
1649 $post->subject = $discussion->name;
1650 $post->message = $discussion->intro;
7f6689e4 1651 $post->attachment = "";
1652 $post->forum = $discussion->forum;
1653 $post->course = $discussion->course;
9f0b8269 1654 $post->format = $discussion->format;
501cdbd8 1655
1656 if (! $post->id = insert_record("forum_posts", $post) ) {
1657 return 0;
1658 }
1659
7f6689e4 1660 if ($post->attachment = forum_add_attachment($post, $discussion->attachment)) {
1661 set_field("forum_posts", "attachment", $post->attachment, "id", $post->id); //ignore errors
1662 }
1663
caadf009 1664 // Now do the real module entry
04eba58f 1665
caadf009 1666 $discussion->firstpost = $post->id;
1667 $discussion->timemodified = $timenow;
04eba58f 1668
caadf009 1669 if (! $discussion->id = insert_record("forum_discussions", $discussion) ) {
1670 delete_records("forum_posts", "id", $post->id);
1671 return 0;
04eba58f 1672 }
1673
caadf009 1674 // Finally, set the pointer on the post.
1675 if (! set_field("forum_posts", "discussion", $discussion->id, "id", $post->id)) {
1676 delete_records("forum_posts", "id", $post->id);
1677 delete_records("forum_discussions", "id", $discussion->id);
1678 return 0;
04eba58f 1679 }
04eba58f 1680
caadf009 1681 return $discussion->id;
1682}
04eba58f 1683
04eba58f 1684
caadf009 1685function forum_delete_discussion($discussion) {
1686// $discussion is a discussion record object
04eba58f 1687
1688 $result = true;
1689
caadf009 1690 if ($posts = get_records("forum_posts", "discussion", $discussion->id)) {
1691 foreach ($posts as $post) {
1692 $post->course = $discussion->course;
1693 $post->forum = $discussion->forum;
1694 if (! delete_records("forum_ratings", "post", "$post->id")) {
1695 $result = false;
1696 }
1697 if (! forum_delete_post($post)) {
04eba58f 1698 $result = false;
1699 }
1700 }
1701 }
1702
caadf009 1703 if (! delete_records("forum_discussions", "id", "$discussion->id")) {
04eba58f 1704 $result = false;
1705 }
1706
1707 return $result;
1708}
1709
1710
caadf009 1711function forum_delete_post($post) {
1712 if (delete_records("forum_posts", "id", $post->id)) {
1713 delete_records("forum_ratings", "post", $post->id); // Just in case
1714 if ($post->attachment) {
1715 $discussion = get_record("forum_discussions", "id", $post->discussion);
1716 $post->course = $discussion->course;
1717 $post->forum = $discussion->forum;
1718 forum_delete_old_attachments($post);
1719 }
1720 return true;
1721 }
1722 return false;
1723}
501cdbd8 1724
501cdbd8 1725
caadf009 1726function forum_print_user_discussions($courseid, $userid) {
1727 global $CFG, $USER;
501cdbd8 1728
b8bf90c5 1729 $maxdiscussions = 10;
1730 $countdiscussions = 0;
1731
1f48942e 1732
1733 if ($discussions = forum_get_user_discussions($courseid, $userid)) {
caadf009 1734 $user = get_record("user", "id", $userid);
1735 echo "<HR>";
b8bf90c5 1736 print_heading( get_string("discussionsstartedbyrecent", "forum", "$user->firstname $user->lastname") );
caadf009 1737 $replies = forum_count_discussion_replies();
1738 foreach ($discussions as $discussion) {
b8bf90c5 1739 $countdiscussions++;
1740 if ($countdiscussions > $maxdiscussions) {
1741 break;
1742 }
caadf009 1743 if (($discussion->forumtype == "teacher") and !isteacher($courseid)) {
ffe11640 1744 continue;
1745 }
47f1da80 1746 if (!empty($replies[$discussion->discussion])) {
caadf009 1747 $discussion->replies = $replies[$discussion->discussion]->replies;
1748 } else {
1749 $discussion->replies = 0;
501cdbd8 1750 }
caadf009 1751 $inforum = get_string("inforum", "forum", "<A HREF=\"$CFG->wwwroot/mod/forum/view.php?f=$discussion->forumid\">$discussion->forumname</A>");
1752 $discussion->subject .= " ($inforum)";
61e96406 1753 if (!empty($USER->id)) {
1754 $ownpost = ($discussion->userid == $USER->id);
1755 } else {
1756 $ownpost = false;
1757 }
caadf009 1758 forum_print_post($discussion, $courseid, $ownpost, $reply=0, $link=1, $assessed=false);
1759 echo "<BR>\n";
501cdbd8 1760 }
1761 }
501cdbd8 1762}
1763
501cdbd8 1764function forum_forcesubscribe($forumid, $value=1) {
1765 return set_field("forum", "forcesubscribe", $value, "id", $forumid);
1766}
1767
1768function forum_is_forcesubscribed($forumid) {
1769 return get_field("forum", "forcesubscribe", "id", $forumid);
1770}
1771
1772function forum_is_subscribed($userid, $forumid) {
1773 if (forum_is_forcesubscribed($forumid)) {
1774 return true;
1775 }
ebc3bd2b 1776 return record_exists("forum_subscriptions", "userid", $userid, "forum", $forumid);
86970225 1777}
1778
501cdbd8 1779function forum_subscribe($userid, $forumid) {
9fa49e22 1780/// Adds user to the subscriber list
1781
ebc3bd2b 1782 $sub->userid = $userid;
9fa49e22 1783 $sub->forum = $forumid;
501cdbd8 1784
9fa49e22 1785 return insert_record("forum_subscriptions", $sub);
501cdbd8 1786}
1787
1788function forum_unsubscribe($userid, $forumid) {
9fa49e22 1789/// Removes user from the subscriber list
ebc3bd2b 1790 return delete_records("forum_subscriptions", "userid", $userid, "forum", $forumid);
501cdbd8 1791}
1792
0a9f61b5 1793function forum_post_subscription($post) {
1794/// Given a new post, subscribes or unsubscribes as appropriate.
1795/// Returns some text which describes what happened.
1796
1797 global $USER;
1798
1799 if (empty($post->subscribe) and empty($post->unsubscribe)) {
1800 return "";
1801 }
1802
1803 if (!$forum = get_record("forum", "id", $post->forum)) {
1804 return "";
1805 }
1806
1807 $info->name = "$USER->firstname $USER->lastname";
1808 $info->forum = $forum->name;
1809
1810 if (!empty($post->subscribe)) {
1811 forum_subscribe($USER->id, $post->forum);
1812 return "<p>".get_string("nowsubscribed", "forum", $info)."</p>";
1813 }
1814
1815 forum_unsubscribe($USER->id, $post->forum);
1816 return "<p>".get_string("nownotsubscribed", "forum", $info)."</p>";
1817}
1818
501cdbd8 1819
11b0c469 1820function forum_user_has_posted_discussion($forumid, $userid) {
29507631 1821 if ($discussions = forum_get_discussions($forumid, "", $userid)) {
501cdbd8 1822 return true;
1823 } else {
1824 return false;
1825 }
1826}
1827
11b0c469 1828function forum_user_can_post_discussion($forum) {
501cdbd8 1829// $forum is an object
1830 global $USER;
1831
1832 if ($forum->type == "eachuser") {
11b0c469 1833 return (! forum_user_has_posted_discussion($forum->id, $USER->id));
501cdbd8 1834 } else if ($forum->type == "teacher") {
1835 return isteacher($forum->course);
1836 } else if (isteacher($forum->course)) {
1837 return true;
1838 } else {
70c476a7 1839 return ($forum->open == 2);
501cdbd8 1840 }
1841}
1842
f690562f 1843function forum_user_can_post($forum, $user=NULL) {
1844// $forum, $user are objects
1845
1846 if ($user) {
1847 $isteacher = isteacher($forum->course, $user->id);
1848 } else {
1849 $isteacher = isteacher($forum->course);
1850 }
70c476a7 1851
1852 if ($forum->type == "teacher") {
f690562f 1853 return $isteacher;
1854 } else if ($isteacher) {
70c476a7 1855 return true;
1856 } else {
1857 return $forum->open;
1858 }
1859}
501cdbd8 1860
501cdbd8 1861
29507631 1862function forum_print_latest_discussions($forum_id=0, $forum_numdiscussions=5, $forum_style="plain", $forum_sort="") {
c585fa17 1863 global $CFG, $USER;
f93f848a 1864
1865 if ($forum_id) {
1866 if (! $forum = get_record("forum", "id", $forum_id)) {
1867 error("Forum ID was incorrect");
1868 }
1869 if (! $course = get_record("course", "id", $forum->course)) {
1870 error("Could not find the course this forum belongs to!");
1871 }
1872
1873 if ($course->category) {
1874 require_login($course->id);
1875 }
1876
1877 } else {
1878 if (! $course = get_record("course", "category", 0)) {
1879 error("Could not find a top-level course!");
1880 }
7beb45d8 1881 if (! $forum = forum_get_course_forum($course->id, "news")) {
f93f848a 1882 error("Could not find or create a main forum in this course (id $course->id)");
1883 }
1884 }
1885
11b0c469 1886 if (forum_user_can_post_discussion($forum)) {
b879effb 1887 echo "<p align=center>";
1888 echo "<a href=\"$CFG->wwwroot/mod/forum/post.php?forum=$forum->id\">";
0351b1f9 1889 if ($forum->type == "news") {
1890 echo get_string("addanewtopic", "forum")."</a>...";
1891 } else {
1892 echo get_string("addanewdiscussion", "forum")."</a>...";
1893 }
b879effb 1894 echo "</p>\n";
77305fe6 1895 }
1896
3c8a606d 1897 if ((!$forum_numdiscussions) && ($forum_style == "plain")) {
1898 $forum_style = "header"; // Abbreviate display by default
3335f6fb 1899 }
f93f848a 1900
2ab968e9 1901 if ($forum_style == "minimal") {
1902 $forum_sort = "p.modified DESC";
1903 }
1904
1905 $fullpost = false;
1906 if ($forum_style == "plain") {
1907 $fullpost = true;
1908 }
1909
1910 if (! $discussions = forum_get_discussions($forum->id, $forum_sort, 0, $fullpost) ) {
0351b1f9 1911 if ($forum->type == "news") {
1912 echo "<p align=center><b>(".get_string("nonews", "forum").")</b></p>";
1913 } else {
1914 echo "<p align=center><b>(".get_string("nodiscussions", "forum").")</b></p>";
1915 }
2ab968e9 1916 return;
1917 }
1918
3335f6fb 1919 $replies = forum_count_discussion_replies($forum->id);
f93f848a 1920
3260de67 1921 $canreply = forum_user_can_post($forum);
1922
3335f6fb 1923 $discussioncount = 0;
c20b762a 1924 $olddiscussionlink = false;
2ab968e9 1925 $strdatestring = get_string("strftimedaydatetime");
f93f848a 1926
dcde9f02 1927 if ($forum_style == "minimal") {
1928 $strftimerecent = get_string("strftimerecent");
1929 $strmore = get_string("more", "forum");
1930 }
1931
29507631 1932 if ($forum_style == "header") {
1933 echo "<table width=\"100%\" border=0 cellpadding=3 cellspacing=1 class=\"forumpost\">";
03aa0dfa 1934 echo "<tr class=\"forumpostheader\">";
9e0a08bd 1935 echo "<th>".get_string("discussion", "forum")."</th>";
29507631 1936 echo "<th colspan=2>".get_string("startedby", "forum")."</th>";
1937 echo "<th>".get_string("replies", "forum")."</th>";
1938 echo "<th>".get_string("lastpost", "forum")."</th>";
1939 echo "</tr>";
1940 }
1941
3335f6fb 1942 foreach ($discussions as $discussion) {
1943 $discussioncount++;
f93f848a 1944
3335f6fb 1945 if ($forum_numdiscussions && ($discussioncount > $forum_numdiscussions)) {
c20b762a 1946 $olddiscussionlink = true;
3335f6fb 1947 break;
1948 }
9c9f7d77 1949 if (!empty($replies[$discussion->discussion])) {
3335f6fb 1950 $discussion->replies = $replies[$discussion->discussion]->replies;
1951 } else {
1952 $discussion->replies = 0;
1953 }
f7477444 1954 if (!empty($USER->id)) {
1955 $ownpost = ($discussion->userid == $USER->id);
1956 } else {
1957 $ownpost=false;
1958 }
3335f6fb 1959 switch ($forum_style) {
1960 case "minimal":
b879effb 1961 echo "<p><font color=#555555>".userdate($discussion->modified, $strftimerecent)." - $discussion->firstname</font>";
1962 echo "<br>$discussion->subject ";
1963 echo "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$discussion->discussion\">";
1964 echo $strmore."...</a>";
1965 echo "</p>\n";
3335f6fb 1966 break;
1967 case "header":
2ab968e9 1968 forum_print_discussion_header($discussion, $forum->course, $strdatestring);
3335f6fb 1969 break;
1970 default:
3260de67 1971 if ($canreply or $discussion->replies) {
1972 $link = true;
1973 } else {
1974 $link = false;
1975 }
1976 forum_print_post($discussion, $forum->course, $ownpost, $reply=0, $link, $assessed=false);
b879effb 1977 echo "<br>\n";
3335f6fb 1978 break;
f93f848a 1979 }
1980 }
29507631 1981
1982 if ($forum_style == "header") {
1983 echo "</table>";
1984 }
c20b762a 1985
1986 if ($olddiscussionlink) {
1987 echo "<p align=right><a href=\"$CFG->wwwroot/mod/forum/view.php?f=$forum->id&showall=1\">";
1988 echo get_string("olderdiscussions", "forum")."</a> ...</p>";
1989 }
f93f848a 1990}
1991
fe25fc9b 1992function forum_print_discussion($course, $forum, $discussion, $post, $mode) {
501cdbd8 1993
1994 global $USER;
1995
61e96406 1996 if (!empty($USER->id)) {
1997 $ownpost = ($USER->id == $post->userid);
1998 } else {
1999 $ownpost = false;
2000 }
70c476a7 2001 $reply = forum_user_can_post($forum);
501cdbd8 2002
02ebf404 2003 $ratings = NULL;
61e96406 2004 if ($forum->assessed and !empty($USER->id)) {
d6bdd9d5 2005 if ($ratings->scale = make_grades_menu($forum->scale)) {
98914efd 2006 $ratings->assesstimestart = $forum->assesstimestart;
2007 $ratings->assesstimefinish = $forum->assesstimefinish;
02ebf404 2008 if ($forum->assessed == 2 and !isteacher($course->id)) {
2009 $ratings->allow = false;
2010 } else {
2011 $ratings->allow = true;
2012 }
2013 echo "<form name=form method=post action=rate.php>";
2014 echo "<input type=hidden name=id value=\"$course->id\">";
9d1b97c5 2015 }
2016 }
2017
02ebf404 2018 forum_print_post($post, $course->id, $ownpost, $reply, $link=false, $ratings);
501cdbd8 2019
2020 switch ($mode) {
2e2e71a8 2021 case FORUM_MODE_FLATOLDEST :
2022 case FORUM_MODE_FLATNEWEST :
501cdbd8 2023 default:
02ebf404 2024 echo "<ul>";
2025 forum_print_posts_flat($post->discussion, $course->id, $mode, $ratings, $reply);
2026 echo "</ul>";
501cdbd8 2027 break;
2028
2e2e71a8 2029 case FORUM_MODE_THREADED :
02ebf404 2030 forum_print_posts_threaded($post->id, $course->id, 0, $ratings, $reply);
501cdbd8 2031 break;
2032
2e2e71a8 2033 case FORUM_MODE_NESTED :
02ebf404 2034 forum_print_posts_nested($post->id, $course->id, $ratings, $reply);
501cdbd8 2035 break;
2036 }
2037
02ebf404 2038 if ($ratings) {
2039 echo "<center><input type=\"submit\" value=\"".get_string("sendinratings", "forum")."\">";
fa01ae8b 2040 if ($forum->scale < 0) {
2041 if ($scale = get_record("scale", "id", abs($forum->scale))) {
2042 print_scale_menu_helpbutton($course->id, $scale );
2043 }
2044 }
02ebf404 2045 echo "</center>";
2046 echo "</form>";
501cdbd8 2047 }
2048}
2049
02ebf404 2050function forum_print_posts_flat($discussion, $course, $direction, $ratings, $reply) {
501cdbd8 2051 global $USER;
2052
501cdbd8 2053 $link = false;
2054
2055 if ($direction < 0) {
2056 $sort = "ORDER BY created DESC";
2057 } else {
2058 $sort = "ORDER BY created ASC";
2059 }
2060
1f48942e 2061 if ($posts = forum_get_discussion_posts($discussion, $sort)) {
501cdbd8 2062 foreach ($posts as $post) {
ebc3bd2b 2063 $ownpost = ($USER->id == $post->userid);
02ebf404 2064 forum_print_post($post, $course, $ownpost, $reply, $link, $ratings);
501cdbd8 2065 }
2066 } else {
2067 return;
2068 }
2069}
2070
02ebf404 2071function forum_print_posts_threaded($parent, $course, $depth, $ratings, $reply) {
501cdbd8 2072 global $USER;
2073
501cdbd8 2074 $link = false;
2075
1f48942e 2076 if ($posts = forum_get_child_posts($parent)) {
501cdbd8 2077 foreach ($posts as $post) {
2078
f95c2a73 2079 echo "<ul>";
501cdbd8 2080 if ($depth > 0) {
ebc3bd2b 2081 $ownpost = ($USER->id == $post->userid);
02ebf404 2082 forum_print_post($post, $course, $ownpost, $reply, $link, $ratings); // link=true?
f95c2a73 2083 echo "<br />";
501cdbd8 2084 } else {
8c3c8481 2085 $by->name = "$post->firstname $post->lastname";
d62413e8 2086 $by->date = userdate($post->modified);
f95c2a73 2087 echo "<li><p><a name=\"$post->id\"></a><font size=-1><b><a href=\"discuss.php?d=$post->discussion&parent=$post->id\">$post->subject</a></b> ";
8c3c8481 2088 print_string("bynameondate", "forum", $by);
f95c2a73 2089 echo "</font></p></li>";
501cdbd8 2090 }
2091
02ebf404 2092 forum_print_posts_threaded($post->id, $course, $depth-1, $ratings, $reply);
f95c2a73 2093 echo "</ul>\n";
501cdbd8 2094 }
2095 } else {
2096 return;
2097 }
2098}
2099
02ebf404 2100function forum_print_posts_nested($parent, $course, $ratings, $reply) {
501cdbd8 2101 global $USER;
2102
501cdbd8 2103 $link = false;
2104
1f48942e 2105 if ($posts = forum_get_child_posts($parent)) {
501cdbd8 2106 foreach ($posts as $post) {
2107
61e96406 2108 if (empty($USER->id)) {
2109 $ownpost = false;
2110 } else {
2111 $ownpost = ($USER->id == $post->userid);
2112 }
501cdbd8 2113
2114 echo "<UL>";
02ebf404 2115 forum_print_post($post, $course, $ownpost, $reply, $link, $ratings);
501cdbd8 2116 echo "<BR>";
02ebf404 2117 forum_print_posts_nested($post->id, $course, $ratings, $reply);
501cdbd8 2118 echo "</UL>\n";
2119 }
2120 } else {
2121 return;
2122 }
2123}
2124
2125function forum_set_display_mode($mode=0) {
5be7800c 2126 global $USER, $CFG;
501cdbd8 2127
2128 if ($mode) {
2129 $USER->mode = $mode;
9c9f7d77 2130 } else if (empty($USER->mode)) {
5be7800c 2131 $USER->mode = $CFG->forum_displaymode;
501cdbd8 2132 }
2133}
f93f848a 2134
eaa3298b 2135function forum_get_participants($forumid) {
2136//Returns the users with data in one forum
2137//(users with records in forum_subscriptions, forum_posts and forum_ratings, students)
2138
2139 global $CFG;
2140
2141 //Get students from forum_subscriptions
2142 $st_subscriptions = get_records_sql("SELECT DISTINCT u.*
2143 FROM {$CFG->prefix}user u,
2144 {$CFG->prefix}forum_subscriptions s
2145 WHERE s.forum = '$forumid' and
2146 u.id = s.userid");
2147 //Get students from forum_posts
2148 $st_posts = get_records_sql("SELECT DISTINCT u.*
2149 FROM {$CFG->prefix}user u,
2150 {$CFG->prefix}forum_discussions d,
2151 {$CFG->prefix}forum_posts p
2152 WHERE d.forum = '$forumid' and
2153 p.discussion = d.id and
2154 u.id = p.userid");
2155
2156 //Get students from forum_ratings
2157 $st_ratings = get_records_sql("SELECT DISTINCT u.*
2158 FROM {$CFG->prefix}user u,
2159 {$CFG->prefix}forum_discussions d,
2160 {$CFG->prefix}forum_posts p,
2161 {$CFG->prefix}forum_ratings r
2162 WHERE d.forum = '$forumid' and
2163 p.discussion = d.id and
2164 r.post = p.id and
2165 u.id = r.userid");
2166
2167 //Add st_posts to st_subscriptions
b32bbab6 2168 if ($st_posts) {
2169 foreach ($st_posts as $st_post) {
2170 $st_subscriptions[$st_post->id] = $st_post;
2171 }
eaa3298b 2172 }
2173 //Add st_ratings to st_subscriptions
b32bbab6 2174 if ($st_ratings) {
2175 foreach ($st_ratings as $st_rating) {
2176 $st_subscriptions[$st_rating->id] = $st_rating;
2177 }
eaa3298b 2178 }
2179 //Return st_subscriptions array (it contains an array of unique users)
2180 return ($st_subscriptions);
2181}
3869a2ac 2182
f93f848a 2183?>