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