When confirming deleting an event, changed OK/Cancel to Yes/No and added
[moodle.git] / mod / forum / lib.php
CommitLineData
41905731 1<?php // $Id$
f93f848a 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
709f0ec8 12define("FORUM_FORCESUBSCRIBE", 1);
13define("FORUM_INITIALSUBSCRIBE", 2);
14
2e2e71a8 15$FORUM_LAYOUT_MODES = array ( FORUM_MODE_FLATOLDEST => get_string("modeflatoldestfirst", "forum"),
16 FORUM_MODE_FLATNEWEST => get_string("modeflatnewestfirst", "forum"),
17 FORUM_MODE_THREADED => get_string("modethreaded", "forum"),
18 FORUM_MODE_NESTED => get_string("modenested", "forum") );
f93f848a 19
11b0c469 20// These are course content forums that can be added to the course manually
ffe11640 21$FORUM_TYPES = array ("general" => get_string("generalforum", "forum"),
22 "eachuser" => get_string("eachuserforum", "forum"),
23 "single" => get_string("singleforum", "forum") );
f93f848a 24
70c476a7 25$FORUM_OPEN_MODES = array ("2" => get_string("openmode2", "forum"),
26 "1" => get_string("openmode1", "forum"),
27 "0" => get_string("openmode0", "forum") );
28
5be7800c 29if (!isset($CFG->forum_displaymode)) {
2e2e71a8 30 set_config("forum_displaymode", FORUM_MODE_NESTED);
65b0e537 31}
73bb0835 32
5be7800c 33if (!isset($CFG->forum_shortpost)) {
34 set_config("forum_shortpost", 300); // Less non-HTML characters than this is short
65b0e537 35}
4d871a72 36
5be7800c 37if (!isset($CFG->forum_longpost)) {
38 set_config("forum_longpost", 600); // More non-HTML characters than this is long
65b0e537 39}
4d871a72 40
5be7800c 41if (!isset($CFG->forum_manydiscussions)) {
42 set_config("forum_manydiscussions", 100); // Number of discussions on a page
65b0e537 43}
e07635f4 44
4909e176 45if (!isset($CFG->forum_maxbytes)) {
46 set_config("forum_maxbytes", 512000); // Default maximum size for all forums
65b0e537 47}
4909e176 48
f37da850 49if (!isset($CFG->forum_trackreadposts)) {
50 set_config("forum_trackreadposts", true); // Default whether user needs to mark a post as read
51}
52
53if (!isset($CFG->forum_oldpostdays)) {
54 set_config("forum_oldpostdays", 60); // Default number of days that a post is considered old
55}
56
57if (!isset($CFG->forum_usermarksread)) {
58 set_config("forum_usermarksread", false); // Default whether user needs to mark a post as read
59}
60
61if (!isset($CFG->forum_cleanreadtime)) {
62 set_config("forum_cleanreadtime", 2); // Default time (hour) to execute 'clean_read_records' cron
63}
64
1246ea56 65if (!isset($CFG->forum_replytouser)) {
66 set_config("forum_replytouser", true); // Default maximum size for all forums
67}
68
27888a20 69if (empty($USER->id) or isguest()) {
70 $CFG->forum_trackreadposts = false; // This feature never works when a user isn't logged in
71}
4909e176 72
e07635f4 73
caadf009 74/// STANDARD FUNCTIONS ///////////////////////////////////////////////////////////
75
76function forum_add_instance($forum) {
65b0e537 77// Given an object containing all the necessary data,
78// (defined by the form in mod.html) this function
79// will create a new instance and return the id number
caadf009 80// of the new instance.
81
82 global $CFG;
83
84 $forum->timemodified = time();
85
f2f56406 86 if (!$forum->userating) {
87 $forum->assessed = 0;
88 }
89
98914efd 90 if (!empty($forum->ratingtime)) {
65b0e537 91 $forum->assesstimestart = make_timestamp($forum->startyear, $forum->startmonth, $forum->startday,
98914efd 92 $forum->starthour, $forum->startminute, 0);
65b0e537 93 $forum->assesstimefinish = make_timestamp($forum->finishyear, $forum->finishmonth, $forum->finishday,
98914efd 94 $forum->finishhour, $forum->finishminute, 0);
95 } else {
96 $forum->assesstimestart = 0;
97 $forum->assesstimefinish = 0;
98 }
caadf009 99
cb9a975f 100 if (! $forum->id = insert_record("forum", $forum)) {
101 return false;
102 }
103
98914efd 104 if ($forum->type == "single") { // Create related discussion.
caadf009 105 $discussion->course = $forum->course;
106 $discussion->forum = $forum->id;
107 $discussion->name = $forum->name;
108 $discussion->intro = $forum->intro;
109 $discussion->assessed = $forum->assessed;
110
111 if (! forum_add_discussion($discussion)) {
112 error("Could not add the discussion for this forum");
113 }
114 }
8f0cd6ef 115
709f0ec8 116 if ($forum->forcesubscribe == FORUM_INITIALSUBSCRIBE) { // all users should be subscribed initially
117 $users = get_course_users($forum->course);
118 foreach ($users as $user) {
119 forum_subscribe($user->id, $forum->id);
120 }
121 }
caadf009 122
123 return $forum->id;
124}
125
126
127function forum_update_instance($forum) {
65b0e537 128// Given an object containing all the necessary data,
129// (defined by the form in mod.html) this function
caadf009 130// will update an existing instance with new data.
131
132 $forum->timemodified = time();
133 $forum->id = $forum->instance;
134
f2f56406 135 if (!$forum->userating) {
136 $forum->assessed = 0;
137 }
138
98914efd 139 if (!empty($forum->ratingtime)) {
65b0e537 140 $forum->assesstimestart = make_timestamp($forum->startyear, $forum->startmonth, $forum->startday,
98914efd 141 $forum->starthour, $forum->startminute, 0);
65b0e537 142 $forum->assesstimefinish = make_timestamp($forum->finishyear, $forum->finishmonth, $forum->finishday,
98914efd 143 $forum->finishhour, $forum->finishminute, 0);
144 } else {
145 $forum->assesstimestart = 0;
146 $forum->assesstimefinish = 0;
147 }
148
caadf009 149 if ($forum->type == "single") { // Update related discussion and post.
150 if (! $discussion = get_record("forum_discussions", "forum", $forum->id)) {
151 if ($discussions = get_records("forum_discussions", "forum", $forum->id, "timemodified ASC")) {
152 notify("Warning! There is more than one discussion in this forum - using the most recent");
153 $discussion = array_pop($discussions);
154 } else {
155 error("Could not find the discussion in this forum");
156 }
157 }
158 if (! $post = get_record("forum_posts", "id", $discussion->firstpost)) {
159 error("Could not find the first post in this forum discussion");
160 }
161
162 $post->subject = $forum->name;
163 $post->message = $forum->intro;
164 $post->modified = $forum->timemodified;
165
166 if (! update_record("forum_posts", $post)) {
167 error("Could not update the first post");
168 }
169
170 $discussion->name = $forum->name;
171
172 if (! update_record("forum_discussions", $discussion)) {
173 error("Could not update the discussion");
174 }
175 }
176
69d79bc3 177 return update_record("forum", $forum);
caadf009 178}
179
180
181function forum_delete_instance($id) {
65b0e537 182// Given an ID of an instance of this module,
183// this function will permanently delete the instance
184// and any data that depends on it.
caadf009 185
186 if (! $forum = get_record("forum", "id", "$id")) {
187 return false;
188 }
189
190 $result = true;
191
192 if ($discussions = get_records("forum_discussions", "forum", $forum->id)) {
193 foreach ($discussions as $discussion) {
194 if (! forum_delete_discussion($discussion)) {
195 $result = false;
196 }
197 }
198 }
199
200 if (! delete_records("forum_subscriptions", "forum", "$forum->id")) {
201 $result = false;
202 }
203
f37da850 204 forum_tp_delete_read_records(-1, -1, -1, $forum->id);
205
caadf009 206 if (! delete_records("forum", "id", "$forum->id")) {
207 $result = false;
208 }
209
210 return $result;
211}
212
213
214function forum_cron () {
edffca15 215/// Function to be run periodically according to the moodle cron
216/// Finds all posts that have yet to be mailed out, and mails them
217/// out to all subscribers
caadf009 218
d30867b0 219 global $CFG, $USER;
aaf7a9dc 220 static $strforums = NULL;
857b798b 221
222 if ($strforums === NULL) {
aaf7a9dc 223 $strforums = get_string('forums', 'forum');
224 }
225
1066e0dc 226 if (!empty($USER->id)) { // Remember real USER account if necessary
ec2137ba 227 $realuser = $USER;
228 }
229
3ecca1ee 230 /// Posts older than 2 days will not be mailed. This is to avoid the problem where
231 /// cron has not been running for a long time, and then suddenly people are flooded
232 /// with mail from the past few weeks or months
caadf009 233
3ecca1ee 234 $timenow = time();
235 $endtime = $timenow - $CFG->maxeditingtime;
38ad519c 236 $starttime = $endtime - 48 * 3600; /// Two days earlier
f37da850 237 $starttime = $endtime - 365 * 24 * 3600; /// Two days earlier
3ecca1ee 238
239 if ($posts = forum_get_unmailed_posts($starttime, $endtime)) {
caadf009 240
65b0e537 241 /// Mark them all now as being mailed. It's unlikely but possible there
242 /// might be an error later so that a post is NOT actually mailed out,
edffca15 243 /// but since mail isn't crucial, we can accept this risk. Doing it now
244 /// prevents the risk of duplicated mails, which is a worse problem.
245
3ecca1ee 246 if (!forum_mark_old_posts_as_mailed($endtime)) {
b140ae85 247 mtrace("Errors occurred while trying to mark some posts as being mailed.");
3ecca1ee 248 return false; // Don't continue trying to mail them, in case we are in a cron loop
edffca15 249 }
250
ca8e8a10 251 @set_time_limit(0); /// so that script does not get timed out when posting to many users
aaf7a9dc 252
857b798b 253 $urlinfo = parse_url($CFG->wwwroot);
254 $hostname = $urlinfo['host'];
255
caadf009 256 foreach ($posts as $post) {
257
b140ae85 258 mtrace(get_string("processingpost", "forum", $post->id), '');
caadf009 259
ebc3bd2b 260 if (! $userfrom = get_record("user", "id", "$post->userid")) {
b140ae85 261 mtrace("Could not find user $post->userid");
caadf009 262 continue;
263 }
264
857b798b 265
266 $userfrom->customheaders = array ( // Headers to make emails easier to track
267 "Precedence: Bulk",
268 "List-id: <moodlecourse{$post->course}@$hostname>",
269 "Message-Id: <moodlepost{$post->id}@$hostname>",
270 "In-Reply-To: <moodlepost{$post->parent}@$hostname>",
8f0cd6ef 271 "References: <moodlepost{$post->parent}@$hostname>"
857b798b 272 );
273
49d9b738 274
caadf009 275 if (! $discussion = get_record("forum_discussions", "id", "$post->discussion")) {
b140ae85 276 mtrace("Could not find discussion $post->discussion");
caadf009 277 continue;
278 }
279
280 if (! $forum = get_record("forum", "id", "$discussion->forum")) {
b140ae85 281 mtrace("Could not find forum $discussion->forum");
caadf009 282 continue;
283 }
284
285 if (! $course = get_record("course", "id", "$forum->course")) {
b140ae85 286 mtrace("Could not find course $forum->course");
caadf009 287 continue;
288 }
289
e1fb2e6e 290 if (!empty($course->lang)) {
291 $CFG->courselang = $course->lang;
292 } else {
293 unset($CFG->courselang);
294 }
9c84314e 295
9197e147 296 $groupmode = false;
297 if ($cm = get_coursemodule_from_instance("forum", $forum->id, $course->id)) {
2862b309 298 if ($groupmode = groupmode($course, $cm) and $discussion->groupid > 0) { // Groups are being used
2f9c977e 299 if (!$group = get_record("groups", "id", $discussion->groupid)) { // Can't find group
9197e147 300 continue; // Be safe and don't send it to anyone
301 }
302 }
69d79bc3 303 } else {
304 $cm->id = 0;
305 }
9197e147 306
caadf009 307 if ($users = forum_subscribed_users($course, $forum)) {
caadf009 308
309 $mailcount=0;
3d94772d 310 $errorcount=0;
caadf009 311 foreach ($users as $userto) {
9197e147 312 if ($groupmode) { // Look for a reason not to send this email
313 if (!isteacheredit($course->id, $userto->id)) {
2862b309 314 if (!empty($group->id)) {
315 if (!ismember($group->id, $userto->id)) {
316 continue;
317 }
9197e147 318 }
319 }
320 }
65b0e537 321
aaf7a9dc 322 if ($userto->maildigest > 0) {
323 // This user wants the mails to be in digest form
324 $queue = New stdClass;
325 $queue->userid = $userto->id;
326 $queue->discussionid = $discussion->id;
327 $queue->postid = $post->id;
328 if(!insert_record('forum_queue', $queue)) {
b140ae85 329 mtrace("Error: mod/forum/cron.php: Could not queue for digest mail for id $post->id to user $userto->id ($userto->email) .. not trying again.");
aaf7a9dc 330 }
331 continue;
332 }
65b0e537 333
334 /// Override the language and timezone of the "current" user, so that
ec2137ba 335 /// mail is customised for the receiver.
336 $USER->lang = $userto->lang;
337 $USER->timezone = $userto->timezone;
338
caadf009 339 $postsubject = "$course->shortname: $post->subject";
aaf7a9dc 340 $posttext = forum_make_mail_text($course, $forum, $discussion, $post, $userfrom, $userto);
341 $posthtml = forum_make_mail_html($course, $forum, $discussion, $post, $userfrom, $userto);
caadf009 342
8f0cd6ef 343 if (!$mailresult = email_to_user($userto, $userfrom, $postsubject, $posttext,
50a26903 344 $posthtml, '', '', $CFG->forum_replytouser)) {
b140ae85 345 mtrace("Error: mod/forum/cron.php: Could not send out mail for id $post->id to user $userto->id".
346 " ($userto->email) .. not trying again.");
8f0cd6ef 347 add_to_log($course->id, 'forum', 'mail error', "discuss.php?d=$discussion->id#$post->id",
50a26903 348 substr($post->subject,0,30), $cm->id, $userto->id);
aaf7a9dc 349 $errorcount++;
b6268a0e 350 } else if ($mailresult === 'emailstop') {
8f0cd6ef 351 add_to_log($course->id, 'forum', 'mail blocked', "discuss.php?d=$discussion->id#$post->id",
50a26903 352 substr($post->subject,0,30), $cm->id, $userto->id);
caadf009 353 } else {
aaf7a9dc 354 $mailcount++;
f37da850 355
356 /// Mark post as read if forum_usermarksread is set off
357 if ($CFG->forum_trackreadposts && !$CFG->forum_usermarksread) {
358 if (!forum_tp_mark_post_read($userto->id, $post, $forum->id)) {
359 mtrace("Error: mod/forum/cron.php: Could not mark post $post->id read for user $userto->id".
360 " while sending email.");
361 }
362 }
caadf009 363 }
aaf7a9dc 364 }
365
b140ae85 366 mtrace(".... mailed to $mailcount users.");
aaf7a9dc 367 if ($errorcount) {
368 set_field("forum_posts", "mailed", "2", "id", "$post->id");
369 }
370 }
371 }
372 }
373
6e6a64b3 374 unset($CFG->courselang);
375
944a2b28 376 if (!empty($realuser)) { // Restore real USER timezone if necessary
377 $sitetimezone = $realuser->timezone;
b140ae85 378 $USER->lang = $realuser->lang;
944a2b28 379 } else {
380 $sitetimezone = $CFG->timezone;
b140ae85 381 $USER->lang = $CFG->lang;
944a2b28 382 }
383
aaf7a9dc 384 /// Now see if there are any digest mails waiting to be sent, and if we should send them
aaf7a9dc 385
8f0cd6ef 386 if (!isset($CFG->digestmailtimelast)) { // To catch the first time
ca8e8a10 387 set_config('digestmailtimelast', 0);
388 }
389
390 $timenow = time();
944a2b28 391 $digesttime = usergetmidnight($timenow, $sitetimezone) + ($CFG->digestmailtime * 3600);
ca8e8a10 392
393 if ($CFG->digestmailtimelast < $digesttime and $timenow > $digesttime) {
b140ae85 394
ca8e8a10 395 set_config('digestmailtimelast', $timenow);
aaf7a9dc 396
b140ae85 397 mtrace('Sending forum digests: '.userdate($timenow, '', $sitetimezone));
398
aaf7a9dc 399 $digestposts = get_records('forum_queue');
400 if(!empty($digestposts)) {
401
402 // We have work to do
403 $usermailcount = 0;
404 $site = get_site();
405
406 $users = array();
407 $posts = array();
408 $discussions = array();
409 $discussionposts = array();
410 $userdiscussions = array();
411 foreach($digestposts as $digestpost) {
412 if(!isset($users[$digestpost->userid])) {
413 $users[$digestpost->userid] = get_record('user', 'id', $digestpost->userid);
414 }
415 if(!isset($discussions[$digestpost->discussionid])) {
416 $discussions[$digestpost->discussionid] = get_record('forum_discussions', 'id', $digestpost->discussionid);
417 }
418 if(!isset($posts[$digestpost->postid])) {
419 $posts[$digestpost->postid] = get_record('forum_posts', 'id', $digestpost->postid);
420 }
421 $userdiscussions[$digestpost->userid][$digestpost->discussionid] = $digestpost->discussionid;
422 $discussionposts[$digestpost->discussionid][$digestpost->postid] = $digestpost->postid;
423 }
424
425 // Data collected, start sending out emails to each user
426
427 foreach($userdiscussions as $userid => $thesediscussions) {
428
b140ae85 429 mtrace(get_string('processingdigest', 'forum', $userid),'... ');
aaf7a9dc 430
431 // First of all delete all the queue entries for this user
432 delete_records('forum_queue', 'userid', $userid);
433 $userto = $users[$userid];
434
435 /// Override the language and timezone of the "current" user, so that
436 /// mail is customised for the receiver.
a0330747 437 $USER->lang = $userto->lang;
438 $USER->timezone = $userto->timezone;
aaf7a9dc 439
440
441 $postsubject = get_string('digestmailsubject', 'forum', $site->shortname);
442 $headerdata = New stdClass;
443 $headerdata->sitename = $site->fullname;
839f2456 444 $headerdata->userprefs = $CFG->wwwroot.'/user/edit.php?id='.$userid.'&amp;course='.$site->id;
aaf7a9dc 445
446 $posttext = get_string('digestmailheader', 'forum', $headerdata)."\n\n";
447 $headerdata->userprefs = '<a target="_blank" href="'.$headerdata->userprefs.'">'.get_string('digestmailprefs', 'forum').'</a>';
9c674431 448
78c0d909 449 $posthtml = "<head>";
450 foreach ($CFG->stylesheets as $stylesheet) {
451 $posthtml .= '<link rel="stylesheet" type="text/css" href="'.$stylesheet.'" />'."\n";
452 }
453 $posthtml .= "</head>\n<body>\n";
a0330747 454 $posthtml .= '<p>'.get_string('digestmailheader', 'forum', $headerdata).'</p><br /><hr size="1" noshade="noshade" />';
aaf7a9dc 455
456 foreach($thesediscussions as $discussionid) {
457 $discussion = $discussions[$discussionid];
458 if(empty($discussion)) {
b140ae85 459 mtrace("Error: Could not find discussion $discussionid");
aaf7a9dc 460 continue;
caadf009 461 }
aaf7a9dc 462
463 if (! $forum = get_record("forum", "id", "$discussion->forum")) {
b140ae85 464 mtrace("Could not find forum $discussion->forum");
aaf7a9dc 465 continue;
f690562f 466 }
aaf7a9dc 467 if (! $course = get_record("course", "id", "$forum->course")) {
b140ae85 468 mtrace("Could not find course $forum->course");
aaf7a9dc 469 continue;
caadf009 470 }
65b0e537 471
aaf7a9dc 472 $canunsubscribe = ! forum_is_forcesubscribed($forum->id);
473 $canreply = forum_user_can_post($forum, $userto);
caadf009 474
caadf009 475
aaf7a9dc 476 $posttext .= "\n \n";
477 $posttext .= '=====================================================================';
478 $posttext .= "\n \n";
479 $posttext .= "$course->shortname -> $strforums -> $forum->name";
480 if ($discussion->name != $forum->name) {
481 $posttext .= " -> $discussion->name";
caadf009 482 }
aaf7a9dc 483 $posttext .= "\n";
65b0e537 484
aaf7a9dc 485 $posthtml .= "<p><font face=\"sans-serif\">".
486 "<a target=\"_blank\" href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> -> ".
487 "<a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/index.php?id=$course->id\">$strforums</a> -> ".
488 "<a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/view.php?f=$forum->id\">$forum->name</a>";
489 if ($discussion->name == $forum->name) {
490 $posthtml .= "</font></p>";
caadf009 491 } else {
aaf7a9dc 492 $posthtml .= " -> <a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$discussion->id\">$discussion->name</a></font></p>";
caadf009 493 }
aaf7a9dc 494 $posthtml .= '<p>';
495
e1c6dde1 496 $postsarray = $discussionposts[$discussionid];
497 sort($postsarray);
498
f37da850 499 /// Create an empty array to use for marking read posts.
500 /// (I'm sure there's already a structure I can use here, but I can't be sure.)
501 $markread = array();
502
857b798b 503 foreach ($postsarray as $postid) {
aaf7a9dc 504 if (! $post = get_record("forum_posts", "id", "$postid")) {
b140ae85 505 mtrace("Error: Could not find post $postid");
aaf7a9dc 506 continue;
507 }
508 if (! $userfrom = get_record("user", "id", "$post->userid")) {
b140ae85 509 mtrace("Error: Could not find user $post->userid");
aaf7a9dc 510 continue;
511 }
512
857b798b 513 $userfrom->customheaders = array ("Precedence: Bulk");
514
515 if ($userto->maildigest == 2) {
aaf7a9dc 516 // Subjects only
517 $by = New stdClass;
518 $by->name = fullname($userfrom);
519 $by->date = userdate($post->modified);
520 $posttext .= "\n".$post->subject.' '.get_string("bynameondate", "forum", $by);
521 $posttext .= "\n---------------------------------------------------------------------";
522
839f2456 523 $by->name = "<a target=\"_blank\" href=\"$CFG->wwwroot/user/view.php?id=$userfrom->id&amp;course=$course->id\">$by->name</a>";
aaf7a9dc 524 $posthtml .= '<div><a target="_blank" href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.$discussion->id.'#'.$post->id.'">'.$post->subject.'</a> '.get_string("bynameondate", "forum", $by).'</div>';
857b798b 525
526 } else {
aaf7a9dc 527 // The full treatment
528 $posttext .= forum_make_mail_text($course, $forum, $discussion, $post, $userfrom, $userto, true);
529 $posthtml .= forum_make_mail_post($post, $userfrom, $userto, $course, false, $canreply, false, false);
f37da850 530
531 /// Create an array of postid's for this user to mark as read.
532 if ($CFG->forum_trackreadposts && !$CFG->forum_usermarksread) {
533 $markread[$post->id]->post = $post;
534 $markread[$post->id]->forumid = $forum->id;
535 }
aaf7a9dc 536 }
537 }
538 if ($canunsubscribe) {
539 $posthtml .= "\n<div align=\"right\"><font size=\"1\"><a href=\"$CFG->wwwroot/mod/forum/subscribe.php?id=$forum->id\">".get_string("unsubscribe", "forum")."</a></font></div>";
857b798b 540 } else {
aaf7a9dc 541 $posthtml .= "\n<div align=\"right\"><font size=\"1\">".get_string("everyoneissubscribed", "forum")."</font></div>";
542 }
543 $posthtml .= '<hr size="1" noshade="noshade" /></p>';
caadf009 544 }
a0330747 545 $posthtml .= '</body>';
caadf009 546
379a42cb 547 if($userto->mailformat != 1) {
548 // This user DOESN'T want to receive HTML
549 $posthtml = '';
550 }
551
8f0cd6ef 552 if (!$mailresult = email_to_user($userto, $site->shortname, $postsubject, $posttext, $posthtml,
50a26903 553 '', '', $CFG->forum_replytouser)) {
b140ae85 554 mtrace("ERROR!");
aaf7a9dc 555 echo "Error: mod/forum/cron.php: Could not send out digest mail to user $userto->id ($userto->email)... not trying again.\n";
556 add_to_log($course->id, 'forum', 'mail digest error', '', '', $cm->id, $userto->id);
b6268a0e 557 } else if ($mailresult === 'emailstop') {
50a26903 558 add_to_log($course->id, 'forum', 'mail digest blocked', '', '', $cm->id, $userto->id);
aaf7a9dc 559 } else {
b140ae85 560 mtrace("success.");
aaf7a9dc 561 $usermailcount++;
f37da850 562
563 /// Mark post as read if forum_usermarksread is set off
564 if ($CFG->forum_trackreadposts && !$CFG->forum_usermarksread) {
565 foreach ($markread as $postinfo) {
566 if (!forum_tp_mark_post_read($userto->id, $postinfo->post, $postinfo->forumid)) {
567 mtrace("Error: mod/forum/cron.php: Could not mark post $postid read for user $userto->id".
568 " while sending digest email.");
569 }
570 }
571 }
3d94772d 572 }
aaf7a9dc 573
caadf009 574 }
aaf7a9dc 575
caadf009 576 }
577 }
578
d658167f 579 if(!empty($usermailcount)) {
b140ae85 580 mtrace(get_string('digestsentusers', 'forum', $usermailcount));
aaf7a9dc 581 }
582
ec2137ba 583 if (!empty($realuser)) { // Restore real USER if necessary
584 $USER = $realuser;
585 }
586
f37da850 587 if (($lastreadclean = get_record("config", "name", "forum_lastreadclean"))) {
588 $cleantime = mktime($CFG->forum_cleanreadtime, 0);
589 $timenow = time();
590 if (($timenow > $cleantime) && ($lastreadclean->value+(24*3600) < $timenow)) {
591 $lastreadclean->value = $timenow;
592 update_record("config", $lastreadclean);
593 forum_tp_clean_read_records();
594 }
595 } else {
596 $lastreadclean->name = 'forum_lastreadclean';
597 $lastreadclean->value = time();
598 insert_record("config", $lastreadclean);
599 }
600
601
caadf009 602 return true;
603}
604
aaf7a9dc 605function forum_make_mail_text($course, $forum, $discussion, $post, $userfrom, $userto, $bare = false) {
606 global $CFG;
607
aaf7a9dc 608 $by = New stdClass;
609 $by->name = fullname($userfrom, isteacher($course->id, $userto->id));
610 $by->date = userdate($post->modified, "", $userto->timezone);
611
612 $strbynameondate = get_string('bynameondate', 'forum', $by);
613
64762ddc 614 $strforums = get_string('forums', 'forum');
615
aaf7a9dc 616 $canunsubscribe = ! forum_is_forcesubscribed($forum->id);
617 $canreply = forum_user_can_post($forum, $userto);
618
619 $posttext = '';
620
621 if(!$bare) {
622 $posttext = "$course->shortname -> $strforums -> $forum->name";
623
624 if ($discussion->name != $forum->name) {
625 $posttext .= " -> $discussion->name";
626 }
627 }
628
629 $posttext .= "\n---------------------------------------------------------------------\n";
630 $posttext .= $post->subject;
631 if($bare) {
632 $posttext .= " ($CFG->wwwroot/mod/forum/discuss.php?d=$discussion->id#$post->id)";
633 }
634 $posttext .= "\n".$strbynameondate."\n";
635 $posttext .= "---------------------------------------------------------------------\n";
636 $posttext .= format_text_email($post->message, $post->format);
637 $posttext .= "\n\n";
638 if ($post->attachment) {
639 $post->course = $course->id;
640 $post->forum = $forum->id;
641 $posttext .= forum_print_attachments($post, "text");
642 }
643 if (!$bare && $canreply) {
644 $posttext .= "---------------------------------------------------------------------\n";
645 $posttext .= get_string("postmailinfo", "forum", $course->shortname)."\n";
646 $posttext .= "$CFG->wwwroot/mod/forum/post.php?reply=$post->id\n";
647 }
648 if (!$bare && $canunsubscribe) {
649 $posttext .= "\n---------------------------------------------------------------------\n";
650 $posttext .= get_string("unsubscribe", "forum");
651 $posttext .= ": $CFG->wwwroot/mod/forum/subscribe.php?id=$forum->id\n";
652 }
653
654 return $posttext;
655}
656
657function forum_make_mail_html($course, $forum, $discussion, $post, $userfrom, $userto) {
658 global $CFG;
659
aaf7a9dc 660 if ($userto->mailformat == 1) { // HTML
661
64762ddc 662 $strforums = get_string('forums', 'forum');
aaf7a9dc 663 $canreply = forum_user_can_post($forum, $userto);
664 $canunsubscribe = ! forum_is_forcesubscribed($forum->id);
665
9c674431 666 $posthtml = '';
78c0d909 667 $posthtml .= '<head>';
668 foreach ($CFG->stylesheets as $stylesheet) {
669 $posthtml .= '<link rel="stylesheet" type="text/css" href="'.$stylesheet.'" />'."\n";
670 }
671 $posthtml .= '</head>';
672 $posthtml .= "\n<body>\n\n";
9c674431 673
674 $posthtml .= "<p><font face=\"sans-serif\">".
675 "<a target=\"_blank\" href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> &raquo; ".
676 "<a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/index.php?id=$course->id\">$strforums</a> &raquo; ".
aaf7a9dc 677 "<a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/view.php?f=$forum->id\">$forum->name</a>";
678 if ($discussion->name == $forum->name) {
679 $posthtml .= "</font></p>";
680 } else {
9c674431 681 $posthtml .= " &raquo; <a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$discussion->id\">$discussion->name</a></font></p>";
aaf7a9dc 682 }
683 $posthtml .= forum_make_mail_post($post, $userfrom, $userto, $course, false, $canreply, false, false);
684
685 if ($canunsubscribe) {
686 $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>";
687 }
688
689 return $posthtml;
690
691 } else {
64762ddc 692 return '';
aaf7a9dc 693 }
694}
695
caadf009 696function forum_user_outline($course, $user, $mod, $forum) {
697
1f48942e 698 if ($posts = forum_get_user_posts($forum->id, $user->id)) {
caadf009 699 $result->info = get_string("numposts", "forum", count($posts));
700
701 $lastpost = array_pop($posts);
702 $result->time = $lastpost->modified;
703 return $result;
704 }
705 return NULL;
706}
707
708
709function forum_user_complete($course, $user, $mod, $forum) {
710 global $CFG;
711
1f48942e 712 if ($posts = forum_get_user_posts($forum->id, $user->id)) {
caadf009 713 foreach ($posts as $post) {
f37da850 714
715 /// Add the forum id to the post object - used by read tracking.
716 $post->forum = $forum->id;
717
497588fe 718 forum_print_post($post, $course->id, $ownpost=false, $reply=false, $link=false, $rate=false);
caadf009 719 }
720
721 } else {
41905731 722 echo "<p>".get_string("noposts", "forum")."</p>";
caadf009 723 }
caadf009 724}
725
1b5910c4 726function forum_print_recent_activity($course, $isteacher, $timestart) {
65b0e537 727/// Given a course and a date, prints a summary of all the new
cc3655a2 728/// messages posted in the course since that date
729
3d891989 730 global $CFG;
caadf009 731
732 $heading = false;
733 $content = false;
734
1b5910c4 735 if (!$logs = get_records_select("log", "time > '$timestart' AND ".
736 "course = '$course->id' AND ".
737 "module = 'forum' AND ".
738 "action LIKE 'add %' ", "time ASC")){
739 return false;
740 }
741
dcde9f02 742 $strftimerecent = get_string("strftimerecent");
743
d05956ac 744 $isteacheredit = isteacheredit($course->id);
745 $mygroupid = mygroupid($course->id);
746
747 $groupmode = array(); /// To cache group modes
748
1b5910c4 749 foreach ($logs as $log) {
750 //Get post info, I'll need it later
ac1d9a22 751 if ($post = forum_get_post_from_log($log)) {
752 //Create a temp valid module structure (course,id)
753 $tempmod->course = $log->course;
754 $tempmod->id = $post->forum;
755 //Obtain the visible property from the instance
756 $modvisible = instance_is_visible($log->module, $tempmod);
757 }
d05956ac 758
ac1d9a22 759 //Only if the post exists and mod is visible
760 if ($post && $modvisible) {
761 /// Check whether this is for teachers only
762 $teacheronly = "";
763 if ($forum = get_record("forum", "id", $post->forum)) {
764 if ($forum->type == "teacher") {
765 if ($isteacher) {
766 $teacheronly = "class=\"teacheronly\"";
767 } else {
768 continue;
b91d6dcd 769 }
770 }
ac1d9a22 771 }
772 /// Check whether this is belongs to a discussion in a group that
773 /// should NOT be accessible to the current user
b91d6dcd 774
ac1d9a22 775 if (!$isteacheredit and $post->groupid != -1) { /// Editing teachers or open discussions
776 if (!isset($cm[$post->forum])) {
777 $cm[$forum->id] = get_coursemodule_from_instance("forum", $forum->id, $course->id);
778 $groupmode[$forum->id] = groupmode($course, $cm[$forum->id]);
436a7cae 779 }
ac1d9a22 780 if ($groupmode[$forum->id]) {
781 if ($mygroupid != $post->groupid) {
782 continue;
783 }
1b5910c4 784 }
caadf009 785 }
ac1d9a22 786
787 if (! $heading) {
788 print_headline(get_string("newforumposts", "forum").":");
789 $heading = true;
790 $content = true;
791 }
792 $date = userdate($post->modified, $strftimerecent);
793 $fullname = fullname($post, $isteacher);
794 echo "<p $teacheronly><font size=\"1\">$date - $fullname<br />";
795 echo "\"<a href=\"$CFG->wwwroot/mod/forum/".str_replace('&', '&amp;', $log->url)."\">";
796 $post->subject = break_up_long_words($post->subject);
797 if (!empty($CFG->filterall)) {
798 $post->subject = filter_text("<nolink>$post->subject</nolink>", $course->id);
799 }
800 if ($log->action == "add discussion") {
801 echo "<b>$post->subject</b>";
802 } else {
803 echo "$post->subject";
804 }
805 echo "</a>\"</font></p>";
caadf009 806 }
807 }
1b5910c4 808
caadf009 809 return $content;
810}
811
812
813function forum_grades($forumid) {
814/// Must return an array of grades, indexed by user, and a max grade.
caadf009 815
4db9d14d 816 if (!$forum = get_record("forum", "id", $forumid)) {
817 return false;
818 }
819 if (!$forum->assessed) {
820 return false;
821 }
d6bdd9d5 822 $scalemenu = make_grades_menu($forum->scale);
02ebf404 823
824 $currentuser = 0;
825 $ratingsuser = array();
826
1f48942e 827 if ($ratings = forum_get_user_grades($forumid)) {
02ebf404 828 foreach ($ratings as $rating) { // Ordered by user
829 if ($currentuser and $rating->userid != $currentuser) {
830 if (!empty($ratingsuser)) {
d6bdd9d5 831 if ($forum->scale < 0) {
832 $return->grades[$currentuser] = forum_get_ratings_mean(0, $scalemenu, $ratingsuser);
833 $return->grades[$currentuser] .= "<br />".forum_get_ratings_summary(0, $scalemenu, $ratingsuser);
834 } else {
835 $total = 0;
836 $count = 0;
837 foreach ($ratingsuser as $ra) {
838 $total += $ra;
839 $count ++;
840 }
841 $return->grades[$currentuser] = format_float($total/$count, 2);
842 }
02ebf404 843 } else {
844 $return->grades[$currentuser] = "";
845 }
846 $ratingsuser = array();
caadf009 847 }
02ebf404 848 $ratingsuser[] = $rating->rating;
849 $currentuser = $rating->userid;
caadf009 850 }
02ebf404 851 if (!empty($ratingsuser)) {
d6bdd9d5 852 if ($forum->scale < 0) {
853 $return->grades[$currentuser] = forum_get_ratings_mean(0, $scalemenu, $ratingsuser);
854 $return->grades[$currentuser] .= "<br />".forum_get_ratings_summary(0, $scalemenu, $ratingsuser);
855 } else {
856 $total = 0;
857 $count = 0;
858 foreach ($ratingsuser as $ra) {
859 $total += $ra;
860 $count ++;
861 }
862 $return->grades[$currentuser] = format_float((float)$total/(float)$count, 2);
863 }
02ebf404 864 } else {
865 $return->grades[$currentuser] = "";
caadf009 866 }
867 } else {
868 $return->grades = array();
869 }
870
d6bdd9d5 871 if ($forum->scale < 0) {
872 $return->maxgrade = "";
873 } else {
874 $return->maxgrade = $forum->scale;
875 }
caadf009 876 return $return;
877}
878
05855091 879function forum_get_participants($forumid) {
880//Returns the users with data in one forum
65b0e537 881//(users with records in forum_subscriptions, forum_posts and forum_ratings, students)
05855091 882
883 global $CFG;
884
885 //Get students from forum_subscriptions
886 $st_subscriptions = get_records_sql("SELECT DISTINCT u.*
887 FROM {$CFG->prefix}user u,
888 {$CFG->prefix}forum_subscriptions s
889 WHERE s.forum = '$forumid' and
65b0e537 890 u.id = s.userid");
05855091 891 //Get students from forum_posts
892 $st_posts = get_records_sql("SELECT DISTINCT u.*
893 FROM {$CFG->prefix}user u,
894 {$CFG->prefix}forum_discussions d,
895 {$CFG->prefix}forum_posts p
896 WHERE d.forum = '$forumid' and
897 p.discussion = d.id and
898 u.id = p.userid");
899
900 //Get students from forum_ratings
901 $st_ratings = get_records_sql("SELECT DISTINCT u.*
902 FROM {$CFG->prefix}user u,
903 {$CFG->prefix}forum_discussions d,
904 {$CFG->prefix}forum_posts p,
905 {$CFG->prefix}forum_ratings r
906 WHERE d.forum = '$forumid' and
907 p.discussion = d.id and
908 r.post = p.id and
909 u.id = r.userid");
910
911 //Add st_posts to st_subscriptions
912 if ($st_posts) {
913 foreach ($st_posts as $st_post) {
914 $st_subscriptions[$st_post->id] = $st_post;
915 }
916 }
917 //Add st_ratings to st_subscriptions
918 if ($st_ratings) {
919 foreach ($st_ratings as $st_rating) {
920 $st_subscriptions[$st_rating->id] = $st_rating;
921 }
922 }
923 //Return st_subscriptions array (it contains an array of unique users)
924 return ($st_subscriptions);
925}
caadf009 926
0f1a97c2 927function forum_scale_used ($forumid,$scaleid) {
928//This function returns if a scale is being used by one forum
65b0e537 929
0f1a97c2 930 $return = false;
65b0e537 931
0f1a97c2 932 $rec = get_record("forum","id","$forumid","scale","-$scaleid");
65b0e537 933
934 if (!empty($rec) && !empty($scaleid)) {
0f1a97c2 935 $return = true;
936 }
65b0e537 937
0f1a97c2 938 return $return;
939}
940
9fa49e22 941/// SQL FUNCTIONS ///////////////////////////////////////////////////////////
942
1f48942e 943function forum_get_post_full($postid) {
944/// Gets a post with all info ready for forum_print_post
945 global $CFG;
946
ebc3bd2b 947 return get_record_sql("SELECT p.*, u.firstname, u.lastname, u.email, u.picture
65b0e537 948 FROM {$CFG->prefix}forum_posts p,
949 {$CFG->prefix}user u
950 WHERE p.id = '$postid'
ebc3bd2b 951 AND p.userid = u.id");
1f48942e 952}
953
954function forum_get_discussion_posts($discussion, $sort) {
955/// Gets posts with all info ready for forum_print_post
956 global $CFG;
957
ebc3bd2b 958 return get_records_sql("SELECT p.*, u.firstname, u.lastname, u.email, u.picture
65b0e537 959 FROM {$CFG->prefix}forum_posts p,
960 {$CFG->prefix}user u
961 WHERE p.discussion = $discussion
962 AND p.parent > 0
ebc3bd2b 963 AND p.userid = u.id $sort");
1f48942e 964}
965
966function forum_get_child_posts($parent) {
967/// Gets posts with all info ready for forum_print_post
968 global $CFG;
969
ebc3bd2b 970 return get_records_sql("SELECT p.*, u.firstname, u.lastname, u.email, u.picture
65b0e537 971 FROM {$CFG->prefix}forum_posts p,
972 {$CFG->prefix}user u
973 WHERE p.parent = '$parent'
ebc3bd2b 974 AND p.userid = u.id
1f48942e 975 ORDER BY p.created ASC");
976}
977
978
8b9c7aa0 979function forum_search_posts($searchterms, $courseid, $page=0, $recordsperpage=50, &$totalcount) {
980/// Returns a list of posts found using an array of search terms
981/// eg word +word -word
982///
983
9fa49e22 984 global $CFG;
855c0839 985 require_once($CFG->libdir.'/searchlib.php');
986
9fa49e22 987 if (!isteacher($courseid)) {
988 $notteacherforum = "AND f.type <> 'teacher'";
4cabd355 989
990 $forummodule = get_record("modules", "name", "forum");
991 $onlyvisible = " AND f.id = cm.instance AND cm.visible = 1 AND cm.module = $forummodule->id";
992 $onlyvisibletable = ", {$CFG->prefix}course_modules cm";
9fa49e22 993 } else {
994 $notteacherforum = "";
4cabd355 995
996 $onlyvisible = "";
997 $onlyvisibletable = "";
9fa49e22 998 }
999
c2a96d6b 1000 switch ($CFG->dbtype) {
1001 case "mysql":
1002 $limit = "LIMIT $page,$recordsperpage";
1003 break;
1004 case "postgres7":
1005 $limit = "LIMIT $recordsperpage OFFSET ".($page * $recordsperpage);
1006 break;
65b0e537 1007 default:
c2a96d6b 1008 $limit = "LIMIT $recordsperpage,$page";
97485d07 1009 }
1010
63d99fcb 1011 /// Some differences in syntax for PostgreSQL
1012 if ($CFG->dbtype == "postgres7") {
a74f950c 1013 $LIKE = "ILIKE"; // case-insensitive
2b4c64e9 1014 $NOTLIKE = "NOT ILIKE"; // case-insensitive
1015 $REGEXP = "~*";
1016 $NOTREGEXP = "!~*";
b800ac5a 1017 } else {
a74f950c 1018 $LIKE = "LIKE";
2b4c64e9 1019 $NOTLIKE = "NOT LIKE";
a74f950c 1020 $REGEXP = "REGEXP";
2b4c64e9 1021 $NOTREGEXP = "NOT REGEXP";
c4c57597 1022 }
1023
b800ac5a 1024 $messagesearch = "";
855c0839 1025 $searchstring = "";
1026 // Need to concat these back together for parser to work.
1027 foreach($searchterms as $searchterm){
1028 if ($searchstring != "") {
1029 $searchstring .= " ";
63d99fcb 1030 }
855c0839 1031 $searchstring .= $searchterm;
b800ac5a 1032 }
1033
855c0839 1034 // We need to allow quoted strings for the search. The quotes *should* be stripped
1035 // by the parser, but this should be examined carefully for security implications.
1036 $searchstring = str_replace("\\\"","\"",$searchstring);
1037 $parser = new search_parser();
1038 $lexer = new search_lexer(&$parser);
1039 if ($lexer->parse($searchstring)) {
1040 $parsearray = $parser->get_parsed_array();
1041 $messagesearch = search_generate_SQL($parsearray,"p.message","p.subject","p.userid","u.id","u.firstname","u.lastname");
1042 }
1043
65b0e537 1044 $selectsql = "{$CFG->prefix}forum_posts p,
1045 {$CFG->prefix}forum_discussions d,
1046 {$CFG->prefix}user u,
4cabd355 1047 {$CFG->prefix}forum f $onlyvisibletable
855c0839 1048 WHERE ($messagesearch)
65b0e537 1049 AND p.userid = u.id
1050 AND p.discussion = d.id
1051 AND d.course = '$courseid'
4cabd355 1052 AND d.forum = f.id $notteacherforum $onlyvisible";
65b0e537 1053
8b9c7aa0 1054 $totalcount = count_records_sql("SELECT COUNT(*) FROM $selectsql");
b800ac5a 1055
8b9c7aa0 1056 return get_records_sql("SELECT p.*,u.firstname,u.lastname,u.email,u.picture FROM
1057 $selectsql ORDER BY p.modified DESC $limit");
9fa49e22 1058}
1059
63d99fcb 1060
9fa49e22 1061function forum_get_ratings($postid, $sort="u.firstname ASC") {
1062/// Returns a list of ratings for a particular post - sorted.
1063 global $CFG;
65b0e537 1064 return get_records_sql("SELECT u.*, r.rating, r.time
1065 FROM {$CFG->prefix}forum_ratings r,
9fa49e22 1066 {$CFG->prefix}user u
65b0e537 1067 WHERE r.post = '$postid'
1068 AND r.userid = u.id
9fa49e22 1069 ORDER BY $sort");
1070}
1071
3ecca1ee 1072function forum_get_unmailed_posts($starttime, $endtime) {
1f48942e 1073/// Returns a list of all new posts that have not been mailed yet
1074 global $CFG;
65b0e537 1075 return get_records_sql("SELECT p.*, d.course
1076 FROM {$CFG->prefix}forum_posts p,
1f48942e 1077 {$CFG->prefix}forum_discussions d
65b0e537 1078 WHERE p.mailed = 0
3ecca1ee 1079 AND p.created >= '$starttime'
1080 AND p.created < '$endtime'
c274b0e0 1081 AND p.discussion = d.id
1082 ORDER BY p.modified ASC");
1f48942e 1083}
1084
3ecca1ee 1085function forum_mark_old_posts_as_mailed($endtime) {
1086/// Marks posts before a certain time as being mailed already
1087 global $CFG;
c274b0e0 1088 return execute_sql("UPDATE {$CFG->prefix}forum_posts
1089 SET mailed = '1'
1090 WHERE created < '$endtime'");
3ecca1ee 1091}
1092
1f48942e 1093function forum_get_user_posts($forumid, $userid) {
1094/// Get all the posts for a user in a forum suitable for forum_print_post
1095 global $CFG;
1096
ebc3bd2b 1097 return get_records_sql("SELECT p.*, u.firstname, u.lastname, u.email, u.picture
65b0e537 1098 FROM {$CFG->prefix}forum f,
1099 {$CFG->prefix}forum_discussions d,
1100 {$CFG->prefix}forum_posts p,
1101 {$CFG->prefix}user u
1102 WHERE f.id = '$forumid'
1103 AND d.forum = f.id
1f48942e 1104 AND p.discussion = d.id
65b0e537 1105 AND p.userid = '$userid'
ebc3bd2b 1106 AND p.userid = u.id
1f48942e 1107 ORDER BY p.modified ASC");
1108}
1109
1110function forum_get_post_from_log($log) {
1111/// Given a log entry, return the forum post details for it.
1112 global $CFG;
1113
1114 if ($log->action == "add post") {
1115
2f9c977e 1116 return get_record_sql("SELECT p.*, d.forum, d.groupid, u.firstname, u.lastname, u.email, u.picture
65b0e537 1117 FROM {$CFG->prefix}forum_discussions d,
1118 {$CFG->prefix}forum_posts p,
1119 {$CFG->prefix}user u
1120 WHERE p.id = '$log->info'
1121 AND d.id = p.discussion
1122 AND p.userid = u.id
1f48942e 1123 AND u.deleted <> '1'");
1124
1125
1126 } else if ($log->action == "add discussion") {
1127
2f9c977e 1128 return get_record_sql("SELECT p.*, d.forum, d.groupid, u.firstname, u.lastname, u.email, u.picture
65b0e537 1129 FROM {$CFG->prefix}forum_discussions d,
1130 {$CFG->prefix}forum_posts p,
1131 {$CFG->prefix}user u
1132 WHERE d.id = '$log->info'
1133 AND d.firstpost = p.id
1134 AND p.userid = u.id
1f48942e 1135 AND u.deleted <> '1'");
1136 }
1137 return NULL;
1138}
1139
d05956ac 1140function forum_get_firstpost_from_discussion($discussionid) {
1141/// Given a discussion id, return the first post from the discussion
1142 global $CFG;
1143
1144 return get_record_sql("SELECT p.*
65b0e537 1145 FROM {$CFG->prefix}forum_discussions d,
d05956ac 1146 {$CFG->prefix}forum_posts p
65b0e537 1147 WHERE d.id = '$discussionid'
d05956ac 1148 AND d.firstpost = p.id ");
1149}
1150
1f48942e 1151
1152function forum_get_user_grades($forumid) {
1153/// Get all user grades for a forum
1154 global $CFG;
1155
ebc3bd2b 1156 return get_records_sql("SELECT r.id, p.userid, r.rating
65b0e537 1157 FROM {$CFG->prefix}forum_discussions d,
1158 {$CFG->prefix}forum_posts p,
1f48942e 1159 {$CFG->prefix}forum_ratings r
65b0e537 1160 WHERE d.forum = '$forumid'
1f48942e 1161 AND p.discussion = d.id
02ebf404 1162 AND r.post = p.id
1163 ORDER by p.userid ");
1f48942e 1164}
1165
1166
1167function forum_count_discussion_replies($forum="0") {
1168// Returns an array of counts of replies to each discussion (optionally in one forum)
1169 global $CFG;
1170
1171 if ($forum) {
1172 $forumselect = " AND d.forum = '$forum'";
f37da850 1173 } else {
1174 $forumselect = '';
1f48942e 1175 }
3599e487 1176 return get_records_sql("SELECT p.discussion, (count(*)) as replies, max(p.id) as lastpostid
65b0e537 1177 FROM {$CFG->prefix}forum_posts p,
1f48942e 1178 {$CFG->prefix}forum_discussions d
65b0e537 1179 WHERE p.parent > 0
1180 AND p.discussion = d.id
f37da850 1181 {$forumselect}
1f48942e 1182 GROUP BY p.discussion");
1183}
1184
1185function forum_count_unrated_posts($discussionid, $userid) {
1186// How many unrated posts are in the given discussion for a given user?
1187 global $CFG;
1188 if ($posts = get_record_sql("SELECT count(*) as num
1189 FROM {$CFG->prefix}forum_posts
65b0e537 1190 WHERE parent > 0
1191 AND discussion = '$discussionid'
ebc3bd2b 1192 AND userid <> '$userid' ")) {
1f48942e 1193
65b0e537 1194 if ($rated = get_record_sql("SELECT count(*) as num
1195 FROM {$CFG->prefix}forum_posts p,
1f48942e 1196 {$CFG->prefix}forum_ratings r
1197 WHERE p.discussion = '$discussionid'
65b0e537 1198 AND p.id = r.post
ebc3bd2b 1199 AND r.userid = '$userid'")) {
1f48942e 1200 $difference = $posts->num - $rated->num;
1201 if ($difference > 0) {
1202 return $difference;
1203 } else {
1204 return 0; // Just in case there was a counting error
1205 }
1206 } else {
1207 return $posts->num;
1208 }
1209 } else {
1210 return 0;
1211 }
1212}
1213
65b0e537 1214function forum_get_discussions($forum="0", $forumsort="d.timemodified DESC",
2862b309 1215 $user=0, $fullpost=true, $visiblegroups=-1) {
1f48942e 1216/// Get all discussions in a forum
1217 global $CFG;
1218
1219 if ($user) {
1220 $userselect = " AND u.id = '$user' ";
1221 } else {
1222 $userselect = "";
1223 }
2862b309 1224
8f0cd6ef 1225
2862b309 1226 if ($visiblegroups == -1) {
02509fe6 1227 $groupselect = "";
2862b309 1228 } else {
1229 $groupselect = " AND (d.groupid = '$visiblegroups' OR d.groupid = '-1') ";
02509fe6 1230 }
2862b309 1231
29507631 1232 if (empty($forumsort)) {
1233 $forumsort = "d.timemodified DESC";
1234 }
2ab968e9 1235 if (empty($fullpost)) {
b879effb 1236 $postdata = "p.id,p.subject,p.modified,p.discussion,p.userid";
2ab968e9 1237 } else {
1238 $postdata = "p.*";
1239 }
9197e147 1240
cf84431b 1241 return get_records_sql("SELECT $postdata, d.name, d.timemodified, d.usermodified,
268c6485 1242 u.firstname, u.lastname, u.email, u.picture,
1243 um.firstname AS umfirstname, um.lastname AS umlastname
65b0e537 1244 FROM {$CFG->prefix}forum_discussions d,
9197e147 1245 {$CFG->prefix}forum_posts p,
268c6485 1246 {$CFG->prefix}user um,
65b0e537 1247 {$CFG->prefix}user u
1248 WHERE d.forum = '$forum'
1249 AND p.discussion = d.id
1250 AND p.parent = 0
9197e147 1251 AND p.userid = u.id $groupselect $userselect
f37da850 1252 AND (d.usermodified = um.id OR d.usermodified = 0)
29507631 1253 ORDER BY $forumsort");
1f48942e 1254}
1255
1256
1257
b656e2a9 1258function forum_get_user_discussions($courseid, $userid, $groupid=0) {
1259/// Get all discussions started by a particular user in a course (or group)
1f48942e 1260 global $CFG;
1261
b656e2a9 1262 if ($groupid) {
1263 $groupselect = " AND d.groupid = '$groupid' ";
1264 } else {
1265 $groupselect = "";
1266 }
1267
2862b309 1268 return get_records_sql("SELECT p.*, d.groupid, u.firstname, u.lastname, u.email, u.picture,
ebc3bd2b 1269 f.type as forumtype, f.name as forumname, f.id as forumid
65b0e537 1270 FROM {$CFG->prefix}forum_discussions d,
1271 {$CFG->prefix}forum_posts p,
1272 {$CFG->prefix}user u,
1f48942e 1273 {$CFG->prefix}forum f
65b0e537 1274 WHERE d.course = '$courseid'
1275 AND p.discussion = d.id
1276 AND p.parent = 0
1277 AND p.userid = u.id
1278 AND u.id = '$userid'
b656e2a9 1279 AND d.forum = f.id $groupselect
b8bf90c5 1280 ORDER BY p.created DESC");
1f48942e 1281}
1282
1283
6673d7bd 1284function forum_subscribed_users($course, $forum, $groupid=0) {
1f48942e 1285/// Returns list of user objects that are subscribed to this forum
1286 global $CFG;
1287
6673d7bd 1288 if ($groupid) {
1289 $grouptables = ", {$CFG->prefix}groups_members g";
1290 $groupselect = " AND g.groupid = '$groupid' AND u.id = g.userid";
1291 } else {
1292 $grouptables = "";
1293 $groupselect = "";
1294 }
1295
709f0ec8 1296 if (forum_is_forcesubscribed($forum->id)) {
7b5944cd 1297 if ($forum->type == "teacher") {
1298 return get_course_teachers($course->id); // Only teachers can be subscribed to teacher forums
adaf3928 1299 } else {
7b5944cd 1300 return get_course_users($course->id); // Otherwise get everyone in the course
1f48942e 1301 }
1302 }
aaf7a9dc 1303 return get_records_sql("SELECT u.id, u.username, u.firstname, u.lastname, u.maildisplay, u.mailformat, u.maildigest, u.emailstop,
0351b1f9 1304 u.email, u.city, u.country, u.lastaccess, u.lastlogin, u.picture, u.timezone, u.lang
65b0e537 1305 FROM {$CFG->prefix}user u,
6673d7bd 1306 {$CFG->prefix}forum_subscriptions s $grouptables
1f48942e 1307 WHERE s.forum = '$forum->id'
65b0e537 1308 AND s.userid = u.id
6673d7bd 1309 AND u.deleted <> 1 $groupselect
7c81b6e2 1310 ORDER BY u.email ASC");
1f48942e 1311}
9fa49e22 1312
067675c0 1313
1314
caadf009 1315/// OTHER FUNCTIONS ///////////////////////////////////////////////////////////
f93f848a 1316
1317
11b0c469 1318function forum_get_course_forum($courseid, $type) {
1319// How to set up special 1-per-course forums
a6fcdf98 1320 global $CFG;
1321
29cbd93a 1322 if ($forums = get_records_select("forum", "course = '$courseid' AND type = '$type'", "id ASC")) {
65b0e537 1323 // There should always only be ONE, but with the right combination of
29cbd93a 1324 // errors there might be more. In this case, just return the oldest one (lowest ID).
1325 foreach ($forums as $forum) {
1326 return $forum; // ie the first one
11b0c469 1327 }
8daaf761 1328 }
e6874d9f 1329
8daaf761 1330 // Doesn't exist, so create one now.
1331 $forum->course = $courseid;
1332 $forum->type = "$type";
1333 switch ($forum->type) {
1334 case "news":
65a3ef30 1335 $forum->name = addslashes(get_string("namenews", "forum"));
1336 $forum->intro = addslashes(get_string("intronews", "forum"));
906fef94 1337 $forum->forcesubscribe = FORUM_FORCESUBSCRIBE;
8daaf761 1338 $forum->open = 1; // 0 - no, 1 - posts only, 2 - discuss and post
1339 $forum->assessed = 0;
709f0ec8 1340 if ($courseid == SITEID) {
1341 $forum->name = get_string("sitenews");
1342 $forum->forcesubscribe = 0;
8f0cd6ef 1343 }
8daaf761 1344 break;
1345 case "social":
65a3ef30 1346 $forum->name = addslashes(get_string("namesocial", "forum"));
1347 $forum->intro = addslashes(get_string("introsocial", "forum"));
8daaf761 1348 $forum->open = 2; // 0 - no, 1 - posts only, 2 - discuss and post
1349 $forum->assessed = 0;
1350 $forum->forcesubscribe = 0;
1351 break;
1352 case "teacher":
65a3ef30 1353 $forum->name = addslashes(get_string("nameteacher", "forum"));
1354 $forum->intro = addslashes(get_string("introteacher", "forum"));
a796d0b8 1355 $forum->open = 2; // 0 - no, 1 - posts only, 2 - discuss and post
8daaf761 1356 $forum->assessed = 0;
1357 $forum->forcesubscribe = 0;
1358 break;
1359 default:
1360 notify("That forum type doesn't exist!");
1361 return false;
1362 break;
1363 }
1364
1365 $forum->timemodified = time();
1366 $forum->id = insert_record("forum", $forum);
1367
1368 if ($forum->type != "teacher") {
1369 if (! $module = get_record("modules", "name", "forum")) {
1370 notify("Could not find forum module!!");
1371 return false;
1372 }
1373 $mod->course = $courseid;
1374 $mod->module = $module->id;
1375 $mod->instance = $forum->id;
1376 $mod->section = 0;
1377 if (! $mod->coursemodule = add_course_module($mod) ) { // assumes course/lib.php is loaded
1378 notify("Could not add a new course module to the course '$course->fullname'");
1379 return false;
1380 }
1381 if (! $sectionid = add_mod_to_section($mod) ) { // assumes course/lib.php is loaded
1382 notify("Could not add the new course module to that section");
1383 return false;
1384 }
1385 if (! set_field("course_modules", "section", $sectionid, "id", $mod->coursemodule)) {
1386 notify("Could not update the course module with the correct section");
1387 return false;
1388 }
1389 include_once("$CFG->dirroot/course/lib.php");
d769d2ee 1390 rebuild_course_cache($courseid);
82aa0e8d 1391 }
65b0e537 1392
8daaf761 1393 return get_record("forum", "id", "$forum->id");
82aa0e8d 1394}
1395
f93f848a 1396
65b0e537 1397function forum_make_mail_post(&$post, $user, $touser, $course,
11b0c469 1398 $ownpost=false, $reply=false, $link=false, $rate=false, $footer="") {
65b0e537 1399// Given the data about a posting, builds up the HTML to display it and
501cdbd8 1400// returns the HTML in a string. This is designed for sending via HTML email.
1401
d30867b0 1402 global $CFG;
501cdbd8 1403
0d851f90 1404 static $formattedtext; // Cached version of formatted text for a post
1405 static $formattedtextid; // The ID number of the post
1406
1407 if (empty($formattedtextid) or $formattedtextid != $post->id) { // Recalculate the formatting
1408 $formattedtext = format_text($post->message, $post->format, NULL, $course->id);
1409 $formattedtextid = $post->id;
1410 }
1411
501cdbd8 1412 $output = "";
1413
9c674431 1414 $output .= '<table border="0" cellpadding="3" cellspacing="0" class="forumpost">';
501cdbd8 1415
d30867b0 1416 $output .= "<tr><td width=\"35\" valign=\"top\" class=\"forumpostpicture\">";
501cdbd8 1417 $output .= print_user_picture($user->id, $course->id, $user->picture, false, true);
72d497d4 1418 $output .= "</td>";
501cdbd8 1419
1420 if ($post->parent) {
d30867b0 1421 $output .= "<td nowrap=\"nowrap\" class=\"forumpostheader\">";
501cdbd8 1422 } else {
d30867b0 1423 $output .= "<td nowrap=\"nowrap\" class=\"forumpostheadertopic\">";
501cdbd8 1424 }
72d497d4 1425 $output .= "<p>";
41905731 1426 $output .= "<font size=\"3\"><b>$post->subject</b></font><br />";
1427 $output .= "<font size=\"2\">";
1b26d5e7 1428
1429 $fullname = fullname($user, isteacher($course->id));
839f2456 1430 $by->name = "<a href=\"$CFG->wwwroot/user/view.php?id=$user->id&amp;course=$course->id\">$fullname</a>";
d62413e8 1431 $by->date = userdate($post->modified, "", $touser->timezone);
ffe11640 1432 $output .= get_string("bynameondate", "forum", $by);
1b26d5e7 1433
72d497d4 1434 $output .= "</font></p></td></tr>";
d30867b0 1435 $output .= "<tr><td width=\"10\" class=\"forumpostside\">";
501cdbd8 1436 $output .= "&nbsp;";
d30867b0 1437 $output .= "</td><td class=\"forumpostmessage\">\n";
501cdbd8 1438
7f6689e4 1439 if ($post->attachment) {
1440 $post->course = $course->id;
1441 $post->forum = get_field("forum_discussions", "forum", "id", $post->discussion);
41905731 1442 $output .= "<div align=\"right\">";
7f6689e4 1443 $output .= forum_print_attachments($post, "html");
72d497d4 1444 $output .= "</div>";
7f6689e4 1445 }
1446
0d851f90 1447 $output .= $formattedtext;
501cdbd8 1448
839f2456 1449 $output .= "<p align=\"right\"><font size=\"-1\">";
501cdbd8 1450
2e2e71a8 1451 if ($post->parent) {
839f2456 1452 $output .= "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion&amp;parent=$post->parent\">".get_string("parent", "forum")."</a> | ";
2e2e71a8 1453 }
ce45515e 1454
501cdbd8 1455 $age = time() - $post->created;
1456 if ($ownpost) {
14eef464 1457 $output .= "<a href=\"$CFG->wwwroot/mod/forum/post.php?delete=$post->id\">".get_string("delete", "forum")."</a>";
501cdbd8 1458 if ($reply) {
cf84431b 1459 $output .= "<a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/post.php?reply=$post->id\">".get_string("replyforum", "forum")."</a>";
501cdbd8 1460 }
1461 $output .= "&nbsp;&nbsp;";
1462 } else {
1463 if ($reply) {
02509fe6 1464 $output .= "<a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/post.php?reply=$post->id\">".get_string("replyforum", "forum")."</a>&nbsp;&nbsp;";
501cdbd8 1465 }
1466 }
1467
72d497d4 1468 $output .= "</p>";
41905731 1469 $output .= "<div align=\"right\"><p align=\"right\">";
65b0e537 1470
501cdbd8 1471 if ($link) {
1472 if ($post->replies == 1) {
ffe11640 1473 $replystring = get_string("repliesone", "forum", $post->replies);
501cdbd8 1474 } else {
ffe11640 1475 $replystring = get_string("repliesmany", "forum", $post->replies);
501cdbd8 1476 }
41905731 1477 $output .= "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\"><b>".get_string("discussthistopic", "forum")."</b></a> ($replystring)&nbsp;&nbsp;";
501cdbd8 1478 }
72d497d4 1479 $output .= "</p></div>";
501cdbd8 1480 if ($footer) {
72d497d4 1481 $output .= "<p>$footer</p>";
501cdbd8 1482 }
72d497d4 1483 $output .= "</td></tr></table>\n\n";
501cdbd8 1484
1485 return $output;
1486}
1487
1488
65b0e537 1489function forum_print_post(&$post, $courseid, $ownpost=false, $reply=false, $link=false,
f37da850 1490 $ratings=NULL, $footer="", $highlight="", $post_read=-99) {
74f5d1e3 1491
d30867b0 1492 global $USER, $CFG;
501cdbd8 1493
359f2758 1494 static $stredit, $strdelete, $strreply, $strparent, $strprune, $strpruneheading, $threadedmode, $isteacher, $adminedit;
2e2e71a8 1495
f37da850 1496 static $strmarkread, $strmarkunread;
1497
2e2e71a8 1498 if (empty($stredit)) {
359f2758 1499 $stredit = get_string('edit', 'forum');
1500 $strdelete = get_string('delete', 'forum');
1501 $strreply = get_string('reply', 'forum');
1502 $strparent = get_string('parent', 'forum');
1503 $strpruneheading = get_string('pruneheading', 'forum');
1504 $strprune = get_string('prune', 'forum');
2e2e71a8 1505 $threadedmode = (!empty($USER->mode) and ($USER->mode == FORUM_MODE_THREADED));
3bd98ad4 1506 $isteacher = isteacher($courseid);
b8be40ce 1507 $adminedit = (isadmin() and !empty($CFG->admineditalways));
f37da850 1508 $strmarkread = get_string('markread', 'forum');
1509 $strmarkunread = get_string('markunread', 'forum');
1510 }
1511
1512 if ($CFG->forum_trackreadposts) {
1513 if ($post_read == -99) { // If we don't know yet...
489de4ae 1514 /// The front page can display a news item post to non-logged in users. This should
1515 /// always appear as 'read'.
1516 $post_read = empty($USER) || forum_tp_is_post_read($USER->id, $post);
f37da850 1517 }
1518 if ($post_read) {
1519 $read_style = ' read';
1520 } else {
1521 $read_style = ' unread';
1522 echo '<a name="unread"></a>';
1523 }
1524 } else {
1525 $read_style = '';
2e2e71a8 1526 }
1527
f37da850 1528 echo '<a name="'.$post->id.'"></a>';
501cdbd8 1529 if ($post->parent) {
f37da850 1530 echo '<table border="0" cellpadding="3" cellspacing="0" class="forumpost'.$read_style.'">';
501cdbd8 1531 } else {
f37da850 1532 echo '<table border="0" cellpadding="3" cellspacing="0" class="forumpost'.$read_style.'" width="100%">';
501cdbd8 1533 }
1534
d30867b0 1535 echo "<tr><td class=\"forumpostpicture\" width=\"35\" valign=\"top\">";
501cdbd8 1536 print_user_picture($post->userid, $courseid, $post->picture);
72d497d4 1537 echo "</td>";
501cdbd8 1538
1539 if ($post->parent) {
d30867b0 1540 echo "<td class=\"forumpostheader\" width=\"100%\">";
501cdbd8 1541 } else {
d30867b0 1542 echo "<td class=\"forumpostheadertopic\" width=\"100%\">";
501cdbd8 1543 }
83ec9098 1544
1545 if (!empty($CFG->filterall)) { /// Put the subject through the filters
34e934a9 1546 $post->subject = filter_text("<nolink>$post->subject</nolink>", $courseid);
83ec9098 1547 }
41905731 1548 echo "<font size=\"3\"><b>$post->subject</b></font><br />";
1549 echo "<font size=\"2\">";
f37da850 1550
3bd98ad4 1551 $fullname = fullname($post, $isteacher);
839f2456 1552 $by->name = "<a href=\"$CFG->wwwroot/user/view.php?id=$post->userid&amp;course=$courseid\">$fullname</a>";
d62413e8 1553 $by->date = userdate($post->modified);
ffe11640 1554 print_string("bynameondate", "forum", $by);
1b26d5e7 1555
f37da850 1556 if ($CFG->forum_trackreadposts) {
1557 echo "</font></span></td></tr>";
1558 } else {
1559 echo "</font></td></tr>";
1560 }
1561
d30867b0 1562 echo "<tr><td valign=\"top\" class=\"forumpostside\" width=\"10\">";
507407a7 1563 if ($group = user_group($courseid, $post->userid)) {
a4fbb0b2 1564 print_group_picture($group, $courseid, false, false, true);
507407a7 1565 } else {
1566 echo "&nbsp;";
1567 }
d30867b0 1568 echo "</td><td class=\"forumpostmessage\">\n";
501cdbd8 1569
7f6689e4 1570 if ($post->attachment) {
1571 $post->course = $courseid;
1572 $post->forum = get_field("forum_discussions", "forum", "id", $post->discussion);
72d497d4 1573 echo "<div align=\"right\">";
1574 $attachedimages = forum_print_attachments($post);
1575 echo "</div>";
e9c2dc1f 1576 } else {
1577 $attachedimages = "";
7f6689e4 1578 }
1579
5be7800c 1580 if ($link and (strlen(strip_tags($post->message)) > $CFG->forum_longpost)) {
aa153f29 1581 // Print shortened version
71767204 1582 echo format_text(forum_shorten_post($post->message), $post->format, NULL, $courseid);
c585fa17 1583 $numwords = count_words(strip_tags($post->message));
72d497d4 1584 echo "<p><a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\">";
ffe11640 1585 echo get_string("readtherest", "forum");
72d497d4 1586 echo "</a> (".get_string("numwords", "", $numwords).")...</p>";
501cdbd8 1587 } else {
aa153f29 1588 // Print whole message
88438a58 1589 if ($highlight) {
71767204 1590 echo highlight($highlight, format_text($post->message, $post->format, NULL, $courseid));
88438a58 1591 } else {
71767204 1592 echo format_text($post->message, $post->format, NULL, $courseid);
88438a58 1593 }
65b0e537 1594 echo $attachedimages;
501cdbd8 1595 }
1596
359f2758 1597 $commands = array();
501cdbd8 1598
f37da850 1599 if ($CFG->forum_trackreadposts) {
489de4ae 1600 /// SPECIAL CASE: The front page can display a news item post to non-logged in users.
1601 /// Don't display the mark read / unread controls in this case.
1602 if ($CFG->forum_usermarksread && !empty($USER)) {
f37da850 1603 if ($post_read) {
1604 $mcmd = '&amp;mark=unread&amp;postid='.$post->id;
1605 $mtxt = $strmarkunread;
1606 } else {
1607 $mcmd = '&amp;mark=read&amp;postid='.$post->id;
1608 $mtxt = $strmarkread;
1609 }
1610 if ($threadedmode) {
1611 $commands[] = "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion&amp;parent=$post->id$mcmd\">$mtxt</a>";
1612 } else {
1613 $commands[] = "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion$mcmd#$post->id\">$mtxt</a>";
1614 }
1615 }
1616 }
1617
2e2e71a8 1618 if ($post->parent) {
1619 if ($threadedmode) {
839f2456 1620 $commands[] = "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion&amp;parent=$post->parent\">$strparent</a>";
2e2e71a8 1621 } else {
359f2758 1622 $commands[] = "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion#$post->parent\">$strparent</a>";
2e2e71a8 1623 }
1624 }
1625
501cdbd8 1626 $age = time() - $post->created;
b8be40ce 1627 if ($ownpost or $adminedit) {
1628 if (($age < $CFG->maxeditingtime) or $adminedit) {
359f2758 1629 $commands[] = "<a href=\"$CFG->wwwroot/mod/forum/post.php?edit=$post->id\">$stredit</a>";
501cdbd8 1630 }
64eacd6f 1631 }
aaf7a9dc 1632
cf84431b 1633 if (isteacheredit($courseid) and $post->parent) {
359f2758 1634 $commands[] = "<a href=\"$CFG->wwwroot/mod/forum/post.php?prune=$post->id\" title=\"$strpruneheading\">$strprune</a>";
cf84431b 1635 }
aaf7a9dc 1636
ac00b904 1637 if (($ownpost and $age < $CFG->maxeditingtime) or $isteacher) {
359f2758 1638 $commands[] = "<a href=\"$CFG->wwwroot/mod/forum/post.php?delete=$post->id\">$strdelete</a>";
64eacd6f 1639 }
359f2758 1640
64eacd6f 1641 if ($reply) {
359f2758 1642 $commands[] = "<a href=\"$CFG->wwwroot/mod/forum/post.php?reply=$post->id\">$strreply</a>";
501cdbd8 1643 }
839f2456 1644 echo "<p align=\"right\"><font size=\"-1\">";
359f2758 1645 echo implode(' | ', $commands).'&nbsp;&nbsp;';
1646 echo "</font></p>";
501cdbd8 1647
41905731 1648 echo "<div align=\"right\"><p align=\"right\">";
74f5d1e3 1649
1650 $ratingsmenuused = false;
02ebf404 1651 if (!empty($ratings) and !empty($USER->id)) {
98914efd 1652 $useratings = true;
1653 if ($ratings->assesstimestart and $ratings->assesstimefinish) {
1654 if ($post->created < $ratings->assesstimestart or $post->created > $ratings->assesstimefinish) {
1655 $useratings = false;
1656 }
1657 }
1658 if ($useratings) {
3bd98ad4 1659 $mypost = ($USER->id == $post->userid);
1660
1661 if (($isteacher or $ratings->assesspublic) and !$mypost) {
1662 forum_print_ratings_mean($post->id, $ratings->scale, $isteacher);
d395046a 1663 if (!empty($ratings->allow)) {
1664 forum_print_rating_menu($post->id, $USER->id, $ratings->scale);
1665 $ratingsmenuused = true;
1666 }
3bd98ad4 1667
1668 } else if ($mypost) {
1669 forum_print_ratings_mean($post->id, $ratings->scale, true);
1670
98914efd 1671 } else if (!empty($ratings->allow) ) {
1672 forum_print_rating_menu($post->id, $USER->id, $ratings->scale);
74f5d1e3 1673 $ratingsmenuused = true;
2a3cda19 1674 }
501cdbd8 1675 }
1676 }
65b0e537 1677
501cdbd8 1678 if ($link) {
1679 if ($post->replies == 1) {
ffe11640 1680 $replystring = get_string("repliesone", "forum", $post->replies);
501cdbd8 1681 } else {
ffe11640 1682 $replystring = get_string("repliesmany", "forum", $post->replies);
501cdbd8 1683 }
74f5d1e3 1684 echo "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\"><b>".
1685 get_string("discussthistopic", "forum")."</b></a> ($replystring)&nbsp;&nbsp;";
501cdbd8 1686 }
72d497d4 1687 echo "</p>";
501cdbd8 1688 if ($footer) {
72d497d4 1689 echo "<p>$footer</p>";
501cdbd8 1690 }
72d497d4 1691 echo "</div>";
1692 echo "</td></tr>\n</table>\n\n";
74f5d1e3 1693
f37da850 1694/// *** Need to get the forum ID from somewhere. Its not automatically part of post.
1695/// *** Backtrack through code to find where 'post' gets set.
1696 if ($CFG->forum_trackreadposts && !$CFG->forum_usermarksread && !empty($post->forum)) {
1697 forum_tp_mark_post_read($USER->id, $post, $post->forum);
1698 }
1699
74f5d1e3 1700 return $ratingsmenuused;
501cdbd8 1701}
1702
3335f6fb 1703
a796d0b8 1704function forum_print_discussion_header(&$post, $forum, $datestring="") {
43921b8a 1705/// This function prints the overview of a discussion in the forum listing.
1706/// It needs some discussion information and some post information, these
8f0cd6ef 1707/// happen to be combined for efficiency in the $post parameter by the function
43921b8a 1708/// that calls this one
1709/// forum_print_latest_discussions()
1710
d30867b0 1711 global $USER, $CFG;
3335f6fb 1712
436a7cae 1713 if (!empty($CFG->filterall)) {
a796d0b8 1714 $post->subject = filter_text("<nolink>$post->subject</nolink>", $forum->course);
436a7cae 1715 }
1716
29507631 1717 echo "<tr class=\"forumpostheader\">";
3335f6fb 1718
29507631 1719 // Topic
d30867b0 1720 echo "<td class=\"forumpostheadertopic\" width=\"100%\">";
29507631 1721 echo "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\">$post->subject</a>";
1722 echo "</td>\n";
1723
1724 // Picture
d30867b0 1725 echo "<td class=\"forumpostheaderpicture\" width=\"35\">";
a796d0b8 1726 print_user_picture($post->userid, $forum->course, $post->picture);
29507631 1727 echo "</td>\n";
3335f6fb 1728
29507631 1729 // User name
a796d0b8 1730 $fullname = fullname($post, isteacher($forum->course));
d30867b0 1731 echo "<td class=\"forumpostheadername\" align=\"left\" nowrap=\"nowrap\">";
839f2456 1732 echo "<a href=\"$CFG->wwwroot/user/view.php?id=$post->userid&amp;course=$forum->course\">$fullname</a>";
29507631 1733 echo "</td>\n";
1734
a796d0b8 1735 if ($forum->open or $forum->type == "teacher") { // Show the column with replies
d30867b0 1736 echo "<td class=\"forumpostheaderreplies\" align=\"center\" nowrap=\"nowrap\">";
f37da850 1737 echo "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\">";
1738 echo $post->replies."</a>";
a796d0b8 1739 echo "</td>\n";
f37da850 1740
1741 if ($CFG->forum_trackreadposts) {
1742 echo '<td class="forumpostheaderreplies" align="center" nowrap="nowrap">';
1743 echo "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion#unread\">";
1744 if ($post->unread > 0) echo '<span class="unread">';
1745 echo $post->unread;
1746 if ($post->unread > 0) echo '</span>';
1747 echo '</a>';
1748 echo "</td>\n";
1749 }
1750
a796d0b8 1751 }
3335f6fb 1752
d30867b0 1753 echo "<td class=\"forumpostheaderdate\" align=\"right\" nowrap=\"nowrap\">";
43921b8a 1754 $usedate = (empty($post->timemodified)) ? $post->modified : $post->timemodified; // Just in case
839f2456 1755 $parenturl = (empty($post->lastpostid)) ? '' : '&amp;parent='.$post->lastpostid;
268c6485 1756 $usermodified->firstname = $post->umfirstname;
1757 $usermodified->lastname = $post->umlastname;
1758 echo "<a href=\"$CFG->wwwroot/user/view.php?id=$post->usermodified&amp;course=$forum->course\">".
1759 fullname($usermodified)."</a><br />";
ac00b904 1760 echo '<a href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.$parenturl.'">'.
43921b8a 1761 userdate($usedate, $datestring).'</a>';
29507631 1762 echo "</td>\n";
1763
1764 echo "</tr>\n";
3335f6fb 1765
3335f6fb 1766}
1767
1768
aa153f29 1769function forum_shorten_post($message) {
c585fa17 1770// Given a post object that we already know has a long message
65b0e537 1771// this function truncates the message nicely to the first
5be7800c 1772// sane place between $CFG->forum_longpost and $CFG->forum_shortpost
1773
1774 global $CFG;
c585fa17 1775
1776 $i = 0;
1777 $tag = false;
1778 $length = strlen($message);
1779 $count = 0;
1780 $stopzone = false;
1781 $truncate = 0;
1782
1783 for ($i=0; $i<$length; $i++) {
a8afb411 1784 $char = $message[$i];
c585fa17 1785
1786 switch ($char) {
65b0e537 1787 case "<":
c585fa17 1788 $tag = true;
1789 break;
65b0e537 1790 case ">":
c585fa17 1791 $tag = false;
1792 break;
1793 default:
1794 if (!$tag) {
1795 if ($stopzone) {
67f0b4cc 1796 if ($char == ".") {
a8afb411 1797 $truncate = $i+1;
c585fa17 1798 break 2;
1799 }
1800 }
1801 $count++;
1802 }
a8afb411 1803 break;
c585fa17 1804 }
1805 if (!$stopzone) {
5be7800c 1806 if ($count > $CFG->forum_shortpost) {
c585fa17 1807 $stopzone = true;
1808 }
1809 }
1810 }
aa153f29 1811
c585fa17 1812 if (!$truncate) {
a8afb411 1813 $truncate = $i;
c585fa17 1814 }
1815
67f0b4cc 1816 return substr($message, 0, $truncate);
aa153f29 1817}
1818
501cdbd8 1819
3bd98ad4 1820function forum_print_ratings_mean($postid, $scale, $link=true) {
02ebf404 1821/// Print the multiple ratings on a post given to the current user by others.
1822/// Scale is an array of ratings
1823
1824 static $strrate;
05c47ef7 1825
1826 $mean = forum_get_ratings_mean($postid, $scale);
65b0e537 1827
05c47ef7 1828 if ($mean !== "") {
02ebf404 1829
1830 if (empty($strratings)) {
1831 $strratings = get_string("ratings", "forum");
501cdbd8 1832 }
501cdbd8 1833
02ebf404 1834 echo "$strratings: ";
3bd98ad4 1835 if ($link) {
1836 link_to_popup_window ("/mod/forum/report.php?id=$postid", "ratings", $mean, 400, 600);
1837 } else {
1838 echo "$mean ";
1839 }
501cdbd8 1840 }
1841}
1842
501cdbd8 1843
0761d83f 1844function forum_get_ratings_mean($postid, $scale, $ratings=NULL) {
1845/// Return the mean rating of a post given to the current user by others.
02ebf404 1846/// Scale is an array of possible ratings in the scale
1847/// Ratings is an optional simple array of actual ratings (just integers)
1848
1849 if (!$ratings) {
1850 $ratings = array();
1851 if ($rates = get_records("forum_ratings", "post", $postid)) {
1852 foreach ($rates as $rate) {
1853 $ratings[] = $rate->rating;
1854 }
501cdbd8 1855 }
501cdbd8 1856 }
02ebf404 1857
0761d83f 1858 $count = count($ratings);
1859
1860 if ($count == 0) {
02ebf404 1861 return "";
02ebf404 1862
0761d83f 1863 } else if ($count == 1) {
1864 return $scale[$ratings[0]];
1865
02ebf404 1866 } else {
0761d83f 1867 $total = 0;
1868 foreach ($ratings as $rating) {
1869 $total += $rating;
1870 }
1871 $mean = round( ((float)$total/(float)$count) + 0.001); // Little fudge factor so that 0.5 goes UP
65b0e537 1872
0761d83f 1873 if (isset($scale[$mean])) {
1874 return $scale[$mean]." ($count)";
1875 } else {
1876 return "$mean ($count)"; // Should never happen, hopefully
1877 }
02ebf404 1878 }
1879}
1880
1881function forum_get_ratings_summary($postid, $scale, $ratings=NULL) {
1882/// Return a summary of post ratings given to the current user by others.
1883/// Scale is an array of possible ratings in the scale
1884/// Ratings is an optional simple array of actual ratings (just integers)
1885
1886 if (!$ratings) {
1887 $ratings = array();
1888 if ($rates = get_records("forum_ratings", "post", $postid)) {
1889 foreach ($rates as $rate) {
1890 $rating[] = $rate->rating;
1891 }
1892 }
1893 }
1894
1895
1896 if (!$count = count($ratings)) {
1897 return "";
1898 }
1899
1900
1901 foreach ($scale as $key => $scaleitem) {
1902 $sumrating[$key] = 0;
1903 }
1904
1905 foreach ($ratings as $rating) {
1906 $sumrating[$rating]++;
1907 }
1908
1909 $summary = "";
1910 foreach ($scale as $key => $scaleitem) {
1911 $summary = $sumrating[$key].$summary;
1912 if ($key > 1) {
1913 $summary = "/$summary";
1914 }
1915 }
1916 return $summary;
1917}
1918
1919function forum_print_rating_menu($postid, $userid, $scale) {
65b0e537 1920/// Print the menu of ratings as part of a larger form.
02ebf404 1921/// If the post has already been - set that value.
1922/// Scale is an array of ratings
1923
1924 static $strrate;
1925
1926 if (!$rating = get_record("forum_ratings", "userid", $userid, "post", $postid)) {
1927 $rating->rating = 0;
1928 }
1929
1930 if (empty($strrate)) {
1931 $strrate = get_string("rate", "forum");
1932 }
1933
1934 choose_from_menu($scale, $postid, $rating->rating, "$strrate...");
501cdbd8 1935}
1936
7a12aab4 1937function forum_print_mode_form($discussion, $mode) {
1938 GLOBAL $FORUM_LAYOUT_MODES;
501cdbd8 1939
839f2456 1940 echo "<div align=\"center\">";
1941 popup_form("discuss.php?d=$discussion&amp;mode=", $FORUM_LAYOUT_MODES, "mode", $mode, "");
1942 echo "</div>\n";
501cdbd8 1943}
1944
97485d07 1945function forum_print_search_form($course, $search="", $return=false, $type="") {
501cdbd8 1946 global $CFG;
1947
97485d07 1948 if ($type == "plain") {
41905731 1949 $output = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr><td nowrap=\"nowrap\">";
1950 $output .= "<form name=\"search\" action=\"$CFG->wwwroot/mod/forum/search.php\">";
8b9c7aa0 1951 $output .= "<font size=\"-1\">";
72b4e283 1952 $output .= "<input name=\"search\" type=\"text\" size=\"15\" value=\"$search\" alt=\"search\" />";
b4510d53 1953 $output .= "<input value=\"".get_string("searchforums", "forum")."\" type=\"submit\" />";
8b9c7aa0 1954 $output .= "</font>";
b4510d53 1955 $output .= "<input name=\"id\" type=\"hidden\" value=\"$course->id\" />";
8b9c7aa0 1956 $output .= "</form>";
1957 $output .= "</td></tr></table>";
97485d07 1958 } else {
41905731 1959 $output = "<table border=\"0\" cellpadding=\"10\" cellspacing=\"0\"><tr><td align=\"center\">";
1960 $output .= "<form name=\"search\" action=\"$CFG->wwwroot/mod/forum/search.php\">";
8b9c7aa0 1961 $output .= "<font size=\"-1\">";
72b4e283 1962 $output .= "<input name=\"search\" type=\"text\" size=\"15\" value=\"$search\" alt=\"search\" /><br />";
b4510d53 1963 $output .= "<input value=\"".get_string("searchforums", "forum")."\" type=\"submit\" />";
8b9c7aa0 1964 $output .= "</font>";
b4510d53 1965 $output .= "<input name=\"id\" type=\"hidden\" value=\"$course->id\" />";
8b9c7aa0 1966 $output .= "</form>";
1967 $output .= "</td></tr></table>";
97485d07 1968 }
5e367a2d 1969
1970 if ($return) {
1971 return $output;
1972 }
1973 echo $output;
501cdbd8 1974}
1975
1976
11b0c469 1977function forum_set_return() {
607809b3 1978 global $CFG, $SESSION;
501cdbd8 1979
28e1e8b9 1980 if (! isset($SESSION->fromdiscussion)) {
48d38fad 1981 if (!empty($_SERVER['HTTP_REFERER'])) {
1982 $referer = $_SERVER['HTTP_REFERER'];
1983 } else {
1984 $referer = "";
1985 }
28e1e8b9 1986 // If the referer is NOT a login screen then save it.
48d38fad 1987 if (! strncasecmp("$CFG->wwwroot/login", $referer, 300)) {
607809b3 1988 $SESSION->fromdiscussion = $_SERVER["HTTP_REFERER"];
28e1e8b9 1989 }
501cdbd8 1990 }
1991}
1992
1993
11b0c469 1994function forum_go_back_to($default) {
501cdbd8 1995 global $SESSION;
1996
9c9f7d77 1997 if (!empty($SESSION->fromdiscussion)) {
501cdbd8 1998 $returnto = $SESSION->fromdiscussion;
1999 unset($SESSION->fromdiscussion);
2000 return $returnto;
2001 } else {
2002 return $default;
2003 }
2004}
2005
7f6689e4 2006function forum_file_area_name($post) {
2007// Creates a directory file name, suitable for make_upload_directory()
2008 global $CFG;
2009
2010 return "$post->course/$CFG->moddata/forum/$post->forum/$post->id";
2011}
2012
2013function forum_file_area($post) {
2014 return make_upload_directory( forum_file_area_name($post) );
2015}
2016
2017function forum_delete_old_attachments($post, $exception="") {
2018// Deletes all the user files in the attachments area for a post
2019// EXCEPT for any file named $exception
2020
2021 if ($basedir = forum_file_area($post)) {
2022 if ($files = get_directory_list($basedir)) {
2023 foreach ($files as $file) {
2024 if ($file != $exception) {
2025 unlink("$basedir/$file");
2026 notify("Existing file '$file' has been deleted!");
2027 }
2028 }
2029 }
2030 if (!$exception) { // Delete directory as well, if empty
2031 rmdir("$basedir");
2032 }
2033 }
2034}
2035
cc2b7ea5 2036function forum_move_attachments($discussion, $forumid) {
65b0e537 2037/// Given a discussion object that is being moved to forumid,
2038/// this function checks all posts in that discussion
2039/// for attachments, and if any are found, these are
cc2b7ea5 2040/// moved to the new forum directory.
2041
2042 global $CFG;
2043
18b8fbfa 2044 require_once($CFG->dirroot.'/lib/uploadlib.php');
2045
cc2b7ea5 2046 $return = true;
2047
2048 if ($posts = get_records_select("forum_posts", "discussion = '$discussion->id' AND attachment <> ''")) {
2049 foreach ($posts as $oldpost) {
2050 $oldpost->course = $discussion->course;
2051 $oldpost->forum = $discussion->forum;
2052 $oldpostdir = "$CFG->dataroot/".forum_file_area_name($oldpost);
2053 if (is_dir($oldpostdir)) {
2054 $newpost = $oldpost;
2055 $newpost->forum = $forumid;
7f0c3a44 2056 $newpostdir = forum_file_area($newpost);
18b8fbfa 2057 $files = get_directory_list($oldpostdir); // get it before we rename it.
cc2b7ea5 2058 if (! @rename($oldpostdir, $newpostdir)) {
2059 $return = false;
2060 }
18b8fbfa 2061 foreach ($files as $file) {
2062 clam_change_log($oldpostdir.'/'.$file,$newpostdir.'/'.$file);
2063 }
cc2b7ea5 2064 }
2065 }
2066 }
2067 return $return;
2068}
2069
7f6689e4 2070function forum_print_attachments($post, $return=NULL) {
2071// if return=html, then return a html string.
2072// if return=text, then return a text-only string.
72d497d4 2073// otherwise, print HTML for non-images, and return image HTML
7f6689e4 2074
2075 global $CFG;
2076
2077 $filearea = forum_file_area_name($post);
2078
72d497d4 2079 $imagereturn = "";
2080 $output = "";
2081
7f6689e4 2082 if ($basedir = forum_file_area($post)) {
2083 if ($files = get_directory_list($basedir)) {
2084 $strattachment = get_string("attachment", "forum");
6afe8558 2085 $strpopupwindow = get_string("popupwindow");
7f6689e4 2086 foreach ($files as $file) {
2087 $icon = mimeinfo("icon", $file);
2088 if ($CFG->slasharguments) {
2089 $ffurl = "file.php/$filearea/$file";
2090 } else {
2091 $ffurl = "file.php?file=/$filearea/$file";
2092 }
839f2456 2093 $image = "<img border=\"0\" src=\"$CFG->pixpath/f/$icon\" height=\"16\" width=\"16\" alt=\"$strpopupwindow\" />";
7f6689e4 2094
2095 if ($return == "html") {
6afe8558 2096 $output .= "<a href=\"$CFG->wwwroot/$ffurl\">$image</a> ";
2097 $output .= "<a href=\"$CFG->wwwroot/$ffurl\">$file</a><br />";
7f6689e4 2098
2099 } else if ($return == "text") {
2100 $output .= "$strattachment $file:\n$CFG->wwwroot/$ffurl\n";
2101
2102 } else {
72d497d4 2103 if ($icon == "image.gif") { // Image attachments don't get printed as links
839f2456 2104 $imagereturn .= "<br /><img src=\"$CFG->wwwroot/$ffurl\" alt=\"\" />";
72d497d4 2105 } else {
2106 link_to_popup_window("/$ffurl", "attachment", $image, 500, 500, $strattachment);
2107 echo "<a href=\"$CFG->wwwroot/$ffurl\">$file</a>";
2108 echo "<br />";
2109 }
7f6689e4 2110 }
2111 }
2112 }
2113 }
72d497d4 2114
7f6689e4 2115 if ($return) {
2116 return $output;
2117 }
72d497d4 2118
2119 return $imagereturn;
7f6689e4 2120}
db290a6e 2121/**
2122 * If successful, this function returns the name of the file
2123 * @param $post is a full post record, including course and forum
2124 * @param $newfile is a full upload array from $_FILES
2125 * @param $message is a string to hold the messages.
2126 */
7f6689e4 2127
db290a6e 2128function forum_add_attachment($post, $inputname,&$message) {
7f6689e4 2129
9dd0b378 2130 global $CFG;
2131
4909e176 2132 if (!$forum = get_record("forum", "id", $post->forum)) {
2133 return "";
2134 }
2135
2136 if (!$course = get_record("course", "id", $forum->course)) {
2137 return "";
2138 }
2139
5ddaa2e2 2140 require_once($CFG->dirroot.'/lib/uploadlib.php');
db290a6e 2141 $um = new upload_manager($inputname,true,false,$course,false,$forum->maxbytes,true,true);
5ddaa2e2 2142 $dir = forum_file_area_name($post);
2143 if ($um->process_file_uploads($dir)) {
db290a6e 2144 $message .= $um->get_errors();
5ddaa2e2 2145 return $um->get_new_filename();
7f6689e4 2146 }
db290a6e 2147 $message .= $um->get_errors();
7f6689e4 2148}
501cdbd8 2149
db290a6e 2150function forum_add_new_post($post,&$message) {
501cdbd8 2151
f37da850 2152 global $USER, $CFG;
a56f0d60 2153
ffe11640 2154 $post->created = $post->modified = time();
501cdbd8 2155 $post->mailed = "0";
a56f0d60 2156 $post->userid = $USER->id;
7f6689e4 2157 $post->attachment = "";
2158
65b0e537 2159 if (! $post->id = insert_record("forum_posts", $post)) {
7f6689e4 2160 return false;
2161 }
2162
db290a6e 2163 if ($post->attachment = forum_add_attachment($post, 'attachment',$message)) {
7f6689e4 2164 set_field("forum_posts", "attachment", $post->attachment, "id", $post->id);
2165 }
29507631 2166
2167 // Update discussion modified date
2168 set_field("forum_discussions", "timemodified", $post->modified, "id", $post->discussion);
016cd6af 2169 set_field("forum_discussions", "usermodified", $post->userid, "id", $post->discussion);
65b0e537 2170
f37da850 2171 if ($CFG->forum_trackreadposts) {
2172 forum_tp_mark_post_read($post->userid, $post, $post->forum);
2173 }
2174
7f6689e4 2175 return $post->id;
501cdbd8 2176}
2177
db290a6e 2178function forum_update_post($post,&$message) {
501cdbd8 2179
f37da850 2180 global $USER, $CFG;
a56f0d60 2181
ffe11640 2182 $post->modified = time();
a56f0d60 2183 $post->userid = $USER->id;
501cdbd8 2184
0ab85112 2185 if (!$post->parent) { // Post is a discussion starter - update discussion title too
2186 set_field("forum_discussions", "name", $post->subject, "id", $post->discussion);
2187 }
29507631 2188
db290a6e 2189 if ($newfilename = forum_add_attachment($post, 'attachment',$message)) {
7f6689e4 2190 $post->attachment = $newfilename;
2191 } else {
2192 unset($post->attachment);
2193 }
29507631 2194
2195 // Update discussion modified date
2196 set_field("forum_discussions", "timemodified", $post->modified, "id", $post->discussion);
016cd6af 2197 set_field("forum_discussions", "usermodified", $post->userid, "id", $post->discussion);
29507631 2198
f37da850 2199 if ($CFG->forum_trackreadposts) {
2200 forum_tp_mark_post_read($post->userid, $post, $post->forum);
2201 }
2202
ffe11640 2203 return update_record("forum_posts", $post);
501cdbd8 2204}
2205
db290a6e 2206function forum_add_discussion($discussion,&$message) {
65b0e537 2207// Given an object containing all the necessary data,
501cdbd8 2208// create a new discussion and return the id
2209
f37da850 2210 GLOBAL $USER, $CFG;
501cdbd8 2211
2212 $timenow = time();
2213
65b0e537 2214 // The first post is stored as a real post, and linked
501cdbd8 2215 // to from the discuss entry.
2216
2217 $post->discussion = 0;
2218 $post->parent = 0;
ebc3bd2b 2219 $post->userid = $USER->id;
501cdbd8 2220 $post->created = $timenow;
2221 $post->modified = $timenow;
2222 $post->mailed = 0;
2223 $post->subject = $discussion->name;
2224 $post->message = $discussion->intro;
7f6689e4 2225 $post->attachment = "";
2226 $post->forum = $discussion->forum;
2227 $post->course = $discussion->course;
9f0b8269 2228 $post->format = $discussion->format;
501cdbd8 2229
2230 if (! $post->id = insert_record("forum_posts", $post) ) {
2231 return 0;
2232 }
2233
db290a6e 2234 if ($post->attachment = forum_add_attachment($post, 'attachment',$message)) {
7f6689e4 2235 set_field("forum_posts", "attachment", $post->attachment, "id", $post->id); //ignore errors
2236 }
2237
65b0e537 2238 // Now do the main entry for the discussion,
02509fe6 2239 // linking to this first post
04eba58f 2240
caadf009 2241 $discussion->firstpost = $post->id;
2242 $discussion->timemodified = $timenow;
016cd6af 2243 $discussion->usermodified = $post->userid;
a56f0d60 2244 $discussion->userid = $USER->id;
04eba58f 2245
caadf009 2246 if (! $discussion->id = insert_record("forum_discussions", $discussion) ) {
2247 delete_records("forum_posts", "id", $post->id);
2248 return 0;
04eba58f 2249 }
2250
caadf009 2251 // Finally, set the pointer on the post.
2252 if (! set_field("forum_posts", "discussion", $discussion->id, "id", $post->id)) {
2253 delete_records("forum_posts", "id", $post->id);
2254 delete_records("forum_discussions", "id", $discussion->id);
2255 return 0;
04eba58f 2256 }
04eba58f 2257
f37da850 2258 if ($CFG->forum_trackreadposts) {
2259 forum_tp_mark_post_read($post->userid, $post, $post->forum);
2260 }
2261
caadf009 2262 return $discussion->id;
2263}
04eba58f 2264
04eba58f 2265
caadf009 2266function forum_delete_discussion($discussion) {
2267// $discussion is a discussion record object
04eba58f 2268
2269 $result = true;
2270
caadf009 2271 if ($posts = get_records("forum_posts", "discussion", $discussion->id)) {
2272 foreach ($posts as $post) {
2273 $post->course = $discussion->course;
2274 $post->forum = $discussion->forum;
2275 if (! delete_records("forum_ratings", "post", "$post->id")) {
2276 $result = false;
2277 }
2278 if (! forum_delete_post($post)) {
04eba58f 2279 $result = false;
2280 }
2281 }
2282 }
2283
f37da850 2284 forum_tp_delete_read_records(-1, -1, $discussion->id);
2285
caadf009 2286 if (! delete_records("forum_discussions", "id", "$discussion->id")) {
04eba58f 2287 $result = false;
2288 }
2289
2290 return $result;
2291}
2292
2293
caadf009 2294function forum_delete_post($post) {
2295 if (delete_records("forum_posts", "id", $post->id)) {
2296 delete_records("forum_ratings", "post", $post->id); // Just in case
f37da850 2297
2298 forum_tp_delete_read_records(-1, $post->id);
2299
caadf009 2300 if ($post->attachment) {
2301 $discussion = get_record("forum_discussions", "id", $post->discussion);
2302 $post->course = $discussion->course;
2303 $post->forum = $discussion->forum;
2304 forum_delete_old_attachments($post);
2305 }
2306 return true;
2307 }
2308 return false;
2309}
501cdbd8 2310
501cdbd8 2311
b656e2a9 2312function forum_print_user_discussions($courseid, $userid, $groupid=0) {
caadf009 2313 global $CFG, $USER;
501cdbd8 2314
b8bf90c5 2315 $maxdiscussions = 10;
2316 $countdiscussions = 0;
2317
65b0e537 2318 $visible = array();
1f48942e 2319
2862b309 2320 $course = get_record("course", "id", $courseid);
2321
2322 $currentgroup = get_current_group($courseid);
2323 $isteacheredit = isteacheredit($courseid);
2324
b656e2a9 2325 if ($discussions = forum_get_user_discussions($courseid, $userid, $groupid=0)) {
2862b309 2326
2327 $user = get_record("user", "id", $userid);
1b26d5e7 2328 $fullname = fullname($user, isteacher($courseid));
2862b309 2329
caadf009 2330 $replies = forum_count_discussion_replies();
2862b309 2331
2332 echo "<hr />";
2333
2334 print_heading( get_string("discussionsstartedbyrecent", "forum", $fullname) );
2335
caadf009 2336 foreach ($discussions as $discussion) {
b8bf90c5 2337 $countdiscussions++;
2338 if ($countdiscussions > $maxdiscussions) {
2339 break;
2340 }
caadf009 2341 if (($discussion->forumtype == "teacher") and !isteacher($courseid)) {
ffe11640 2342 continue;
2343 }
65b0e537 2344 if(!isset($visible[$discussion->forumid])) {
2345 $mod = New stdClass;
2346 $mod->course = $courseid;
2347 $mod->id = $discussion->forumid;
2348 $visible[$discussion->forumid] = instance_is_visible('forum', $mod);
2349 }
2350 if(!$visible[$discussion->forumid] && !isteacheredit($courseid, $USER->id)) {
2351 continue;
2352 }
2862b309 2353
2354 /// Check whether this is belongs to a discussion in a group that
2355 /// should NOT be accessible to the current user
2356
2357 if (!$isteacheredit and $discussion->groupid != -1) { /// Editing teachers or open discussions
7b07a935 2358 if (!isset($cm[$discussion->forumid])) {
2359 $cm[$discussion->forumid] = get_coursemodule_from_instance("forum", $discussion->forumid, $courseid);
2360 $groupmode[$discussion->forumid] = groupmode($course, $cm[$discussion->forumid]);
2862b309 2361 }
7b07a935 2362 if ($groupmode[$discussion->forumid] == SEPARATEGROUPS) {
2862b309 2363 if ($currentgroup != $discussion->groupid) {
2364 continue;
2365 }
2366 }
2367 }
2368
47f1da80 2369 if (!empty($replies[$discussion->discussion])) {
caadf009 2370 $discussion->replies = $replies[$discussion->discussion]->replies;
2371 } else {
2372 $discussion->replies = 0;
501cdbd8 2373 }
41905731 2374 $inforum = get_string("inforum", "forum", "<a href=\"$CFG->wwwroot/mod/forum/view.php?f=$discussion->forumid\">$discussion->forumname</a>");
caadf009 2375 $discussion->subject .= " ($inforum)";
61e96406 2376 if (!empty($USER->id)) {
2377 $ownpost = ($discussion->userid == $USER->id);
2378 } else {
2379 $ownpost = false;
2380 }
caadf009 2381 forum_print_post($discussion, $courseid, $ownpost, $reply=0, $link=1, $assessed=false);
41905731 2382 echo "<br />\n";
501cdbd8 2383 }
2384 }
501cdbd8 2385}
2386
501cdbd8 2387function forum_forcesubscribe($forumid, $value=1) {
2388 return set_field("forum", "forcesubscribe", $value, "id", $forumid);
2389}
2390
2391function forum_is_forcesubscribed($forumid) {
709f0ec8 2392 return (get_field("forum", "forcesubscribe", "id", $forumid) == 1);
501cdbd8 2393}
2394
2395function forum_is_subscribed($userid, $forumid) {
2396 if (forum_is_forcesubscribed($forumid)) {
2397 return true;
2398 }
ebc3bd2b 2399 return record_exists("forum_subscriptions", "userid", $userid, "forum", $forumid);
86970225 2400}
2401
501cdbd8 2402function forum_subscribe($userid, $forumid) {
9fa49e22 2403/// Adds user to the subscriber list
2404
6673d7bd 2405 if (record_exists("forum_subscriptions", "userid", $userid, "forum", $forumid)) {
2406 return true;
2407 }
2408
ebc3bd2b 2409 $sub->userid = $userid;
9fa49e22 2410 $sub->forum = $forumid;
501cdbd8 2411
9fa49e22 2412 return insert_record("forum_subscriptions", $sub);
501cdbd8 2413}
2414
2415function forum_unsubscribe($userid, $forumid) {
9fa49e22 2416/// Removes user from the subscriber list
ebc3bd2b 2417 return delete_records("forum_subscriptions", "userid", $userid, "forum", $forumid);
501cdbd8 2418}
2419
0a9f61b5 2420function forum_post_subscription($post) {
2421/// Given a new post, subscribes or unsubscribes as appropriate.
2422/// Returns some text which describes what happened.
2423
2424 global $USER;
2425
2426 if (empty($post->subscribe) and empty($post->unsubscribe)) {
2427 return "";
2428 }
2429
2430 if (!$forum = get_record("forum", "id", $post->forum)) {
2431 return "";
2432 }
2433
067675c0 2434 $info->name = fullname($USER);
0a9f61b5 2435 $info->forum = $forum->name;
2436
2437 if (!empty($post->subscribe)) {
2438 forum_subscribe($USER->id, $post->forum);
2439 return "<p>".get_string("nowsubscribed", "forum", $info)."</p>";
2440 }
2441
2442 forum_unsubscribe($USER->id, $post->forum);
2443 return "<p>".get_string("nownotsubscribed", "forum", $info)."</p>";
2444}
2445
501cdbd8 2446
11b0c469 2447function forum_user_has_posted_discussion($forumid, $userid) {
29507631 2448 if ($discussions = forum_get_discussions($forumid, "", $userid)) {
501cdbd8 2449 return true;
2450 } else {
2451 return false;
2452 }
2453}
2454
9197e147 2455function forum_user_can_post_discussion($forum, $currentgroup=false) {
501cdbd8 2456// $forum is an object
2457 global $USER;
2458
2459 if ($forum->type == "eachuser") {
11b0c469 2460 return (! forum_user_has_posted_discussion($forum->id, $USER->id));
501cdbd8 2461 } else if ($forum->type == "teacher") {
2462 return isteacher($forum->course);
9197e147 2463 } else if ($currentgroup) {
d591b40f 2464 return (isteacheredit($forum->course) or (ismember($currentgroup) and $forum->open == 2));
501cdbd8 2465 } else if (isteacher($forum->course)) {
2466 return true;
2467 } else {
70c476a7 2468 return ($forum->open == 2);
501cdbd8 2469 }
2470}
2471
f690562f 2472function forum_user_can_post($forum, $user=NULL) {
2473// $forum, $user are objects
2474
2475 if ($user) {
2476 $isteacher = isteacher($forum->course, $user->id);
2477 } else {
2478 $isteacher = isteacher($forum->course);
2479 }
70c476a7 2480
2481 if ($forum->type == "teacher") {
f690562f 2482 return $isteacher;
2483 } else if ($isteacher) {
70c476a7 2484 return true;
2485 } else {
2486 return $forum->open;
2487 }
2488}
501cdbd8 2489
501cdbd8 2490
65b0e537 2491function forum_print_latest_discussions($forum_id=0, $forum_numdiscussions=5,
2492 $forum_style="plain", $forum_sort="",
f6bb7eaa 2493 $currentgroup=0, $groupmode=-1, $page=-1) {
c585fa17 2494 global $CFG, $USER;
65b0e537 2495
f93f848a 2496 if ($forum_id) {
2497 if (! $forum = get_record("forum", "id", $forum_id)) {
2498 error("Forum ID was incorrect");
2499 }
2500 if (! $course = get_record("course", "id", $forum->course)) {
2501 error("Could not find the course this forum belongs to!");
2502 }
2503
2504 if ($course->category) {
2505 require_login($course->id);
2506 }
2507
2508 } else {
2509 if (! $course = get_record("course", "category", 0)) {
2510 error("Could not find a top-level course!");
2511 }
7beb45d8 2512 if (! $forum = forum_get_course_forum($course->id, "news")) {
f93f848a 2513 error("Could not find or create a main forum in this course (id $course->id)");
2514 }
2515 }
2516
2862b309 2517 if ($groupmode == -1) { /// We need to reconstruct groupmode because none was given
2518 if ($cm = get_coursemodule_from_instance("forum", $forum->id, $course->id)) {
2519 $groupmode = groupmode($course, $cm);
2520 } else {
2521 $groupmode = SEPARATEGROUPS;
2522 }
2523 }
8f0cd6ef 2524
2862b309 2525
9197e147 2526 if (forum_user_can_post_discussion($forum, $currentgroup)) {
3479c82f 2527 echo '<div class="';
2528 echo ($forum_style == 'minimal') ? 'forumaddnewminimal' : 'forumaddnew';
2529 echo '">';
49aa3742 2530 echo "<form name=\"newdiscussionform\" method=\"get\" action=\"$CFG->wwwroot/mod/forum/post.php\">";
2531 echo "<input type=\"hidden\" name=\"forum\" value=\"$forum->id\" />";
2532 echo '<input type="submit" value="';
2533 echo ($forum->type == "news") ? get_string("addanewtopic", "forum") : get_string("addanewdiscussion", "forum");
2534 echo '" />';
2535 echo '</form>';
3479c82f 2536 echo "</div>\n";
77305fe6 2537 }
2538
65b0e537 2539 if ((!$forum_numdiscussions) && ($forum_style == "plain")) {
3c8a606d 2540 $forum_style = "header"; // Abbreviate display by default
3335f6fb 2541 }
f93f848a 2542
65b0e537 2543 if ($forum_style == "minimal") {
2ab968e9 2544 $forum_sort = "p.modified DESC";
2545 }
2546
2547 $fullpost = false;
65b0e537 2548 if ($forum_style == "plain") {
2ab968e9 2549 $fullpost = true;
2550 }
2551
2862b309 2552
2553/// Decides if current user is allowed to see ALL the current discussions or not
2554
2555 if (!$currentgroup and ($groupmode != SEPARATEGROUPS or isteacheredit($forum->course)) ) {
2556 $visiblegroups = -1;
2557 } else {
2558 $visiblegroups = $currentgroup;
2559 }
2560
2561/// Get all the recent discussions we're allowed to see
2562
2563 if (! $discussions = forum_get_discussions($forum->id, $forum_sort, 0, $fullpost, $visiblegroups) ) {
3479c82f 2564 echo '<div class="';
2565 echo ($forum_style == 'minimal') ? 'forumnodiscussminimal' : 'forumnodiscuss';
2566 echo '">';
0351b1f9 2567 if ($forum->type == "news") {
3479c82f 2568 echo "(".get_string("nonews", "forum").")";
0351b1f9 2569 } else {
3479c82f 2570 echo "(".get_string("nodiscussions", "forum").")";
0351b1f9 2571 }
f13075f1 2572 echo "</div>\n";
2ab968e9 2573 return;
2574 }
65b0e537 2575
f6bb7eaa 2576 //If forum_numdiscussions <= 0 don't paging (to avoid some divided by 0 errors)
2577 if ($forum_numdiscussions <= 0) {
2578 $page = -1;
2579 $forum_numdiscussions = 0;
2580 }
2581
2582 //If we want paging
2583 if ($page != -1) {
2584 ///Get the number of discussions found
2585 $numdiscussions = count($discussions);
2586
2587 ///Show the paging bar
2588 echo "<center>";
2589 print_paging_bar($numdiscussions, $page, $forum_numdiscussions, "view.php?f=$forum->id&");
2590 echo "</center>";
2591
2592 //Calculate the page "window"
2593 $pagestart = ($page * $forum_numdiscussions) + 1;
2594 $pageend = $pagestart + $forum_numdiscussions - 1;
2595 }
2596
3335f6fb 2597 $replies = forum_count_discussion_replies($forum->id);
f93f848a 2598
3260de67 2599 $canreply = forum_user_can_post($forum);
2600
3335f6fb 2601 $discussioncount = 0;
c20b762a 2602 $olddiscussionlink = false;
3599e487 2603 $strdatestring = get_string("strftimerecentfull");
f93f848a 2604
dcde9f02 2605 if ($forum_style == "minimal") {
2606 $strftimerecent = get_string("strftimerecent");
2607 $strmore = get_string("more", "forum");
2608 }
2609
29507631 2610 if ($forum_style == "header") {
41905731 2611 echo "<table width=\"100%\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\" class=\"forumheaderlist\">";
03aa0dfa 2612 echo "<tr class=\"forumpostheader\">";
65b0e537 2613 echo "<th>".get_string("discussion", "forum")."</th>";
41905731 2614 echo "<th colspan=\"2\">".get_string("startedby", "forum")."</th>";
a796d0b8 2615 if ($forum->open or $forum->type == "teacher") {
2616 echo "<th>".get_string("replies", "forum")."</th>";
2617 }
f37da850 2618 if ($CFG->forum_trackreadposts) {
2619 echo '<th>'.get_string('unread', 'forum').'</th>';
2620 }
29507631 2621 echo "<th>".get_string("lastpost", "forum")."</th>";
2622 echo "</tr>";
2623 }
2624
3335f6fb 2625 foreach ($discussions as $discussion) {
2626 $discussioncount++;
f93f848a 2627
f6bb7eaa 2628 //If we want paging
2629 if ($page != -1) {
2630 //And we aren't inside the page "window"
2631 if ($discussioncount < $pagestart || $discussioncount > $pageend) {
2632 //Skip this discussion
2633 continue;
2634 }
2635 //Without paging, old approach
2636 } else if ($forum_numdiscussions && ($discussioncount > $forum_numdiscussions)) {
c20b762a 2637 $olddiscussionlink = true;
3335f6fb 2638 break;
2639 }
f37da850 2640
9c9f7d77 2641 if (!empty($replies[$discussion->discussion])) {
3335f6fb 2642 $discussion->replies = $replies[$discussion->discussion]->replies;
3599e487 2643 $discussion->lastpostid = $replies[$discussion->discussion]->lastpostid;
3335f6fb 2644 } else {
2645 $discussion->replies = 0;
2646 }
f37da850 2647 if ($CFG->forum_trackreadposts) {
489de4ae 2648 /// SPECIAL CASE: The front page can display a news item post to non-logged in users.
2649 /// All posts are read in this case.
2650 if (empty($USER)) {
2651 $discussion->unread = 0;
2652 } else {
f37da850 2653 /// Add in the unread posts. Add one to the replies to include the original post.
489de4ae 2654 $discussion->unread = $discussion->replies+1 -
2655 forum_tp_count_discussion_read_records($USER->id, $discussion->discussion);
2656 }
f37da850 2657 }
2658
f7477444 2659 if (!empty($USER->id)) {
2660 $ownpost = ($discussion->userid == $USER->id);
2661 } else {
2662 $ownpost=false;
2663 }
cf84431b 2664 // Use discussion name instead of subject of first post
2665 $discussion->subject = $discussion->name;
2666
3335f6fb 2667 switch ($forum_style) {
2668 case "minimal":
436a7cae 2669 if (!empty($CFG->filterall)) {
2670 $discussion->subject = filter_text($discussion->subject, $forum->course);
2671 }
3479c82f 2672 echo "<p><span class=\"forumheadminimal\">".
b656e2a9 2673 userdate($discussion->modified, $strftimerecent).
2674 " - ".
2675 fullname($discussion).
2676 "</span><br />";
3479c82f 2677 echo "<span class=\"foruminfominimal\">$discussion->subject ";
b879effb 2678 echo "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$discussion->discussion\">";
00363389 2679 echo $strmore."...</a></span>";
b879effb 2680 echo "</p>\n";
3335f6fb 2681 break;
2682 case "header":
a796d0b8 2683 forum_print_discussion_header($discussion, $forum, $strdatestring);
3335f6fb 2684 break;
2685 default:
3260de67 2686 if ($canreply or $discussion->replies) {
2687 $link = true;
2688 } else {
2689 $link = false;
2690 }
f37da850 2691
2692 /// Need to add in the forum id for forum_print_post.
2693 $discussion->forum = $forum_id;
2694
3260de67 2695 forum_print_post($discussion, $forum->course, $ownpost, $reply=0, $link, $assessed=false);
a9ef4a63 2696 echo "<br />\n";
3335f6fb 2697 break;
f93f848a 2698 }
2699 }
29507631 2700
2701 if ($forum_style == "header") {
2702 echo "</table>";
2703 }
c20b762a 2704
2705 if ($olddiscussionlink) {
3479c82f 2706 echo '<div class="';
2707 echo ($forum_style == 'minimal') ? 'forumolddiscussminimal">' : 'forumolddiscuss">';
e2d41062 2708 if ($forum_style == "minimal") {
2709 echo '<p align="center">';
2710 } else {
2711 echo '<p align="right">';
2712 }
839f2456 2713 echo "<a href=\"$CFG->wwwroot/mod/forum/view.php?f=$forum->id&amp;showall=1\">";
3479c82f 2714 echo get_string("olderdiscussions", "forum")."</a> ...</div>";
c20b762a 2715 }
f6bb7eaa 2716
2717 //If we want paging
2718 if ($page != -1) {
2719 ///Show the paging bar
2720 echo "<center>";
2721 print_paging_bar($numdiscussions, $page, $forum_numdiscussions, "view.php?f=$forum->id&");
2722 echo "</center>";
2723 }
f93f848a 2724}
2725
c6d691dc 2726function forum_print_discussion($course, $forum, $discussion, $post, $mode, $canreply=NULL) {
501cdbd8 2727
f37da850 2728 global $USER, $CFG;
501cdbd8 2729
61e96406 2730 if (!empty($USER->id)) {
2731 $ownpost = ($USER->id == $post->userid);
2732 } else {
2733 $ownpost = false;
2734 }
c6d691dc 2735 if ($canreply === NULL) {
2736 $reply = forum_user_can_post($forum);
2737 } else {
2738 $reply = $canreply;
2739 }
501cdbd8 2740
02ebf404 2741 $ratings = NULL;
74f5d1e3 2742 $ratingsmenuused = false;
61e96406 2743 if ($forum->assessed and !empty($USER->id)) {
d6bdd9d5 2744 if ($ratings->scale = make_grades_menu($forum->scale)) {
3bd98ad4 2745 $ratings->assesspublic = $forum->assesspublic;
98914efd 2746 $ratings->assesstimestart = $forum->assesstimestart;
2747 $ratings->assesstimefinish = $forum->assesstimefinish;
3bd98ad4 2748 $ratings->allow = ($forum->assessed != 2 or isteacher($course->id));
2749
41905731 2750 echo "<form name=\"form\" method=\"post\" action=\"rate.php\">";
b4510d53 2751 echo "<input type=\"hidden\" name=\"id\" value=\"$course->id\" />";
9d1b97c5 2752 }
2753 }
2754
f37da850 2755/// Add the forum id to the post object - used by read tracking.
2756 $post->forum = $forum->id;
2757
2758 if ($CFG->forum_trackreadposts) {
2759 $user_read_array = forum_tp_get_discussion_read_records($USER->id, $post->discussion);
2760 } else {
2761 $user_read_array = array();
2762 }
2763
2764 if (forum_print_post($post, $course->id, $ownpost, $reply, $link=false, $ratings,
2765 '', '', (isset($user_read_array[$post->id]) || forum_tp_is_post_old($post)))) {
74f5d1e3 2766 $ratingsmenuused = true;
2767 }
501cdbd8 2768
2769 switch ($mode) {
2e2e71a8 2770 case FORUM_MODE_FLATOLDEST :
2771 case FORUM_MODE_FLATNEWEST :
65b0e537 2772 default:
f37da850 2773 if (forum_print_posts_flat($post->discussion, $course->id, $mode, $ratings, $reply,
2774 $user_read_array, $post->forum)) {
74f5d1e3 2775 $ratingsmenuused = true;
2776 }
501cdbd8 2777 break;
2778
2e2e71a8 2779 case FORUM_MODE_THREADED :
f37da850 2780 if (forum_print_posts_threaded($post->id, $course->id, 0, $ratings, $reply,
2781 $user_read_array, $post->forum)) {
74f5d1e3 2782 $ratingsmenuused = true;
2783 }
501cdbd8 2784 break;
2785
2e2e71a8 2786 case FORUM_MODE_NESTED :
f37da850 2787 if (forum_print_posts_nested($post->id, $course->id, $ratings, $reply,
2788 $user_read_array, $post->forum)) {
74f5d1e3 2789 $ratingsmenuused = true;
2790 }
501cdbd8 2791 break;
2792 }
2793
74f5d1e3 2794 if ($ratingsmenuused) {
b4510d53 2795 echo "<center><input type=\"submit\" value=\"".get_string("sendinratings", "forum")."\" />";
fa01ae8b 2796 if ($forum->scale < 0) {
2797 if ($scale = get_record("scale", "id", abs($forum->scale))) {
2798 print_scale_menu_helpbutton($course->id, $scale );
2799 }
2800 }
02ebf404 2801 echo "</center>";
2802 echo "</form>";
501cdbd8 2803 }
2804}
2805
f37da850 2806/// Add the forum id to the argument list, for use in 'forum_print_post'.
2807/// Add the user_read_array to the argument list.
83a305a7 2808function forum_print_posts_flat($discussion, $courseid, $direction, $ratings, $reply, &$user_read_array, $forumid=0) {
f37da850 2809 global $USER, $CFG;
501cdbd8 2810
501cdbd8 2811 $link = false;
74f5d1e3 2812 $ratingsmenuused = false;
501cdbd8 2813
2814 if ($direction < 0) {
2815 $sort = "ORDER BY created DESC";
2816 } else {
2817 $sort = "ORDER BY created ASC";
2818 }
2819
1f48942e 2820 if ($posts = forum_get_discussion_posts($discussion, $sort)) {
501cdbd8 2821 foreach ($posts as $post) {
f37da850 2822
2823 /// Add the forum id to the post object - used by read tracking.
2824 if (!$CFG->forum_usermarksread) {
2825 $post->forum = $forumid;
2826 } else {
2827 $post->forum = 0;
2828 }
2829
ebc3bd2b 2830 $ownpost = ($USER->id == $post->userid);
83a305a7 2831 if (forum_print_post($post, $courseid, $ownpost, $reply, $link, $ratings,
f37da850 2832 '', '', (isset($user_read_array[$post->id]) || forum_tp_is_post_old($post)))) {
74f5d1e3 2833 $ratingsmenuused = true;
2834 }
501cdbd8 2835 }
501cdbd8 2836 }
74f5d1e3 2837
2838 return $ratingsmenuused;
501cdbd8 2839}
2840
f37da850 2841/// Add the forum id to the argument list, for use in 'forum_print_post'.
2842/// Add the user_read_array to the argument list.
83a305a7 2843function forum_print_posts_threaded($parent, $courseid, $depth, $ratings, $reply, &$user_read_array, $forumid=0) {
f37da850 2844 global $USER, $CFG;
501cdbd8 2845
501cdbd8 2846 $link = false;
74f5d1e3 2847 $ratingsmenuused = false;
501cdbd8 2848
1f48942e 2849 if ($posts = forum_get_child_posts($parent)) {
501cdbd8 2850 foreach ($posts as $post) {
2851
039c0ec4 2852 echo '<div class="forumpostindent">';
501cdbd8 2853 if ($depth > 0) {
ebc3bd2b 2854 $ownpost = ($USER->id == $post->userid);
f37da850 2855
2856 if (!$CFG->forum_usermarksread) {
2857 $post->forum = $forumid;
2858 } else {
2859 $post->forum = 0;
2860 }
2861
83a305a7 2862 if (forum_print_post($post, $courseid, $ownpost, $reply, $link, $ratings,
f37da850 2863 '', '', (isset($user_read_array[$post->id]) || forum_tp_is_post_old($post)))) {
74f5d1e3 2864 $ratingsmenuused = true;
2865 }
f95c2a73 2866 echo "<br />";
501cdbd8 2867 } else {
83a305a7 2868 $by->name = fullname($post, isteacher($courseid));
d62413e8 2869 $by->date = userdate($post->modified);
f37da850 2870
2871 if ($CFG->forum_trackreadposts) {
2872 if (isset($user_read_array[$post->id]) || forum_tp_is_post_old($post)) {
2873 $style = '<span class="forumthread read">';
2874 } else {
2875 $style = '<span class="forumthread unread">';
2876 }
2877 } else {
2878 $style = '<span class="forumthread">';
2879 }
2880 echo $style."<a name=\"$post->id\"></a>".
2881 "<a href=\"discuss.php?d=$post->discussion&amp;parent=$post->id\">$post->subject</a> ";
8c3c8481 2882 print_string("bynameondate", "forum", $by);
f37da850 2883 echo "</span>";
501cdbd8 2884 }
2885
83a305a7 2886 if (forum_print_posts_threaded($post->id, $courseid, $depth-1, $ratings, $reply,
f37da850 2887 $user_read_array, $forumid)) {
74f5d1e3 2888 $ratingsmenuused = true;
2889 }
bb3b56c6 2890 echo "</div>\n";
501cdbd8 2891 }
501cdbd8 2892 }
74f5d1e3 2893 return $ratingsmenuused;
501cdbd8 2894}
2895
f37da850 2896/// Add the forum id to the argument list, for use in 'forum_print_post'.
2897/// Add the user_read_array to the argument list.
83a305a7 2898function forum_print_posts_nested($parent, $courseid, $ratings, $reply, &$user_read_array, $forumid=0) {
f37da850 2899 global $USER, $CFG;
501cdbd8 2900
501cdbd8 2901 $link = false;
74f5d1e3 2902 $ratingsmenuused = false;
501cdbd8 2903
1f48942e 2904 if ($posts = forum_get_child_posts($parent)) {
501cdbd8 2905 foreach ($posts as $post) {
2906
f37da850 2907 echo '<div class="forumpostindent">';
61e96406 2908 if (empty($USER->id)) {
2909 $ownpost = false;
2910 } else {
2911 $ownpost = ($USER->id == $post->userid);
2912 }
501cdbd8 2913
f37da850 2914 /// Add the forum id to the post object - used by read tracking.
2915 if (!$CFG->forum_usermarksread) {
2916 $post->forum = $forumid;
2917 } else {
2918 $post->forum = 0;
2919 }
2920
83a305a7 2921 if (forum_print_post($post, $courseid, $ownpost, $reply, $link, $ratings,
f37da850 2922 '', '', (isset($user_read_array[$post->id]) || forum_tp_is_post_old($post)))) {
74f5d1e3 2923 $ratingsmenuused = true;
2924 }
2925 echo "<br />";
83a305a7 2926 if (forum_print_posts_nested($post->id, $courseid, $ratings, $reply, $user_read_array, $forumid)) {
74f5d1e3 2927 $ratingsmenuused = true;
2928 }
bb3b56c6 2929 echo "</div>\n";
501cdbd8 2930 }
501cdbd8 2931 }
74f5d1e3 2932 return $ratingsmenuused;
501cdbd8 2933}
2934
2862b309 2935function forum_get_recent_mod_activity(&$activities, &$index, $sincetime, $courseid, $cmid="0", $user="", $groupid="") {
a57a7794 2936// Returns all forum posts since a given time. If forum is specified then
2937// this restricts the results
2938
2939 global $CFG;
2940
2862b309 2941 if ($cmid) {
2942 $forumselect = " AND cm.id = '$cmid'";
a57a7794 2943 } else {
2944 $forumselect = "";
2945 }
2946
2947 if ($user) {
2948 $userselect = " AND u.id = '$user'";
2949 } else {
2950 $userselect = "";
2951 }
2952
a57a7794 2953 $posts = get_records_sql("SELECT p.*, d.name, u.firstname, u.lastname,
2954 u.picture, d.groupid, cm.instance, f.name, cm.section
2955 FROM {$CFG->prefix}forum_posts p,
2956 {$CFG->prefix}forum_discussions d,
2957 {$CFG->prefix}user u,
2958 {$CFG->prefix}course_modules cm,
2959 {$CFG->prefix}forum f
2960 WHERE p.modified > '$sincetime' $forumselect
2961 AND p.userid = u.id $userselect
2962 AND d.course = '$courseid'
8f0cd6ef 2963 AND p.discussion = d.id
a57a7794 2964 AND cm.instance = f.id
2965 AND cm.course = d.course
2966 AND cm.course = f.course
2967 AND f.id = d.forum
2968 ORDER BY d.id");
2969
2862b309 2970 if (empty($posts)) {
2971 return;
2972 }
2973
2974 $isteacheredit = isteacheredit($courseid);
a57a7794 2975
90708fc1 2976 foreach ($posts as $post) {
a57a7794 2977
2862b309 2978 if ($groupid and ($post->groupid != -1 and $groupid != $post->groupid and !$isteacheredit)) {
2979 continue;
2980 }
a57a7794 2981
2862b309 2982 $tmpactivity->type = "forum";
2983 $tmpactivity->defaultindex = $index;
2984 $tmpactivity->instance = $post->instance;
2985 $tmpactivity->name = $post->name;
2986 $tmpactivity->section = $post->section;
65b0e537 2987
2862b309 2988 $tmpactivity->content->id = $post->id;
2989 $tmpactivity->content->discussion = $post->discussion;
2990 $tmpactivity->content->subject = $post->subject;
2991 $tmpactivity->content->parent = $post->parent;
a57a7794 2992
2862b309 2993 $tmpactivity->user->userid = $post->userid;
2994 $tmpactivity->user->fullname = fullname($post);
2995 $tmpactivity->user->picture = $post->picture;
65b0e537 2996
2862b309 2997 $tmpactivity->timestamp = $post->modified;
2998 $activities[] = $tmpactivity;
2999
3000 $index++;
90708fc1 3001 }
a57a7794 3002
90708fc1 3003 return;
a57a7794 3004}
3005
3006function forum_print_recent_mod_activity($activity, $course, $detail=false) {
3007
d30867b0 3008 global $CFG;
a57a7794 3009
3010 echo '<table border="0" cellpadding="3" cellspacing="0">';
3011
3012 if ($activity->content->parent) {
3013 $openformat = "<font size=\"2\"><i>";
3014 $closeformat = "</i></font>";
3015 } else {
3016 $openformat = "<b>";
3017 $closeformat = "</b>";
3018 }
3019
d30867b0 3020 echo "<tr><td class=\"forumpostpicture\" width=\"35\" valign=\"top\">";
a57a7794 3021 print_user_picture($activity->user->userid, $course, $activity->user->picture);
3022 echo "</td><td>$openformat";
3023
3024 if ($detail) {
3025 echo "<img src=\"$CFG->modpixpath/$activity->type/icon.gif\" ".
839f2456 3026 "height=\"16\" width=\"16\" alt=\"$activity->name\" /> ";
a57a7794 3027 }
3028 echo "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=" . $activity->content->discussion
3029 . "#" . $activity->content->id . "\">";
3030
3031 echo $activity->content->subject;
3032 echo "</a>$closeformat";
3033
a9ef4a63 3034 echo "<br /><font size=\"2\">";
839f2456 3035 echo "<a href=\"$CFG->wwwroot/user/view.php?id=" . $activity->user->userid . "&amp;course=" . "$course\">"
a57a7794 3036 . $activity->user->fullname . "</a>";
3037 echo " - " . userdate($activity->timestamp) . "</font></td></tr>";
3038 echo "</table>";
3039
3040 return;
3041}
3042
cf84431b 3043function forum_change_discussionid($postid, $discussionid) {
3044/// recursively sets the discussion field to $discussionid on $postid and all its children
3045/// used when pruning a post
3046 set_field('forum_posts', 'discussion', $discussionid, 'id', $postid);
3047 if ($posts = get_records('forum_posts', 'parent', $postid)) {
3048 foreach ($posts as $post) {
3049 forum_change_discussionid($post->id, $discussionid);
3050 }
3051 }
3052 return true;
3053}
3054
90e7063e 3055function forum_update_subscriptions_button($courseid, $forumid) {
3056// Prints the editing button on subscribers page
3057 global $CFG, $USER;
3058
f88803e0 3059 if (isteacher($courseid)) {
90e7063e 3060 if (!empty($USER->subscriptionsediting)) {
3061 $string = get_string("turneditingoff");
3062 $edit = "off";
3063 } else {
3064 $string = get_string("turneditingon");
3065 $edit = "on";
3066 }
3067 return "<form target=\"$CFG->framename\" method=\"get\" action=\"$CFG->wwwroot/mod/forum/subscribers.php\">".
3068 "<input type=\"hidden\" name=\"id\" value=\"$forumid\" />".
3069 "<input type=\"hidden\" name=\"edit\" value=\"$edit\" />".
3070 "<input type=\"submit\" value=\"$string\" /></form>";
3071 }
3072}
3073
709f0ec8 3074function forum_add_user($userid, $courseid) {
3075/// Add subscriptions for new users
906fef94 3076 if ($forums = get_records_select('forum', "course = '$courseid' AND forcesubscribe = '".FORUM_INITIALSUBSCRIBE."'")) {
709f0ec8 3077 foreach ($forums as $forum) {
3078 forum_subscribe($userid, $forum->id);
3079 }
3080 }
906fef94 3081 if ($forums = get_records_select('forum', "course = '".SITEID."' AND forcesubscribe = '".FORUM_INITIALSUBSCRIBE."'")) {
7b5944cd 3082 foreach ($forums as $forum) {
3083 forum_subscribe($userid, $forum->id);
3084 }
3085 }
709f0ec8 3086}
3087
f37da850 3088function forum_tp_add_read_record($userid, $postid, $discussionid=-1, $forumid=-1) {
3089 if (($readrecord = forum_tp_get_read_records($userid, $postid)) === false) {
3090 /// New read record
3091 unset($readrecord);
3092 $readrecord->userid = $userid;
3093 $readrecord->postid = $postid;
3094 $readrecord->discussionid = $discussionid;
3095 $readrecord->forumid = $forumid;
3096 $readrecord->firstread = time();
3097 $readrecord->lastread = $readrecord->firstread;
90fd2b51 3098 return insert_record('forum_read', $readrecord, true);
f37da850 3099 }
3100 else {
3101 /// Update read record
3102 $readrecord = reset($readrecord);
3103 $readrecord->lastread = time();
3104
3105 /// This shouldn't happen, but just in case...
3106 if (!$readrecord->firstread) {
3107 $readrecord->firstread = $readrecord->lastread;
3108 /// Update the 'firstread' field.
3109 set_field('forum_read', 'firstread', $readrecord->firstread, 'userid', $userid, 'postid', $postid);
3110 }
3111 if ($discussionid > -1) {
3112 /// Update the 'discussionid' field.
3113 set_field('forum_read', 'discussionid', $discussionid, 'userid', $userid, 'postid', $postid);
3114 }
3115 if ($forumid > -1) {
3116 /// Update the 'forumid' field.
3117 set_field('forum_read', 'forumid', $forumid, 'userid', $userid, 'postid', $postid);
3118 }
3119
3120 $readrecord->forumid = $forumid;
3121 /// Update the 'lastread' field.
3122 return set_field('forum_read', 'lastread', $readrecord->lastread, 'userid', $userid, 'postid', $postid);
3123 }
3124}
3125
3126function forum_tp_get_read_records($userid=-1, $postid=-1, $discussionid=-1, $forumid=-1) {
3127 /// Returns all records in the 'forum_read' table matching the passed keys, indexed
3128 /// by userid.
3129 $select = '';
3130 if ($userid > -1) {
3131 if ($select != '') $select .= ' AND ';
3132 $select .= 'userid = \''.$userid.'\'';
3133 }
3134 if ($postid > -1) {
3135 if ($select != '') $select .= ' AND ';
3136 $select .= 'postid = \''.$postid.'\'';
3137 }
3138 if ($discussionid > -1) {
3139 if ($select != '') $select .= ' AND ';
3140 $select .= 'discussionid = \''.$discussionid.'\'';
3141 }
3142 if ($forumid > -1) {
3143 if ($select != '') $select .= ' AND ';
3144 $select .= 'forumid = \''.$forumid.'\'';
3145 }
3146
3147 return get_records_select('forum_read', $select);
3148}
3149
3150function forum_tp_get_discussion_read_records($userid, $discussionid) {
3151 /// Returns all read records for the provided user and discussion, indexed by postid.
3152 $select = 'userid = \''.$userid.'\' AND discussionid = \''.$discussionid.'\'';
3153 $fields = 'postid, firstread, lastread';
3154 return get_records_select('forum_read', $select, '', $fields);
3155}
3156
3157function forum_tp_mark_post_read($userid, &$post, $forumid) {
3158/// If its an old post, do nothing. If the record exists, the maintenance will clear it up later.
3159 if (!forum_tp_is_post_old($post)) {
3160 return forum_tp_add_read_record($userid, $post->id, $post->discussion, $forumid);
3161 } else {
3162 return true;
3163 }
3164}
3165
3166function forum_tp_is_post_read($userid, &$post) {
3167 return (forum_tp_is_post_old($post) ||
3168 (get_record('forum_read', 'userid', $userid, 'postid', $post->id) !== false));
3169}
3170
3171function forum_tp_is_post_old(&$post, $time=null) {
3172 global $CFG;
3173
3174 if (is_null($time)) $time = time();
3175 return ($post->modified < ($time - ($CFG->forum_oldpostdays * 24 * 3600)));
3176}
3177
3178function forum_tp_count_discussion_read_records($userid, $discussionid) {
3179 /// Returns the count of records for the provided user and discussion.
3180 global $CFG;
3181
3182 $cutoffdate = isset($CFG->forum_oldpostdays) ? (time() - ($CFG->forum_oldpostdays*24*60*60)) : 0;
3183
3184 $sql = 'SELECT COUNT(DISTINCT p.id) '.
3185 'FROM '.$CFG->prefix.'forum_discussions d '.
3186 'LEFT JOIN '.$CFG->prefix.'forum_read r ON d.id = r.discussionid AND r.userid = '.$userid.' '.
3187 'LEFT JOIN '.$CFG->prefix.'forum_posts p ON p.discussion = d.id '.
3188 'AND (p.modified < '.$cutoffdate.' OR p.id = r.postid) '.
3189 'WHERE d.id = '.$discussionid;
3190
3191 return (count_records_sql($sql));
3192}
3193
3194function forum_tp_count_forum_posts($forumid, $groupid=false) {
3195 /// Returns the count of posts for the provided forum and [optionally] group.
3196 global $CFG;
3197
3198 $sql = 'SELECT COUNT(*) '.
3199 'FROM '.$CFG->prefix.'forum_posts fp,'.$CFG->prefix.'forum_discussions fd '.
3200 'WHERE fd.forum = '.$forumid.' AND fp.discussion = fd.id';
3201 if ($groupid !== false) {
3202 $sql .= ' AND (fd.groupid = '.$groupid.' OR fd.groupid = -1)';
3203 }
3204 $count = count_records_sql($sql);
3205
3206
3207 return $count;
3208}
3209
3210function forum_tp_count_forum_read_records($userid, $forumid, $groupid=false) {
3211 /// Returns the count of records for the provided user and forum and [optionally] group.
3212 global $CFG;
3213
3214 $cutoffdate = isset($CFG->forum_oldpostdays) ? (time() - ($CFG->forum_oldpostdays*24*60*60)) : 0;
3215
3216 $groupsel = '';
3217 if ($groupid !== false) {
3218 $groupsel = ' AND (d.groupid = '.$groupid.' OR d.groupid = -1)';
3219 }
3220
3221 $sql = 'SELECT COUNT(DISTINCT p.id) '.
3222 'FROM '.$CFG->prefix.'forum_posts p,'.$CFG->prefix.'forum_read r,'.$CFG->prefix.'forum_discussions d '.
3223 'WHERE d.forum = '.$forumid.$groupsel.' AND p.discussion = d.id AND '.